|
@@ -46,13 +46,13 @@ void ColorPicker::_notification(int p_what) {
|
|
|
switch (p_what) {
|
|
|
case NOTIFICATION_THEME_CHANGED: {
|
|
|
btn_pick->set_icon(get_icon("screen_picker", "ColorPicker"));
|
|
|
- bt_add_preset->set_icon(get_icon("add_preset"));
|
|
|
-
|
|
|
+ btn_add_preset->set_icon(get_icon("add_preset"));
|
|
|
+ _update_presets();
|
|
|
_update_controls();
|
|
|
} break;
|
|
|
case NOTIFICATION_ENTER_TREE: {
|
|
|
btn_pick->set_icon(get_icon("screen_picker", "ColorPicker"));
|
|
|
- bt_add_preset->set_icon(get_icon("add_preset"));
|
|
|
+ btn_add_preset->set_icon(get_icon("add_preset"));
|
|
|
|
|
|
_update_controls();
|
|
|
_update_color();
|
|
@@ -69,7 +69,6 @@ void ColorPicker::_notification(int p_what) {
|
|
|
for (int i = 0; i < preset_cache.size(); i++) {
|
|
|
presets.push_back(preset_cache[i]);
|
|
|
}
|
|
|
- preset->update();
|
|
|
}
|
|
|
#endif
|
|
|
} break;
|
|
@@ -255,19 +254,15 @@ void ColorPicker::_update_color(bool p_update_sliders) {
|
|
|
}
|
|
|
|
|
|
void ColorPicker::_update_presets() {
|
|
|
- presets_per_row = 10;
|
|
|
- Size2 size = bt_add_preset->get_size();
|
|
|
- Size2 preset_size = Size2(MIN(size.width * presets.size(), presets_per_row * size.width), size.height * (Math::ceil((float)presets.size() / presets_per_row)));
|
|
|
- preset->set_custom_minimum_size(preset_size);
|
|
|
- preset_container->set_custom_minimum_size(preset_size);
|
|
|
- preset->draw_rect(Rect2(Point2(), preset_size), Color(1, 1, 1, 0));
|
|
|
-
|
|
|
- for (int i = 0; i < presets.size(); i++) {
|
|
|
- int x = (i % presets_per_row) * size.width;
|
|
|
- int y = (Math::floor((float)i / presets_per_row)) * size.height;
|
|
|
- preset->draw_rect(Rect2(Point2(x, y), size), presets[i]);
|
|
|
+ // Only load preset buttons when the only child is the add-preset button.
|
|
|
+ int preset_size = _get_preset_size();
|
|
|
+ btn_add_preset->set_custom_minimum_size(Size2(preset_size, preset_size));
|
|
|
+ if (preset_container->get_child_count() == 1) {
|
|
|
+ for (int i = 0; i < preset_cache.size(); i++) {
|
|
|
+ _add_preset_button(preset_size, preset_cache[i]);
|
|
|
+ }
|
|
|
+ _notification(NOTIFICATION_VISIBILITY_CHANGED);
|
|
|
}
|
|
|
- _notification(NOTIFICATION_VISIBILITY_CHANGED);
|
|
|
}
|
|
|
|
|
|
void ColorPicker::_text_type_toggled() {
|
|
@@ -290,14 +285,38 @@ Color ColorPicker::get_pick_color() const {
|
|
|
return color;
|
|
|
}
|
|
|
|
|
|
+inline int ColorPicker::_get_preset_size() {
|
|
|
+ return (int(get_size().width) - (preset_container->get_constant("hseparation") * (preset_column_count - 1))) / preset_column_count;
|
|
|
+}
|
|
|
+
|
|
|
+void ColorPicker::_add_preset_button(int p_size, const Color &p_color) {
|
|
|
+ ColorPresetButton *btn_preset = memnew(ColorPresetButton(p_color));
|
|
|
+ btn_preset->set_preset_color(p_color);
|
|
|
+ btn_preset->set_custom_minimum_size(Size2(p_size, p_size));
|
|
|
+ btn_preset->connect("gui_input", this, "_preset_input", varray(p_color));
|
|
|
+ btn_preset->set_tooltip(vformat(RTR("Color: #%s\nLMB: Apply color\nRMB: Remove preset"), p_color.to_html(p_color.a < 1)));
|
|
|
+ preset_container->add_child(btn_preset);
|
|
|
+}
|
|
|
+
|
|
|
void ColorPicker::add_preset(const Color &p_color) {
|
|
|
if (presets.find(p_color)) {
|
|
|
presets.move_to_back(presets.find(p_color));
|
|
|
+
|
|
|
+ // Find button to move to the end.
|
|
|
+ for (int i = 1; i < preset_container->get_child_count(); i++) {
|
|
|
+ ColorPresetButton *current_btn = Object::cast_to<ColorPresetButton>(preset_container->get_child(i));
|
|
|
+ if (current_btn && p_color == current_btn->get_preset_color()) {
|
|
|
+ preset_container->move_child(current_btn, preset_container->get_child_count() - 1);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
} else {
|
|
|
presets.push_back(p_color);
|
|
|
preset_cache.push_back(p_color);
|
|
|
+
|
|
|
+ _add_preset_button(_get_preset_size(), p_color);
|
|
|
+ _notification(NOTIFICATION_VISIBILITY_CHANGED);
|
|
|
}
|
|
|
- preset->update();
|
|
|
|
|
|
#ifdef TOOLS_ENABLED
|
|
|
if (Engine::get_singleton()->is_editor_hint()) {
|
|
@@ -311,7 +330,15 @@ void ColorPicker::erase_preset(const Color &p_color) {
|
|
|
if (presets.find(p_color)) {
|
|
|
presets.erase(presets.find(p_color));
|
|
|
preset_cache.erase(preset_cache.find(p_color));
|
|
|
- preset->update();
|
|
|
+
|
|
|
+ // Find preset button to remove.
|
|
|
+ for (int i = 1; i < preset_container->get_child_count(); i++) {
|
|
|
+ ColorPresetButton *current_btn = Object::cast_to<ColorPresetButton>(preset_container->get_child(i));
|
|
|
+ if (current_btn && p_color == current_btn->get_preset_color()) {
|
|
|
+ current_btn->queue_delete();
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
#ifdef TOOLS_ENABLED
|
|
|
if (Engine::get_singleton()->is_editor_hint()) {
|
|
@@ -585,42 +612,18 @@ void ColorPicker::_w_input(const Ref<InputEvent> &p_event) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void ColorPicker::_preset_input(const Ref<InputEvent> &p_event) {
|
|
|
+void ColorPicker::_preset_input(const Ref<InputEvent> &p_event, const Color &p_color) {
|
|
|
Ref<InputEventMouseButton> bev = p_event;
|
|
|
|
|
|
if (bev.is_valid()) {
|
|
|
- int index = 0;
|
|
|
if (bev->is_pressed() && bev->get_button_index() == BUTTON_LEFT) {
|
|
|
- for (int i = 0; i < presets.size(); i++) {
|
|
|
- int x = (i % presets_per_row) * bt_add_preset->get_size().x;
|
|
|
- int y = (Math::floor((float)i / presets_per_row)) * bt_add_preset->get_size().y;
|
|
|
- if (bev->get_position().x > x && bev->get_position().x < x + preset->get_size().x && bev->get_position().y > y && bev->get_position().y < y + preset->get_size().y) {
|
|
|
- index = i;
|
|
|
- }
|
|
|
- }
|
|
|
- set_pick_color(presets[index]);
|
|
|
+ set_pick_color(p_color);
|
|
|
_update_color();
|
|
|
- emit_signal("color_changed", color);
|
|
|
+ emit_signal("color_changed", p_color);
|
|
|
} else if (bev->is_pressed() && bev->get_button_index() == BUTTON_RIGHT && presets_enabled) {
|
|
|
- index = bev->get_position().x / (preset->get_size().x / presets.size());
|
|
|
- Color clicked_preset = presets[index];
|
|
|
- erase_preset(clicked_preset);
|
|
|
- emit_signal("preset_removed", clicked_preset);
|
|
|
- bt_add_preset->show();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- Ref<InputEventMouseMotion> mev = p_event;
|
|
|
-
|
|
|
- if (mev.is_valid()) {
|
|
|
- int index = mev->get_position().x * presets.size();
|
|
|
- if (preset->get_size().x != 0) {
|
|
|
- index /= preset->get_size().x;
|
|
|
+ erase_preset(p_color);
|
|
|
+ emit_signal("preset_removed", p_color);
|
|
|
}
|
|
|
- if (index < 0 || index >= presets.size()) {
|
|
|
- return;
|
|
|
- }
|
|
|
- preset->set_tooltip(vformat(RTR("Color: #%s\nLMB: Set color\nRMB: Remove preset"), presets[index].to_html(presets[index].a < 1)));
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -715,11 +718,11 @@ void ColorPicker::_html_focus_exit() {
|
|
|
void ColorPicker::set_presets_enabled(bool p_enabled) {
|
|
|
presets_enabled = p_enabled;
|
|
|
if (!p_enabled) {
|
|
|
- bt_add_preset->set_disabled(true);
|
|
|
- bt_add_preset->set_focus_mode(FOCUS_NONE);
|
|
|
+ btn_add_preset->set_disabled(true);
|
|
|
+ btn_add_preset->set_focus_mode(FOCUS_NONE);
|
|
|
} else {
|
|
|
- bt_add_preset->set_disabled(false);
|
|
|
- bt_add_preset->set_focus_mode(FOCUS_ALL);
|
|
|
+ btn_add_preset->set_disabled(false);
|
|
|
+ btn_add_preset->set_focus_mode(FOCUS_ALL);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -731,7 +734,6 @@ void ColorPicker::set_presets_visible(bool p_visible) {
|
|
|
presets_visible = p_visible;
|
|
|
preset_separator->set_visible(p_visible);
|
|
|
preset_container->set_visible(p_visible);
|
|
|
- preset_container2->set_visible(p_visible);
|
|
|
}
|
|
|
|
|
|
bool ColorPicker::are_presets_visible() const {
|
|
@@ -915,22 +917,14 @@ ColorPicker::ColorPicker() :
|
|
|
preset_separator = memnew(HSeparator);
|
|
|
add_child(preset_separator);
|
|
|
|
|
|
- preset_container = memnew(HBoxContainer);
|
|
|
preset_container->set_h_size_flags(SIZE_EXPAND_FILL);
|
|
|
+ preset_container->set_columns(preset_column_count);
|
|
|
add_child(preset_container);
|
|
|
|
|
|
- preset = memnew(TextureRect);
|
|
|
- preset_container->add_child(preset);
|
|
|
- preset->connect("gui_input", this, "_preset_input");
|
|
|
- preset->connect("draw", this, "_update_presets");
|
|
|
-
|
|
|
- preset_container2 = memnew(HBoxContainer);
|
|
|
- preset_container2->set_h_size_flags(SIZE_EXPAND_FILL);
|
|
|
- add_child(preset_container2);
|
|
|
- bt_add_preset = memnew(Button);
|
|
|
- preset_container2->add_child(bt_add_preset);
|
|
|
- bt_add_preset->set_tooltip(RTR("Add current color as a preset."));
|
|
|
- bt_add_preset->connect("pressed", this, "_add_preset_pressed");
|
|
|
+ btn_add_preset = memnew(Button);
|
|
|
+ btn_add_preset->connect("pressed", this, "_add_preset_pressed");
|
|
|
+ btn_add_preset->set_tooltip(RTR("Add current color as a preset."));
|
|
|
+ preset_container->add_child(btn_add_preset);
|
|
|
}
|
|
|
|
|
|
/////////////////
|
|
@@ -954,6 +948,7 @@ void ColorPickerButton::_modal_closed() {
|
|
|
|
|
|
void ColorPickerButton::pressed() {
|
|
|
_update_picker();
|
|
|
+ picker->_update_presets();
|
|
|
popup->set_position(get_global_position() - picker->get_combined_minimum_size() * get_global_transform().get_scale());
|
|
|
popup->set_scale(get_global_transform().get_scale());
|
|
|
popup->popup();
|
|
@@ -1077,3 +1072,64 @@ ColorPickerButton::ColorPickerButton() {
|
|
|
|
|
|
set_toggle_mode(true);
|
|
|
}
|
|
|
+
|
|
|
+/////////////////
|
|
|
+
|
|
|
+void ColorPresetButton::_notification(int p_what) {
|
|
|
+ switch (p_what) {
|
|
|
+ case NOTIFICATION_DRAW: {
|
|
|
+ const Rect2 r = Rect2(Point2(0, 0), get_size());
|
|
|
+ Ref<StyleBox> sb_raw = get_stylebox("preset_fg", "ColorPresetButton")->duplicate();
|
|
|
+ Ref<StyleBoxFlat> sb_flat = sb_raw;
|
|
|
+ Ref<StyleBoxTexture> sb_texture = sb_raw;
|
|
|
+
|
|
|
+ if (sb_raw->get_class_name() == "StyleBoxFlat") {
|
|
|
+ if (preset_color.a < 1) {
|
|
|
+ // Draw a background pattern when the color is transparent.
|
|
|
+ sb_flat->set_bg_color(Color(1, 1, 1));
|
|
|
+ sb_flat->draw(get_canvas_item(), r);
|
|
|
+
|
|
|
+ Rect2 bg_texture_rect = r.grow_margin(MARGIN_LEFT, -sb_flat->get_margin(MARGIN_LEFT));
|
|
|
+ bg_texture_rect = bg_texture_rect.grow_margin(MARGIN_RIGHT, -sb_flat->get_margin(MARGIN_RIGHT));
|
|
|
+ bg_texture_rect = bg_texture_rect.grow_margin(MARGIN_TOP, -sb_flat->get_margin(MARGIN_TOP));
|
|
|
+ bg_texture_rect = bg_texture_rect.grow_margin(MARGIN_BOTTOM, -sb_flat->get_margin(MARGIN_BOTTOM));
|
|
|
+
|
|
|
+ draw_texture_rect(get_icon("preset_bg_icon", "ColorPresetButton"), bg_texture_rect, true);
|
|
|
+ sb_flat->set_bg_color(preset_color);
|
|
|
+ }
|
|
|
+ sb_flat->set_bg_color(preset_color);
|
|
|
+ sb_flat->draw(get_canvas_item(), r);
|
|
|
+ } else if (sb_raw->get_class_name() == "StyleBoxTexture") {
|
|
|
+ if (preset_color.a < 1) {
|
|
|
+ // Draw a background pattern when the color is transparent.
|
|
|
+ bool use_tile_texture = (sb_texture->get_h_axis_stretch_mode() == StyleBoxTexture::AxisStretchMode::AXIS_STRETCH_MODE_TILE) || (sb_texture->get_h_axis_stretch_mode() == StyleBoxTexture::AxisStretchMode::AXIS_STRETCH_MODE_TILE_FIT);
|
|
|
+ draw_texture_rect(get_icon("preset_bg_icon", "ColorPresetButton"), r, use_tile_texture);
|
|
|
+ }
|
|
|
+ sb_texture->set_modulate(preset_color);
|
|
|
+ sb_texture->draw(get_canvas_item(), r);
|
|
|
+ } else {
|
|
|
+ WARN_PRINT("Unsupported StyleBox used for ColorPresetButton. Use StyleBoxFlat and StyleBoxTexture instead.");
|
|
|
+ }
|
|
|
+ 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_texture(Control::get_icon("overbright_indicator", "ColorPresetButton"), Vector2(0, 0));
|
|
|
+ }
|
|
|
+
|
|
|
+ } break;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void ColorPresetButton::set_preset_color(const Color &p_color) {
|
|
|
+ preset_color = p_color;
|
|
|
+}
|
|
|
+
|
|
|
+Color ColorPresetButton::get_preset_color() const {
|
|
|
+ return preset_color;
|
|
|
+}
|
|
|
+
|
|
|
+ColorPresetButton::ColorPresetButton(Color p_color) {
|
|
|
+ preset_color = p_color;
|
|
|
+}
|
|
|
+
|
|
|
+ColorPresetButton::~ColorPresetButton() {
|
|
|
+}
|