Serenity Operating System
at master 104 lines 2.9 kB view raw
1/* 2 * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org> 3 * Copyright (c) 2022, the SerenityOS developers. 4 * 5 * SPDX-License-Identifier: BSD-2-Clause 6 */ 7 8#pragma once 9 10#include <LibGUI/Widget.h> 11 12namespace GUI { 13 14class Splitter : public Widget { 15 C_OBJECT(Splitter); 16 17public: 18 enum class OpportunisticResizee { 19 First, 20 Second 21 }; 22 23 virtual ~Splitter() override = default; 24 25protected: 26 explicit Splitter(Gfx::Orientation); 27 28 virtual void paint_event(PaintEvent&) override; 29 virtual void resize_event(ResizeEvent&) override; 30 virtual void mousedown_event(MouseEvent&) override; 31 virtual void mousemove_event(MouseEvent&) override; 32 virtual void mouseup_event(MouseEvent&) override; 33 virtual void leave_event(Core::Event&) override; 34 35 virtual void did_layout() override; 36 virtual void custom_layout() override; 37 38 OpportunisticResizee opportunisitic_resizee() const { return m_opportunistic_resizee; } 39 void set_opportunisitic_resizee(OpportunisticResizee resizee) { m_opportunistic_resizee = resizee; } 40 41private: 42 void override_cursor(bool do_override); 43 Gfx::IntRect rect_between_widgets(GUI::Widget const& first_widget, GUI::Widget const& second_widget, bool honor_grabbable_margins) const; 44 45 Gfx::Orientation m_orientation; 46 bool m_resizing { false }; 47 bool m_overriding_cursor { false }; 48 Gfx::IntPoint m_resize_origin; 49 WeakPtr<Widget> m_first_resizee; 50 WeakPtr<Widget> m_second_resizee; 51 Gfx::IntSize m_first_resizee_start_size; 52 Gfx::IntSize m_second_resizee_start_size; 53 OpportunisticResizee m_opportunistic_resizee { OpportunisticResizee::Second }; 54 size_t m_last_child_count { 0 }; 55 int m_first_resizee_max_size { 0 }; 56 int m_second_resizee_max_size { 0 }; 57 58 void recompute_grabbables(); 59 60 struct Grabbable { 61 // Index in m_grabbables, for convenience. 62 size_t index { 0 }; 63 64 // The full grabbable rect, includes the content margin of adjacent elements. 65 Gfx::IntRect grabbable_rect; 66 // The rect used for painting. Does not include content margins. 67 Gfx::IntRect paint_rect; 68 69 WeakPtr<Widget> first_widget; 70 WeakPtr<Widget> second_widget; 71 }; 72 73 Grabbable* grabbable_at(Gfx::IntPoint); 74 void set_hovered_grabbable(Grabbable*); 75 76 Vector<Grabbable> m_grabbables; 77 Optional<size_t> m_hovered_index; 78}; 79 80class VerticalSplitter final : public Splitter { 81 C_OBJECT(VerticalSplitter) 82public: 83 virtual ~VerticalSplitter() override = default; 84 85private: 86 VerticalSplitter() 87 : Splitter(Gfx::Orientation::Vertical) 88 { 89 } 90}; 91 92class HorizontalSplitter final : public Splitter { 93 C_OBJECT(HorizontalSplitter) 94public: 95 virtual ~HorizontalSplitter() override = default; 96 97private: 98 HorizontalSplitter() 99 : Splitter(Gfx::Orientation::Horizontal) 100 { 101 } 102}; 103 104}