mirror of
https://github.com/godotengine/godot.git
synced 2025-12-07 22:00:10 +00:00
Modify color in ColorPicker with keyboard or joypad
This commit is contained in:
parent
4f0cbc9a58
commit
e6f812c056
8 changed files with 539 additions and 8 deletions
|
|
@ -402,6 +402,7 @@ static const _BuiltinActionDisplayName _builtin_action_display_names[] = {
|
||||||
{ "ui_filedialog_show_hidden", TTRC("Show Hidden") },
|
{ "ui_filedialog_show_hidden", TTRC("Show Hidden") },
|
||||||
{ "ui_swap_input_direction ", TTRC("Swap Input Direction") },
|
{ "ui_swap_input_direction ", TTRC("Swap Input Direction") },
|
||||||
{ "ui_unicode_start", TTRC("Start Unicode Character Input") },
|
{ "ui_unicode_start", TTRC("Start Unicode Character Input") },
|
||||||
|
{ "ui_colorpicker_delete_preset", TTRC("Toggle License Notices") },
|
||||||
{ "", ""}
|
{ "", ""}
|
||||||
/* clang-format on */
|
/* clang-format on */
|
||||||
};
|
};
|
||||||
|
|
@ -789,6 +790,12 @@ const HashMap<String, List<Ref<InputEvent>>> &InputMap::get_builtins() {
|
||||||
inputs.push_back(InputEventKey::create_reference(Key::QUOTELEFT | KeyModifierMask::CMD_OR_CTRL));
|
inputs.push_back(InputEventKey::create_reference(Key::QUOTELEFT | KeyModifierMask::CMD_OR_CTRL));
|
||||||
default_builtin_cache.insert("ui_swap_input_direction", inputs);
|
default_builtin_cache.insert("ui_swap_input_direction", inputs);
|
||||||
|
|
||||||
|
// ///// UI ColorPicker Shortcuts /////
|
||||||
|
inputs = List<Ref<InputEvent>>();
|
||||||
|
inputs.push_back(InputEventJoypadButton::create_reference(JoyButton::X));
|
||||||
|
inputs.push_back(InputEventKey::create_reference(Key::KEY_DELETE));
|
||||||
|
default_builtin_cache.insert("ui_colorpicker_delete_preset", inputs);
|
||||||
|
|
||||||
return default_builtin_cache;
|
return default_builtin_cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -141,6 +141,9 @@
|
||||||
</constant>
|
</constant>
|
||||||
</constants>
|
</constants>
|
||||||
<theme_items>
|
<theme_items>
|
||||||
|
<theme_item name="focused_not_editing_cursor_color" data_type="color" type="Color" default="Color(1, 1, 1, 0.275)">
|
||||||
|
Color of rectangle or circle drawn when a picker shape part is focused but not editable via keyboard or joypad. Displayed [i]over[/i] the picker shape, so a partially transparent color should be used to ensure the picker shape remains visible.
|
||||||
|
</theme_item>
|
||||||
<theme_item name="center_slider_grabbers" data_type="constant" type="int" default="1">
|
<theme_item name="center_slider_grabbers" data_type="constant" type="int" default="1">
|
||||||
Overrides the [theme_item Slider.center_grabber] theme property of the sliders.
|
Overrides the [theme_item Slider.center_grabber] theme property of the sliders.
|
||||||
</theme_item>
|
</theme_item>
|
||||||
|
|
@ -204,5 +207,14 @@
|
||||||
<theme_item name="shape_rect_wheel" data_type="icon" type="Texture2D">
|
<theme_item name="shape_rect_wheel" data_type="icon" type="Texture2D">
|
||||||
The icon for rectangular wheel picker shapes.
|
The icon for rectangular wheel picker shapes.
|
||||||
</theme_item>
|
</theme_item>
|
||||||
|
<theme_item name="picker_focus_circle" data_type="style" type="StyleBox">
|
||||||
|
The [StyleBox] used when the circle-shaped part of the picker is focused. Displayed [i]over[/i] the picker shape, so a partially transparent [StyleBox] should be used to ensure the picker shape remains visible. A [StyleBox] that represents an outline or an underline works well for this purpose. To disable the focus visual effect, assign a [StyleBoxEmpty] resource. Note that disabling the focus visual effect will harm keyboard/controller navigation usability, so this is not recommended for accessibility reasons.
|
||||||
|
</theme_item>
|
||||||
|
<theme_item name="picker_focus_rectangle" data_type="style" type="StyleBox">
|
||||||
|
The [StyleBox] used when the rectangle-shaped part of the picker is focused. Displayed [i]over[/i] the picker shape, so a partially transparent [StyleBox] should be used to ensure the picker shape remains visible. A [StyleBox] that represents an outline or an underline works well for this purpose. To disable the focus visual effect, assign a [StyleBoxEmpty] resource. Note that disabling the focus visual effect will harm keyboard/controller navigation usability, so this is not recommended for accessibility reasons.
|
||||||
|
</theme_item>
|
||||||
|
<theme_item name="sample_focus" data_type="style" type="StyleBox">
|
||||||
|
The [StyleBox] used for the old color sample part when it is focused. Displayed [i]over[/i] the sample, so a partially transparent [StyleBox] should be used to ensure the picker shape remains visible. A [StyleBox] that represents an outline or an underline works well for this purpose. To disable the focus visual effect, assign a [StyleBoxEmpty] resource. Note that disabling the focus visual effect will harm keyboard/controller navigation usability, so this is not recommended for accessibility reasons.
|
||||||
|
</theme_item>
|
||||||
</theme_items>
|
</theme_items>
|
||||||
</class>
|
</class>
|
||||||
|
|
|
||||||
|
|
@ -1123,6 +1123,10 @@
|
||||||
Default [InputEventAction] to discard a modal or pending input.
|
Default [InputEventAction] to discard a modal or pending input.
|
||||||
[b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified.
|
[b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified.
|
||||||
</member>
|
</member>
|
||||||
|
<member name="input/ui_colorpicker_delete_preset" type="Dictionary" setter="" getter="">
|
||||||
|
Default [InputEventAction] to delete a color preset in a [ColorPicker].
|
||||||
|
[b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified.
|
||||||
|
</member>
|
||||||
<member name="input/ui_copy" type="Dictionary" setter="" getter="">
|
<member name="input/ui_copy" type="Dictionary" setter="" getter="">
|
||||||
Default [InputEventAction] to copy a selection to the clipboard.
|
Default [InputEventAction] to copy a selection to the clipboard.
|
||||||
[b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified.
|
[b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified.
|
||||||
|
|
|
||||||
|
|
@ -1750,6 +1750,9 @@ void EditorThemeManager::_populate_standard_styles(const Ref<EditorTheme> &p_the
|
||||||
// ColorPicker and related nodes.
|
// ColorPicker and related nodes.
|
||||||
{
|
{
|
||||||
// ColorPicker.
|
// ColorPicker.
|
||||||
|
p_config.circle_style_focus = p_config.button_style_focus->duplicate();
|
||||||
|
p_config.circle_style_focus->set_corner_radius_all(256 * EDSCALE);
|
||||||
|
p_config.circle_style_focus->set_corner_detail(32 * EDSCALE);
|
||||||
|
|
||||||
p_theme->set_constant("margin", "ColorPicker", p_config.base_margin);
|
p_theme->set_constant("margin", "ColorPicker", p_config.base_margin);
|
||||||
p_theme->set_constant("sv_width", "ColorPicker", 256 * EDSCALE);
|
p_theme->set_constant("sv_width", "ColorPicker", 256 * EDSCALE);
|
||||||
|
|
@ -1758,6 +1761,11 @@ void EditorThemeManager::_populate_standard_styles(const Ref<EditorTheme> &p_the
|
||||||
p_theme->set_constant("label_width", "ColorPicker", 10 * EDSCALE);
|
p_theme->set_constant("label_width", "ColorPicker", 10 * EDSCALE);
|
||||||
p_theme->set_constant("center_slider_grabbers", "ColorPicker", 1);
|
p_theme->set_constant("center_slider_grabbers", "ColorPicker", 1);
|
||||||
|
|
||||||
|
p_theme->set_stylebox("sample_focus", "ColorPicker", p_config.button_style_focus);
|
||||||
|
p_theme->set_stylebox("picker_focus_rectangle", "ColorPicker", p_config.button_style_focus);
|
||||||
|
p_theme->set_stylebox("picker_focus_circle", "ColorPicker", p_config.circle_style_focus);
|
||||||
|
p_theme->set_color("focused_not_editing_cursor_color", "ColorPicker", p_config.highlight_color);
|
||||||
|
|
||||||
p_theme->set_icon("screen_picker", "ColorPicker", p_theme->get_icon(SNAME("ColorPick"), EditorStringName(EditorIcons)));
|
p_theme->set_icon("screen_picker", "ColorPicker", p_theme->get_icon(SNAME("ColorPick"), EditorStringName(EditorIcons)));
|
||||||
p_theme->set_icon("shape_circle", "ColorPicker", p_theme->get_icon(SNAME("PickerShapeCircle"), EditorStringName(EditorIcons)));
|
p_theme->set_icon("shape_circle", "ColorPicker", p_theme->get_icon(SNAME("PickerShapeCircle"), EditorStringName(EditorIcons)));
|
||||||
p_theme->set_icon("shape_rect", "ColorPicker", p_theme->get_icon(SNAME("PickerShapeRectangle"), EditorStringName(EditorIcons)));
|
p_theme->set_icon("shape_rect", "ColorPicker", p_theme->get_icon(SNAME("PickerShapeRectangle"), EditorStringName(EditorIcons)));
|
||||||
|
|
|
||||||
|
|
@ -133,6 +133,8 @@ class EditorThemeManager {
|
||||||
Ref<StyleBoxFlat> button_style_pressed;
|
Ref<StyleBoxFlat> button_style_pressed;
|
||||||
Ref<StyleBoxFlat> button_style_hover;
|
Ref<StyleBoxFlat> button_style_hover;
|
||||||
|
|
||||||
|
Ref<StyleBoxFlat> circle_style_focus;
|
||||||
|
|
||||||
Ref<StyleBoxFlat> popup_style;
|
Ref<StyleBoxFlat> popup_style;
|
||||||
Ref<StyleBoxFlat> popup_border_style;
|
Ref<StyleBoxFlat> popup_border_style;
|
||||||
Ref<StyleBoxFlat> window_style;
|
Ref<StyleBoxFlat> window_style;
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,12 @@ void ColorPicker::_notification(int p_what) {
|
||||||
btn_pick->set_tooltip_text(ETR("Pick a color from the application window."));
|
btn_pick->set_tooltip_text(ETR("Pick a color from the application window."));
|
||||||
btn_pick->connect(SceneStringName(pressed), callable_mp(this, &ColorPicker::_pick_button_pressed_legacy));
|
btn_pick->connect(SceneStringName(pressed), callable_mp(this, &ColorPicker::_pick_button_pressed_legacy));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// In HSV Wheel shape the wheel is around the rectangle and the engine cannot automatically select
|
||||||
|
// the square while pressing ui_up to change focused control from the wheel.
|
||||||
|
wheel->set_focus_neighbor(SIDE_TOP, wheel_uv->get_path());
|
||||||
|
wheel_uv->set_focus_neighbor(SIDE_BOTTOM, wheel->get_path());
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case NOTIFICATION_TRANSLATION_CHANGED: {
|
case NOTIFICATION_TRANSLATION_CHANGED: {
|
||||||
|
|
@ -153,8 +159,40 @@ void ColorPicker::_notification(int p_what) {
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case NOTIFICATION_FOCUS_ENTER:
|
||||||
|
case NOTIFICATION_FOCUS_EXIT: {
|
||||||
|
cursor_editing = false;
|
||||||
|
} break;
|
||||||
|
|
||||||
case NOTIFICATION_INTERNAL_PROCESS: {
|
case NOTIFICATION_INTERNAL_PROCESS: {
|
||||||
if (!is_picking_color) {
|
if (!is_picking_color) {
|
||||||
|
Input *input = Input::get_singleton();
|
||||||
|
bool is_picker_focused = uv_edit->has_focus() || wheel_uv->has_focus() || wheel->has_focus();
|
||||||
|
|
||||||
|
if (input->is_action_just_released("ui_left") ||
|
||||||
|
input->is_action_just_released("ui_right") ||
|
||||||
|
input->is_action_just_released("ui_up") ||
|
||||||
|
input->is_action_just_released("ui_down")) {
|
||||||
|
gamepad_event_delay_ms = DEFAULT_GAMEPAD_EVENT_DELAY_MS;
|
||||||
|
echo_multiplier = 1;
|
||||||
|
accept_event();
|
||||||
|
set_process_internal(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gamepad_event_delay_ms -= get_process_delta_time();
|
||||||
|
if (gamepad_event_delay_ms <= 0) {
|
||||||
|
gamepad_event_delay_ms = GAMEPAD_EVENT_REPEAT_RATE_MS + gamepad_event_delay_ms;
|
||||||
|
// Treat any input from joypad axis as -1, 0, or 1, as the value is added to Vector2i and would be lost.
|
||||||
|
Vector2 color_change_vector = Vector2(
|
||||||
|
input->is_action_pressed("ui_right") - input->is_action_pressed("ui_left"),
|
||||||
|
input->is_action_pressed("ui_down") - input->is_action_pressed("ui_up"));
|
||||||
|
if (is_picker_focused) {
|
||||||
|
_update_uv_cursor(color_change_vector, true);
|
||||||
|
} else if (w_edit->has_focus()) {
|
||||||
|
_update_w_cursor(color_change_vector.y, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DisplayServer *ds = DisplayServer::get_singleton();
|
DisplayServer *ds = DisplayServer::get_singleton();
|
||||||
|
|
@ -180,7 +218,7 @@ void ColorPicker::_notification(int p_what) {
|
||||||
}
|
}
|
||||||
|
|
||||||
set_pick_color(c);
|
set_pick_color(c);
|
||||||
}
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -277,6 +315,42 @@ void ColorPicker::set_focus_on_line_edit() {
|
||||||
callable_mp((Control *)c_text, &Control::grab_focus).call_deferred();
|
callable_mp((Control *)c_text, &Control::grab_focus).call_deferred();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ColorPicker::set_focus_on_picker_shape() {
|
||||||
|
switch (current_shape) {
|
||||||
|
case SHAPE_HSV_RECTANGLE:
|
||||||
|
callable_mp(w_edit, &Control::grab_focus).call_deferred();
|
||||||
|
break;
|
||||||
|
case SHAPE_HSV_WHEEL:
|
||||||
|
callable_mp(wheel, &Control::grab_focus).call_deferred();
|
||||||
|
break;
|
||||||
|
case SHAPE_VHS_CIRCLE:
|
||||||
|
case SHAPE_OKHSL_CIRCLE:
|
||||||
|
callable_mp(wheel_uv, &Control::grab_focus).call_deferred();
|
||||||
|
break;
|
||||||
|
default: {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColorPicker::_picker_shape_focus_entered() {
|
||||||
|
Input *input = Input::get_singleton();
|
||||||
|
if (!(input->is_action_pressed("ui_up") || input->is_action_pressed("ui_down") || input->is_action_pressed("ui_left") || input->is_action_pressed("ui_right"))) {
|
||||||
|
cursor_editing = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current_shape == SHAPE_HSV_WHEEL) {
|
||||||
|
wheel_focus_mode = wheel->has_focus() ? 2 : 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColorPicker::_picker_shape_focus_exited() {
|
||||||
|
cursor_editing = false;
|
||||||
|
if (wheel_focus_mode == 2) {
|
||||||
|
wheel_uv->queue_redraw();
|
||||||
|
}
|
||||||
|
wheel_focus_mode = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void ColorPicker::_update_controls() {
|
void ColorPicker::_update_controls() {
|
||||||
int mode_sliders_count = modes[current_mode]->get_slider_count();
|
int mode_sliders_count = modes[current_mode]->get_slider_count();
|
||||||
|
|
||||||
|
|
@ -309,15 +383,33 @@ void ColorPicker::_update_controls() {
|
||||||
alpha_label->hide();
|
alpha_label->hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool pre_update_cursor_editing = cursor_editing;
|
||||||
switch (current_shape) {
|
switch (current_shape) {
|
||||||
case SHAPE_HSV_RECTANGLE:
|
case SHAPE_HSV_RECTANGLE:
|
||||||
wheel_edit->hide();
|
|
||||||
w_edit->show();
|
w_edit->show();
|
||||||
uv_edit->show();
|
uv_edit->show();
|
||||||
btn_shape->show();
|
btn_shape->show();
|
||||||
|
|
||||||
|
if (wheel_focus_mode == 1) {
|
||||||
|
uv_edit->grab_focus();
|
||||||
|
} else if (wheel_focus_mode == 2) {
|
||||||
|
w_edit->grab_focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
wheel_edit->hide();
|
||||||
|
wheel->set_focus_mode(FOCUS_NONE);
|
||||||
break;
|
break;
|
||||||
case SHAPE_HSV_WHEEL:
|
case SHAPE_HSV_WHEEL:
|
||||||
wheel_edit->show();
|
wheel_edit->show();
|
||||||
|
wheel->set_focus_mode(FOCUS_ALL);
|
||||||
|
|
||||||
|
if (w_edit->has_focus()) {
|
||||||
|
wheel_focus_mode = 2;
|
||||||
|
wheel->grab_focus();
|
||||||
|
} else if (uv_edit->has_focus()) {
|
||||||
|
wheel_uv->grab_focus();
|
||||||
|
}
|
||||||
|
|
||||||
w_edit->hide();
|
w_edit->hide();
|
||||||
uv_edit->hide();
|
uv_edit->hide();
|
||||||
btn_shape->show();
|
btn_shape->show();
|
||||||
|
|
@ -326,20 +418,37 @@ void ColorPicker::_update_controls() {
|
||||||
case SHAPE_VHS_CIRCLE:
|
case SHAPE_VHS_CIRCLE:
|
||||||
wheel_edit->show();
|
wheel_edit->show();
|
||||||
w_edit->show();
|
w_edit->show();
|
||||||
|
|
||||||
|
if (uv_edit->has_focus()) {
|
||||||
|
wheel_uv->grab_focus();
|
||||||
|
} else if (wheel->has_focus()) {
|
||||||
|
w_edit->grab_focus();
|
||||||
|
}
|
||||||
|
|
||||||
uv_edit->hide();
|
uv_edit->hide();
|
||||||
btn_shape->show();
|
btn_shape->show();
|
||||||
wheel->set_material(circle_mat);
|
wheel->set_material(circle_mat);
|
||||||
circle_mat->set_shader(circle_shader);
|
circle_mat->set_shader(circle_shader);
|
||||||
|
wheel->set_focus_mode(FOCUS_NONE);
|
||||||
break;
|
break;
|
||||||
case SHAPE_OKHSL_CIRCLE:
|
case SHAPE_OKHSL_CIRCLE:
|
||||||
wheel_edit->show();
|
wheel_edit->show();
|
||||||
w_edit->show();
|
w_edit->show();
|
||||||
|
|
||||||
|
if (uv_edit->has_focus()) {
|
||||||
|
wheel_uv->grab_focus();
|
||||||
|
} else if (wheel->has_focus()) {
|
||||||
|
w_edit->grab_focus();
|
||||||
|
}
|
||||||
|
|
||||||
uv_edit->hide();
|
uv_edit->hide();
|
||||||
btn_shape->show();
|
btn_shape->show();
|
||||||
wheel->set_material(circle_mat);
|
wheel->set_material(circle_mat);
|
||||||
circle_mat->set_shader(circle_ok_color_shader);
|
circle_mat->set_shader(circle_ok_color_shader);
|
||||||
|
wheel->set_focus_mode(FOCUS_NONE);
|
||||||
break;
|
break;
|
||||||
case SHAPE_NONE:
|
case SHAPE_NONE:
|
||||||
|
wheel->set_focus_mode(FOCUS_NONE);
|
||||||
wheel_edit->hide();
|
wheel_edit->hide();
|
||||||
w_edit->hide();
|
w_edit->hide();
|
||||||
uv_edit->hide();
|
uv_edit->hide();
|
||||||
|
|
@ -348,6 +457,8 @@ void ColorPicker::_update_controls() {
|
||||||
default: {
|
default: {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cursor_editing = pre_update_cursor_editing;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorPicker::_set_pick_color(const Color &p_color, bool p_update_sliders) {
|
void ColorPicker::_set_pick_color(const Color &p_color, bool p_update_sliders) {
|
||||||
|
|
@ -423,6 +534,8 @@ void ColorPicker::_slider_value_changed() {
|
||||||
ok_hsl_h = color.get_ok_hsl_h();
|
ok_hsl_h = color.get_ok_hsl_h();
|
||||||
ok_hsl_s = color.get_ok_hsl_s();
|
ok_hsl_s = color.get_ok_hsl_s();
|
||||||
ok_hsl_l = color.get_ok_hsl_l();
|
ok_hsl_l = color.get_ok_hsl_l();
|
||||||
|
|
||||||
|
circle_keyboard_joypad_picker_cursor_position = Vector2i();
|
||||||
last_color = color;
|
last_color = color;
|
||||||
} else if (current_mode == MODE_OKHSL) {
|
} else if (current_mode == MODE_OKHSL) {
|
||||||
ok_hsl_h = sliders[0]->get_value() / 360.0;
|
ok_hsl_h = sliders[0]->get_value() / 360.0;
|
||||||
|
|
@ -431,6 +544,8 @@ void ColorPicker::_slider_value_changed() {
|
||||||
h = color.get_h();
|
h = color.get_h();
|
||||||
s = color.get_s();
|
s = color.get_s();
|
||||||
v = color.get_v();
|
v = color.get_v();
|
||||||
|
|
||||||
|
circle_keyboard_joypad_picker_cursor_position = Vector2i();
|
||||||
last_color = color;
|
last_color = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -801,6 +916,7 @@ void ColorPicker::set_picker_shape(PickerShapeType p_shape) {
|
||||||
btn_shape->set_button_icon(shape_popup->get_item_icon(p_shape));
|
btn_shape->set_button_icon(shape_popup->get_item_icon(p_shape));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
circle_keyboard_joypad_picker_cursor_position = Vector2i();
|
||||||
current_shape = p_shape;
|
current_shape = p_shape;
|
||||||
|
|
||||||
#ifdef TOOLS_ENABLED
|
#ifdef TOOLS_ENABLED
|
||||||
|
|
@ -973,6 +1089,7 @@ void ColorPicker::_set_mode_popup_value(ColorModeType p_mode) {
|
||||||
} else {
|
} else {
|
||||||
set_color_mode(p_mode);
|
set_color_mode(p_mode);
|
||||||
}
|
}
|
||||||
|
circle_keyboard_joypad_picker_cursor_position = Vector2i();
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant ColorPicker::_get_drag_data_fw(const Point2 &p_point, Control *p_from_control) {
|
Variant ColorPicker::_get_drag_data_fw(const Point2 &p_point, Control *p_from_control) {
|
||||||
|
|
@ -1078,6 +1195,9 @@ void ColorPicker::erase_preset(const Color &p_color) {
|
||||||
ColorPresetButton *current_btn = Object::cast_to<ColorPresetButton>(preset_container->get_child(i));
|
ColorPresetButton *current_btn = Object::cast_to<ColorPresetButton>(preset_container->get_child(i));
|
||||||
if (current_btn && p_color == current_btn->get_preset_color()) {
|
if (current_btn && p_color == current_btn->get_preset_color()) {
|
||||||
current_btn->queue_free();
|
current_btn->queue_free();
|
||||||
|
// Removing focused control loose the focus totally. We focus on previous button to keep it possible to navigate with keyboard/joypad.
|
||||||
|
Control *focus_target = Object::cast_to<Control>(preset_container->get_child(i - 1));
|
||||||
|
focus_target->grab_focus();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1263,21 +1383,29 @@ void ColorPicker::_sample_input(const Ref<InputEvent> &p_event) {
|
||||||
if (rect_old.has_point(mb->get_position())) {
|
if (rect_old.has_point(mb->get_position())) {
|
||||||
// Revert to the old color when left-clicking the old color sample.
|
// Revert to the old color when left-clicking the old color sample.
|
||||||
set_pick_color(old_color);
|
set_pick_color(old_color);
|
||||||
|
|
||||||
|
sample->set_focus_mode(FOCUS_NONE);
|
||||||
emit_signal(SNAME("color_changed"), color);
|
emit_signal(SNAME("color_changed"), color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (p_event->is_action_pressed(SNAME("ui_accept"), false, true)) {
|
||||||
|
set_pick_color(old_color);
|
||||||
|
emit_signal(SNAME("color_changed"), color);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorPicker::_sample_draw() {
|
void ColorPicker::_sample_draw() {
|
||||||
// Covers the right half of the sample if the old color is being displayed,
|
// Covers the right half of the sample if the old color is being displayed,
|
||||||
// or the whole sample if it's not being displayed.
|
// or the whole sample if it's not being displayed.
|
||||||
Rect2 rect_new;
|
Rect2 rect_new;
|
||||||
|
Rect2 rect_old;
|
||||||
|
|
||||||
if (display_old_color) {
|
if (display_old_color) {
|
||||||
rect_new = Rect2(Point2(sample->get_size().width * 0.5, 0), Size2(sample->get_size().width * 0.5, sample->get_size().height * 0.95));
|
rect_new = Rect2(Point2(sample->get_size().width * 0.5, 0), Size2(sample->get_size().width * 0.5, sample->get_size().height * 0.95));
|
||||||
|
|
||||||
// Draw both old and new colors for easier comparison (only if spawned from a ColorPickerButton).
|
// Draw both old and new colors for easier comparison (only if spawned from a ColorPickerButton).
|
||||||
const Rect2 rect_old = Rect2(Point2(), Size2(sample->get_size().width * 0.5, sample->get_size().height * 0.95));
|
rect_old = Rect2(Point2(), Size2(sample->get_size().width * 0.5, sample->get_size().height * 0.95));
|
||||||
|
|
||||||
if (old_color.a < 1.0) {
|
if (old_color.a < 1.0) {
|
||||||
sample->draw_texture_rect(theme_cache.sample_bg, rect_old, true);
|
sample->draw_texture_rect(theme_cache.sample_bg, rect_old, true);
|
||||||
|
|
@ -1291,6 +1419,10 @@ void ColorPicker::_sample_draw() {
|
||||||
sample->draw_texture(theme_cache.sample_revert,
|
sample->draw_texture(theme_cache.sample_revert,
|
||||||
rect_old.size * 0.5 - theme_cache.sample_revert->get_size() * 0.5,
|
rect_old.size * 0.5 - theme_cache.sample_revert->get_size() * 0.5,
|
||||||
Math::lerp(0.75f, old_color.get_luminance(), old_color.a) < 0.455 ? Color(1, 1, 1) : (Color(0.01, 0.01, 0.01)));
|
Math::lerp(0.75f, old_color.get_luminance(), old_color.a) < 0.455 ? Color(1, 1, 1) : (Color(0.01, 0.01, 0.01)));
|
||||||
|
|
||||||
|
sample->set_focus_mode(FOCUS_ALL);
|
||||||
|
} else {
|
||||||
|
sample->set_focus_mode(FOCUS_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (old_color.r > 1 || old_color.g > 1 || old_color.b > 1) {
|
if (old_color.r > 1 || old_color.g > 1 || old_color.b > 1) {
|
||||||
|
|
@ -1307,16 +1439,43 @@ void ColorPicker::_sample_draw() {
|
||||||
|
|
||||||
sample->draw_rect(rect_new, color);
|
sample->draw_rect(rect_new, color);
|
||||||
|
|
||||||
|
if (display_old_color && !old_color.is_equal_approx(color) && sample->has_focus()) {
|
||||||
|
RID ci = sample->get_canvas_item();
|
||||||
|
theme_cache.sample_focus->draw(ci, rect_old);
|
||||||
|
}
|
||||||
|
|
||||||
if (color.r > 1 || color.g > 1 || color.b > 1) {
|
if (color.r > 1 || color.g > 1 || color.b > 1) {
|
||||||
// Draw an indicator to denote that the new color is "overbright" and can't be displayed accurately in the preview.
|
// Draw an indicator to denote that the new color is "overbright" and can't be displayed accurately in the preview.
|
||||||
sample->draw_texture(theme_cache.overbright_indicator, Point2(display_old_color ? sample->get_size().width * 0.5 : 0, 0));
|
sample->draw_texture(theme_cache.overbright_indicator, Point2(display_old_color ? sample->get_size().width * 0.5 : 0, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ColorPicker::_draw_focus_stylebox(Control *p_c, Rect2 p_focus_rect, Ref<StyleBox> &p_focus_stylebox) {
|
||||||
|
if (p_c->has_focus()) {
|
||||||
|
RID ci = p_c->get_canvas_item();
|
||||||
|
if (wheel_focus_mode == 2) {
|
||||||
|
ci = wheel_uv->get_canvas_item();
|
||||||
|
p_focus_stylebox = theme_cache.picker_focus_circle;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cursor_editing) {
|
||||||
|
Color not_editing_color = theme_cache.focused_not_editing_cursor_color;
|
||||||
|
if (p_focus_stylebox == theme_cache.picker_focus_circle) {
|
||||||
|
RenderingServer::get_singleton()->canvas_item_add_circle(ci, p_focus_rect.get_center(), p_focus_rect.size.y / 2, not_editing_color);
|
||||||
|
} else {
|
||||||
|
RenderingServer::get_singleton()->canvas_item_add_rect(ci, p_focus_rect, not_editing_color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p_focus_stylebox->draw(ci, p_focus_rect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ColorPicker::_hsv_draw(int p_which, Control *c) {
|
void ColorPicker::_hsv_draw(int p_which, Control *c) {
|
||||||
if (!c) {
|
if (!c) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Rect2 focus_rect = Rect2(Point2(), c->get_size());
|
||||||
|
Ref<StyleBox> focus_stylebox = theme_cache.picker_focus_rectangle;
|
||||||
|
|
||||||
if (p_which == 0) {
|
if (p_which == 0) {
|
||||||
Color col = color;
|
Color col = color;
|
||||||
|
|
@ -1372,6 +1531,8 @@ void ColorPicker::_hsv_draw(int p_which, Control *c) {
|
||||||
}
|
}
|
||||||
x = center.x + hue_offset.x - (theme_cache.picker_cursor->get_width() / 2);
|
x = center.x + hue_offset.x - (theme_cache.picker_cursor->get_width() / 2);
|
||||||
y = center.y + hue_offset.y - (theme_cache.picker_cursor->get_height() / 2);
|
y = center.y + hue_offset.y - (theme_cache.picker_cursor->get_height() / 2);
|
||||||
|
|
||||||
|
focus_stylebox = theme_cache.picker_focus_circle;
|
||||||
} else {
|
} else {
|
||||||
real_t corner_x = (c == wheel_uv) ? center.x - Math_SQRT12 * c->get_size().width * WHEEL_RADIUS : 0;
|
real_t corner_x = (c == wheel_uv) ? center.x - Math_SQRT12 * c->get_size().width * WHEEL_RADIUS : 0;
|
||||||
real_t corner_y = (c == wheel_uv) ? center.y - Math_SQRT12 * c->get_size().height * WHEEL_RADIUS : 0;
|
real_t corner_y = (c == wheel_uv) ? center.y - Math_SQRT12 * c->get_size().height * WHEEL_RADIUS : 0;
|
||||||
|
|
@ -1379,7 +1540,11 @@ void ColorPicker::_hsv_draw(int p_which, Control *c) {
|
||||||
Size2 real_size(c->get_size().x - corner_x * 2, c->get_size().y - corner_y * 2);
|
Size2 real_size(c->get_size().x - corner_x * 2, c->get_size().y - corner_y * 2);
|
||||||
x = CLAMP(real_size.x * s, 0, real_size.x) + corner_x - (theme_cache.picker_cursor->get_width() / 2);
|
x = CLAMP(real_size.x * s, 0, real_size.x) + corner_x - (theme_cache.picker_cursor->get_width() / 2);
|
||||||
y = CLAMP(real_size.y - real_size.y * v, 0, real_size.y) + corner_y - (theme_cache.picker_cursor->get_height() / 2);
|
y = CLAMP(real_size.y - real_size.y * v, 0, real_size.y) + corner_y - (theme_cache.picker_cursor->get_height() / 2);
|
||||||
|
if (c == wheel_uv) {
|
||||||
|
focus_rect = Rect2(Point2(corner_x, corner_y), real_size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
_draw_focus_stylebox(c, focus_rect, focus_stylebox);
|
||||||
Color _col = color;
|
Color _col = color;
|
||||||
_col.a = 1.0;
|
_col.a = 1.0;
|
||||||
c->draw_texture(theme_cache.picker_cursor_bg, Point2(x, y), _col);
|
c->draw_texture(theme_cache.picker_cursor_bg, Point2(x, y), _col);
|
||||||
|
|
@ -1400,6 +1565,7 @@ void ColorPicker::_hsv_draw(int p_which, Control *c) {
|
||||||
int y = c->get_size().y - c->get_size().y * (1.0 - h);
|
int y = c->get_size().y - c->get_size().y * (1.0 - h);
|
||||||
Color col;
|
Color col;
|
||||||
col.set_hsv(h, 1, 1);
|
col.set_hsv(h, 1, 1);
|
||||||
|
_draw_focus_stylebox(c, focus_rect, focus_stylebox);
|
||||||
c->draw_line(Point2(0, y), Point2(c->get_size().x, y), col.inverted());
|
c->draw_line(Point2(0, y), Point2(c->get_size().x, y), col.inverted());
|
||||||
} else if (current_shape == SHAPE_OKHSL_CIRCLE) {
|
} else if (current_shape == SHAPE_OKHSL_CIRCLE) {
|
||||||
Vector<Point2> points;
|
Vector<Point2> points;
|
||||||
|
|
@ -1427,6 +1593,7 @@ void ColorPicker::_hsv_draw(int p_which, Control *c) {
|
||||||
c->draw_polygon(points, colors);
|
c->draw_polygon(points, colors);
|
||||||
int y = c->get_size().y - c->get_size().y * CLAMP(ok_hsl_l, 0, 1);
|
int y = c->get_size().y - c->get_size().y * CLAMP(ok_hsl_l, 0, 1);
|
||||||
col.set_ok_hsl(ok_hsl_h, 1, ok_hsl_l);
|
col.set_ok_hsl(ok_hsl_h, 1, ok_hsl_l);
|
||||||
|
_draw_focus_stylebox(c, focus_rect, focus_stylebox);
|
||||||
c->draw_line(Point2(0, y), Point2(c->get_size().x, y), col.inverted());
|
c->draw_line(Point2(0, y), Point2(c->get_size().x, y), col.inverted());
|
||||||
} else if (current_shape == SHAPE_VHS_CIRCLE) {
|
} else if (current_shape == SHAPE_VHS_CIRCLE) {
|
||||||
Vector<Point2> points;
|
Vector<Point2> points;
|
||||||
|
|
@ -1446,6 +1613,7 @@ void ColorPicker::_hsv_draw(int p_which, Control *c) {
|
||||||
c->draw_polygon(points, colors);
|
c->draw_polygon(points, colors);
|
||||||
int y = c->get_size().y - c->get_size().y * CLAMP(v, 0, 1);
|
int y = c->get_size().y - c->get_size().y * CLAMP(v, 0, 1);
|
||||||
col.set_hsv(h, 1, v);
|
col.set_hsv(h, 1, v);
|
||||||
|
_draw_focus_stylebox(c, focus_rect, focus_stylebox);
|
||||||
c->draw_line(Point2(0, y), Point2(c->get_size().x, y), col.inverted());
|
c->draw_line(Point2(0, y), Point2(c->get_size().x, y), col.inverted());
|
||||||
}
|
}
|
||||||
} else if (p_which == 2) {
|
} else if (p_which == 2) {
|
||||||
|
|
@ -1455,6 +1623,10 @@ void ColorPicker::_hsv_draw(int p_which, Control *c) {
|
||||||
} else if (current_shape == SHAPE_OKHSL_CIRCLE) {
|
} else if (current_shape == SHAPE_OKHSL_CIRCLE) {
|
||||||
circle_mat->set_shader_parameter("ok_hsl_l", ok_hsl_l);
|
circle_mat->set_shader_parameter("ok_hsl_l", ok_hsl_l);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (wheel_focus_mode == 2) {
|
||||||
|
_draw_focus_stylebox(c, focus_rect, focus_stylebox);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1464,7 +1636,153 @@ void ColorPicker::_slider_draw(int p_which) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ColorPicker::_get_edge_h_change(const Vector2 &p_color_change_vector) {
|
||||||
|
int h_change = 0;
|
||||||
|
|
||||||
|
if (h > 0 && h < 0.5) {
|
||||||
|
h_change -= p_color_change_vector.x;
|
||||||
|
} else if (h > 0.5 && h < 1) {
|
||||||
|
h_change += p_color_change_vector.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (h > 0.25 && h < 0.75) {
|
||||||
|
h_change -= p_color_change_vector.y;
|
||||||
|
} else if (h < 0.25 || h > 0.75) {
|
||||||
|
h_change += p_color_change_vector.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
return h_change;
|
||||||
|
}
|
||||||
|
|
||||||
|
float ColorPicker::_get_h_on_circle_edge(const Vector2 &p_color_change_vector) {
|
||||||
|
int h_change = _get_edge_h_change(p_color_change_vector);
|
||||||
|
|
||||||
|
float target_h = Math::wrapf(h + h_change / 360.0, 0, 1);
|
||||||
|
int current_quarter = h * 4;
|
||||||
|
int future_quarter = target_h * 4;
|
||||||
|
if (p_color_change_vector.y > 0 && ((future_quarter == 0 && current_quarter == 1) || (future_quarter == 1 && current_quarter == 0))) {
|
||||||
|
target_h = 0.25f;
|
||||||
|
} else if (p_color_change_vector.y < 0 && ((future_quarter == 2 && current_quarter == 3) || (future_quarter == 3 && current_quarter == 2))) {
|
||||||
|
target_h = 0.75f;
|
||||||
|
} else if (p_color_change_vector.x < 0 && ((future_quarter == 1 && current_quarter == 2) || (future_quarter == 2 && current_quarter == 1))) {
|
||||||
|
target_h = 0.5f;
|
||||||
|
} else if (p_color_change_vector.x > 0 && ((future_quarter == 3 && current_quarter == 0) || (future_quarter == 0 && current_quarter == 3))) {
|
||||||
|
target_h = 0;
|
||||||
|
}
|
||||||
|
return target_h;
|
||||||
|
}
|
||||||
|
|
||||||
|
float ColorPicker::_get_h_on_wheel(const Vector2 &p_color_change_vector) {
|
||||||
|
int h_change = _get_edge_h_change(p_color_change_vector);
|
||||||
|
|
||||||
|
float target_h = Math::wrapf(h + h_change / 360.0, 0, 1);
|
||||||
|
int current_quarter = h * 4;
|
||||||
|
int future_quarter = target_h * 4;
|
||||||
|
|
||||||
|
if (p_color_change_vector.y > 0 && ((future_quarter == 0 && current_quarter == 1) || (future_quarter == 1 && current_quarter == 0))) {
|
||||||
|
rotate_next_echo_event = !rotate_next_echo_event;
|
||||||
|
} else if (p_color_change_vector.y < 0 && ((future_quarter == 2 && current_quarter == 3) || (future_quarter == 3 && current_quarter == 2))) {
|
||||||
|
rotate_next_echo_event = !rotate_next_echo_event;
|
||||||
|
} else if (p_color_change_vector.x < 0 && ((future_quarter == 1 && current_quarter == 2) || (future_quarter == 2 && current_quarter == 1))) {
|
||||||
|
rotate_next_echo_event = !rotate_next_echo_event;
|
||||||
|
} else if (p_color_change_vector.x > 0 && ((future_quarter == 3 && current_quarter == 0) || (future_quarter == 0 && current_quarter == 3))) {
|
||||||
|
rotate_next_echo_event = !rotate_next_echo_event;
|
||||||
|
}
|
||||||
|
|
||||||
|
return target_h;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColorPicker::_update_uv_cursor(Vector2 &p_color_change_vector, bool p_is_echo) {
|
||||||
|
echo_multiplier = p_is_echo ? CLAMP(echo_multiplier * echo_multiplier_step, 1, 25) : 1;
|
||||||
|
|
||||||
|
if (!p_color_change_vector.is_zero_approx()) {
|
||||||
|
p_color_change_vector *= echo_multiplier;
|
||||||
|
|
||||||
|
if (current_shape == SHAPE_HSV_RECTANGLE) {
|
||||||
|
s = CLAMP(s + p_color_change_vector.x / 100.0, 0, 1);
|
||||||
|
v = CLAMP(v - p_color_change_vector.y / 100.0, 0, 1);
|
||||||
|
} else if (current_shape == SHAPE_VHS_CIRCLE || current_shape == SHAPE_OKHSL_CIRCLE) {
|
||||||
|
Vector2 center = wheel_uv->get_size() / 2.0;
|
||||||
|
|
||||||
|
if (circle_keyboard_joypad_picker_cursor_position == Vector2i()) {
|
||||||
|
Vector2 hue_offset;
|
||||||
|
if (current_shape == SHAPE_OKHSL_CIRCLE) {
|
||||||
|
hue_offset = center * Vector2(Math::cos(ok_hsl_h * Math_TAU), Math::sin(ok_hsl_h * Math_TAU)) * ok_hsl_s;
|
||||||
|
} else {
|
||||||
|
hue_offset = center * Vector2(Math::cos(h * Math_TAU), Math::sin(h * Math_TAU)) * s;
|
||||||
|
}
|
||||||
|
circle_keyboard_joypad_picker_cursor_position = center + hue_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2i potential_cursor_position = circle_keyboard_joypad_picker_cursor_position + p_color_change_vector;
|
||||||
|
real_t potential_new_cursor_distance = center.distance_to(potential_cursor_position);
|
||||||
|
real_t dist_pre = center.distance_to(circle_keyboard_joypad_picker_cursor_position);
|
||||||
|
if (s < 1 || potential_new_cursor_distance < dist_pre) {
|
||||||
|
circle_keyboard_joypad_picker_cursor_position += p_color_change_vector;
|
||||||
|
real_t dist = center.distance_to(circle_keyboard_joypad_picker_cursor_position);
|
||||||
|
real_t rad = center.angle_to_point(circle_keyboard_joypad_picker_cursor_position);
|
||||||
|
h = ((rad >= 0) ? rad : (Math_TAU + rad)) / Math_TAU;
|
||||||
|
s = CLAMP(dist / center.x, 0, 1);
|
||||||
|
} else {
|
||||||
|
h = _get_h_on_circle_edge(p_color_change_vector);
|
||||||
|
circle_keyboard_joypad_picker_cursor_position = Vector2i();
|
||||||
|
}
|
||||||
|
|
||||||
|
ok_hsl_h = h;
|
||||||
|
ok_hsl_s = s;
|
||||||
|
} else if (current_shape == SHAPE_HSV_WHEEL) {
|
||||||
|
if (wheel_focus_mode == 1) {
|
||||||
|
s = CLAMP(s + p_color_change_vector.x / 100.0, 0, 1);
|
||||||
|
v = CLAMP(v - p_color_change_vector.y / 100.0, 0, 1);
|
||||||
|
} else if (wheel_focus_mode == 2) {
|
||||||
|
if (p_is_echo && rotate_next_echo_event) {
|
||||||
|
p_color_change_vector *= -1;
|
||||||
|
} else {
|
||||||
|
rotate_next_echo_event = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
h = _get_h_on_wheel(p_color_change_vector);
|
||||||
|
wheel_uv->queue_redraw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_copy_hsv_to_color();
|
||||||
|
last_color = color;
|
||||||
|
set_pick_color(color);
|
||||||
|
|
||||||
|
emit_signal(SNAME("color_changed"), color);
|
||||||
|
} else {
|
||||||
|
echo_multiplier = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
accept_event();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColorPicker::_update_cursor_editing(const Ref<InputEvent> &p_event, Control *p_c) {
|
||||||
|
if (p_event->is_action_pressed("ui_accept", false, true)) {
|
||||||
|
cursor_editing = !cursor_editing;
|
||||||
|
accept_event();
|
||||||
|
|
||||||
|
if (wheel_focus_mode == 2) {
|
||||||
|
wheel_uv->queue_redraw();
|
||||||
|
}
|
||||||
|
p_c->queue_redraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cursor_editing && p_event->is_action_pressed("ui_cancel", false, true)) {
|
||||||
|
cursor_editing = false;
|
||||||
|
accept_event();
|
||||||
|
|
||||||
|
if (wheel_focus_mode == 2) {
|
||||||
|
wheel_uv->queue_redraw();
|
||||||
|
}
|
||||||
|
p_c->queue_redraw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ColorPicker::_uv_input(const Ref<InputEvent> &p_event, Control *c) {
|
void ColorPicker::_uv_input(const Ref<InputEvent> &p_event, Control *c) {
|
||||||
|
_update_cursor_editing(p_event, c);
|
||||||
|
|
||||||
Ref<InputEventMouseButton> bev = p_event;
|
Ref<InputEventMouseButton> bev = p_event;
|
||||||
|
|
||||||
if (bev.is_valid()) {
|
if (bev.is_valid()) {
|
||||||
|
|
@ -1478,6 +1796,7 @@ void ColorPicker::_uv_input(const Ref<InputEvent> &p_event, Control *c) {
|
||||||
s = CLAMP(dist / center.x, 0, 1);
|
s = CLAMP(dist / center.x, 0, 1);
|
||||||
ok_hsl_h = h;
|
ok_hsl_h = h;
|
||||||
ok_hsl_s = s;
|
ok_hsl_s = s;
|
||||||
|
circle_keyboard_joypad_picker_cursor_position = Vector2i();
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -1490,11 +1809,12 @@ void ColorPicker::_uv_input(const Ref<InputEvent> &p_event, Control *c) {
|
||||||
bev->get_position().y < corner_y || bev->get_position().y > c->get_size().y - corner_y) {
|
bev->get_position().y < corner_y || bev->get_position().y > c->get_size().y - corner_y) {
|
||||||
{
|
{
|
||||||
real_t dist = center.distance_to(bev->get_position());
|
real_t dist = center.distance_to(bev->get_position());
|
||||||
|
|
||||||
if (dist >= center.x * 0.84 && dist <= center.x) {
|
if (dist >= center.x * 0.84 && dist <= center.x) {
|
||||||
real_t rad = center.angle_to_point(bev->get_position());
|
real_t rad = center.angle_to_point(bev->get_position());
|
||||||
h = ((rad >= 0) ? rad : (Math_TAU + rad)) / Math_TAU;
|
h = ((rad >= 0) ? rad : (Math_TAU + rad)) / Math_TAU;
|
||||||
spinning = true;
|
spinning = true;
|
||||||
|
wheel->grab_focus();
|
||||||
|
wheel_uv->queue_redraw();
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -1507,6 +1827,7 @@ void ColorPicker::_uv_input(const Ref<InputEvent> &p_event, Control *c) {
|
||||||
|
|
||||||
s = x / real_size.x;
|
s = x / real_size.x;
|
||||||
v = 1.0 - y / real_size.y;
|
v = 1.0 - y / real_size.y;
|
||||||
|
wheel_focus_mode = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1547,10 +1868,12 @@ void ColorPicker::_uv_input(const Ref<InputEvent> &p_event, Control *c) {
|
||||||
s = CLAMP(dist / center.x, 0, 1);
|
s = CLAMP(dist / center.x, 0, 1);
|
||||||
ok_hsl_h = h;
|
ok_hsl_h = h;
|
||||||
ok_hsl_s = s;
|
ok_hsl_s = s;
|
||||||
|
circle_keyboard_joypad_picker_cursor_position = Vector2i();
|
||||||
} else {
|
} else {
|
||||||
if (spinning) {
|
if (spinning) {
|
||||||
real_t rad = center.angle_to_point(mev->get_position());
|
real_t rad = center.angle_to_point(mev->get_position());
|
||||||
h = ((rad >= 0) ? rad : (Math_TAU + rad)) / Math_TAU;
|
h = ((rad >= 0) ? rad : (Math_TAU + rad)) / Math_TAU;
|
||||||
|
wheel_uv->queue_redraw();
|
||||||
} else {
|
} else {
|
||||||
real_t corner_x = (c == wheel_uv) ? center.x - Math_SQRT12 * c->get_size().width * 0.42 : 0;
|
real_t corner_x = (c == wheel_uv) ? center.x - Math_SQRT12 * c->get_size().width * 0.42 : 0;
|
||||||
real_t corner_y = (c == wheel_uv) ? center.y - Math_SQRT12 * c->get_size().height * 0.42 : 0;
|
real_t corner_y = (c == wheel_uv) ? center.y - Math_SQRT12 * c->get_size().height * 0.42 : 0;
|
||||||
|
|
@ -1572,9 +1895,64 @@ void ColorPicker::_uv_input(const Ref<InputEvent> &p_event, Control *c) {
|
||||||
emit_signal(SNAME("color_changed"), color);
|
emit_signal(SNAME("color_changed"), color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!cursor_editing) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<InputEventJoypadMotion> joypadmotion_event = p_event;
|
||||||
|
Ref<InputEventJoypadButton> joypadbutton_event = p_event;
|
||||||
|
bool is_joypad_event = (joypadmotion_event.is_valid() || joypadbutton_event.is_valid());
|
||||||
|
bool is_echo = p_event->is_echo();
|
||||||
|
|
||||||
|
if (p_event->is_action_pressed("ui_left", true) ||
|
||||||
|
p_event->is_action_pressed("ui_right", true) ||
|
||||||
|
p_event->is_action_pressed("ui_up", true) ||
|
||||||
|
p_event->is_action_pressed("ui_down", true)) {
|
||||||
|
if (is_joypad_event) {
|
||||||
|
// Make sure moving joypad axis further in the same direction is not handled here, as NOTIFICATION_INTERNAL_PROCESS will handle it.
|
||||||
|
if (is_processing_internal()) {
|
||||||
|
accept_event();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
set_process_internal(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Treat any input from joypad axis as -1, 0, or 1, as the value is added to Vector2i and would be lost.
|
||||||
|
Vector2 color_change_vector = Vector2(
|
||||||
|
p_event->is_action_pressed("ui_right", true) - p_event->is_action_pressed("ui_left", true),
|
||||||
|
p_event->is_action_pressed("ui_down", true) - p_event->is_action_pressed("ui_up", true));
|
||||||
|
_update_uv_cursor(color_change_vector, is_echo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColorPicker::_update_w_cursor(float p_color_change, bool p_is_echo) {
|
||||||
|
echo_multiplier = p_is_echo ? CLAMP(echo_multiplier * echo_multiplier_step, 1, 25) : 1;
|
||||||
|
|
||||||
|
if (!Math::is_zero_approx(p_color_change)) {
|
||||||
|
p_color_change *= echo_multiplier;
|
||||||
|
if (current_shape == SHAPE_HSV_RECTANGLE) {
|
||||||
|
h = CLAMP(h + p_color_change / 360.0, 0, 1);
|
||||||
|
} else if (current_shape == SHAPE_VHS_CIRCLE || current_shape == SHAPE_OKHSL_CIRCLE) {
|
||||||
|
v = CLAMP(v - p_color_change / 100.0, 0, 1);
|
||||||
|
ok_hsl_l = CLAMP(ok_hsl_l - p_color_change / 100.0, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
_copy_hsv_to_color();
|
||||||
|
last_color = color;
|
||||||
|
set_pick_color(color);
|
||||||
|
|
||||||
|
emit_signal(SNAME("color_changed"), color);
|
||||||
|
} else {
|
||||||
|
echo_multiplier = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
accept_event();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorPicker::_w_input(const Ref<InputEvent> &p_event) {
|
void ColorPicker::_w_input(const Ref<InputEvent> &p_event) {
|
||||||
|
_update_cursor_editing(p_event, w_edit);
|
||||||
|
|
||||||
Ref<InputEventMouseButton> bev = p_event;
|
Ref<InputEventMouseButton> bev = p_event;
|
||||||
|
|
||||||
if (bev.is_valid()) {
|
if (bev.is_valid()) {
|
||||||
|
|
@ -1625,6 +2003,27 @@ void ColorPicker::_w_input(const Ref<InputEvent> &p_event) {
|
||||||
emit_signal(SNAME("color_changed"), color);
|
emit_signal(SNAME("color_changed"), color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!cursor_editing) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<InputEventJoypadMotion> joypadmotion_event = p_event;
|
||||||
|
Ref<InputEventJoypadButton> joypadbutton_event = p_event;
|
||||||
|
bool is_joypad_event = (joypadmotion_event.is_valid() || joypadbutton_event.is_valid());
|
||||||
|
bool is_echo = p_event->is_echo();
|
||||||
|
|
||||||
|
if (p_event->is_action_pressed("ui_left", true) ||
|
||||||
|
p_event->is_action_pressed("ui_right", true) ||
|
||||||
|
p_event->is_action_pressed("ui_up", true) ||
|
||||||
|
p_event->is_action_pressed("ui_down", true)) {
|
||||||
|
if (is_joypad_event) {
|
||||||
|
set_process_internal(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
float color_change = Input::get_singleton()->get_axis("ui_up", "ui_down");
|
||||||
|
_update_w_cursor(color_change, is_echo);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorPicker::_slider_or_spin_input(const Ref<InputEvent> &p_event) {
|
void ColorPicker::_slider_or_spin_input(const Ref<InputEvent> &p_event) {
|
||||||
|
|
@ -1658,6 +2057,15 @@ void ColorPicker::_preset_input(const Ref<InputEvent> &p_event, const Color &p_c
|
||||||
emit_signal(SNAME("preset_removed"), p_color);
|
emit_signal(SNAME("preset_removed"), p_color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (p_event->is_action_pressed(SNAME("ui_accept"), false, true)) {
|
||||||
|
set_pick_color(p_color);
|
||||||
|
add_recent_preset(color);
|
||||||
|
emit_signal(SNAME("color_changed"), p_color);
|
||||||
|
} else if (p_event->is_action_pressed(SNAME("ui_colorpicker_delete_preset"), false, true) && can_add_swatches) {
|
||||||
|
erase_preset(p_color);
|
||||||
|
emit_signal(SNAME("preset_removed"), p_color);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorPicker::_recent_preset_pressed(const bool p_pressed, ColorPresetButton *p_preset) {
|
void ColorPicker::_recent_preset_pressed(const bool p_pressed, ColorPresetButton *p_preset) {
|
||||||
|
|
@ -1869,6 +2277,18 @@ void ColorPicker::_options_menu_cbk(int p_which) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ColorPicker::_block_input_on_popup_show() {
|
||||||
|
if (!get_tree()->get_root()->is_embedding_subwindows()) {
|
||||||
|
get_viewport()->set_disable_input(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColorPicker::_enable_input_on_popup_hide() {
|
||||||
|
if (!get_tree()->get_root()->is_embedding_subwindows()) {
|
||||||
|
get_viewport()->set_disable_input(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ColorPicker::_pick_button_pressed_legacy() {
|
void ColorPicker::_pick_button_pressed_legacy() {
|
||||||
if (!is_inside_tree()) {
|
if (!is_inside_tree()) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -2014,6 +2434,7 @@ void ColorPicker::_html_focus_exit() {
|
||||||
} else {
|
} else {
|
||||||
_update_text_value();
|
_update_text_value();
|
||||||
}
|
}
|
||||||
|
circle_keyboard_joypad_picker_cursor_position = Vector2i();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorPicker::set_can_add_swatches(bool p_enabled) {
|
void ColorPicker::set_can_add_swatches(bool p_enabled) {
|
||||||
|
|
@ -2160,6 +2581,10 @@ void ColorPicker::_bind_methods() {
|
||||||
BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, ColorPicker, h_width);
|
BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, ColorPicker, h_width);
|
||||||
|
|
||||||
BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, ColorPicker, center_slider_grabbers);
|
BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, ColorPicker, center_slider_grabbers);
|
||||||
|
BIND_THEME_ITEM(Theme::DATA_TYPE_STYLEBOX, ColorPicker, sample_focus);
|
||||||
|
BIND_THEME_ITEM(Theme::DATA_TYPE_STYLEBOX, ColorPicker, picker_focus_rectangle);
|
||||||
|
BIND_THEME_ITEM(Theme::DATA_TYPE_STYLEBOX, ColorPicker, picker_focus_circle);
|
||||||
|
BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, ColorPicker, focused_not_editing_cursor_color);
|
||||||
|
|
||||||
BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, ColorPicker, menu_option);
|
BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, ColorPicker, menu_option);
|
||||||
BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, ColorPicker, screen_picker);
|
BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, ColorPicker, screen_picker);
|
||||||
|
|
@ -2199,9 +2624,12 @@ ColorPicker::ColorPicker() {
|
||||||
hb_edit->add_child(uv_edit);
|
hb_edit->add_child(uv_edit);
|
||||||
uv_edit->connect(SceneStringName(gui_input), callable_mp(this, &ColorPicker::_uv_input).bind(uv_edit));
|
uv_edit->connect(SceneStringName(gui_input), callable_mp(this, &ColorPicker::_uv_input).bind(uv_edit));
|
||||||
uv_edit->set_mouse_filter(MOUSE_FILTER_PASS);
|
uv_edit->set_mouse_filter(MOUSE_FILTER_PASS);
|
||||||
|
uv_edit->set_focus_mode(FOCUS_ALL);
|
||||||
uv_edit->set_h_size_flags(SIZE_EXPAND_FILL);
|
uv_edit->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||||
uv_edit->set_v_size_flags(SIZE_EXPAND_FILL);
|
uv_edit->set_v_size_flags(SIZE_EXPAND_FILL);
|
||||||
uv_edit->connect(SceneStringName(draw), callable_mp(this, &ColorPicker::_hsv_draw).bind(0, uv_edit));
|
uv_edit->connect(SceneStringName(draw), callable_mp(this, &ColorPicker::_hsv_draw).bind(0, uv_edit));
|
||||||
|
uv_edit->connect(SceneStringName(focus_entered), callable_mp(this, &ColorPicker::_picker_shape_focus_entered));
|
||||||
|
uv_edit->connect(SceneStringName(focus_exited), callable_mp(this, &ColorPicker::_picker_shape_focus_exited));
|
||||||
|
|
||||||
sample_hbc = memnew(HBoxContainer);
|
sample_hbc = memnew(HBoxContainer);
|
||||||
real_vbox->add_child(sample_hbc);
|
real_vbox->add_child(sample_hbc);
|
||||||
|
|
@ -2222,6 +2650,7 @@ ColorPicker::ColorPicker() {
|
||||||
btn_shape->set_toggle_mode(true);
|
btn_shape->set_toggle_mode(true);
|
||||||
btn_shape->set_tooltip_text(ETR("Select a picker shape."));
|
btn_shape->set_tooltip_text(ETR("Select a picker shape."));
|
||||||
btn_shape->set_icon_alignment(HORIZONTAL_ALIGNMENT_CENTER);
|
btn_shape->set_icon_alignment(HORIZONTAL_ALIGNMENT_CENTER);
|
||||||
|
btn_shape->set_focus_mode(FOCUS_ALL);
|
||||||
|
|
||||||
current_shape = SHAPE_HSV_RECTANGLE;
|
current_shape = SHAPE_HSV_RECTANGLE;
|
||||||
|
|
||||||
|
|
@ -2232,6 +2661,8 @@ ColorPicker::ColorPicker() {
|
||||||
shape_popup->add_radio_check_item("OKHSL Circle", SHAPE_OKHSL_CIRCLE);
|
shape_popup->add_radio_check_item("OKHSL Circle", SHAPE_OKHSL_CIRCLE);
|
||||||
shape_popup->set_item_checked(current_shape, true);
|
shape_popup->set_item_checked(current_shape, true);
|
||||||
shape_popup->connect(SceneStringName(id_pressed), callable_mp(this, &ColorPicker::set_picker_shape));
|
shape_popup->connect(SceneStringName(id_pressed), callable_mp(this, &ColorPicker::set_picker_shape));
|
||||||
|
shape_popup->connect("about_to_popup", callable_mp(this, &ColorPicker::_block_input_on_popup_show));
|
||||||
|
shape_popup->connect(SNAME("popup_hide"), callable_mp(this, &ColorPicker::_enable_input_on_popup_hide));
|
||||||
|
|
||||||
add_mode(new ColorModeRGB(this));
|
add_mode(new ColorModeRGB(this));
|
||||||
add_mode(new ColorModeHSV(this));
|
add_mode(new ColorModeHSV(this));
|
||||||
|
|
@ -2246,7 +2677,7 @@ ColorPicker::ColorPicker() {
|
||||||
for (int i = 0; i < MODE_BUTTON_COUNT; i++) {
|
for (int i = 0; i < MODE_BUTTON_COUNT; i++) {
|
||||||
mode_btns[i] = memnew(Button);
|
mode_btns[i] = memnew(Button);
|
||||||
mode_hbc->add_child(mode_btns[i]);
|
mode_hbc->add_child(mode_btns[i]);
|
||||||
mode_btns[i]->set_focus_mode(FOCUS_NONE);
|
mode_btns[i]->set_focus_mode(FOCUS_ALL);
|
||||||
mode_btns[i]->set_h_size_flags(SIZE_EXPAND_FILL);
|
mode_btns[i]->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||||
mode_btns[i]->set_toggle_mode(true);
|
mode_btns[i]->set_toggle_mode(true);
|
||||||
mode_btns[i]->set_text(modes[i]->get_name());
|
mode_btns[i]->set_text(modes[i]->get_name());
|
||||||
|
|
@ -2261,6 +2692,7 @@ ColorPicker::ColorPicker() {
|
||||||
mode_hbc->add_child(btn_mode);
|
mode_hbc->add_child(btn_mode);
|
||||||
btn_mode->set_toggle_mode(true);
|
btn_mode->set_toggle_mode(true);
|
||||||
btn_mode->set_tooltip_text(ETR("Select a picker mode."));
|
btn_mode->set_tooltip_text(ETR("Select a picker mode."));
|
||||||
|
btn_mode->set_focus_mode(FOCUS_ALL);
|
||||||
|
|
||||||
current_mode = MODE_RGB;
|
current_mode = MODE_RGB;
|
||||||
|
|
||||||
|
|
@ -2273,6 +2705,8 @@ ColorPicker::ColorPicker() {
|
||||||
mode_popup->set_item_checked(current_mode, true);
|
mode_popup->set_item_checked(current_mode, true);
|
||||||
mode_popup->set_item_checked(MODE_MAX + 1, true);
|
mode_popup->set_item_checked(MODE_MAX + 1, true);
|
||||||
mode_popup->connect(SceneStringName(id_pressed), callable_mp(this, &ColorPicker::_set_mode_popup_value));
|
mode_popup->connect(SceneStringName(id_pressed), callable_mp(this, &ColorPicker::_set_mode_popup_value));
|
||||||
|
mode_popup->connect("about_to_popup", callable_mp(this, &ColorPicker::_block_input_on_popup_show));
|
||||||
|
mode_popup->connect(SNAME("popup_hide"), callable_mp(this, &ColorPicker::_enable_input_on_popup_hide));
|
||||||
|
|
||||||
slider_gc = memnew(GridContainer);
|
slider_gc = memnew(GridContainer);
|
||||||
|
|
||||||
|
|
@ -2300,6 +2734,7 @@ ColorPicker::ColorPicker() {
|
||||||
text_type->connect(SceneStringName(pressed), callable_mp(this, &ColorPicker::_text_type_toggled));
|
text_type->connect(SceneStringName(pressed), callable_mp(this, &ColorPicker::_text_type_toggled));
|
||||||
} else {
|
} else {
|
||||||
text_type->set_flat(true);
|
text_type->set_flat(true);
|
||||||
|
text_type->set_focus_mode(FOCUS_NONE);
|
||||||
text_type->set_mouse_filter(MOUSE_FILTER_IGNORE);
|
text_type->set_mouse_filter(MOUSE_FILTER_IGNORE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2332,18 +2767,27 @@ ColorPicker::ColorPicker() {
|
||||||
wheel_margin->add_child(wheel);
|
wheel_margin->add_child(wheel);
|
||||||
wheel->set_mouse_filter(MOUSE_FILTER_PASS);
|
wheel->set_mouse_filter(MOUSE_FILTER_PASS);
|
||||||
wheel->connect(SceneStringName(draw), callable_mp(this, &ColorPicker::_hsv_draw).bind(2, wheel));
|
wheel->connect(SceneStringName(draw), callable_mp(this, &ColorPicker::_hsv_draw).bind(2, wheel));
|
||||||
|
wheel->connect(SceneStringName(gui_input), callable_mp(this, &ColorPicker::_uv_input).bind(wheel));
|
||||||
|
wheel->connect(SceneStringName(focus_entered), callable_mp(this, &ColorPicker::_picker_shape_focus_entered));
|
||||||
|
wheel->connect(SceneStringName(focus_exited), callable_mp(this, &ColorPicker::_picker_shape_focus_exited));
|
||||||
|
|
||||||
wheel_uv = memnew(Control);
|
wheel_uv = memnew(Control);
|
||||||
wheel_margin->add_child(wheel_uv);
|
wheel_margin->add_child(wheel_uv);
|
||||||
|
wheel_uv->set_focus_mode(FOCUS_ALL);
|
||||||
wheel_uv->connect(SceneStringName(gui_input), callable_mp(this, &ColorPicker::_uv_input).bind(wheel_uv));
|
wheel_uv->connect(SceneStringName(gui_input), callable_mp(this, &ColorPicker::_uv_input).bind(wheel_uv));
|
||||||
wheel_uv->connect(SceneStringName(draw), callable_mp(this, &ColorPicker::_hsv_draw).bind(0, wheel_uv));
|
wheel_uv->connect(SceneStringName(draw), callable_mp(this, &ColorPicker::_hsv_draw).bind(0, wheel_uv));
|
||||||
|
wheel_uv->connect(SceneStringName(focus_entered), callable_mp(this, &ColorPicker::_picker_shape_focus_entered));
|
||||||
|
wheel_uv->connect(SceneStringName(focus_exited), callable_mp(this, &ColorPicker::_picker_shape_focus_exited));
|
||||||
|
|
||||||
w_edit = memnew(Control);
|
w_edit = memnew(Control);
|
||||||
hb_edit->add_child(w_edit);
|
hb_edit->add_child(w_edit);
|
||||||
|
w_edit->set_focus_mode(FOCUS_ALL);
|
||||||
w_edit->set_h_size_flags(SIZE_FILL);
|
w_edit->set_h_size_flags(SIZE_FILL);
|
||||||
w_edit->set_v_size_flags(SIZE_EXPAND_FILL);
|
w_edit->set_v_size_flags(SIZE_EXPAND_FILL);
|
||||||
w_edit->connect(SceneStringName(gui_input), callable_mp(this, &ColorPicker::_w_input));
|
w_edit->connect(SceneStringName(gui_input), callable_mp(this, &ColorPicker::_w_input));
|
||||||
w_edit->connect(SceneStringName(draw), callable_mp(this, &ColorPicker::_hsv_draw).bind(1, w_edit));
|
w_edit->connect(SceneStringName(draw), callable_mp(this, &ColorPicker::_hsv_draw).bind(1, w_edit));
|
||||||
|
w_edit->connect(SceneStringName(focus_entered), callable_mp(this, &ColorPicker::_picker_shape_focus_entered));
|
||||||
|
w_edit->connect(SceneStringName(focus_exited), callable_mp(this, &ColorPicker::_picker_shape_focus_exited));
|
||||||
|
|
||||||
_update_controls();
|
_update_controls();
|
||||||
updating = false;
|
updating = false;
|
||||||
|
|
@ -2366,7 +2810,7 @@ ColorPicker::ColorPicker() {
|
||||||
btn_preset->set_text("Swatches");
|
btn_preset->set_text("Swatches");
|
||||||
btn_preset->set_flat(true);
|
btn_preset->set_flat(true);
|
||||||
btn_preset->set_toggle_mode(true);
|
btn_preset->set_toggle_mode(true);
|
||||||
btn_preset->set_focus_mode(FOCUS_NONE);
|
btn_preset->set_focus_mode(FOCUS_ALL);
|
||||||
btn_preset->set_text_alignment(HORIZONTAL_ALIGNMENT_LEFT);
|
btn_preset->set_text_alignment(HORIZONTAL_ALIGNMENT_LEFT);
|
||||||
btn_preset->set_h_size_flags(SIZE_EXPAND_FILL);
|
btn_preset->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||||
btn_preset->connect(SceneStringName(toggled), callable_mp(this, &ColorPicker::_show_hide_preset).bind(btn_preset, preset_container));
|
btn_preset->connect(SceneStringName(toggled), callable_mp(this, &ColorPicker::_show_hide_preset).bind(btn_preset, preset_container));
|
||||||
|
|
@ -2374,12 +2818,15 @@ ColorPicker::ColorPicker() {
|
||||||
|
|
||||||
menu_btn = memnew(MenuButton);
|
menu_btn = memnew(MenuButton);
|
||||||
menu_btn->set_flat(true);
|
menu_btn->set_flat(true);
|
||||||
|
menu_btn->set_focus_mode(FOCUS_ALL);
|
||||||
menu_btn->set_tooltip_text(ETR("Show all options available."));
|
menu_btn->set_tooltip_text(ETR("Show all options available."));
|
||||||
menu_btn->connect("about_to_popup", callable_mp(this, &ColorPicker::_update_menu_items));
|
menu_btn->connect("about_to_popup", callable_mp(this, &ColorPicker::_update_menu_items));
|
||||||
palette_box->add_child(menu_btn);
|
palette_box->add_child(menu_btn);
|
||||||
|
|
||||||
options_menu = menu_btn->get_popup();
|
options_menu = menu_btn->get_popup();
|
||||||
options_menu->connect(SceneStringName(id_pressed), callable_mp(this, &ColorPicker::_options_menu_cbk));
|
options_menu->connect(SceneStringName(id_pressed), callable_mp(this, &ColorPicker::_options_menu_cbk));
|
||||||
|
options_menu->connect("about_to_popup", callable_mp(this, &ColorPicker::_block_input_on_popup_show));
|
||||||
|
options_menu->connect(SNAME("popup_hide"), callable_mp(this, &ColorPicker::_enable_input_on_popup_hide));
|
||||||
|
|
||||||
palette_name = memnew(Label);
|
palette_name = memnew(Label);
|
||||||
palette_name->hide();
|
palette_name->hide();
|
||||||
|
|
@ -2397,7 +2844,7 @@ ColorPicker::ColorPicker() {
|
||||||
btn_recent_preset = memnew(Button(ETR("Recent Colors")));
|
btn_recent_preset = memnew(Button(ETR("Recent Colors")));
|
||||||
btn_recent_preset->set_flat(true);
|
btn_recent_preset->set_flat(true);
|
||||||
btn_recent_preset->set_toggle_mode(true);
|
btn_recent_preset->set_toggle_mode(true);
|
||||||
btn_recent_preset->set_focus_mode(FOCUS_NONE);
|
btn_recent_preset->set_focus_mode(FOCUS_ALL);
|
||||||
btn_recent_preset->set_text_alignment(HORIZONTAL_ALIGNMENT_LEFT);
|
btn_recent_preset->set_text_alignment(HORIZONTAL_ALIGNMENT_LEFT);
|
||||||
btn_recent_preset->connect(SceneStringName(toggled), callable_mp(this, &ColorPicker::_show_hide_preset).bind(btn_recent_preset, recent_preset_hbc));
|
btn_recent_preset->connect(SceneStringName(toggled), callable_mp(this, &ColorPicker::_show_hide_preset).bind(btn_recent_preset, recent_preset_hbc));
|
||||||
swatches_vbc->add_child(btn_recent_preset);
|
swatches_vbc->add_child(btn_recent_preset);
|
||||||
|
|
@ -2431,6 +2878,9 @@ void ColorPickerPopupPanel::_input_from_window(const Ref<InputEvent> &p_event) {
|
||||||
/////////////////
|
/////////////////
|
||||||
|
|
||||||
void ColorPickerButton::_about_to_popup() {
|
void ColorPickerButton::_about_to_popup() {
|
||||||
|
if (!get_tree()->get_root()->is_embedding_subwindows()) {
|
||||||
|
get_viewport()->set_disable_input(true);
|
||||||
|
}
|
||||||
set_pressed(true);
|
set_pressed(true);
|
||||||
if (picker) {
|
if (picker) {
|
||||||
picker->set_old_color(color);
|
picker->set_old_color(color);
|
||||||
|
|
@ -2450,6 +2900,9 @@ void ColorPickerButton::_modal_closed() {
|
||||||
}
|
}
|
||||||
emit_signal(SNAME("popup_closed"));
|
emit_signal(SNAME("popup_closed"));
|
||||||
set_pressed(false);
|
set_pressed(false);
|
||||||
|
if (!get_tree()->get_root()->is_embedding_subwindows()) {
|
||||||
|
get_viewport()->set_disable_input(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorPickerButton::pressed() {
|
void ColorPickerButton::pressed() {
|
||||||
|
|
@ -2473,7 +2926,9 @@ void ColorPickerButton::pressed() {
|
||||||
float v_offset = show_above ? -minsize.y : get_size().y;
|
float v_offset = show_above ? -minsize.y : get_size().y;
|
||||||
popup->set_position(get_screen_position() + Vector2(h_offset, v_offset));
|
popup->set_position(get_screen_position() + Vector2(h_offset, v_offset));
|
||||||
popup->popup();
|
popup->popup();
|
||||||
if (DisplayServer::get_singleton()->has_hardware_keyboard()) {
|
if (!picker->is_hex_visible() && picker->get_picker_shape() != ColorPicker::SHAPE_NONE) {
|
||||||
|
callable_mp(picker, &ColorPicker::set_focus_on_picker_shape).call_deferred();
|
||||||
|
} else if (DisplayServer::get_singleton()->has_hardware_keyboard()) {
|
||||||
picker->set_focus_on_line_edit();
|
picker->set_focus_on_line_edit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2633,6 +3088,12 @@ void ColorPresetButton::_notification(int p_what) {
|
||||||
} else {
|
} else {
|
||||||
WARN_PRINT("Unsupported StyleBox used for ColorPresetButton. Use StyleBoxFlat or StyleBoxTexture instead.");
|
WARN_PRINT("Unsupported StyleBox used for ColorPresetButton. Use StyleBoxFlat or StyleBoxTexture instead.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (has_focus()) {
|
||||||
|
RID ci = get_canvas_item();
|
||||||
|
theme_cache.focus_style->draw(ci, Rect2(Point2(), get_size()));
|
||||||
|
}
|
||||||
|
|
||||||
if (preset_color.r > 1 || preset_color.g > 1 || preset_color.b > 1) {
|
if (preset_color.r > 1 || preset_color.g > 1 || preset_color.b > 1) {
|
||||||
// Draw an indicator to denote that the color is "overbright" and can't be displayed accurately in the preview
|
// Draw an indicator to denote that the color is "overbright" and can't be displayed accurately in the preview
|
||||||
draw_texture(theme_cache.overbright_indicator, Vector2(0, 0));
|
draw_texture(theme_cache.overbright_indicator, Vector2(0, 0));
|
||||||
|
|
@ -2652,6 +3113,7 @@ Color ColorPresetButton::get_preset_color() const {
|
||||||
|
|
||||||
void ColorPresetButton::_bind_methods() {
|
void ColorPresetButton::_bind_methods() {
|
||||||
BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_STYLEBOX, ColorPresetButton, foreground_style, "preset_fg");
|
BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_STYLEBOX, ColorPresetButton, foreground_style, "preset_fg");
|
||||||
|
BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_STYLEBOX, ColorPresetButton, focus_style, "preset_focus");
|
||||||
BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_ICON, ColorPresetButton, background_icon, "preset_bg");
|
BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_ICON, ColorPresetButton, background_icon, "preset_bg");
|
||||||
BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, ColorPresetButton, overbright_indicator);
|
BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, ColorPresetButton, overbright_indicator);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,7 @@ class ColorPresetButton : public BaseButton {
|
||||||
|
|
||||||
struct ThemeCache {
|
struct ThemeCache {
|
||||||
Ref<StyleBox> foreground_style;
|
Ref<StyleBox> foreground_style;
|
||||||
|
Ref<StyleBox> focus_style;
|
||||||
|
|
||||||
Ref<Texture2D> background_icon;
|
Ref<Texture2D> background_icon;
|
||||||
Ref<Texture2D> overbright_indicator;
|
Ref<Texture2D> overbright_indicator;
|
||||||
|
|
@ -125,6 +126,16 @@ private:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int current_slider_count = SLIDER_COUNT;
|
int current_slider_count = SLIDER_COUNT;
|
||||||
|
Vector2i circle_keyboard_joypad_picker_cursor_position;
|
||||||
|
float echo_multiplier = 1;
|
||||||
|
float echo_multiplier_step = 1.1;
|
||||||
|
bool rotate_next_echo_event = false;
|
||||||
|
|
||||||
|
const float DEFAULT_GAMEPAD_EVENT_DELAY_MS = 1.0 / 2;
|
||||||
|
const float GAMEPAD_EVENT_REPEAT_RATE_MS = 1.0 / 30;
|
||||||
|
float gamepad_event_delay_ms = DEFAULT_GAMEPAD_EVENT_DELAY_MS;
|
||||||
|
bool cursor_editing = false;
|
||||||
|
int wheel_focus_mode = 0;
|
||||||
static const int MODE_BUTTON_COUNT = 3;
|
static const int MODE_BUTTON_COUNT = 3;
|
||||||
const float WHEEL_RADIUS = 0.42;
|
const float WHEEL_RADIUS = 0.42;
|
||||||
|
|
||||||
|
|
@ -250,6 +261,9 @@ private:
|
||||||
|
|
||||||
bool center_slider_grabbers = true;
|
bool center_slider_grabbers = true;
|
||||||
|
|
||||||
|
Ref<StyleBox> picker_focus_rectangle;
|
||||||
|
Ref<StyleBox> picker_focus_circle;
|
||||||
|
Color focused_not_editing_cursor_color;
|
||||||
Ref<Texture2D> menu_option;
|
Ref<Texture2D> menu_option;
|
||||||
Ref<Texture2D> screen_picker;
|
Ref<Texture2D> screen_picker;
|
||||||
Ref<Texture2D> expanded_arrow;
|
Ref<Texture2D> expanded_arrow;
|
||||||
|
|
@ -263,6 +277,7 @@ private:
|
||||||
Ref<Texture2D> bar_arrow;
|
Ref<Texture2D> bar_arrow;
|
||||||
Ref<Texture2D> sample_bg;
|
Ref<Texture2D> sample_bg;
|
||||||
Ref<Texture2D> sample_revert;
|
Ref<Texture2D> sample_revert;
|
||||||
|
Ref<StyleBox> sample_focus;
|
||||||
Ref<Texture2D> overbright_indicator;
|
Ref<Texture2D> overbright_indicator;
|
||||||
Ref<Texture2D> picker_cursor;
|
Ref<Texture2D> picker_cursor;
|
||||||
Ref<Texture2D> picker_cursor_bg;
|
Ref<Texture2D> picker_cursor_bg;
|
||||||
|
|
@ -289,10 +304,17 @@ private:
|
||||||
void _text_type_toggled();
|
void _text_type_toggled();
|
||||||
void _sample_input(const Ref<InputEvent> &p_event);
|
void _sample_input(const Ref<InputEvent> &p_event);
|
||||||
void _sample_draw();
|
void _sample_draw();
|
||||||
|
void _draw_focus_stylebox(Control *p_c, Rect2 p_focus_rect, Ref<StyleBox> &p_focus_stylebox);
|
||||||
void _hsv_draw(int p_which, Control *c);
|
void _hsv_draw(int p_which, Control *c);
|
||||||
void _slider_draw(int p_which);
|
void _slider_draw(int p_which);
|
||||||
|
int _get_edge_h_change(const Vector2 &p_color_change_vector);
|
||||||
|
float _get_h_on_circle_edge(const Vector2 &p_color_change_vector);
|
||||||
|
float _get_h_on_wheel(const Vector2 &p_color_change_vector);
|
||||||
|
void _update_uv_cursor(Vector2 &p_color_change_vector, bool p_is_echo);
|
||||||
|
void _update_cursor_editing(const Ref<InputEvent> &p_event, Control *p_c);
|
||||||
|
|
||||||
void _uv_input(const Ref<InputEvent> &p_event, Control *c);
|
void _uv_input(const Ref<InputEvent> &p_event, Control *c);
|
||||||
|
void _update_w_cursor(float p_color_change, bool p_is_echo);
|
||||||
void _w_input(const Ref<InputEvent> &p_event);
|
void _w_input(const Ref<InputEvent> &p_event);
|
||||||
void _slider_or_spin_input(const Ref<InputEvent> &p_event);
|
void _slider_or_spin_input(const Ref<InputEvent> &p_event);
|
||||||
void _line_edit_input(const Ref<InputEvent> &p_event);
|
void _line_edit_input(const Ref<InputEvent> &p_event);
|
||||||
|
|
@ -306,6 +328,8 @@ private:
|
||||||
void _pick_finished();
|
void _pick_finished();
|
||||||
void _update_menu_items();
|
void _update_menu_items();
|
||||||
void _options_menu_cbk(int p_which);
|
void _options_menu_cbk(int p_which);
|
||||||
|
void _block_input_on_popup_show();
|
||||||
|
void _enable_input_on_popup_hide();
|
||||||
|
|
||||||
// Legacy color picking.
|
// Legacy color picking.
|
||||||
void _pick_button_pressed_legacy();
|
void _pick_button_pressed_legacy();
|
||||||
|
|
@ -403,7 +427,10 @@ public:
|
||||||
bool is_hex_visible() const;
|
bool is_hex_visible() const;
|
||||||
|
|
||||||
void set_focus_on_line_edit();
|
void set_focus_on_line_edit();
|
||||||
|
void set_focus_on_picker_shape();
|
||||||
|
|
||||||
|
void _picker_shape_focus_entered();
|
||||||
|
void _picker_shape_focus_exited();
|
||||||
ColorPicker();
|
ColorPicker();
|
||||||
~ColorPicker();
|
~ColorPicker();
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1040,6 +1040,9 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
|
||||||
theme->set_constant("separation", "VSeparator", Math::round(4 * scale));
|
theme->set_constant("separation", "VSeparator", Math::round(4 * scale));
|
||||||
|
|
||||||
// ColorPicker
|
// ColorPicker
|
||||||
|
Ref<StyleBoxFlat> focus_circle = make_flat_stylebox(style_focus_color, default_margin, default_margin, default_margin, default_margin, default_corner_radius, false, 2);
|
||||||
|
focus_circle->set_corner_radius_all(Math::round(256 * scale));
|
||||||
|
focus_circle->set_corner_detail(Math::round(32 * scale));
|
||||||
|
|
||||||
theme->set_constant("margin", "ColorPicker", Math::round(4 * scale));
|
theme->set_constant("margin", "ColorPicker", Math::round(4 * scale));
|
||||||
theme->set_constant("sv_width", "ColorPicker", Math::round(256 * scale));
|
theme->set_constant("sv_width", "ColorPicker", Math::round(256 * scale));
|
||||||
|
|
@ -1048,6 +1051,11 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
|
||||||
theme->set_constant("label_width", "ColorPicker", Math::round(10 * scale));
|
theme->set_constant("label_width", "ColorPicker", Math::round(10 * scale));
|
||||||
theme->set_constant("center_slider_grabbers", "ColorPicker", 1);
|
theme->set_constant("center_slider_grabbers", "ColorPicker", 1);
|
||||||
|
|
||||||
|
theme->set_stylebox("sample_focus", "ColorPicker", focus);
|
||||||
|
theme->set_stylebox("picker_focus_rectangle", "ColorPicker", focus);
|
||||||
|
theme->set_stylebox("picker_focus_circle", "ColorPicker", focus_circle);
|
||||||
|
theme->set_color("focused_not_editing_cursor_color", "ColorPicker", Color(1, 1, 1, 0.275f));
|
||||||
|
|
||||||
theme->set_icon("menu_option", "ColorPicker", icons["tabs_menu_hl"]);
|
theme->set_icon("menu_option", "ColorPicker", icons["tabs_menu_hl"]);
|
||||||
theme->set_icon("folded_arrow", "ColorPicker", icons["arrow_right"]);
|
theme->set_icon("folded_arrow", "ColorPicker", icons["arrow_right"]);
|
||||||
theme->set_icon("expanded_arrow", "ColorPicker", icons["arrow_down"]);
|
theme->set_icon("expanded_arrow", "ColorPicker", icons["arrow_down"]);
|
||||||
|
|
@ -1120,6 +1128,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
|
||||||
preset_sb->set_anti_aliased(false);
|
preset_sb->set_anti_aliased(false);
|
||||||
|
|
||||||
theme->set_stylebox("preset_fg", "ColorPresetButton", preset_sb);
|
theme->set_stylebox("preset_fg", "ColorPresetButton", preset_sb);
|
||||||
|
theme->set_stylebox("preset_focus", "ColorPicker", focus);
|
||||||
theme->set_icon("preset_bg", "ColorPresetButton", icons["mini_checkerboard"]);
|
theme->set_icon("preset_bg", "ColorPresetButton", icons["mini_checkerboard"]);
|
||||||
theme->set_icon("overbright_indicator", "ColorPresetButton", icons["color_picker_overbright"]);
|
theme->set_icon("overbright_indicator", "ColorPresetButton", icons["color_picker_overbright"]);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue