1 | /**************************************************************************/ |
2 | /* control_editor_plugin.h */ |
3 | /**************************************************************************/ |
4 | /* This file is part of: */ |
5 | /* GODOT ENGINE */ |
6 | /* https://godotengine.org */ |
7 | /**************************************************************************/ |
8 | /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ |
9 | /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ |
10 | /* */ |
11 | /* Permission is hereby granted, free of charge, to any person obtaining */ |
12 | /* a copy of this software and associated documentation files (the */ |
13 | /* "Software"), to deal in the Software without restriction, including */ |
14 | /* without limitation the rights to use, copy, modify, merge, publish, */ |
15 | /* distribute, sublicense, and/or sell copies of the Software, and to */ |
16 | /* permit persons to whom the Software is furnished to do so, subject to */ |
17 | /* the following conditions: */ |
18 | /* */ |
19 | /* The above copyright notice and this permission notice shall be */ |
20 | /* included in all copies or substantial portions of the Software. */ |
21 | /* */ |
22 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ |
23 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ |
24 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ |
25 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ |
26 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ |
27 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ |
28 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ |
29 | /**************************************************************************/ |
30 | |
31 | #ifndef CONTROL_EDITOR_PLUGIN_H |
32 | #define CONTROL_EDITOR_PLUGIN_H |
33 | |
34 | #include "editor/editor_inspector.h" |
35 | #include "editor/editor_plugin.h" |
36 | #include "scene/gui/box_container.h" |
37 | #include "scene/gui/button.h" |
38 | #include "scene/gui/check_box.h" |
39 | #include "scene/gui/control.h" |
40 | #include "scene/gui/label.h" |
41 | #include "scene/gui/margin_container.h" |
42 | #include "scene/gui/option_button.h" |
43 | #include "scene/gui/panel_container.h" |
44 | #include "scene/gui/popup.h" |
45 | #include "scene/gui/separator.h" |
46 | #include "scene/gui/texture_rect.h" |
47 | |
48 | class EditorSelection; |
49 | class GridContainer; |
50 | |
51 | // Inspector controls. |
52 | class ControlPositioningWarning : public MarginContainer { |
53 | GDCLASS(ControlPositioningWarning, MarginContainer); |
54 | |
55 | Control *control_node = nullptr; |
56 | |
57 | PanelContainer *bg_panel = nullptr; |
58 | GridContainer *grid = nullptr; |
59 | TextureRect *title_icon = nullptr; |
60 | TextureRect *hint_icon = nullptr; |
61 | Label *title_label = nullptr; |
62 | Label *hint_label = nullptr; |
63 | Control *hint_filler_left = nullptr; |
64 | Control *hint_filler_right = nullptr; |
65 | |
66 | void _update_warning(); |
67 | void _update_toggler(); |
68 | virtual void gui_input(const Ref<InputEvent> &p_event) override; |
69 | |
70 | protected: |
71 | void _notification(int p_notification); |
72 | |
73 | public: |
74 | void set_control(Control *p_node); |
75 | |
76 | ControlPositioningWarning(); |
77 | }; |
78 | |
79 | class EditorPropertyAnchorsPreset : public EditorProperty { |
80 | GDCLASS(EditorPropertyAnchorsPreset, EditorProperty); |
81 | OptionButton *options = nullptr; |
82 | |
83 | void _option_selected(int p_which); |
84 | |
85 | protected: |
86 | virtual void _set_read_only(bool p_read_only) override; |
87 | |
88 | public: |
89 | void setup(const Vector<String> &p_options); |
90 | virtual void update_property() override; |
91 | EditorPropertyAnchorsPreset(); |
92 | }; |
93 | |
94 | class EditorPropertySizeFlags : public EditorProperty { |
95 | GDCLASS(EditorPropertySizeFlags, EditorProperty); |
96 | |
97 | enum FlagPreset { |
98 | SIZE_FLAGS_PRESET_FILL, |
99 | SIZE_FLAGS_PRESET_SHRINK_BEGIN, |
100 | SIZE_FLAGS_PRESET_SHRINK_CENTER, |
101 | SIZE_FLAGS_PRESET_SHRINK_END, |
102 | SIZE_FLAGS_PRESET_CUSTOM, |
103 | }; |
104 | |
105 | OptionButton *flag_presets = nullptr; |
106 | CheckBox *flag_expand = nullptr; |
107 | VBoxContainer *flag_options = nullptr; |
108 | Vector<CheckBox *> flag_checks; |
109 | |
110 | bool vertical = false; |
111 | |
112 | bool keep_selected_preset = false; |
113 | |
114 | void _preset_selected(int p_which); |
115 | void _expand_toggled(); |
116 | void _flag_toggled(); |
117 | |
118 | protected: |
119 | virtual void _set_read_only(bool p_read_only) override; |
120 | |
121 | public: |
122 | void setup(const Vector<String> &p_options, bool p_vertical); |
123 | virtual void update_property() override; |
124 | EditorPropertySizeFlags(); |
125 | }; |
126 | |
127 | class EditorInspectorPluginControl : public EditorInspectorPlugin { |
128 | GDCLASS(EditorInspectorPluginControl, EditorInspectorPlugin); |
129 | |
130 | public: |
131 | virtual bool can_handle(Object *p_object) override; |
132 | virtual void parse_group(Object *p_object, const String &p_group) override; |
133 | virtual bool parse_property(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint, const String &p_hint_text, const BitField<PropertyUsageFlags> p_usage, const bool p_wide = false) override; |
134 | }; |
135 | |
136 | // Toolbar controls. |
137 | class : public Button { |
138 | GDCLASS(ControlEditorPopupButton, Button); |
139 | |
140 | Ref<Texture2D> ; |
141 | |
142 | PopupPanel * = nullptr; |
143 | VBoxContainer * = nullptr; |
144 | |
145 | void (bool p_visible); |
146 | |
147 | protected: |
148 | void (int p_what); |
149 | |
150 | public: |
151 | virtual Size2 () const override; |
152 | virtual void (bool p_pressed) override; |
153 | |
154 | VBoxContainer *() const { return popup_vbox; } |
155 | |
156 | (); |
157 | }; |
158 | |
159 | class ControlEditorPresetPicker : public MarginContainer { |
160 | GDCLASS(ControlEditorPresetPicker, MarginContainer); |
161 | |
162 | virtual void _preset_button_pressed(const int p_preset) {} |
163 | |
164 | protected: |
165 | static constexpr int grid_separation = 0; |
166 | HashMap<int, Button *> preset_buttons; |
167 | |
168 | void _add_row_button(HBoxContainer *p_row, const int p_preset, const String &p_name); |
169 | void _add_separator(BoxContainer *p_box, Separator *p_separator); |
170 | |
171 | public: |
172 | ControlEditorPresetPicker() {} |
173 | }; |
174 | |
175 | class AnchorPresetPicker : public ControlEditorPresetPicker { |
176 | GDCLASS(AnchorPresetPicker, ControlEditorPresetPicker); |
177 | |
178 | virtual void _preset_button_pressed(const int p_preset) override; |
179 | |
180 | protected: |
181 | void _notification(int p_notification); |
182 | static void _bind_methods(); |
183 | |
184 | public: |
185 | AnchorPresetPicker(); |
186 | }; |
187 | |
188 | class SizeFlagPresetPicker : public ControlEditorPresetPicker { |
189 | GDCLASS(SizeFlagPresetPicker, ControlEditorPresetPicker); |
190 | |
191 | CheckBox *expand_button = nullptr; |
192 | |
193 | bool vertical = false; |
194 | |
195 | virtual void _preset_button_pressed(const int p_preset) override; |
196 | |
197 | protected: |
198 | void _notification(int p_notification); |
199 | static void _bind_methods(); |
200 | |
201 | public: |
202 | void set_allowed_flags(Vector<SizeFlags> &p_flags); |
203 | |
204 | SizeFlagPresetPicker(bool p_vertical); |
205 | }; |
206 | |
207 | class ControlEditorToolbar : public HBoxContainer { |
208 | GDCLASS(ControlEditorToolbar, HBoxContainer); |
209 | |
210 | EditorSelection *editor_selection = nullptr; |
211 | |
212 | ControlEditorPopupButton *anchors_button = nullptr; |
213 | ControlEditorPopupButton *containers_button = nullptr; |
214 | Button *anchor_mode_button = nullptr; |
215 | |
216 | SizeFlagPresetPicker *container_h_picker = nullptr; |
217 | SizeFlagPresetPicker *container_v_picker = nullptr; |
218 | |
219 | bool anchors_mode = false; |
220 | |
221 | void _anchors_preset_selected(int p_preset); |
222 | void _anchors_to_current_ratio(); |
223 | void _anchor_mode_toggled(bool p_status); |
224 | void _container_flags_selected(int p_flags, bool p_vertical); |
225 | |
226 | Vector2 _position_to_anchor(const Control *p_control, Vector2 position); |
227 | bool _is_node_locked(const Node *p_node); |
228 | List<Control *> _get_edited_controls(); |
229 | void _selection_changed(); |
230 | |
231 | protected: |
232 | void _notification(int p_notification); |
233 | |
234 | static ControlEditorToolbar *singleton; |
235 | |
236 | public: |
237 | bool is_anchors_mode_enabled() { return anchors_mode; }; |
238 | |
239 | static ControlEditorToolbar *get_singleton() { return singleton; } |
240 | |
241 | ControlEditorToolbar(); |
242 | }; |
243 | |
244 | // Editor plugin. |
245 | class ControlEditorPlugin : public EditorPlugin { |
246 | GDCLASS(ControlEditorPlugin, EditorPlugin); |
247 | |
248 | ControlEditorToolbar *toolbar = nullptr; |
249 | |
250 | public: |
251 | virtual String get_name() const override { return "Control" ; } |
252 | |
253 | ControlEditorPlugin(); |
254 | }; |
255 | |
256 | #endif // CONTROL_EDITOR_PLUGIN_H |
257 | |