diff --git a/Userland/Libraries/LibGUI/ColorPicker.cpp b/Userland/Libraries/LibGUI/ColorPicker.cpp index 50be4baaa7..d4e3a0d1ce 100644 --- a/Userland/Libraries/LibGUI/ColorPicker.cpp +++ b/Userland/Libraries/LibGUI/ColorPicker.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include namespace GUI { @@ -125,6 +126,60 @@ private: RefPtr m_color_slider; }; +class ColorSelectOverlay final : public Widget { + C_OBJECT(ColorSelectOverlay) +public: + ColorSelectOverlay() + { + set_override_cursor(Gfx::StandardCursor::Eyedropper); + } + + Optional exec() + { + m_event_loop = make(); + + // FIXME: Allow creation of fully transparent windows without a backing store. + auto window = Window::construct(); + window->set_main_widget(this); + window->set_has_alpha_channel(true); + window->set_background_color(Color::Transparent); + window->set_fullscreen(true); + window->set_frameless(true); + window->show(); + + if (!m_event_loop->exec()) + return {}; + return m_col; + } + + virtual ~ColorSelectOverlay() override { } + Function on_color_changed; + +private: + virtual void mousedown_event(GUI::MouseEvent&) { m_event_loop->quit(1); } + virtual void mousemove_event(GUI::MouseEvent&) + { + auto new_col = WindowServerConnection::the().get_color_under_cursor(); + if (new_col == m_col) + return; + m_col = new_col; + if (on_color_changed) + on_color_changed(m_col); + } + + virtual void keydown_event(GUI::KeyEvent& event) + { + if (event.key() == KeyCode::Key_Escape) { + event.accept(); + m_event_loop->quit(0); + return; + } + } + + OwnPtr m_event_loop; + Color m_col; +}; + ColorPicker::ColorPicker(Color color, Window* parent_window, String title) : Dialog(parent_window) , m_color(color) @@ -247,7 +302,7 @@ void ColorPicker::build_ui_custom(Widget& root_container) preview_container.set_layout(); preview_container.layout()->set_margins(2); preview_container.layout()->set_spacing(0); - preview_container.set_fixed_height(128); + preview_container.set_fixed_height(100); // Current color preview_container.add(m_color); @@ -340,6 +395,24 @@ void ColorPicker::build_ui_custom(Widget& root_container) make_spinbox(Green, m_color.green()); make_spinbox(Blue, m_color.blue()); make_spinbox(Alpha, m_color.alpha()); + + m_selector_button = vertical_container.add("Select on screen"); + m_selector_button->on_click = [this](auto) { + auto selector = ColorSelectOverlay::construct(); + auto original_color = m_color; + // This allows us to use the color preview widget as a live-preview for + // the color currently under the cursor, which is helpful. + selector->on_color_changed = [this](auto color) { + m_color = color; + update_color_widgets(); + }; + + // Set the final color + auto maybe_color = selector->exec(); + m_color = maybe_color.value_or(original_color); + m_custom_color->set_color(m_color); + update_color_widgets(); + }; } void ColorPicker::update_color_widgets() diff --git a/Userland/Libraries/LibGUI/ColorPicker.h b/Userland/Libraries/LibGUI/ColorPicker.h index e2627a094b..fb9ed0eee3 100644 --- a/Userland/Libraries/LibGUI/ColorPicker.h +++ b/Userland/Libraries/LibGUI/ColorPicker.h @@ -14,6 +14,7 @@ namespace GUI { class ColorButton; class ColorPreview; class CustomColorWidget; +class ColorSelectOverlay; class ColorPicker final : public Dialog { C_OBJECT(ColorPicker) @@ -40,6 +41,7 @@ private: Vector m_color_widgets; RefPtr m_custom_color; RefPtr m_preview_widget; + RefPtr