GSlider.cpp 5.1 KB

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