Splitter.h 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /*
  2. * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <LibGUI/Widget.h>
  8. namespace GUI {
  9. class Splitter : public Widget {
  10. C_OBJECT(Splitter);
  11. public:
  12. virtual ~Splitter() override;
  13. int first_resizee_minimum_size() { return m_first_resizee_minimum_size; }
  14. void set_first_resizee_minimum_size(int minimum_size) { m_first_resizee_minimum_size = minimum_size; }
  15. int second_resizee_minimum_size() { return m_second_resizee_minimum_size; }
  16. void set_second_resizee_minimum_size(int minimum_size) { m_second_resizee_minimum_size = minimum_size; }
  17. protected:
  18. explicit Splitter(Gfx::Orientation);
  19. virtual void paint_event(PaintEvent&) override;
  20. virtual void resize_event(ResizeEvent&) override;
  21. virtual void mousedown_event(MouseEvent&) override;
  22. virtual void mousemove_event(MouseEvent&) override;
  23. virtual void mouseup_event(MouseEvent&) override;
  24. virtual void leave_event(Core::Event&) override;
  25. virtual void did_layout() override;
  26. private:
  27. void override_cursor(bool do_override);
  28. Gfx::IntRect rect_between_widgets(GUI::Widget const& first_widget, GUI::Widget const& second_widget, bool honor_content_margins) const;
  29. Gfx::Orientation m_orientation;
  30. bool m_resizing { false };
  31. bool m_overriding_cursor { false };
  32. Gfx::IntPoint m_resize_origin;
  33. WeakPtr<Widget> m_first_resizee;
  34. WeakPtr<Widget> m_second_resizee;
  35. Gfx::IntSize m_first_resizee_start_size;
  36. Gfx::IntSize m_second_resizee_start_size;
  37. int m_first_resizee_minimum_size { 0 };
  38. int m_second_resizee_minimum_size { 0 };
  39. void recompute_grabbables();
  40. struct Grabbable {
  41. // Index in m_grabbables, for convenience.
  42. size_t index { 0 };
  43. // The full grabbable rect, includes the content margin of adjacent elements.
  44. Gfx::IntRect grabbable_rect;
  45. // The rect used for painting. Does not include content margins.
  46. Gfx::IntRect paint_rect;
  47. WeakPtr<Widget> first_widget;
  48. WeakPtr<Widget> second_widget;
  49. };
  50. Grabbable* grabbable_at(Gfx::IntPoint const&);
  51. void set_hovered_grabbable(Grabbable*);
  52. Vector<Grabbable> m_grabbables;
  53. Optional<size_t> m_hovered_index;
  54. };
  55. class VerticalSplitter final : public Splitter {
  56. C_OBJECT(VerticalSplitter)
  57. public:
  58. virtual ~VerticalSplitter() override { }
  59. private:
  60. VerticalSplitter()
  61. : Splitter(Gfx::Orientation::Vertical)
  62. {
  63. }
  64. };
  65. class HorizontalSplitter final : public Splitter {
  66. C_OBJECT(HorizontalSplitter)
  67. public:
  68. virtual ~HorizontalSplitter() override { }
  69. private:
  70. HorizontalSplitter()
  71. : Splitter(Gfx::Orientation::Horizontal)
  72. {
  73. }
  74. };
  75. }