From 5f0230a57e0eca44a80e771f4063d6c894f32a28 Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Tue, 9 Jan 2024 16:24:11 +0000 Subject: [PATCH] LibGUI: Make NumericInput work well in GML - Register the widget - Register property getters and setters - Rename getters and setters to match the property names, as required by the GML compiler. The names min/max/value are chosen to match SpinBox. - Prevent a crash when the minimum is less than the maximum (which can happen while editing the GML). --- .../PDFViewer/PDFViewerWidget.cpp | 12 ++--- Userland/Libraries/LibGUI/NumericInput.cpp | 53 +++++++++++-------- Userland/Libraries/LibGUI/NumericInput.h | 16 +++--- 3 files changed, 46 insertions(+), 35 deletions(-) diff --git a/Userland/Applications/PDFViewer/PDFViewerWidget.cpp b/Userland/Applications/PDFViewer/PDFViewerWidget.cpp index 69f8043a16..2b9a95acd2 100644 --- a/Userland/Applications/PDFViewer/PDFViewerWidget.cpp +++ b/Userland/Applications/PDFViewer/PDFViewerWidget.cpp @@ -187,7 +187,7 @@ PDFViewerWidget::PDFViewerWidget() m_viewer = v_splitter.add(); m_viewer->on_page_change = [&](auto new_page) { - m_page_text_box->set_current_number(new_page + 1, GUI::AllowCallback::No); + m_page_text_box->set_value(new_page + 1, GUI::AllowCallback::No); m_go_to_prev_page_action->set_enabled(new_page > 0); m_go_to_next_page_action->set_enabled(new_page < m_viewer->document()->get_page_count() - 1); }; @@ -263,13 +263,13 @@ void PDFViewerWidget::initialize_toolbar(GUI::Toolbar& toolbar) m_go_to_prev_page_action = GUI::Action::create("Go to &Previous Page", Gfx::Bitmap::load_from_file("/res/icons/16x16/go-up.png"sv).release_value_but_fixme_should_propagate_errors(), [&](auto&) { VERIFY(m_viewer->current_page() > 0); - m_page_text_box->set_current_number(m_viewer->current_page()); + m_page_text_box->set_value(m_viewer->current_page()); }); m_go_to_prev_page_action->set_enabled(false); m_go_to_next_page_action = GUI::Action::create("Go to &Next Page", Gfx::Bitmap::load_from_file("/res/icons/16x16/go-down.png"sv).release_value_but_fixme_should_propagate_errors(), [&](auto&) { VERIFY(m_viewer->current_page() < m_viewer->document()->get_page_count() - 1); - m_page_text_box->set_current_number(m_viewer->current_page() + 2); + m_page_text_box->set_value(m_viewer->current_page() + 2); }); m_go_to_next_page_action->set_enabled(false); @@ -279,7 +279,7 @@ void PDFViewerWidget::initialize_toolbar(GUI::Toolbar& toolbar) m_page_text_box = toolbar.add(); m_page_text_box->set_enabled(false); m_page_text_box->set_fixed_width(30); - m_page_text_box->set_min_number(1); + m_page_text_box->set_min(1); m_page_text_box->on_number_changed = [&](i64 number) { auto page_count = m_viewer->document()->get_page_count(); @@ -396,8 +396,8 @@ PDF::PDFErrorOr PDFViewerWidget::try_open_file(StringView path, NonnullOwn m_total_page_label->set_text(TRY(String::formatted("of {}", document->get_page_count()))); m_page_text_box->set_enabled(true); - m_page_text_box->set_current_number(1, GUI::AllowCallback::No); - m_page_text_box->set_max_number(document->get_page_count()); + m_page_text_box->set_value(1, GUI::AllowCallback::No); + m_page_text_box->set_max(document->get_page_count()); m_go_to_prev_page_action->set_enabled(false); m_go_to_next_page_action->set_enabled(document->get_page_count() > 1); m_toggle_sidebar_action->set_enabled(true); diff --git a/Userland/Libraries/LibGUI/NumericInput.cpp b/Userland/Libraries/LibGUI/NumericInput.cpp index 518db3b02d..aaa128a093 100644 --- a/Userland/Libraries/LibGUI/NumericInput.cpp +++ b/Userland/Libraries/LibGUI/NumericInput.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2021, Matthew Olsson + * Copyright (c) 2024, Sam Atkins * * SPDX-License-Identifier: BSD-2-Clause */ @@ -7,6 +8,8 @@ #include "NumericInput.h" #include +REGISTER_WIDGET(GUI, NumericInput); + namespace GUI { NumericInput::NumericInput() @@ -16,14 +19,14 @@ NumericInput::NumericInput() on_change = [&] { auto number_opt = text().to_number(); if (number_opt.has_value()) { - set_current_number(number_opt.value(), GUI::AllowCallback::No); + set_value(number_opt.value(), GUI::AllowCallback::No); return; } StringBuilder builder; bool first = true; for (auto& ch : text()) { - if (isdigit(ch) || (first && ((ch == '-' && m_min_number < 0) || ch == '+'))) + if (isdigit(ch) || (first && ((ch == '-' && m_min < 0) || ch == '+'))) builder.append(ch); first = false; } @@ -37,57 +40,61 @@ NumericInput::NumericInput() } set_text(builder.to_byte_string()); - set_current_number(new_number_opt.value(), GUI::AllowCallback::No); + set_value(new_number_opt.value(), GUI::AllowCallback::No); }; on_up_pressed = [&] { - if (m_current_number < m_max_number) - set_current_number(m_current_number + 1); + if (m_value < m_max) + set_value(m_value + 1); }; on_down_pressed = [&] { - if (m_current_number > m_min_number) - set_current_number(m_current_number - 1); + if (m_value > m_min) + set_value(m_value - 1); }; on_focusout = [&] { on_focus_lost(); }; on_return_pressed = [&] { on_focus_lost(); }; on_escape_pressed = [&] { on_focus_lost(); }; + + REGISTER_INT_PROPERTY("min", min, set_min); + REGISTER_INT_PROPERTY("max", max, set_max); + REGISTER_INT_PROPERTY("value", value, set_value); } -void NumericInput::set_min_number(i64 number) +void NumericInput::set_min(i64 number) { - m_min_number = number; - if (m_current_number < number) - set_current_number(number); + m_min = number; + if (m_value < number) + set_value(number); } -void NumericInput::set_max_number(i64 number) +void NumericInput::set_max(i64 number) { - m_max_number = number; - if (m_current_number > number) - set_current_number(number); + m_max = number; + if (m_value > number) + set_value(number); } void NumericInput::on_focus_lost() { if (m_needs_text_reset) { - set_text(ByteString::number(m_current_number)); + set_text(ByteString::number(m_value)); m_needs_text_reset = false; } if (on_number_changed) - on_number_changed(m_current_number); + on_number_changed(m_value); } -void NumericInput::set_current_number(i64 number, GUI::AllowCallback allow_callback) +void NumericInput::set_value(i64 number, GUI::AllowCallback allow_callback) { - if (number == m_current_number) + if (number == m_value) return; - m_current_number = clamp(number, m_min_number, m_max_number); - set_text(ByteString::number(m_current_number)); + m_value = clamp(number, ::min(m_min, m_max), ::max(m_min, m_max)); + set_text(ByteString::number(m_value)); if (on_number_changed && allow_callback == GUI::AllowCallback::Yes) - on_number_changed(m_current_number); + on_number_changed(m_value); } void NumericInput::mousewheel_event(GUI::MouseEvent& event) @@ -95,7 +102,7 @@ void NumericInput::mousewheel_event(GUI::MouseEvent& event) auto wheel_delta = event.wheel_delta_y() / abs(event.wheel_delta_y()); if (event.modifiers() == KeyModifier::Mod_Ctrl) wheel_delta *= 6; - set_current_number(m_current_number - wheel_delta); + set_value(m_value - wheel_delta); event.accept(); } diff --git a/Userland/Libraries/LibGUI/NumericInput.h b/Userland/Libraries/LibGUI/NumericInput.h index cde7e8ea78..4ff11b5995 100644 --- a/Userland/Libraries/LibGUI/NumericInput.h +++ b/Userland/Libraries/LibGUI/NumericInput.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2021, Matthew Olsson + * Copyright (c) 2024, Sam Atkins * * SPDX-License-Identifier: BSD-2-Clause */ @@ -18,9 +19,12 @@ public: Function on_number_changed; - void set_min_number(i64 number); - void set_max_number(i64 number); - void set_current_number(i64 number, GUI::AllowCallback allow_callback = GUI::AllowCallback::Yes); + i64 min() const { return m_min; } + void set_min(i64 number); + i64 max() const { return m_max; } + void set_max(i64 number); + i64 value() const { return m_value; } + void set_value(i64 number, GUI::AllowCallback allow_callback = GUI::AllowCallback::Yes); virtual void mousewheel_event(GUI::MouseEvent&) override; @@ -29,9 +33,9 @@ private: void on_focus_lost(); bool m_needs_text_reset { false }; - i64 m_current_number { 0 }; - i64 m_min_number { NumericLimits::min() }; - i64 m_max_number { NumericLimits::max() }; + i64 m_value { 0 }; + i64 m_min { NumericLimits::min() }; + i64 m_max { NumericLimits::max() }; }; }