NumericInput.cpp 2.3 KB

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