summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/2d/tile_map.cpp1
-rw-r--r--scene/gui/button.cpp6
-rw-r--r--scene/gui/color_mode.cpp330
-rw-r--r--scene/gui/color_mode.h143
-rw-r--r--scene/gui/color_picker.cpp505
-rw-r--r--scene/gui/color_picker.h93
-rw-r--r--scene/gui/dialogs.cpp28
-rw-r--r--scene/gui/dialogs.h7
-rw-r--r--scene/gui/file_dialog.cpp26
-rw-r--r--scene/gui/file_dialog.h2
-rw-r--r--scene/gui/rich_text_label.cpp4
-rw-r--r--scene/gui/text_edit.cpp4
-rw-r--r--scene/gui/tree.cpp32
-rw-r--r--scene/gui/tree.h2
-rw-r--r--scene/resources/default_theme/default_theme.cpp4
-rw-r--r--scene/resources/texture.cpp29
-rw-r--r--scene/resources/texture.h3
-rw-r--r--scene/resources/tile_set.cpp11
-rw-r--r--scene/resources/visual_shader_particle_nodes.cpp6
19 files changed, 885 insertions, 351 deletions
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index 9c4b0feea2..cf8b6b8f94 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -1158,6 +1158,7 @@ void TileMap::_rendering_update_dirty_quadrants(SelfList<TileMapQuadrant>::List
rs->canvas_item_set_transform(canvas_item, xform);
rs->canvas_item_set_light_mask(canvas_item, get_light_mask());
+ rs->canvas_item_set_z_as_relative_to_parent(canvas_item, true);
rs->canvas_item_set_z_index(canvas_item, z_index);
rs->canvas_item_set_default_texture_filter(canvas_item, RS::CanvasItemTextureFilter(get_texture_filter()));
diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp
index d23a4fff43..d8de22d27c 100644
--- a/scene/gui/button.cpp
+++ b/scene/gui/button.cpp
@@ -342,7 +342,11 @@ void Button::_notification(int p_what) {
} break;
}
- text_buf->draw_outline(ci, text_ofs, get_theme_constant(SNAME("outline_size")), get_theme_color(SNAME("font_outline_color")));
+ Color font_outline_color = get_theme_color(SNAME("font_outline_color"));
+ int outline_size = get_theme_constant(SNAME("outline_size"));
+ if (outline_size > 0 && font_outline_color.a > 0) {
+ text_buf->draw_outline(ci, text_ofs, outline_size, font_outline_color);
+ }
text_buf->draw(ci, text_ofs, color);
} break;
}
diff --git a/scene/gui/color_mode.cpp b/scene/gui/color_mode.cpp
new file mode 100644
index 0000000000..af78d67e5a
--- /dev/null
+++ b/scene/gui/color_mode.cpp
@@ -0,0 +1,330 @@
+/*************************************************************************/
+/* color_mode.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "color_mode.h"
+
+#include "core/math/color.h"
+#include "scene/gui/slider.h"
+#include "thirdparty/misc/ok_color.h"
+
+ColorMode::ColorMode(ColorPicker *p_color_picker) {
+ color_picker = p_color_picker;
+}
+
+String ColorModeRGB::get_slider_label(int idx) const {
+ ERR_FAIL_INDEX_V_MSG(idx, 3, String(), "Couldn't get slider label.");
+ return labels[idx];
+}
+
+float ColorModeRGB::get_slider_max(int idx) const {
+ ERR_FAIL_INDEX_V_MSG(idx, 4, 0, "Couldn't get slider max value.");
+ Color color = color_picker->get_pick_color();
+ return next_power_of_2(MAX(255, color.components[idx] * 255.0)) - 1;
+}
+
+float ColorModeRGB::get_slider_value(int idx) const {
+ ERR_FAIL_INDEX_V_MSG(idx, 4, 0, "Couldn't get slider value.");
+ return color_picker->get_pick_color().components[idx] * 255;
+}
+
+Color ColorModeRGB::get_color() const {
+ Vector<float> values = color_picker->get_active_slider_values();
+ Color color;
+ for (int i = 0; i < 4; i++) {
+ color.components[i] = values[i] / 255.0;
+ }
+ return color;
+}
+
+void ColorModeRGB::slider_draw(int p_which) {
+ Vector<Vector2> pos;
+ pos.resize(4);
+ Vector<Color> col;
+ col.resize(4);
+ HSlider *slider = color_picker->get_slider(p_which);
+ Size2 size = slider->get_size();
+ Color left_color;
+ Color right_color;
+ Color color = color_picker->get_pick_color();
+ const real_t margin = 4 * color_picker->get_theme_default_base_scale();
+
+ if (p_which == ColorPicker::SLIDER_COUNT) {
+ slider->draw_texture_rect(color_picker->get_theme_icon(SNAME("sample_bg"), SNAME("ColorPicker")), Rect2(Point2(0, margin), Size2(size.x, margin)), true);
+
+ left_color = color;
+ left_color.a = 0;
+ right_color = color;
+ right_color.a = 1;
+ } else {
+ left_color = Color(
+ p_which == 0 ? 0 : color.r,
+ p_which == 1 ? 0 : color.g,
+ p_which == 2 ? 0 : color.b);
+ right_color = Color(
+ p_which == 0 ? 1 : color.r,
+ p_which == 1 ? 1 : color.g,
+ p_which == 2 ? 1 : color.b);
+ }
+
+ col.set(0, left_color);
+ col.set(1, right_color);
+ col.set(2, right_color);
+ col.set(3, left_color);
+ pos.set(0, Vector2(0, margin));
+ pos.set(1, Vector2(size.x, margin));
+ pos.set(2, Vector2(size.x, margin * 2));
+ pos.set(3, Vector2(0, margin * 2));
+
+ slider->draw_polygon(pos, col);
+}
+
+String ColorModeHSV::get_slider_label(int idx) const {
+ ERR_FAIL_INDEX_V_MSG(idx, 3, String(), "Couldn't get slider label.");
+ return labels[idx];
+}
+
+float ColorModeHSV::get_slider_max(int idx) const {
+ ERR_FAIL_INDEX_V_MSG(idx, 4, 0, "Couldn't get slider max value.");
+ return slider_max[idx];
+}
+
+float ColorModeHSV::get_slider_value(int idx) const {
+ switch (idx) {
+ case 0:
+ return color_picker->get_pick_color().get_h() * 360.0;
+ case 1:
+ return color_picker->get_pick_color().get_s() * 100.0;
+ case 2:
+ return color_picker->get_pick_color().get_v() * 100.0;
+ case 3:
+ return Math::round(color_picker->get_pick_color().components[3] * 255.0);
+ default:
+ ERR_FAIL_V_MSG(0, "Couldn't get slider value.");
+ }
+}
+
+Color ColorModeHSV::get_color() const {
+ Vector<float> values = color_picker->get_active_slider_values();
+ Color color;
+ color.set_hsv(values[0] / 360.0, values[1] / 100.0, values[2] / 100.0, values[3] / 255.0);
+ return color;
+}
+
+void ColorModeHSV::slider_draw(int p_which) {
+ Vector<Vector2> pos;
+ pos.resize(4);
+ Vector<Color> col;
+ col.resize(4);
+ HSlider *slider = color_picker->get_slider(p_which);
+ Size2 size = slider->get_size();
+ Color left_color;
+ Color right_color;
+ Color color = color_picker->get_pick_color();
+ const real_t margin = 4 * color_picker->get_theme_default_base_scale();
+
+ if (p_which == ColorPicker::SLIDER_COUNT) {
+ slider->draw_texture_rect(color_picker->get_theme_icon(SNAME("sample_bg"), SNAME("ColorPicker")), Rect2(Point2(0, margin), Size2(size.x, margin)), true);
+
+ left_color = color;
+ left_color.a = 0;
+ right_color = color;
+ right_color.a = 1;
+ } else if (p_which == 0) {
+ Ref<Texture2D> hue = color_picker->get_theme_icon(SNAME("color_hue"), SNAME("ColorPicker"));
+ slider->draw_set_transform(Point2(), -Math_PI / 2, Size2(1.0, 1.0));
+ slider->draw_texture_rect(hue, Rect2(Vector2(margin * -2, 0), Vector2(slider->get_size().x, margin)), false, Color(1, 1, 1), true);
+ return;
+ } else {
+ Color s_col;
+ Color v_col;
+ s_col.set_hsv(color.get_h(), 0, color.get_v());
+ left_color = (p_which == 1) ? s_col : Color(0, 0, 0);
+ s_col.set_hsv(color.get_h(), 1, color.get_v());
+ v_col.set_hsv(color.get_h(), color.get_s(), 1);
+ right_color = (p_which == 1) ? s_col : v_col;
+ }
+ col.set(0, left_color);
+ col.set(1, right_color);
+ col.set(2, right_color);
+ col.set(3, left_color);
+ pos.set(0, Vector2(0, margin));
+ pos.set(1, Vector2(size.x, margin));
+ pos.set(2, Vector2(size.x, margin * 2));
+ pos.set(3, Vector2(0, margin * 2));
+
+ slider->draw_polygon(pos, col);
+}
+
+String ColorModeRAW::get_slider_label(int idx) const {
+ ERR_FAIL_INDEX_V_MSG(idx, 3, String(), "Couldn't get slider label.");
+ return labels[idx];
+}
+
+float ColorModeRAW::get_slider_max(int idx) const {
+ ERR_FAIL_INDEX_V_MSG(idx, 4, 0, "Couldn't get slider max value.");
+ return slider_max[idx];
+}
+
+float ColorModeRAW::get_slider_value(int idx) const {
+ ERR_FAIL_INDEX_V_MSG(idx, 4, 0, "Couldn't get slider value.");
+ return color_picker->get_pick_color().components[idx];
+}
+
+Color ColorModeRAW::get_color() const {
+ Vector<float> values = color_picker->get_active_slider_values();
+ Color color;
+ for (int i = 0; i < 4; i++) {
+ color.components[i] = values[i];
+ }
+ return color;
+}
+
+void ColorModeRAW::slider_draw(int p_which) {
+ Vector<Vector2> pos;
+ pos.resize(4);
+ Vector<Color> col;
+ col.resize(4);
+ HSlider *slider = color_picker->get_slider(p_which);
+ Size2 size = slider->get_size();
+ Color left_color;
+ Color right_color;
+ Color color = color_picker->get_pick_color();
+ const real_t margin = 4 * color_picker->get_theme_default_base_scale();
+
+ if (p_which == ColorPicker::SLIDER_COUNT) {
+ slider->draw_texture_rect(color_picker->get_theme_icon(SNAME("sample_bg"), SNAME("ColorPicker")), Rect2(Point2(0, margin), Size2(size.x, margin)), true);
+
+ left_color = color;
+ left_color.a = 0;
+ right_color = color;
+ right_color.a = 1;
+
+ col.set(0, left_color);
+ col.set(1, right_color);
+ col.set(2, right_color);
+ col.set(3, left_color);
+ pos.set(0, Vector2(0, margin));
+ pos.set(1, Vector2(size.x, margin));
+ pos.set(2, Vector2(size.x, margin * 2));
+ pos.set(3, Vector2(0, margin * 2));
+
+ slider->draw_polygon(pos, col);
+ }
+}
+
+bool ColorModeRAW::apply_theme() const {
+ for (int i = 0; i < 4; i++) {
+ HSlider *slider = color_picker->get_slider(i);
+ slider->remove_theme_icon_override("grabber");
+ slider->remove_theme_icon_override("grabber_highlight");
+ slider->remove_theme_style_override("slider");
+ slider->remove_theme_style_override("grabber_area");
+ slider->remove_theme_style_override("grabber_area_highlight");
+ }
+
+ return true;
+}
+
+String ColorModeOKHSL::get_slider_label(int idx) const {
+ ERR_FAIL_INDEX_V_MSG(idx, 3, String(), "Couldn't get slider label.");
+ return labels[idx];
+}
+
+float ColorModeOKHSL::get_slider_max(int idx) const {
+ ERR_FAIL_INDEX_V_MSG(idx, 4, 0, "Couldn't get slider max value.");
+ return slider_max[idx];
+}
+
+float ColorModeOKHSL::get_slider_value(int idx) const {
+ switch (idx) {
+ case 0:
+ return color_picker->get_pick_color().get_ok_hsl_h() * 360.0;
+ case 1:
+ return color_picker->get_pick_color().get_ok_hsl_s() * 100.0;
+ case 2:
+ return color_picker->get_pick_color().get_ok_hsl_l() * 100.0;
+ case 3:
+ return Math::round(color_picker->get_pick_color().components[3] * 255.0);
+ default:
+ ERR_FAIL_V_MSG(0, "Couldn't get slider value.");
+ }
+}
+
+Color ColorModeOKHSL::get_color() const {
+ Vector<float> values = color_picker->get_active_slider_values();
+ Color color;
+ color.set_ok_hsl(values[0] / 360.0, values[1] / 100.0, values[2] / 100.0, values[3] / 255.0);
+ return color;
+}
+
+void ColorModeOKHSL::slider_draw(int p_which) {
+ Vector<Vector2> pos;
+ pos.resize(4);
+ Vector<Color> col;
+ col.resize(4);
+ HSlider *slider = color_picker->get_slider(p_which);
+ Size2 size = slider->get_size();
+ Color left_color;
+ Color right_color;
+ Color color = color_picker->get_pick_color();
+ const real_t margin = 4 * color_picker->get_theme_default_base_scale();
+
+ if (p_which == ColorPicker::SLIDER_COUNT) {
+ slider->draw_texture_rect(color_picker->get_theme_icon(SNAME("sample_bg"), SNAME("ColorPicker")), Rect2(Point2(0, margin), Size2(size.x, margin)), true);
+
+ left_color = color;
+ left_color.a = 0;
+ right_color = color;
+ right_color.a = 1;
+ } else if (p_which == 0) {
+ Ref<Texture2D> hue = color_picker->get_theme_icon(SNAME("color_hue"), SNAME("ColorPicker"));
+ slider->draw_set_transform(Point2(), -Math_PI / 2, Size2(1.0, 1.0));
+ slider->draw_texture_rect(hue, Rect2(Vector2(margin * -2, 0), Vector2(slider->get_size().x, margin)), false, Color(1, 1, 1), true);
+ return;
+ } else {
+ Color s_col;
+ Color v_col;
+ s_col.set_ok_hsl(color.get_h(), 0, color.get_v());
+ left_color = (p_which == 1) ? s_col : Color(0, 0, 0);
+ s_col.set_ok_hsl(color.get_h(), 1, color.get_v());
+ v_col.set_ok_hsl(color.get_h(), color.get_s(), 1);
+ right_color = (p_which == 1) ? s_col : v_col;
+ }
+ col.set(0, left_color);
+ col.set(1, right_color);
+ col.set(2, right_color);
+ col.set(3, left_color);
+ pos.set(0, Vector2(0, margin));
+ pos.set(1, Vector2(size.x, margin));
+ pos.set(2, Vector2(size.x, margin * 2));
+ pos.set(3, Vector2(0, margin * 2));
+
+ slider->draw_polygon(pos, col);
+}
diff --git a/scene/gui/color_mode.h b/scene/gui/color_mode.h
new file mode 100644
index 0000000000..8a19699c40
--- /dev/null
+++ b/scene/gui/color_mode.h
@@ -0,0 +1,143 @@
+/*************************************************************************/
+/* color_mode.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef COLOR_MODE_H
+#define COLOR_MODE_H
+
+#include "scene/gui/color_picker.h"
+
+struct Color;
+
+class ColorMode {
+public:
+ ColorPicker *color_picker = nullptr;
+
+ virtual String get_name() const = 0;
+
+ virtual int get_slider_count() const { return 3; };
+ virtual float get_slider_step() const = 0;
+ virtual String get_slider_label(int idx) const = 0;
+ virtual float get_slider_max(int idx) const = 0;
+ virtual float get_slider_value(int idx) const = 0;
+
+ virtual Color get_color() const = 0;
+
+ virtual void slider_draw(int p_which) = 0;
+ virtual bool apply_theme() const { return false; }
+ virtual ColorPicker::PickerShapeType get_shape_override() const { return ColorPicker::SHAPE_MAX; }
+
+ ColorMode(ColorPicker *p_color_picker);
+ virtual ~ColorMode(){};
+};
+
+class ColorModeHSV : public ColorMode {
+public:
+ String labels[3] = { "H", "S", "V" };
+ float slider_max[4] = { 359, 100, 100, 255 };
+
+ virtual String get_name() const override { return "HSV"; }
+
+ virtual float get_slider_step() const override { return 1.0; }
+ virtual String get_slider_label(int idx) const override;
+ virtual float get_slider_max(int idx) const override;
+ virtual float get_slider_value(int idx) const override;
+
+ virtual Color get_color() const override;
+
+ virtual void slider_draw(int p_which) override;
+
+ ColorModeHSV(ColorPicker *p_color_picker) :
+ ColorMode(p_color_picker){};
+};
+
+class ColorModeRGB : public ColorMode {
+public:
+ String labels[3] = { "R", "G", "B" };
+
+ virtual String get_name() const override { return "RGB"; }
+
+ virtual float get_slider_step() const override { return 1; }
+ virtual String get_slider_label(int idx) const override;
+ virtual float get_slider_max(int idx) const override;
+ virtual float get_slider_value(int idx) const override;
+
+ virtual Color get_color() const override;
+
+ virtual void slider_draw(int p_which) override;
+
+ ColorModeRGB(ColorPicker *p_color_picker) :
+ ColorMode(p_color_picker){};
+};
+
+class ColorModeRAW : public ColorMode {
+public:
+ String labels[3] = { "R", "G", "B" };
+ float slider_max[4] = { 100, 100, 100, 1 };
+
+ virtual String get_name() const override { return "RAW"; }
+
+ virtual float get_slider_step() const override { return 0.01; }
+ virtual String get_slider_label(int idx) const override;
+ virtual float get_slider_max(int idx) const override;
+ virtual float get_slider_value(int idx) const override;
+
+ virtual Color get_color() const override;
+
+ virtual void slider_draw(int p_which) override;
+ virtual bool apply_theme() const override;
+
+ ColorModeRAW(ColorPicker *p_color_picker) :
+ ColorMode(p_color_picker){};
+};
+
+class ColorModeOKHSL : public ColorMode {
+public:
+ String labels[3] = { "H", "S", "L" };
+ float slider_max[4] = { 359, 100, 100, 255 };
+
+ virtual String get_name() const override { return "OKHSL"; }
+
+ virtual float get_slider_step() const override { return 1.0; }
+ virtual String get_slider_label(int idx) const override;
+ virtual float get_slider_max(int idx) const override;
+ virtual float get_slider_value(int idx) const override;
+
+ virtual Color get_color() const override;
+
+ virtual void slider_draw(int p_which) override;
+ virtual ColorPicker::PickerShapeType get_shape_override() const override { return ColorPicker::SHAPE_OKHSL_CIRCLE; }
+
+ ColorModeOKHSL(ColorPicker *p_color_picker) :
+ ColorMode(p_color_picker){};
+
+ ~ColorModeOKHSL(){};
+};
+
+#endif // COLOR_MODE_H
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index 28d645e8f6..492a81f933 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -34,7 +34,7 @@
#include "core/math/color.h"
#include "core/os/keyboard.h"
#include "core/os/os.h"
-#include "scene/main/window.h"
+#include "scene/gui/color_mode.h"
#ifdef TOOLS_ENABLED
#include "editor/editor_settings.h"
@@ -75,10 +75,14 @@ void ColorPicker::_notification(int p_what) {
wheel_edit->set_custom_minimum_size(Size2(get_theme_constant(SNAME("sv_width")), get_theme_constant(SNAME("sv_height"))));
wheel_margin->add_theme_constant_override("margin_bottom", 8 * get_theme_default_base_scale());
- for (int i = 0; i < 4; i++) {
+ for (int i = 0; i < SLIDER_COUNT; i++) {
labels[i]->set_custom_minimum_size(Size2(get_theme_constant(SNAME("label_width")), 0));
set_offset((Side)i, get_offset((Side)i) + get_theme_constant(SNAME("margin")));
}
+ alpha_label->set_custom_minimum_size(Size2(get_theme_constant(SNAME("label_width")), 0));
+ set_offset((Side)0, get_offset((Side)0) + get_theme_constant(SNAME("margin")));
+
+ _reset_theme();
if (Engine::get_singleton()->is_editor_hint()) {
// Adjust for the width of the "Script" icon.
@@ -194,75 +198,38 @@ void ColorPicker::set_focus_on_line_edit() {
}
void ColorPicker::_update_controls() {
- const char *rgb[3] = { "R", "G", "B" };
- const char *hsv[3] = { "H", "S", "V" };
- const char *hsl[3] = { "H", "S", "L" };
- if (hsv_mode_enabled && picker_type == SHAPE_OKHSL_CIRCLE) {
- for (int i = 0; i < 3; i++) {
- labels[i]->set_text(hsl[i]);
- }
- } else if (hsv_mode_enabled && picker_type != SHAPE_OKHSL_CIRCLE) {
- for (int i = 0; i < 3; i++) {
- labels[i]->set_text(hsv[i]);
- }
- } else {
- for (int i = 0; i < 3; i++) {
- labels[i]->set_text(rgb[i]);
- }
+ int mode_sliders_count = modes[current_mode]->get_slider_count();
+
+ for (int i = current_slider_count; i < mode_sliders_count; i++) {
+ sliders[i]->show();
+ labels[i]->show();
+ values[i]->show();
}
- if (picker_type == SHAPE_OKHSL_CIRCLE) {
- btn_hsv->set_text(RTR("OKHSL"));
- } else {
- btn_hsv->set_text(RTR("HSV"));
- }
- if (hsv_mode_enabled) {
- set_raw_mode(false);
- set_hsv_mode(true);
- btn_raw->set_disabled(true);
- } else if (raw_mode_enabled) {
- set_raw_mode(true);
- set_hsv_mode(false);
- btn_raw->set_disabled(false);
- btn_hsv->set_disabled(true);
- } else {
- set_raw_mode(false);
- set_hsv_mode(false);
- btn_raw->set_disabled(false);
- btn_hsv->set_disabled(false);
- }
-
- if (raw_mode_enabled) {
- for (int i = 0; i < 3; i++) {
- scroll[i]->remove_theme_icon_override("grabber");
- scroll[i]->remove_theme_icon_override("grabber_highlight");
- scroll[i]->remove_theme_style_override("slider");
- scroll[i]->remove_theme_style_override("grabber_area");
- scroll[i]->remove_theme_style_override("grabber_area_highlight");
- }
- } else {
- Ref<StyleBoxEmpty> style_box_empty(memnew(StyleBoxEmpty));
- Ref<Texture2D> bar_arrow = get_theme_icon(SNAME("bar_arrow"));
-
- for (int i = 0; i < 4; i++) {
- scroll[i]->add_theme_icon_override("grabber", bar_arrow);
- scroll[i]->add_theme_icon_override("grabber_highlight", bar_arrow);
- scroll[i]->add_theme_style_override("slider", style_box_empty);
- scroll[i]->add_theme_style_override("grabber_area", style_box_empty);
- scroll[i]->add_theme_style_override("grabber_area_highlight", style_box_empty);
- }
+ for (int i = mode_sliders_count; i < current_slider_count; i++) {
+ sliders[i]->hide();
+ labels[i]->hide();
+ values[i]->hide();
}
+ current_slider_count = mode_sliders_count;
+
+ for (int i = 0; i < current_slider_count; i++) {
+ labels[i]->set_text(modes[current_mode]->get_slider_label(i));
+ }
+ alpha_label->set_text("A");
+
+ slider_theme_modified = modes[current_mode]->apply_theme();
if (edit_alpha) {
- values[3]->show();
- scroll[3]->show();
- labels[3]->show();
+ alpha_value->show();
+ alpha_slider->show();
+ alpha_label->show();
} else {
- values[3]->hide();
- scroll[3]->hide();
- labels[3]->hide();
+ alpha_value->hide();
+ alpha_slider->hide();
+ alpha_label->hide();
}
- switch (picker_type) {
+ switch (_get_actual_shape()) {
case SHAPE_HSV_RECTANGLE:
wheel_edit->hide();
w_edit->show();
@@ -297,7 +264,7 @@ void ColorPicker::_update_controls() {
void ColorPicker::_set_pick_color(const Color &p_color, bool p_update_sliders) {
color = p_color;
if (color != last_color) {
- if (picker_type == SHAPE_OKHSL_CIRCLE) {
+ if (_get_actual_shape() == SHAPE_OKHSL_CIRCLE) {
h = color.get_ok_hsl_h();
s = color.get_ok_hsl_s();
v = color.get_ok_hsl_l();
@@ -353,27 +320,93 @@ void ColorPicker::_value_changed(double) {
return;
}
- if (hsv_mode_enabled) {
- h = scroll[0]->get_value() / 360.0;
- s = scroll[1]->get_value() / 100.0;
- v = scroll[2]->get_value() / 100.0;
- if (picker_type == SHAPE_OKHSL_CIRCLE) {
- color.set_ok_hsl(h, s, v, Math::round(scroll[3]->get_value() / 255.0));
- } else {
- color.set_hsv(h, s, v, Math::round(scroll[3]->get_value() / 255.0));
- }
+ color = modes[current_mode]->get_color();
+ if (current_mode == MODE_HSV || current_mode == MODE_OKHSL) {
+ h = sliders[0]->get_value() / 360.0;
+ s = sliders[1]->get_value() / 100.0;
+ v = sliders[2]->get_value() / 100.0;
last_color = color;
- } else {
- for (int i = 0; i < 4; i++) {
- color.components[i] = scroll[i]->get_value() / (raw_mode_enabled ? 1.0 : 255.0);
- }
}
_set_pick_color(color, false);
emit_signal(SNAME("color_changed"), color);
}
+void ColorPicker::add_mode(ColorMode *p_mode) {
+ modes.push_back(p_mode);
+ mode_option_button->add_item(RTR(p_mode->get_name()));
+}
+
+void ColorPicker::create_slider(GridContainer *gc, int idx) {
+ Label *l = memnew(Label());
+ l->set_v_size_flags(SIZE_SHRINK_CENTER);
+ gc->add_child(l);
+
+ HSlider *s = memnew(HSlider);
+ s->set_v_size_flags(SIZE_SHRINK_CENTER);
+ s->set_focus_mode(FOCUS_NONE);
+ gc->add_child(s);
+
+ SpinBox *v = memnew(SpinBox);
+ s->share(v);
+ gc->add_child(v);
+ v->get_line_edit()->connect("focus_entered", callable_mp(this, &ColorPicker::_focus_enter));
+ v->get_line_edit()->connect("focus_exited", callable_mp(this, &ColorPicker::_focus_exit));
+
+ s->set_h_size_flags(SIZE_EXPAND_FILL);
+
+ s->connect("value_changed", callable_mp(this, &ColorPicker::_value_changed));
+ s->connect("draw", callable_mp(this, &ColorPicker::_slider_draw), make_binds(idx));
+
+ if (idx < SLIDER_COUNT) {
+ sliders[idx] = s;
+ values[idx] = v;
+ labels[idx] = l;
+ } else {
+ alpha_slider = s;
+ alpha_value = v;
+ alpha_label = l;
+ }
+}
+
+HSlider *ColorPicker::get_slider(int idx) {
+ if (idx < SLIDER_COUNT) {
+ return sliders[idx];
+ }
+ return alpha_slider;
+}
+
+Vector<float> ColorPicker::get_active_slider_values() {
+ Vector<float> values;
+ for (int i = 0; i < current_slider_count; i++) {
+ values.push_back(sliders[i]->get_value());
+ }
+ values.push_back(alpha_slider->get_value());
+ return values;
+}
+
+ColorPicker::PickerShapeType ColorPicker::_get_actual_shape() const {
+ return modes[current_mode]->get_shape_override() != SHAPE_MAX ? modes[current_mode]->get_shape_override() : current_shape;
+}
+
+void ColorPicker::_reset_theme() {
+ Ref<StyleBoxEmpty> style_box_empty(memnew(StyleBoxEmpty));
+
+ for (int i = 0; i < SLIDER_COUNT; i++) {
+ sliders[i]->add_theme_icon_override("grabber", get_theme_icon(SNAME("bar_arrow"), SNAME("ColorPicker")));
+ sliders[i]->add_theme_icon_override("grabber_highlight", get_theme_icon(SNAME("bar_arrow"), SNAME("ColorPicker")));
+ sliders[i]->add_theme_style_override("slider", style_box_empty);
+ sliders[i]->add_theme_style_override("grabber_area", style_box_empty);
+ sliders[i]->add_theme_style_override("grabber_area_highlight", style_box_empty);
+ }
+ alpha_slider->add_theme_icon_override("grabber", get_theme_icon(SNAME("bar_arrow"), SNAME("ColorPicker")));
+ alpha_slider->add_theme_icon_override("grabber_highlight", get_theme_icon(SNAME("bar_arrow"), SNAME("ColorPicker")));
+ alpha_slider->add_theme_style_override("slider", style_box_empty);
+ alpha_slider->add_theme_style_override("grabber_area", style_box_empty);
+ alpha_slider->add_theme_style_override("grabber_area_highlight", style_box_empty);
+}
+
void ColorPicker::_html_submitted(const String &p_html) {
if (updating || text_is_constructor || !c_text->is_visible()) {
return;
@@ -397,35 +430,15 @@ void ColorPicker::_update_color(bool p_update_sliders) {
updating = true;
if (p_update_sliders) {
- if (hsv_mode_enabled) {
- for (int i = 0; i < 4; i++) {
- scroll[i]->set_step(1.0);
- }
- scroll[0]->set_max(359);
- scroll[0]->set_value(h * 360.0);
- scroll[1]->set_max(100);
- scroll[1]->set_value(s * 100.0);
- scroll[2]->set_max(100);
- scroll[2]->set_value(v * 100.0);
- scroll[3]->set_max(255);
- scroll[3]->set_value(Math::round(color.components[3] * 255.0));
- } else {
- for (int i = 0; i < 4; i++) {
- if (raw_mode_enabled) {
- scroll[i]->set_step(0.01);
- scroll[i]->set_max(100);
- if (i == 3) {
- scroll[i]->set_max(1);
- }
- scroll[i]->set_value(color.components[i]);
- } else {
- scroll[i]->set_step(1);
- const float byte_value = Math::round(color.components[i] * 255.0);
- scroll[i]->set_max(next_power_of_2(MAX(255, byte_value)) - 1);
- scroll[i]->set_value(byte_value);
- }
- }
+ float step = modes[current_mode]->get_slider_step();
+ for (int i = 0; i < current_slider_count; i++) {
+ sliders[i]->set_max(modes[current_mode]->get_slider_max(i));
+ sliders[i]->set_step(step);
+ sliders[i]->set_value(modes[current_mode]->get_slider_value(i));
}
+ alpha_slider->set_max(modes[current_mode]->get_slider_max(current_slider_count));
+ alpha_slider->set_step(step);
+ alpha_slider->set_value(modes[current_mode]->get_slider_value(current_slider_count));
}
_update_text_value();
@@ -433,9 +446,10 @@ void ColorPicker::_update_color(bool p_update_sliders) {
sample->update();
uv_edit->update();
w_edit->update();
- for (int i = 0; i < 4; i++) {
- scroll[i]->update();
+ for (int i = 0; i < current_slider_count; i++) {
+ sliders[i]->update();
}
+ alpha_slider->update();
wheel->update();
wheel_uv->update();
updating = false;
@@ -481,15 +495,16 @@ Color ColorPicker::get_pick_color() const {
return color;
}
-void ColorPicker::set_picker_shape(PickerShapeType p_picker_type) {
- ERR_FAIL_INDEX(p_picker_type, SHAPE_MAX);
- picker_type = p_picker_type;
+void ColorPicker::set_picker_shape(PickerShapeType p_shape) {
+ ERR_FAIL_INDEX(p_shape, SHAPE_MAX);
+ current_shape = p_shape;
+
_update_controls();
_update_color();
}
ColorPicker::PickerShapeType ColorPicker::get_picker_shape() const {
- return picker_type;
+ return current_shape;
}
inline int ColorPicker::_get_preset_size() {
@@ -505,6 +520,21 @@ void ColorPicker::_add_preset_button(int p_size, const Color &p_color) {
preset_container->add_child(btn_preset);
}
+void ColorPicker::_set_color_mode(ColorModeType p_mode) {
+ if (slider_theme_modified) {
+ _reset_theme();
+ }
+
+ current_mode = p_mode;
+
+ if (!is_inside_tree()) {
+ return;
+ }
+
+ _update_controls();
+ _update_color();
+}
+
void ColorPicker::add_preset(const Color &p_color) {
if (presets.find(p_color)) {
presets.move_to_back(presets.find(p_color));
@@ -564,46 +594,14 @@ PackedColorArray ColorPicker::get_presets() const {
return arr;
}
-void ColorPicker::set_hsv_mode(bool p_enabled) {
- if (hsv_mode_enabled == p_enabled || raw_mode_enabled) {
- return;
- }
- hsv_mode_enabled = p_enabled;
- if (btn_hsv->is_pressed() != p_enabled) {
- btn_hsv->set_pressed(p_enabled);
- }
-
- if (!is_inside_tree()) {
- return;
- }
-
- _update_controls();
- _update_color();
-}
-
-bool ColorPicker::is_hsv_mode() const {
- return hsv_mode_enabled;
-}
-
-void ColorPicker::set_raw_mode(bool p_enabled) {
- if (raw_mode_enabled == p_enabled || hsv_mode_enabled) {
- return;
- }
- raw_mode_enabled = p_enabled;
- if (btn_raw->is_pressed() != p_enabled) {
- btn_raw->set_pressed(p_enabled);
- }
-
- if (!is_inside_tree()) {
- return;
- }
-
- _update_controls();
- _update_color();
+void ColorPicker::set_color_mode(ColorModeType p_mode) {
+ ERR_FAIL_INDEX(p_mode, MODE_MAX);
+ mode_option_button->select(p_mode);
+ _set_color_mode(p_mode);
}
-bool ColorPicker::is_raw_mode() const {
- return raw_mode_enabled;
+ColorPicker::ColorModeType ColorPicker::get_color_mode() const {
+ return current_mode;
}
void ColorPicker::set_deferred_mode(bool p_enabled) {
@@ -690,6 +688,8 @@ void ColorPicker::_hsv_draw(int p_which, Control *c) {
if (!c) {
return;
}
+
+ PickerShapeType actual_shape = _get_actual_shape();
if (p_which == 0) {
Vector<Point2> points;
Vector<Color> colors;
@@ -697,7 +697,7 @@ void ColorPicker::_hsv_draw(int p_which, Control *c) {
Color col = color;
Vector2 center = c->get_size() / 2.0;
- switch (picker_type) {
+ switch (actual_shape) {
case SHAPE_HSV_WHEEL: {
points.resize(4);
colors.resize(4);
@@ -759,7 +759,7 @@ void ColorPicker::_hsv_draw(int p_which, Control *c) {
Ref<Texture2D> cursor = get_theme_icon(SNAME("picker_cursor"), SNAME("ColorPicker"));
int x;
int y;
- if (picker_type == SHAPE_VHS_CIRCLE || picker_type == SHAPE_OKHSL_CIRCLE) {
+ if (actual_shape == SHAPE_VHS_CIRCLE || actual_shape == SHAPE_OKHSL_CIRCLE) {
x = center.x + (center.x * Math::cos(h * Math_TAU) * s) - (cursor->get_width() / 2);
y = center.y + (center.y * Math::sin(h * Math_TAU) * s) - (cursor->get_height() / 2);
} else {
@@ -773,7 +773,7 @@ void ColorPicker::_hsv_draw(int p_which, Control *c) {
c->draw_texture(cursor, Point2(x, y));
col.set_hsv(h, 1, 1);
- if (picker_type == SHAPE_HSV_WHEEL) {
+ if (actual_shape == SHAPE_HSV_WHEEL) {
points.resize(4);
double h1 = h - (0.5 / 360);
double h2 = h + (0.5 / 360);
@@ -785,14 +785,14 @@ void ColorPicker::_hsv_draw(int p_which, Control *c) {
}
} else if (p_which == 1) {
- if (picker_type == SHAPE_HSV_RECTANGLE) {
+ if (actual_shape == SHAPE_HSV_RECTANGLE) {
Ref<Texture2D> hue = get_theme_icon(SNAME("color_hue"), SNAME("ColorPicker"));
c->draw_texture_rect(hue, Rect2(Point2(), c->get_size()));
int y = c->get_size().y - c->get_size().y * (1.0 - h);
Color col;
col.set_hsv(h, 1, 1);
c->draw_line(Point2(0, y), Point2(c->get_size().x, y), col.inverted());
- } else if (picker_type == SHAPE_OKHSL_CIRCLE) {
+ } else if (actual_shape == SHAPE_OKHSL_CIRCLE) {
Vector<Point2> points;
Vector<Color> colors;
Color col;
@@ -811,7 +811,7 @@ void ColorPicker::_hsv_draw(int p_which, Control *c) {
int y = c->get_size().y - c->get_size().y * CLAMP(v, 0, 1);
col.set_ok_hsl(h, 1, v);
c->draw_line(Point2(0, y), Point2(c->get_size().x, y), col.inverted());
- } else if (picker_type == SHAPE_VHS_CIRCLE) {
+ } else if (actual_shape == SHAPE_VHS_CIRCLE) {
Vector<Point2> points;
Vector<Color> colors;
Color col;
@@ -833,87 +833,24 @@ void ColorPicker::_hsv_draw(int p_which, Control *c) {
}
} else if (p_which == 2) {
c->draw_rect(Rect2(Point2(), c->get_size()), Color(1, 1, 1));
- if (picker_type == SHAPE_VHS_CIRCLE || picker_type == SHAPE_OKHSL_CIRCLE) {
+ if (actual_shape == SHAPE_VHS_CIRCLE || actual_shape == SHAPE_OKHSL_CIRCLE) {
circle_mat->set_shader_param("v", v);
}
}
}
void ColorPicker::_slider_draw(int p_which) {
- Vector<Vector2> pos;
- pos.resize(4);
- Vector<Color> col;
- col.resize(4);
- Size2 size = scroll[p_which]->get_size();
- Color left_color;
- Color right_color;
- const real_t margin = 4 * get_theme_default_base_scale();
-
- if (p_which == 3) {
- scroll[p_which]->draw_texture_rect(get_theme_icon(SNAME("sample_bg"), SNAME("ColorPicker")), Rect2(Point2(0, margin), Size2(size.x, margin)), true);
-
- left_color = color;
- left_color.a = 0;
- right_color = color;
- right_color.a = 1;
- } else {
- if (raw_mode_enabled) {
- return;
- }
- if (hsv_mode_enabled) {
- if (p_which == 0) {
- Ref<Texture2D> hue = get_theme_icon(SNAME("color_hue"), SNAME("ColorPicker"));
- scroll[p_which]->draw_set_transform(Point2(), -Math_PI / 2, Size2(1.0, 1.0));
- scroll[p_which]->draw_texture_rect(hue, Rect2(Vector2(margin * -2, 0), Vector2(scroll[p_which]->get_size().x, margin)), false, Color(1, 1, 1), true);
- return;
- }
- Color s_col;
- Color v_col;
- if (picker_type == SHAPE_OKHSL_CIRCLE) {
- s_col.set_ok_hsl(h, 0, v);
- } else {
- s_col.set_hsv(h, 0, v);
- }
- left_color = (p_which == 1) ? s_col : Color(0, 0, 0);
- if (picker_type == SHAPE_OKHSL_CIRCLE) {
- s_col.set_ok_hsl(h, 1, v);
- v_col.set_ok_hsl(h, s, 1);
- } else {
- s_col.set_hsv(h, 1, v);
- v_col.set_hsv(h, s, 1);
- }
- right_color = (p_which == 1) ? s_col : v_col;
- } else {
- left_color = Color(
- p_which == 0 ? 0 : color.r,
- p_which == 1 ? 0 : color.g,
- p_which == 2 ? 0 : color.b);
- right_color = Color(
- p_which == 0 ? 1 : color.r,
- p_which == 1 ? 1 : color.g,
- p_which == 2 ? 1 : color.b);
- }
- }
-
- col.set(0, left_color);
- col.set(1, right_color);
- col.set(2, right_color);
- col.set(3, left_color);
- pos.set(0, Vector2(0, margin));
- pos.set(1, Vector2(size.x, margin));
- pos.set(2, Vector2(size.x, margin * 2));
- pos.set(3, Vector2(0, margin * 2));
-
- scroll[p_which]->draw_polygon(pos, col);
+ modes[current_mode]->slider_draw(p_which);
}
void ColorPicker::_uv_input(const Ref<InputEvent> &p_event, Control *c) {
Ref<InputEventMouseButton> bev = p_event;
+ PickerShapeType current_picker = _get_actual_shape();
if (bev.is_valid()) {
if (bev->is_pressed() && bev->get_button_index() == MouseButton::LEFT) {
Vector2 center = c->get_size() / 2.0;
- if (picker_type == SHAPE_VHS_CIRCLE || picker_type == SHAPE_OKHSL_CIRCLE) {
+ if (current_picker == SHAPE_VHS_CIRCLE || current_picker == SHAPE_OKHSL_CIRCLE) {
real_t dist = center.distance_to(bev->get_position());
if (dist <= center.x) {
real_t rad = center.angle_to_point(bev->get_position());
@@ -951,11 +888,12 @@ void ColorPicker::_uv_input(const Ref<InputEvent> &p_event, Control *c) {
}
}
changing_color = true;
- if (picker_type == SHAPE_OKHSL_CIRCLE) {
+ if (current_picker == SHAPE_OKHSL_CIRCLE) {
color.set_ok_hsl(h, s, v, color.a);
- } else if (picker_type != SHAPE_OKHSL_CIRCLE) {
+ } else {
color.set_hsv(h, s, v, color.a);
}
+
last_color = color;
set_pick_color(color);
@@ -981,7 +919,7 @@ void ColorPicker::_uv_input(const Ref<InputEvent> &p_event, Control *c) {
}
Vector2 center = c->get_size() / 2.0;
- if (picker_type == SHAPE_VHS_CIRCLE || picker_type == SHAPE_OKHSL_CIRCLE) {
+ if (current_picker == SHAPE_VHS_CIRCLE || current_picker == SHAPE_OKHSL_CIRCLE) {
real_t dist = center.distance_to(mev->get_position());
real_t rad = center.angle_to_point(mev->get_position());
h = ((rad >= 0) ? rad : (Math_TAU + rad)) / Math_TAU;
@@ -1002,9 +940,9 @@ void ColorPicker::_uv_input(const Ref<InputEvent> &p_event, Control *c) {
v = 1.0 - (y - corner_y) / real_size.y;
}
}
- if (picker_type != SHAPE_OKHSL_CIRCLE) {
+ if (current_picker != SHAPE_OKHSL_CIRCLE) {
color.set_hsv(h, s, v, color.a);
- } else if (picker_type == SHAPE_OKHSL_CIRCLE) {
+ } else {
color.set_ok_hsl(h, s, v, color.a);
}
last_color = color;
@@ -1018,12 +956,13 @@ void ColorPicker::_uv_input(const Ref<InputEvent> &p_event, Control *c) {
void ColorPicker::_w_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> bev = p_event;
+ PickerShapeType actual_shape = _get_actual_shape();
if (bev.is_valid()) {
if (bev->is_pressed() && bev->get_button_index() == MouseButton::LEFT) {
changing_color = true;
float y = CLAMP((float)bev->get_position().y, 0, w_edit->get_size().height);
- if (picker_type == SHAPE_VHS_CIRCLE || picker_type == SHAPE_OKHSL_CIRCLE) {
+ if (actual_shape == SHAPE_VHS_CIRCLE || actual_shape == SHAPE_OKHSL_CIRCLE) {
v = 1.0 - (y / w_edit->get_size().height);
} else {
h = y / w_edit->get_size().height;
@@ -1031,9 +970,9 @@ void ColorPicker::_w_input(const Ref<InputEvent> &p_event) {
} else {
changing_color = false;
}
- if (picker_type != SHAPE_OKHSL_CIRCLE) {
+ if (actual_shape != SHAPE_OKHSL_CIRCLE) {
color.set_hsv(h, s, v, color.a);
- } else if (picker_type == SHAPE_OKHSL_CIRCLE) {
+ } else {
color.set_ok_hsl(h, s, v, color.a);
}
last_color = color;
@@ -1053,16 +992,18 @@ void ColorPicker::_w_input(const Ref<InputEvent> &p_event) {
return;
}
float y = CLAMP((float)mev->get_position().y, 0, w_edit->get_size().height);
- if (picker_type == SHAPE_VHS_CIRCLE || picker_type == SHAPE_OKHSL_CIRCLE) {
+ if (actual_shape == SHAPE_VHS_CIRCLE || actual_shape == SHAPE_OKHSL_CIRCLE) {
v = 1.0 - (y / w_edit->get_size().height);
} else {
h = y / w_edit->get_size().height;
}
- if (hsv_mode_enabled && picker_type != SHAPE_OKHSL_CIRCLE) {
+
+ if (current_mode == MODE_HSV) {
color.set_hsv(h, s, v, color.a);
- } else if (hsv_mode_enabled && picker_type == SHAPE_OKHSL_CIRCLE) {
+ } else if (current_mode == MODE_OKHSL) {
color.set_ok_hsl(h, s, v, color.a);
}
+
last_color = color;
set_pick_color(color);
_update_color();
@@ -1153,21 +1094,30 @@ void ColorPicker::_focus_enter() {
c_text->select(0, 0);
}
- for (int i = 0; i < 4; i++) {
+ for (int i = 0; i < current_slider_count; i++) {
if (values[i]->get_line_edit()->has_focus() && !has_ctext_focus) {
values[i]->get_line_edit()->select_all();
} else {
values[i]->get_line_edit()->select(0, 0);
}
}
+ if (alpha_value->get_line_edit()->has_focus() && !has_ctext_focus) {
+ alpha_value->get_line_edit()->select_all();
+ } else {
+ alpha_value->get_line_edit()->select(0, 0);
+ }
}
void ColorPicker::_focus_exit() {
- for (int i = 0; i < 4; i++) {
+ for (int i = 0; i < current_slider_count; i++) {
if (!values[i]->get_line_edit()->get_menu()->is_visible()) {
values[i]->get_line_edit()->select(0, 0);
}
}
+ if (!alpha_value->get_line_edit()->get_menu()->is_visible()) {
+ alpha_value->get_line_edit()->select(0, 0);
+ }
+
c_text->select(0, 0);
}
@@ -1207,12 +1157,10 @@ bool ColorPicker::are_presets_visible() const {
void ColorPicker::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_pick_color", "color"), &ColorPicker::set_pick_color);
ClassDB::bind_method(D_METHOD("get_pick_color"), &ColorPicker::get_pick_color);
- ClassDB::bind_method(D_METHOD("set_hsv_mode", "enabled"), &ColorPicker::set_hsv_mode);
- ClassDB::bind_method(D_METHOD("is_hsv_mode"), &ColorPicker::is_hsv_mode);
- ClassDB::bind_method(D_METHOD("set_raw_mode", "enabled"), &ColorPicker::set_raw_mode);
- ClassDB::bind_method(D_METHOD("is_raw_mode"), &ColorPicker::is_raw_mode);
ClassDB::bind_method(D_METHOD("set_deferred_mode", "mode"), &ColorPicker::set_deferred_mode);
ClassDB::bind_method(D_METHOD("is_deferred_mode"), &ColorPicker::is_deferred_mode);
+ ClassDB::bind_method(D_METHOD("set_color_mode", "color_mode"), &ColorPicker::set_color_mode);
+ ClassDB::bind_method(D_METHOD("get_color_mode"), &ColorPicker::get_color_mode);
ClassDB::bind_method(D_METHOD("set_edit_alpha", "show"), &ColorPicker::set_edit_alpha);
ClassDB::bind_method(D_METHOD("is_editing_alpha"), &ColorPicker::is_editing_alpha);
ClassDB::bind_method(D_METHOD("set_presets_enabled", "enabled"), &ColorPicker::set_presets_enabled);
@@ -1222,13 +1170,12 @@ void ColorPicker::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_preset", "color"), &ColorPicker::add_preset);
ClassDB::bind_method(D_METHOD("erase_preset", "color"), &ColorPicker::erase_preset);
ClassDB::bind_method(D_METHOD("get_presets"), &ColorPicker::get_presets);
- ClassDB::bind_method(D_METHOD("set_picker_shape", "picker"), &ColorPicker::set_picker_shape);
+ ClassDB::bind_method(D_METHOD("set_picker_shape", "shape"), &ColorPicker::set_picker_shape);
ClassDB::bind_method(D_METHOD("get_picker_shape"), &ColorPicker::get_picker_shape);
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_pick_color", "get_pick_color");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "edit_alpha"), "set_edit_alpha", "is_editing_alpha");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hsv_mode"), "set_hsv_mode", "is_hsv_mode");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "raw_mode"), "set_raw_mode", "is_raw_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "color_mode", PROPERTY_HINT_ENUM, "RGB,HSV,RAW,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"), "set_picker_shape", "get_picker_shape");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "presets_enabled"), "set_presets_enabled", "are_presets_enabled");
@@ -1238,6 +1185,11 @@ void ColorPicker::_bind_methods() {
ADD_SIGNAL(MethodInfo("preset_added", PropertyInfo(Variant::COLOR, "color")));
ADD_SIGNAL(MethodInfo("preset_removed", PropertyInfo(Variant::COLOR, "color")));
+ BIND_ENUM_CONSTANT(MODE_RGB);
+ BIND_ENUM_CONSTANT(MODE_HSV);
+ BIND_ENUM_CONSTANT(MODE_RAW);
+ BIND_ENUM_CONSTANT(MODE_OKHSL);
+
BIND_ENUM_CONSTANT(SHAPE_HSV_RECTANGLE);
BIND_ENUM_CONSTANT(SHAPE_HSV_WHEEL);
BIND_ENUM_CONSTANT(SHAPE_VHS_CIRCLE);
@@ -1250,6 +1202,7 @@ ColorPicker::ColorPicker() :
add_child(hb_edit, false, INTERNAL_MODE_FRONT);
hb_edit->set_v_size_flags(SIZE_EXPAND_FILL);
+ uv_edit = memnew(Control);
hb_edit->add_child(uv_edit);
uv_edit->connect("gui_input", callable_mp(this, &ColorPicker::_uv_input), make_binds(uv_edit));
uv_edit->set_mouse_filter(MOUSE_FILTER_PASS);
@@ -1260,11 +1213,13 @@ ColorPicker::ColorPicker() :
HBoxContainer *hb_smpl = memnew(HBoxContainer);
add_child(hb_smpl, false, INTERNAL_MODE_FRONT);
+ sample = memnew(TextureRect);
hb_smpl->add_child(sample);
sample->set_h_size_flags(SIZE_EXPAND_FILL);
sample->connect("gui_input", callable_mp(this, &ColorPicker::_sample_input));
sample->connect("draw", callable_mp(this, &ColorPicker::_sample_draw));
+ btn_pick = memnew(Button);
btn_pick->set_flat(true);
hb_smpl->add_child(btn_pick);
btn_pick->set_toggle_mode(true);
@@ -1277,51 +1232,35 @@ ColorPicker::ColorPicker() :
add_child(memnew(HSeparator), false, INTERNAL_MODE_FRONT);
VBoxContainer *vbr = memnew(VBoxContainer);
+
add_child(vbr, false, INTERNAL_MODE_FRONT);
vbr->set_h_size_flags(SIZE_EXPAND_FILL);
- for (int i = 0; i < 4; i++) {
- HBoxContainer *hbc = memnew(HBoxContainer);
+ GridContainer *gc = memnew(GridContainer);
- labels[i] = memnew(Label());
- labels[i]->set_custom_minimum_size(Size2(get_theme_constant(SNAME("label_width")), 0));
- labels[i]->set_v_size_flags(SIZE_SHRINK_CENTER);
- hbc->add_child(labels[i]);
+ vbr->add_child(gc);
+ gc->set_h_size_flags(SIZE_EXPAND_FILL);
+ gc->set_columns(3);
- scroll[i] = memnew(HSlider);
- scroll[i]->set_v_size_flags(SIZE_SHRINK_CENTER);
- scroll[i]->set_focus_mode(FOCUS_NONE);
- hbc->add_child(scroll[i]);
-
- values[i] = memnew(SpinBox);
- scroll[i]->share(values[i]);
- hbc->add_child(values[i]);
- values[i]->get_line_edit()->connect("focus_entered", callable_mp(this, &ColorPicker::_focus_enter));
- values[i]->get_line_edit()->connect("focus_exited", callable_mp(this, &ColorPicker::_focus_exit));
-
- scroll[i]->set_min(0);
- scroll[i]->set_page(0);
- scroll[i]->set_h_size_flags(SIZE_EXPAND_FILL);
-
- scroll[i]->connect("value_changed", callable_mp(this, &ColorPicker::_value_changed));
- scroll[i]->connect("draw", callable_mp(this, &ColorPicker::_slider_draw), make_binds(i));
-
- vbr->add_child(hbc);
+ for (int i = 0; i < SLIDER_COUNT + 1; i++) {
+ create_slider(gc, i);
}
- labels[3]->set_text("A");
+ alpha_label->set_text("A");
HBoxContainer *hhb = memnew(HBoxContainer);
vbr->add_child(hhb);
- hhb->add_child(btn_hsv);
- btn_hsv->set_text(RTR("HSV"));
- btn_hsv->connect("toggled", callable_mp(this, &ColorPicker::set_hsv_mode));
+ mode_option_button = memnew(OptionButton);
- hhb->add_child(btn_raw);
- btn_raw->set_text(RTR("Raw"));
- btn_raw->connect("toggled", callable_mp(this, &ColorPicker::set_raw_mode));
+ hhb->add_child(mode_option_button);
+ add_mode(new ColorModeRGB(this));
+ add_mode(new ColorModeHSV(this));
+ add_mode(new ColorModeRAW(this));
+ add_mode(new ColorModeOKHSL(this));
+ mode_option_button->connect("item_selected", callable_mp(this, &ColorPicker::_set_color_mode));
+ text_type = memnew(Button);
hhb->add_child(text_type);
text_type->set_text("#");
text_type->set_tooltip(RTR("Switch between hexadecimal and code values."));
@@ -1332,12 +1271,14 @@ ColorPicker::ColorPicker() :
text_type->set_mouse_filter(MOUSE_FILTER_IGNORE);
}
+ c_text = memnew(LineEdit);
hhb->add_child(c_text);
c_text->set_h_size_flags(SIZE_EXPAND_FILL);
c_text->connect("text_submitted", callable_mp(this, &ColorPicker::_html_submitted));
c_text->connect("focus_entered", callable_mp(this, &ColorPicker::_focus_enter));
c_text->connect("focus_exited", callable_mp(this, &ColorPicker::_html_focus_exit));
+ wheel_edit = memnew(AspectRatioContainer);
wheel_edit->set_h_size_flags(SIZE_EXPAND_FILL);
wheel_edit->set_v_size_flags(SIZE_EXPAND_FILL);
hb_edit->add_child(wheel_edit);
@@ -1347,41 +1288,53 @@ ColorPicker::ColorPicker() :
circle_mat.instantiate();
circle_mat->set_shader(circle_shader);
+ wheel_margin = memnew(MarginContainer);
wheel_margin->add_theme_constant_override("margin_bottom", 8);
wheel_edit->add_child(wheel_margin);
+ wheel = memnew(Control);
wheel_margin->add_child(wheel);
wheel->set_mouse_filter(MOUSE_FILTER_PASS);
wheel->connect("draw", callable_mp(this, &ColorPicker::_hsv_draw), make_binds(2, wheel));
+ wheel_uv = memnew(Control);
wheel_margin->add_child(wheel_uv);
wheel_uv->connect("gui_input", callable_mp(this, &ColorPicker::_uv_input), make_binds(wheel_uv));
wheel_uv->connect("draw", callable_mp(this, &ColorPicker::_hsv_draw), make_binds(0, wheel_uv));
+ w_edit = memnew(Control);
hb_edit->add_child(w_edit);
w_edit->set_h_size_flags(SIZE_FILL);
w_edit->set_v_size_flags(SIZE_EXPAND_FILL);
w_edit->connect("gui_input", callable_mp(this, &ColorPicker::_w_input));
w_edit->connect("draw", callable_mp(this, &ColorPicker::_hsv_draw), make_binds(1, w_edit));
- picker_type = SHAPE_HSV_RECTANGLE;
_update_controls();
updating = false;
set_pick_color(Color(1, 1, 1));
+ preset_separator = memnew(HSeparator);
add_child(preset_separator, false, INTERNAL_MODE_FRONT);
+ preset_container = memnew(GridContainer);
preset_container->set_h_size_flags(SIZE_EXPAND_FILL);
preset_container->set_columns(preset_column_count);
add_child(preset_container, false, INTERNAL_MODE_FRONT);
+ btn_add_preset = memnew(Button);
btn_add_preset->set_icon_alignment(HORIZONTAL_ALIGNMENT_CENTER);
btn_add_preset->set_tooltip(RTR("Add current color as a preset."));
btn_add_preset->connect("pressed", callable_mp(this, &ColorPicker::_add_preset_pressed));
preset_container->add_child(btn_add_preset);
}
+ColorPicker::~ColorPicker() {
+ for (int i = 0; i < modes.size(); i++) {
+ delete modes[i];
+ }
+}
+
/////////////////
void ColorPickerButton::_about_to_popup() {
diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h
index 953be032ec..e219c78319 100644
--- a/scene/gui/color_picker.h
+++ b/scene/gui/color_picker.h
@@ -34,16 +34,23 @@
#include "scene/gui/aspect_ratio_container.h"
#include "scene/gui/box_container.h"
#include "scene/gui/button.h"
-#include "scene/gui/check_button.h"
+#include "scene/gui/control.h"
#include "scene/gui/grid_container.h"
#include "scene/gui/label.h"
#include "scene/gui/line_edit.h"
+#include "scene/gui/option_button.h"
#include "scene/gui/popup.h"
#include "scene/gui/separator.h"
#include "scene/gui/slider.h"
#include "scene/gui/spin_box.h"
#include "scene/gui/texture_rect.h"
+class ColorMode;
+class ColorModeRGB;
+class ColorModeHSV;
+class ColorModeRAW;
+class ColorModeOKHSL;
+
class ColorPresetButton : public BaseButton {
GDCLASS(ColorPresetButton, BaseButton);
@@ -64,6 +71,15 @@ class ColorPicker : public BoxContainer {
GDCLASS(ColorPicker, BoxContainer);
public:
+ enum ColorModeType {
+ MODE_RGB,
+ MODE_HSV,
+ MODE_RAW,
+ MODE_OKHSL,
+
+ MODE_MAX
+ };
+
enum PickerShapeType {
SHAPE_HSV_RECTANGLE,
SHAPE_HSV_WHEEL,
@@ -73,38 +89,52 @@ public:
SHAPE_MAX
};
+ static const int SLIDER_COUNT = 4;
+
private:
static Ref<Shader> wheel_shader;
static Ref<Shader> circle_shader;
static Ref<Shader> circle_ok_color_shader;
static List<Color> preset_cache;
+ int current_slider_count = SLIDER_COUNT;
+
+ bool slider_theme_modified = true;
+
+ Vector<ColorMode *> modes;
+
Control *screen = nullptr;
- Control *uv_edit = memnew(Control);
- Control *w_edit = memnew(Control);
- AspectRatioContainer *wheel_edit = memnew(AspectRatioContainer);
- MarginContainer *wheel_margin = memnew(MarginContainer);
+ Control *uv_edit = nullptr;
+ Control *w_edit = nullptr;
+ AspectRatioContainer *wheel_edit = nullptr;
+ MarginContainer *wheel_margin = nullptr;
Ref<ShaderMaterial> wheel_mat;
Ref<ShaderMaterial> circle_mat;
- Control *wheel = memnew(Control);
- Control *wheel_uv = memnew(Control);
- TextureRect *sample = memnew(TextureRect);
- GridContainer *preset_container = memnew(GridContainer);
- HSeparator *preset_separator = memnew(HSeparator);
- Button *btn_add_preset = memnew(Button);
- Button *btn_pick = memnew(Button);
- CheckButton *btn_hsv = memnew(CheckButton);
- CheckButton *btn_raw = memnew(CheckButton);
- HSlider *scroll[4];
- SpinBox *values[4];
- Label *labels[4];
- Button *text_type = memnew(Button);
- LineEdit *c_text = memnew(LineEdit);
+ Control *wheel = nullptr;
+ Control *wheel_uv = nullptr;
+ TextureRect *sample = nullptr;
+ GridContainer *preset_container = nullptr;
+ HSeparator *preset_separator = nullptr;
+ Button *btn_add_preset = nullptr;
+ Button *btn_pick = nullptr;
+
+ OptionButton *mode_option_button = nullptr;
+
+ HSlider *sliders[SLIDER_COUNT];
+ SpinBox *values[SLIDER_COUNT];
+ Label *labels[SLIDER_COUNT];
+ Button *text_type = nullptr;
+ LineEdit *c_text = nullptr;
+
+ HSlider *alpha_slider = nullptr;
+ SpinBox *alpha_value = nullptr;
+ Label *alpha_label = nullptr;
bool edit_alpha = true;
Size2i ms;
bool text_is_constructor = false;
- PickerShapeType picker_type = SHAPE_HSV_WHEEL;
+ PickerShapeType current_shape = SHAPE_HSV_RECTANGLE;
+ ColorModeType current_mode = MODE_RGB;
const int preset_column_count = 9;
int prev_preset_size = 0;
@@ -114,8 +144,6 @@ private:
Color old_color;
bool display_old_color = false;
- bool raw_mode_enabled = false;
- bool hsv_mode_enabled = false;
bool deferred_mode_enabled = false;
bool updating = true;
bool changing_color = false;
@@ -128,6 +156,9 @@ private:
float v = 0.0;
Color last_color;
+ PickerShapeType _get_actual_shape() const;
+ void create_slider(GridContainer *gc, int idx);
+ void _reset_theme();
void _html_submitted(const String &p_html);
void _value_changed(double);
void _update_controls();
@@ -152,14 +183,21 @@ private:
inline int _get_preset_size();
void _add_preset_button(int p_size, const Color &p_color);
+ void _set_color_mode(ColorModeType p_mode);
+
protected:
void _notification(int);
static void _bind_methods();
public:
+ HSlider *get_slider(int idx);
+ Vector<float> get_active_slider_values();
+
static void init_shaders();
static void finish_shaders();
+ void add_mode(ColorMode *p_mode);
+
void set_edit_alpha(bool p_show);
bool is_editing_alpha() const;
@@ -173,7 +211,7 @@ public:
void set_display_old_color(bool p_enabled);
bool is_displaying_old_color() const;
- void set_picker_shape(PickerShapeType p_picker_type);
+ void set_picker_shape(PickerShapeType p_shape);
PickerShapeType get_picker_shape() const;
void add_preset(const Color &p_color);
@@ -181,11 +219,8 @@ public:
PackedColorArray get_presets() const;
void _update_presets();
- void set_hsv_mode(bool p_enabled);
- bool is_hsv_mode() const;
-
- void set_raw_mode(bool p_enabled);
- bool is_raw_mode() const;
+ void set_color_mode(ColorModeType p_mode);
+ ColorModeType get_color_mode() const;
void set_deferred_mode(bool p_enabled);
bool is_deferred_mode() const;
@@ -199,6 +234,7 @@ public:
void set_focus_on_line_edit();
ColorPicker();
+ ~ColorPicker();
};
class ColorPickerButton : public Button {
@@ -239,4 +275,5 @@ public:
};
VARIANT_ENUM_CAST(ColorPicker::PickerShapeType);
+VARIANT_ENUM_CAST(ColorPicker::ColorModeType);
#endif // COLOR_PICKER_H
diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp
index a2b05ee50d..44e2bb89eb 100644
--- a/scene/gui/dialogs.cpp
+++ b/scene/gui/dialogs.cpp
@@ -161,6 +161,14 @@ bool AcceptDialog::has_autowrap() {
return label->get_autowrap_mode() != TextServer::AUTOWRAP_OFF;
}
+void AcceptDialog::set_ok_button_text(String p_ok_button_text) {
+ ok->set_text(p_ok_button_text);
+}
+
+String AcceptDialog::get_ok_button_text() const {
+ return ok->get_text();
+}
+
void AcceptDialog::register_text_enter(Control *p_line_edit) {
ERR_FAIL_NULL(p_line_edit);
LineEdit *line_edit = Object::cast_to<LineEdit>(p_line_edit);
@@ -262,7 +270,7 @@ Button *AcceptDialog::add_button(const String &p_text, bool p_right, const Strin
Button *AcceptDialog::add_cancel_button(const String &p_cancel) {
String c = p_cancel;
if (p_cancel.is_empty()) {
- c = RTR("Cancel");
+ c = "Cancel";
}
Button *b = swap_cancel_ok ? add_button(c, true) : add_button(c);
b->connect("pressed", callable_mp(this, &AcceptDialog::_cancel_pressed));
@@ -306,11 +314,15 @@ void AcceptDialog::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_text"), &AcceptDialog::get_text);
ClassDB::bind_method(D_METHOD("set_autowrap", "autowrap"), &AcceptDialog::set_autowrap);
ClassDB::bind_method(D_METHOD("has_autowrap"), &AcceptDialog::has_autowrap);
+ ClassDB::bind_method(D_METHOD("set_ok_button_text", "text"), &AcceptDialog::set_ok_button_text);
+ ClassDB::bind_method(D_METHOD("get_ok_button_text"), &AcceptDialog::get_ok_button_text);
ADD_SIGNAL(MethodInfo("confirmed"));
ADD_SIGNAL(MethodInfo("cancelled"));
ADD_SIGNAL(MethodInfo("custom_action", PropertyInfo(Variant::STRING_NAME, "action")));
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "ok_button_text"), "set_ok_button_text", "get_ok_button_text");
+
ADD_GROUP("Dialog", "dialog");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "dialog_text", PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_DEFAULT_INTL), "set_text", "get_text");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "dialog_hide_on_ok"), "set_hide_on_ok", "get_hide_on_ok");
@@ -349,7 +361,7 @@ AcceptDialog::AcceptDialog() {
hbc->add_spacer();
ok = memnew(Button);
- ok->set_text(RTR("OK"));
+ ok->set_text("OK");
hbc->add_child(ok);
hbc->add_spacer();
@@ -365,8 +377,20 @@ AcceptDialog::~AcceptDialog() {
// ConfirmationDialog
+void ConfirmationDialog::set_cancel_button_text(String p_cancel_button_text) {
+ cancel->set_text(p_cancel_button_text);
+}
+
+String ConfirmationDialog::get_cancel_button_text() const {
+ return cancel->get_text();
+}
+
void ConfirmationDialog::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_cancel_button"), &ConfirmationDialog::get_cancel_button);
+ ClassDB::bind_method(D_METHOD("set_cancel_button_text"), &ConfirmationDialog::set_cancel_button_text);
+ ClassDB::bind_method(D_METHOD("get_cancel_button_text"), &ConfirmationDialog::get_cancel_button_text);
+
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "cancel_button_text"), "set_cancel_button_text", "get_cancel_button_text");
}
Button *ConfirmationDialog::get_cancel_button() {
diff --git a/scene/gui/dialogs.h b/scene/gui/dialogs.h
index 41fd9c0a10..711361de88 100644
--- a/scene/gui/dialogs.h
+++ b/scene/gui/dialogs.h
@@ -97,6 +97,9 @@ public:
void set_autowrap(bool p_autowrap);
bool has_autowrap();
+ void set_ok_button_text(String p_ok_button_text);
+ String get_ok_button_text() const;
+
AcceptDialog();
~AcceptDialog();
};
@@ -110,6 +113,10 @@ protected:
public:
Button *get_cancel_button();
+
+ void set_cancel_button_text(String p_cancel_button_text);
+ String get_cancel_button_text() const;
+
ConfirmationDialog();
};
diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp
index 6bb4ac9c6f..8ec930b753 100644
--- a/scene/gui/file_dialog.cpp
+++ b/scene/gui/file_dialog.cpp
@@ -419,10 +419,10 @@ void FileDialog::deselect_all() {
switch (mode) {
case FILE_MODE_OPEN_FILE:
case FILE_MODE_OPEN_FILES:
- get_ok_button()->set_text(RTR("Open"));
+ set_ok_button_text(RTR("Open"));
break;
case FILE_MODE_OPEN_DIR:
- get_ok_button()->set_text(RTR("Select Current Folder"));
+ set_ok_button_text(RTR("Select Current Folder"));
break;
case FILE_MODE_OPEN_ANY:
case FILE_MODE_SAVE_FILE:
@@ -446,7 +446,7 @@ void FileDialog::_tree_selected() {
if (!d["dir"]) {
file->set_text(d["name"]);
} else if (mode == FILE_MODE_OPEN_DIR) {
- get_ok_button()->set_text(RTR("Select This Folder"));
+ set_ok_button_text(RTR("Select This Folder"));
}
get_ok_button()->set_disabled(_is_open_should_be_disabled());
@@ -673,9 +673,13 @@ void FileDialog::clear_filters() {
invalidate();
}
-void FileDialog::add_filter(const String &p_filter) {
+void FileDialog::add_filter(const String &p_filter, const String &p_description) {
ERR_FAIL_COND_MSG(p_filter.begins_with("."), "Filter must be \"filename.extension\", can't start with dot.");
- filters.push_back(p_filter);
+ if (p_description.is_empty()) {
+ filters.push_back(p_filter);
+ } else {
+ filters.push_back(vformat("%s ; %s", p_filter, p_description));
+ }
update_filters();
invalidate();
}
@@ -764,35 +768,35 @@ void FileDialog::set_file_mode(FileMode p_mode) {
mode = p_mode;
switch (mode) {
case FILE_MODE_OPEN_FILE:
- get_ok_button()->set_text(RTR("Open"));
+ set_ok_button_text(RTR("Open"));
if (mode_overrides_title) {
set_title(TTRC("Open a File"));
}
makedir->hide();
break;
case FILE_MODE_OPEN_FILES:
- get_ok_button()->set_text(RTR("Open"));
+ set_ok_button_text(RTR("Open"));
if (mode_overrides_title) {
set_title(TTRC("Open File(s)"));
}
makedir->hide();
break;
case FILE_MODE_OPEN_DIR:
- get_ok_button()->set_text(RTR("Select Current Folder"));
+ set_ok_button_text(RTR("Select Current Folder"));
if (mode_overrides_title) {
set_title(TTRC("Open a Directory"));
}
makedir->show();
break;
case FILE_MODE_OPEN_ANY:
- get_ok_button()->set_text(RTR("Open"));
+ set_ok_button_text(RTR("Open"));
if (mode_overrides_title) {
set_title(TTRC("Open a File or Directory"));
}
makedir->show();
break;
case FILE_MODE_SAVE_FILE:
- get_ok_button()->set_text(RTR("Save"));
+ set_ok_button_text(RTR("Save"));
if (mode_overrides_title) {
set_title(TTRC("Save a File"));
}
@@ -919,7 +923,7 @@ void FileDialog::_bind_methods() {
ClassDB::bind_method(D_METHOD("_cancel_pressed"), &FileDialog::_cancel_pressed);
ClassDB::bind_method(D_METHOD("clear_filters"), &FileDialog::clear_filters);
- ClassDB::bind_method(D_METHOD("add_filter", "filter"), &FileDialog::add_filter);
+ ClassDB::bind_method(D_METHOD("add_filter", "filter", "description"), &FileDialog::add_filter, DEFVAL(""));
ClassDB::bind_method(D_METHOD("set_filters", "filters"), &FileDialog::set_filters);
ClassDB::bind_method(D_METHOD("get_filters"), &FileDialog::get_filters);
ClassDB::bind_method(D_METHOD("get_current_dir"), &FileDialog::get_current_dir);
diff --git a/scene/gui/file_dialog.h b/scene/gui/file_dialog.h
index 8b8d93920c..017c9d8d4f 100644
--- a/scene/gui/file_dialog.h
+++ b/scene/gui/file_dialog.h
@@ -151,7 +151,7 @@ protected:
public:
void popup_file_dialog();
void clear_filters();
- void add_filter(const String &p_filter);
+ void add_filter(const String &p_filter, const String &p_description = "");
void set_filters(const Vector<String> &p_filters);
Vector<String> get_filters() const;
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index df23a39224..f5ff274683 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -2120,7 +2120,7 @@ Ref<Font> RichTextLabel::_find_font(Item *p_item) {
fontitem = fontitem->parent;
}
- return Ref<FontFile>();
+ return Ref<Font>();
}
int RichTextLabel::_find_font_size(Item *p_item) {
@@ -4041,7 +4041,7 @@ void RichTextLabel::append_text(const String &p_bbcode) {
if (subtag_a.size() == 2) {
if (subtag_a[0] == "name" || subtag_a[0] == "n") {
String fnt = subtag_a[1];
- Ref<Font> font_data = ResourceLoader::load(fnt, "FontFile");
+ Ref<Font> font_data = ResourceLoader::load(fnt, "Font");
if (font_data.is_valid()) {
fc->set_base_font(font_data);
}
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 9c6cd6bdb2..06553cd0f6 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -1217,7 +1217,7 @@ void TextEdit::_notification(int p_what) {
if (brace_open_mismatch) {
current_color = brace_mismatch_color;
}
- Rect2 rect = Rect2(char_pos, ofs_y + font->get_underline_position(font_size), glyphs[j].advance * glyphs[j].repeat, font->get_underline_thickness(font_size));
+ Rect2 rect = Rect2(char_pos, ofs_y + font->get_underline_position(font_size), glyphs[j].advance * glyphs[j].repeat, MAX(font->get_underline_thickness(font_size) * get_theme_default_base_scale(), 1));
draw_rect(rect, current_color);
}
@@ -1226,7 +1226,7 @@ void TextEdit::_notification(int p_what) {
if (brace_close_mismatch) {
current_color = brace_mismatch_color;
}
- Rect2 rect = Rect2(char_pos, ofs_y + font->get_underline_position(font_size), glyphs[j].advance * glyphs[j].repeat, font->get_underline_thickness(font_size));
+ Rect2 rect = Rect2(char_pos, ofs_y + font->get_underline_position(font_size), glyphs[j].advance * glyphs[j].repeat, MAX(font->get_underline_thickness(font_size) * get_theme_default_base_scale(), 1));
draw_rect(rect, current_color);
}
}
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index 32d348c121..f43a91b85f 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -2815,6 +2815,9 @@ void Tree::value_editor_changed(double p_value) {
TreeItem::Cell &c = popup_edited_item->cells.write[popup_edited_item_col];
c.val = p_value;
+
+ text_editor->set_text(String::num(c.val, Math::range_step_decimals(c.step)));
+
item_edited(popup_edited_item_col, popup_edited_item);
update();
}
@@ -2967,6 +2970,15 @@ void Tree::_go_down() {
accept_event();
}
+bool Tree::_scroll(bool p_horizontal, float p_pages) {
+ ScrollBar *scroll = p_horizontal ? (ScrollBar *)h_scroll : (ScrollBar *)v_scroll;
+
+ double prev_value = scroll->get_value();
+ scroll->set_value(scroll->get_value() + scroll->get_page() * p_pages);
+
+ return scroll->get_value() != prev_value;
+}
+
void Tree::gui_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
@@ -3481,17 +3493,25 @@ void Tree::gui_input(const Ref<InputEvent> &p_event) {
} break;
case MouseButton::WHEEL_UP: {
- double prev_value = v_scroll->get_value();
- v_scroll->set_value(v_scroll->get_value() - v_scroll->get_page() * mb->get_factor() / 8);
- if (v_scroll->get_value() != prev_value) {
+ if (_scroll(false, -mb->get_factor() / 8)) {
accept_event();
}
} break;
case MouseButton::WHEEL_DOWN: {
- double prev_value = v_scroll->get_value();
- v_scroll->set_value(v_scroll->get_value() + v_scroll->get_page() * mb->get_factor() / 8);
- if (v_scroll->get_value() != prev_value) {
+ if (_scroll(false, mb->get_factor() / 8)) {
+ accept_event();
+ }
+
+ } break;
+ case MouseButton::WHEEL_LEFT: {
+ if (_scroll(true, -mb->get_factor() / 8)) {
+ accept_event();
+ }
+
+ } break;
+ case MouseButton::WHEEL_RIGHT: {
+ if (_scroll(true, mb->get_factor() / 8)) {
accept_event();
}
diff --git a/scene/gui/tree.h b/scene/gui/tree.h
index 65f7ab185c..1690e7ac57 100644
--- a/scene/gui/tree.h
+++ b/scene/gui/tree.h
@@ -610,6 +610,8 @@ private:
void _go_down();
void _go_up();
+ bool _scroll(bool p_horizontal, float p_pages);
+
protected:
static void _bind_methods();
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index 9d13ac3a38..520a0a04ed 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -76,7 +76,6 @@ static Ref<StyleBoxFlat> sb_expand(Ref<StyleBoxFlat> p_sbox, float p_left, float
// See also `editor_generate_icon()` in `editor/editor_themes.cpp`.
static Ref<ImageTexture> generate_icon(int p_index) {
- Ref<ImageTexture> icon = memnew(ImageTexture);
Ref<Image> img = memnew(Image);
#ifdef MODULE_SVG_ENABLED
@@ -87,9 +86,8 @@ static Ref<ImageTexture> generate_icon(int p_index) {
ImageLoaderSVG img_loader;
img_loader.create_image_from_string(img, default_theme_icons_sources[p_index], scale, upsample, false);
#endif
- icon->create_from_image(img);
- return icon;
+ return ImageTexture::create_from_image(img);
}
static Ref<StyleBox> make_empty_stylebox(float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_bottom = -1) {
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index f31a71eada..8c175e9ced 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -139,7 +139,7 @@ void ImageTexture::reload_from_file() {
img.instantiate();
if (ImageLoader::load_image(path, img) == OK) {
- create_from_image(img);
+ set_image(img);
} else {
Resource::reload_from_file();
notify_property_list_changed();
@@ -149,7 +149,7 @@ void ImageTexture::reload_from_file() {
bool ImageTexture::_set(const StringName &p_name, const Variant &p_value) {
if (p_name == "image") {
- create_from_image(p_value);
+ set_image(p_value);
return true;
}
return false;
@@ -167,7 +167,16 @@ void ImageTexture::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::OBJECT, PNAME("image"), PROPERTY_HINT_RESOURCE_TYPE, "Image", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT));
}
-void ImageTexture::create_from_image(const Ref<Image> &p_image) {
+Ref<ImageTexture> ImageTexture::create_from_image(const Ref<Image> &p_image) {
+ ERR_FAIL_COND_V_MSG(p_image.is_null() || p_image->is_empty(), Ref<ImageTexture>(), "Invalid image");
+
+ Ref<ImageTexture> image_texture;
+ image_texture.instantiate();
+ image_texture->set_image(p_image);
+ return image_texture;
+}
+
+void ImageTexture::set_image(const Ref<Image> &p_image) {
ERR_FAIL_COND_MSG(p_image.is_null() || p_image->is_empty(), "Invalid image");
w = p_image->get_width();
h = p_image->get_height();
@@ -311,7 +320,7 @@ void ImageTexture::set_path(const String &p_path, bool p_take_over) {
}
void ImageTexture::_bind_methods() {
- ClassDB::bind_method(D_METHOD("create_from_image", "image"), &ImageTexture::create_from_image);
+ ClassDB::bind_static_method("ImageTexture", D_METHOD("create_from_image", "image"), &ImageTexture::create_from_image);
ClassDB::bind_method(D_METHOD("get_format"), &ImageTexture::get_format);
ClassDB::bind_method(D_METHOD("update", "image"), &ImageTexture::update);
@@ -3016,12 +3025,12 @@ Error ImageTextureLayered::create_from_images(Vector<Ref<Image>> p_images) {
}
void ImageTextureLayered::update_layer(const Ref<Image> &p_image, int p_layer) {
- ERR_FAIL_COND(texture.is_valid());
- ERR_FAIL_COND(p_image.is_null());
- ERR_FAIL_COND(p_image->get_format() != format);
- ERR_FAIL_COND(p_image->get_width() != width || p_image->get_height() != height);
- ERR_FAIL_INDEX(p_layer, layers);
- ERR_FAIL_COND(p_image->has_mipmaps() != mipmaps);
+ ERR_FAIL_COND_MSG(texture.is_null(), "Texture is not initialized.");
+ ERR_FAIL_COND_MSG(p_image.is_null(), "Invalid image.");
+ ERR_FAIL_COND_MSG(p_image->get_format() != format, "Image format must match texture's image format.");
+ ERR_FAIL_COND_MSG(p_image->get_width() != width || p_image->get_height() != height, "Image size must match texture's image size.");
+ ERR_FAIL_COND_MSG(p_image->has_mipmaps() != mipmaps, "Image mipmap configuration must match texture's image mipmap configuration.");
+ ERR_FAIL_INDEX_MSG(p_layer, layers, "Layer index is out of bounds.");
RS::get_singleton()->texture_2d_update(texture, p_image, p_layer);
}
diff --git a/scene/resources/texture.h b/scene/resources/texture.h
index 317756e313..5973643034 100644
--- a/scene/resources/texture.h
+++ b/scene/resources/texture.h
@@ -110,7 +110,8 @@ protected:
static void _bind_methods();
public:
- void create_from_image(const Ref<Image> &p_image);
+ void set_image(const Ref<Image> &p_image);
+ static Ref<ImageTexture> create_from_image(const Ref<Image> &p_image);
Image::Format get_format() const;
diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp
index 13b671e562..05483db1e4 100644
--- a/scene/resources/tile_set.cpp
+++ b/scene/resources/tile_set.cpp
@@ -1809,11 +1809,8 @@ Vector<Vector<Ref<Texture2D>>> TileSet::generate_terrains_icons(Size2i p_size) {
image->create(1, 1, false, Image::FORMAT_RGBA8);
image->set_pixel(0, 0, get_terrain_color(terrain_set, terrain));
}
- Ref<ImageTexture> icon;
- icon.instantiate();
- icon->create_from_image(image);
+ Ref<ImageTexture> icon = ImageTexture::create_from_image(image);
icon->set_size_override(p_size);
-
output.write[terrain_set].write[terrain] = icon;
}
}
@@ -4594,7 +4591,7 @@ void TileSetAtlasSource::_update_padded_texture() {
if (!padded_texture.is_valid()) {
padded_texture.instantiate();
}
- padded_texture->create_from_image(image);
+ padded_texture->set_image(image);
emit_changed();
}
@@ -4924,6 +4921,10 @@ void TileData::move_terrain(int p_terrain_set, int p_from_index, int p_to_pos) {
void TileData::remove_terrain(int p_terrain_set, int p_index) {
if (terrain_set == p_terrain_set) {
+ if (terrain == p_index) {
+ terrain = -1;
+ }
+
for (int i = 0; i < 16; i++) {
if (terrain_peering_bits[i] == p_index) {
terrain_peering_bits[i] = -1;
diff --git a/scene/resources/visual_shader_particle_nodes.cpp b/scene/resources/visual_shader_particle_nodes.cpp
index 54df935168..bdfbb59fa6 100644
--- a/scene/resources/visual_shader_particle_nodes.cpp
+++ b/scene/resources/visual_shader_particle_nodes.cpp
@@ -470,7 +470,7 @@ void VisualShaderNodeParticleMeshEmitter::_update_texture(const Vector<Vector2>
image->set_pixel(i, 0, Color(v.x, v.y, 0));
}
if (r_texture->get_width() != p_array.size() || p_array.size() == 0) {
- r_texture->create_from_image(image);
+ r_texture->set_image(image);
} else {
r_texture->update(image);
}
@@ -491,7 +491,7 @@ void VisualShaderNodeParticleMeshEmitter::_update_texture(const Vector<Vector3>
image->set_pixel(i, 0, Color(v.x, v.y, v.z));
}
if (r_texture->get_width() != p_array.size() || p_array.size() == 0) {
- r_texture->create_from_image(image);
+ r_texture->set_image(image);
} else {
r_texture->update(image);
}
@@ -511,7 +511,7 @@ void VisualShaderNodeParticleMeshEmitter::_update_texture(const Vector<Color> &p
image->set_pixel(i, 0, p_array[i]);
}
if (r_texture->get_width() != p_array.size() || p_array.size() == 0) {
- r_texture->create_from_image(image);
+ r_texture->set_image(image);
} else {
r_texture->update(image);
}