forked from std-microblock/breeze-shell
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmenu_widget.h
More file actions
183 lines (151 loc) · 5.97 KB
/
menu_widget.h
File metadata and controls
183 lines (151 loc) · 5.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#pragma once
#include "breeze_ui/animator.h"
#include "breeze_ui/extra_widgets.h"
#include "breeze_ui/nanovg_wrapper.h"
#include "breeze_ui/ui.h"
#include "breeze_ui/widget.h"
#include "contextmenu.h"
#include "shell/config.h"
#include "shell/utils.h"
#include "shell/widgets/background_widget.h"
#include <algorithm>
#include <functional>
#include <memory>
#include <optional>
namespace mb_shell {
struct menu_widget;
struct menu_item_widget : public ui::widget {
using super = ui::widget;
menu_item item;
ui::sp_anim_float opacity = anim_float(0, 200);
menu_item_widget();
virtual void reset_appear_animation(float delay);
};
struct menu_item_ownerdraw_widget : public menu_item_widget {
using super = menu_item_widget;
owner_draw_menu_info owner_draw;
std::optional<ui::NVGImage> img{};
menu_item_ownerdraw_widget(menu_item item);
void update(ui::update_context &ctx) override;
void render(ui::nanovg_context ctx) override;
void reset_appear_animation(float delay) override;
};
struct menu_item_parent_widget : public menu_item_widget {
using super = menu_item_widget;
void update(ui::update_context &ctx) override;
void reset_appear_animation(float delay) override;
};
struct menu_item_normal_widget : public menu_item_widget {
using super = menu_item_widget;
ui::sp_anim_float opacity = anim_float(0, 200);
float text_padding = config::current->context_menu.theme.text_padding;
float margin = config::current->context_menu.theme.margin;
bool has_icon_padding = false;
bool has_submenu_padding = false;
float padding = config::current->context_menu.theme.padding;
float icon_padding = config::current->context_menu.theme.icon_padding;
float right_icon_padding =
config::current->context_menu.theme.right_icon_padding;
menu_item_normal_widget(menu_item item);
void reset_appear_animation(float delay) override;
std::optional<ui::NVGImage> icon_img{};
std::optional<ui::NVGImage> icon_unfold_img{};
std::shared_ptr<menu_widget> submenu_wid = nullptr;
float show_submenu_timer = 0.f;
ui::sp_anim_float bg_opacity = anim_float(0, 200);
ui::sp_anim_float text_blur = anim_float(0, 200);
void render(ui::nanovg_context ctx) override;
void update(ui::update_context &ctx) override;
float measure_width(ui::update_context &ctx) override;
bool check_hit(const ui::update_context &ctx) override;
void hide_submenu();
void show_submenu(ui::update_context &ctx);
void reload_icon_img(ui::nanovg_context ctx);
};
struct menu_item_custom_widget : public menu_item_widget {
using super = menu_item_widget;
std::shared_ptr<ui::widget> custom_widget;
menu_item_custom_widget(std::shared_ptr<ui::widget> custom_widget)
: custom_widget(custom_widget) {}
void render(ui::nanovg_context ctx) override;
void update(ui::update_context &ctx) override;
float measure_width(ui::update_context &ctx) override;
float measure_height(ui::update_context &ctx) override;
};
enum class popup_direction {
// 第一象限 ~ 第四象限
top_left,
top_right,
bottom_left,
bottom_right,
};
struct menu_item_widget;
struct menu_animation_rect {
float x = 0;
float y = 0;
float width = 0;
float height = 0;
};
struct menu_widget : public ui::flex_widget {
using super = ui::flex_widget;
float bg_padding_vertical = 6;
std::shared_ptr<background_widget> bg;
std::shared_ptr<menu_widget> current_submenu;
std::optional<std::weak_ptr<ui::widget>> parent_item_widget;
std::vector<std::shared_ptr<widget>> rendering_submenus;
menu_widget *parent_menu = nullptr;
menu menu_data;
explicit menu_widget(bool is_main = false);
popup_direction direction = popup_direction::bottom_right;
bool is_top_level_menu = false;
bool bg_animation_armed = false;
bool bg_appear_initialized = false;
std::optional<menu_animation_rect> bg_start_rect;
void init_from_data(menu menu_data);
void arm_background_animation(
std::optional<menu_animation_rect> initial_rect = std::nullopt);
bool animate_appear_started = false;
void reset_animation(bool reverse = false);
void update(ui::update_context &ctx) override;
void update_icon_width();
void render(ui::nanovg_context ctx) override;
bool check_hit(const ui::update_context &ctx) override;
void close();
};
struct screenside_button_group_widget : public ui::flex_widget {
struct button_widget : public ui::widget {
using super = ui::widget;
std::string icon_svg;
std::optional<ui::NVGImage> icon{};
std::function<void()> on_click;
button_widget(std::string icon_svg);
ui::sp_anim_float bg_opacity = anim_float(0, 200);
void update(ui::update_context &ctx) override;
void render(ui::nanovg_context ctx) override;
};
using super = ui::flex_widget;
screenside_button_group_widget();
};
struct mouse_menu_widget_main : public ui::widget {
float anchor_x = 0, anchor_y = 0;
mouse_menu_widget_main(menu menu_data, float x, float y);
bool position_calibrated = false, direction_calibrated = false;
bool ignore_outside_click_until_mouse_release = false;
bool prev_lmb_down = false;
bool prev_rmb_down = false;
popup_direction direction;
std::shared_ptr<menu_widget> menu_wid;
void update(ui::update_context &ctx);
void render(ui::nanovg_context ctx);
static std::pair<float, float>
calculate_position(menu_widget *menu_wid, ui::update_context &ctx,
float anchor_x, float anchor_y,
popup_direction direction);
static popup_direction calculate_direction(
menu_widget *menu_wid, ui::update_context &ctx, float anchor_x,
float anchor_y,
popup_direction prefer_direction = popup_direction::bottom_right);
void calibrate_position(ui::update_context &ctx, bool animated = true);
void calibrate_direction(ui::update_context &ctx);
};
} // namespace mb_shell