From 81e65600090726704610968fcdfa4a2ec099285c Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Tue, 20 Jul 2021 21:35:00 +0200 Subject: [PATCH] MouseSettings: Give this application a GUI facelift :^) Note that the double-click "icon" adapts to the double-click speed and also reacts to double-clicks. :^) --- Base/res/graphics/double-click-down-arrow.png | Bin 0 -> 151 bytes Base/res/graphics/mouse-cursor-speed.png | Bin 0 -> 275 bytes Base/res/graphics/scroll-wheel-step-size.png | Bin 0 -> 373 bytes .../Applications/MouseSettings/CMakeLists.txt | 1 + .../MouseSettings/DoubleClickArrowWidget.cpp | 63 ++++++ .../MouseSettings/DoubleClickArrowWidget.h | 30 +++ .../MouseSettings/MouseSettingsWindow.cpp | 58 ++++-- .../MouseSettings/MouseSettingsWindow.gml | 182 +++++++++++------- .../MouseSettings/MouseSettingsWindow.h | 3 + Userland/Applications/MouseSettings/main.cpp | 16 +- 10 files changed, 257 insertions(+), 96 deletions(-) create mode 100644 Base/res/graphics/double-click-down-arrow.png create mode 100644 Base/res/graphics/mouse-cursor-speed.png create mode 100644 Base/res/graphics/scroll-wheel-step-size.png create mode 100644 Userland/Applications/MouseSettings/DoubleClickArrowWidget.cpp create mode 100644 Userland/Applications/MouseSettings/DoubleClickArrowWidget.h diff --git a/Base/res/graphics/double-click-down-arrow.png b/Base/res/graphics/double-click-down-arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..115a6bcbb11beeb23d0cd3938d41c6e12f7841de GIT binary patch literal 151 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s7;yhg(Lo7}ooqUjsL4m{B z^w! zOj0`b#yFqQN^@N_A+{z*Npn)#>Kp~1Ila98^~uaU_Y{QVlo#A)U|?YIboFyt=akR{ E01R_9>Hq)$ literal 0 HcmV?d00001 diff --git a/Base/res/graphics/mouse-cursor-speed.png b/Base/res/graphics/mouse-cursor-speed.png new file mode 100644 index 0000000000000000000000000000000000000000..9704e79d0d96f6ce70b3a94a107e6abdba8d1809 GIT binary patch literal 275 zcmeAS@N?(olHy`uVBq!ia0y~yU{C;I4mJh`hT^KKFANL}w>(`OLn02p4RhpcQQ*mu z{@1$xQ_Q+OTyfWIGdXtYc?fP!6ylpU$!|s`Yr-Slgfz*(>28w^ULN11bKuOOGc#JQ z`)&Q}$Rs#Xpvk6EcnbTPt-pPF6hD}7e$G7{wcES+Atwt%;8%yfd-E2=bMAe*VA7I# zDn6M>3)R2aUbrnBQtc4Ux2xD=vdc#Hq@MPO$NLY53*O)goBetn%Q;I27n_@hCNKT0 zaC1WT>@tVLFLXaQ6!Qi7YWHlrH6u&dGGEqFfcH9y85}Sb4q9e0MJQw5&!@I literal 0 HcmV?d00001 diff --git a/Base/res/graphics/scroll-wheel-step-size.png b/Base/res/graphics/scroll-wheel-step-size.png new file mode 100644 index 0000000000000000000000000000000000000000..6f879283ad323c3630d5692cd21e42d6ad2d0845 GIT binary patch literal 373 zcmeAS@N?(olHy`uVBq!ia0y~yU{C;I4mJh`hT^KKFANNfHl8kyArXh)h6NTKRp4mx zdB4!yvv1nsLJx(16ebkJ_&O4LbL3noQV(30!|(ZV>%*KFh&n z7GtQ;)`Pk`u1~nb#qoJ!2jjlSZFa1ucB~3qTXC%IFIPv+WR8x9dJcR3ZGAqO>4{_L zE*6~?)AmHOR(VAP9qo!WSK7Kj?8fA_>9;Rx-b>}Zq8+iG%`JD=@&j-6I<$_g)a&>W gxL347`va%OswfSm74n-I7#J8lUHx3vIVCg!0E$GWuK)l5 literal 0 HcmV?d00001 diff --git a/Userland/Applications/MouseSettings/CMakeLists.txt b/Userland/Applications/MouseSettings/CMakeLists.txt index 398946ae38..dff69c96c1 100644 --- a/Userland/Applications/MouseSettings/CMakeLists.txt +++ b/Userland/Applications/MouseSettings/CMakeLists.txt @@ -8,6 +8,7 @@ compile_gml(MouseSettingsWindow.gml MouseSettingsWindowGML.h mouse_settings_wind set(SOURCES main.cpp + DoubleClickArrowWidget.cpp MouseSettingsWindow.cpp MouseSettingsWindow.h MouseSettingsWindowGML.h diff --git a/Userland/Applications/MouseSettings/DoubleClickArrowWidget.cpp b/Userland/Applications/MouseSettings/DoubleClickArrowWidget.cpp new file mode 100644 index 0000000000..f18f2dbee1 --- /dev/null +++ b/Userland/Applications/MouseSettings/DoubleClickArrowWidget.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2021, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include "DoubleClickArrowWidget.h" +#include +#include + +REGISTER_WIDGET(MouseSettings, DoubleClickArrowWidget); + +namespace MouseSettings { + +DoubleClickArrowWidget::~DoubleClickArrowWidget() +{ +} + +void DoubleClickArrowWidget::set_double_click_speed(int speed) +{ + if (m_double_click_speed == speed) + return; + m_double_click_speed = speed; + update(); +} + +DoubleClickArrowWidget::DoubleClickArrowWidget() +{ + m_arrow_bitmap = Gfx::Bitmap::load_from_file("/res/graphics/double-click-down-arrow.png"); +} + +void DoubleClickArrowWidget::paint_event(GUI::PaintEvent& event) +{ + GUI::Painter painter(*this); + painter.add_clip_rect(event.rect()); + + auto bottom_arrow_rect = m_arrow_bitmap->rect(); + bottom_arrow_rect.center_within(rect()); + bottom_arrow_rect.translate_by(0, m_arrow_bitmap->height() / 2); + + painter.blit_filtered(bottom_arrow_rect.location(), *m_arrow_bitmap, m_arrow_bitmap->rect(), [&](Color color) { + return m_inverted ? color.inverted() : color; + }); + + auto top_arrow_rect = bottom_arrow_rect; + top_arrow_rect.translate_by(0, -(m_double_click_speed / 50)); + + painter.blit_filtered(top_arrow_rect.location(), *m_arrow_bitmap, m_arrow_bitmap->rect(), [&](Color color) { + return m_inverted ? color.inverted() : color; + }); + + auto text_rect = rect(); + text_rect.set_y(bottom_arrow_rect.bottom()); + text_rect.set_height(font().glyph_height()); +} + +void DoubleClickArrowWidget::doubleclick_event(GUI::MouseEvent&) +{ + m_inverted = !m_inverted; + update(); +} + +} diff --git a/Userland/Applications/MouseSettings/DoubleClickArrowWidget.h b/Userland/Applications/MouseSettings/DoubleClickArrowWidget.h new file mode 100644 index 0000000000..ac8eeaaa58 --- /dev/null +++ b/Userland/Applications/MouseSettings/DoubleClickArrowWidget.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include + +namespace MouseSettings { + +class DoubleClickArrowWidget final : public GUI::Widget { + C_OBJECT(DoubleClickArrowWidget); + +public: + virtual ~DoubleClickArrowWidget() override; + void set_double_click_speed(int); + +private: + DoubleClickArrowWidget(); + virtual void paint_event(GUI::PaintEvent&) override; + virtual void doubleclick_event(GUI::MouseEvent&) override; + + RefPtr m_arrow_bitmap; + int m_double_click_speed { 0 }; + bool m_inverted { false }; +}; + +} diff --git a/Userland/Applications/MouseSettings/MouseSettingsWindow.cpp b/Userland/Applications/MouseSettings/MouseSettingsWindow.cpp index 3c6f923fa1..63ffe80762 100644 --- a/Userland/Applications/MouseSettings/MouseSettingsWindow.cpp +++ b/Userland/Applications/MouseSettings/MouseSettingsWindow.cpp @@ -1,16 +1,20 @@ /* * Copyright (c) 2020, Idan Horowitz * Copyright (c) 2021, the SerenityOS developers. + * Copyright (c) 2021, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ #include "MouseSettingsWindow.h" +#include "DoubleClickArrowWidget.h" #include #include +#include #include #include #include +#include #include #include #include @@ -40,44 +44,74 @@ void MouseSettingsWindow::reset_default_values() MouseSettingsWindow::MouseSettingsWindow() { auto& main_widget = set_main_widget(); - main_widget.load_from_gml(mouse_settings_window_gml); + main_widget.set_fill_with_background_color(true); + main_widget.set_layout(); + main_widget.layout()->set_margins({ 4, 4, 4, 4 }); + main_widget.layout()->set_spacing(6); + + auto& tab_widget = main_widget.add(); + auto& mouse_widget = tab_widget.add_tab("Mouse"); + mouse_widget.load_from_gml(mouse_settings_window_gml); m_speed_label = *main_widget.find_descendant_of_type_named("speed_label"); m_speed_slider = *main_widget.find_descendant_of_type_named("speed_slider"); m_speed_slider->set_range(WindowServer::mouse_accel_min * speed_slider_scale, WindowServer::mouse_accel_max * speed_slider_scale); - m_speed_slider->on_change = [&](const int value) { + m_speed_slider->on_change = [&](int value) { m_speed_label->set_text(String::formatted("{} %", value)); }; const int slider_value = float { speed_slider_scale } * GUI::WindowServerConnection::the().get_mouse_acceleration(); m_speed_slider->set_value(slider_value); + auto& cursor_speed_image_label = *main_widget.find_descendant_of_type_named("cursor_speed_image_label"); + cursor_speed_image_label.set_icon(Gfx::Bitmap::load_from_file("/res/graphics/mouse-cursor-speed.png")); + + auto& scroll_step_size_image_label = *main_widget.find_descendant_of_type_named("scroll_step_size_image_label"); + scroll_step_size_image_label.set_icon(Gfx::Bitmap::load_from_file("/res/graphics/scroll-wheel-step-size.png")); + m_scroll_length_spinbox = *main_widget.find_descendant_of_type_named("scroll_length_spinbox"); m_scroll_length_spinbox->set_min(WindowServer::scroll_step_size_min); m_scroll_length_spinbox->set_value(GUI::WindowServerConnection::the().get_scroll_step_size()); + m_double_click_arrow_widget = *main_widget.find_descendant_of_type_named("double_click_arrow_widget"); m_double_click_speed_label = *main_widget.find_descendant_of_type_named("double_click_speed_label"); m_double_click_speed_slider = *main_widget.find_descendant_of_type_named("double_click_speed_slider"); m_double_click_speed_slider->set_min(WindowServer::double_click_speed_min); m_double_click_speed_slider->set_max(WindowServer::double_click_speed_max); - m_double_click_speed_slider->on_change = [&](const int value) { - m_double_click_speed_label->set_text(String::formatted("{} ms", value)); + m_double_click_speed_slider->on_change = [&](int speed) { + m_double_click_arrow_widget->set_double_click_speed(speed); + m_double_click_speed_label->set_text(String::formatted("{} ms", speed)); }; m_double_click_speed_slider->set_value(GUI::WindowServerConnection::the().get_double_click_speed()); - m_ok_button = *main_widget.find_descendant_of_type_named("ok_button"); - m_ok_button->on_click = [this](auto) { + auto& button_container = main_widget.add(); + button_container.set_shrink_to_fit(true); + button_container.set_layout(); + button_container.layout()->set_spacing(6); + + m_reset_button = button_container.add("Defaults"); + m_reset_button->on_click = [this](auto) { + reset_default_values(); + }; + + button_container.layout()->add_spacer(); + + m_ok_button = button_container.add("OK"); + m_ok_button->set_fixed_width(75); + m_ok_button->on_click = [&](auto) { update_window_server(); GUI::Application::the()->quit(); }; - m_apply_button = *main_widget.find_descendant_of_type_named("apply_button"); - m_apply_button->on_click = [this](auto) { - update_window_server(); + m_cancel_button = button_container.add("Cancel"); + m_cancel_button->set_fixed_width(75); + m_cancel_button->on_click = [&](auto) { + GUI::Application::the()->quit(); }; - m_reset_button = *main_widget.find_descendant_of_type_named("reset_button"); - m_reset_button->on_click = [this](auto) { - reset_default_values(); + m_apply_button = button_container.add("Apply"); + m_apply_button->set_fixed_width(75); + m_apply_button->on_click = [&](auto) { + update_window_server(); }; } diff --git a/Userland/Applications/MouseSettings/MouseSettingsWindow.gml b/Userland/Applications/MouseSettings/MouseSettingsWindow.gml index 96c6ec6e9c..2ac829a11f 100644 --- a/Userland/Applications/MouseSettings/MouseSettingsWindow.gml +++ b/Userland/Applications/MouseSettings/MouseSettingsWindow.gml @@ -1,105 +1,147 @@ -@GUI::Widget { +@GUI::Frame { fill_with_background_color: true - layout: @GUI::VerticalBoxLayout { - margins: [4, 4, 4, 4] + margins: [10, 10, 10, 10] + spacing: 5 } @GUI::GroupBox { - title: "Mouse speed" - fixed_height: 60 + title: "Cursor speed" + fixed_height: 110 - layout: @GUI::HorizontalBoxLayout { - margins: [6, 16, 8, 6] + layout: @GUI::VerticalBoxLayout { + margins: [8, 16, 8, 8] } - @GUI::HorizontalSlider { - name: "speed_slider" - max: 3500 - min: 500 - value: 100 + @GUI::Widget { + layout: @GUI::HorizontalBoxLayout { + margins: [8, 8, 8, 8] + spacing: 16 + } + + @GUI::Label { + fixed_width: 32 + fixed_height: 32 + name: "cursor_speed_image_label" + } + + @GUI::Label { + text: "The relative speed of the mouse cursor." + text_alignment: "CenterLeft" + } } - @GUI::Label { - name: "speed_label" - text: "100.0 %" - fixed_width: 50 - text_alignment: "CenterRight" + @GUI::Widget { + layout: @GUI::HorizontalBoxLayout { + } + + @GUI::HorizontalSlider { + name: "speed_slider" + min: 0 + max: 100 + value: 50 + } + + @GUI::Label { + fixed_width: 40 + name: "speed_label" + } } } @GUI::GroupBox { - title: "Scroll length" - fixed_height: 60 + title: "Scroll wheel step size" + fixed_height: 110 - layout: @GUI::HorizontalBoxLayout { - margins: [16, 16, 8, 6] + layout: @GUI::VerticalBoxLayout { + margins: [8, 16, 8, 8] } - @GUI::Label { - text: "Scroll by " - autosize: true - text_alignment: "CenterLeft" + @GUI::Widget { + layout: @GUI::HorizontalBoxLayout { + margins: [8, 8, 8, 8] + spacing: 16 + } + + @GUI::Label { + fixed_width: 32 + fixed_height: 32 + name: "scroll_step_size_image_label" + } + + @GUI::Label { + text: "The number of steps taken when the scroll wheel is\nmoved a single notch." + text_alignment: "CenterLeft" + } } - @GUI::SpinBox { - name: "scroll_length_spinbox" - max: 32 - min: 1 - value: 4 - text_alignment: "CenterRight" - fixed_width: 80 - } + @GUI::Widget { + layout: @GUI::HorizontalBoxLayout { + spacing: 8 + } - @GUI::Label { - text: " lines at a time" - text_alignent: "CenterLeft" - autosize: true + @GUI::Widget { + } + + @GUI::Label { + autosize: true + text: "Step size:" + } + + @GUI::SpinBox { + name: "scroll_length_spinbox" + min: 0 + max: 100 + value: 50 + fixed_width: 100 + } + + @GUI::Widget { + } } } @GUI::GroupBox { title: "Double-click speed" - fixed_height: 60 + fixed_height: 110 - layout: @GUI::HorizontalBoxLayout { - margins: [6, 16, 8, 6] + layout: @GUI::VerticalBoxLayout { + margins: [8, 16, 8, 8] } - @GUI::HorizontalSlider { - name: "double_click_speed_slider" - max: 900 - min: 100 - value: 250 + @GUI::Widget { + layout: @GUI::HorizontalBoxLayout { + margins: [8, 8, 8, 8] + spacing: 16 + } + + @MouseSettings::DoubleClickArrowWidget { + fixed_width: 32 + fixed_height: 32 + name: "double_click_arrow_widget" + } + + @GUI::Label { + text: "The maximum time that may pass between two clicks\nin order for them to become a double-click." + text_alignment: "CenterLeft" + } } - @GUI::Label { - name: "double_click_speed_label" - text: "250 ms" - fixed_width: 50 - text_alignment: "CenterRight" - } - } + @GUI::Widget { + layout: @GUI::HorizontalBoxLayout { + } - @GUI::Widget { - fixed_height: 22 + @GUI::HorizontalSlider { + name: "double_click_speed_slider" + min: 0 + max: 100 + value: 50 + } - layout: @GUI::HorizontalBoxLayout { - } - - @GUI::Button { - name: "ok_button" - text: "OK" - } - - @GUI::Button { - name: "apply_button" - text: "Apply" - } - - @GUI::Button { - name: "reset_button" - text: "Reset" + @GUI::Label { + fixed_width: 40 + name: "double_click_speed_label" + } } } } diff --git a/Userland/Applications/MouseSettings/MouseSettingsWindow.h b/Userland/Applications/MouseSettings/MouseSettingsWindow.h index 433bdc1fa0..2159636034 100644 --- a/Userland/Applications/MouseSettings/MouseSettingsWindow.h +++ b/Userland/Applications/MouseSettings/MouseSettingsWindow.h @@ -7,6 +7,7 @@ #pragma once +#include "DoubleClickArrowWidget.h" #include #include #include @@ -29,6 +30,8 @@ private: RefPtr m_double_click_speed_slider; RefPtr m_double_click_speed_label; RefPtr m_ok_button; + RefPtr m_cancel_button; RefPtr m_apply_button; RefPtr m_reset_button; + RefPtr m_double_click_arrow_widget; }; diff --git a/Userland/Applications/MouseSettings/main.cpp b/Userland/Applications/MouseSettings/main.cpp index 9ed2b4ffd8..4ca4e05f91 100644 --- a/Userland/Applications/MouseSettings/main.cpp +++ b/Userland/Applications/MouseSettings/main.cpp @@ -1,6 +1,7 @@ /* * Copyright (c) 2020, Idan Horowitz * Copyright (c) 2021, the SerenityOS developers. + * Copyright (c) 2021, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ @@ -9,8 +10,6 @@ #include #include #include -#include -#include #include int main(int argc, char** argv) @@ -31,22 +30,11 @@ int main(int argc, char** argv) auto window = MouseSettingsWindow::construct(); window->set_title("Mouse Settings"); - window->resize(300, 220); + window->resize(400, 480); window->set_resizable(false); window->set_minimizable(false); window->set_icon(app_icon.bitmap_for_size(16)); - auto menubar = GUI::Menubar::construct(); - auto& file_menu = menubar->add_menu("&File"); - file_menu.add_action(GUI::CommonActions::make_quit_action([&](auto&) { - app->quit(); - })); - - auto& help_menu = menubar->add_menu("&Help"); - help_menu.add_action(GUI::CommonActions::make_about_action("Mouse Settings", app_icon, window)); - - window->set_menubar(move(menubar)); - window->show(); return app->exec(); }