Serenity Operating System
at master 135 lines 4.4 kB view raw
1/* 2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> 3 * Copyright (c) 2021, networkException <networkexception@serenityos.org> 4 * Copyright (c) 2022, the SerenityOS developers. 5 * 6 * SPDX-License-Identifier: BSD-2-Clause 7 */ 8 9#include <LibGUI/BoxLayout.h> 10#include <LibGUI/Button.h> 11#include <LibGUI/InputBox.h> 12#include <LibGUI/Label.h> 13#include <LibGUI/TextBox.h> 14#include <LibGfx/Font/Font.h> 15 16namespace GUI { 17 18InputBox::InputBox(Window* parent_window, DeprecatedString text_value, StringView prompt, StringView title, InputType input_type, StringView placeholder) 19 : Dialog(parent_window) 20 , m_text_value(move(text_value)) 21 , m_prompt(prompt) 22 , m_input_type(input_type) 23 , m_placeholder(placeholder) 24{ 25 set_title(title); 26 build(); 27} 28 29Dialog::ExecResult InputBox::show(Window* parent_window, DeprecatedString& text_value, StringView prompt, StringView title, InputType input_type, StringView placeholder) 30{ 31 auto box = InputBox::construct(parent_window, text_value, prompt, title, input_type, placeholder); 32 box->set_resizable(false); 33 if (parent_window) 34 box->set_icon(parent_window->icon()); 35 auto result = box->exec(); 36 text_value = box->text_value(); 37 return result; 38} 39 40void InputBox::set_text_value(DeprecatedString text_value) 41{ 42 m_text_editor->set_text(move(text_value)); 43} 44 45void InputBox::on_done(ExecResult result) 46{ 47 if (result == ExecResult::OK) { 48 m_text_value = m_text_editor->text(); 49 50 switch (m_input_type) { 51 case InputType::Text: 52 case InputType::Password: 53 break; 54 55 case InputType::NonemptyText: 56 VERIFY(!m_text_value.is_empty()); 57 break; 58 } 59 } 60} 61 62void InputBox::build() 63{ 64 auto widget = set_main_widget<Widget>().release_value_but_fixme_should_propagate_errors(); 65 66 int text_width = widget->font().width(m_prompt); 67 int title_width = widget->font().width(title()) + 24 /* icon, plus a little padding -- not perfect */; 68 int max_width = max(text_width, title_width); 69 70 widget->set_layout<VerticalBoxLayout>(6, 6); 71 widget->set_fill_with_background_color(true); 72 widget->set_preferred_height(SpecialDimension::Fit); 73 74 auto& label_editor_container = widget->add<Widget>(); 75 label_editor_container.set_layout<HorizontalBoxLayout>(); 76 label_editor_container.set_preferred_height(SpecialDimension::Fit); 77 78 auto& label = label_editor_container.add<Label>(m_prompt); 79 label.set_preferred_width(text_width); 80 81 switch (m_input_type) { 82 case InputType::Text: 83 case InputType::NonemptyText: 84 m_text_editor = label_editor_container.add<TextBox>(); 85 break; 86 case InputType::Password: 87 m_text_editor = label_editor_container.add<PasswordBox>(); 88 break; 89 } 90 91 m_text_editor->set_text(m_text_value); 92 93 if (!m_placeholder.is_null()) 94 m_text_editor->set_placeholder(m_placeholder); 95 96 auto& button_container_outer = widget->add<Widget>(); 97 button_container_outer.set_preferred_height(SpecialDimension::Fit); 98 button_container_outer.set_layout<VerticalBoxLayout>(); 99 100 auto& button_container_inner = button_container_outer.add<Widget>(); 101 button_container_inner.set_layout<HorizontalBoxLayout>(GUI::Margins {}, 6); 102 button_container_inner.set_preferred_height(SpecialDimension::Fit); 103 button_container_inner.add_spacer().release_value_but_fixme_should_propagate_errors(); 104 105 m_ok_button = button_container_inner.add<DialogButton>(); 106 m_ok_button->set_text("OK"_short_string); 107 m_ok_button->on_click = [this](auto) { 108 dbgln("GUI::InputBox: OK button clicked"); 109 done(ExecResult::OK); 110 }; 111 m_ok_button->set_default(true); 112 113 m_cancel_button = button_container_inner.add<DialogButton>(); 114 m_cancel_button->set_text("Cancel"_short_string); 115 m_cancel_button->on_click = [this](auto) { 116 dbgln("GUI::InputBox: Cancel button clicked"); 117 done(ExecResult::Cancel); 118 }; 119 120 m_text_editor->on_escape_pressed = [this] { 121 m_cancel_button->click(); 122 }; 123 m_text_editor->set_focus(true); 124 125 if (m_input_type == InputType::NonemptyText) { 126 m_text_editor->on_change = [this] { 127 m_ok_button->set_enabled(!m_text_editor->text().is_empty()); 128 }; 129 m_text_editor->on_change(); 130 } 131 132 set_rect(x(), y(), max_width + 140, widget->effective_preferred_size().height().as_int()); 133} 134 135}