GSlider.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. #include <LibDraw/StylePainter.h>
  2. #include <LibGUI/GPainter.h>
  3. #include <LibGUI/GSlider.h>
  4. GSlider::GSlider(GWidget* parent)
  5. : GSlider(Orientation::Horizontal, parent)
  6. {
  7. }
  8. GSlider::GSlider(Orientation orientation, GWidget* parent)
  9. : GWidget(parent)
  10. , m_orientation(orientation)
  11. {
  12. }
  13. GSlider::~GSlider()
  14. {
  15. }
  16. void GSlider::set_range(int min, int max)
  17. {
  18. ASSERT(min <= max);
  19. if (m_min == min && m_max == max)
  20. return;
  21. m_min = min;
  22. m_max = max;
  23. if (m_value > max)
  24. m_value = max;
  25. if (m_value < min)
  26. m_value = min;
  27. update();
  28. }
  29. void GSlider::set_value(int value)
  30. {
  31. if (value > m_max)
  32. value = m_max;
  33. if (value < m_min)
  34. value = m_min;
  35. if (m_value == value)
  36. return;
  37. m_value = value;
  38. update();
  39. if (on_value_changed)
  40. on_value_changed(m_value);
  41. }
  42. void GSlider::paint_event(GPaintEvent& event)
  43. {
  44. GPainter painter(*this);
  45. painter.add_clip_rect(event.rect());
  46. Rect track_rect;
  47. if (orientation() == Orientation::Horizontal) {
  48. track_rect = { inner_rect().x(), 0, inner_rect().width(), track_size() };
  49. track_rect.center_vertically_within(inner_rect());
  50. } else {
  51. track_rect = { 0, inner_rect().y(), track_size(), inner_rect().height() };
  52. track_rect.center_horizontally_within(inner_rect());
  53. }
  54. StylePainter::paint_frame(painter, track_rect, palette(), FrameShape::Panel, FrameShadow::Sunken, 1);
  55. StylePainter::paint_button(painter, knob_rect(), palette(), ButtonStyle::Normal, false, m_knob_hovered);
  56. }
  57. Rect GSlider::knob_rect() const
  58. {
  59. auto inner_rect = this->inner_rect();
  60. Rect rect;
  61. rect.set_secondary_offset_for_orientation(orientation(), 0);
  62. rect.set_secondary_size_for_orientation(orientation(), knob_secondary_size());
  63. if (knob_size_mode() == KnobSizeMode::Fixed) {
  64. if (m_max - m_min) {
  65. float scale = (float)inner_rect.primary_size_for_orientation(orientation()) / (float)(m_max - m_min);
  66. rect.set_primary_offset_for_orientation(orientation(), inner_rect.primary_offset_for_orientation(orientation()) + ((int)(m_value * scale)) - (knob_fixed_primary_size() / 2));
  67. } else
  68. rect.set_primary_size_for_orientation(orientation(), 0);
  69. rect.set_primary_size_for_orientation(orientation(), knob_fixed_primary_size());
  70. } else {
  71. float scale = (float)inner_rect.primary_size_for_orientation(orientation()) / (float)(m_max - m_min + 1);
  72. rect.set_primary_offset_for_orientation(orientation(), inner_rect.primary_offset_for_orientation(orientation()) + ((int)(m_value * scale)));
  73. if (m_max - m_min)
  74. rect.set_primary_size_for_orientation(orientation(), ::max((int)(scale), knob_fixed_primary_size()));
  75. else
  76. rect.set_primary_size_for_orientation(orientation(), inner_rect.primary_size_for_orientation(orientation()));
  77. }
  78. if (orientation() == Orientation::Horizontal)
  79. rect.center_vertically_within(inner_rect);
  80. else
  81. rect.center_horizontally_within(inner_rect);
  82. return rect;
  83. }
  84. void GSlider::mousedown_event(GMouseEvent& event)
  85. {
  86. if (!is_enabled())
  87. return;
  88. if (event.button() == GMouseButton::Left) {
  89. if (knob_rect().contains(event.position())) {
  90. m_dragging = true;
  91. m_drag_origin = event.position();
  92. m_drag_origin_value = m_value;
  93. return;
  94. } else {
  95. if (event.position().primary_offset_for_orientation(orientation()) > knob_rect().last_edge_for_orientation(orientation()))
  96. set_value(m_value + 1);
  97. else if (event.position().primary_offset_for_orientation(orientation()) < knob_rect().first_edge_for_orientation(orientation()))
  98. set_value(m_value - 1);
  99. }
  100. }
  101. return GWidget::mousedown_event(event);
  102. }
  103. void GSlider::mousemove_event(GMouseEvent& event)
  104. {
  105. if (!is_enabled())
  106. return;
  107. set_knob_hovered(knob_rect().contains(event.position()));
  108. if (m_dragging) {
  109. float delta = event.position().primary_offset_for_orientation(orientation()) - m_drag_origin.primary_offset_for_orientation(orientation());
  110. float scrubbable_range = inner_rect().primary_size_for_orientation(orientation());
  111. float value_steps_per_scrubbed_pixel = (m_max - m_min) / scrubbable_range;
  112. float new_value = m_drag_origin_value + (value_steps_per_scrubbed_pixel * delta);
  113. set_value((int)new_value);
  114. return;
  115. }
  116. return GWidget::mousemove_event(event);
  117. }
  118. void GSlider::mouseup_event(GMouseEvent& event)
  119. {
  120. if (!is_enabled())
  121. return;
  122. if (event.button() == GMouseButton::Left) {
  123. m_dragging = false;
  124. return;
  125. }
  126. return GWidget::mouseup_event(event);
  127. }
  128. void GSlider::leave_event(CEvent& event)
  129. {
  130. if (!is_enabled())
  131. return;
  132. set_knob_hovered(false);
  133. GWidget::leave_event(event);
  134. }
  135. void GSlider::change_event(GEvent& event)
  136. {
  137. if (event.type() == GEvent::Type::EnabledChange) {
  138. if (!is_enabled())
  139. m_dragging = false;
  140. }
  141. GWidget::change_event(event);
  142. }
  143. void GSlider::set_knob_hovered(bool hovered)
  144. {
  145. if (m_knob_hovered == hovered)
  146. return;
  147. m_knob_hovered = hovered;
  148. update(knob_rect());
  149. }