Merge pull request #103583 from beicause/color-picker-add-intensity
ColorPicker: Add an intensity slider to all modes for HDR
This commit is contained in:
@ -73,6 +73,9 @@
|
||||
<member name="edit_alpha" type="bool" setter="set_edit_alpha" getter="is_editing_alpha" default="true">
|
||||
If [code]true[/code], shows an alpha channel slider (opacity).
|
||||
</member>
|
||||
<member name="edit_intensity" type="bool" setter="set_edit_intensity" getter="is_editing_intensity" default="true">
|
||||
If [code]true[/code], shows an intensity slider. The intensity is applied as follows: multiply the color by [code]2 ** intensity[/code] in linear RGB space, and then convert it back to sRGB.
|
||||
</member>
|
||||
<member name="hex_visible" type="bool" setter="set_hex_visible" getter="is_hex_visible" default="true">
|
||||
If [code]true[/code], the hex color code input field is visible.
|
||||
</member>
|
||||
@ -111,13 +114,15 @@
|
||||
</signals>
|
||||
<constants>
|
||||
<constant name="MODE_RGB" value="0" enum="ColorModeType">
|
||||
Allows editing the color with Red/Green/Blue sliders.
|
||||
Allows editing the color with Red/Green/Blue sliders in sRGB color space.
|
||||
</constant>
|
||||
<constant name="MODE_HSV" value="1" enum="ColorModeType">
|
||||
Allows editing the color with Hue/Saturation/Value sliders.
|
||||
</constant>
|
||||
<constant name="MODE_RAW" value="2" enum="ColorModeType">
|
||||
Allows the color R, G, B component values to go beyond 1.0, which can be used for certain special operations that require it (like tinting without darkening or rendering sprites in HDR).
|
||||
<constant name="MODE_RAW" value="2" enum="ColorModeType" deprecated="This is replaced by [constant MODE_LINEAR].">
|
||||
</constant>
|
||||
<constant name="MODE_LINEAR" value="2" enum="ColorModeType">
|
||||
Allows editing the color with Red/Green/Blue sliders in linear color space.
|
||||
</constant>
|
||||
<constant name="MODE_OKHSL" value="3" enum="ColorModeType">
|
||||
Allows editing the color with Hue/Saturation/Lightness sliders.
|
||||
@ -171,6 +176,9 @@
|
||||
<theme_item name="color_hue" data_type="icon" type="Texture2D">
|
||||
Custom texture for the hue selection slider on the right.
|
||||
</theme_item>
|
||||
<theme_item name="color_script" data_type="icon" type="Texture2D">
|
||||
The icon for the button that switches color text to hexadecimal.
|
||||
</theme_item>
|
||||
<theme_item name="expanded_arrow" data_type="icon" type="Texture2D">
|
||||
The icon for color preset drop down menu when expanded.
|
||||
</theme_item>
|
||||
|
||||
@ -35,6 +35,9 @@
|
||||
<member name="edit_alpha" type="bool" setter="set_edit_alpha" getter="is_editing_alpha" default="true">
|
||||
If [code]true[/code], the alpha channel in the displayed [ColorPicker] will be visible.
|
||||
</member>
|
||||
<member name="edit_intensity" type="bool" setter="set_edit_intensity" getter="is_editing_intensity" default="true">
|
||||
If [code]true[/code], the intensity slider in the displayed [ColorPicker] will be visible.
|
||||
</member>
|
||||
<member name="toggle_mode" type="bool" setter="set_toggle_mode" getter="is_toggle_mode" overrides="BaseButton" default="true" />
|
||||
</members>
|
||||
<signals>
|
||||
|
||||
@ -973,6 +973,9 @@
|
||||
<member name="interface/inspector/auto_unfold_foreign_scenes" type="bool" setter="" getter="">
|
||||
If [code]true[/code], automatically expands property groups in the Inspector dock when opening a scene that hasn't been opened previously. If [code]false[/code], all groups remain collapsed by default.
|
||||
</member>
|
||||
<member name="interface/inspector/color_picker_show_intensity" type="bool" setter="" getter="">
|
||||
If [code]true[/code], show the intensity slider in the [ColorPicker]s opened in the editor.
|
||||
</member>
|
||||
<member name="interface/inspector/default_color_picker_mode" type="int" setter="" getter="">
|
||||
The default color picker mode to use when opening [ColorPicker]s in the editor. This mode can be temporarily adjusted on the color picker itself.
|
||||
</member>
|
||||
|
||||
@ -4196,9 +4196,11 @@ void EditorNode::setup_color_picker(ColorPicker *p_picker) {
|
||||
p_picker->set_editor_settings(EditorSettings::get_singleton());
|
||||
int default_color_mode = EditorSettings::get_singleton()->get_project_metadata("color_picker", "color_mode", EDITOR_GET("interface/inspector/default_color_picker_mode"));
|
||||
int picker_shape = EditorSettings::get_singleton()->get_project_metadata("color_picker", "picker_shape", EDITOR_GET("interface/inspector/default_color_picker_shape"));
|
||||
bool show_intensity = EditorSettings::get_singleton()->get_project_metadata("color_picker", "show_intensity", EDITOR_GET("interface/inspector/color_picker_show_intensity"));
|
||||
|
||||
p_picker->set_color_mode((ColorPicker::ColorModeType)default_color_mode);
|
||||
p_picker->set_picker_shape((ColorPicker::PickerShapeType)picker_shape);
|
||||
p_picker->set_edit_intensity(show_intensity);
|
||||
|
||||
p_picker->set_quick_open_callback(callable_mp(this, &EditorNode::_palette_quick_open_dialog));
|
||||
p_picker->set_palette_saved_callback(callable_mp(EditorFileSystem::get_singleton(), &EditorFileSystem::update_file));
|
||||
|
||||
@ -570,6 +570,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
|
||||
|
||||
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::BOOL, PROPERTY_HINT_NONE, "interface/inspector/color_picker_show_intensity", true, "");
|
||||
|
||||
// Theme
|
||||
EDITOR_SETTING_BASIC(Variant::BOOL, PROPERTY_HINT_ENUM, "interface/theme/follow_system_theme", false, "")
|
||||
|
||||
@ -1821,6 +1821,7 @@ void EditorThemeManager::_populate_standard_styles(const Ref<EditorTheme> &p_the
|
||||
p_theme->set_icon("bar_arrow", "ColorPicker", p_theme->get_icon(SNAME("ColorPickerBarArrow"), EditorStringName(EditorIcons)));
|
||||
p_theme->set_icon("picker_cursor", "ColorPicker", p_theme->get_icon(SNAME("PickerCursor"), EditorStringName(EditorIcons)));
|
||||
p_theme->set_icon("picker_cursor_bg", "ColorPicker", p_theme->get_icon(SNAME("PickerCursorBg"), EditorStringName(EditorIcons)));
|
||||
p_theme->set_icon("color_script", "ColorPicker", p_theme->get_icon(SNAME("Script"), EditorStringName(EditorIcons)));
|
||||
|
||||
// ColorPickerButton.
|
||||
p_theme->set_icon("bg", "ColorPickerButton", p_theme->get_icon(SNAME("GuiMiniCheckerboard"), EditorStringName(EditorIcons)));
|
||||
|
||||
@ -39,13 +39,13 @@ ColorMode::ColorMode(ColorPicker *p_color_picker) {
|
||||
}
|
||||
|
||||
String ColorModeRGB::get_slider_label(int idx) const {
|
||||
ERR_FAIL_INDEX_V_MSG(idx, 3, String(), "Couldn't get slider label.");
|
||||
ERR_FAIL_INDEX_V_MSG(idx, get_slider_count(), String(), "Couldn't get slider label.");
|
||||
return labels[idx];
|
||||
}
|
||||
|
||||
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;
|
||||
ERR_FAIL_INDEX_V_MSG(idx, get_slider_count(), 0, "Couldn't get slider value.");
|
||||
return color_picker->color_normalized.components[idx] * 255;
|
||||
}
|
||||
|
||||
Color ColorModeRGB::get_color() const {
|
||||
@ -57,6 +57,25 @@ Color ColorModeRGB::get_color() const {
|
||||
return color;
|
||||
}
|
||||
|
||||
void ColorModeRGB::_greater_value_inputted() {
|
||||
HSlider **sliders = color_picker->sliders;
|
||||
Color color_prev = color_picker->color;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (sliders[i]->get_value() > 255) {
|
||||
color_prev.components[i] = sliders[i]->get_value() / 255.0;
|
||||
}
|
||||
}
|
||||
Color linear_color = color_prev.srgb_to_linear();
|
||||
float multiplier = MAX(1, MAX(MAX(linear_color.r, linear_color.g), linear_color.b));
|
||||
Color srgb = Color(linear_color.r / multiplier, linear_color.g / multiplier, linear_color.b / multiplier, linear_color.a).linear_to_srgb();
|
||||
sliders[0]->set_value_no_signal(srgb.r * 255);
|
||||
sliders[1]->set_value_no_signal(srgb.g * 255);
|
||||
sliders[2]->set_value_no_signal(srgb.b * 255);
|
||||
|
||||
color_picker->intensity = Math::log2(multiplier);
|
||||
color_picker->intensity_slider->set_value_no_signal(color_picker->intensity);
|
||||
}
|
||||
|
||||
void ColorModeRGB::slider_draw(int p_which) {
|
||||
Vector<Vector2> pos;
|
||||
pos.resize(4);
|
||||
@ -66,37 +85,39 @@ void ColorModeRGB::slider_draw(int p_which) {
|
||||
Size2 size = slider->get_size();
|
||||
Color left_color;
|
||||
Color right_color;
|
||||
Color color = color_picker->get_pick_color();
|
||||
Color color = color_picker->color_normalized;
|
||||
const real_t margin = 16 * color_picker->theme_cache.base_scale;
|
||||
|
||||
if (p_which == ColorPicker::SLIDER_COUNT) {
|
||||
slider->draw_texture_rect(color_picker->theme_cache.sample_bg, Rect2(Point2(0, 0), Size2(size.x, margin)), true);
|
||||
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);
|
||||
|
||||
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);
|
||||
if (rgb_texture[p_which].is_null()) {
|
||||
rgb_texture[p_which].instantiate();
|
||||
rgb_texture[p_which]->set_width(400);
|
||||
rgb_texture[p_which]->set_height(6);
|
||||
}
|
||||
|
||||
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, 0));
|
||||
pos.set(1, Vector2(size.x, 0));
|
||||
pos.set(2, Vector2(size.x, margin));
|
||||
pos.set(3, Vector2(0, margin));
|
||||
Ref<GradientTexture2D> gradient_texture = rgb_texture[p_which];
|
||||
|
||||
slider->draw_polygon(pos, col);
|
||||
Ref<Gradient> gradient = gradient_texture->get_gradient();
|
||||
if (gradient.is_null()) {
|
||||
gradient.instantiate();
|
||||
PackedFloat32Array offsets = { 0, 1 };
|
||||
gradient->set_offsets(offsets);
|
||||
gradient->set_interpolation_color_space(Gradient::ColorSpace::GRADIENT_COLOR_SPACE_SRGB);
|
||||
gradient_texture->set_gradient(gradient);
|
||||
}
|
||||
|
||||
PackedColorArray colors = { left_color, right_color };
|
||||
gradient->set_colors(colors);
|
||||
|
||||
slider->draw_texture_rect(gradient_texture, Rect2(Vector2(), Vector2(size.x, margin)), false);
|
||||
}
|
||||
|
||||
void ColorModeHSV::_value_changed() {
|
||||
@ -108,38 +129,43 @@ void ColorModeHSV::_value_changed() {
|
||||
if (values[2] > 0 || values[1] != cached_saturation) {
|
||||
cached_saturation = values[1];
|
||||
}
|
||||
|
||||
// Cache real HSV values in ColorPicker.
|
||||
color_picker->h = color_picker->sliders[0]->get_value() / 360.0;
|
||||
color_picker->s = color_picker->sliders[1]->get_value() / 100.0;
|
||||
color_picker->v = color_picker->sliders[2]->get_value() / 100.0;
|
||||
|
||||
color_picker->hsv_cached = true;
|
||||
}
|
||||
|
||||
String ColorModeHSV::get_slider_label(int idx) const {
|
||||
ERR_FAIL_INDEX_V_MSG(idx, 3, String(), "Couldn't get slider label.");
|
||||
ERR_FAIL_INDEX_V_MSG(idx, get_slider_count(), 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.");
|
||||
ERR_FAIL_INDEX_V_MSG(idx, get_slider_count(), 0, "Couldn't get slider max value.");
|
||||
return slider_max[idx];
|
||||
}
|
||||
|
||||
float ColorModeHSV::get_slider_value(int idx) const {
|
||||
switch (idx) {
|
||||
case 0: {
|
||||
if (color_picker->get_pick_color().get_s() > 0) {
|
||||
return color_picker->get_pick_color().get_h() * 360.0;
|
||||
if (color_picker->color_normalized.get_s() > 0) {
|
||||
return color_picker->color_normalized.get_h() * 360.0;
|
||||
} else {
|
||||
return cached_hue;
|
||||
}
|
||||
}
|
||||
case 1: {
|
||||
if (color_picker->get_pick_color().get_v() > 0) {
|
||||
return color_picker->get_pick_color().get_s() * 100.0;
|
||||
if (color_picker->color_normalized.get_v() > 0) {
|
||||
return color_picker->color_normalized.get_s() * 100.0;
|
||||
} else {
|
||||
return cached_saturation;
|
||||
}
|
||||
}
|
||||
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);
|
||||
return color_picker->color_normalized.get_v() * 100.0;
|
||||
default:
|
||||
ERR_FAIL_V_MSG(0, "Couldn't get slider value.");
|
||||
}
|
||||
@ -147,8 +173,7 @@ float ColorModeHSV::get_slider_value(int idx) const {
|
||||
|
||||
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);
|
||||
Color color = Color::from_hsv(values[0] / 360.0, values[1] / 100.0, values[2] / 100.0, values[3] / 255.0);
|
||||
return color;
|
||||
}
|
||||
|
||||
@ -161,17 +186,10 @@ void ColorModeHSV::slider_draw(int p_which) {
|
||||
Size2 size = slider->get_size();
|
||||
Color left_color;
|
||||
Color right_color;
|
||||
Color color = color_picker->get_pick_color();
|
||||
Color color = color_picker->color_normalized;
|
||||
const real_t margin = 16 * color_picker->theme_cache.base_scale;
|
||||
|
||||
if (p_which == ColorPicker::SLIDER_COUNT) {
|
||||
slider->draw_texture_rect(color_picker->theme_cache.sample_bg, Rect2(Point2(0, 0), Size2(size.x, margin)), true);
|
||||
|
||||
left_color = color;
|
||||
left_color.a = 0;
|
||||
right_color = color;
|
||||
right_color.a = 1;
|
||||
} else if (p_which == 0) {
|
||||
if (p_which == 0) {
|
||||
float v = color.get_v();
|
||||
left_color = Color(v, v, v);
|
||||
right_color = left_color;
|
||||
@ -203,31 +221,60 @@ void ColorModeHSV::slider_draw(int p_which) {
|
||||
}
|
||||
}
|
||||
|
||||
String ColorModeRAW::get_slider_label(int idx) const {
|
||||
ERR_FAIL_INDEX_V_MSG(idx, 3, String(), "Couldn't get slider label.");
|
||||
String ColorModeLinear::get_slider_label(int idx) const {
|
||||
ERR_FAIL_INDEX_V_MSG(idx, get_slider_count(), 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.");
|
||||
float ColorModeLinear::get_slider_max(int idx) const {
|
||||
ERR_FAIL_INDEX_V_MSG(idx, get_slider_count(), 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];
|
||||
float ColorModeLinear::get_slider_value(int idx) const {
|
||||
ERR_FAIL_INDEX_V_MSG(idx, get_slider_count(), 0, "Couldn't get slider value.");
|
||||
Color color = color_picker->color_normalized.srgb_to_linear();
|
||||
return color.components[idx];
|
||||
}
|
||||
|
||||
Color ColorModeRAW::get_color() const {
|
||||
float ColorModeLinear::get_alpha_slider_max() const {
|
||||
return 1;
|
||||
}
|
||||
|
||||
float ColorModeLinear::get_alpha_slider_value() const {
|
||||
return color_picker->get_pick_color().a;
|
||||
}
|
||||
|
||||
Color ColorModeLinear::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;
|
||||
return color.linear_to_srgb();
|
||||
}
|
||||
|
||||
void ColorModeRAW::slider_draw(int p_which) {
|
||||
void ColorModeLinear::_greater_value_inputted() {
|
||||
HSlider **sliders = color_picker->sliders;
|
||||
Color color_prev = color_picker->color;
|
||||
Color linear_color = color_prev.srgb_to_linear();
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (sliders[i]->get_value() > 1 + CMP_EPSILON) {
|
||||
linear_color.components[i] = sliders[i]->get_value();
|
||||
}
|
||||
}
|
||||
|
||||
float multiplier = MAX(1, MAX(MAX(linear_color.r, linear_color.g), linear_color.b));
|
||||
|
||||
sliders[0]->set_value_no_signal(linear_color.r / multiplier);
|
||||
sliders[1]->set_value_no_signal(linear_color.g / multiplier);
|
||||
sliders[2]->set_value_no_signal(linear_color.b / multiplier);
|
||||
|
||||
color_picker->intensity = Math::log2(multiplier);
|
||||
color_picker->intensity_slider->set_value_no_signal(color_picker->intensity);
|
||||
}
|
||||
|
||||
void ColorModeLinear::slider_draw(int p_which) {
|
||||
Vector<Vector2> pos;
|
||||
pos.resize(4);
|
||||
Vector<Color> col;
|
||||
@ -236,40 +283,39 @@ void ColorModeRAW::slider_draw(int p_which) {
|
||||
Size2 size = slider->get_size();
|
||||
Color left_color;
|
||||
Color right_color;
|
||||
Color color = color_picker->get_pick_color();
|
||||
Color color = color_picker->color_normalized.linear_to_srgb();
|
||||
const real_t margin = 16 * color_picker->theme_cache.base_scale;
|
||||
|
||||
if (p_which == ColorPicker::SLIDER_COUNT) {
|
||||
slider->draw_texture_rect(color_picker->theme_cache.sample_bg, Rect2(Point2(0, 0), Size2(size.x, margin)), true);
|
||||
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);
|
||||
|
||||
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, 0));
|
||||
pos.set(1, Vector2(size.x, 0));
|
||||
pos.set(2, Vector2(size.x, margin));
|
||||
pos.set(3, Vector2(0, margin));
|
||||
|
||||
slider->draw_polygon(pos, col);
|
||||
}
|
||||
}
|
||||
|
||||
bool ColorModeRAW::apply_theme() const {
|
||||
for (int i = 0; i < ColorPicker::SLIDER_COUNT; 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_constant_override("grabber_offset");
|
||||
if (rgb_texture[p_which].is_null()) {
|
||||
rgb_texture[p_which].instantiate();
|
||||
rgb_texture[p_which]->set_width(400);
|
||||
rgb_texture[p_which]->set_height(6);
|
||||
}
|
||||
|
||||
return true;
|
||||
Ref<GradientTexture2D> gradient_texture = rgb_texture[p_which];
|
||||
|
||||
Ref<Gradient> gradient = gradient_texture->get_gradient();
|
||||
if (gradient.is_null()) {
|
||||
gradient.instantiate();
|
||||
PackedFloat32Array offsets = { 0, 1 };
|
||||
gradient->set_offsets(offsets);
|
||||
gradient->set_interpolation_color_space(Gradient::ColorSpace::GRADIENT_COLOR_SPACE_LINEAR_SRGB);
|
||||
gradient_texture->set_gradient(gradient);
|
||||
}
|
||||
|
||||
PackedColorArray colors = { left_color, right_color };
|
||||
gradient->set_colors(colors);
|
||||
|
||||
slider->draw_texture_rect(gradient_texture, Rect2(Vector2(), Vector2(size.x, margin)), false);
|
||||
}
|
||||
|
||||
void ColorModeOKHSL::_value_changed() {
|
||||
@ -281,38 +327,43 @@ void ColorModeOKHSL::_value_changed() {
|
||||
if (values[2] > 0 || values[1] != cached_saturation) {
|
||||
cached_saturation = values[1];
|
||||
}
|
||||
|
||||
// Cache real OKHSL values in ColorPicker.
|
||||
color_picker->ok_hsl_h = color_picker->sliders[0]->get_value() / 360.0;
|
||||
color_picker->ok_hsl_s = color_picker->sliders[1]->get_value() / 100.0;
|
||||
color_picker->ok_hsl_l = color_picker->sliders[2]->get_value() / 100.0;
|
||||
|
||||
color_picker->okhsl_cached = true;
|
||||
}
|
||||
|
||||
String ColorModeOKHSL::get_slider_label(int idx) const {
|
||||
ERR_FAIL_INDEX_V_MSG(idx, 3, String(), "Couldn't get slider label.");
|
||||
ERR_FAIL_INDEX_V_MSG(idx, get_slider_count(), 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.");
|
||||
ERR_FAIL_INDEX_V_MSG(idx, get_slider_count(), 0, "Couldn't get slider max value.");
|
||||
return slider_max[idx];
|
||||
}
|
||||
|
||||
float ColorModeOKHSL::get_slider_value(int idx) const {
|
||||
switch (idx) {
|
||||
case 0: {
|
||||
if (color_picker->get_pick_color().get_ok_hsl_s() > 0) {
|
||||
return color_picker->get_pick_color().get_ok_hsl_h() * 360.0;
|
||||
if (color_picker->color_normalized.get_ok_hsl_s() > 0) {
|
||||
return color_picker->color_normalized.get_ok_hsl_h() * 360.0;
|
||||
} else {
|
||||
return cached_hue;
|
||||
}
|
||||
}
|
||||
case 1: {
|
||||
if (color_picker->get_pick_color().get_ok_hsl_l() > 0) {
|
||||
return color_picker->get_pick_color().get_ok_hsl_s() * 100.0;
|
||||
if (color_picker->color_normalized.get_ok_hsl_l() > 0) {
|
||||
return color_picker->color_normalized.get_ok_hsl_s() * 100.0;
|
||||
} else {
|
||||
return cached_saturation;
|
||||
}
|
||||
}
|
||||
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);
|
||||
return color_picker->color_normalized.get_ok_hsl_l() * 100.0;
|
||||
default:
|
||||
ERR_FAIL_V_MSG(0, "Couldn't get slider value.");
|
||||
}
|
||||
@ -320,8 +371,7 @@ float ColorModeOKHSL::get_slider_value(int idx) const {
|
||||
|
||||
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);
|
||||
Color color = Color::from_ok_hsl(values[0] / 360.0, values[1] / 100.0, values[2] / 100.0, values[3] / 255.0);
|
||||
return color;
|
||||
}
|
||||
|
||||
@ -334,17 +384,16 @@ void ColorModeOKHSL::slider_draw(int p_which) {
|
||||
Vector<Color> col;
|
||||
Color left_color;
|
||||
Color right_color;
|
||||
Color color = color_picker->get_pick_color();
|
||||
Color color = color_picker->color_normalized;
|
||||
float okhsl_l = color.get_ok_hsl_l();
|
||||
float slider_hue = (Math::is_zero_approx(color.get_ok_hsl_s())) ? cached_hue / 360.0 : color.get_ok_hsl_h();
|
||||
float slider_sat = (Math::is_zero_approx(okhsl_l) || Math::is_equal_approx(okhsl_l, 1)) ? cached_saturation / 100.0 : color.get_ok_hsl_s();
|
||||
|
||||
if (p_which == 2) { // L
|
||||
pos.resize(6);
|
||||
col.resize(6);
|
||||
left_color = Color(0, 0, 0);
|
||||
Color middle_color;
|
||||
float slider_hue = (Math::is_zero_approx(color.get_ok_hsl_s())) ? cached_hue / 360.0 : color.get_ok_hsl_h();
|
||||
float slider_sat = (Math::is_zero_approx(color.get_ok_hsl_l())) ? cached_saturation / 100.0 : color.get_ok_hsl_s();
|
||||
|
||||
middle_color.set_ok_hsl(slider_hue, slider_sat, 0.5);
|
||||
Color middle_color = Color::from_ok_hsl(slider_hue, slider_sat, 0.5);
|
||||
right_color.set_ok_hsl(slider_hue, slider_sat, 1);
|
||||
|
||||
col.set(0, left_color);
|
||||
@ -359,26 +408,13 @@ void ColorModeOKHSL::slider_draw(int p_which) {
|
||||
pos.set(3, Vector2(size.x, margin));
|
||||
pos.set(4, Vector2(size.x * 0.5, margin));
|
||||
pos.set(5, Vector2(0, margin));
|
||||
} else {
|
||||
slider->draw_polygon(pos, col);
|
||||
} else if (p_which == 1) { // S
|
||||
pos.resize(4);
|
||||
col.resize(4);
|
||||
|
||||
if (p_which == ColorPicker::SLIDER_COUNT) {
|
||||
slider->draw_texture_rect(color_picker->theme_cache.sample_bg, Rect2(Point2(0, 0), Size2(size.x, margin)), true);
|
||||
|
||||
left_color = color;
|
||||
left_color.a = 0;
|
||||
right_color = color;
|
||||
right_color.a = 1;
|
||||
} else if (p_which == 0) {
|
||||
float l = color.get_ok_hsl_l();
|
||||
left_color = Color(l, l, l);
|
||||
right_color = left_color;
|
||||
} else {
|
||||
left_color.set_ok_hsl(color.get_ok_hsl_h(), 0, color.get_ok_hsl_l());
|
||||
float s_col_hue = (Math::is_zero_approx(color.get_ok_hsl_s())) ? cached_hue / 360.0 : color.get_ok_hsl_h();
|
||||
right_color.set_ok_hsl(s_col_hue, 1, color.get_ok_hsl_l());
|
||||
}
|
||||
left_color.set_ok_hsl(slider_hue, 0, okhsl_l);
|
||||
right_color.set_ok_hsl(slider_hue, 1, okhsl_l);
|
||||
|
||||
col.set(0, left_color);
|
||||
col.set(1, right_color);
|
||||
@ -388,34 +424,36 @@ void ColorModeOKHSL::slider_draw(int p_which) {
|
||||
pos.set(1, Vector2(size.x, 0));
|
||||
pos.set(2, Vector2(size.x, margin));
|
||||
pos.set(3, Vector2(0, margin));
|
||||
}
|
||||
|
||||
slider->draw_polygon(pos, col);
|
||||
|
||||
if (p_which == 0) { // H
|
||||
slider->draw_polygon(pos, col);
|
||||
} else if (p_which == 0) { // H
|
||||
const int precision = 7;
|
||||
if (hue_texture.is_null()) {
|
||||
hue_texture.instantiate();
|
||||
hue_texture->set_width(400);
|
||||
hue_texture->set_height(6);
|
||||
}
|
||||
Ref<Gradient> hue_gradient = hue_texture->get_gradient();
|
||||
if (hue_gradient.is_null()) {
|
||||
hue_gradient.instantiate();
|
||||
PackedFloat32Array offsets;
|
||||
offsets.resize(precision);
|
||||
for (int i = 0; i < precision; i++) {
|
||||
float h = i / float(precision - 1);
|
||||
offsets.write[i] = h;
|
||||
}
|
||||
hue_gradient->set_offsets(offsets);
|
||||
hue_gradient->set_interpolation_color_space(Gradient::ColorSpace::GRADIENT_COLOR_SPACE_OKLAB);
|
||||
hue_texture->set_gradient(hue_gradient);
|
||||
}
|
||||
|
||||
Ref<Gradient> hue_gradient;
|
||||
hue_gradient.instantiate();
|
||||
PackedFloat32Array offsets;
|
||||
offsets.resize(precision);
|
||||
PackedColorArray colors;
|
||||
colors.resize(precision);
|
||||
|
||||
for (int i = 0; i < precision; i++) {
|
||||
float h = i / float(precision - 1);
|
||||
offsets.write[i] = h;
|
||||
colors.write[i] = Color::from_ok_hsl(h, color.get_ok_hsl_s(), color.get_ok_hsl_l());
|
||||
colors.write[i] = Color::from_ok_hsl(h, slider_sat, okhsl_l);
|
||||
}
|
||||
hue_gradient->set_offsets(offsets);
|
||||
hue_gradient->set_colors(colors);
|
||||
hue_gradient->set_interpolation_color_space(Gradient::ColorSpace::GRADIENT_COLOR_SPACE_OKLAB);
|
||||
if (hue_texture.is_null()) {
|
||||
hue_texture.instantiate();
|
||||
hue_texture->set_width(800);
|
||||
hue_texture->set_height(6);
|
||||
}
|
||||
hue_texture->set_gradient(hue_gradient);
|
||||
slider->draw_texture_rect(hue_texture, Rect2(Vector2(), Vector2(size.x, margin)), false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,12 +48,15 @@ public:
|
||||
virtual bool get_allow_greater() const { return false; }
|
||||
virtual float get_slider_value(int idx) const = 0;
|
||||
|
||||
virtual float get_alpha_slider_max() const { return 255.0; }
|
||||
virtual float get_alpha_slider_value() const { return color_picker->get_pick_color().a * 255.0; }
|
||||
|
||||
virtual Color get_color() const = 0;
|
||||
|
||||
virtual void _value_changed() {}
|
||||
virtual void _greater_value_inputted() {}
|
||||
|
||||
virtual void slider_draw(int p_which) = 0;
|
||||
virtual bool apply_theme() const { return false; }
|
||||
|
||||
ColorMode(ColorPicker *p_color_picker);
|
||||
virtual ~ColorMode() {}
|
||||
@ -62,7 +65,7 @@ public:
|
||||
class ColorModeHSV : public ColorMode {
|
||||
public:
|
||||
String labels[3] = { "H", "S", "V" };
|
||||
float slider_max[4] = { 359, 100, 100, 255 };
|
||||
float slider_max[3] = { 359, 100, 100 };
|
||||
float cached_hue = 0.0;
|
||||
float cached_saturation = 0.0;
|
||||
|
||||
@ -86,6 +89,7 @@ public:
|
||||
class ColorModeRGB : public ColorMode {
|
||||
public:
|
||||
String labels[3] = { "R", "G", "B" };
|
||||
Ref<GradientTexture2D> rgb_texture[3];
|
||||
|
||||
virtual String get_name() const override { return "RGB"; }
|
||||
|
||||
@ -97,18 +101,21 @@ public:
|
||||
|
||||
virtual Color get_color() const override;
|
||||
|
||||
virtual void _greater_value_inputted() override;
|
||||
|
||||
virtual void slider_draw(int p_which) override;
|
||||
|
||||
ColorModeRGB(ColorPicker *p_color_picker) :
|
||||
ColorMode(p_color_picker) {}
|
||||
};
|
||||
|
||||
class ColorModeRAW : public ColorMode {
|
||||
class ColorModeLinear : public ColorMode {
|
||||
public:
|
||||
String labels[3] = { "R", "G", "B" };
|
||||
float slider_max[4] = { 100, 100, 100, 1 };
|
||||
float slider_max[3] = { 1, 1, 1 };
|
||||
Ref<GradientTexture2D> rgb_texture[3];
|
||||
|
||||
virtual String get_name() const override { return "RAW"; }
|
||||
virtual String get_name() const override { return "Linear"; }
|
||||
|
||||
virtual float get_slider_step() const override { return 0.001; }
|
||||
virtual float get_spinbox_arrow_step() const override { return 0.01; }
|
||||
@ -117,19 +124,23 @@ public:
|
||||
virtual bool get_allow_greater() const override { return true; }
|
||||
virtual float get_slider_value(int idx) const override;
|
||||
|
||||
virtual float get_alpha_slider_max() const override;
|
||||
virtual float get_alpha_slider_value() const override;
|
||||
|
||||
virtual Color get_color() const override;
|
||||
|
||||
virtual void slider_draw(int p_which) override;
|
||||
virtual bool apply_theme() const override;
|
||||
virtual void _greater_value_inputted() override;
|
||||
|
||||
ColorModeRAW(ColorPicker *p_color_picker) :
|
||||
virtual void slider_draw(int p_which) override;
|
||||
|
||||
ColorModeLinear(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 };
|
||||
float slider_max[3] = { 359, 100, 100 };
|
||||
float cached_hue = 0.0;
|
||||
float cached_saturation = 0.0;
|
||||
Ref<GradientTexture2D> hue_texture;
|
||||
|
||||
@ -31,6 +31,7 @@
|
||||
#include "color_picker.h"
|
||||
|
||||
#include "core/io/image.h"
|
||||
#include "core/math/expression.h"
|
||||
#include "scene/gui/color_mode.h"
|
||||
#include "scene/gui/color_picker_shape.h"
|
||||
#include "scene/gui/file_dialog.h"
|
||||
@ -53,6 +54,27 @@
|
||||
#include "scene/theme/theme_db.h"
|
||||
#include "thirdparty/misc/ok_color_shader.h"
|
||||
|
||||
static inline bool is_color_overbright(const Color &color) {
|
||||
return (color.r > 1.0) || (color.g > 1.0) || (color.b > 1.0);
|
||||
}
|
||||
|
||||
static inline bool is_color_valid_hex(const Color &color) {
|
||||
return !is_color_overbright(color) && color.r >= 0 && color.g >= 0 && color.b >= 0;
|
||||
}
|
||||
|
||||
static inline String color_to_string(const Color &color, bool show_alpha = true, bool force_value_format = false) {
|
||||
if (!force_value_format && !is_color_overbright(color)) {
|
||||
return "#" + color.to_html(show_alpha);
|
||||
}
|
||||
String t = "(" + String::num(color.r, 3) + ", " + String::num(color.g, 3) + ", " + String::num(color.b, 3);
|
||||
if (show_alpha) {
|
||||
t += ", " + String::num(color.a, 3) + ")";
|
||||
} else {
|
||||
t += ")";
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
void ColorPicker::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_ACCESSIBILITY_UPDATE: {
|
||||
@ -126,6 +148,7 @@ void ColorPicker::_notification(int p_what) {
|
||||
}
|
||||
alpha_label->set_custom_minimum_size(Size2(theme_cache.label_width, 0));
|
||||
alpha_slider->add_theme_constant_override(SNAME("center_grabber"), theme_cache.center_slider_grabbers);
|
||||
intensity_label->set_custom_minimum_size(Size2(theme_cache.label_width, 0));
|
||||
|
||||
for (int i = 0; i < MODE_BUTTON_COUNT; i++) {
|
||||
mode_btns[i]->begin_bulk_theme_override();
|
||||
@ -144,10 +167,9 @@ void ColorPicker::_notification(int p_what) {
|
||||
|
||||
_reset_sliders_theme();
|
||||
|
||||
if (Engine::get_singleton()->is_editor_hint()) {
|
||||
// Adjust for the width of the "Script" icon.
|
||||
text_type->set_custom_minimum_size(Size2(28 * theme_cache.base_scale, 0));
|
||||
}
|
||||
hex_label->set_custom_minimum_size(Size2(38 * theme_cache.base_scale, 0));
|
||||
// Adjust for the width of the "script" icon.
|
||||
text_type->set_custom_minimum_size(Size2(28 * theme_cache.base_scale, 0));
|
||||
|
||||
_update_presets();
|
||||
_update_recent_presets();
|
||||
@ -348,17 +370,17 @@ void ColorPicker::_update_controls() {
|
||||
alpha_slider->set_accessibility_name(ETR("Alpha"));
|
||||
alpha_value->set_accessibility_name(ETR("Alpha"));
|
||||
|
||||
slider_theme_modified = modes[current_mode]->apply_theme();
|
||||
intensity_label->set_text("I");
|
||||
intensity_slider->set_accessibility_name(ETR("Intensity"));
|
||||
intensity_value->set_accessibility_name(ETR("Intensity"));
|
||||
|
||||
if (edit_alpha) {
|
||||
alpha_value->show();
|
||||
alpha_slider->show();
|
||||
alpha_label->show();
|
||||
} else {
|
||||
alpha_value->hide();
|
||||
alpha_slider->hide();
|
||||
alpha_label->hide();
|
||||
}
|
||||
alpha_value->set_visible(edit_alpha);
|
||||
alpha_slider->set_visible(edit_alpha);
|
||||
alpha_label->set_visible(edit_alpha);
|
||||
|
||||
intensity_value->set_visible(edit_intensity);
|
||||
intensity_slider->set_visible(edit_intensity);
|
||||
intensity_label->set_visible(edit_intensity);
|
||||
|
||||
int i = 0;
|
||||
for (ColorPickerShape *shape : shapes) {
|
||||
@ -381,17 +403,17 @@ void ColorPicker::_update_controls() {
|
||||
btn_shape->set_visible(current_shape != SHAPE_NONE);
|
||||
}
|
||||
|
||||
void ColorPicker::_set_pick_color(const Color &p_color, bool p_update_sliders) {
|
||||
void ColorPicker::_set_pick_color(const Color &p_color, bool p_update_sliders, bool p_calc_intensity) {
|
||||
if (text_changed) {
|
||||
add_recent_preset(color);
|
||||
text_changed = false;
|
||||
}
|
||||
|
||||
color = p_color;
|
||||
if (color != last_color) {
|
||||
_copy_color_to_hsv();
|
||||
last_color = color;
|
||||
if (p_calc_intensity) {
|
||||
_copy_color_to_normalized_and_intensity();
|
||||
}
|
||||
_copy_normalized_to_hsv_okhsl();
|
||||
|
||||
if (!is_inside_tree()) {
|
||||
return;
|
||||
@ -401,7 +423,7 @@ void ColorPicker::_set_pick_color(const Color &p_color, bool p_update_sliders) {
|
||||
}
|
||||
|
||||
void ColorPicker::set_pick_color(const Color &p_color) {
|
||||
_set_pick_color(p_color, true); //because setters can't have more arguments
|
||||
_set_pick_color(p_color, true, true); // Because setters can't have more arguments.
|
||||
}
|
||||
|
||||
void ColorPicker::set_old_color(const Color &p_color) {
|
||||
@ -435,6 +457,32 @@ bool ColorPicker::is_editing_alpha() const {
|
||||
return edit_alpha;
|
||||
}
|
||||
|
||||
void ColorPicker::set_edit_intensity(bool p_show) {
|
||||
if (edit_intensity == p_show) {
|
||||
return;
|
||||
}
|
||||
if (p_show) {
|
||||
set_pick_color(color);
|
||||
} else {
|
||||
_normalized_apply_intensity_to_color();
|
||||
color_normalized = color;
|
||||
intensity = 0;
|
||||
}
|
||||
edit_intensity = p_show;
|
||||
_update_controls();
|
||||
|
||||
if (!is_inside_tree()) {
|
||||
return;
|
||||
}
|
||||
|
||||
_update_color();
|
||||
sample->queue_redraw();
|
||||
}
|
||||
|
||||
bool ColorPicker::is_editing_intensity() const {
|
||||
return edit_intensity;
|
||||
}
|
||||
|
||||
void ColorPicker::_slider_drag_started() {
|
||||
currently_dragging = true;
|
||||
}
|
||||
@ -444,32 +492,18 @@ void ColorPicker::_slider_value_changed() {
|
||||
return;
|
||||
}
|
||||
|
||||
color = modes[current_mode]->get_color();
|
||||
intensity = intensity_value->get_value();
|
||||
color_normalized = modes[current_mode]->get_color();
|
||||
if (edit_intensity && is_color_overbright(color_normalized)) {
|
||||
modes[current_mode]->_greater_value_inputted();
|
||||
color_normalized = modes[current_mode]->get_color();
|
||||
}
|
||||
_normalized_apply_intensity_to_color();
|
||||
intensity_value->set_prefix(intensity < 0 ? "" : "+");
|
||||
|
||||
modes[current_mode]->_value_changed();
|
||||
|
||||
if (current_mode == MODE_HSV) {
|
||||
h = sliders[0]->get_value() / 360.0;
|
||||
s = sliders[1]->get_value() / 100.0;
|
||||
v = sliders[2]->get_value() / 100.0;
|
||||
ok_hsl_h = color.get_ok_hsl_h();
|
||||
ok_hsl_s = color.get_ok_hsl_s();
|
||||
ok_hsl_l = color.get_ok_hsl_l();
|
||||
|
||||
circle_keyboard_joypad_picker_cursor_position = Vector2i();
|
||||
last_color = color;
|
||||
} else if (current_mode == MODE_OKHSL) {
|
||||
ok_hsl_h = sliders[0]->get_value() / 360.0;
|
||||
ok_hsl_s = sliders[1]->get_value() / 100.0;
|
||||
ok_hsl_l = sliders[2]->get_value() / 100.0;
|
||||
h = color.get_h();
|
||||
s = color.get_s();
|
||||
v = color.get_v();
|
||||
|
||||
circle_keyboard_joypad_picker_cursor_position = Vector2i();
|
||||
last_color = color;
|
||||
}
|
||||
|
||||
_set_pick_color(color, false);
|
||||
_set_pick_color(color, false, false);
|
||||
if (!deferred_mode_enabled || !currently_dragging) {
|
||||
emit_signal(SNAME("color_changed"), color);
|
||||
}
|
||||
@ -518,14 +552,22 @@ 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));
|
||||
slider->connect(SceneStringName(draw), callable_mp(this, &ColorPicker::_slider_draw).bind(idx));
|
||||
if (idx < 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) {
|
||||
sliders[idx] = slider;
|
||||
values[idx] = val;
|
||||
labels[idx] = lbl;
|
||||
} else {
|
||||
} else if (idx == SLIDER_INTENSITY) {
|
||||
intensity_slider = slider;
|
||||
intensity_value = val;
|
||||
intensity_label = lbl;
|
||||
} else if (idx == SLIDER_ALPHA) {
|
||||
alpha_slider = slider;
|
||||
alpha_value = val;
|
||||
alpha_label = lbl;
|
||||
@ -591,23 +633,55 @@ Vector<float> ColorPicker::get_active_slider_values() {
|
||||
return cur_values;
|
||||
}
|
||||
|
||||
void ColorPicker::_copy_color_to_hsv() {
|
||||
ok_hsl_h = color.get_ok_hsl_h();
|
||||
ok_hsl_s = color.get_ok_hsl_s();
|
||||
ok_hsl_l = color.get_ok_hsl_l();
|
||||
h = color.get_h();
|
||||
s = color.get_s();
|
||||
v = color.get_v();
|
||||
void ColorPicker::_copy_normalized_to_hsv_okhsl() {
|
||||
if (!okhsl_cached) {
|
||||
ok_hsl_h = color_normalized.get_ok_hsl_h();
|
||||
ok_hsl_s = color_normalized.get_ok_hsl_s();
|
||||
ok_hsl_l = color_normalized.get_ok_hsl_l();
|
||||
}
|
||||
if (!hsv_cached) {
|
||||
h = color_normalized.get_h();
|
||||
s = color_normalized.get_s();
|
||||
v = color_normalized.get_v();
|
||||
}
|
||||
hsv_cached = false;
|
||||
okhsl_cached = false;
|
||||
}
|
||||
|
||||
void ColorPicker::_copy_hsv_to_color() {
|
||||
void ColorPicker::_copy_hsv_okhsl_to_normalized() {
|
||||
if (current_shape != SHAPE_NONE && shapes[current_shape]->is_ok_hsl()) {
|
||||
color.set_ok_hsl(ok_hsl_h, ok_hsl_s, ok_hsl_l, color.a);
|
||||
color_normalized.set_ok_hsl(ok_hsl_h, ok_hsl_s, ok_hsl_l, color_normalized.a);
|
||||
} else {
|
||||
color.set_hsv(h, s, v, color.a);
|
||||
color_normalized.set_hsv(h, s, v, color_normalized.a);
|
||||
}
|
||||
}
|
||||
|
||||
Color ColorPicker::_color_apply_intensity(const Color &col) const {
|
||||
Color linear_color = col.srgb_to_linear();
|
||||
Color result;
|
||||
float multiplier = Math::pow(2, intensity);
|
||||
for (int i = 0; i < 3; i++) {
|
||||
result.components[i] = linear_color.components[i] * multiplier;
|
||||
}
|
||||
result.a = col.a;
|
||||
return result.linear_to_srgb();
|
||||
}
|
||||
|
||||
void ColorPicker::_normalized_apply_intensity_to_color() {
|
||||
color = _color_apply_intensity(color_normalized);
|
||||
}
|
||||
|
||||
void ColorPicker::_copy_color_to_normalized_and_intensity() {
|
||||
Color linear_color = color.srgb_to_linear();
|
||||
float multiplier = MAX(1, MAX(MAX(linear_color.r, linear_color.g), linear_color.b));
|
||||
for (int i = 0; i < 3; i++) {
|
||||
color_normalized.components[i] = linear_color.components[i] / multiplier;
|
||||
}
|
||||
color_normalized.a = linear_color.a;
|
||||
color_normalized = color_normalized.linear_to_srgb();
|
||||
intensity = Math::log2(multiplier);
|
||||
}
|
||||
|
||||
void ColorPicker::_select_from_preset_container(const Color &p_color) {
|
||||
if (preset_group->get_pressed_button()) {
|
||||
preset_group->get_pressed_button()->set_pressed(false);
|
||||
@ -660,35 +734,52 @@ void ColorPicker::_reset_sliders_theme() {
|
||||
}
|
||||
|
||||
void ColorPicker::_html_submitted(const String &p_html) {
|
||||
if (updating || text_is_constructor || !c_text->is_visible()) {
|
||||
if (updating) {
|
||||
return;
|
||||
}
|
||||
|
||||
Color new_color = Color::from_string(p_html.strip_edges(), color);
|
||||
String html_no_prefix = p_html.strip_edges().trim_prefix("#");
|
||||
if (html_no_prefix.is_valid_hex_number(false)) {
|
||||
// Convert invalid HTML color codes that software like Figma supports.
|
||||
if (html_no_prefix.length() == 1) {
|
||||
// Turn `#1` into `#111111`.
|
||||
html_no_prefix = html_no_prefix.repeat(6);
|
||||
} else if (html_no_prefix.length() == 2) {
|
||||
// Turn `#12` into `#121212`.
|
||||
html_no_prefix = html_no_prefix.repeat(3);
|
||||
} else if (html_no_prefix.length() == 5) {
|
||||
// Turn `#12345` into `#11223344`.
|
||||
html_no_prefix = html_no_prefix.left(4);
|
||||
} else if (html_no_prefix.length() == 7) {
|
||||
// Turn `#1234567` into `#123456`.
|
||||
html_no_prefix = html_no_prefix.left(6);
|
||||
Color new_color = color;
|
||||
if (text_is_constructor || !is_color_valid_hex(color)) {
|
||||
Ref<Expression> expr;
|
||||
expr.instantiate();
|
||||
Error err = expr->parse(p_html);
|
||||
if (err == OK) {
|
||||
Variant result = expr->execute(Array(), nullptr, false, true);
|
||||
// This is basically the same as Variant::operator Color(), but remains original color if Color::from_string() fails
|
||||
if (result.get_type() == Variant::COLOR) {
|
||||
new_color = result;
|
||||
} else if (result.get_type() == Variant::STRING) {
|
||||
new_color = Color::from_string(result, color);
|
||||
} else if (result.get_type() == Variant::INT) {
|
||||
new_color = Color::hex(result);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
new_color = Color::from_string(p_html.strip_edges(), color);
|
||||
String html_no_prefix = p_html.strip_edges().trim_prefix("#");
|
||||
if (html_no_prefix.is_valid_hex_number(false)) {
|
||||
// Convert invalid HTML color codes that software like Figma supports.
|
||||
if (html_no_prefix.length() == 1) {
|
||||
// Turn `#1` into `#111111`.
|
||||
html_no_prefix = html_no_prefix.repeat(6);
|
||||
} else if (html_no_prefix.length() == 2) {
|
||||
// Turn `#12` into `#121212`.
|
||||
html_no_prefix = html_no_prefix.repeat(3);
|
||||
} else if (html_no_prefix.length() == 5) {
|
||||
// Turn `#12345` into `#11223344`.
|
||||
html_no_prefix = html_no_prefix.left(4);
|
||||
} else if (html_no_prefix.length() == 7) {
|
||||
// Turn `#1234567` into `#123456`.
|
||||
html_no_prefix = html_no_prefix.left(6);
|
||||
}
|
||||
}
|
||||
new_color = Color::from_string(html_no_prefix, new_color);
|
||||
}
|
||||
new_color = Color::from_string(html_no_prefix, new_color);
|
||||
|
||||
if (!is_editing_alpha()) {
|
||||
new_color.a = color.a;
|
||||
}
|
||||
|
||||
if (new_color.to_argb32() == color.to_argb32()) {
|
||||
if (new_color == color) {
|
||||
return;
|
||||
}
|
||||
color = new_color;
|
||||
@ -714,9 +805,11 @@ void ColorPicker::_update_color(bool p_update_sliders) {
|
||||
values[i]->set_custom_arrow_step(spinbox_arrow_step);
|
||||
values[i]->set_allow_greater(modes[current_mode]->get_allow_greater());
|
||||
}
|
||||
alpha_slider->set_max(modes[current_mode]->get_slider_max(current_slider_count));
|
||||
alpha_slider->set_max(modes[current_mode]->get_alpha_slider_max());
|
||||
alpha_slider->set_step(step);
|
||||
alpha_slider->set_value(modes[current_mode]->get_slider_value(current_slider_count));
|
||||
alpha_slider->set_value(modes[current_mode]->get_alpha_slider_value());
|
||||
intensity_slider->set_value(intensity);
|
||||
intensity_value->set_prefix(intensity < 0 ? "" : "+");
|
||||
}
|
||||
|
||||
_update_text_value();
|
||||
@ -808,16 +901,16 @@ void ColorPicker::_update_recent_presets() {
|
||||
void ColorPicker::_text_type_toggled() {
|
||||
text_is_constructor = !text_is_constructor;
|
||||
if (text_is_constructor) {
|
||||
hex_label->set_text(ETR("Expr"));
|
||||
text_type->set_text("");
|
||||
text_type->set_button_icon(get_editor_theme_icon(SNAME("Script")));
|
||||
text_type->set_button_icon(theme_cache.color_script);
|
||||
|
||||
c_text->set_editable(false);
|
||||
c_text->set_tooltip_text(TTRC("Copy this constructor in a script."));
|
||||
c_text->set_tooltip_text(RTR("Execute an expression as a color."));
|
||||
} else {
|
||||
hex_label->set_text(ETR("Hex"));
|
||||
text_type->set_text("#");
|
||||
text_type->set_button_icon(nullptr);
|
||||
|
||||
c_text->set_editable(true);
|
||||
c_text->set_tooltip_text(ETR("Enter a hex code (\"#ff0000\") or named color (\"red\")."));
|
||||
}
|
||||
_update_color();
|
||||
@ -845,7 +938,6 @@ void ColorPicker::set_picker_shape(PickerShapeType p_shape) {
|
||||
btn_shape->set_button_icon(shape_popup->get_item_icon(p_shape));
|
||||
}
|
||||
|
||||
circle_keyboard_joypad_picker_cursor_position = Vector2i();
|
||||
current_shape = p_shape;
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
@ -854,8 +946,6 @@ void ColorPicker::set_picker_shape(PickerShapeType p_shape) {
|
||||
}
|
||||
#endif
|
||||
|
||||
_copy_color_to_hsv();
|
||||
|
||||
_update_controls();
|
||||
_update_color();
|
||||
}
|
||||
@ -1012,7 +1102,6 @@ void ColorPicker::_set_mode_popup_value(ColorModeType p_mode) {
|
||||
} else {
|
||||
set_color_mode(p_mode);
|
||||
}
|
||||
circle_keyboard_joypad_picker_cursor_position = Vector2i();
|
||||
}
|
||||
|
||||
Variant ColorPicker::_get_drag_data_fw(const Point2 &p_point, Control *p_from_control) {
|
||||
@ -1215,10 +1304,6 @@ void ColorPicker::set_color_mode(ColorModeType p_mode) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (slider_theme_modified) {
|
||||
_reset_sliders_theme();
|
||||
}
|
||||
|
||||
mode_popup->set_item_checked(current_mode, false);
|
||||
mode_popup->set_item_checked(p_mode, true);
|
||||
|
||||
@ -1259,22 +1344,20 @@ void ColorPicker::set_colorize_sliders(bool p_colorize_sliders) {
|
||||
if (colorize_sliders) {
|
||||
Ref<StyleBoxEmpty> style_box_empty(memnew(StyleBoxEmpty));
|
||||
|
||||
if (!slider_theme_modified) {
|
||||
for (int i = 0; i < SLIDER_COUNT; i++) {
|
||||
sliders[i]->add_theme_style_override("slider", style_box_empty);
|
||||
}
|
||||
for (int i = 0; i < SLIDER_COUNT; i++) {
|
||||
sliders[i]->add_theme_style_override("slider", style_box_empty);
|
||||
}
|
||||
|
||||
alpha_slider->add_theme_style_override("slider", style_box_empty);
|
||||
} else {
|
||||
Ref<StyleBoxFlat> style_box_flat(memnew(StyleBoxFlat));
|
||||
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());
|
||||
|
||||
if (!slider_theme_modified) {
|
||||
for (int i = 0; i < SLIDER_COUNT; i++) {
|
||||
sliders[i]->add_theme_style_override("slider", style_box_flat);
|
||||
}
|
||||
for (int i = 0; i < SLIDER_COUNT; i++) {
|
||||
sliders[i]->add_theme_style_override("slider", style_box_flat);
|
||||
}
|
||||
|
||||
alpha_slider->add_theme_style_override("slider", style_box_flat);
|
||||
}
|
||||
}
|
||||
@ -1292,25 +1375,21 @@ bool ColorPicker::is_deferred_mode() const {
|
||||
}
|
||||
|
||||
void ColorPicker::_update_text_value() {
|
||||
bool text_visible = true;
|
||||
if (text_is_constructor) {
|
||||
String t = "Color(" + String::num(color.r, 3) + ", " + String::num(color.g, 3) + ", " + String::num(color.b, 3);
|
||||
if (edit_alpha && color.a < 1) {
|
||||
t += ", " + String::num(color.a, 3) + ")";
|
||||
} else {
|
||||
t += ")";
|
||||
}
|
||||
c_text->set_text(t);
|
||||
}
|
||||
if (text_is_constructor || !is_color_valid_hex(color)) {
|
||||
String t = "Color" + color_to_string(color, edit_alpha && color.a < 1, true);
|
||||
|
||||
if (color.r > 1 || color.g > 1 || color.b > 1 || color.r < 0 || color.g < 0 || color.b < 0) {
|
||||
text_visible = false;
|
||||
} else if (!text_is_constructor) {
|
||||
text_type->set_text("");
|
||||
text_type->set_button_icon(theme_cache.color_script);
|
||||
text_type->set_disabled(!is_color_valid_hex(color));
|
||||
hex_label->set_text(ETR("Expr"));
|
||||
c_text->set_text(t);
|
||||
} else {
|
||||
text_type->set_text("#");
|
||||
text_type->set_button_icon(nullptr);
|
||||
text_type->set_disabled(false);
|
||||
hex_label->set_text(ETR("Hex"));
|
||||
c_text->set_text(color.to_html(edit_alpha && color.a < 1));
|
||||
}
|
||||
|
||||
text_type->set_visible(text_visible);
|
||||
c_text->set_visible(text_visible);
|
||||
}
|
||||
|
||||
void ColorPicker::_sample_input(const Ref<InputEvent> &p_event) {
|
||||
@ -1366,7 +1445,7 @@ void ColorPicker::_sample_draw() {
|
||||
sample->set_focus_mode(FOCUS_NONE);
|
||||
}
|
||||
|
||||
if (old_color.r > 1 || old_color.g > 1 || old_color.b > 1) {
|
||||
if (is_color_overbright(color)) {
|
||||
// Draw an indicator to denote that the old color is "overbright" and can't be displayed accurately in the preview.
|
||||
sample->draw_texture(theme_cache.overbright_indicator, Point2());
|
||||
}
|
||||
@ -1385,7 +1464,7 @@ void ColorPicker::_sample_draw() {
|
||||
theme_cache.sample_focus->draw(ci, rect_old);
|
||||
}
|
||||
|
||||
if (color.r > 1 || color.g > 1 || color.b > 1) {
|
||||
if (is_color_overbright(color)) {
|
||||
// Draw an indicator to denote that the new color is "overbright" and can't be displayed accurately in the preview.
|
||||
sample->draw_texture(theme_cache.overbright_indicator, Point2(sample->get_size().width * 0.5, 0));
|
||||
}
|
||||
@ -1397,6 +1476,37 @@ void ColorPicker::_slider_draw(int p_which) {
|
||||
}
|
||||
}
|
||||
|
||||
void ColorPicker::_alpha_slider_draw() {
|
||||
if (!colorize_sliders) {
|
||||
return;
|
||||
}
|
||||
Vector<Vector2> pos;
|
||||
pos.resize(4);
|
||||
Vector<Color> col;
|
||||
col.resize(4);
|
||||
Size2 size = alpha_slider->get_size();
|
||||
Color left_color;
|
||||
Color right_color;
|
||||
const real_t margin = 16 * theme_cache.base_scale;
|
||||
alpha_slider->draw_texture_rect(theme_cache.sample_bg, Rect2(Point2(0, 0), Size2(size.x, margin)), true);
|
||||
|
||||
left_color = color_normalized;
|
||||
left_color.a = 0;
|
||||
right_color = color_normalized;
|
||||
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, 0));
|
||||
pos.set(1, Vector2(size.x, 0));
|
||||
pos.set(2, Vector2(size.x, margin));
|
||||
pos.set(3, Vector2(0, margin));
|
||||
|
||||
alpha_slider->draw_polygon(pos, col);
|
||||
}
|
||||
|
||||
void ColorPicker::_slider_or_spin_input(const Ref<InputEvent> &p_event) {
|
||||
if (line_edit_mouse_release) {
|
||||
line_edit_mouse_release = false;
|
||||
@ -1443,7 +1553,11 @@ void ColorPicker::_recent_preset_pressed(const bool p_pressed, ColorPresetButton
|
||||
if (!p_pressed) {
|
||||
return;
|
||||
}
|
||||
set_pick_color(p_preset->get_preset_color());
|
||||
|
||||
// Avoid applying and recalculating the intensity for non-overbright color if it doesn't change.
|
||||
if (color != p_preset->get_preset_color()) {
|
||||
set_pick_color(p_preset->get_preset_color());
|
||||
}
|
||||
|
||||
recent_presets.move_to_back(recent_presets.find(p_preset->get_preset_color()));
|
||||
List<Color>::Element *e = recent_preset_cache.find(p_preset->get_preset_color());
|
||||
@ -1820,7 +1934,6 @@ void ColorPicker::_html_focus_exit() {
|
||||
} else {
|
||||
_update_text_value();
|
||||
}
|
||||
circle_keyboard_joypad_picker_cursor_position = Vector2i();
|
||||
}
|
||||
|
||||
void ColorPicker::set_can_add_swatches(bool p_enabled) {
|
||||
@ -1910,6 +2023,8 @@ void ColorPicker::_bind_methods() {
|
||||
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_edit_intensity", "show"), &ColorPicker::set_edit_intensity);
|
||||
ClassDB::bind_method(D_METHOD("is_editing_intensity"), &ColorPicker::is_editing_intensity);
|
||||
ClassDB::bind_method(D_METHOD("set_can_add_swatches", "enabled"), &ColorPicker::set_can_add_swatches);
|
||||
ClassDB::bind_method(D_METHOD("are_swatches_enabled"), &ColorPicker::are_swatches_enabled);
|
||||
ClassDB::bind_method(D_METHOD("set_presets_visible", "visible"), &ColorPicker::set_presets_visible);
|
||||
@ -1933,7 +2048,8 @@ void ColorPicker::_bind_methods() {
|
||||
|
||||
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::INT, "color_mode", PROPERTY_HINT_ENUM, "RGB,HSV,RAW,OKHSL"), "set_color_mode", "get_color_mode");
|
||||
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::BOOL, "can_add_swatches"), "set_can_add_swatches", "are_swatches_enabled");
|
||||
@ -1950,7 +2066,10 @@ void ColorPicker::_bind_methods() {
|
||||
|
||||
BIND_ENUM_CONSTANT(MODE_RGB);
|
||||
BIND_ENUM_CONSTANT(MODE_HSV);
|
||||
#ifndef DISABLE_DEPRECATED
|
||||
BIND_ENUM_CONSTANT(MODE_RAW);
|
||||
#endif
|
||||
BIND_ENUM_CONSTANT(MODE_LINEAR);
|
||||
BIND_ENUM_CONSTANT(MODE_OKHSL);
|
||||
|
||||
BIND_ENUM_CONSTANT(SHAPE_HSV_RECTANGLE);
|
||||
@ -1990,6 +2109,8 @@ void ColorPicker::_bind_methods() {
|
||||
BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, ColorPicker, picker_cursor_bg);
|
||||
BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, ColorPicker, color_hue);
|
||||
|
||||
BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, ColorPicker, color_script);
|
||||
|
||||
BIND_THEME_ITEM_EXT(Theme::DATA_TYPE_STYLEBOX, ColorPicker, mode_button_normal, "tab_unselected", "TabContainer");
|
||||
BIND_THEME_ITEM_EXT(Theme::DATA_TYPE_STYLEBOX, ColorPicker, mode_button_pressed, "tab_selected", "TabContainer");
|
||||
BIND_THEME_ITEM_EXT(Theme::DATA_TYPE_STYLEBOX, ColorPicker, mode_button_hover, "tab_selected", "TabContainer");
|
||||
@ -2049,7 +2170,7 @@ ColorPicker::ColorPicker() {
|
||||
|
||||
add_mode(memnew(ColorModeRGB(this)));
|
||||
add_mode(memnew(ColorModeHSV(this)));
|
||||
add_mode(memnew(ColorModeRAW(this)));
|
||||
add_mode(memnew(ColorModeLinear(this)));
|
||||
add_mode(memnew(ColorModeOKHSL(this)));
|
||||
|
||||
mode_hbc = memnew(HBoxContainer);
|
||||
@ -2099,17 +2220,23 @@ ColorPicker::ColorPicker() {
|
||||
slider_gc->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||
slider_gc->set_columns(3);
|
||||
|
||||
for (int i = 0; i < SLIDER_COUNT + 1; i++) {
|
||||
for (int i = 0; i < SLIDER_MAX; i++) {
|
||||
create_slider(slider_gc, i);
|
||||
}
|
||||
|
||||
alpha_label->set_text("A");
|
||||
|
||||
intensity_label->set_text("I");
|
||||
intensity_slider->set_min(-10);
|
||||
intensity_slider->set_max(10);
|
||||
intensity_slider->set_step(0.001);
|
||||
intensity_value->set_allow_greater(true);
|
||||
intensity_value->set_custom_arrow_step(1);
|
||||
|
||||
hex_hbc = memnew(HBoxContainer);
|
||||
hex_hbc->set_alignment(ALIGNMENT_BEGIN);
|
||||
real_vbox->add_child(hex_hbc);
|
||||
|
||||
hex_hbc->add_child(memnew(Label(ETR("Hex"))));
|
||||
hex_label = memnew(Label(ETR("Hex")));
|
||||
hex_hbc->add_child(hex_label);
|
||||
|
||||
text_type = memnew(Button);
|
||||
hex_hbc->add_child(text_type);
|
||||
@ -2128,8 +2255,6 @@ ColorPicker::ColorPicker() {
|
||||
text_type->set_accessibility_name(ETR("Hexadecimal Values"));
|
||||
#endif // TOOLS_ENABLED
|
||||
text_type->set_flat(true);
|
||||
text_type->set_focus_mode(FOCUS_NONE);
|
||||
text_type->set_mouse_filter(MOUSE_FILTER_IGNORE);
|
||||
}
|
||||
|
||||
c_text = memnew(LineEdit);
|
||||
@ -2376,6 +2501,20 @@ bool ColorPickerButton::is_editing_alpha() const {
|
||||
return edit_alpha;
|
||||
}
|
||||
|
||||
void ColorPickerButton::set_edit_intensity(bool p_show) {
|
||||
if (edit_intensity == p_show) {
|
||||
return;
|
||||
}
|
||||
edit_intensity = p_show;
|
||||
if (picker) {
|
||||
picker->set_edit_intensity(p_show);
|
||||
}
|
||||
}
|
||||
|
||||
bool ColorPickerButton::is_editing_intensity() const {
|
||||
return edit_intensity;
|
||||
}
|
||||
|
||||
ColorPicker *ColorPickerButton::get_picker() {
|
||||
_update_picker();
|
||||
return picker;
|
||||
@ -2400,6 +2539,7 @@ void ColorPickerButton::_update_picker() {
|
||||
picker->connect(SceneStringName(minimum_size_changed), callable_mp((Window *)popup, &Window::reset_size));
|
||||
picker->set_pick_color(color);
|
||||
picker->set_edit_alpha(edit_alpha);
|
||||
picker->set_edit_intensity(edit_intensity);
|
||||
picker->set_display_old_color(true);
|
||||
emit_signal(SNAME("picker_created"));
|
||||
}
|
||||
@ -2412,6 +2552,8 @@ void ColorPickerButton::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_popup"), &ColorPickerButton::get_popup);
|
||||
ClassDB::bind_method(D_METHOD("set_edit_alpha", "show"), &ColorPickerButton::set_edit_alpha);
|
||||
ClassDB::bind_method(D_METHOD("is_editing_alpha"), &ColorPickerButton::is_editing_alpha);
|
||||
ClassDB::bind_method(D_METHOD("set_edit_intensity", "show"), &ColorPickerButton::set_edit_intensity);
|
||||
ClassDB::bind_method(D_METHOD("is_editing_intensity"), &ColorPickerButton::is_editing_intensity);
|
||||
ClassDB::bind_method(D_METHOD("_about_to_popup"), &ColorPickerButton::_about_to_popup);
|
||||
|
||||
ADD_SIGNAL(MethodInfo("color_changed", PropertyInfo(Variant::COLOR, "color")));
|
||||
@ -2419,6 +2561,7 @@ void ColorPickerButton::_bind_methods() {
|
||||
ADD_SIGNAL(MethodInfo("picker_created"));
|
||||
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, "edit_intensity"), "set_edit_intensity", "is_editing_intensity");
|
||||
|
||||
BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_STYLEBOX, ColorPickerButton, normal_style, "normal");
|
||||
BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_ICON, ColorPickerButton, background_icon, "bg");
|
||||
@ -2488,7 +2631,7 @@ void ColorPresetButton::_notification(int p_what) {
|
||||
theme_cache.focus_style->draw(ci, Rect2(Point2(), get_size()));
|
||||
}
|
||||
|
||||
if (preset_color.r > 1 || preset_color.g > 1 || preset_color.b > 1) {
|
||||
if (is_color_overbright(preset_color)) {
|
||||
// Draw an indicator to denote that the color is "overbright" and can't be displayed accurately in the preview
|
||||
draw_texture(theme_cache.overbright_indicator, Vector2(0, 0));
|
||||
}
|
||||
@ -2509,9 +2652,9 @@ Color ColorPresetButton::get_preset_color() const {
|
||||
String ColorPresetButton::get_tooltip(const Point2 &p_pos) const {
|
||||
Color color = get_preset_color();
|
||||
if (recent) {
|
||||
return vformat(atr(ETR("Color: #%s\nLMB: Apply color")), color.to_html(color.a < 1));
|
||||
return vformat(atr(ETR("Color: %s\nLMB: Apply color")), color_to_string(color, color.a < 1));
|
||||
}
|
||||
return vformat(atr(ETR("Color: #%s\nLMB: Apply color\nRMB: Remove preset")), color.to_html(color.a < 1));
|
||||
return vformat(atr(ETR("Color: %s\nLMB: Apply color\nRMB: Remove preset")), color_to_string(color, color.a < 1));
|
||||
}
|
||||
|
||||
void ColorPresetButton::_bind_methods() {
|
||||
@ -2526,7 +2669,7 @@ ColorPresetButton::ColorPresetButton(Color p_color, int p_size, bool p_recent) {
|
||||
recent = p_recent;
|
||||
set_toggle_mode(true);
|
||||
set_custom_minimum_size(Size2(p_size, p_size));
|
||||
set_accessibility_name(vformat(atr(ETR("Color: #%s")), p_color.to_html(p_color.a < 1)));
|
||||
set_accessibility_name(vformat(atr(ETR("Color: %s")), color_to_string(p_color, p_color.a < 1)));
|
||||
set_tooltip_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
|
||||
}
|
||||
|
||||
|
||||
@ -91,14 +91,17 @@ class ColorPicker : public VBoxContainer {
|
||||
|
||||
friend class ColorModeRGB;
|
||||
friend class ColorModeHSV;
|
||||
friend class ColorModeRAW;
|
||||
friend class ColorModeLinear;
|
||||
friend class ColorModeOKHSL;
|
||||
|
||||
public:
|
||||
enum ColorModeType {
|
||||
MODE_RGB,
|
||||
MODE_HSV,
|
||||
MODE_RAW,
|
||||
#ifndef DISABLE_DEPRECATED
|
||||
MODE_RAW = 2,
|
||||
#endif
|
||||
MODE_LINEAR = 2,
|
||||
MODE_OKHSL,
|
||||
|
||||
MODE_MAX
|
||||
@ -115,6 +118,12 @@ public:
|
||||
};
|
||||
|
||||
static const int SLIDER_COUNT = 3;
|
||||
enum SLIDER_EXTRA {
|
||||
SLIDER_INTENSITY = 3,
|
||||
SLIDER_ALPHA,
|
||||
|
||||
SLIDER_MAX
|
||||
};
|
||||
|
||||
private:
|
||||
enum class MenuOption {
|
||||
@ -136,7 +145,6 @@ private:
|
||||
#endif
|
||||
|
||||
int current_slider_count = SLIDER_COUNT;
|
||||
Vector2i circle_keyboard_joypad_picker_cursor_position;
|
||||
|
||||
const float DEFAULT_GAMEPAD_EVENT_DELAY_MS = 1.0 / 2;
|
||||
const float GAMEPAD_EVENT_REPEAT_RATE_MS = 1.0 / 30;
|
||||
@ -182,6 +190,7 @@ private:
|
||||
HBoxContainer *sample_hbc = nullptr;
|
||||
GridContainer *slider_gc = nullptr;
|
||||
HBoxContainer *hex_hbc = nullptr;
|
||||
Label *hex_label = nullptr;
|
||||
MenuButton *btn_mode = nullptr;
|
||||
Button *mode_btns[MODE_BUTTON_COUNT];
|
||||
Ref<ButtonGroup> mode_group;
|
||||
@ -199,9 +208,10 @@ private:
|
||||
|
||||
OptionButton *mode_option_button = nullptr;
|
||||
|
||||
HSlider *sliders[SLIDER_COUNT];
|
||||
SpinBox *values[SLIDER_COUNT];
|
||||
Label *labels[SLIDER_COUNT];
|
||||
HSlider *sliders[SLIDER_MAX];
|
||||
SpinBox *values[SLIDER_MAX];
|
||||
Label *labels[SLIDER_MAX];
|
||||
|
||||
Button *text_type = nullptr;
|
||||
LineEdit *c_text = nullptr;
|
||||
|
||||
@ -210,6 +220,13 @@ private:
|
||||
Label *alpha_label = nullptr;
|
||||
|
||||
bool edit_alpha = true;
|
||||
|
||||
HSlider *intensity_slider = nullptr;
|
||||
SpinBox *intensity_value = nullptr;
|
||||
Label *intensity_label = nullptr;
|
||||
|
||||
bool edit_intensity = true;
|
||||
|
||||
Size2i ms;
|
||||
bool text_is_constructor = false;
|
||||
PickerShapeType current_shape = SHAPE_HSV_RECTANGLE;
|
||||
@ -223,6 +240,7 @@ private:
|
||||
List<Color> recent_presets;
|
||||
|
||||
Color color;
|
||||
Color color_normalized;
|
||||
Color old_color;
|
||||
Color pre_picking_color;
|
||||
bool is_picking_color = false;
|
||||
@ -250,7 +268,10 @@ private:
|
||||
float ok_hsl_s = 0.0;
|
||||
float ok_hsl_l = 0.0;
|
||||
|
||||
Color last_color;
|
||||
bool hsv_cached = false;
|
||||
bool okhsl_cached = false;
|
||||
|
||||
float intensity = 0.0;
|
||||
|
||||
struct ThemeCache {
|
||||
float base_scale = 1.0;
|
||||
@ -286,14 +307,20 @@ private:
|
||||
Ref<Texture2D> picker_cursor_bg;
|
||||
Ref<Texture2D> color_hue;
|
||||
|
||||
Ref<Texture2D> color_script;
|
||||
|
||||
/* Mode buttons */
|
||||
Ref<StyleBox> mode_button_normal;
|
||||
Ref<StyleBox> mode_button_pressed;
|
||||
Ref<StyleBox> mode_button_hover;
|
||||
} theme_cache;
|
||||
|
||||
void _copy_color_to_hsv();
|
||||
void _copy_hsv_to_color();
|
||||
void _copy_normalized_to_hsv_okhsl();
|
||||
void _copy_hsv_okhsl_to_normalized();
|
||||
|
||||
Color _color_apply_intensity(const Color &col) const;
|
||||
void _normalized_apply_intensity_to_color();
|
||||
void _copy_color_to_normalized_and_intensity();
|
||||
|
||||
void create_slider(GridContainer *gc, int idx);
|
||||
void _reset_sliders_theme();
|
||||
@ -310,6 +337,7 @@ private:
|
||||
void _sample_input(const Ref<InputEvent> &p_event);
|
||||
void _sample_draw();
|
||||
void _slider_draw(int p_which);
|
||||
void _alpha_slider_draw();
|
||||
|
||||
void _slider_or_spin_input(const Ref<InputEvent> &p_event);
|
||||
void _line_edit_input(const Ref<InputEvent> &p_event);
|
||||
@ -378,7 +406,10 @@ public:
|
||||
void set_edit_alpha(bool p_show);
|
||||
bool is_editing_alpha() const;
|
||||
|
||||
void _set_pick_color(const Color &p_color, bool p_update_sliders);
|
||||
void set_edit_intensity(bool p_show);
|
||||
bool is_editing_intensity() const;
|
||||
|
||||
void _set_pick_color(const Color &p_color, bool p_update_sliders, bool p_calc_intensity);
|
||||
void set_pick_color(const Color &p_color);
|
||||
Color get_pick_color() const;
|
||||
void set_old_color(const Color &p_color);
|
||||
@ -453,6 +484,7 @@ class ColorPickerButton : public Button {
|
||||
ColorPicker *picker = nullptr;
|
||||
Color color;
|
||||
bool edit_alpha = true;
|
||||
bool edit_intensity = true;
|
||||
|
||||
struct ThemeCache {
|
||||
Ref<StyleBox> normal_style;
|
||||
@ -480,6 +512,9 @@ public:
|
||||
void set_edit_alpha(bool p_show);
|
||||
bool is_editing_alpha() const;
|
||||
|
||||
void set_edit_intensity(bool p_show);
|
||||
bool is_editing_intensity() const;
|
||||
|
||||
ColorPicker *get_picker();
|
||||
PopupPanel *get_popup();
|
||||
|
||||
|
||||
@ -68,9 +68,11 @@ bool ColorPickerShape::can_handle(const Ref<InputEvent> &p_event, Vector2 &r_pos
|
||||
}
|
||||
|
||||
void ColorPickerShape::apply_color() {
|
||||
color_picker->_copy_hsv_to_color();
|
||||
color_picker->last_color = color_picker->color;
|
||||
color_picker->set_pick_color(color_picker->color);
|
||||
color_picker->_copy_hsv_okhsl_to_normalized();
|
||||
color_picker->_normalized_apply_intensity_to_color();
|
||||
color_picker->hsv_cached = true;
|
||||
color_picker->okhsl_cached = true;
|
||||
color_picker->_set_pick_color(color_picker->color, true, false);
|
||||
|
||||
if (!color_picker->deferred_mode_enabled) {
|
||||
_emit_color_changed();
|
||||
@ -122,10 +124,8 @@ void ColorPickerShape::draw_sv_square(Control *p_control, const Rect2 &p_square,
|
||||
Vector2(p_square.position.x, end.y),
|
||||
};
|
||||
|
||||
Color color1 = color_picker->color;
|
||||
color1.set_hsv(color_picker->h, 1, 1);
|
||||
Color color2 = color1;
|
||||
color2.set_hsv(color_picker->h, 1, 0);
|
||||
Color color1 = Color::from_hsv(color_picker->h, 1, 1);
|
||||
Color color2 = Color::from_hsv(color_picker->h, 1, 0);
|
||||
|
||||
PackedColorArray colors = {
|
||||
Color(1, 1, 1, 1),
|
||||
|
||||
@ -1060,6 +1060,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
|
||||
theme->set_icon("bar_arrow", "ColorPicker", icons["color_picker_bar_arrow"]);
|
||||
theme->set_icon("picker_cursor", "ColorPicker", icons["color_picker_cursor"]);
|
||||
theme->set_icon("picker_cursor_bg", "ColorPicker", icons["color_picker_cursor_bg"]);
|
||||
theme->set_icon("color_script", "ColorPicker", icons["script"]);
|
||||
|
||||
{
|
||||
const int precision = 7;
|
||||
|
||||
1
scene/theme/icons/script.svg
Normal file
1
scene/theme/icons/script.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#e0e0e0" d="M6 1a2 2 0 0 0-2 2v7H1v3a2 2 0 0 0 2 2h7a2 2 0 0 0 2-2V5h3V3a2 2 0 0 0-2-2z"/><path fill-opacity=".2" d="M6 1a2 2 0 0 0-2 2v7H1v3a2 2 0 1 0 4 0V3a1 1 0 0 1 2 0v3h5V5H8V3a2 2 0 0 0-2-2zM2 11h2v2a1 1 0 0 1-2 0z"/></svg>
|
||||
|
After Width: | Height: | Size: 305 B |
Reference in New Issue
Block a user