Added a new ColorSelectorButton. Same idea as the ColorPickerButton, except left clicking it emits a pressed signal, right clicking it opens a color picker.

This commit is contained in:
Relintai 2022-11-17 17:42:07 +01:00
parent 6ddd0c1fa3
commit f72fa755e0
3 changed files with 198 additions and 5 deletions

View File

@ -34,6 +34,7 @@
#include "core/os/keyboard.h" #include "core/os/keyboard.h"
#include "core/os/os.h" #include "core/os/os.h"
#include "core/input/shortcut.h"
#include "scene/gui/check_button.h" #include "scene/gui/check_button.h"
#include "scene/gui/grid_container.h" #include "scene/gui/grid_container.h"
#include "scene/gui/label.h" #include "scene/gui/label.h"
@ -41,7 +42,6 @@
#include "scene/gui/popup.h" #include "scene/gui/popup.h"
#include "scene/gui/popup_menu.h" #include "scene/gui/popup_menu.h"
#include "scene/gui/separator.h" #include "scene/gui/separator.h"
#include "core/input/shortcut.h"
#include "scene/gui/slider.h" #include "scene/gui/slider.h"
#include "scene/gui/spin_box.h" #include "scene/gui/spin_box.h"
#include "scene/gui/texture_rect.h" #include "scene/gui/texture_rect.h"
@ -1148,3 +1148,158 @@ ColorPresetButton::ColorPresetButton(Color p_color) {
ColorPresetButton::~ColorPresetButton() { ColorPresetButton::~ColorPresetButton() {
} }
/////////////////
void ColorSelectorButton::_about_to_show() {
set_pressed(true);
if (picker) {
picker->set_old_color(color);
}
}
void ColorSelectorButton::_color_changed(const Color &p_color) {
color = p_color;
update();
emit_signal("color_changed", color);
}
void ColorSelectorButton::_modal_closed() {
emit_signal("popup_closed");
}
void ColorSelectorButton::popup_open_request() {
_update_picker();
picker->_update_presets();
popup->set_position(get_global_position() - picker->get_combined_minimum_size() * get_global_transform().get_scale());
popup->set_scale(get_global_transform().get_scale());
popup->popup();
picker->set_focus_on_line_edit();
}
void ColorSelectorButton::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_DRAW: {
const Ref<StyleBox> normal = get_theme_stylebox("normal");
const Rect2 r = Rect2(normal->get_offset(), get_size() - normal->get_minimum_size());
draw_texture_rect(Control::get_theme_icon("bg", "ColorPickerButton"), r, true);
draw_rect(r, color);
if (color.r > 1 || color.g > 1 || color.b > 1) {
// Draw an indicator to denote that the color is "overbright" and can't be displayed accurately in the preview
draw_texture(Control::get_theme_icon("overbright_indicator", "ColorPicker"), normal->get_offset());
}
} break;
case MainLoop::NOTIFICATION_WM_QUIT_REQUEST: {
if (popup) {
popup->hide();
}
} break;
}
if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
if (popup && !is_visible_in_tree()) {
popup->hide();
}
}
}
void ColorSelectorButton::set_pick_color(const Color &p_color) {
color = p_color;
if (picker) {
picker->set_pick_color(p_color);
}
update();
}
Color ColorSelectorButton::get_pick_color() const {
return color;
}
void ColorSelectorButton::set_edit_alpha(bool p_show) {
edit_alpha = p_show;
if (picker) {
picker->set_edit_alpha(p_show);
}
}
bool ColorSelectorButton::is_editing_alpha() const {
return edit_alpha;
}
ColorPicker *ColorSelectorButton::get_picker() {
_update_picker();
return picker;
}
PopupPanel *ColorSelectorButton::get_popup() {
_update_picker();
return popup;
}
void ColorSelectorButton::_update_picker() {
if (!picker) {
popup = memnew(PopupPanel);
picker = memnew(ColorPicker);
popup->add_child(picker);
add_child(popup);
picker->connect("color_changed", this, "_color_changed");
popup->connect("modal_closed", this, "_modal_closed");
popup->connect("about_to_show", this, "_about_to_show");
popup->connect("popup_hide", this, "set_pressed", varray(false));
popup->connect("popup_hide", this, "set_toggle_mode", varray(false));
picker->set_pick_color(color);
picker->set_edit_alpha(edit_alpha);
picker->set_display_old_color(true);
emit_signal("picker_created");
}
}
void ColorSelectorButton::pressed() {
if (_button == BUTTON_LEFT) {
Button::pressed();
} else if (_button == BUTTON_RIGHT) {
set_toggle_mode(true);
popup_open_request();
}
}
void ColorSelectorButton::_gui_input(Ref<InputEvent> p_event) {
Ref<InputEventMouseButton> mouse_button = p_event;
if (mouse_button.is_valid()) {
_button = mouse_button->get_button_index();
}
BaseButton::_gui_input(p_event);
}
void ColorSelectorButton::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_pick_color", "color"), &ColorSelectorButton::set_pick_color);
ClassDB::bind_method(D_METHOD("get_pick_color"), &ColorSelectorButton::get_pick_color);
ClassDB::bind_method(D_METHOD("get_picker"), &ColorSelectorButton::get_picker);
ClassDB::bind_method(D_METHOD("get_popup"), &ColorSelectorButton::get_popup);
ClassDB::bind_method(D_METHOD("set_edit_alpha", "show"), &ColorSelectorButton::set_edit_alpha);
ClassDB::bind_method(D_METHOD("is_editing_alpha"), &ColorSelectorButton::is_editing_alpha);
ClassDB::bind_method(D_METHOD("_about_to_show"), &ColorSelectorButton::_about_to_show);
ClassDB::bind_method(D_METHOD("_color_changed"), &ColorSelectorButton::_color_changed);
ClassDB::bind_method(D_METHOD("_modal_closed"), &ColorSelectorButton::_modal_closed);
ADD_SIGNAL(MethodInfo("color_changed", PropertyInfo(Variant::COLOR, "color")));
ADD_SIGNAL(MethodInfo("popup_closed"));
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");
}
ColorSelectorButton::ColorSelectorButton() {
_button = 0;
// Initialization is now done deferred,
// this improves performance in the inspector as the color picker
// can be expensive to initialize.
picker = nullptr;
popup = nullptr;
edit_alpha = true;
set_button_mask(BUTTON_MASK_LEFT | BUTTON_MASK_RIGHT);
}

