diff --git a/Userland/Libraries/LibGUI/InputBox.cpp b/Userland/Libraries/LibGUI/InputBox.cpp index 9bcb68f2bf..445741f53c 100644 --- a/Userland/Libraries/LibGUI/InputBox.cpp +++ b/Userland/Libraries/LibGUI/InputBox.cpp @@ -11,17 +11,26 @@ #include #include #include +#include #include namespace GUI { ErrorOr> InputBox::create(Window* parent_window, String text_value, StringView prompt, StringView title, InputType input_type, RefPtr icon) { + VERIFY(input_type != InputType::Numeric); auto box = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) InputBox(parent_window, text_value, TRY(String::from_utf8(title)), TRY(String::from_utf8(prompt)), input_type, move(icon)))); TRY(box->build()); return box; } +ErrorOr> InputBox::create_numeric(Window* parent_window, int value, StringView title, StringView prompt, RefPtr icon) +{ + auto box = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) InputBox(parent_window, value, TRY(String::from_utf8(title)), TRY(String::from_utf8(prompt)), move(icon)))); + TRY(box->build()); + return box; +} + InputBox::InputBox(Window* parent_window, String text_value, String title, String prompt, InputType input_type, RefPtr icon) : Dialog(parent_window) , m_text_value(move(text_value)) @@ -34,6 +43,18 @@ InputBox::InputBox(Window* parent_window, String text_value, String title, Strin set_auto_shrink(true); } +InputBox::InputBox(Window* parent_window, int value, String title, String prompt, RefPtr icon) + : Dialog(parent_window) + , m_numeric_value(value) + , m_prompt(move(prompt)) + , m_input_type(InputType::Numeric) + , m_icon(move(icon)) +{ + set_title(move(title).to_deprecated_string()); + set_resizable(false); + set_auto_shrink(true); +} + Dialog::ExecResult InputBox::show(Window* parent_window, String& text_value, StringView prompt, StringView title, InputType input_type, StringView placeholder, RefPtr icon) { return MUST(try_show(parent_window, text_value, prompt, title, input_type, placeholder, move(icon))); @@ -41,6 +62,7 @@ Dialog::ExecResult InputBox::show(Window* parent_window, String& text_value, Str ErrorOr InputBox::try_show(Window* parent_window, String& text_value, StringView prompt, StringView title, InputType input_type, StringView placeholder, RefPtr icon) { + VERIFY(input_type != InputType::Numeric); auto box = TRY(InputBox::create(parent_window, text_value, prompt, title, input_type, move(icon))); if (parent_window) box->set_icon(parent_window->icon()); @@ -50,11 +72,27 @@ ErrorOr InputBox::try_show(Window* parent_window, String& te return result; } +ErrorOr InputBox::show_numeric(Window* parent_window, int& value, int min, int max, StringView title, StringView prompt, RefPtr icon) +{ + auto box = TRY(InputBox::create_numeric(parent_window, value, title, prompt, move(icon))); + if (parent_window) + box->set_icon(parent_window->icon()); + box->set_range(min, max); + auto result = box->exec(); + value = box->numeric_value(); + return result; +} + void InputBox::set_placeholder(StringView view) { m_text_editor->set_placeholder(view); } +void InputBox::set_range(int min, int max) +{ + m_spinbox->set_range(min, max); +} + void InputBox::set_text_value(String value) { if (m_text_value == value) @@ -63,23 +101,28 @@ void InputBox::set_text_value(String value) m_text_editor->set_text(m_text_value); } +void InputBox::set_numeric_value(int value) +{ + if (m_numeric_value == value) + return; + m_numeric_value = value; + m_spinbox->set_value(value); +} + void InputBox::on_done(ExecResult result) { if (result != ExecResult::OK) return; - if (auto value = String::from_deprecated_string(m_text_editor->text()); !value.is_error()) - m_text_value = value.release_value(); + if (m_text_editor) { + auto value = String::from_deprecated_string(m_text_editor->text()); + if (!value.is_error()) + m_text_value = value.release_value(); + } else if (m_spinbox) + m_numeric_value = m_spinbox->value(); - switch (m_input_type) { - case InputType::Text: - case InputType::Password: - break; - - case InputType::NonemptyText: + if (m_input_type == InputType::NonemptyText) VERIFY(!m_text_value.is_empty()); - break; - } } ErrorOr InputBox::build() @@ -119,6 +162,9 @@ ErrorOr InputBox::build() case InputType::Password: m_text_editor = TRY(input_container->try_add()); break; + case InputType::Numeric: + m_spinbox = TRY(input_container->try_add()); + break; } TRY(input_container->add_spacer()); @@ -128,7 +174,11 @@ ErrorOr InputBox::build() TRY(button_container->add_spacer()); m_ok_button = TRY(button_container->try_add("OK"_short_string)); - m_ok_button->on_click = [this](auto) { done(ExecResult::OK); }; + m_ok_button->on_click = [this](auto) { + if (m_spinbox) + m_spinbox->set_value_from_current_text(); + done(ExecResult::OK); + }; m_ok_button->set_default(true); m_cancel_button = TRY(button_container->try_add("Cancel"_short_string)); @@ -136,22 +186,30 @@ ErrorOr InputBox::build() auto resize_editor = [this, button_container] { auto width = button_container->effective_min_size().width().as_int(); - m_text_editor->set_min_width(width); + if (m_text_editor) + m_text_editor->set_min_width(width); + if (m_spinbox) + m_spinbox->set_min_width(width); if (!m_icon && m_label_container) m_label_container->set_fixed_width(m_prompt_label->max_width()); }; resize_editor(); on_font_change = [resize_editor] { resize_editor(); }; - m_text_editor->set_text(m_text_value); + if (m_text_editor) { + m_text_editor->set_text(m_text_value); - if (m_input_type == InputType::NonemptyText) { - m_text_editor->on_change = [this] { - m_ok_button->set_enabled(!m_text_editor->text().is_empty()); - }; - m_text_editor->on_change(); + if (m_input_type == InputType::NonemptyText) { + m_text_editor->on_change = [this] { + m_ok_button->set_enabled(!m_text_editor->text().is_empty()); + }; + m_text_editor->on_change(); + } } + if (m_spinbox) + m_spinbox->set_value(m_numeric_value); + auto size = main_widget->effective_min_size(); resize(TRY(size.width().shrink_value()), TRY(size.height().shrink_value())); diff --git a/Userland/Libraries/LibGUI/InputBox.h b/Userland/Libraries/LibGUI/InputBox.h index 8441a0faef..2776bfd538 100644 --- a/Userland/Libraries/LibGUI/InputBox.h +++ b/Userland/Libraries/LibGUI/InputBox.h @@ -15,7 +15,8 @@ namespace GUI { enum class InputType { Text, NonemptyText, - Password + Password, + Numeric }; class InputBox : public Dialog { @@ -27,17 +28,26 @@ public: static ErrorOr try_show(Window* parent_window, String& text_value, StringView prompt, StringView title, InputType input_type = InputType::Text, StringView placeholder = {}, RefPtr icon = nullptr); static ErrorOr> create(Window* parent_window, String text_value, StringView prompt, StringView title, InputType input_type, RefPtr icon = nullptr); + static ErrorOr show_numeric(Window* parent_window, int& value, int min, int max, StringView title, StringView prompt = {}, RefPtr icon = nullptr); + static ErrorOr> create_numeric(Window* parent_window, int value, StringView title, StringView prompt = {}, RefPtr icon = nullptr); + String const& text_value() const { return m_text_value; } void set_text_value(String); + int numeric_value() const { return m_numeric_value; } + void set_numeric_value(int); + void set_placeholder(StringView); + void set_range(int min, int max); private: InputBox(Window* parent_window, String text_value, String title, String prompt, InputType input_type, RefPtr icon); + InputBox(Window* parent_window, int value, String title, String prompt, RefPtr icon); virtual void on_done(ExecResult) override; ErrorOr build(); + int m_numeric_value { 0 }; String m_text_value; String m_prompt; InputType m_input_type; @@ -45,6 +55,7 @@ private: RefPtr