You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-04 12:00:25 +00:00
ColorPicker: Add okhsl HS and HL rectangular picker shapes
This commit is contained in:
@@ -144,6 +144,12 @@
|
||||
<constant name="SHAPE_NONE" value="4" enum="PickerShapeType">
|
||||
The color space shape and the shape select button are hidden. Can't be selected from the shapes popup.
|
||||
</constant>
|
||||
<constant name="SHAPE_OK_HS_RECTANGLE" value="5" enum="PickerShapeType">
|
||||
OKHSL Color Model rectangle with constant lightness.
|
||||
</constant>
|
||||
<constant name="SHAPE_OK_HL_RECTANGLE" value="6" enum="PickerShapeType">
|
||||
OKHSL Color Model rectangle with constant saturation.
|
||||
</constant>
|
||||
</constants>
|
||||
<theme_items>
|
||||
<theme_item name="focused_not_editing_cursor_color" data_type="color" type="Color" default="Color(1, 1, 1, 0.275)">
|
||||
|
||||
@@ -569,7 +569,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
|
||||
_initial_set("interface/inspector/resources_to_open_in_new_inspector", open_in_new_inspector_defaults);
|
||||
|
||||
EDITOR_SETTING_BASIC(Variant::INT, PROPERTY_HINT_ENUM, "interface/inspector/default_color_picker_mode", (int32_t)ColorPicker::MODE_RGB, "RGB,HSV,RAW,OKHSL")
|
||||
EDITOR_SETTING_BASIC(Variant::INT, PROPERTY_HINT_ENUM, "interface/inspector/default_color_picker_shape", (int32_t)ColorPicker::SHAPE_OKHSL_CIRCLE, "HSV Rectangle,HSV Rectangle Wheel,VHS Circle,OKHSL Circle")
|
||||
EDITOR_SETTING_BASIC(Variant::INT, PROPERTY_HINT_ENUM, "interface/inspector/default_color_picker_shape", (int32_t)ColorPicker::SHAPE_OKHSL_CIRCLE, "HSV Rectangle,HSV Rectangle Wheel,VHS Circle,OKHSL Circle,OK HS Rectangle:5,OK HL Rectangle") // `SHAPE_NONE` is 4.
|
||||
EDITOR_SETTING_BASIC(Variant::BOOL, PROPERTY_HINT_NONE, "interface/inspector/color_picker_show_intensity", true, "");
|
||||
|
||||
// Theme
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "editor/gui/editor_toaster.h"
|
||||
#include "editor/plugins/editor_context_menu_plugin.h"
|
||||
#include "editor/themes/editor_scale.h"
|
||||
#include "scene/gui/grid_container.h"
|
||||
#include "scene/gui/menu_button.h"
|
||||
#include "scene/gui/rich_text_label.h"
|
||||
#include "scene/gui/slider.h"
|
||||
@@ -2845,7 +2846,7 @@ ScriptTextEditor::ScriptTextEditor() {
|
||||
inline_color_options->set_text_overrun_behavior(TextServer::OVERRUN_TRIM_ELLIPSIS);
|
||||
inline_color_options->set_fit_to_longest_item(false);
|
||||
inline_color_options->connect("item_selected", callable_mp(this, &ScriptTextEditor::_update_color_text).unbind(1));
|
||||
inline_color_picker->get_slider(ColorPicker::SLIDER_COUNT)->get_parent()->add_sibling(inline_color_options);
|
||||
inline_color_picker->get_slider_container()->add_sibling(inline_color_options);
|
||||
|
||||
connection_info_dialog = memnew(ConnectionInfoDialog);
|
||||
|
||||
|
||||
@@ -139,10 +139,10 @@ void ColorPicker::_notification(int p_what) {
|
||||
}
|
||||
|
||||
if (current_shape != SHAPE_NONE) {
|
||||
btn_shape->set_button_icon(shape_popup->get_item_icon(current_shape));
|
||||
btn_shape->set_button_icon(shape_popup->get_item_icon(get_current_shape_index()));
|
||||
}
|
||||
|
||||
for (int i = 0; i < SLIDER_COUNT; i++) {
|
||||
for (int i = 0; i < MODE_SLIDER_COUNT; i++) {
|
||||
labels[i]->set_custom_minimum_size(Size2(theme_cache.label_width, 0));
|
||||
sliders[i]->add_theme_constant_override(SNAME("center_grabber"), theme_cache.center_slider_grabbers);
|
||||
}
|
||||
@@ -185,7 +185,7 @@ void ColorPicker::_notification(int p_what) {
|
||||
case NOTIFICATION_FOCUS_ENTER:
|
||||
case NOTIFICATION_FOCUS_EXIT: {
|
||||
if (current_shape != SHAPE_NONE) {
|
||||
shapes[current_shape]->cursor_editing = false;
|
||||
shapes[get_current_shape_index()]->cursor_editing = false;
|
||||
}
|
||||
} break;
|
||||
|
||||
@@ -198,7 +198,7 @@ void ColorPicker::_notification(int p_what) {
|
||||
input->is_action_just_released("ui_down")) {
|
||||
gamepad_event_delay_ms = DEFAULT_GAMEPAD_EVENT_DELAY_MS;
|
||||
if (current_shape == SHAPE_NONE) {
|
||||
shapes[current_shape]->echo_multiplier = 1;
|
||||
shapes[get_current_shape_index()]->echo_multiplier = 1;
|
||||
}
|
||||
accept_event();
|
||||
set_process_internal(false);
|
||||
@@ -217,7 +217,7 @@ void ColorPicker::_notification(int p_what) {
|
||||
input->is_action_pressed("ui_right") - input->is_action_pressed("ui_left"),
|
||||
input->is_action_pressed("ui_down") - input->is_action_pressed("ui_up"));
|
||||
|
||||
shapes[current_shape]->update_cursor(color_change_vector, true);
|
||||
shapes[get_current_shape_index()]->update_cursor(color_change_vector, true);
|
||||
accept_event();
|
||||
}
|
||||
return;
|
||||
@@ -309,7 +309,7 @@ void fragment() {
|
||||
|
||||
circle_ok_color_shader.instantiate();
|
||||
circle_ok_color_shader->set_code(OK_COLOR_SHADER + R"(
|
||||
// ColorPicker ok color hsv circle shader.
|
||||
// ColorPicker ok color hsl circle shader.
|
||||
|
||||
uniform float ok_hsl_l = 1.0;
|
||||
|
||||
@@ -330,12 +330,40 @@ void fragment() {
|
||||
float b4 = float(sqrt(x * x + y * y) < 0.5);
|
||||
COLOR = vec4(col, (b + b2 + b3 + b4) / 4.00);
|
||||
})");
|
||||
|
||||
rectangle_ok_color_hs_shader.instantiate();
|
||||
rectangle_ok_color_hs_shader->set_code(OK_COLOR_SHADER + R"(
|
||||
// ColorPicker ok color hs rectangle shader.
|
||||
|
||||
uniform float ok_hsl_l = 0.0;
|
||||
|
||||
void fragment() {
|
||||
float h = UV.x;
|
||||
float s = 1.0 - UV.y;
|
||||
vec3 col = okhsl_to_srgb(vec3(h, s, ok_hsl_l));
|
||||
COLOR = vec4(col, 1.0);
|
||||
})");
|
||||
|
||||
rectangle_ok_color_hl_shader.instantiate();
|
||||
rectangle_ok_color_hl_shader->set_code(OK_COLOR_SHADER + R"(
|
||||
// ColorPicker ok color hl rectangle shader.
|
||||
|
||||
uniform float ok_hsl_s = 0.0;
|
||||
|
||||
void fragment() {
|
||||
float h = UV.x;
|
||||
float l = 1.0 - UV.y;
|
||||
vec3 col = okhsl_to_srgb(vec3(h, ok_hsl_s, l));
|
||||
COLOR = vec4(col, 1.0);
|
||||
})");
|
||||
}
|
||||
|
||||
void ColorPicker::finish_shaders() {
|
||||
wheel_shader.unref();
|
||||
circle_shader.unref();
|
||||
circle_ok_color_shader.unref();
|
||||
rectangle_ok_color_hs_shader.unref();
|
||||
rectangle_ok_color_hl_shader.unref();
|
||||
}
|
||||
|
||||
void ColorPicker::set_focus_on_line_edit() {
|
||||
@@ -343,7 +371,7 @@ void ColorPicker::set_focus_on_line_edit() {
|
||||
}
|
||||
|
||||
void ColorPicker::set_focus_on_picker_shape() {
|
||||
shapes[current_shape]->grab_focus();
|
||||
shapes[get_current_shape_index()]->grab_focus();
|
||||
}
|
||||
|
||||
void ColorPicker::_update_controls() {
|
||||
@@ -384,7 +412,7 @@ void ColorPicker::_update_controls() {
|
||||
|
||||
int i = 0;
|
||||
for (ColorPickerShape *shape : shapes) {
|
||||
bool is_active = current_shape == i;
|
||||
bool is_active = get_current_shape_index() == i;
|
||||
i++;
|
||||
|
||||
if (!shape->is_initialized) {
|
||||
@@ -552,14 +580,14 @@ void ColorPicker::create_slider(GridContainer *gc, int idx) {
|
||||
slider->connect("drag_started", callable_mp(this, &ColorPicker::_slider_drag_started));
|
||||
slider->connect(SceneStringName(value_changed), callable_mp(this, &ColorPicker::_slider_value_changed).unbind(1));
|
||||
slider->connect("drag_ended", callable_mp(this, &ColorPicker::_slider_drag_ended).unbind(1));
|
||||
if (idx < SLIDER_COUNT) {
|
||||
if (idx < MODE_SLIDER_COUNT) {
|
||||
slider->connect(SceneStringName(draw), callable_mp(this, &ColorPicker::_slider_draw).bind(idx));
|
||||
} else if (idx == SLIDER_ALPHA) {
|
||||
slider->connect(SceneStringName(draw), callable_mp(this, &ColorPicker::_alpha_slider_draw));
|
||||
}
|
||||
slider->connect(SceneStringName(gui_input), callable_mp(this, &ColorPicker::_slider_or_spin_input));
|
||||
|
||||
if (idx < SLIDER_COUNT) {
|
||||
if (idx < MODE_SLIDER_COUNT) {
|
||||
sliders[idx] = slider;
|
||||
values[idx] = val;
|
||||
labels[idx] = lbl;
|
||||
@@ -618,10 +646,8 @@ void ColorPicker::set_palette_saved_callback(const Callable &p_palette_saved) {
|
||||
#endif
|
||||
|
||||
HSlider *ColorPicker::get_slider(int p_idx) {
|
||||
if (p_idx < SLIDER_COUNT) {
|
||||
return sliders[p_idx];
|
||||
}
|
||||
return alpha_slider;
|
||||
ERR_FAIL_INDEX_V(p_idx, MODE_MAX, nullptr);
|
||||
return sliders[p_idx];
|
||||
}
|
||||
|
||||
Vector<float> ColorPicker::get_active_slider_values() {
|
||||
@@ -649,7 +675,7 @@ void ColorPicker::_copy_normalized_to_hsv_okhsl() {
|
||||
}
|
||||
|
||||
void ColorPicker::_copy_hsv_okhsl_to_normalized() {
|
||||
if (current_shape != SHAPE_NONE && shapes[current_shape]->is_ok_hsl()) {
|
||||
if (current_shape != SHAPE_NONE && shapes[get_current_shape_index()]->is_ok_hsl()) {
|
||||
color_normalized.set_ok_hsl(ok_hsl_h, ok_hsl_s, ok_hsl_l, color_normalized.a);
|
||||
} else {
|
||||
color_normalized.set_hsv(h, s, v, color_normalized.a);
|
||||
@@ -712,7 +738,7 @@ void ColorPicker::_reset_sliders_theme() {
|
||||
style_box_flat->set_content_margin(SIDE_TOP, 16 * theme_cache.base_scale);
|
||||
style_box_flat->set_bg_color(Color(0.2, 0.23, 0.31).lerp(Color(0, 0, 0, 1), 0.3).clamp());
|
||||
|
||||
for (int i = 0; i < SLIDER_COUNT; i++) {
|
||||
for (int i = 0; i < MODE_SLIDER_COUNT; i++) {
|
||||
sliders[i]->begin_bulk_theme_override();
|
||||
sliders[i]->add_theme_icon_override(SNAME("grabber"), theme_cache.bar_arrow);
|
||||
sliders[i]->add_theme_icon_override(SNAME("grabber_highlight"), theme_cache.bar_arrow);
|
||||
@@ -815,7 +841,7 @@ void ColorPicker::_update_color(bool p_update_sliders) {
|
||||
_update_text_value();
|
||||
|
||||
if (current_shape != SHAPE_NONE) {
|
||||
for (Control *control : shapes[current_shape]->controls) {
|
||||
for (Control *control : shapes[get_current_shape_index()]->controls) {
|
||||
control->queue_redraw();
|
||||
}
|
||||
}
|
||||
@@ -931,11 +957,11 @@ void ColorPicker::set_picker_shape(PickerShapeType p_shape) {
|
||||
return;
|
||||
}
|
||||
if (current_shape != SHAPE_NONE) {
|
||||
shape_popup->set_item_checked(current_shape, false);
|
||||
shape_popup->set_item_checked(get_current_shape_index(), false);
|
||||
}
|
||||
if (p_shape != SHAPE_NONE) {
|
||||
shape_popup->set_item_checked(p_shape, true);
|
||||
btn_shape->set_button_icon(shape_popup->get_item_icon(p_shape));
|
||||
shape_popup->set_item_checked(shape_to_index(p_shape), true);
|
||||
btn_shape->set_button_icon(shape_popup->get_item_icon(shape_to_index(p_shape)));
|
||||
}
|
||||
|
||||
current_shape = p_shape;
|
||||
@@ -1018,6 +1044,11 @@ void ColorPicker::_quick_open_palette_file_selected(const String &p_path) {
|
||||
file_dialog->set_file_mode(FileDialog::FILE_MODE_OPEN_FILE);
|
||||
_palette_file_selected(p_path);
|
||||
}
|
||||
|
||||
GridContainer *ColorPicker::get_slider_container() {
|
||||
return slider_gc;
|
||||
}
|
||||
|
||||
#endif // ifdef TOOLS_ENABLED
|
||||
|
||||
void ColorPicker::_palette_file_selected(const String &p_path) {
|
||||
@@ -1344,7 +1375,7 @@ void ColorPicker::set_colorize_sliders(bool p_colorize_sliders) {
|
||||
if (colorize_sliders) {
|
||||
Ref<StyleBoxEmpty> style_box_empty(memnew(StyleBoxEmpty));
|
||||
|
||||
for (int i = 0; i < SLIDER_COUNT; i++) {
|
||||
for (int i = 0; i < MODE_SLIDER_COUNT; i++) {
|
||||
sliders[i]->add_theme_style_override("slider", style_box_empty);
|
||||
}
|
||||
|
||||
@@ -1354,7 +1385,7 @@ void ColorPicker::set_colorize_sliders(bool p_colorize_sliders) {
|
||||
style_box_flat->set_content_margin(SIDE_TOP, 16 * theme_cache.base_scale);
|
||||
style_box_flat->set_bg_color(Color(0.2, 0.23, 0.31).lerp(Color(0, 0, 0, 1), 0.3).clamp());
|
||||
|
||||
for (int i = 0; i < SLIDER_COUNT; i++) {
|
||||
for (int i = 0; i < MODE_SLIDER_COUNT; i++) {
|
||||
sliders[i]->add_theme_style_override("slider", style_box_flat);
|
||||
}
|
||||
|
||||
@@ -2051,7 +2082,7 @@ void ColorPicker::_bind_methods() {
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "edit_intensity"), "set_edit_intensity", "is_editing_intensity");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "color_mode", PROPERTY_HINT_ENUM, "RGB,HSV,LINEAR,OKHSL"), "set_color_mode", "get_color_mode");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "deferred_mode"), "set_deferred_mode", "is_deferred_mode");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "picker_shape", PROPERTY_HINT_ENUM, "HSV Rectangle,HSV Rectangle Wheel,VHS Circle,OKHSL Circle,None"), "set_picker_shape", "get_picker_shape");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "picker_shape", PROPERTY_HINT_ENUM, "HSV Rectangle,HSV Rectangle Wheel,VHS Circle,OKHSL Circle,OK HS Rectangle:5,OK HL Rectangle,None:4"), "set_picker_shape", "get_picker_shape");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "can_add_swatches"), "set_can_add_swatches", "are_swatches_enabled");
|
||||
ADD_GROUP("Customization", "");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sampler_visible"), "set_sampler_visible", "is_sampler_visible");
|
||||
@@ -2077,6 +2108,8 @@ void ColorPicker::_bind_methods() {
|
||||
BIND_ENUM_CONSTANT(SHAPE_VHS_CIRCLE);
|
||||
BIND_ENUM_CONSTANT(SHAPE_OKHSL_CIRCLE);
|
||||
BIND_ENUM_CONSTANT(SHAPE_NONE);
|
||||
BIND_ENUM_CONSTANT(SHAPE_OK_HS_RECTANGLE);
|
||||
BIND_ENUM_CONSTANT(SHAPE_OK_HL_RECTANGLE);
|
||||
|
||||
BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_CONSTANT, ColorPicker, content_margin, "margin");
|
||||
BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, ColorPicker, label_width);
|
||||
@@ -2158,16 +2191,18 @@ ColorPicker::ColorPicker() {
|
||||
add_shape(memnew(ColorPickerShapeWheel(this)));
|
||||
add_shape(memnew(ColorPickerShapeVHSCircle(this)));
|
||||
add_shape(memnew(ColorPickerShapeOKHSLCircle(this)));
|
||||
add_shape(memnew(ColorPickerShapeOKHSRectangle(this)));
|
||||
add_shape(memnew(ColorPickerShapeOKHLRectangle(this)));
|
||||
|
||||
shape_popup = btn_shape->get_popup();
|
||||
{
|
||||
int i = 0;
|
||||
for (const ColorPickerShape *shape : shapes) {
|
||||
shape_popup->add_radio_check_item(shape->get_name(), i);
|
||||
shape_popup->add_radio_check_item(shape->get_name(), index_to_shape(i));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
shape_popup->set_item_checked(current_shape, true);
|
||||
shape_popup->set_item_checked(get_current_shape_index(), true);
|
||||
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));
|
||||
|
||||
@@ -88,6 +88,8 @@ class ColorPicker : public VBoxContainer {
|
||||
friend class ColorPickerShapeCircle;
|
||||
friend class ColorPickerShapeVHSCircle;
|
||||
friend class ColorPickerShapeOKHSLCircle;
|
||||
friend class ColorPickerShapeOKHSRectangle;
|
||||
friend class ColorPickerShapeOKHLRectangle;
|
||||
|
||||
friend class ColorModeRGB;
|
||||
friend class ColorModeHSV;
|
||||
@@ -113,19 +115,49 @@ public:
|
||||
SHAPE_VHS_CIRCLE,
|
||||
SHAPE_OKHSL_CIRCLE,
|
||||
SHAPE_NONE,
|
||||
SHAPE_OK_HS_RECTANGLE,
|
||||
SHAPE_OK_HL_RECTANGLE,
|
||||
|
||||
SHAPE_MAX
|
||||
};
|
||||
|
||||
static const int SLIDER_COUNT = 3;
|
||||
private:
|
||||
// Ideally, `SHAPE_NONE` should be -1 so that we don't need to convert shape type to index.
|
||||
// In order to avoid breaking compatibility, we have to use these methods for conversion.
|
||||
inline int get_current_shape_index() {
|
||||
return shape_to_index(current_shape);
|
||||
}
|
||||
|
||||
static inline int shape_to_index(PickerShapeType p_shape) {
|
||||
if (p_shape == SHAPE_NONE) {
|
||||
return -1;
|
||||
}
|
||||
if (p_shape > SHAPE_NONE) {
|
||||
return p_shape - 1;
|
||||
}
|
||||
return p_shape;
|
||||
}
|
||||
|
||||
static inline PickerShapeType index_to_shape(int p_index) {
|
||||
if (p_index == -1) {
|
||||
return SHAPE_NONE;
|
||||
}
|
||||
if (p_index >= SHAPE_NONE) {
|
||||
return (PickerShapeType)(p_index + 1);
|
||||
}
|
||||
return (PickerShapeType)p_index;
|
||||
}
|
||||
|
||||
public:
|
||||
static const int MODE_SLIDER_COUNT = 3;
|
||||
|
||||
enum SLIDER_EXTRA {
|
||||
SLIDER_INTENSITY = 3,
|
||||
SLIDER_INTENSITY = MODE_SLIDER_COUNT,
|
||||
SLIDER_ALPHA,
|
||||
|
||||
SLIDER_MAX
|
||||
};
|
||||
|
||||
private:
|
||||
enum class MenuOption {
|
||||
MENU_SAVE,
|
||||
MENU_SAVE_AS,
|
||||
@@ -134,9 +166,12 @@ private:
|
||||
MENU_CLEAR,
|
||||
};
|
||||
|
||||
private:
|
||||
static inline Ref<Shader> wheel_shader;
|
||||
static inline Ref<Shader> circle_shader;
|
||||
static inline Ref<Shader> circle_ok_color_shader;
|
||||
static inline Ref<Shader> rectangle_ok_color_hs_shader;
|
||||
static inline Ref<Shader> rectangle_ok_color_hl_shader;
|
||||
static inline List<Color> preset_cache;
|
||||
static inline List<Color> recent_preset_cache;
|
||||
|
||||
@@ -144,7 +179,7 @@ private:
|
||||
Object *editor_settings = nullptr;
|
||||
#endif
|
||||
|
||||
int current_slider_count = SLIDER_COUNT;
|
||||
int current_slider_count = MODE_SLIDER_COUNT;
|
||||
|
||||
const float DEFAULT_GAMEPAD_EVENT_DELAY_MS = 1.0 / 2;
|
||||
const float GAMEPAD_EVENT_REPEAT_RATE_MS = 1.0 / 30;
|
||||
@@ -394,6 +429,7 @@ public:
|
||||
void _quick_open_palette_file_selected(const String &p_path);
|
||||
#endif
|
||||
|
||||
GridContainer *get_slider_container();
|
||||
HSlider *get_slider(int idx);
|
||||
Vector<float> get_active_slider_values();
|
||||
|
||||
|
||||
@@ -131,7 +131,7 @@ void ColorPickerShape::draw_sv_square(Control *p_control, const Rect2 &p_square,
|
||||
Color(1, 1, 1, 1),
|
||||
Color(1, 1, 1, 1),
|
||||
Color(0, 0, 0, 1),
|
||||
Color(0, 0, 0, 1)
|
||||
Color(0, 0, 0, 1),
|
||||
};
|
||||
p_control->draw_polygon(points, colors);
|
||||
|
||||
@@ -139,7 +139,7 @@ void ColorPickerShape::draw_sv_square(Control *p_control, const Rect2 &p_square,
|
||||
Color(color1, 0),
|
||||
Color(color1, 1),
|
||||
Color(color2, 1),
|
||||
Color(color2, 0)
|
||||
Color(color2, 0),
|
||||
};
|
||||
p_control->draw_polygon(points, colors);
|
||||
|
||||
@@ -356,6 +356,220 @@ void ColorPickerShapeRectangle::grab_focus() {
|
||||
hue_slider->grab_focus();
|
||||
}
|
||||
|
||||
void ColorPickerShapeOKHSRectangle::_initialize_controls() {
|
||||
rectangle_margin = memnew(MarginContainer);
|
||||
color_picker->shape_container->add_child(rectangle_margin);
|
||||
|
||||
Ref<ShaderMaterial> material;
|
||||
material.instantiate();
|
||||
material->set_shader(_get_shader());
|
||||
|
||||
square = memnew(Control);
|
||||
rectangle_margin->add_child(square);
|
||||
square->connect(SceneStringName(draw), callable_mp(this, &ColorPickerShapeOKHSRectangle::_square_draw));
|
||||
square->set_material(material);
|
||||
|
||||
square_overlay = memnew(Control);
|
||||
rectangle_margin->add_child(square_overlay);
|
||||
square_overlay->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
|
||||
square_overlay->connect(SceneStringName(gui_input), callable_mp(this, &ColorPickerShapeOKHSRectangle::_square_overlay_input));
|
||||
square_overlay->connect(SceneStringName(draw), callable_mp(this, &ColorPickerShapeOKHSRectangle::_square_overlay_draw));
|
||||
connect_shape_focus(square_overlay);
|
||||
|
||||
value_slider = memnew(Control);
|
||||
color_picker->shape_container->add_child(value_slider);
|
||||
value_slider->connect(SceneStringName(gui_input), callable_mp(this, &ColorPickerShapeOKHSRectangle::_value_slider_input));
|
||||
value_slider->connect(SceneStringName(draw), callable_mp(this, &ColorPickerShapeOKHSRectangle::_value_slider_draw));
|
||||
connect_shape_focus(value_slider);
|
||||
|
||||
controls.append(rectangle_margin);
|
||||
controls.append(square);
|
||||
controls.append(square_overlay);
|
||||
controls.append(value_slider);
|
||||
}
|
||||
|
||||
void ColorPickerShapeOKHSRectangle::update_theme() {
|
||||
const ColorPicker::ThemeCache &theme_cache = color_picker->theme_cache;
|
||||
rectangle_margin->set_custom_minimum_size(Size2(theme_cache.sv_width, theme_cache.sv_height));
|
||||
value_slider->set_custom_minimum_size(Size2(theme_cache.h_width, 0));
|
||||
}
|
||||
|
||||
void ColorPickerShapeOKHSRectangle::grab_focus() {
|
||||
square_overlay->grab_focus();
|
||||
}
|
||||
|
||||
void ColorPickerShapeOKHSRectangle::_update_cursor(const Vector2 &p_color_change_vector, bool p_is_echo) {
|
||||
if (square_overlay->has_focus()) {
|
||||
color_picker->ok_hsl_h = CLAMP(color_picker->ok_hsl_h + p_color_change_vector.x / 100.0, 0, 1);
|
||||
color_picker->ok_hsl_s = CLAMP(color_picker->ok_hsl_s - p_color_change_vector.y / 100.0, 0, 1);
|
||||
} else if (value_slider->has_focus()) {
|
||||
color_picker->ok_hsl_l = CLAMP(color_picker->ok_hsl_l + p_color_change_vector.y * echo_multiplier / 360.0, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void ColorPickerShapeOKHSRectangle::_square_draw() {
|
||||
Ref<ShaderMaterial> material = square->get_material();
|
||||
material->set_shader_parameter(SNAME("ok_hsl_l"), color_picker->ok_hsl_l);
|
||||
square->draw_rect(Rect2(Point2(), square->get_size()), Color(1, 1, 1));
|
||||
}
|
||||
|
||||
void ColorPickerShapeOKHSRectangle::_square_overlay_input(const Ref<InputEvent> &p_event) {
|
||||
handle_cursor_editing(p_event, square_overlay);
|
||||
|
||||
Vector2 event_position;
|
||||
if (!can_handle(p_event, event_position)) {
|
||||
return;
|
||||
}
|
||||
event_position = (event_position / square_overlay->get_size()).clampf(0.0, 1.0);
|
||||
|
||||
color_picker->ok_hsl_h = event_position.x;
|
||||
color_picker->ok_hsl_s = 1.0 - event_position.y;
|
||||
|
||||
apply_color();
|
||||
}
|
||||
|
||||
void ColorPickerShapeOKHSRectangle::_square_overlay_draw() {
|
||||
const Rect2 rect = Rect2(Vector2(), square_overlay->get_size());
|
||||
const Vector2 end = rect.get_end();
|
||||
Vector2 cursor_pos;
|
||||
cursor_pos.x = CLAMP(rect.position.x + rect.size.x * color_picker->ok_hsl_h, rect.position.x, end.x);
|
||||
cursor_pos.y = CLAMP(rect.position.y + rect.size.y * (1.0 - color_picker->ok_hsl_s), rect.position.y, end.y);
|
||||
|
||||
draw_focus_rect(square_overlay);
|
||||
draw_cursor(square_overlay, cursor_pos);
|
||||
}
|
||||
|
||||
void ColorPickerShapeOKHSRectangle::_value_slider_input(const Ref<InputEvent> &p_event) {
|
||||
handle_cursor_editing(p_event, value_slider);
|
||||
|
||||
Vector2 event_position;
|
||||
if (!can_handle(p_event, event_position)) {
|
||||
return;
|
||||
}
|
||||
color_picker->ok_hsl_l = 1 - CLAMP(event_position.y / value_slider->get_size().y, 0.0, 1.0);
|
||||
apply_color();
|
||||
}
|
||||
|
||||
void ColorPickerShapeOKHSRectangle::_value_slider_draw() {
|
||||
const float ok_hsl_h = color_picker->ok_hsl_h;
|
||||
const float ok_hsl_s = color_picker->ok_hsl_s;
|
||||
|
||||
const Vector2 size = value_slider->get_size();
|
||||
PackedVector2Array points{
|
||||
Vector2(size.x, 0),
|
||||
Vector2(size.x, size.y * 0.5),
|
||||
size,
|
||||
Vector2(0, size.y),
|
||||
Vector2(0, size.y * 0.5),
|
||||
Vector2(),
|
||||
};
|
||||
|
||||
Color color1 = Color::from_ok_hsl(ok_hsl_h, ok_hsl_s, 1);
|
||||
Color color2 = Color::from_ok_hsl(ok_hsl_h, ok_hsl_s, 0.5);
|
||||
Color color3 = Color::from_ok_hsl(ok_hsl_h, ok_hsl_s, 0);
|
||||
PackedColorArray colors = {
|
||||
color1,
|
||||
color2,
|
||||
color3,
|
||||
color3,
|
||||
color2,
|
||||
color1,
|
||||
};
|
||||
value_slider->draw_polygon(points, colors);
|
||||
|
||||
draw_focus_rect(value_slider);
|
||||
|
||||
int y = size.y * (1 - CLAMP(color_picker->ok_hsl_l, 0, 1));
|
||||
const Color color = Color::from_ok_hsl(ok_hsl_h, 1, color_picker->ok_hsl_l);
|
||||
value_slider->draw_line(Vector2(0, y), Vector2(size.x, y), color.inverted());
|
||||
}
|
||||
|
||||
void ColorPickerShapeOKHLRectangle::_update_cursor(const Vector2 &p_color_change_vector, bool p_is_echo) {
|
||||
if (square_overlay->has_focus()) {
|
||||
color_picker->ok_hsl_h = CLAMP(color_picker->ok_hsl_h + p_color_change_vector.x / 100.0, 0, 1);
|
||||
color_picker->ok_hsl_l = CLAMP(color_picker->ok_hsl_l - p_color_change_vector.y / 100.0, 0, 1);
|
||||
} else if (value_slider->has_focus()) {
|
||||
color_picker->ok_hsl_s = CLAMP(color_picker->ok_hsl_s + p_color_change_vector.y * echo_multiplier / 360.0, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void ColorPickerShapeOKHLRectangle::_square_overlay_input(const Ref<InputEvent> &p_event) {
|
||||
handle_cursor_editing(p_event, square_overlay);
|
||||
|
||||
Vector2 event_position;
|
||||
if (!can_handle(p_event, event_position)) {
|
||||
return;
|
||||
}
|
||||
event_position = (event_position / square_overlay->get_size()).clampf(0.0, 1.0);
|
||||
|
||||
color_picker->ok_hsl_h = event_position.x;
|
||||
color_picker->ok_hsl_l = 1.0 - event_position.y;
|
||||
|
||||
apply_color();
|
||||
}
|
||||
|
||||
void ColorPickerShapeOKHLRectangle::_square_overlay_draw() {
|
||||
const Rect2 rect = Rect2(Vector2(), square_overlay->get_size());
|
||||
const Vector2 end = rect.get_end();
|
||||
Vector2 cursor_pos;
|
||||
cursor_pos.x = CLAMP(rect.position.x + rect.size.x * color_picker->ok_hsl_h, rect.position.x, end.x);
|
||||
cursor_pos.y = CLAMP(rect.position.y + rect.size.y * (1.0 - color_picker->ok_hsl_l), rect.position.y, end.y);
|
||||
|
||||
draw_focus_rect(square_overlay);
|
||||
draw_cursor(square_overlay, cursor_pos);
|
||||
}
|
||||
|
||||
void ColorPickerShapeOKHLRectangle::_square_draw() {
|
||||
Ref<ShaderMaterial> material = square->get_material();
|
||||
material->set_shader_parameter(SNAME("ok_hsl_s"), color_picker->ok_hsl_s);
|
||||
square->draw_rect(Rect2(Point2(), square->get_size()), Color(1, 1, 1));
|
||||
}
|
||||
|
||||
void ColorPickerShapeOKHLRectangle::_value_slider_input(const Ref<InputEvent> &p_event) {
|
||||
handle_cursor_editing(p_event, value_slider);
|
||||
|
||||
Vector2 event_position;
|
||||
if (!can_handle(p_event, event_position)) {
|
||||
return;
|
||||
}
|
||||
color_picker->ok_hsl_s = 1 - CLAMP(event_position.y / value_slider->get_size().y, 0.0, 1.0);
|
||||
apply_color();
|
||||
}
|
||||
|
||||
void ColorPickerShapeOKHLRectangle::_value_slider_draw() {
|
||||
const float ok_hsl_h = color_picker->ok_hsl_h;
|
||||
const float ok_hsl_l = color_picker->ok_hsl_l;
|
||||
|
||||
const Vector2 size = value_slider->get_size();
|
||||
PackedVector2Array points{
|
||||
Vector2(size.x, 0),
|
||||
Vector2(size.x, size.y * 0.5),
|
||||
size,
|
||||
Vector2(0, size.y),
|
||||
Vector2(0, size.y * 0.5),
|
||||
Vector2(),
|
||||
};
|
||||
|
||||
Color color1 = Color::from_ok_hsl(ok_hsl_h, 1, ok_hsl_l);
|
||||
Color color2 = Color::from_ok_hsl(ok_hsl_h, 0.5, ok_hsl_l);
|
||||
Color color3 = Color::from_ok_hsl(ok_hsl_h, 0, ok_hsl_l);
|
||||
PackedColorArray colors = {
|
||||
color1,
|
||||
color2,
|
||||
color3,
|
||||
color3,
|
||||
color2,
|
||||
color1,
|
||||
};
|
||||
value_slider->draw_polygon(points, colors);
|
||||
|
||||
draw_focus_rect(value_slider);
|
||||
|
||||
int y = size.y * (1 - CLAMP(color_picker->ok_hsl_s, 0, 1));
|
||||
const Color color = Color::from_ok_hsl(ok_hsl_h, 1, ok_hsl_l);
|
||||
value_slider->draw_line(Vector2(0, y), Vector2(size.x, y), color.inverted());
|
||||
}
|
||||
|
||||
float ColorPickerShapeWheel::_get_h_on_wheel(const Vector2 &p_color_change_vector) {
|
||||
int h_change = get_edge_h_change(p_color_change_vector);
|
||||
|
||||
@@ -645,7 +859,7 @@ void ColorPickerShapeVHSCircle::_value_slider_draw() {
|
||||
Vector2(),
|
||||
Vector2(size.x, 0),
|
||||
size,
|
||||
Vector2(0, size.y)
|
||||
Vector2(0, size.y),
|
||||
};
|
||||
|
||||
Color color = Color::from_hsv(color_picker->h, color_picker->s, 1);
|
||||
@@ -653,7 +867,7 @@ void ColorPickerShapeVHSCircle::_value_slider_draw() {
|
||||
color,
|
||||
color,
|
||||
Color(),
|
||||
Color()
|
||||
Color(),
|
||||
};
|
||||
|
||||
value_slider->draw_polygon(points, colors);
|
||||
@@ -736,7 +950,7 @@ void ColorPickerShapeOKHSLCircle::_value_slider_draw() {
|
||||
size,
|
||||
Vector2(0, size.y),
|
||||
Vector2(0, size.y * 0.5),
|
||||
Vector2()
|
||||
Vector2(),
|
||||
};
|
||||
|
||||
Color color1 = Color::from_ok_hsl(ok_hsl_h, ok_hsl_s, 1);
|
||||
@@ -755,7 +969,7 @@ void ColorPickerShapeOKHSLCircle::_value_slider_draw() {
|
||||
draw_focus_rect(value_slider);
|
||||
|
||||
int y = size.y * (1 - CLAMP(ok_hsl_l, 0, 1));
|
||||
value_slider->draw_line(Vector2(0, y), Vector2(size.x, y), Color::from_hsv(ok_hsl_h, 1, ok_hsl_l).inverted());
|
||||
value_slider->draw_line(Vector2(0, y), Vector2(size.x, y), Color::from_ok_hsl(ok_hsl_h, 1, ok_hsl_l).inverted());
|
||||
}
|
||||
|
||||
void ColorPickerShapeOKHSLCircle::_update_cursor(const Vector2 &p_color_change_vector, bool p_is_echo) {
|
||||
|
||||
@@ -104,6 +104,60 @@ public:
|
||||
ColorPickerShape(p_color_picker) {}
|
||||
};
|
||||
|
||||
class ColorPickerShapeOKHSRectangle : public ColorPickerShape {
|
||||
GDCLASS(ColorPickerShapeOKHSRectangle, ColorPickerShape);
|
||||
|
||||
MarginContainer *rectangle_margin = nullptr;
|
||||
|
||||
protected:
|
||||
Control *square = nullptr;
|
||||
Control *square_overlay = nullptr;
|
||||
Control *value_slider = nullptr;
|
||||
virtual Ref<Shader> _get_shader() const { return ColorPicker::rectangle_ok_color_hs_shader; }
|
||||
virtual void _initialize_controls() override;
|
||||
virtual void _update_cursor(const Vector2 &p_color_change_vector, bool p_is_echo) override;
|
||||
|
||||
virtual void _square_draw();
|
||||
virtual void _square_overlay_input(const Ref<InputEvent> &p_event);
|
||||
virtual void _square_overlay_draw();
|
||||
|
||||
virtual void _value_slider_input(const Ref<InputEvent> &p_event);
|
||||
virtual void _value_slider_draw();
|
||||
|
||||
public:
|
||||
virtual String get_name() const override { return ETR("OK HS Rectangle"); }
|
||||
virtual bool is_ok_hsl() const override { return true; }
|
||||
virtual Ref<Texture2D> get_icon() const override { return color_picker->theme_cache.shape_rect; }
|
||||
virtual void update_theme() override;
|
||||
virtual void grab_focus() override;
|
||||
|
||||
ColorPickerShapeOKHSRectangle(ColorPicker *p_color_picker) :
|
||||
ColorPickerShape(p_color_picker) {}
|
||||
};
|
||||
|
||||
class ColorPickerShapeOKHLRectangle : public ColorPickerShapeOKHSRectangle {
|
||||
GDCLASS(ColorPickerShapeOKHLRectangle, ColorPickerShapeOKHSRectangle);
|
||||
|
||||
protected:
|
||||
virtual Ref<Shader> _get_shader() const override { return ColorPicker::rectangle_ok_color_hl_shader; }
|
||||
virtual void _update_cursor(const Vector2 &p_color_change_vector, bool p_is_echo) override;
|
||||
|
||||
virtual void _square_draw() override;
|
||||
virtual void _square_overlay_input(const Ref<InputEvent> &p_event) override;
|
||||
virtual void _square_overlay_draw() override;
|
||||
|
||||
virtual void _value_slider_input(const Ref<InputEvent> &p_event) override;
|
||||
virtual void _value_slider_draw() override;
|
||||
|
||||
public:
|
||||
virtual String get_name() const override { return ETR("OK HL Rectangle"); }
|
||||
virtual bool is_ok_hsl() const override { return true; }
|
||||
virtual Ref<Texture2D> get_icon() const override { return color_picker->theme_cache.shape_rect; }
|
||||
|
||||
ColorPickerShapeOKHLRectangle(ColorPicker *p_color_picker) :
|
||||
ColorPickerShapeOKHSRectangle(p_color_picker) {}
|
||||
};
|
||||
|
||||
class ColorPickerShapeWheel : public ColorPickerShape {
|
||||
GDCLASS(ColorPickerShapeWheel, ColorPickerShape);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user