Serenity Operating System
at master 89 lines 2.4 kB view raw
1/* 2 * Copyright (c) 2021, Matthew Olsson <mattco@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include "NumericInput.h" 8#include <ctype.h> 9 10NumericInput::NumericInput() 11{ 12 set_text("0"sv); 13 14 on_change = [&] { 15 auto number_opt = text().to_int(); 16 if (number_opt.has_value()) { 17 set_current_number(number_opt.value(), GUI::AllowCallback::No); 18 return; 19 } 20 21 StringBuilder builder; 22 bool first = true; 23 for (auto& ch : text()) { 24 if (isdigit(ch) || (first && ((ch == '-' && m_min_number < 0) || ch == '+'))) 25 builder.append(ch); 26 first = false; 27 } 28 29 auto new_number_opt = builder.to_deprecated_string().to_int(); 30 if (!new_number_opt.has_value()) { 31 m_needs_text_reset = true; 32 return; 33 } else { 34 m_needs_text_reset = false; 35 } 36 37 set_text(builder.to_deprecated_string()); 38 set_current_number(new_number_opt.value(), GUI::AllowCallback::No); 39 }; 40 41 on_up_pressed = [&] { 42 if (m_current_number < m_max_number) 43 set_current_number(m_current_number + 1); 44 }; 45 46 on_down_pressed = [&] { 47 if (m_current_number > m_min_number) 48 set_current_number(m_current_number - 1); 49 }; 50 51 on_focusout = [&] { on_focus_lost(); }; 52 on_return_pressed = [&] { on_focus_lost(); }; 53 on_escape_pressed = [&] { on_focus_lost(); }; 54} 55 56void NumericInput::set_min_number(i32 number) 57{ 58 m_min_number = number; 59 if (m_current_number < number) 60 set_current_number(number); 61} 62 63void NumericInput::set_max_number(i32 number) 64{ 65 m_max_number = number; 66 if (m_current_number > number) 67 set_current_number(number); 68} 69 70void NumericInput::on_focus_lost() 71{ 72 if (m_needs_text_reset) { 73 set_text(DeprecatedString::number(m_current_number)); 74 m_needs_text_reset = false; 75 } 76 if (on_number_changed) 77 on_number_changed(m_current_number); 78} 79 80void NumericInput::set_current_number(i32 number, GUI::AllowCallback allow_callback) 81{ 82 if (number == m_current_number) 83 return; 84 85 m_current_number = clamp(number, m_min_number, m_max_number); 86 set_text(DeprecatedString::number(m_current_number)); 87 if (on_number_changed && allow_callback == GUI::AllowCallback::Yes) 88 on_number_changed(m_current_number); 89}