Files
ladybird/Applications/DisplayProperties/DisplayProperties.cpp
Jesse Buhagiar ecbc0322c1 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.
2019-09-07 16:51:15 +02:00

157 lines
6.0 KiB
C++

#include <AK/StringBuilder.h>
#include <LibCore/CDirIterator.h>
#include <LibGUI/GAction.h>
#include <LibGUI/GApplication.h>
#include <LibGUI/GBoxLayout.h>
#include <LibGUI/GButton.h>
#include <LibGUI/GDesktop.h>
#include <LibGUI/GEventLoop.h>
#include <LibGUI/GFileSystemModel.h>
#include <LibGUI/GGroupBox.h>
#include <LibGUI/GListView.h>
#include <LibGUI/GScrollBar.h>
#include <LibGUI/GSplitter.h>
#include <LibGUI/GTabWidget.h>
#include <LibGUI/GToolBar.h>
#include <LibGUI/GWidget.h>
#include <LibGUI/GWindow.h>
#include <Servers/WindowServer/WSWindowManager.h>
#include "DisplayProperties.h"
#include "ItemListModel.h"
DisplayPropertiesWidget::DisplayPropertiesWidget()
: m_wm_config(CConfigFile::get_for_app("WindowManager"))
{
create_root_widget();
create_frame();
create_resolution_list();
create_wallpaper_list();
}
void DisplayPropertiesWidget::create_resolution_list()
{
// TODO: Find a better way to get the default resolution
m_resolutions.append({ 640, 480 });
m_resolutions.append({ 800, 600 });
m_resolutions.append({ 1024, 768 });
m_resolutions.append({ 1280, 1024 });
m_resolutions.append({ 1366, 768 });
m_resolutions.append({ 1440, 900 });
m_resolutions.append({ 1600, 900 });
m_resolutions.append({ 1920, 1080 });
m_resolutions.append({ 2560, 1080 });
m_selected_resolution = m_resolutions.at(0);
}
void DisplayPropertiesWidget::create_root_widget()
{
m_root_widget = new GWidget;
m_root_widget->set_layout(make<GBoxLayout>(Orientation::Vertical));
m_root_widget->set_fill_with_background_color(true);
m_root_widget->layout()->set_margins({ 4, 4, 4, 16 });
}
void DisplayPropertiesWidget::create_wallpaper_list()
{
CDirIterator iterator("/res/wallpapers/", CDirIterator::Flags::SkipDots);
while (iterator.has_next())
m_wallpapers.append(iterator.next_path());
}
void DisplayPropertiesWidget::create_frame()
{
auto* tab_widget = new GTabWidget(m_root_widget);
// First, let's create the "Background" tab
auto* background_splitter = new GSplitter(Orientation::Vertical, nullptr);
tab_widget->add_widget("Wallpaper", background_splitter);
auto* background_content = new GWidget(background_splitter);
background_content->set_layout(make<GBoxLayout>(Orientation::Vertical));
background_content->layout()->add_spacer();
background_content->layout()->set_margins({ 4, 4, 4, 4 });
auto* wallpaper_list = new GListView(background_content);
wallpaper_list->set_background_color(Color::White);
wallpaper_list->set_model(*ItemListModel<AK::String>::create(m_wallpapers));
wallpaper_list->horizontal_scrollbar().set_visible(false);
wallpaper_list->on_selection = [this](auto& index) {
m_selected_wallpaper = m_wallpapers.at(index.row());
};
// Let's add the settings tab
auto* settings_splitter = new GSplitter(Orientation::Vertical, nullptr);
tab_widget->add_widget("Settings", settings_splitter);
auto* settings_content = new GWidget(settings_splitter);
settings_content->set_layout(make<GBoxLayout>(Orientation::Vertical));
settings_content->layout()->add_spacer();
settings_content->layout()->set_margins({ 4, 4, 4, 4 });
auto* resolution_list = new GListView(settings_content);
resolution_list->set_background_color(Color::White);
resolution_list->set_model(*ItemListModel<Size>::create(m_resolutions));
resolution_list->horizontal_scrollbar().set_visible(false);
resolution_list->on_selection = [this](auto& index) {
m_selected_resolution = m_resolutions.at(index.row());
};
// Add the apply and cancel buttons
auto* bottom_widget = new GWidget(m_root_widget);
bottom_widget->set_layout(make<GBoxLayout>(Orientation::Horizontal));
bottom_widget->layout()->add_spacer();
bottom_widget->set_size_policy(Orientation::Vertical, SizePolicy::Fixed);
bottom_widget->set_preferred_size(1, 22);
auto* apply_button = new GButton(bottom_widget);
apply_button->set_text("Apply");
apply_button->set_size_policy(Orientation::Vertical, SizePolicy::Fixed);
apply_button->set_size_policy(Orientation::Horizontal, SizePolicy::Fixed);
apply_button->set_preferred_size(60, 22);
apply_button->on_click = [this, tab_widget](GButton&) {
send_settings_to_window_server(tab_widget->get_active_tab());
};
auto* ok_button = new GButton(bottom_widget);
ok_button->set_text("OK");
ok_button->set_size_policy(Orientation::Vertical, SizePolicy::Fixed);
ok_button->set_size_policy(Orientation::Horizontal, SizePolicy::Fixed);
ok_button->set_preferred_size(60, 22);
ok_button->on_click = [this, tab_widget](GButton&) {
send_settings_to_window_server(tab_widget->get_active_tab());
GApplication::the().quit();
};
auto* cancel_button = new GButton(bottom_widget);
cancel_button->set_text("Cancel");
cancel_button->set_size_policy(Orientation::Vertical, SizePolicy::Fixed);
cancel_button->set_size_policy(Orientation::Horizontal, SizePolicy::Fixed);
cancel_button->set_preferred_size(60, 22);
cancel_button->on_click = [this](GButton&) {
GApplication::the().quit();
};
}
void DisplayPropertiesWidget::send_settings_to_window_server(int tab_index)
{
if (tab_index == TabIndices::Wallpaper) {
StringBuilder builder;
builder.append("/res/wallpapers/");
builder.append(m_selected_wallpaper);
GDesktop::the().set_wallpaper(builder.to_string());
} else if (tab_index == TabIndices::Settings) {
WSAPI_ClientMessage request;
request.type = WSAPI_ClientMessage::Type::SetResolution;
dbg() << "Attempting to set resolution " << m_selected_resolution;
request.wm_conf.resolution = { m_selected_resolution.width(), m_selected_resolution.height() };
auto response = GWindowServerConnection::the().sync_request(request, WSAPI_ServerMessage::Type::DidSetResolution);
ASSERT(response.value == 1);
} else {
dbg() << "Invalid tab index " << tab_index;
}
}