BackgroundSettingsWidget.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /*
  2. * Copyright (c) 2019-2020, Jesse Buhagiar <jooster669@gmail.com>
  3. * Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org>
  4. * Copyright (c) 2022, the SerenityOS developers.
  5. *
  6. * SPDX-License-Identifier: BSD-2-Clause
  7. */
  8. #include "BackgroundSettingsWidget.h"
  9. #include <AK/StringBuilder.h>
  10. #include <Applications/DisplaySettings/BackgroundSettingsGML.h>
  11. #include <LibCore/ConfigFile.h>
  12. #include <LibDesktop/Launcher.h>
  13. #include <LibGUI/Application.h>
  14. #include <LibGUI/BoxLayout.h>
  15. #include <LibGUI/Button.h>
  16. #include <LibGUI/Clipboard.h>
  17. #include <LibGUI/ComboBox.h>
  18. #include <LibGUI/ConnectionToWindowServer.h>
  19. #include <LibGUI/Desktop.h>
  20. #include <LibGUI/FilePicker.h>
  21. #include <LibGUI/FileSystemModel.h>
  22. #include <LibGUI/IconView.h>
  23. #include <LibGUI/ItemListModel.h>
  24. #include <LibGUI/MessageBox.h>
  25. #include <LibGfx/Palette.h>
  26. #include <LibGfx/SystemTheme.h>
  27. // Including this after to avoid LibIPC errors
  28. #include <LibConfig/Client.h>
  29. namespace DisplaySettings {
  30. BackgroundSettingsWidget::BackgroundSettingsWidget(bool& background_settings_changed)
  31. : m_background_settings_changed { background_settings_changed }
  32. {
  33. m_modes.append("tile");
  34. m_modes.append("center");
  35. m_modes.append("stretch");
  36. create_frame();
  37. load_current_settings();
  38. }
  39. void BackgroundSettingsWidget::create_frame()
  40. {
  41. load_from_gml(background_settings_gml);
  42. m_monitor_widget = *find_descendant_of_type_named<DisplaySettings::MonitorWidget>("monitor_widget");
  43. m_wallpaper_view = *find_descendant_of_type_named<GUI::IconView>("wallpaper_view");
  44. m_wallpaper_view->set_model(GUI::FileSystemModel::create("/res/wallpapers"));
  45. m_wallpaper_view->set_model_column(GUI::FileSystemModel::Column::Name);
  46. m_wallpaper_view->on_selection_change = [this] {
  47. String path;
  48. if (m_wallpaper_view->selection().is_empty()) {
  49. path = "";
  50. } else {
  51. auto index = m_wallpaper_view->selection().first();
  52. path = static_cast<GUI::FileSystemModel*>(m_wallpaper_view->model())->full_path(index);
  53. }
  54. m_monitor_widget->set_wallpaper(path);
  55. };
  56. m_context_menu = GUI::Menu::construct();
  57. m_show_in_file_manager_action = GUI::Action::create("Show in File Manager", Gfx::Bitmap::try_load_from_file("/res/icons/16x16/app-file-manager.png").release_value_but_fixme_should_propagate_errors(), [this](GUI::Action const&) {
  58. LexicalPath path { m_monitor_widget->wallpaper() };
  59. Desktop::Launcher::open(URL::create_with_file_protocol(path.dirname(), path.basename()));
  60. });
  61. m_context_menu->add_action(*m_show_in_file_manager_action);
  62. m_context_menu->add_separator();
  63. m_copy_action = GUI::CommonActions::make_copy_action([this](auto&) { GUI::Clipboard::the().set_plain_text(m_monitor_widget->wallpaper()); }, this);
  64. m_context_menu->add_action(*m_copy_action);
  65. m_wallpaper_view->on_context_menu_request = [&](const GUI::ModelIndex& index, const GUI::ContextMenuEvent& event) {
  66. if (index.is_valid()) {
  67. m_context_menu->popup(event.screen_position(), m_show_in_file_manager_action);
  68. }
  69. };
  70. auto& button = *find_descendant_of_type_named<GUI::Button>("wallpaper_open_button");
  71. button.on_click = [this](auto) {
  72. auto path = GUI::FilePicker::get_open_filepath(window(), "Select wallpaper from file system", "/res/wallpapers");
  73. if (!path.has_value())
  74. return;
  75. m_wallpaper_view->selection().clear();
  76. m_monitor_widget->set_wallpaper(path.value());
  77. m_background_settings_changed = true;
  78. };
  79. m_mode_combo = *find_descendant_of_type_named<GUI::ComboBox>("mode_combo");
  80. m_mode_combo->set_only_allow_values_from_model(true);
  81. m_mode_combo->set_model(*GUI::ItemListModel<String>::create(m_modes));
  82. bool first_mode_change = true;
  83. m_mode_combo->on_change = [this, first_mode_change](auto&, const GUI::ModelIndex& index) mutable {
  84. m_monitor_widget->set_wallpaper_mode(m_modes.at(index.row()));
  85. m_background_settings_changed = !first_mode_change;
  86. first_mode_change = false;
  87. };
  88. m_color_input = *find_descendant_of_type_named<GUI::ColorInput>("color_input");
  89. m_color_input->set_color_has_alpha_channel(false);
  90. m_color_input->set_color_picker_title("Select color for desktop");
  91. bool first_color_change = true;
  92. m_color_input->on_change = [this, first_color_change]() mutable {
  93. m_monitor_widget->set_background_color(m_color_input->color());
  94. m_background_settings_changed = !first_color_change;
  95. first_color_change = false;
  96. };
  97. }
  98. void BackgroundSettingsWidget::load_current_settings()
  99. {
  100. auto ws_config = Core::ConfigFile::open("/etc/WindowServer.ini").release_value_but_fixme_should_propagate_errors();
  101. auto selected_wallpaper = Config::read_string("WindowManager", "Background", "Wallpaper", "");
  102. if (!selected_wallpaper.is_empty()) {
  103. auto index = static_cast<GUI::FileSystemModel*>(m_wallpaper_view->model())->index(selected_wallpaper, m_wallpaper_view->model_column());
  104. m_wallpaper_view->set_cursor(index, GUI::AbstractView::SelectionUpdate::Set);
  105. m_monitor_widget->set_wallpaper(selected_wallpaper);
  106. }
  107. auto mode = ws_config->read_entry("Background", "Mode", "center");
  108. if (!m_modes.contains_slow(mode)) {
  109. warnln("Invalid background mode '{}' in WindowServer config, falling back to 'center'", mode);
  110. mode = "center";
  111. }
  112. m_monitor_widget->set_wallpaper_mode(mode);
  113. m_mode_combo->set_selected_index(m_modes.find_first_index(mode).value_or(0));
  114. auto palette_desktop_color = palette().desktop_background();
  115. auto background_color = ws_config->read_entry("Background", "Color", "");
  116. if (!background_color.is_empty()) {
  117. auto opt_color = Color::from_string(background_color);
  118. if (opt_color.has_value())
  119. palette_desktop_color = opt_color.value();
  120. }
  121. m_color_input->set_color(palette_desktop_color);
  122. m_monitor_widget->set_background_color(palette_desktop_color);
  123. m_background_settings_changed = false;
  124. }
  125. void BackgroundSettingsWidget::apply_settings()
  126. {
  127. if (!GUI::Desktop::the().set_wallpaper(m_monitor_widget->wallpaper_bitmap(), m_monitor_widget->wallpaper()))
  128. GUI::MessageBox::show_error(window(), String::formatted("Unable to load file {} as wallpaper", m_monitor_widget->wallpaper()));
  129. GUI::Desktop::the().set_background_color(m_color_input->text());
  130. GUI::Desktop::the().set_wallpaper_mode(m_monitor_widget->wallpaper_mode());
  131. }
  132. }