mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-01-08 12:19:37 +03:00
MouseSettings: Add a tab to change cursor theme
This commit is contained in:
parent
3597b6eb9d
commit
42df4fb2df
Notes:
sideshowbarker
2024-07-18 05:21:31 +09:00
Author: https://github.com/sppmacd Commit: https://github.com/SerenityOS/serenity/commit/42df4fb2df2 Pull-request: https://github.com/SerenityOS/serenity/pull/9157 Reviewed-by: https://github.com/sin-ack
@ -4,14 +4,19 @@ serenity_component(
|
||||
TARGETS MouseSettings
|
||||
)
|
||||
|
||||
compile_gml(MouseSettingsWindow.gml MouseSettingsWindowGML.h mouse_settings_window_gml)
|
||||
compile_gml(Mouse.gml MouseWidgetGML.h mouse_widget_gml)
|
||||
compile_gml(Theme.gml ThemeWidgetGML.h theme_widget_gml)
|
||||
|
||||
set(SOURCES
|
||||
main.cpp
|
||||
DoubleClickArrowWidget.cpp
|
||||
MouseSettingsWindow.cpp
|
||||
MouseSettingsWindow.h
|
||||
MouseSettingsWindowGML.h
|
||||
MouseWidget.cpp
|
||||
MouseWidget.h
|
||||
MouseWidgetGML.h
|
||||
ThemeWidget.cpp
|
||||
ThemeWidget.h
|
||||
ThemeWidgetGML.h
|
||||
)
|
||||
|
||||
serenity_app(MouseSettings ICON app-mouse)
|
||||
|
@ -7,37 +7,13 @@
|
||||
*/
|
||||
|
||||
#include "MouseSettingsWindow.h"
|
||||
#include "DoubleClickArrowWidget.h"
|
||||
#include <Applications/MouseSettings/MouseSettingsWindowGML.h>
|
||||
#include "MouseWidget.h"
|
||||
#include "ThemeWidget.h"
|
||||
#include <LibGUI/Application.h>
|
||||
#include <LibGUI/BoxLayout.h>
|
||||
#include <LibGUI/Button.h>
|
||||
#include <LibGUI/Label.h>
|
||||
#include <LibGUI/TabWidget.h>
|
||||
#include <LibGUI/Widget.h>
|
||||
#include <LibGUI/WindowServerConnection.h>
|
||||
#include <WindowServer/Screen.h>
|
||||
#include <WindowServer/WindowManager.h>
|
||||
|
||||
constexpr double speed_slider_scale = 100.0;
|
||||
constexpr int default_scroll_length = 4;
|
||||
constexpr int double_click_speed_default = 250;
|
||||
|
||||
void MouseSettingsWindow::update_window_server()
|
||||
{
|
||||
const float factor = m_speed_slider->value() / speed_slider_scale;
|
||||
GUI::WindowServerConnection::the().async_set_mouse_acceleration(factor);
|
||||
GUI::WindowServerConnection::the().async_set_scroll_step_size(m_scroll_length_spinbox->value());
|
||||
GUI::WindowServerConnection::the().async_set_double_click_speed(m_double_click_speed_slider->value());
|
||||
}
|
||||
|
||||
void MouseSettingsWindow::reset_default_values()
|
||||
{
|
||||
m_speed_slider->set_value(speed_slider_scale);
|
||||
m_scroll_length_spinbox->set_value(default_scroll_length);
|
||||
m_double_click_speed_slider->set_value(double_click_speed_default);
|
||||
update_window_server();
|
||||
}
|
||||
|
||||
MouseSettingsWindow::MouseSettingsWindow()
|
||||
{
|
||||
@ -48,38 +24,9 @@ MouseSettingsWindow::MouseSettingsWindow()
|
||||
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 = [&](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::try_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::try_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 = [&](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());
|
||||
auto& mouse_widget = tab_widget.add_tab<MouseWidget>("Mouse");
|
||||
auto& theme_widget = tab_widget.add_tab<ThemeWidget>("Cursor Theme");
|
||||
|
||||
auto& button_container = main_widget.add<GUI::Widget>();
|
||||
button_container.set_shrink_to_fit(true);
|
||||
@ -87,8 +34,9 @@ MouseSettingsWindow::MouseSettingsWindow()
|
||||
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();
|
||||
m_reset_button->on_click = [&](auto) {
|
||||
mouse_widget.reset_default_values();
|
||||
theme_widget.reset_default_values();
|
||||
};
|
||||
|
||||
button_container.layout()->add_spacer();
|
||||
@ -96,7 +44,8 @@ MouseSettingsWindow::MouseSettingsWindow()
|
||||
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();
|
||||
mouse_widget.update_window_server();
|
||||
theme_widget.update_window_server();
|
||||
GUI::Application::the()->quit();
|
||||
};
|
||||
|
||||
@ -109,7 +58,8 @@ MouseSettingsWindow::MouseSettingsWindow()
|
||||
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();
|
||||
mouse_widget.update_window_server();
|
||||
theme_widget.update_window_server();
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -7,10 +7,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "DoubleClickArrowWidget.h"
|
||||
#include <LibGUI/Button.h>
|
||||
#include <LibGUI/Slider.h>
|
||||
#include <LibGUI/SpinBox.h>
|
||||
#include <LibGUI/Window.h>
|
||||
|
||||
class MouseSettingsWindow final : public GUI::Window {
|
||||
@ -21,17 +18,8 @@ public:
|
||||
private:
|
||||
MouseSettingsWindow();
|
||||
|
||||
void update_window_server();
|
||||
void reset_default_values();
|
||||
|
||||
RefPtr<GUI::HorizontalSlider> m_speed_slider;
|
||||
RefPtr<GUI::Label> m_speed_label;
|
||||
RefPtr<GUI::SpinBox> m_scroll_length_spinbox;
|
||||
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;
|
||||
};
|
||||
|
74
Userland/Applications/MouseSettings/MouseWidget.cpp
Normal file
74
Userland/Applications/MouseSettings/MouseWidget.cpp
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 2021, the SerenityOS developers.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include "MouseWidget.h"
|
||||
|
||||
#include <Applications/MouseSettings/MouseWidgetGML.h>
|
||||
#include <LibGUI/Label.h>
|
||||
#include <LibGUI/Slider.h>
|
||||
#include <LibGUI/SpinBox.h>
|
||||
#include <LibGUI/WindowServerConnection.h>
|
||||
#include <WindowServer/Screen.h>
|
||||
#include <WindowServer/WindowManager.h>
|
||||
|
||||
constexpr double speed_slider_scale = 100.0;
|
||||
constexpr int default_scroll_length = 4;
|
||||
constexpr int double_click_speed_default = 250;
|
||||
|
||||
MouseWidget::MouseWidget()
|
||||
{
|
||||
load_from_gml(mouse_widget_gml);
|
||||
|
||||
m_speed_label = *find_descendant_of_type_named<GUI::Label>("speed_label");
|
||||
m_speed_slider = *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 = [&](int value) {
|
||||
m_speed_label->set_text(String::formatted("{} %", value));
|
||||
};
|
||||
int const slider_value = float { speed_slider_scale } * GUI::WindowServerConnection::the().get_mouse_acceleration();
|
||||
m_speed_slider->set_value(slider_value);
|
||||
|
||||
auto& cursor_speed_image_label = *find_descendant_of_type_named<GUI::Label>("cursor_speed_image_label");
|
||||
cursor_speed_image_label.set_icon(Gfx::Bitmap::try_load_from_file("/res/graphics/mouse-cursor-speed.png"));
|
||||
|
||||
auto& scroll_step_size_image_label = *find_descendant_of_type_named<GUI::Label>("scroll_step_size_image_label");
|
||||
scroll_step_size_image_label.set_icon(Gfx::Bitmap::try_load_from_file("/res/graphics/scroll-wheel-step-size.png"));
|
||||
|
||||
m_scroll_length_spinbox = *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 = *find_descendant_of_type_named<MouseSettings::DoubleClickArrowWidget>("double_click_arrow_widget");
|
||||
m_double_click_speed_label = *find_descendant_of_type_named<GUI::Label>("double_click_speed_label");
|
||||
m_double_click_speed_slider = *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 = [&](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());
|
||||
}
|
||||
|
||||
void MouseWidget::update_window_server()
|
||||
{
|
||||
float const factor = m_speed_slider->value() / speed_slider_scale;
|
||||
GUI::WindowServerConnection::the().async_set_mouse_acceleration(factor);
|
||||
GUI::WindowServerConnection::the().async_set_scroll_step_size(m_scroll_length_spinbox->value());
|
||||
GUI::WindowServerConnection::the().async_set_double_click_speed(m_double_click_speed_slider->value());
|
||||
}
|
||||
|
||||
void MouseWidget::reset_default_values()
|
||||
{
|
||||
m_speed_slider->set_value(speed_slider_scale);
|
||||
m_scroll_length_spinbox->set_value(default_scroll_length);
|
||||
m_double_click_speed_slider->set_value(double_click_speed_default);
|
||||
update_window_server();
|
||||
}
|
||||
|
||||
MouseWidget::~MouseWidget()
|
||||
{
|
||||
}
|
30
Userland/Applications/MouseSettings/MouseWidget.h
Normal file
30
Userland/Applications/MouseSettings/MouseWidget.h
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2021, the SerenityOS developers.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibGUI/Window.h>
|
||||
|
||||
#include "DoubleClickArrowWidget.h"
|
||||
|
||||
class MouseWidget final : public GUI::Widget {
|
||||
C_OBJECT(MouseWidget)
|
||||
public:
|
||||
virtual ~MouseWidget() override;
|
||||
|
||||
void update_window_server();
|
||||
void reset_default_values();
|
||||
|
||||
private:
|
||||
MouseWidget();
|
||||
|
||||
RefPtr<GUI::HorizontalSlider> m_speed_slider;
|
||||
RefPtr<GUI::Label> m_speed_label;
|
||||
RefPtr<GUI::SpinBox> m_scroll_length_spinbox;
|
||||
RefPtr<GUI::HorizontalSlider> m_double_click_speed_slider;
|
||||
RefPtr<GUI::Label> m_double_click_speed_label;
|
||||
RefPtr<MouseSettings::DoubleClickArrowWidget> m_double_click_arrow_widget;
|
||||
};
|
39
Userland/Applications/MouseSettings/Theme.gml
Normal file
39
Userland/Applications/MouseSettings/Theme.gml
Normal file
@ -0,0 +1,39 @@
|
||||
@GUI::Frame {
|
||||
fill_with_background_color: true
|
||||
|
||||
layout: @GUI::VerticalBoxLayout {
|
||||
margins: [10, 10, 10, 10]
|
||||
}
|
||||
|
||||
@GUI::GroupBox {
|
||||
title: "Theme"
|
||||
|
||||
layout: @GUI::VerticalBoxLayout {
|
||||
margins: [16, 2, 16, 16]
|
||||
}
|
||||
|
||||
@GUI::Widget {
|
||||
fixed_height: 50
|
||||
|
||||
layout: @GUI::HorizontalBoxLayout {
|
||||
spacing: 10
|
||||
margins: [8, 16, 0, 8]
|
||||
}
|
||||
|
||||
@GUI::Label {
|
||||
text: "Select Theme: "
|
||||
text_alignment: "CenterRight"
|
||||
}
|
||||
|
||||
@GUI::ComboBox {
|
||||
name: "theme_name_box"
|
||||
model_only: true
|
||||
}
|
||||
}
|
||||
|
||||
@GUI::TableView {
|
||||
name: "cursors_tableview"
|
||||
font_size: 12
|
||||
}
|
||||
}
|
||||
}
|
144
Userland/Applications/MouseSettings/ThemeWidget.cpp
Normal file
144
Userland/Applications/MouseSettings/ThemeWidget.cpp
Normal file
@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright (c) 2021, the SerenityOS developers.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include "ThemeWidget.h"
|
||||
|
||||
#include <Applications/MouseSettings/ThemeWidgetGML.h>
|
||||
#include <LibCore/DirIterator.h>
|
||||
#include <LibGUI/Button.h>
|
||||
#include <LibGUI/ComboBox.h>
|
||||
#include <LibGUI/SortingProxyModel.h>
|
||||
#include <LibGUI/TableView.h>
|
||||
#include <LibGUI/WindowServerConnection.h>
|
||||
|
||||
String MouseCursorModel::column_name(int column_index) const
|
||||
{
|
||||
switch (column_index) {
|
||||
case Column::Bitmap:
|
||||
return {};
|
||||
case Column::Name:
|
||||
return "Name";
|
||||
}
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
GUI::Variant MouseCursorModel::data(GUI::ModelIndex const& index, GUI::ModelRole role) const
|
||||
{
|
||||
auto& cursor = m_cursors[index.row()];
|
||||
|
||||
if (role == GUI::ModelRole::Display) {
|
||||
switch (index.column()) {
|
||||
case Column::Bitmap:
|
||||
if (!cursor.bitmap)
|
||||
return {};
|
||||
return *cursor.bitmap;
|
||||
case Column::Name:
|
||||
return cursor.name;
|
||||
}
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
void MouseCursorModel::invalidate()
|
||||
{
|
||||
if (m_theme_name.is_empty())
|
||||
return;
|
||||
|
||||
m_cursors.clear();
|
||||
Core::DirIterator iterator(String::formatted("/res/cursor-themes/{}", m_theme_name), Core::DirIterator::Flags::SkipDots);
|
||||
|
||||
while (iterator.has_next()) {
|
||||
auto path = iterator.next_full_path();
|
||||
if (path.ends_with(".ini"))
|
||||
continue;
|
||||
if (path.contains("2x"))
|
||||
continue;
|
||||
|
||||
Cursor cursor;
|
||||
cursor.path = move(path);
|
||||
auto filename_split = cursor.path.split('/');
|
||||
cursor.name = filename_split[3];
|
||||
|
||||
// FIXME: Animated cursor bitmaps
|
||||
auto cursor_bitmap = Gfx::Bitmap::try_load_from_file(cursor.path);
|
||||
auto cursor_bitmap_rect = cursor_bitmap->rect();
|
||||
cursor.params = Gfx::CursorParams::parse_from_filename(cursor.name, cursor_bitmap_rect.center()).constrained(*cursor_bitmap);
|
||||
cursor.bitmap = cursor_bitmap->cropped(Gfx::IntRect(Gfx::FloatRect(cursor_bitmap_rect).scaled(1.0 / cursor.params.frames(), 1.0)));
|
||||
|
||||
m_cursors.append(move(cursor));
|
||||
}
|
||||
Model::invalidate();
|
||||
}
|
||||
|
||||
GUI::Variant ThemeModel::data(GUI::ModelIndex const& index, GUI::ModelRole role) const
|
||||
{
|
||||
if (role == GUI::ModelRole::Display) {
|
||||
return m_themes[index.row()];
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
void ThemeModel::invalidate()
|
||||
{
|
||||
m_themes.clear();
|
||||
|
||||
Core::DirIterator iterator("/res/cursor-themes", Core::DirIterator::Flags::SkipDots);
|
||||
|
||||
while (iterator.has_next()) {
|
||||
auto path = iterator.next_path();
|
||||
if (access(String::formatted("/res/cursor-themes/{}/Config.ini", path).characters(), R_OK) == 0)
|
||||
m_themes.append(path);
|
||||
}
|
||||
Model::invalidate();
|
||||
}
|
||||
|
||||
ThemeWidget::ThemeWidget()
|
||||
{
|
||||
load_from_gml(theme_widget_gml);
|
||||
m_cursors_tableview = find_descendant_of_type_named<GUI::TableView>("cursors_tableview");
|
||||
m_cursors_tableview->set_highlight_selected_rows(true);
|
||||
m_cursors_tableview->set_alternating_row_colors(false);
|
||||
m_cursors_tableview->set_vertical_padding(16);
|
||||
m_cursors_tableview->set_column_headers_visible(false);
|
||||
m_cursors_tableview->set_highlight_key_column(false);
|
||||
|
||||
auto mouse_cursor_model = MouseCursorModel::create();
|
||||
auto sorting_proxy_model = GUI::SortingProxyModel::create(mouse_cursor_model);
|
||||
sorting_proxy_model->set_sort_role(GUI::ModelRole::Display);
|
||||
|
||||
m_cursors_tableview->set_model(sorting_proxy_model);
|
||||
m_cursors_tableview->set_key_column_and_sort_order(MouseCursorModel::Column::Name, GUI::SortOrder::Ascending);
|
||||
m_cursors_tableview->set_column_width(0, 25);
|
||||
m_cursors_tableview->model()->invalidate();
|
||||
|
||||
m_theme_name = GUI::WindowServerConnection::the().get_cursor_theme();
|
||||
mouse_cursor_model->change_theme(m_theme_name);
|
||||
|
||||
m_theme_name_box = find_descendant_of_type_named<GUI::ComboBox>("theme_name_box");
|
||||
m_theme_name_box->on_change = [this, mouse_cursor_model](String const& value, GUI::ModelIndex const&) mutable {
|
||||
m_theme_name = value;
|
||||
mouse_cursor_model->change_theme(m_theme_name);
|
||||
};
|
||||
m_theme_name_box->set_model(ThemeModel::create());
|
||||
m_theme_name_box->model()->invalidate();
|
||||
m_theme_name_box->set_text(m_theme_name);
|
||||
}
|
||||
|
||||
void ThemeWidget::update_window_server()
|
||||
{
|
||||
GUI::WindowServerConnection::the().async_apply_cursor_theme(m_theme_name_box->text());
|
||||
}
|
||||
|
||||
void ThemeWidget::reset_default_values()
|
||||
{
|
||||
m_theme_name_box->set_text("Default");
|
||||
update_window_server();
|
||||
}
|
||||
|
||||
ThemeWidget::~ThemeWidget()
|
||||
{
|
||||
}
|
82
Userland/Applications/MouseSettings/ThemeWidget.h
Normal file
82
Userland/Applications/MouseSettings/ThemeWidget.h
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2021, the SerenityOS developers.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibGUI/Model.h>
|
||||
#include <LibGUI/Window.h>
|
||||
#include <LibGUI/WindowServerConnection.h>
|
||||
#include <LibGfx/CursorParams.h>
|
||||
|
||||
#include "DoubleClickArrowWidget.h"
|
||||
#include "LibGUI/FilePicker.h"
|
||||
|
||||
class MouseCursorModel final : public GUI::Model {
|
||||
public:
|
||||
static NonnullRefPtr<MouseCursorModel> create() { return adopt_ref(*new MouseCursorModel); }
|
||||
virtual ~MouseCursorModel() override { }
|
||||
|
||||
enum Column {
|
||||
Bitmap,
|
||||
Name,
|
||||
__Count,
|
||||
};
|
||||
|
||||
virtual int row_count(const GUI::ModelIndex&) const override { return m_cursors.size(); }
|
||||
virtual int column_count(const GUI::ModelIndex&) const override { return Column::__Count; }
|
||||
|
||||
virtual String column_name(int column_index) const override;
|
||||
virtual GUI::Variant data(const GUI::ModelIndex& index, GUI::ModelRole role) const override;
|
||||
virtual void invalidate() override;
|
||||
|
||||
void change_theme(String const& name)
|
||||
{
|
||||
m_theme_name = name;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
private:
|
||||
MouseCursorModel() { }
|
||||
|
||||
struct Cursor {
|
||||
RefPtr<Gfx::Bitmap> bitmap;
|
||||
String path;
|
||||
String name;
|
||||
Gfx::CursorParams params;
|
||||
};
|
||||
|
||||
Vector<Cursor> m_cursors;
|
||||
String m_theme_name;
|
||||
};
|
||||
|
||||
class ThemeModel final : public GUI::Model {
|
||||
public:
|
||||
static NonnullRefPtr<ThemeModel> create() { return adopt_ref(*new ThemeModel); }
|
||||
virtual int row_count(const GUI::ModelIndex&) const override { return m_themes.size(); }
|
||||
virtual int column_count(const GUI::ModelIndex&) const override { return 1; }
|
||||
|
||||
virtual GUI::Variant data(const GUI::ModelIndex& index, GUI::ModelRole role) const override;
|
||||
virtual void invalidate() override;
|
||||
|
||||
private:
|
||||
Vector<String> m_themes;
|
||||
};
|
||||
|
||||
class ThemeWidget final : public GUI::Widget {
|
||||
C_OBJECT(ThemeWidget)
|
||||
public:
|
||||
virtual ~ThemeWidget() override;
|
||||
|
||||
void update_window_server();
|
||||
void reset_default_values();
|
||||
|
||||
private:
|
||||
ThemeWidget();
|
||||
|
||||
RefPtr<GUI::TableView> m_cursors_tableview;
|
||||
RefPtr<GUI::ComboBox> m_theme_name_box;
|
||||
String m_theme_name;
|
||||
};
|
Loading…
Reference in New Issue
Block a user