VBForm.cpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. #include "VBForm.h"
  2. #include "VBWidget.h"
  3. #include <LibGUI/GPainter.h>
  4. static VBForm* s_current;
  5. VBForm* VBForm::current()
  6. {
  7. return s_current;
  8. }
  9. VBForm::VBForm(const String& name, GWidget* parent)
  10. : GWidget(parent)
  11. , m_name(name)
  12. {
  13. s_current = this;
  14. set_fill_with_background_color(true);
  15. set_background_color(Color::LightGray);
  16. set_greedy_for_hits(true);
  17. auto box1 = VBWidget::create(VBWidgetType::GSpinBox, *this);
  18. box1->set_rect({ 10, 10, 81, 21 });
  19. m_widgets.append(move(box1));
  20. auto box2 = VBWidget::create(VBWidgetType::GTextEditor, *this);
  21. box2->set_rect({ 100, 100, 161, 161 });
  22. m_widgets.append(move(box2));
  23. auto button1 = VBWidget::create(VBWidgetType::GButton, *this);
  24. button1->set_rect({ 200, 50, 81, 21 });
  25. m_widgets.append(move(button1));
  26. auto groupbox1 = VBWidget::create(VBWidgetType::GGroupBox, *this);
  27. groupbox1->set_rect({ 300, 150, 161, 51 });
  28. m_widgets.append(move(groupbox1));
  29. }
  30. void VBForm::insert_widget(VBWidgetType type)
  31. {
  32. auto widget = VBWidget::create(type, *this);
  33. widget->set_rect({ m_next_insertion_position, { m_grid_size * 10 + 1, m_grid_size * 5 + 1 } });
  34. m_next_insertion_position.move_by(m_grid_size, m_grid_size);
  35. m_widgets.append(move(widget));
  36. }
  37. VBForm::~VBForm()
  38. {
  39. }
  40. void VBForm::paint_event(GPaintEvent& event)
  41. {
  42. GPainter painter(*this);
  43. painter.add_clip_rect(event.rect());
  44. for (int y = 0; y < height(); y += m_grid_size) {
  45. for (int x = 0; x < width(); x += m_grid_size) {
  46. painter.set_pixel({ x, y }, Color::Black);
  47. }
  48. }
  49. }
  50. void VBForm::second_paint_event(GPaintEvent& event)
  51. {
  52. GPainter painter(*this);
  53. painter.add_clip_rect(event.rect());
  54. for (auto& widget : m_widgets) {
  55. if (widget->is_selected()) {
  56. for_each_direction([&] (Direction direction) {
  57. painter.fill_rect(widget->grabber_rect(direction), Color::Black);
  58. });
  59. }
  60. }
  61. }
  62. bool VBForm::is_selected(const VBWidget& widget) const
  63. {
  64. return &widget == m_selected_widget.ptr();
  65. }
  66. VBWidget* VBForm::widget_at(const Point& position)
  67. {
  68. for (int i = m_widgets.size() - 1; i >= 0; --i) {
  69. auto& widget = *m_widgets[i];
  70. if (widget.rect().contains(position))
  71. return &widget;
  72. }
  73. return nullptr;
  74. }
  75. void VBForm::grabber_mousedown_event(GMouseEvent& event, VBWidget& widget, Direction grabber)
  76. {
  77. m_transform_event_origin = event.position();
  78. m_transform_widget_origin_rect = widget.rect();
  79. m_resize_direction = grabber;
  80. }
  81. void VBForm::mousedown_event(GMouseEvent& event)
  82. {
  83. if (m_selected_widget && m_resize_direction == Direction::None) {
  84. auto grabber = m_selected_widget->grabber_at(event.position());
  85. if (grabber != Direction::None)
  86. return grabber_mousedown_event(event, *m_selected_widget, grabber);
  87. }
  88. auto* widget = widget_at(event.position());
  89. if (!widget) {
  90. if (m_selected_widget) {
  91. m_selected_widget = nullptr;
  92. if (on_widget_selected)
  93. on_widget_selected(nullptr);
  94. update();
  95. }
  96. return;
  97. }
  98. if (event.button() == GMouseButton::Left) {
  99. m_selected_widget = widget->make_weak_ptr();
  100. m_transform_event_origin = event.position();
  101. m_transform_widget_origin_rect = widget->rect();
  102. if (on_widget_selected)
  103. on_widget_selected(widget);
  104. update();
  105. }
  106. }
  107. void VBForm::mousemove_event(GMouseEvent& event)
  108. {
  109. if (event.buttons() & GMouseButton::Left && m_selected_widget) {
  110. if (m_resize_direction == Direction::None) {
  111. auto delta = event.position() - m_transform_event_origin;
  112. auto new_rect = m_transform_widget_origin_rect.translated(delta);
  113. new_rect.set_x(new_rect.x() - (new_rect.x() % m_grid_size));
  114. new_rect.set_y(new_rect.y() - (new_rect.y() % m_grid_size));
  115. m_selected_widget->set_rect(new_rect);
  116. update();
  117. return;
  118. }
  119. int diff_x = event.x() - m_transform_event_origin.x();
  120. int diff_y = event.y() - m_transform_event_origin.y();
  121. int change_x = 0;
  122. int change_y = 0;
  123. int change_w = 0;
  124. int change_h = 0;
  125. switch (m_resize_direction) {
  126. case Direction::DownRight:
  127. change_w = diff_x;
  128. change_h = diff_y;
  129. break;
  130. case Direction::Right:
  131. change_w = diff_x;
  132. break;
  133. case Direction::UpRight:
  134. change_w = diff_x;
  135. change_y = diff_y;
  136. change_h = -diff_y;
  137. break;
  138. case Direction::Up:
  139. change_y = diff_y;
  140. change_h = -diff_y;
  141. break;
  142. case Direction::UpLeft:
  143. change_x = diff_x;
  144. change_w = -diff_x;
  145. change_y = diff_y;
  146. change_h = -diff_y;
  147. break;
  148. case Direction::Left:
  149. change_x = diff_x;
  150. change_w = -diff_x;
  151. break;
  152. case Direction::DownLeft:
  153. change_x = diff_x;
  154. change_w = -diff_x;
  155. change_h = diff_y;
  156. break;
  157. case Direction::Down:
  158. change_h = diff_y;
  159. break;
  160. default:
  161. ASSERT_NOT_REACHED();
  162. }
  163. auto new_rect = m_transform_widget_origin_rect;
  164. Size minimum_size { 5, 5 };
  165. new_rect.set_x(new_rect.x() + change_x);
  166. new_rect.set_y(new_rect.y() + change_y);
  167. new_rect.set_width(max(minimum_size.width(), new_rect.width() + change_w));
  168. new_rect.set_height(max(minimum_size.height(), new_rect.height() + change_h));
  169. new_rect.set_x(new_rect.x() - (new_rect.x() % m_grid_size));
  170. new_rect.set_y(new_rect.y() - (new_rect.y() % m_grid_size));
  171. new_rect.set_width(new_rect.width() - (new_rect.width() % m_grid_size) + 1);
  172. new_rect.set_height(new_rect.height() - (new_rect.height() % m_grid_size) + 1);
  173. m_selected_widget->set_rect(new_rect);
  174. update();
  175. }
  176. }
  177. void VBForm::mouseup_event(GMouseEvent& event)
  178. {
  179. if (event.button() == GMouseButton::Left) {
  180. m_transform_event_origin = { };
  181. m_transform_widget_origin_rect = { };
  182. m_resize_direction = Direction::None;
  183. }
  184. }