View File

@ -201,4 +201,42 @@ public:
ColorPickerButton(); ColorPickerButton();
}; };
class ColorSelectorButton : public Button {
GDCLASS(ColorSelectorButton, Button);
PopupPanel *popup;
ColorPicker *picker;
Color color;
bool edit_alpha;
void _about_to_show();
void _color_changed(const Color &p_color);
void _modal_closed();
virtual void popup_open_request();
void _update_picker();
protected:
void pressed();
void _gui_input(Ref<InputEvent> p_event);
void _notification(int);
static void _bind_methods();
int _button;
public:
void set_pick_color(const Color &p_color);
Color get_pick_color() const;
void set_edit_alpha(bool p_show);
bool is_editing_alpha() const;
ColorPicker *get_picker();
PopupPanel *get_popup();
ColorSelectorButton();
};
#endif // COLOR_PICKER_H #endif // COLOR_PICKER_H

View File

@ -133,8 +133,8 @@
#include "scene/main/resource_preloader.h" #include "scene/main/resource_preloader.h"
#include "scene/main/scene_tree.h" #include "scene/main/scene_tree.h"
#include "scene/main/timer.h" #include "scene/main/timer.h"
#include "scene/main/world.h"
#include "scene/main/viewport.h" #include "scene/main/viewport.h"
#include "scene/main/world.h"
#include "scene/resources/audio_stream_sample.h" #include "scene/resources/audio_stream_sample.h"
#include "scene/resources/bit_map.h" #include "scene/resources/bit_map.h"
#include "scene/resources/box_shape.h" #include "scene/resources/box_shape.h"
@ -155,6 +155,7 @@
#include "scene/resources/material.h" #include "scene/resources/material.h"
#include "scene/resources/mesh.h" #include "scene/resources/mesh.h"
#include "scene/resources/mesh_data_tool.h" #include "scene/resources/mesh_data_tool.h"
#include "scene/resources/multimesh.h"
#include "scene/resources/navigation_mesh.h" #include "scene/resources/navigation_mesh.h"
#include "scene/resources/packed_scene.h" #include "scene/resources/packed_scene.h"
#include "scene/resources/particles_material.h" #include "scene/resources/particles_material.h"
@ -166,7 +167,6 @@
#include "scene/resources/rectangle_shape_2d.h" #include "scene/resources/rectangle_shape_2d.h"
#include "scene/resources/resource_format_text.h" #include "scene/resources/resource_format_text.h"
#include "scene/resources/segment_shape_2d.h" #include "scene/resources/segment_shape_2d.h"
#include "scene/resources/multimesh.h"
#include "scene/resources/sky.h" #include "scene/resources/sky.h"
#include "scene/resources/sphere_shape.h" #include "scene/resources/sphere_shape.h"
@ -174,11 +174,10 @@
#include "scene/resources/text_file.h" #include "scene/resources/text_file.h"
#include "scene/resources/texture.h" #include "scene/resources/texture.h"
#include "scene/resources/video_stream.h" #include "scene/resources/video_stream.h"
#include "scene/resources/world_3d.h"
#include "scene/resources/world_2d.h" #include "scene/resources/world_2d.h"
#include "scene/resources/world_3d.h"
#include "scene/scene_string_names.h" #include "scene/scene_string_names.h"
#ifndef _3D_DISABLED #ifndef _3D_DISABLED
#include "scene/3d/area.h" #include "scene/3d/area.h"
#include "scene/3d/audio_stream_player_3d.h" #include "scene/3d/audio_stream_player_3d.h"
@ -362,6 +361,7 @@ void register_scene_types() {
ClassDB::register_class<SpinBox>(); ClassDB::register_class<SpinBox>();
ClassDB::register_class<ColorPicker>(); ClassDB::register_class<ColorPicker>();
ClassDB::register_class<ColorPickerButton>(); ClassDB::register_class<ColorPickerButton>();
ClassDB::register_class<ColorSelectorButton>();
ClassDB::register_class<RichTextLabel>(); ClassDB::register_class<RichTextLabel>();
ClassDB::register_class<RichTextEffect>(); ClassDB::register_class<RichTextEffect>();
ClassDB::register_class<CharFXTransform>(); ClassDB::register_class<CharFXTransform>();