HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
overlay_widget.hpp
Go to the documentation of this file.
1// Copyright Take Vos 2021.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
8
9#pragma once
10
11#include "widget.hpp"
12#include "../macros.hpp"
13#include <coroutine>
14
15hi_export_module(hikogui.widgets.overlay_widget);
16
17hi_export namespace hi {
18inline namespace v1 {
19
43class overlay_widget : public widget {
44public:
45 using super = widget;
46
48
53 overlay_widget() noexcept : super() {}
54
55 void set_widget(std::unique_ptr<widget> new_widget) noexcept
56 {
57 if (new_widget) {
58 new_widget->set_parent(this);
59 }
60 auto old_widget = std::exchange(_content, std::move(new_widget));
61 if (old_widget) {
62 old_widget->set_parent(nullptr);
63 }
64
65 ++global_counter<"overlay_widget:set_widget:constrain">;
67 }
68
78 template<typename Widget, typename... Args>
79 Widget& emplace(Args&&... args) noexcept
80 {
81 hi_axiom(loop::main().on_thread());
82 hi_assert(_content == nullptr);
83
84 auto tmp = std::make_unique<Widget>(std::forward<Args>(args)...);
85 auto& ref = *tmp;
86 set_widget(std::move(tmp));
87 return ref;
88 }
89
91 [[nodiscard]] generator<widget_intf&> children(bool include_invisible) noexcept override
92 {
93 if (_content) {
94 co_yield *_content;
95 }
96 }
97
98 [[nodiscard]] box_constraints update_constraints() noexcept override
99 {
100 _layout = {};
101 _content_constraints = _content->update_constraints();
102 return _content_constraints;
103 }
104
105 void set_layout(widget_layout const& context) noexcept override
106 {
107 _layout = context;
108
109 // The clipping rectangle of the overlay matches the rectangle exactly, with a border around it.
110 _layout.clipping_rectangle = context.rectangle() + theme().border_width();
111
112 auto const content_rectangle = context.rectangle();
113 _content_shape = box_shape{_content_constraints, content_rectangle, theme().baseline_adjustment()};
114
115 // The content should not draw in the border of the overlay, so give a tight clipping rectangle.
116 _content->set_layout(_layout.transform(_content_shape, context.rectangle()));
117 }
118
119 void draw(draw_context const& context) noexcept override
120 {
121 if (mode() > widget_mode::invisible) {
122 if (overlaps(context, layout())) {
123 draw_background(context);
124 }
125 _content->draw(context);
126 }
127 }
128
129 [[nodiscard]] color background_color() const noexcept override
130 {
131 return theme().fill_color(_layout.layer + 1);
132 }
133
134 [[nodiscard]] color foreground_color() const noexcept override
135 {
136 return theme().border_color(_layout.layer + 1);
137 }
138
139 void scroll_to_show(hi::aarectangle rectangle) noexcept override
140 {
141 // An overlay is in an absolute position on the window,
142 // so do not forward the scroll_to_show message to its parent.
143 }
144
145 [[nodiscard]] hitbox hitbox_test(point2 position) const noexcept override
146 {
147 hi_axiom(loop::main().on_thread());
148
149 if (mode() >= widget_mode::partial) {
150 return _content->hitbox_test_from_parent(position);
151 } else {
152 return {};
153 }
154 }
155
156 bool handle_event(gui_event const& event) noexcept override
157 {
158 // Short-cut event handling, no-events should be passed below the overlay.
159 return true;
160 }
162private:
163 std::unique_ptr<widget> _content;
164 box_constraints _content_constraints;
165 box_shape _content_shape;
166
167 void draw_background(draw_context const& context) noexcept
168 {
169 context.draw_box(
170 layout(), layout().rectangle(), background_color(), foreground_color(), theme().border_width(), border_side::outside);
171 }
172};
173
174} // namespace v1
175} // namespace hi::v1
Defines widget.
@ window_reconstrain
Request that widget get constraint on the next frame.
Definition gui_event_type.hpp:48
@ rectangle
The gui_event has rectangle data.
Definition gui_event_variant.hpp:44
@ partial
A widget is partially enabled.
Definition widget_state.hpp:73
@ invisible
The widget is invisible.
Definition widget_state.hpp:41
The HikoGUI namespace.
Definition array_generic.hpp:21
The HikoGUI API version 1.
Definition array_generic.hpp:22
@ color
A color value was modified.
Definition style_modify_mask.hpp:27
@ outside
The border is drawn outside the edge of a quad.
Definition draw_context_intf.hpp:39
widget_layout const & layout() const noexcept
Get the current layout for this widget.
Definition widget_intf.hpp:241
A GUI widget which may exist anywhere on a window overlaid above any other widget.
Definition overlay_widget.hpp:43
overlay_widget() noexcept
Constructs an empty overlay widget.
Definition overlay_widget.hpp:53
Widget & emplace(Args &&... args) noexcept
Add a content widget directly to this overlay widget.
Definition overlay_widget.hpp:79
void scroll_to_show() noexcept
Scroll to show the important part of the widget.
Definition widget_intf.hpp:347
widget() noexcept
Constructor for creating sub views.
Definition widget.hpp:50
box_constraints update_constraints() noexcept override
Update the constraints of the widget.
Definition widget.hpp:110
bool process_event(gui_event const &event) const noexcept override
Send a event to the window.
Definition widget.hpp:125
T forward(T... args)
T move(T... args)