mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 04:47:35 +00:00
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. :^)
This commit is contained in:
parent
3652ab8b2a
commit
81e6560009
10 changed files with 257 additions and 96 deletions
BIN
Base/res/graphics/double-click-down-arrow.png
Normal file
BIN
Base/res/graphics/double-click-down-arrow.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 151 B |
BIN
Base/res/graphics/mouse-cursor-speed.png
Normal file
BIN
Base/res/graphics/mouse-cursor-speed.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 275 B |
BIN
Base/res/graphics/scroll-wheel-step-size.png
Normal file
BIN
Base/res/graphics/scroll-wheel-step-size.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 373 B |
|
@ -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
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include "DoubleClickArrowWidget.h"
|
||||
#include <LibGUI/Painter.h>
|
||||
#include <LibGfx/Font.h>
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
30
Userland/Applications/MouseSettings/DoubleClickArrowWidget.h
Normal file
30
Userland/Applications/MouseSettings/DoubleClickArrowWidget.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibGUI/Widget.h>
|
||||
|
||||
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<Gfx::Bitmap> m_arrow_bitmap;
|
||||
int m_double_click_speed { 0 };
|
||||
bool m_inverted { false };
|
||||
};
|
||||
|
||||
}
|
|
@ -1,16 +1,20 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Idan Horowitz <idan.horowitz@serenityos.org>
|
||||
* Copyright (c) 2021, the SerenityOS developers.
|
||||
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include "MouseSettingsWindow.h"
|
||||
#include "DoubleClickArrowWidget.h"
|
||||
#include <Applications/MouseSettings/MouseSettingsWindowGML.h>
|
||||
#include <LibGUI/Application.h>
|
||||
#include <LibGUI/BoxLayout.h>
|
||||
#include <LibGUI/Button.h>
|
||||
#include <LibGUI/Event.h>
|
||||
#include <LibGUI/Label.h>
|
||||
#include <LibGUI/TabWidget.h>
|
||||
#include <LibGUI/Widget.h>
|
||||
#include <LibGUI/Window.h>
|
||||
#include <LibGUI/WindowServerConnection.h>
|
||||
|
@ -40,44 +44,74 @@ void MouseSettingsWindow::reset_default_values()
|
|||
MouseSettingsWindow::MouseSettingsWindow()
|
||||
{
|
||||
auto& main_widget = set_main_widget<GUI::Widget>();
|
||||
main_widget.load_from_gml(mouse_settings_window_gml);
|
||||
main_widget.set_fill_with_background_color(true);
|
||||
main_widget.set_layout<GUI::VerticalBoxLayout>();
|
||||
main_widget.layout()->set_margins({ 4, 4, 4, 4 });
|
||||
main_widget.layout()->set_spacing(6);
|
||||
|
||||
auto& tab_widget = main_widget.add<GUI::TabWidget>();
|
||||
auto& mouse_widget = tab_widget.add_tab<GUI::Widget>("Mouse");
|
||||
mouse_widget.load_from_gml(mouse_settings_window_gml);
|
||||
|
||||
m_speed_label = *main_widget.find_descendant_of_type_named<GUI::Label>("speed_label");
|
||||
m_speed_slider = *main_widget.find_descendant_of_type_named<GUI::HorizontalSlider>("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<GUI::Label>("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<GUI::Label>("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<GUI::SpinBox>("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<MouseSettings::DoubleClickArrowWidget>("double_click_arrow_widget");
|
||||
m_double_click_speed_label = *main_widget.find_descendant_of_type_named<GUI::Label>("double_click_speed_label");
|
||||
m_double_click_speed_slider = *main_widget.find_descendant_of_type_named<GUI::HorizontalSlider>("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<GUI::Button>("ok_button");
|
||||
m_ok_button->on_click = [this](auto) {
|
||||
auto& button_container = main_widget.add<GUI::Widget>();
|
||||
button_container.set_shrink_to_fit(true);
|
||||
button_container.set_layout<GUI::HorizontalBoxLayout>();
|
||||
button_container.layout()->set_spacing(6);
|
||||
|
||||
m_reset_button = button_container.add<GUI::Button>("Defaults");
|
||||
m_reset_button->on_click = [this](auto) {
|
||||
reset_default_values();
|
||||
};
|
||||
|
||||
button_container.layout()->add_spacer();
|
||||
|
||||
m_ok_button = button_container.add<GUI::Button>("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<GUI::Button>("apply_button");
|
||||
m_apply_button->on_click = [this](auto) {
|
||||
update_window_server();
|
||||
m_cancel_button = button_container.add<GUI::Button>("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<GUI::Button>("reset_button");
|
||||
m_reset_button->on_click = [this](auto) {
|
||||
reset_default_values();
|
||||
m_apply_button = button_container.add<GUI::Button>("Apply");
|
||||
m_apply_button->set_fixed_width(75);
|
||||
m_apply_button->on_click = [&](auto) {
|
||||
update_window_server();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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::VerticalBoxLayout {
|
||||
margins: [8, 16, 8, 8]
|
||||
}
|
||||
|
||||
@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::Widget {
|
||||
layout: @GUI::HorizontalBoxLayout {
|
||||
margins: [6, 16, 8, 6]
|
||||
}
|
||||
|
||||
@GUI::HorizontalSlider {
|
||||
name: "speed_slider"
|
||||
max: 3500
|
||||
min: 500
|
||||
value: 100
|
||||
min: 0
|
||||
max: 100
|
||||
value: 50
|
||||
}
|
||||
|
||||
@GUI::Label {
|
||||
fixed_width: 40
|
||||
name: "speed_label"
|
||||
text: "100.0 %"
|
||||
fixed_width: 50
|
||||
text_alignment: "CenterRight"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@GUI::GroupBox {
|
||||
title: "Scroll length"
|
||||
fixed_height: 60
|
||||
title: "Scroll wheel step size"
|
||||
fixed_height: 110
|
||||
|
||||
layout: @GUI::VerticalBoxLayout {
|
||||
margins: [8, 16, 8, 8]
|
||||
}
|
||||
|
||||
@GUI::Widget {
|
||||
layout: @GUI::HorizontalBoxLayout {
|
||||
margins: [16, 16, 8, 6]
|
||||
margins: [8, 8, 8, 8]
|
||||
spacing: 16
|
||||
}
|
||||
|
||||
@GUI::Label {
|
||||
text: "Scroll by "
|
||||
autosize: true
|
||||
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::Widget {
|
||||
layout: @GUI::HorizontalBoxLayout {
|
||||
spacing: 8
|
||||
}
|
||||
|
||||
@GUI::Widget {
|
||||
}
|
||||
|
||||
@GUI::Label {
|
||||
autosize: true
|
||||
text: "Step size:"
|
||||
}
|
||||
|
||||
@GUI::SpinBox {
|
||||
name: "scroll_length_spinbox"
|
||||
max: 32
|
||||
min: 1
|
||||
value: 4
|
||||
text_alignment: "CenterRight"
|
||||
fixed_width: 80
|
||||
min: 0
|
||||
max: 100
|
||||
value: 50
|
||||
fixed_width: 100
|
||||
}
|
||||
|
||||
@GUI::Label {
|
||||
text: " lines at a time"
|
||||
text_alignent: "CenterLeft"
|
||||
autosize: true
|
||||
@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 {
|
||||
name: "double_click_speed_label"
|
||||
text: "250 ms"
|
||||
fixed_width: 50
|
||||
text_alignment: "CenterRight"
|
||||
text: "The maximum time that may pass between two clicks\nin order for them to become a double-click."
|
||||
text_alignment: "CenterLeft"
|
||||
}
|
||||
}
|
||||
|
||||
@GUI::Widget {
|
||||
fixed_height: 22
|
||||
|
||||
layout: @GUI::HorizontalBoxLayout {
|
||||
}
|
||||
|
||||
@GUI::Button {
|
||||
name: "ok_button"
|
||||
text: "OK"
|
||||
@GUI::HorizontalSlider {
|
||||
name: "double_click_speed_slider"
|
||||
min: 0
|
||||
max: 100
|
||||
value: 50
|
||||
}
|
||||
|
||||
@GUI::Button {
|
||||
name: "apply_button"
|
||||
text: "Apply"
|
||||
@GUI::Label {
|
||||
fixed_width: 40
|
||||
name: "double_click_speed_label"
|
||||
}
|
||||
|
||||
@GUI::Button {
|
||||
name: "reset_button"
|
||||
text: "Reset"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "DoubleClickArrowWidget.h"
|
||||
#include <LibGUI/Button.h>
|
||||
#include <LibGUI/Slider.h>
|
||||
#include <LibGUI/SpinBox.h>
|
||||
|
@ -29,6 +30,8 @@ private:
|
|||
RefPtr<GUI::HorizontalSlider> m_double_click_speed_slider;
|
||||
RefPtr<GUI::Label> m_double_click_speed_label;
|
||||
RefPtr<GUI::Button> m_ok_button;
|
||||
RefPtr<GUI::Button> m_cancel_button;
|
||||
RefPtr<GUI::Button> m_apply_button;
|
||||
RefPtr<GUI::Button> m_reset_button;
|
||||
RefPtr<MouseSettings::DoubleClickArrowWidget> m_double_click_arrow_widget;
|
||||
};
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Idan Horowitz <idan.horowitz@serenityos.org>
|
||||
* Copyright (c) 2021, the SerenityOS developers.
|
||||
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -9,8 +10,6 @@
|
|||
#include <LibGUI/Action.h>
|
||||
#include <LibGUI/Application.h>
|
||||
#include <LibGUI/Icon.h>
|
||||
#include <LibGUI/Menu.h>
|
||||
#include <LibGUI/Menubar.h>
|
||||
#include <unistd.h>
|
||||
|
||||
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();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue