Serenity Operating System
at master 128 lines 4.3 kB view raw
1/* 2 * Copyright (c) 2020, Idan Horowitz <idan.horowitz@serenityos.org> 3 * Copyright (c) 2021-2022, the SerenityOS developers. 4 * Copyright (c) 2021, Andreas Kling <kling@serenityos.org> 5 * Copyright (c) 2021-2022, Sam Atkins <atkinssj@serenityos.org> 6 * 7 * SPDX-License-Identifier: BSD-2-Clause 8 */ 9 10#include <LibGUI/Application.h> 11#include <LibGUI/BoxLayout.h> 12#include <LibGUI/Button.h> 13#include <LibGUI/MessageBox.h> 14#include <LibGUI/SettingsWindow.h> 15#include <LibGUI/Widget.h> 16 17namespace GUI { 18 19void SettingsWindow::set_modified(bool modified) 20{ 21 Window::set_modified(modified); 22 if (m_apply_button) 23 m_apply_button->set_enabled(modified); 24} 25 26ErrorOr<NonnullRefPtr<SettingsWindow>> SettingsWindow::create(DeprecatedString title, ShowDefaultsButton show_defaults_button) 27{ 28 auto window = TRY(SettingsWindow::try_create()); 29 30 window->set_title(move(title)); 31 window->resize(400, 480); 32 window->set_resizable(false); 33 window->set_minimizable(false); 34 35 auto main_widget = TRY(window->set_main_widget<GUI::Widget>()); 36 main_widget->set_fill_with_background_color(true); 37 TRY(main_widget->try_set_layout<GUI::VerticalBoxLayout>(4, 6)); 38 39 window->m_tab_widget = TRY(main_widget->try_add<GUI::TabWidget>()); 40 41 auto button_container = TRY(main_widget->try_add<GUI::Widget>()); 42 button_container->set_preferred_size({ SpecialDimension::Grow, SpecialDimension::Fit }); 43 TRY(button_container->try_set_layout<GUI::HorizontalBoxLayout>(GUI::Margins {}, 6)); 44 45 if (show_defaults_button == ShowDefaultsButton::Yes) { 46 window->m_reset_button = TRY(button_container->try_add<GUI::DialogButton>(TRY("Defaults"_string))); 47 window->m_reset_button->on_click = [window = window->make_weak_ptr<SettingsWindow>()](auto) { 48 window->reset_default_values(); 49 }; 50 } 51 52 TRY(button_container->add_spacer()); 53 54 window->m_ok_button = TRY(button_container->try_add<GUI::DialogButton>("OK"_short_string)); 55 window->m_ok_button->on_click = [window = window->make_weak_ptr<SettingsWindow>()](auto) { 56 window->apply_settings(); 57 GUI::Application::the()->quit(); 58 }; 59 60 window->m_cancel_button = TRY(button_container->try_add<GUI::DialogButton>("Cancel"_short_string)); 61 window->m_cancel_button->on_click = [window = window->make_weak_ptr<SettingsWindow>()](auto) { 62 window->cancel_settings(); 63 GUI::Application::the()->quit(); 64 }; 65 66 window->m_apply_button = TRY(button_container->try_add<GUI::DialogButton>("Apply"_short_string)); 67 window->m_apply_button->set_enabled(false); 68 window->m_apply_button->on_click = [window = window->make_weak_ptr<SettingsWindow>()](auto) { 69 window->apply_settings(); 70 }; 71 72 window->on_close_request = [window = window->make_weak_ptr<SettingsWindow>()]() -> Window::CloseRequestDecision { 73 if (!window->is_modified()) 74 return Window::CloseRequestDecision::Close; 75 76 auto result = MessageBox::show(window, "Apply these settings before closing?"sv, "Unsaved changes"sv, MessageBox::Type::Warning, MessageBox::InputType::YesNoCancel); 77 switch (result) { 78 case MessageBox::ExecResult::Yes: 79 window->apply_settings(); 80 return Window::CloseRequestDecision::Close; 81 case MessageBox::ExecResult::No: 82 window->cancel_settings(); 83 return Window::CloseRequestDecision::Close; 84 default: 85 return Window::CloseRequestDecision::StayOpen; 86 } 87 }; 88 89 return window; 90} 91 92Optional<NonnullRefPtr<SettingsWindow::Tab>> SettingsWindow::get_tab(StringView id) const 93{ 94 auto tab = m_tabs.find(id); 95 if (tab == m_tabs.end()) 96 return {}; 97 return tab->value; 98} 99 100void SettingsWindow::set_active_tab(StringView id) 101{ 102 if (auto tab = get_tab(id); tab.has_value()) 103 m_tab_widget->set_active_widget(tab.value()); 104} 105 106void SettingsWindow::apply_settings() 107{ 108 for (auto& [id, tab] : m_tabs) 109 tab->apply_settings(); 110 set_modified(false); 111} 112 113void SettingsWindow::cancel_settings() 114{ 115 for (auto& [id, tab] : m_tabs) 116 tab->cancel_settings(); 117} 118 119void SettingsWindow::reset_default_values() 120{ 121 for (auto& [id, tab] : m_tabs) { 122 tab->reset_default_values(); 123 tab->apply_settings(); 124 } 125 set_modified(false); 126} 127 128}