entry_double.vala 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /*
  2. * Copyright (c) 2012-2020 Daniele Bartolini and individual contributors.
  3. * License: https://github.com/dbartolini/crown/blob/master/LICENSE
  4. */
  5. using Gtk;
  6. using Gdk;
  7. namespace Crown
  8. {
  9. public class EntryDouble : Gtk.Entry
  10. {
  11. public double _min;
  12. public double _max;
  13. public double _value;
  14. public bool _stop_emit;
  15. public string _format;
  16. public double value
  17. {
  18. get
  19. {
  20. return _value;
  21. }
  22. set
  23. {
  24. _stop_emit = true;
  25. set_value_safe(value);
  26. _stop_emit = false;
  27. }
  28. }
  29. // Signals
  30. public signal void value_changed();
  31. public EntryDouble(double val, double min, double max, string fmt = "%.6g")
  32. {
  33. this.hexpand = true;
  34. this.input_purpose = Gtk.InputPurpose.DIGITS;
  35. this.set_width_chars(1);
  36. this.scroll_event.connect(on_scroll);
  37. this.button_release_event.connect(on_button_release);
  38. this.activate.connect(on_activate);
  39. this.focus_out_event.connect(on_focus_out);
  40. this._min = min;
  41. this._max = max;
  42. this._format = fmt;
  43. _stop_emit = true;
  44. set_value_safe(val);
  45. _stop_emit = false;
  46. }
  47. private bool on_scroll(Gdk.EventScroll ev)
  48. {
  49. GLib.Signal.stop_emission_by_name(this, "scroll-event");
  50. return false; // Propagate the event
  51. }
  52. private bool on_button_release(Gdk.EventButton ev)
  53. {
  54. if (ev.button == 1 && this.has_focus) // Left button
  55. {
  56. this.text = "%.6g".printf(_value);
  57. this.set_position(-1);
  58. this.select_region(0, -1);
  59. return true; // Do not propagate
  60. }
  61. return false;
  62. }
  63. private void on_activate()
  64. {
  65. set_value_safe(string_to_double(this.text, _value));
  66. }
  67. private bool on_focus_out(Gdk.EventFocus ef)
  68. {
  69. set_value_safe(string_to_double(this.text, _value));
  70. return true; // Do not propagate
  71. }
  72. private void set_value_safe(double val)
  73. {
  74. _value = val.clamp(_min, _max);
  75. // Convert to text for displaying
  76. this.text = _format.printf(_value);
  77. // Notify value changed
  78. if (!_stop_emit)
  79. value_changed();
  80. }
  81. /// Returns @a str as double or @a deffault if conversion fails.
  82. private double string_to_double(string str, double deffault)
  83. {
  84. double result;
  85. return double.try_parse(str, out result) ? result : deffault;
  86. }
  87. }
  88. }