mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 16:32:45 +00:00 
			
		
		
		
	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).
This commit is contained in:
		
							parent
							
								
									da349607a3
								
							
						
					
					
						commit
						5f0230a57e
					
				
					 3 changed files with 46 additions and 35 deletions
				
			
		|  | @ -187,7 +187,7 @@ PDFViewerWidget::PDFViewerWidget() | ||||||
| 
 | 
 | ||||||
|     m_viewer = v_splitter.add<PDFViewer>(); |     m_viewer = v_splitter.add<PDFViewer>(); | ||||||
|     m_viewer->on_page_change = [&](auto new_page) { |     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_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); |         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&) { |     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); |         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_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&) { |     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); |         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); |     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<GUI::NumericInput>(); |     m_page_text_box = toolbar.add<GUI::NumericInput>(); | ||||||
|     m_page_text_box->set_enabled(false); |     m_page_text_box->set_enabled(false); | ||||||
|     m_page_text_box->set_fixed_width(30); |     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) { |     m_page_text_box->on_number_changed = [&](i64 number) { | ||||||
|         auto page_count = m_viewer->document()->get_page_count(); |         auto page_count = m_viewer->document()->get_page_count(); | ||||||
|  | @ -396,8 +396,8 @@ PDF::PDFErrorOr<void> PDFViewerWidget::try_open_file(StringView path, NonnullOwn | ||||||
|     m_total_page_label->set_text(TRY(String::formatted("of {}", document->get_page_count()))); |     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_enabled(true); | ||||||
|     m_page_text_box->set_current_number(1, GUI::AllowCallback::No); |     m_page_text_box->set_value(1, GUI::AllowCallback::No); | ||||||
|     m_page_text_box->set_max_number(document->get_page_count()); |     m_page_text_box->set_max(document->get_page_count()); | ||||||
|     m_go_to_prev_page_action->set_enabled(false); |     m_go_to_prev_page_action->set_enabled(false); | ||||||
|     m_go_to_next_page_action->set_enabled(document->get_page_count() > 1); |     m_go_to_next_page_action->set_enabled(document->get_page_count() > 1); | ||||||
|     m_toggle_sidebar_action->set_enabled(true); |     m_toggle_sidebar_action->set_enabled(true); | ||||||
|  |  | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| /*
 | /*
 | ||||||
|  * Copyright (c) 2021, Matthew Olsson <mattco@serenityos.org> |  * Copyright (c) 2021, Matthew Olsson <mattco@serenityos.org> | ||||||
|  |  * Copyright (c) 2024, Sam Atkins <atkinssj@serenityos.org> | ||||||
|  * |  * | ||||||
|  * SPDX-License-Identifier: BSD-2-Clause |  * SPDX-License-Identifier: BSD-2-Clause | ||||||
|  */ |  */ | ||||||
|  | @ -7,6 +8,8 @@ | ||||||
| #include "NumericInput.h" | #include "NumericInput.h" | ||||||
| #include <ctype.h> | #include <ctype.h> | ||||||
| 
 | 
 | ||||||
|  | REGISTER_WIDGET(GUI, NumericInput); | ||||||
|  | 
 | ||||||
| namespace GUI { | namespace GUI { | ||||||
| 
 | 
 | ||||||
| NumericInput::NumericInput() | NumericInput::NumericInput() | ||||||
|  | @ -16,14 +19,14 @@ NumericInput::NumericInput() | ||||||
|     on_change = [&] { |     on_change = [&] { | ||||||
|         auto number_opt = text().to_number<int>(); |         auto number_opt = text().to_number<int>(); | ||||||
|         if (number_opt.has_value()) { |         if (number_opt.has_value()) { | ||||||
|             set_current_number(number_opt.value(), GUI::AllowCallback::No); |             set_value(number_opt.value(), GUI::AllowCallback::No); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         StringBuilder builder; |         StringBuilder builder; | ||||||
|         bool first = true; |         bool first = true; | ||||||
|         for (auto& ch : text()) { |         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); |                 builder.append(ch); | ||||||
|             first = false; |             first = false; | ||||||
|         } |         } | ||||||
|  | @ -37,57 +40,61 @@ NumericInput::NumericInput() | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         set_text(builder.to_byte_string()); |         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 = [&] { |     on_up_pressed = [&] { | ||||||
|         if (m_current_number < m_max_number) |         if (m_value < m_max) | ||||||
|             set_current_number(m_current_number + 1); |             set_value(m_value + 1); | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     on_down_pressed = [&] { |     on_down_pressed = [&] { | ||||||
|         if (m_current_number > m_min_number) |         if (m_value > m_min) | ||||||
|             set_current_number(m_current_number - 1); |             set_value(m_value - 1); | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     on_focusout = [&] { on_focus_lost(); }; |     on_focusout = [&] { on_focus_lost(); }; | ||||||
|     on_return_pressed = [&] { on_focus_lost(); }; |     on_return_pressed = [&] { on_focus_lost(); }; | ||||||
|     on_escape_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; |     m_min = number; | ||||||
|     if (m_current_number < number) |     if (m_value < number) | ||||||
|         set_current_number(number); |         set_value(number); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void NumericInput::set_max_number(i64 number) | void NumericInput::set_max(i64 number) | ||||||
| { | { | ||||||
|     m_max_number = number; |     m_max = number; | ||||||
|     if (m_current_number > number) |     if (m_value > number) | ||||||
|         set_current_number(number); |         set_value(number); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void NumericInput::on_focus_lost() | void NumericInput::on_focus_lost() | ||||||
| { | { | ||||||
|     if (m_needs_text_reset) { |     if (m_needs_text_reset) { | ||||||
|         set_text(ByteString::number(m_current_number)); |         set_text(ByteString::number(m_value)); | ||||||
|         m_needs_text_reset = false; |         m_needs_text_reset = false; | ||||||
|     } |     } | ||||||
|     if (on_number_changed) |     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; |         return; | ||||||
| 
 | 
 | ||||||
|     m_current_number = clamp(number, m_min_number, m_max_number); |     m_value = clamp(number, ::min(m_min, m_max), ::max(m_min, m_max)); | ||||||
|     set_text(ByteString::number(m_current_number)); |     set_text(ByteString::number(m_value)); | ||||||
|     if (on_number_changed && allow_callback == GUI::AllowCallback::Yes) |     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) | 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()); |     auto wheel_delta = event.wheel_delta_y() / abs(event.wheel_delta_y()); | ||||||
|     if (event.modifiers() == KeyModifier::Mod_Ctrl) |     if (event.modifiers() == KeyModifier::Mod_Ctrl) | ||||||
|         wheel_delta *= 6; |         wheel_delta *= 6; | ||||||
|     set_current_number(m_current_number - wheel_delta); |     set_value(m_value - wheel_delta); | ||||||
|     event.accept(); |     event.accept(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| /*
 | /*
 | ||||||
|  * Copyright (c) 2021, Matthew Olsson <mattco@serenityos.org> |  * Copyright (c) 2021, Matthew Olsson <mattco@serenityos.org> | ||||||
|  |  * Copyright (c) 2024, Sam Atkins <atkinssj@serenityos.org> | ||||||
|  * |  * | ||||||
|  * SPDX-License-Identifier: BSD-2-Clause |  * SPDX-License-Identifier: BSD-2-Clause | ||||||
|  */ |  */ | ||||||
|  | @ -18,9 +19,12 @@ public: | ||||||
| 
 | 
 | ||||||
|     Function<void(i64)> on_number_changed; |     Function<void(i64)> on_number_changed; | ||||||
| 
 | 
 | ||||||
|     void set_min_number(i64 number); |     i64 min() const { return m_min; } | ||||||
|     void set_max_number(i64 number); |     void set_min(i64 number); | ||||||
|     void set_current_number(i64 number, GUI::AllowCallback allow_callback = GUI::AllowCallback::Yes); |     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; |     virtual void mousewheel_event(GUI::MouseEvent&) override; | ||||||
| 
 | 
 | ||||||
|  | @ -29,9 +33,9 @@ private: | ||||||
|     void on_focus_lost(); |     void on_focus_lost(); | ||||||
| 
 | 
 | ||||||
|     bool m_needs_text_reset { false }; |     bool m_needs_text_reset { false }; | ||||||
|     i64 m_current_number { 0 }; |     i64 m_value { 0 }; | ||||||
|     i64 m_min_number { NumericLimits<i64>::min() }; |     i64 m_min { NumericLimits<i64>::min() }; | ||||||
|     i64 m_max_number { NumericLimits<i64>::max() }; |     i64 m_max { NumericLimits<i64>::max() }; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Sam Atkins
						Sam Atkins