1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 04:57:45 +00:00

MouseSettings: Add tab to configure cursor highlighting

This adds a nice little tab, including a preview, for configuring
the cursor highlighting. Which allows setting the color, size/radius,
and opacity.
This commit is contained in:
MacDue 2022-06-04 20:41:13 +01:00 committed by Linus Groh
parent 5fc13e1d53
commit b558d899ea
7 changed files with 295 additions and 1 deletions

View file

@ -6,10 +6,14 @@ serenity_component(
compile_gml(Mouse.gml MouseWidgetGML.h mouse_widget_gml)
compile_gml(Theme.gml ThemeWidgetGML.h theme_widget_gml)
compile_gml(Highlight.gml HighlightWidgetGML.h highlight_widget_gml)
set(SOURCES
main.cpp
DoubleClickArrowWidget.cpp
HighlightPreviewWidget.cpp
HighlightWidget.cpp
HighlightWidgetGML.h
MouseWidget.cpp
MouseWidget.h
MouseWidgetGML.h

View file

@ -0,0 +1,99 @@
@GUI::Frame {
fill_with_background_color: true
layout: @GUI::VerticalBoxLayout {
margins: [10]
}
@GUI::Frame {
layout: @GUI::HorizontalBoxLayout {}
name: "preview_frame"
fixed_width: 136
fixed_height: 136
}
@GUI::GroupBox {
title: "Highlight color"
fixed_height: 80
layout: @GUI::VerticalBoxLayout {
margins: [6]
spacing: 2
}
@GUI::Widget {}
@GUI::ColorInput {
name: "highlight_color_input"
has_alpha_channel: false
}
@GUI::Widget {}
}
@GUI::GroupBox {
title: "Highlight opacity"
fixed_height: 80
layout: @GUI::VerticalBoxLayout {
margins: [6]
spacing: 2
}
@GUI::Widget {
layout: @GUI::HorizontalBoxLayout {
margins: [8]
spacing: 8
}
@GUI::Label {
autosize: true
text: "0%"
}
@GUI::Slider {
name: "highlight_opacity_slider"
orientation: "Horizontal"
max: 230
min: 0
value: 80
}
@GUI::Label {
autosize: true
text: "100%"
}
}
}
@GUI::GroupBox {
title: "Highlight size"
fixed_height: 80
layout: @GUI::VerticalBoxLayout {
margins: [6]
spacing: 2
}
@GUI::Widget {
layout: @GUI::HorizontalBoxLayout {
margins: [8]
spacing: 8
}
@GUI::Label {
autosize: true
text: "Off"
}
@GUI::Slider {
name: "highlight_radius_slider"
orientation: "Horizontal"
max: 60
min: 19
value: 30
}
@GUI::Label {
autosize: true
text: "Largest"
}
}
}
}

View file

@ -0,0 +1,34 @@
/*
* Copyright (c) 2022, MacDue <macdue@dueutil.tech>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include "HighlightPreviewWidget.h"
#include <AK/String.h>
#include <LibGUI/ConnectionToWindowServer.h>
#include <LibGUI/Painter.h>
#include <LibGfx/AntiAliasingPainter.h>
namespace MouseSettings {
HighlightPreviewWidget::HighlightPreviewWidget(Gfx::Palette const& palette)
: GUI::AbstractThemePreview(palette)
{
auto cursor_theme = GUI::ConnectionToWindowServer::the().get_cursor_theme();
m_cursor_bitmap = Gfx::Bitmap::try_load_from_file(String::formatted("/res/cursor-themes/{}/arrow.x2y2.png", cursor_theme)).release_value_but_fixme_should_propagate_errors();
}
void HighlightPreviewWidget::paint_preview(GUI::PaintEvent&)
{
GUI::Painter painter(*this);
if (m_radius > 0 && m_color.alpha() > 0) {
Gfx::AntiAliasingPainter aa_painter { painter };
Gfx::IntRect highlight_rect { 0, 0, m_radius * 2, m_radius * 2 };
highlight_rect.center_within(frame_inner_rect());
aa_painter.fill_ellipse(highlight_rect, m_color);
}
painter.blit(m_cursor_bitmap->rect().centered_within(frame_inner_rect()).location(), *m_cursor_bitmap, m_cursor_bitmap->rect());
}
}

View file

@ -0,0 +1,42 @@
/*
* Copyright (c) 2022, MacDue <macdue@dueutil.tech>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <LibGUI/AbstractThemePreview.h>
#include <LibGfx/Color.h>
namespace MouseSettings {
class HighlightPreviewWidget final : public GUI::AbstractThemePreview {
C_OBJECT(HighlightPreviewWidget)
public:
virtual ~HighlightPreviewWidget() override = default;
virtual void paint_preview(GUI::PaintEvent&) override;
void set_radius(int radius)
{
m_radius = radius;
update();
}
void set_color(Gfx::Color const& color)
{
m_color = color;
update();
}
private:
explicit HighlightPreviewWidget(Gfx::Palette const& palette);
RefPtr<Gfx::Bitmap> m_cursor_bitmap;
int m_radius { 0 };
Gfx::Color m_color;
};
}

View file

@ -0,0 +1,78 @@
/*
* Copyright (c) 2022, MacDue <macdue@dueutil.tech>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include "HighlightWidget.h"
#include <Applications/MouseSettings/HighlightWidgetGML.h>
#include <LibGUI/ConnectionToWindowServer.h>
HighlightWidget::HighlightWidget()
{
load_from_gml(highlight_widget_gml);
m_highlight_preview = find_descendant_of_type_named<GUI::Frame>("preview_frame")->add<MouseSettings::HighlightPreviewWidget>(palette());
auto current_highlight_color = GUI::ConnectionToWindowServer::the().get_cursor_highlight_color();
auto current_highlight_color_no_alpha = current_highlight_color;
current_highlight_color_no_alpha.set_alpha(255);
m_highlight_color_input = *find_descendant_of_type_named<GUI::ColorInput>("highlight_color_input");
m_highlight_color_input->set_color(current_highlight_color_no_alpha);
m_highlight_color_input->on_change = [&]() {
m_highlight_preview->set_color(highlight_color());
set_modified(true);
};
m_highlight_opacity_slider = *find_descendant_of_type_named<GUI::Slider>("highlight_opacity_slider");
m_highlight_opacity_slider->set_value(current_highlight_color.alpha());
m_highlight_opacity_slider->on_change = [&](int) {
m_highlight_preview->set_color(highlight_color());
set_modified(true);
};
m_highlight_radius_slider = *find_descendant_of_type_named<GUI::Slider>("highlight_radius_slider");
m_highlight_radius_slider->set_value(GUI::ConnectionToWindowServer::the().get_cursor_highlight_radius());
m_highlight_radius_slider->on_change = [&](int) {
m_highlight_preview->set_radius(highlight_radius());
set_modified(true);
};
m_highlight_preview->set_color(highlight_color());
m_highlight_preview->set_radius(highlight_radius());
}
Gfx::Color HighlightWidget::highlight_color()
{
auto color = m_highlight_color_input->color();
color.set_alpha(m_highlight_opacity_slider->value());
return color;
}
int HighlightWidget::highlight_radius()
{
auto current_value = m_highlight_radius_slider->value();
if (current_value <= m_highlight_radius_slider->min())
return 0;
return current_value;
}
void HighlightWidget::apply_settings()
{
GUI::ConnectionToWindowServer::the().async_set_cursor_highlight_radius(highlight_radius());
GUI::ConnectionToWindowServer::the().async_set_cursor_highlight_color(highlight_color());
}
void HighlightWidget::reset_default_values()
{
constexpr auto default_highlight_color = Gfx::Color::NamedColor::Yellow;
constexpr auto default_highlight_opacity = 80; // (in range of 0-255)
// Disable the highlighting by default.
// The range of radii you can configure the highlight to is 20 to 60px,
// anything less than that is treated as 'no highlighting'.
constexpr auto default_highlight_radius_length = 19;
m_highlight_color_input->set_color(default_highlight_color);
m_highlight_opacity_slider->set_value(default_highlight_opacity);
m_highlight_radius_slider->set_value(default_highlight_radius_length);
}

View file

@ -0,0 +1,33 @@
/*
* Copyright (c) 2022, MacDue <macdue@dueutil.tech>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include "HighlightPreviewWidget.h"
#include <LibGUI/ColorInput.h>
#include <LibGUI/SettingsWindow.h>
#include <LibGUI/Slider.h>
#include <LibGUI/Window.h>
class HighlightWidget final : public GUI::SettingsWindow::Tab {
C_OBJECT(HighlightWidget)
public:
virtual ~HighlightWidget() override = default;
virtual void apply_settings() override;
virtual void reset_default_values() override;
private:
Gfx::Color highlight_color();
int highlight_radius();
HighlightWidget();
RefPtr<MouseSettings::HighlightPreviewWidget> m_highlight_preview;
RefPtr<GUI::ColorInput> m_highlight_color_input;
RefPtr<GUI::Slider> m_highlight_opacity_slider;
RefPtr<GUI::Slider> m_highlight_radius_slider;
};

View file

@ -3,10 +3,12 @@
* Copyright (c) 2021, the SerenityOS developers.
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2021-2022, Sam Atkins <atkinssj@serenityos.org>
* Copyright (c) 2022, MacDue <macdue@dueutil.tech>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include "HighlightWidget.h"
#include "MouseWidget.h"
#include "ThemeWidget.h"
#include <LibCore/ArgsParser.h>
@ -26,7 +28,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
StringView selected_tab;
Core::ArgsParser args_parser;
args_parser.add_option(selected_tab, "Tab, one of 'cursor-theme' or 'mouse'", "open-tab", 't', "tab");
args_parser.add_option(selected_tab, "Tab, one of 'cursor-theme', 'cursor-highlight', or 'mouse'", "open-tab", 't', "tab");
args_parser.parse(arguments);
auto app_icon = GUI::Icon::default_icon("app-mouse");
@ -34,6 +36,8 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
auto window = TRY(GUI::SettingsWindow::create("Mouse Settings", GUI::SettingsWindow::ShowDefaultsButton::Yes));
(void)TRY(window->add_tab<MouseWidget>("Mouse", "mouse"));
(void)TRY(window->add_tab<ThemeWidget>("Cursor Theme", "cursor-theme"));
(void)TRY(window->add_tab<HighlightWidget>("Cursor Highlight", "cursor-highlight"));
window->set_icon(app_icon.bitmap_for_size(16));
window->set_active_tab(selected_tab);