mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-10 13:00:29 +03:00
b65e711929
Add a new widget "DynamicWidgetContainer" that is used to group it's child widgets within an collapsable and detachable container. The DynmnicWidgetContainer is able to persist it's view state if a config domain has been provided. Having that set will allow the widget to restore it's view state automatically.
100 lines
3.6 KiB
C++
100 lines
3.6 KiB
C++
/*
|
|
* Copyright (c) 2023, Torsten Engelmann <engelTorsten@gmx.de>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <LibGUI/Frame.h>
|
|
#include <LibGUI/Label.h>
|
|
#include <LibGUI/LabelWithEventDispatcher.h>
|
|
#include <LibGUI/Window.h>
|
|
|
|
namespace GUI {
|
|
|
|
class DynamicWidgetContainer : public Frame {
|
|
C_OBJECT(DynamicWidgetContainer);
|
|
|
|
public:
|
|
enum class ViewState {
|
|
Expanded,
|
|
Collapsed,
|
|
Detached
|
|
};
|
|
|
|
enum class MoveTargetOperation {
|
|
SetTarget,
|
|
ClearAllTargets
|
|
};
|
|
|
|
ViewState view_state() const { return m_view_state; }
|
|
void set_view_state(ViewState);
|
|
StringView section_label() const& { return m_section_label; }
|
|
void set_section_label(String);
|
|
StringView config_domain() const& { return m_config_domain; }
|
|
void set_config_domain(String);
|
|
bool persist_state() const { return !m_config_domain.is_empty(); }
|
|
void set_detached_size(Gfx::IntSize const);
|
|
Gfx::IntSize detached_size() const { return m_detached_size.value(); }
|
|
bool has_detached_size() { return m_detached_size.has_value(); }
|
|
void set_container_with_individual_order(bool);
|
|
bool is_container_with_individual_order() const { return m_is_container_with_individual_order; }
|
|
void set_show_controls(bool);
|
|
bool show_controls() const { return m_show_controls; }
|
|
void set_parent_container(RefPtr<GUI::DynamicWidgetContainer>);
|
|
bool check_has_move_target(Gfx::IntPoint, MoveTargetOperation);
|
|
// FIXME: this should not be a public api and static - but currently the destructor is not being called when the widget was created via a gml file.
|
|
static void close_all_detached_windows();
|
|
virtual ~DynamicWidgetContainer() override;
|
|
|
|
protected:
|
|
explicit DynamicWidgetContainer(Gfx::Orientation = Gfx::Orientation::Vertical);
|
|
virtual void paint_event(PaintEvent&) override {};
|
|
virtual void second_paint_event(PaintEvent&) override;
|
|
virtual void resize_event(ResizeEvent&) override;
|
|
virtual void child_event(Core::ChildEvent&) override;
|
|
|
|
template<typename Callback>
|
|
void for_each_child_container(Callback callback);
|
|
Vector<GUI::DynamicWidgetContainer&> child_containers() const;
|
|
|
|
private:
|
|
struct RelevantSizes {
|
|
UISize preferred_size;
|
|
UISize min_size;
|
|
};
|
|
ViewState m_view_state = ViewState::Expanded;
|
|
String m_section_label;
|
|
String m_config_domain;
|
|
bool m_is_container_with_individual_order { false };
|
|
bool m_persist_state { false };
|
|
bool m_is_dragging { false };
|
|
bool m_render_as_move_target { false };
|
|
bool m_show_controls { true };
|
|
Gfx::IntPoint m_drag_start_location;
|
|
Gfx::IntPoint m_current_mouse_position;
|
|
RefPtr<GUI::Widget> m_controls_widget;
|
|
RefPtr<GUI::LabelWithEventDispatcher> m_label_widget;
|
|
Gfx::IntRect m_move_widget_knurl = { 0, 0, 16, 16 };
|
|
Optional<NonnullRefPtr<GUI::Window>> m_detached_widgets_window;
|
|
Optional<Gfx::FrameStyle> m_previous_frame_style;
|
|
Optional<RelevantSizes> m_dimensions_before_collapse;
|
|
Optional<Gfx::IntSize> m_detached_size;
|
|
RefPtr<GUI::DynamicWidgetContainer> m_parent_container;
|
|
static Vector<NonnullRefPtr<GUI::Window>> s_open_windows;
|
|
|
|
ErrorOr<void> detach_widgets();
|
|
void restore_view_state();
|
|
void register_open_window(NonnullRefPtr<GUI::Window>);
|
|
void unregister_open_window(NonnullRefPtr<GUI::Window>);
|
|
void set_render_as_move_target(bool);
|
|
void swap_widget_positions(NonnullRefPtr<Core::EventReceiver> source, Gfx::IntPoint destination_positon);
|
|
|
|
void handle_mousemove_event(MouseEvent&);
|
|
void handle_mouseup_event(MouseEvent&);
|
|
void handle_doubleclick_event(MouseEvent&);
|
|
void update_control_button_visibility();
|
|
};
|
|
}
|