Skip to content

Commit ecbc032

Browse files
Quaker762awesomekling
authored andcommitted
Applications: Create a display properties manager
An interactive application to modify the current display settings, such as the current wallpaper as well as the screen resolution. Currently we're adding the resolutions ourselves, because there's currently no way to detect was resolutions the current display adapter supports (or at least I can't see one... Maybe VBE does and I'm stupid). It even comes with a very nice template'd `ItemList` that can support a vector of any type, which makes life much simpler.
1 parent af14b8d commit ecbc032

File tree

15 files changed

+329
-1
lines changed

15 files changed

+329
-1
lines changed
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
#include <AK/StringBuilder.h>
2+
#include <LibCore/CDirIterator.h>
3+
#include <LibGUI/GAction.h>
4+
#include <LibGUI/GApplication.h>
5+
#include <LibGUI/GBoxLayout.h>
6+
#include <LibGUI/GButton.h>
7+
#include <LibGUI/GDesktop.h>
8+
#include <LibGUI/GEventLoop.h>
9+
#include <LibGUI/GFileSystemModel.h>
10+
#include <LibGUI/GGroupBox.h>
11+
#include <LibGUI/GListView.h>
12+
#include <LibGUI/GScrollBar.h>
13+
#include <LibGUI/GSplitter.h>
14+
#include <LibGUI/GTabWidget.h>
15+
#include <LibGUI/GToolBar.h>
16+
#include <LibGUI/GWidget.h>
17+
#include <LibGUI/GWindow.h>
18+
19+
#include <Servers/WindowServer/WSWindowManager.h>
20+
21+
#include "DisplayProperties.h"
22+
#include "ItemListModel.h"
23+
24+
DisplayPropertiesWidget::DisplayPropertiesWidget()
25+
: m_wm_config(CConfigFile::get_for_app("WindowManager"))
26+
{
27+
create_root_widget();
28+
create_frame();
29+
create_resolution_list();
30+
create_wallpaper_list();
31+
}
32+
33+
void DisplayPropertiesWidget::create_resolution_list()
34+
{
35+
// TODO: Find a better way to get the default resolution
36+
m_resolutions.append({ 640, 480 });
37+
m_resolutions.append({ 800, 600 });
38+
m_resolutions.append({ 1024, 768 });
39+
m_resolutions.append({ 1280, 1024 });
40+
m_resolutions.append({ 1366, 768 });
41+
m_resolutions.append({ 1440, 900 });
42+
m_resolutions.append({ 1600, 900 });
43+
m_resolutions.append({ 1920, 1080 });
44+
m_resolutions.append({ 2560, 1080 });
45+
46+
m_selected_resolution = m_resolutions.at(0);
47+
}
48+
49+
void DisplayPropertiesWidget::create_root_widget()
50+
{
51+
m_root_widget = new GWidget;
52+
m_root_widget->set_layout(make<GBoxLayout>(Orientation::Vertical));
53+
m_root_widget->set_fill_with_background_color(true);
54+
m_root_widget->layout()->set_margins({ 4, 4, 4, 16 });
55+
}
56+
57+
void DisplayPropertiesWidget::create_wallpaper_list()
58+
{
59+
CDirIterator iterator("/res/wallpapers/", CDirIterator::Flags::SkipDots);
60+
61+
while (iterator.has_next())
62+
m_wallpapers.append(iterator.next_path());
63+
}
64+
65+
void DisplayPropertiesWidget::create_frame()
66+
{
67+
auto* tab_widget = new GTabWidget(m_root_widget);
68+
69+
// First, let's create the "Background" tab
70+
auto* background_splitter = new GSplitter(Orientation::Vertical, nullptr);
71+
tab_widget->add_widget("Wallpaper", background_splitter);
72+
73+
auto* background_content = new GWidget(background_splitter);
74+
background_content->set_layout(make<GBoxLayout>(Orientation::Vertical));
75+
background_content->layout()->add_spacer();
76+
background_content->layout()->set_margins({ 4, 4, 4, 4 });
77+
78+
auto* wallpaper_list = new GListView(background_content);
79+
wallpaper_list->set_background_color(Color::White);
80+
wallpaper_list->set_model(*ItemListModel<AK::String>::create(m_wallpapers));
81+
wallpaper_list->horizontal_scrollbar().set_visible(false);
82+
wallpaper_list->on_selection = [this](auto& index) {
83+
m_selected_wallpaper = m_wallpapers.at(index.row());
84+
};
85+
86+
// Let's add the settings tab
87+
auto* settings_splitter = new GSplitter(Orientation::Vertical, nullptr);
88+
tab_widget->add_widget("Settings", settings_splitter);
89+
90+
auto* settings_content = new GWidget(settings_splitter);
91+
settings_content->set_layout(make<GBoxLayout>(Orientation::Vertical));
92+
settings_content->layout()->add_spacer();
93+
settings_content->layout()->set_margins({ 4, 4, 4, 4 });
94+
95+
auto* resolution_list = new GListView(settings_content);
96+
resolution_list->set_background_color(Color::White);
97+
resolution_list->set_model(*ItemListModel<Size>::create(m_resolutions));
98+
resolution_list->horizontal_scrollbar().set_visible(false);
99+
resolution_list->on_selection = [this](auto& index) {
100+
m_selected_resolution = m_resolutions.at(index.row());
101+
};
102+
103+
// Add the apply and cancel buttons
104+
auto* bottom_widget = new GWidget(m_root_widget);
105+
bottom_widget->set_layout(make<GBoxLayout>(Orientation::Horizontal));
106+
bottom_widget->layout()->add_spacer();
107+
bottom_widget->set_size_policy(Orientation::Vertical, SizePolicy::Fixed);
108+
bottom_widget->set_preferred_size(1, 22);
109+
110+
auto* apply_button = new GButton(bottom_widget);
111+
apply_button->set_text("Apply");
112+
apply_button->set_size_policy(Orientation::Vertical, SizePolicy::Fixed);
113+
apply_button->set_size_policy(Orientation::Horizontal, SizePolicy::Fixed);
114+
apply_button->set_preferred_size(60, 22);
115+
apply_button->on_click = [this, tab_widget](GButton&) {
116+
send_settings_to_window_server(tab_widget->get_active_tab());
117+
};
118+
119+
auto* ok_button = new GButton(bottom_widget);
120+
ok_button->set_text("OK");
121+
ok_button->set_size_policy(Orientation::Vertical, SizePolicy::Fixed);
122+
ok_button->set_size_policy(Orientation::Horizontal, SizePolicy::Fixed);
123+
ok_button->set_preferred_size(60, 22);
124+
ok_button->on_click = [this, tab_widget](GButton&) {
125+
send_settings_to_window_server(tab_widget->get_active_tab());
126+
GApplication::the().quit();
127+
};
128+
129+
auto* cancel_button = new GButton(bottom_widget);
130+
cancel_button->set_text("Cancel");
131+
cancel_button->set_size_policy(Orientation::Vertical, SizePolicy::Fixed);
132+
cancel_button->set_size_policy(Orientation::Horizontal, SizePolicy::Fixed);
133+
cancel_button->set_preferred_size(60, 22);
134+
cancel_button->on_click = [this](GButton&) {
135+
GApplication::the().quit();
136+
};
137+
}
138+
139+
void DisplayPropertiesWidget::send_settings_to_window_server(int tab_index)
140+
{
141+
if (tab_index == TabIndices::Wallpaper) {
142+
StringBuilder builder;
143+
builder.append("/res/wallpapers/");
144+
builder.append(m_selected_wallpaper);
145+
GDesktop::the().set_wallpaper(builder.to_string());
146+
} else if (tab_index == TabIndices::Settings) {
147+
WSAPI_ClientMessage request;
148+
request.type = WSAPI_ClientMessage::Type::SetResolution;
149+
dbg() << "Attempting to set resolution " << m_selected_resolution;
150+
request.wm_conf.resolution = { m_selected_resolution.width(), m_selected_resolution.height() };
151+
auto response = GWindowServerConnection::the().sync_request(request, WSAPI_ServerMessage::Type::DidSetResolution);
152+
ASSERT(response.value == 1);
153+
} else {
154+
dbg() << "Invalid tab index " << tab_index;
155+
}
156+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#pragma once
2+
3+
#include <AK/AKString.h>
4+
#include <AK/RefPtr.h>
5+
#include <AK/Vector.h>
6+
#include <LibCore/CConfigFile.h>
7+
#include <LibDraw/Color.h>
8+
#include <LibDraw/Size.h>
9+
#include <LibGUI/GWidget.h>
10+
11+
class DisplayPropertiesWidget final {
12+
public:
13+
enum class ButtonOperations {
14+
Ok,
15+
Apply,
16+
Cancel,
17+
};
18+
19+
enum TabIndices {
20+
Wallpaper,
21+
Settings
22+
};
23+
24+
public:
25+
DisplayPropertiesWidget();
26+
27+
// Apply the settings to the Window Server
28+
void send_settings_to_window_server(int tabIndex);
29+
void create_frame();
30+
31+
inline GWidget* get_root_widget() const { return m_root_widget; }
32+
33+
private:
34+
void create_wallpaper_list();
35+
void create_resolution_list();
36+
void create_root_widget();
37+
38+
private:
39+
String m_wallpaper_path;
40+
RefPtr<CConfigFile> m_wm_config;
41+
GWidget* m_root_widget { nullptr };
42+
Vector<Size> m_resolutions;
43+
Vector<String> m_wallpapers;
44+
45+
Size m_selected_resolution;
46+
String m_selected_wallpaper;
47+
};
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#pragma once
2+
3+
#include <AK/NonnullRefPtr.h>
4+
#include <AK/Vector.h>
5+
#include <LibGUI/GModel.h>
6+
7+
template<typename T>
8+
class ItemListModel final : public GModel {
9+
public:
10+
static NonnullRefPtr<ItemListModel> create(Vector<T>& data) { return adopt(*new ItemListModel<T>(data)); }
11+
12+
virtual ~ItemListModel() override {}
13+
14+
virtual int row_count(const GModelIndex&) const override
15+
{
16+
return m_data.size();
17+
}
18+
19+
virtual int column_count(const GModelIndex&) const override
20+
{
21+
return 1;
22+
}
23+
24+
virtual String column_name(int) const override
25+
{
26+
return "Data";
27+
}
28+
29+
virtual ColumnMetadata column_metadata(int) const override
30+
{
31+
return { 70, TextAlignment::CenterLeft };
32+
}
33+
34+
virtual GVariant data(const GModelIndex& index, Role role = Role::Display) const override
35+
{
36+
if (role == Role::Display)
37+
return m_data.at(index.row());
38+
39+
return {};
40+
}
41+
42+
virtual void update() override
43+
{
44+
did_update();
45+
}
46+
47+
private:
48+
explicit ItemListModel(Vector<T>& data)
49+
: m_data(data)
50+
{
51+
}
52+
53+
Vector<T>& m_data;
54+
};
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
include ../../Makefile.common
2+
3+
OBJS = \
4+
DisplayProperties.o \
5+
main.o \
6+
7+
APP = DisplayProperties
8+
9+
include ../Makefile.common
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#include "DisplayProperties.h"
2+
#include <LibDraw/PNGLoader.h>
3+
#include <LibGUI/GApplication.h>
4+
#include <LibGUI/GBoxLayout.h>
5+
#include <LibGUI/GWidget.h>
6+
#include <LibGUI/GWindow.h>
7+
8+
int main(int argc, char** argv)
9+
{
10+
GApplication app(argc, argv);
11+
DisplayPropertiesWidget instance;
12+
13+
auto* window = new GWindow();
14+
window->set_title("Display Properties");
15+
window->resize(400, 448);
16+
window->set_resizable(false);
17+
window->set_main_widget(instance.get_root_widget());
18+
window->set_icon(load_png("/res/icons/16x16/app-display-properties.png"));
19+
20+
window->show();
21+
return app.exec();
22+
}
1.58 KB
Loading
2.74 KB
Loading

Kernel/build-root-filesystem.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ cp ../Applications/SystemDialog/SystemDialog mnt/bin/SystemDialog
8686
cp ../Applications/ChanViewer/ChanViewer mnt/bin/ChanViewer
8787
cp ../Applications/Calculator/Calculator mnt/bin/Calculator
8888
cp ../Applications/SoundPlayer/SoundPlayer mnt/bin/SoundPlayer
89+
cp ../Applications/DisplayProperties/DisplayProperties mnt/bin/DisplayProperties
8990
cp ../Demos/HelloWorld/HelloWorld mnt/bin/HelloWorld
9091
cp ../Demos/HelloWorld2/HelloWorld2 mnt/bin/HelloWorld2
9192
cp ../Demos/RetroFetch/RetroFetch mnt/bin/RetroFetch

Kernel/makeall.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ build_targets="$build_targets ../Libraries/LibVT"
4242
build_targets="$build_targets ../Applications/About"
4343
build_targets="$build_targets ../Applications/Calculator"
4444
build_targets="$build_targets ../Applications/ChanViewer"
45+
build_targets="$build_targets ../Applications/DisplayProperties"
4546
build_targets="$build_targets ../Applications/Downloader"
4647
build_targets="$build_targets ../Applications/FileManager"
4748
build_targets="$build_targets ../Applications/FontEditor"

Libraries/LibGUI/GTabWidget.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1+
#include <LibDraw/StylePainter.h>
12
#include <LibGUI/GBoxLayout.h>
23
#include <LibGUI/GPainter.h>
34
#include <LibGUI/GTabWidget.h>
4-
#include <LibDraw/StylePainter.h>
55

66
GTabWidget::GTabWidget(GWidget* parent)
77
: GWidget(parent)

0 commit comments

Comments
 (0)