1 /*************************************************************************/ 2 /* canvas_item_editor_plugin.h */ 3 /*************************************************************************/ 4 /* This file is part of: */ 5 /* GODOT ENGINE */ 6 /* https://godotengine.org */ 7 /*************************************************************************/ 8 /* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ 9 /* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ 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 #ifndef CONTROL_EDITOR_PLUGIN_H 31 #define CONTROL_EDITOR_PLUGIN_H 32 33 #include "editor/editor_node.h" 34 #include "editor/editor_plugin.h" 35 #include "scene/2d/canvas_item.h" 36 #include "scene/gui/box_container.h" 37 #include "scene/gui/button_group.h" 38 #include "scene/gui/check_box.h" 39 #include "scene/gui/label.h" 40 #include "scene/gui/panel_container.h" 41 #include "scene/gui/spin_box.h" 42 /** 43 @author Juan Linietsky <reduzio@gmail.com> 44 */ 45 46 class CanvasItemEditorViewport; 47 48 class CanvasItemEditorSelectedItem : public Object { 49 50 OBJ_TYPE(CanvasItemEditorSelectedItem, Object); 51 52 public: 53 Variant undo_state; 54 Vector2 undo_pivot; 55 56 Matrix32 prev_xform; 57 float prev_rot; 58 Rect2 prev_rect; 59 CanvasItemEditorSelectedItem()60 CanvasItemEditorSelectedItem() { prev_rot = 0; } 61 }; 62 63 class CanvasItemEditor : public VBoxContainer { 64 65 OBJ_TYPE(CanvasItemEditor, VBoxContainer); 66 67 EditorNode *editor; 68 69 enum Tool { 70 71 TOOL_SELECT, 72 TOOL_LIST_SELECT, 73 TOOL_MOVE, 74 TOOL_ROTATE, 75 TOOL_EDIT_PIVOT, 76 TOOL_PAN, 77 TOOL_MAX 78 }; 79 80 enum MenuOption { 81 SNAP_USE, 82 SNAP_SHOW_GRID, 83 SNAP_USE_ROTATION, 84 SNAP_RELATIVE, 85 SNAP_CONFIGURE, 86 SNAP_USE_PIXEL, 87 ZOOM_IN, 88 ZOOM_OUT, 89 ZOOM_RESET, 90 ZOOM_SET, 91 LOCK_SELECTED, 92 UNLOCK_SELECTED, 93 GROUP_SELECTED, 94 UNGROUP_SELECTED, 95 ALIGN_HORIZONTAL, 96 ALIGN_VERTICAL, 97 ANCHOR_ALIGN_TOP_LEFT, 98 ANCHOR_ALIGN_TOP_RIGHT, 99 ANCHOR_ALIGN_BOTTOM_LEFT, 100 ANCHOR_ALIGN_BOTTOM_RIGHT, 101 ANCHOR_ALIGN_CENTER_LEFT, 102 ANCHOR_ALIGN_CENTER_RIGHT, 103 ANCHOR_ALIGN_CENTER_TOP, 104 ANCHOR_ALIGN_CENTER_BOTTOM, 105 ANCHOR_ALIGN_CENTER, 106 ANCHOR_ALIGN_TOP_WIDE, 107 ANCHOR_ALIGN_LEFT_WIDE, 108 ANCHOR_ALIGN_RIGHT_WIDE, 109 ANCHOR_ALIGN_BOTTOM_WIDE, 110 ANCHOR_ALIGN_VCENTER_WIDE, 111 ANCHOR_ALIGN_HCENTER_WIDE, 112 ANCHOR_ALIGN_WIDE, 113 114 SPACE_HORIZONTAL, 115 SPACE_VERTICAL, 116 EXPAND_TO_PARENT, 117 ANIM_INSERT_KEY, 118 ANIM_INSERT_KEY_EXISTING, 119 ANIM_INSERT_POS, 120 ANIM_INSERT_ROT, 121 ANIM_INSERT_SCALE, 122 ANIM_COPY_POSE, 123 ANIM_PASTE_POSE, 124 ANIM_CLEAR_POSE, 125 VIEW_CENTER_TO_SELECTION, 126 VIEW_FRAME_TO_SELECTION, 127 SKELETON_MAKE_BONES, 128 SKELETON_CLEAR_BONES, 129 SKELETON_SET_IK_CHAIN, 130 SKELETON_CLEAR_IK_CHAIN 131 132 }; 133 134 enum DragType { 135 DRAG_NONE, 136 DRAG_LEFT, 137 DRAG_TOP_LEFT, 138 DRAG_TOP, 139 DRAG_TOP_RIGHT, 140 DRAG_RIGHT, 141 DRAG_BOTTOM_RIGHT, 142 DRAG_BOTTOM, 143 DRAG_BOTTOM_LEFT, 144 DRAG_ALL, 145 DRAG_ROTATE, 146 DRAG_PIVOT, 147 DRAG_NODE_2D, 148 149 }; 150 151 enum KeyMoveMODE { 152 MOVE_VIEW_BASE, 153 MOVE_LOCAL_BASE, 154 MOVE_LOCAL_WITH_ROT 155 }; 156 157 EditorSelection *editor_selection; 158 bool additive_selection; 159 160 Tool tool; 161 bool first_update; 162 Control *viewport; 163 164 bool can_move_pivot; 165 166 HScrollBar *h_scroll; 167 VScrollBar *v_scroll; 168 HBoxContainer *hb; 169 170 Matrix32 transform; 171 float zoom; 172 Vector2 snap_offset; 173 Vector2 snap_step; 174 float snap_rotation_step; 175 float snap_rotation_offset; 176 bool snap_grid; 177 bool snap_show_grid; 178 bool snap_rotation; 179 bool snap_relative; 180 bool snap_pixel; 181 bool box_selecting; 182 Point2 box_selecting_to; 183 bool key_pos; 184 bool key_rot; 185 bool key_scale; 186 187 void _tool_select(int p_index); 188 189 MenuOption last_option; 190 191 struct _SelectResult { 192 193 CanvasItem *item; 194 float z; 195 bool has_z; 196 _FORCE_INLINE_ bool operator<(const _SelectResult &p_rr) const { 197 return has_z && p_rr.has_z ? p_rr.z < z : p_rr.has_z; 198 } 199 }; 200 201 Vector<_SelectResult> selection_results; 202 203 struct LockList { 204 Point2 pos; 205 bool lock; 206 bool group; LockListLockList207 LockList() { 208 lock = false; 209 group = false; 210 } 211 }; 212 213 List<LockList> lock_list; 214 215 struct BoneList { 216 217 Matrix32 xform; 218 Vector2 from; 219 Vector2 to; 220 ObjectID bone; 221 uint64_t last_pass; 222 }; 223 224 uint64_t bone_last_frame; 225 Map<ObjectID, BoneList> bone_list; 226 227 Matrix32 bone_orig_xform; 228 229 struct BoneIK { 230 231 Variant orig_state; 232 Vector2 pos; 233 float len; 234 Node2D *node; 235 }; 236 237 List<BoneIK> bone_ik_list; 238 239 struct PoseClipboard { 240 241 Vector2 pos; 242 Vector2 scale; 243 float rot; 244 ObjectID id; 245 }; 246 247 List<PoseClipboard> pose_clipboard; 248 249 ToolButton *select_button; 250 ToolButton *list_select_button; 251 ToolButton *move_button; 252 ToolButton *rotate_button; 253 254 ToolButton *pivot_button; 255 ToolButton *pan_button; 256 257 ToolButton *lock_button; 258 ToolButton *unlock_button; 259 260 ToolButton *group_button; 261 ToolButton *ungroup_button; 262 263 MenuButton *edit_menu; 264 MenuButton *view_menu; 265 HBoxContainer *animation_hb; 266 MenuButton *animation_menu; 267 MenuButton *anchor_menu; 268 269 Button *key_loc_button; 270 Button *key_rot_button; 271 Button *key_scale_button; 272 Button *key_insert_button; 273 274 PopupMenu *selection_menu; 275 276 //PopupMenu *popup; 277 DragType drag; 278 Point2 drag_from; 279 Point2 drag_point_from; 280 bool updating_value_dialog; 281 Point2 display_rotate_from; 282 Point2 display_rotate_to; 283 #if 0 284 struct EditInfo { 285 286 Variant undo_state; 287 288 Matrix32 prev_xform; 289 float prev_rot; 290 Rect2 prev_rect; 291 EditInfo() { prev_rot=0; } 292 }; 293 294 typedef Map<CanvasItem*,EditInfo> CanvasItemMap; 295 CanvasItemMap canvas_items; 296 #endif 297 Ref<StyleBoxTexture> select_sb; 298 Ref<Texture> select_handle; 299 300 int handle_len; 301 bool _is_part_of_subscene(CanvasItem *p_item); 302 CanvasItem *_select_canvas_item_at_pos(const Point2 &p_pos, Node *p_node, const Matrix32 &p_parent_xform, const Matrix32 &p_canvas_xform); 303 void _find_canvas_items_at_pos(const Point2 &p_pos, Node *p_node, const Matrix32 &p_parent_xform, const Matrix32 &p_canvas_xform, Vector<_SelectResult> &r_items); 304 void _find_canvas_items_at_rect(const Rect2 &p_rect, Node *p_node, const Matrix32 &p_parent_xform, const Matrix32 &p_canvas_xform, List<CanvasItem *> *r_items); 305 306 bool _select(CanvasItem *item, Point2 p_click_pos, bool p_append, bool p_drag = true); 307 308 ConfirmationDialog *snap_dialog; 309 310 AcceptDialog *value_dialog; 311 Label *dialog_label; 312 SpinBox *dialog_val; 313 314 CanvasItem *ref_item; 315 316 void _edit_set_pivot(const Vector2 &mouse_pos); 317 void _add_canvas_item(CanvasItem *p_canvas_item); 318 void _remove_canvas_item(CanvasItem *p_canvas_item); 319 void _clear_canvas_items(); 320 void _visibility_changed(ObjectID p_canvas_item); 321 void _key_move(const Vector2 &p_dir, bool p_snap, KeyMoveMODE p_move_mode); 322 void _list_select(const InputEventMouseButton &b); 323 324 DragType _find_drag_type(const Matrix32 &p_xform, const Rect2 &p_local_rect, const Point2 &p_click, Vector2 &r_point); 325 void _prepare_drag(const Point2 &p_click_pos); 326 327 void _popup_callback(int p_op); 328 bool updating_scroll; 329 void _update_scroll(float); 330 void _update_scrollbars(); 331 void incbeg(float &beg, float &end, float inc, float minsize, bool p_symmetric); 332 void incend(float &beg, float &end, float inc, float minsize, bool p_symmetric); 333 334 void _append_canvas_item(CanvasItem *p_item); 335 void _dialog_value_changed(double); 336 void _snap_changed(); 337 void _selection_result_pressed(int); 338 void _selection_menu_hide(); 339 340 UndoRedo *undo_redo; 341 342 Point2 _find_topleftmost_point(); 343 344 void _find_canvas_items_span(Node *p_node, Rect2 &r_rect, const Matrix32 &p_xform); 345 346 Object *_get_editor_data(Object *p_what); 347 348 CanvasItem *get_single_item(); 349 int get_item_count(); 350 void _keying_changed(); 351 352 void _unhandled_key_input(const InputEvent &p_ev); 353 354 void _viewport_input_event(const InputEvent &p_event); 355 void _viewport_draw(); 356 357 void _set_anchor(Control::AnchorType p_left, Control::AnchorType p_top, Control::AnchorType p_right, Control::AnchorType p_bottom); 358 359 HSplitContainer *palette_split; 360 VSplitContainer *bottom_split; 361 362 friend class CanvasItemEditorPlugin; 363 364 protected: 365 void _notification(int p_what); 366 367 void _node_removed(Node *p_node); 368 static void _bind_methods(); 369 void end_drag(); 370 void box_selection_start(Point2 &click); 371 bool box_selection_end(); 372 get_panel_hb()373 HBoxContainer *get_panel_hb() { return hb; } 374 375 struct compare_items_x { operatorcompare_items_x376 bool operator()(const CanvasItem *a, const CanvasItem *b) const { 377 return a->get_global_transform().elements[2].x < b->get_global_transform().elements[2].x; 378 } 379 }; 380 381 struct compare_items_y { operatorcompare_items_y382 bool operator()(const CanvasItem *a, const CanvasItem *b) const { 383 return a->get_global_transform().elements[2].y < b->get_global_transform().elements[2].y; 384 } 385 }; 386 387 struct proj_vector2_x { getproj_vector2_x388 float get(const Vector2 &v) { return v.x; } setproj_vector2_x389 void set(Vector2 &v, float f) { v.x = f; } 390 }; 391 392 struct proj_vector2_y { getproj_vector2_y393 float get(const Vector2 &v) { return v.y; } setproj_vector2_y394 void set(Vector2 &v, float f) { v.y = f; } 395 }; 396 397 template <class P, class C> 398 void space_selected_items(); 399 400 static CanvasItemEditor *singleton; 401 402 public: 403 Vector2 snap_point(Vector2 p_target, Vector2 p_start = Vector2(0, 0)) const; 404 float snap_angle(float p_target, float p_start = 0) const; 405 get_canvas_transform()406 Matrix32 get_canvas_transform() const { return transform; } 407 get_singleton()408 static CanvasItemEditor *get_singleton() { return singleton; } 409 Dictionary get_state() const; 410 void set_state(const Dictionary &p_state); 411 412 void add_control_to_menu_panel(Control *p_control); 413 414 HSplitContainer *get_palette_split(); 415 VSplitContainer *get_bottom_split(); 416 get_viewport_control()417 Control *get_viewport_control() { return viewport; } 418 419 bool get_remove_list(List<Node *> *p_list); set_undo_redo(UndoRedo * p_undo_redo)420 void set_undo_redo(UndoRedo *p_undo_redo) { undo_redo = p_undo_redo; } 421 void edit(CanvasItem *p_canvas_item); 422 CanvasItemEditor(EditorNode *p_editor); 423 }; 424 425 class CanvasItemEditorPlugin : public EditorPlugin { 426 427 OBJ_TYPE(CanvasItemEditorPlugin, EditorPlugin); 428 429 CanvasItemEditor *canvas_item_editor; 430 EditorNode *editor; 431 432 public: get_name()433 virtual String get_name() const { return "2D"; } has_main_screen()434 bool has_main_screen() const { return true; } 435 virtual void edit(Object *p_object); 436 virtual bool handles(Object *p_object) const; 437 virtual void make_visible(bool p_visible); get_remove_list(List<Node * > * p_list)438 virtual bool get_remove_list(List<Node *> *p_list) { return canvas_item_editor->get_remove_list(p_list); } 439 virtual Dictionary get_state() const; 440 virtual void set_state(const Dictionary &p_state); 441 get_canvas_item_editor()442 CanvasItemEditor *get_canvas_item_editor() { return canvas_item_editor; } 443 444 CanvasItemEditorPlugin(EditorNode *p_node); 445 ~CanvasItemEditorPlugin(); 446 }; 447 448 class CanvasItemEditorViewport : public Control { 449 OBJ_TYPE(CanvasItemEditorViewport, Control); 450 451 String default_type; 452 Vector<String> types; 453 454 Vector<String> selected_files; 455 Node *target_node; 456 Point2 drop_pos; 457 458 EditorNode *editor; 459 EditorData *editor_data; 460 CanvasItemEditor *canvas; 461 Node2D *preview; 462 AcceptDialog *accept; 463 WindowDialog *selector; 464 Label *selector_label; 465 Label *label; 466 Label *label_desc; 467 ButtonGroup *btn_group; 468 469 void _on_mouse_exit(); 470 void _on_select_type(Object *selected); 471 void _on_change_type(); 472 473 void _create_preview(const Vector<String> &files) const; 474 void _remove_preview(); 475 476 bool _cyclical_dependency_exists(const String &p_target_scene_path, Node *p_desired_node); 477 void _create_nodes(Node *parent, Node *child, String &path, const Point2 &p_point); 478 bool _create_instance(Node *parent, String &path, const Point2 &p_point); 479 void _perform_drop_data(); 480 481 static void _bind_methods(); 482 483 protected: 484 void _notification(int p_what); 485 486 public: 487 virtual bool can_drop_data(const Point2 &p_point, const Variant &p_data) const; 488 virtual void drop_data(const Point2 &p_point, const Variant &p_data); 489 490 CanvasItemEditorViewport(EditorNode *p_node, CanvasItemEditor *p_canvas); 491 }; 492 493 #endif 494