polygon_2d_editor_plugin.cpp 54 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487
  1. /**************************************************************************/
  2. /* polygon_2d_editor_plugin.cpp */
  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. #include "polygon_2d_editor_plugin.h"
  31. #include "core/input/input_event.h"
  32. #include "core/math/geometry_2d.h"
  33. #include "editor/editor_command_palette.h"
  34. #include "editor/editor_node.h"
  35. #include "editor/editor_settings.h"
  36. #include "editor/editor_undo_redo_manager.h"
  37. #include "editor/gui/editor_bottom_panel.h"
  38. #include "editor/gui/editor_zoom_widget.h"
  39. #include "editor/plugins/canvas_item_editor_plugin.h"
  40. #include "editor/themes/editor_scale.h"
  41. #include "scene/2d/skeleton_2d.h"
  42. #include "scene/gui/check_box.h"
  43. #include "scene/gui/dialogs.h"
  44. #include "scene/gui/label.h"
  45. #include "scene/gui/menu_button.h"
  46. #include "scene/gui/panel.h"
  47. #include "scene/gui/scroll_container.h"
  48. #include "scene/gui/separator.h"
  49. #include "scene/gui/slider.h"
  50. #include "scene/gui/spin_box.h"
  51. #include "scene/gui/split_container.h"
  52. #include "scene/gui/view_panner.h"
  53. Node2D *Polygon2DEditor::_get_node() const {
  54. return node;
  55. }
  56. void Polygon2DEditor::_set_node(Node *p_polygon) {
  57. CanvasItem *draw = Object::cast_to<CanvasItem>(canvas);
  58. if (node) {
  59. node->disconnect(SceneStringName(draw), callable_mp(draw, &CanvasItem::queue_redraw));
  60. node->disconnect(SceneStringName(draw), callable_mp(this, &Polygon2DEditor::_update_available_modes));
  61. }
  62. node = Object::cast_to<Polygon2D>(p_polygon);
  63. _update_polygon_editing_state();
  64. canvas->queue_redraw();
  65. if (node) {
  66. canvas->set_texture_filter(node->get_texture_filter_in_tree());
  67. _update_bone_list();
  68. _update_available_modes();
  69. if (current_mode == MODE_MAX) {
  70. _select_mode(MODE_POINTS); // Initialize when opening the first time.
  71. }
  72. if (previous_node != node) {
  73. _center_view_on_draw();
  74. }
  75. previous_node = node;
  76. // Whenever polygon gets redrawn, there's possible changes for the editor as well.
  77. node->connect(SceneStringName(draw), callable_mp(draw, &CanvasItem::queue_redraw));
  78. node->connect(SceneStringName(draw), callable_mp(this, &Polygon2DEditor::_update_available_modes));
  79. }
  80. }
  81. Vector2 Polygon2DEditor::_get_offset(int p_idx) const {
  82. return node->get_offset();
  83. }
  84. int Polygon2DEditor::_get_polygon_count() const {
  85. if (node->get_internal_vertex_count() > 0) {
  86. return 0; //do not edit if internal vertices exist
  87. } else {
  88. return 1;
  89. }
  90. }
  91. void Polygon2DEditor::_notification(int p_what) {
  92. switch (p_what) {
  93. case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
  94. if (!EditorSettings::get_singleton()->check_changed_settings_in_group("editors/panning")) {
  95. break;
  96. }
  97. [[fallthrough]];
  98. }
  99. case NOTIFICATION_ENTER_TREE: {
  100. panner->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/sub_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EDITOR_GET("editors/panning/simple_panning")));
  101. panner->setup_warped_panning(get_viewport(), EDITOR_GET("editors/panning/warped_mouse_panning"));
  102. } break;
  103. case NOTIFICATION_READY: {
  104. action_buttons[ACTION_CREATE]->set_button_icon(get_editor_theme_icon(SNAME("Edit")));
  105. action_buttons[ACTION_CREATE_INTERNAL]->set_button_icon(get_editor_theme_icon(SNAME("EditInternal")));
  106. action_buttons[ACTION_REMOVE_INTERNAL]->set_button_icon(get_editor_theme_icon(SNAME("RemoveInternal")));
  107. action_buttons[ACTION_EDIT_POINT]->set_button_icon(get_editor_theme_icon(SNAME("ToolSelect")));
  108. action_buttons[ACTION_MOVE]->set_button_icon(get_editor_theme_icon(SNAME("ToolMove")));
  109. action_buttons[ACTION_ROTATE]->set_button_icon(get_editor_theme_icon(SNAME("ToolRotate")));
  110. action_buttons[ACTION_SCALE]->set_button_icon(get_editor_theme_icon(SNAME("ToolScale")));
  111. action_buttons[ACTION_ADD_POLYGON]->set_button_icon(get_editor_theme_icon(SNAME("Edit")));
  112. action_buttons[ACTION_REMOVE_POLYGON]->set_button_icon(get_editor_theme_icon(SNAME("Close")));
  113. action_buttons[ACTION_PAINT_WEIGHT]->set_button_icon(get_editor_theme_icon(SNAME("Bucket")));
  114. action_buttons[ACTION_CLEAR_WEIGHT]->set_button_icon(get_editor_theme_icon(SNAME("Clear")));
  115. b_snap_grid->set_button_icon(get_editor_theme_icon(SNAME("Grid")));
  116. b_snap_enable->set_button_icon(get_editor_theme_icon(SNAME("SnapGrid")));
  117. vscroll->set_anchors_and_offsets_preset(PRESET_RIGHT_WIDE);
  118. hscroll->set_anchors_and_offsets_preset(PRESET_BOTTOM_WIDE);
  119. // Avoid scrollbar overlapping.
  120. Size2 hmin = hscroll->get_combined_minimum_size();
  121. Size2 vmin = vscroll->get_combined_minimum_size();
  122. hscroll->set_anchor_and_offset(SIDE_RIGHT, ANCHOR_END, -vmin.width);
  123. vscroll->set_anchor_and_offset(SIDE_BOTTOM, ANCHOR_END, -hmin.height);
  124. [[fallthrough]];
  125. }
  126. case NOTIFICATION_THEME_CHANGED: {
  127. canvas->add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SceneStringName(panel), SNAME("Tree")));
  128. bone_scroll->add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SceneStringName(panel), SNAME("Tree")));
  129. } break;
  130. case NOTIFICATION_VISIBILITY_CHANGED: {
  131. if (is_visible()) {
  132. dock_button->show();
  133. EditorNode::get_bottom_panel()->make_item_visible(polygon_edit);
  134. } else {
  135. dock_button->hide();
  136. if (polygon_edit->is_visible_in_tree()) {
  137. EditorNode::get_bottom_panel()->hide_bottom_panel();
  138. }
  139. }
  140. } break;
  141. }
  142. }
  143. void Polygon2DEditor::_sync_bones() {
  144. Skeleton2D *skeleton = nullptr;
  145. if (!node->has_node(node->get_skeleton())) {
  146. error->set_text(TTR("The skeleton property of the Polygon2D does not point to a Skeleton2D node"));
  147. error->popup_centered();
  148. } else {
  149. Node *sn = node->get_node(node->get_skeleton());
  150. skeleton = Object::cast_to<Skeleton2D>(sn);
  151. }
  152. Array prev_bones = node->call("_get_bones");
  153. node->clear_bones();
  154. if (!skeleton) {
  155. error->set_text(TTR("The skeleton property of the Polygon2D does not point to a Skeleton2D node"));
  156. error->popup_centered();
  157. } else {
  158. for (int i = 0; i < skeleton->get_bone_count(); i++) {
  159. NodePath path = skeleton->get_path_to(skeleton->get_bone(i));
  160. Vector<float> weights;
  161. int wc = node->get_polygon().size();
  162. for (int j = 0; j < prev_bones.size(); j += 2) {
  163. NodePath pvp = prev_bones[j];
  164. Vector<float> pv = prev_bones[j + 1];
  165. if (pvp == path && pv.size() == wc) {
  166. weights = pv;
  167. }
  168. }
  169. if (weights.size() == 0) { //create them
  170. weights.resize(wc);
  171. float *w = weights.ptrw();
  172. for (int j = 0; j < wc; j++) {
  173. w[j] = 0.0;
  174. }
  175. }
  176. node->add_bone(path, weights);
  177. }
  178. }
  179. Array new_bones = node->call("_get_bones");
  180. EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
  181. undo_redo->create_action(TTR("Sync Bones"));
  182. undo_redo->add_do_method(node, "_set_bones", new_bones);
  183. undo_redo->add_undo_method(node, "_set_bones", prev_bones);
  184. undo_redo->add_do_method(this, "_update_bone_list");
  185. undo_redo->add_undo_method(this, "_update_bone_list");
  186. undo_redo->commit_action();
  187. }
  188. void Polygon2DEditor::_update_bone_list() {
  189. NodePath selected;
  190. while (bone_scroll_vb->get_child_count()) {
  191. CheckBox *cb = Object::cast_to<CheckBox>(bone_scroll_vb->get_child(0));
  192. if (cb && cb->is_pressed()) {
  193. selected = cb->get_meta("bone_path");
  194. }
  195. memdelete(bone_scroll_vb->get_child(0));
  196. }
  197. Ref<ButtonGroup> bg;
  198. bg.instantiate();
  199. for (int i = 0; i < node->get_bone_count(); i++) {
  200. CheckBox *cb = memnew(CheckBox);
  201. NodePath np = node->get_bone_path(i);
  202. String name;
  203. if (np.get_name_count()) {
  204. name = np.get_name(np.get_name_count() - 1);
  205. }
  206. if (name.is_empty()) {
  207. name = "Bone " + itos(i);
  208. }
  209. cb->set_text(name);
  210. cb->set_button_group(bg);
  211. cb->set_meta("bone_path", np);
  212. cb->set_focus_mode(FOCUS_NONE);
  213. bone_scroll_vb->add_child(cb);
  214. if (np == selected || bone_scroll_vb->get_child_count() < 2) {
  215. cb->set_pressed(true);
  216. }
  217. cb->connect(SceneStringName(pressed), callable_mp(this, &Polygon2DEditor::_bone_paint_selected).bind(i));
  218. }
  219. canvas->queue_redraw();
  220. }
  221. void Polygon2DEditor::_bone_paint_selected(int p_index) {
  222. canvas->queue_redraw();
  223. }
  224. void Polygon2DEditor::_select_mode(int p_mode) {
  225. current_mode = Mode(p_mode);
  226. mode_buttons[current_mode]->set_pressed(true);
  227. for (int i = 0; i < ACTION_MAX; i++) {
  228. action_buttons[i]->hide();
  229. }
  230. bone_scroll_main_vb->hide();
  231. bone_paint_strength->hide();
  232. bone_paint_radius->hide();
  233. bone_paint_radius_label->hide();
  234. switch (current_mode) {
  235. case MODE_POINTS: {
  236. action_buttons[ACTION_CREATE]->show();
  237. action_buttons[ACTION_CREATE_INTERNAL]->show();
  238. action_buttons[ACTION_REMOVE_INTERNAL]->show();
  239. action_buttons[ACTION_EDIT_POINT]->show();
  240. action_buttons[ACTION_MOVE]->show();
  241. action_buttons[ACTION_ROTATE]->show();
  242. action_buttons[ACTION_SCALE]->show();
  243. if (node->get_polygon().is_empty()) {
  244. _set_action(ACTION_CREATE);
  245. } else {
  246. _set_action(ACTION_EDIT_POINT);
  247. }
  248. } break;
  249. case MODE_POLYGONS: {
  250. action_buttons[ACTION_ADD_POLYGON]->show();
  251. action_buttons[ACTION_REMOVE_POLYGON]->show();
  252. _set_action(ACTION_ADD_POLYGON);
  253. } break;
  254. case MODE_UV: {
  255. if (node->get_uv().size() != node->get_polygon().size()) {
  256. _edit_menu_option(MENU_POLYGON_TO_UV);
  257. }
  258. action_buttons[ACTION_EDIT_POINT]->show();
  259. action_buttons[ACTION_MOVE]->show();
  260. action_buttons[ACTION_ROTATE]->show();
  261. action_buttons[ACTION_SCALE]->show();
  262. _set_action(ACTION_EDIT_POINT);
  263. } break;
  264. case MODE_BONES: {
  265. action_buttons[ACTION_PAINT_WEIGHT]->show();
  266. action_buttons[ACTION_CLEAR_WEIGHT]->show();
  267. _set_action(ACTION_PAINT_WEIGHT);
  268. bone_scroll_main_vb->show();
  269. bone_paint_strength->show();
  270. bone_paint_radius->show();
  271. bone_paint_radius_label->show();
  272. _update_bone_list();
  273. bone_paint_pos = Vector2(-100000, -100000); // Send brush away when switching.
  274. } break;
  275. default:
  276. break;
  277. }
  278. canvas->queue_redraw();
  279. }
  280. void Polygon2DEditor::_edit_menu_option(int p_option) {
  281. EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
  282. switch (p_option) {
  283. case MENU_POLYGON_TO_UV: {
  284. Vector<Vector2> points = node->get_polygon();
  285. if (points.size() == 0) {
  286. break;
  287. }
  288. Vector<Vector2> uvs = node->get_uv();
  289. undo_redo->create_action(TTR("Create UV Map"));
  290. undo_redo->add_do_method(node, "set_uv", points);
  291. undo_redo->add_undo_method(node, "set_uv", uvs);
  292. undo_redo->commit_action();
  293. } break;
  294. case MENU_UV_TO_POLYGON: {
  295. Vector<Vector2> points = node->get_polygon();
  296. Vector<Vector2> uvs = node->get_uv();
  297. if (uvs.size() == 0) {
  298. break;
  299. }
  300. undo_redo->create_action(TTR("Create Polygon"));
  301. undo_redo->add_do_method(node, "set_polygon", uvs);
  302. undo_redo->add_undo_method(node, "set_polygon", points);
  303. undo_redo->commit_action();
  304. } break;
  305. case MENU_UV_CLEAR: {
  306. Vector<Vector2> uvs = node->get_uv();
  307. if (uvs.size() == 0) {
  308. break;
  309. }
  310. undo_redo->create_action(TTR("Create UV Map"));
  311. undo_redo->add_do_method(node, "set_uv", Vector<Vector2>());
  312. undo_redo->add_undo_method(node, "set_uv", uvs);
  313. undo_redo->commit_action();
  314. } break;
  315. case MENU_GRID_SETTINGS: {
  316. grid_settings->popup_centered();
  317. } break;
  318. }
  319. }
  320. void Polygon2DEditor::_cancel_editing() {
  321. if (is_creating) {
  322. is_dragging = false;
  323. is_creating = false;
  324. node->set_uv(previous_uv);
  325. node->set_polygon(previous_polygon);
  326. node->set_internal_vertex_count(previous_internal_vertices);
  327. node->set_vertex_colors(previous_colors);
  328. node->call("_set_bones", previous_bones);
  329. node->set_polygons(previous_polygons);
  330. _update_polygon_editing_state();
  331. _update_available_modes();
  332. } else if (is_dragging) {
  333. is_dragging = false;
  334. if (current_mode == MODE_UV) {
  335. node->set_uv(editing_points);
  336. } else if (current_mode == MODE_POINTS) {
  337. node->set_polygon(editing_points);
  338. }
  339. }
  340. polygon_create.clear();
  341. }
  342. void Polygon2DEditor::_update_polygon_editing_state() {
  343. if (!_get_node()) {
  344. return;
  345. }
  346. if (node->get_internal_vertex_count() > 0) {
  347. disable_polygon_editing(true, TTR("Polygon 2D has internal vertices, so it can no longer be edited in the viewport."));
  348. } else {
  349. disable_polygon_editing(false, String());
  350. }
  351. }
  352. void Polygon2DEditor::_commit_action() {
  353. // Makes that undo/redoing actions made outside of the UV editor still affect its polygon.
  354. EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
  355. undo_redo->add_do_method(CanvasItemEditor::get_singleton(), "update_viewport");
  356. undo_redo->add_undo_method(CanvasItemEditor::get_singleton(), "update_viewport");
  357. undo_redo->commit_action();
  358. }
  359. void Polygon2DEditor::_set_use_snap(bool p_use) {
  360. use_snap = p_use;
  361. EditorSettings::get_singleton()->set_project_metadata("polygon_2d_uv_editor", "snap_enabled", p_use);
  362. }
  363. void Polygon2DEditor::_set_show_grid(bool p_show) {
  364. snap_show_grid = p_show;
  365. EditorSettings::get_singleton()->set_project_metadata("polygon_2d_uv_editor", "show_grid", p_show);
  366. canvas->queue_redraw();
  367. }
  368. void Polygon2DEditor::_set_snap_off_x(real_t p_val) {
  369. snap_offset.x = p_val;
  370. EditorSettings::get_singleton()->set_project_metadata("polygon_2d_uv_editor", "snap_offset", snap_offset);
  371. canvas->queue_redraw();
  372. }
  373. void Polygon2DEditor::_set_snap_off_y(real_t p_val) {
  374. snap_offset.y = p_val;
  375. EditorSettings::get_singleton()->set_project_metadata("polygon_2d_uv_editor", "snap_offset", snap_offset);
  376. canvas->queue_redraw();
  377. }
  378. void Polygon2DEditor::_set_snap_step_x(real_t p_val) {
  379. snap_step.x = p_val;
  380. EditorSettings::get_singleton()->set_project_metadata("polygon_2d_uv_editor", "snap_step", snap_step);
  381. canvas->queue_redraw();
  382. }
  383. void Polygon2DEditor::_set_snap_step_y(real_t p_val) {
  384. snap_step.y = p_val;
  385. EditorSettings::get_singleton()->set_project_metadata("polygon_2d_uv_editor", "snap_step", snap_step);
  386. canvas->queue_redraw();
  387. }
  388. void Polygon2DEditor::_set_action(int p_action) {
  389. polygon_create.clear();
  390. is_dragging = false;
  391. is_creating = false;
  392. selected_action = Action(p_action);
  393. for (int i = 0; i < ACTION_MAX; i++) {
  394. action_buttons[i]->set_pressed(p_action == i);
  395. }
  396. canvas->queue_redraw();
  397. }
  398. void Polygon2DEditor::_canvas_input(const Ref<InputEvent> &p_input) {
  399. if (!_get_node()) {
  400. return;
  401. }
  402. if (panner->gui_input(p_input, canvas->get_global_rect())) {
  403. accept_event();
  404. return;
  405. }
  406. Transform2D mtx;
  407. mtx.columns[2] = -draw_offset * draw_zoom;
  408. mtx.scale_basis(Vector2(draw_zoom, draw_zoom));
  409. EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
  410. Ref<InputEventMouseButton> mb = p_input;
  411. if (mb.is_valid()) {
  412. if (mb->get_button_index() == MouseButton::LEFT) {
  413. if (mb->is_pressed()) {
  414. drag_from = snap_point(mb->get_position());
  415. is_dragging = true;
  416. if (current_mode == MODE_UV) {
  417. editing_points = node->get_uv();
  418. } else {
  419. editing_points = node->get_polygon();
  420. }
  421. current_action = selected_action;
  422. if (current_action == ACTION_CREATE) {
  423. if (!is_creating) {
  424. editing_points.clear();
  425. Vector2 tuv = mtx.affine_inverse().xform(snap_point(mb->get_position()));
  426. editing_points.push_back(tuv);
  427. create_to = tuv;
  428. point_drag_index = 0;
  429. drag_from = tuv;
  430. is_dragging = true;
  431. is_creating = true;
  432. previous_uv = node->get_uv();
  433. previous_polygon = node->get_polygon();
  434. previous_internal_vertices = node->get_internal_vertex_count();
  435. previous_colors = node->get_vertex_colors();
  436. previous_bones = node->call("_get_bones");
  437. previous_polygons = node->get_polygons();
  438. disable_polygon_editing(false, String());
  439. node->set_polygon(editing_points);
  440. node->set_uv(editing_points);
  441. node->set_internal_vertex_count(0);
  442. canvas->queue_redraw();
  443. } else {
  444. Vector2 tuv = mtx.affine_inverse().xform(snap_point(mb->get_position()));
  445. // Close the polygon if selected point is near start. Threshold for closing scaled by zoom level
  446. if (editing_points.size() > 2 && tuv.distance_to(editing_points[0]) < (8 / draw_zoom)) {
  447. undo_redo->create_action(TTR("Create Polygon & UV"));
  448. undo_redo->add_do_method(node, "set_uv", node->get_uv());
  449. undo_redo->add_undo_method(node, "set_uv", previous_uv);
  450. undo_redo->add_do_method(node, "set_polygon", node->get_polygon());
  451. undo_redo->add_undo_method(node, "set_polygon", previous_polygon);
  452. undo_redo->add_do_method(node, "set_internal_vertex_count", 0);
  453. undo_redo->add_undo_method(node, "set_internal_vertex_count", previous_internal_vertices);
  454. undo_redo->add_do_method(node, "set_vertex_colors", Vector<Color>());
  455. undo_redo->add_undo_method(node, "set_vertex_colors", previous_colors);
  456. undo_redo->add_do_method(node, "clear_bones");
  457. undo_redo->add_undo_method(node, "_set_bones", previous_bones);
  458. undo_redo->add_do_method(this, "_update_polygon_editing_state");
  459. undo_redo->add_undo_method(this, "_update_polygon_editing_state");
  460. undo_redo->commit_action();
  461. is_dragging = false;
  462. is_creating = false;
  463. _update_available_modes();
  464. _set_action(ACTION_EDIT_POINT);
  465. _menu_option(MODE_EDIT);
  466. } else {
  467. editing_points.push_back(tuv);
  468. point_drag_index = editing_points.size() - 1;
  469. drag_from = tuv;
  470. }
  471. node->set_polygon(editing_points);
  472. node->set_uv(editing_points);
  473. }
  474. CanvasItemEditor::get_singleton()->update_viewport();
  475. }
  476. if (current_action == ACTION_CREATE_INTERNAL) {
  477. previous_uv = node->get_uv();
  478. previous_polygon = node->get_polygon();
  479. previous_colors = node->get_vertex_colors();
  480. previous_bones = node->call("_get_bones");
  481. int internal_vertices = node->get_internal_vertex_count();
  482. Vector2 pos = mtx.affine_inverse().xform(snap_point(mb->get_position()));
  483. previous_polygon.push_back(pos);
  484. previous_uv.push_back(pos);
  485. if (previous_colors.size()) {
  486. previous_colors.push_back(Color(1, 1, 1));
  487. }
  488. undo_redo->create_action(TTR("Create Internal Vertex"));
  489. undo_redo->add_do_method(node, "set_uv", previous_uv);
  490. undo_redo->add_undo_method(node, "set_uv", node->get_uv());
  491. undo_redo->add_do_method(node, "set_polygon", previous_polygon);
  492. undo_redo->add_undo_method(node, "set_polygon", node->get_polygon());
  493. undo_redo->add_do_method(node, "set_vertex_colors", previous_colors);
  494. undo_redo->add_undo_method(node, "set_vertex_colors", node->get_vertex_colors());
  495. for (int i = 0; i < node->get_bone_count(); i++) {
  496. Vector<float> bonew = node->get_bone_weights(i);
  497. bonew.push_back(0);
  498. undo_redo->add_do_method(node, "set_bone_weights", i, bonew);
  499. undo_redo->add_undo_method(node, "set_bone_weights", i, node->get_bone_weights(i));
  500. }
  501. undo_redo->add_do_method(node, "set_internal_vertex_count", internal_vertices + 1);
  502. undo_redo->add_undo_method(node, "set_internal_vertex_count", internal_vertices);
  503. undo_redo->add_do_method(this, "_update_polygon_editing_state");
  504. undo_redo->add_undo_method(this, "_update_polygon_editing_state");
  505. undo_redo->commit_action();
  506. }
  507. if (current_action == ACTION_REMOVE_INTERNAL) {
  508. previous_uv = node->get_uv();
  509. previous_polygon = node->get_polygon();
  510. previous_colors = node->get_vertex_colors();
  511. previous_bones = node->call("_get_bones");
  512. int internal_vertices = node->get_internal_vertex_count();
  513. if (internal_vertices <= 0) {
  514. return;
  515. }
  516. int closest = -1;
  517. real_t closest_dist = 1e20;
  518. for (int i = editing_points.size() - internal_vertices; i < editing_points.size(); i++) {
  519. Vector2 tuv = mtx.xform(previous_polygon[i]);
  520. real_t dist = tuv.distance_to(mb->get_position());
  521. if (dist < 8 && dist < closest_dist) {
  522. closest = i;
  523. closest_dist = dist;
  524. }
  525. }
  526. if (closest == -1) {
  527. return;
  528. }
  529. previous_polygon.remove_at(closest);
  530. previous_uv.remove_at(closest);
  531. if (previous_colors.size()) {
  532. previous_colors.remove_at(closest);
  533. }
  534. undo_redo->create_action(TTR("Remove Internal Vertex"));
  535. undo_redo->add_do_method(node, "set_uv", previous_uv);
  536. undo_redo->add_undo_method(node, "set_uv", node->get_uv());
  537. undo_redo->add_do_method(node, "set_polygon", previous_polygon);
  538. undo_redo->add_undo_method(node, "set_polygon", node->get_polygon());
  539. undo_redo->add_do_method(node, "set_vertex_colors", previous_colors);
  540. undo_redo->add_undo_method(node, "set_vertex_colors", node->get_vertex_colors());
  541. for (int i = 0; i < node->get_bone_count(); i++) {
  542. Vector<float> bonew = node->get_bone_weights(i);
  543. bonew.remove_at(closest);
  544. undo_redo->add_do_method(node, "set_bone_weights", i, bonew);
  545. undo_redo->add_undo_method(node, "set_bone_weights", i, node->get_bone_weights(i));
  546. }
  547. undo_redo->add_do_method(node, "set_internal_vertex_count", internal_vertices - 1);
  548. undo_redo->add_undo_method(node, "set_internal_vertex_count", internal_vertices);
  549. undo_redo->add_do_method(this, "_update_polygon_editing_state");
  550. undo_redo->add_undo_method(this, "_update_polygon_editing_state");
  551. undo_redo->commit_action();
  552. }
  553. if (current_action == ACTION_EDIT_POINT) {
  554. if (mb->is_shift_pressed() && mb->is_command_or_control_pressed()) {
  555. current_action = ACTION_SCALE;
  556. } else if (mb->is_shift_pressed()) {
  557. current_action = ACTION_MOVE;
  558. } else if (mb->is_command_or_control_pressed()) {
  559. current_action = ACTION_ROTATE;
  560. }
  561. }
  562. if (current_action == ACTION_EDIT_POINT) {
  563. point_drag_index = -1;
  564. for (int i = 0; i < editing_points.size(); i++) {
  565. Vector2 tuv = mtx.xform(editing_points[i]);
  566. if (tuv.distance_to(mb->get_position()) < 8) {
  567. drag_from = tuv;
  568. point_drag_index = i;
  569. }
  570. }
  571. if (point_drag_index == -1) {
  572. is_dragging = false;
  573. }
  574. }
  575. if (current_action == ACTION_ADD_POLYGON) {
  576. int closest = -1;
  577. real_t closest_dist = 1e20;
  578. for (int i = 0; i < editing_points.size(); i++) {
  579. Vector2 tuv = mtx.xform(editing_points[i]);
  580. real_t dist = tuv.distance_to(mb->get_position());
  581. if (dist < 8 && dist < closest_dist) {
  582. closest = i;
  583. closest_dist = dist;
  584. }
  585. }
  586. if (closest != -1) {
  587. if (polygon_create.size() && closest == polygon_create[0]) {
  588. //close
  589. if (polygon_create.size() < 3) {
  590. error->set_text(TTR("Invalid Polygon (need 3 different vertices)"));
  591. error->popup_centered();
  592. } else {
  593. Array polygons = node->get_polygons();
  594. polygons = polygons.duplicate(); //copy because its a reference
  595. //todo, could check whether it already exists?
  596. polygons.push_back(polygon_create);
  597. undo_redo->create_action(TTR("Add Custom Polygon"));
  598. undo_redo->add_do_method(node, "set_polygons", polygons);
  599. undo_redo->add_undo_method(node, "set_polygons", node->get_polygons());
  600. undo_redo->commit_action();
  601. }
  602. polygon_create.clear();
  603. } else if (!polygon_create.has(closest)) {
  604. //add temporarily if not exists
  605. polygon_create.push_back(closest);
  606. }
  607. }
  608. }
  609. if (current_action == ACTION_REMOVE_POLYGON) {
  610. Array polygons = node->get_polygons();
  611. polygons = polygons.duplicate(); //copy because its a reference
  612. int erase_index = -1;
  613. for (int i = polygons.size() - 1; i >= 0; i--) {
  614. Vector<int> points = polygons[i];
  615. Vector<Vector2> polys;
  616. polys.resize(points.size());
  617. for (int j = 0; j < polys.size(); j++) {
  618. int idx = points[j];
  619. if (idx < 0 || idx >= editing_points.size()) {
  620. continue;
  621. }
  622. polys.write[j] = mtx.xform(editing_points[idx]);
  623. }
  624. if (Geometry2D::is_point_in_polygon(mb->get_position(), polys)) {
  625. erase_index = i;
  626. break;
  627. }
  628. }
  629. if (erase_index != -1) {
  630. polygons.remove_at(erase_index);
  631. undo_redo->create_action(TTR("Remove Custom Polygon"));
  632. undo_redo->add_do_method(node, "set_polygons", polygons);
  633. undo_redo->add_undo_method(node, "set_polygons", node->get_polygons());
  634. undo_redo->commit_action();
  635. }
  636. }
  637. if (current_action == ACTION_PAINT_WEIGHT || current_action == ACTION_CLEAR_WEIGHT) {
  638. int bone_selected = -1;
  639. for (int i = 0; i < bone_scroll_vb->get_child_count(); i++) {
  640. CheckBox *c = Object::cast_to<CheckBox>(bone_scroll_vb->get_child(i));
  641. if (c && c->is_pressed()) {
  642. bone_selected = i;
  643. break;
  644. }
  645. }
  646. if (bone_selected != -1 && node->get_bone_weights(bone_selected).size() == editing_points.size()) {
  647. prev_weights = node->get_bone_weights(bone_selected);
  648. bone_painting = true;
  649. bone_painting_bone = bone_selected;
  650. }
  651. }
  652. } else {
  653. if (is_dragging && !is_creating) {
  654. if (current_mode == MODE_UV) {
  655. undo_redo->create_action(TTR("Transform UV Map"));
  656. undo_redo->add_do_method(node, "set_uv", node->get_uv());
  657. undo_redo->add_undo_method(node, "set_uv", editing_points);
  658. undo_redo->commit_action();
  659. } else if (current_mode == MODE_POINTS) {
  660. switch (current_action) {
  661. case ACTION_EDIT_POINT:
  662. case ACTION_MOVE:
  663. case ACTION_ROTATE:
  664. case ACTION_SCALE: {
  665. undo_redo->create_action(TTR("Transform Polygon"));
  666. undo_redo->add_do_method(node, "set_polygon", node->get_polygon());
  667. undo_redo->add_undo_method(node, "set_polygon", editing_points);
  668. undo_redo->commit_action();
  669. } break;
  670. default: {
  671. } break;
  672. }
  673. }
  674. is_dragging = false;
  675. }
  676. if (bone_painting) {
  677. undo_redo->create_action(TTR("Paint Bone Weights"));
  678. undo_redo->add_do_method(node, "set_bone_weights", bone_painting_bone, node->get_bone_weights(bone_painting_bone));
  679. undo_redo->add_undo_method(node, "set_bone_weights", bone_painting_bone, prev_weights);
  680. undo_redo->commit_action();
  681. bone_painting = false;
  682. }
  683. }
  684. } else if (mb->get_button_index() == MouseButton::RIGHT && mb->is_pressed()) {
  685. _cancel_editing();
  686. if (bone_painting) {
  687. node->set_bone_weights(bone_painting_bone, prev_weights);
  688. }
  689. canvas->queue_redraw();
  690. }
  691. }
  692. Ref<InputEventMouseMotion> mm = p_input;
  693. if (mm.is_valid()) {
  694. if (is_dragging) {
  695. Vector2 uv_drag_to = mm->get_position();
  696. uv_drag_to = snap_point(uv_drag_to);
  697. Vector2 drag = mtx.affine_inverse().basis_xform(uv_drag_to - drag_from);
  698. switch (current_action) {
  699. case ACTION_CREATE: {
  700. if (is_creating) {
  701. create_to = mtx.affine_inverse().xform(snap_point(mm->get_position()));
  702. }
  703. } break;
  704. case ACTION_EDIT_POINT: {
  705. Vector<Vector2> uv_new = editing_points;
  706. uv_new.set(point_drag_index, uv_new[point_drag_index] + drag);
  707. if (current_mode == MODE_UV) {
  708. node->set_uv(uv_new);
  709. } else if (current_mode == MODE_POINTS) {
  710. node->set_polygon(uv_new);
  711. }
  712. } break;
  713. case ACTION_MOVE: {
  714. Vector<Vector2> uv_new = editing_points;
  715. for (int i = 0; i < uv_new.size(); i++) {
  716. uv_new.set(i, uv_new[i] + drag);
  717. }
  718. if (current_mode == MODE_UV) {
  719. node->set_uv(uv_new);
  720. } else if (current_mode == MODE_POINTS) {
  721. node->set_polygon(uv_new);
  722. }
  723. } break;
  724. case ACTION_ROTATE: {
  725. Vector2 center;
  726. Vector<Vector2> uv_new = editing_points;
  727. for (int i = 0; i < uv_new.size(); i++) {
  728. center += editing_points[i];
  729. }
  730. center /= uv_new.size();
  731. real_t angle = (drag_from - mtx.xform(center)).normalized().angle_to((uv_drag_to - mtx.xform(center)).normalized());
  732. for (int i = 0; i < uv_new.size(); i++) {
  733. Vector2 rel = editing_points[i] - center;
  734. rel = rel.rotated(angle);
  735. uv_new.set(i, center + rel);
  736. }
  737. if (current_mode == MODE_UV) {
  738. node->set_uv(uv_new);
  739. } else if (current_mode == MODE_POINTS) {
  740. node->set_polygon(uv_new);
  741. }
  742. } break;
  743. case ACTION_SCALE: {
  744. Vector2 center;
  745. Vector<Vector2> uv_new = editing_points;
  746. for (int i = 0; i < uv_new.size(); i++) {
  747. center += editing_points[i];
  748. }
  749. center /= uv_new.size();
  750. real_t from_dist = drag_from.distance_to(mtx.xform(center));
  751. real_t to_dist = uv_drag_to.distance_to(mtx.xform(center));
  752. if (from_dist < 2) {
  753. break;
  754. }
  755. real_t scale = to_dist / from_dist;
  756. for (int i = 0; i < uv_new.size(); i++) {
  757. Vector2 rel = editing_points[i] - center;
  758. rel = rel * scale;
  759. uv_new.set(i, center + rel);
  760. }
  761. if (current_mode == MODE_UV) {
  762. node->set_uv(uv_new);
  763. } else if (current_mode == MODE_POINTS) {
  764. node->set_polygon(uv_new);
  765. }
  766. } break;
  767. case ACTION_PAINT_WEIGHT:
  768. case ACTION_CLEAR_WEIGHT: {
  769. bone_paint_pos = mm->get_position();
  770. } break;
  771. default: {
  772. }
  773. }
  774. if (bone_painting) {
  775. Vector<float> painted_weights = node->get_bone_weights(bone_painting_bone);
  776. {
  777. int pc = painted_weights.size();
  778. real_t amount = bone_paint_strength->get_value();
  779. real_t radius = bone_paint_radius->get_value() * EDSCALE;
  780. if (selected_action == ACTION_CLEAR_WEIGHT) {
  781. amount = -amount;
  782. }
  783. float *w = painted_weights.ptrw();
  784. const float *r = prev_weights.ptr();
  785. const Vector2 *rv = editing_points.ptr();
  786. for (int i = 0; i < pc; i++) {
  787. if (mtx.xform(rv[i]).distance_to(bone_paint_pos) < radius) {
  788. w[i] = CLAMP(r[i] + amount, 0, 1);
  789. }
  790. }
  791. }
  792. node->set_bone_weights(bone_painting_bone, painted_weights);
  793. }
  794. canvas->queue_redraw();
  795. CanvasItemEditor::get_singleton()->update_viewport();
  796. } else if (polygon_create.size()) {
  797. create_to = mtx.affine_inverse().xform(mm->get_position());
  798. canvas->queue_redraw();
  799. } else if (selected_action == ACTION_PAINT_WEIGHT || selected_action == ACTION_CLEAR_WEIGHT) {
  800. bone_paint_pos = mm->get_position();
  801. canvas->queue_redraw();
  802. }
  803. }
  804. }
  805. void Polygon2DEditor::_update_available_modes() {
  806. // Force point editing mode if there's no polygon yet.
  807. if (node->get_polygon().is_empty()) {
  808. if (current_mode != MODE_POINTS) {
  809. _select_mode(MODE_POINTS);
  810. }
  811. mode_buttons[MODE_UV]->set_disabled(true);
  812. mode_buttons[MODE_POLYGONS]->set_disabled(true);
  813. mode_buttons[MODE_BONES]->set_disabled(true);
  814. } else {
  815. mode_buttons[MODE_UV]->set_disabled(false);
  816. mode_buttons[MODE_POLYGONS]->set_disabled(false);
  817. mode_buttons[MODE_BONES]->set_disabled(false);
  818. }
  819. }
  820. void Polygon2DEditor::_center_view() {
  821. Size2 texture_size;
  822. if (node->get_texture().is_valid()) {
  823. texture_size = node->get_texture()->get_size();
  824. Vector2 zoom_factor = (canvas->get_size() - Vector2(1, 1) * 50 * EDSCALE) / texture_size;
  825. zoom_widget->set_zoom(MIN(zoom_factor.x, zoom_factor.y));
  826. } else {
  827. zoom_widget->set_zoom(EDSCALE);
  828. }
  829. // Recalculate scroll limits.
  830. _update_zoom_and_pan(false);
  831. Size2 offset = (texture_size - canvas->get_size() / draw_zoom) / 2;
  832. hscroll->set_value_no_signal(offset.x);
  833. vscroll->set_value_no_signal(offset.y);
  834. _update_zoom_and_pan(false);
  835. }
  836. void Polygon2DEditor::_pan_callback(Vector2 p_scroll_vec, Ref<InputEvent> p_event) {
  837. hscroll->set_value_no_signal(hscroll->get_value() - p_scroll_vec.x / draw_zoom);
  838. vscroll->set_value_no_signal(vscroll->get_value() - p_scroll_vec.y / draw_zoom);
  839. _update_zoom_and_pan(false);
  840. }
  841. void Polygon2DEditor::_zoom_callback(float p_zoom_factor, Vector2 p_origin, Ref<InputEvent> p_event) {
  842. zoom_widget->set_zoom(draw_zoom * p_zoom_factor);
  843. draw_offset += p_origin / draw_zoom - p_origin / zoom_widget->get_zoom();
  844. hscroll->set_value_no_signal(draw_offset.x);
  845. vscroll->set_value_no_signal(draw_offset.y);
  846. _update_zoom_and_pan(false);
  847. }
  848. void Polygon2DEditor::_update_zoom_and_pan(bool p_zoom_at_center) {
  849. draw_offset = Vector2(hscroll->get_value(), vscroll->get_value());
  850. real_t previous_zoom = draw_zoom;
  851. draw_zoom = zoom_widget->get_zoom();
  852. if (p_zoom_at_center) {
  853. Vector2 center = canvas->get_size() / 2;
  854. draw_offset += center / previous_zoom - center / draw_zoom;
  855. }
  856. Point2 min_corner;
  857. Point2 max_corner;
  858. if (node->get_texture().is_valid()) {
  859. max_corner += node->get_texture()->get_size();
  860. }
  861. Vector<Vector2> points = current_mode == MODE_UV ? node->get_uv() : node->get_polygon();
  862. for (int i = 0; i < points.size(); i++) {
  863. min_corner = min_corner.min(points[i]);
  864. max_corner = max_corner.max(points[i]);
  865. }
  866. Size2 page_size = canvas->get_size() / draw_zoom;
  867. Vector2 margin = Vector2(50, 50) * EDSCALE / draw_zoom;
  868. min_corner -= page_size - margin;
  869. max_corner += page_size - margin;
  870. hscroll->set_block_signals(true);
  871. hscroll->set_min(min_corner.x);
  872. hscroll->set_max(max_corner.x);
  873. hscroll->set_page(page_size.x);
  874. hscroll->set_value(draw_offset.x);
  875. hscroll->set_block_signals(false);
  876. vscroll->set_block_signals(true);
  877. vscroll->set_min(min_corner.y);
  878. vscroll->set_max(max_corner.y);
  879. vscroll->set_page(page_size.y);
  880. vscroll->set_value(draw_offset.y);
  881. vscroll->set_block_signals(false);
  882. canvas->queue_redraw();
  883. }
  884. void Polygon2DEditor::_center_view_on_draw(bool p_enabled) {
  885. if (center_view_on_draw == p_enabled) {
  886. return;
  887. }
  888. center_view_on_draw = p_enabled;
  889. if (center_view_on_draw) {
  890. // Ensure that the view is centered even if the canvas is redrawn multiple times in the frame.
  891. get_tree()->connect("process_frame", callable_mp(this, &Polygon2DEditor::_center_view_on_draw).bind(false), CONNECT_ONE_SHOT);
  892. }
  893. }
  894. void Polygon2DEditor::_canvas_draw() {
  895. if (!polygon_edit->is_visible() || !_get_node()) {
  896. return;
  897. }
  898. if (center_view_on_draw) {
  899. _center_view();
  900. }
  901. Ref<Texture2D> base_tex = node->get_texture();
  902. String warning;
  903. Transform2D mtx;
  904. mtx.columns[2] = -draw_offset * draw_zoom;
  905. mtx.scale_basis(Vector2(draw_zoom, draw_zoom));
  906. // Draw texture as a background if editing uvs or no uv mapping exist.
  907. if (current_mode == MODE_UV || selected_action == ACTION_CREATE || node->get_polygon().is_empty() || node->get_uv().size() != node->get_polygon().size()) {
  908. if (base_tex.is_valid()) {
  909. Transform2D texture_transform = Transform2D(node->get_texture_rotation(), node->get_texture_offset());
  910. texture_transform.scale(node->get_texture_scale());
  911. texture_transform.affine_invert();
  912. RS::get_singleton()->canvas_item_add_set_transform(canvas->get_canvas_item(), mtx * texture_transform);
  913. canvas->draw_texture(base_tex, Point2());
  914. RS::get_singleton()->canvas_item_add_set_transform(canvas->get_canvas_item(), Transform2D());
  915. }
  916. preview_polygon->hide();
  917. } else {
  918. preview_polygon->set_transform(mtx);
  919. // Keep in sync with newly added Polygon2D properties (when relevant).
  920. preview_polygon->set_texture(node->get_texture());
  921. preview_polygon->set_texture_offset(node->get_texture_offset());
  922. preview_polygon->set_texture_rotation(node->get_texture_rotation());
  923. preview_polygon->set_texture_scale(node->get_texture_scale());
  924. preview_polygon->set_texture_filter(node->get_texture_filter_in_tree());
  925. preview_polygon->set_texture_repeat(node->get_texture_repeat_in_tree());
  926. preview_polygon->set_polygon(node->get_polygon());
  927. preview_polygon->set_uv(node->get_uv());
  928. preview_polygon->set_invert(node->get_invert());
  929. preview_polygon->set_invert_border(node->get_invert_border());
  930. preview_polygon->set_internal_vertex_count(node->get_internal_vertex_count());
  931. if (selected_action == ACTION_ADD_POLYGON) {
  932. preview_polygon->set_polygons(Array());
  933. } else {
  934. preview_polygon->set_polygons(node->get_polygons());
  935. }
  936. preview_polygon->show();
  937. }
  938. if (snap_show_grid) {
  939. Color grid_color = Color(1.0, 1.0, 1.0, 0.15);
  940. Size2 s = canvas->get_size();
  941. int last_cell = 0;
  942. if (snap_step.x != 0) {
  943. for (int i = 0; i < s.width; i++) {
  944. int cell = Math::fast_ftoi(Math::floor((mtx.affine_inverse().xform(Vector2(i, 0)).x - snap_offset.x) / snap_step.x));
  945. if (i == 0) {
  946. last_cell = cell;
  947. }
  948. if (last_cell != cell) {
  949. canvas->draw_line(Point2(i, 0), Point2(i, s.height), grid_color, Math::round(EDSCALE));
  950. }
  951. last_cell = cell;
  952. }
  953. }
  954. if (snap_step.y != 0) {
  955. for (int i = 0; i < s.height; i++) {
  956. int cell = Math::fast_ftoi(Math::floor((mtx.affine_inverse().xform(Vector2(0, i)).y - snap_offset.y) / snap_step.y));
  957. if (i == 0) {
  958. last_cell = cell;
  959. }
  960. if (last_cell != cell) {
  961. canvas->draw_line(Point2(0, i), Point2(s.width, i), grid_color, Math::round(EDSCALE));
  962. }
  963. last_cell = cell;
  964. }
  965. }
  966. }
  967. Array polygons = node->get_polygons();
  968. Vector<Vector2> uvs;
  969. if (current_mode == MODE_UV) {
  970. uvs = node->get_uv();
  971. } else {
  972. uvs = node->get_polygon();
  973. }
  974. const float *weight_r = nullptr;
  975. if (current_mode == MODE_BONES) {
  976. int bone_selected = -1;
  977. for (int i = 0; i < bone_scroll_vb->get_child_count(); i++) {
  978. CheckBox *c = Object::cast_to<CheckBox>(bone_scroll_vb->get_child(i));
  979. if (c && c->is_pressed()) {
  980. bone_selected = i;
  981. break;
  982. }
  983. }
  984. if (bone_selected != -1 && node->get_bone_weights(bone_selected).size() == uvs.size()) {
  985. weight_r = node->get_bone_weights(bone_selected).ptr();
  986. }
  987. }
  988. // All UV points are sharp, so use the sharp handle icon
  989. Ref<Texture2D> handle = get_editor_theme_icon(SNAME("EditorPathSharpHandle"));
  990. Color poly_line_color = Color(0.9, 0.5, 0.5);
  991. if (polygons.size() || polygon_create.size()) {
  992. poly_line_color.a *= 0.25;
  993. }
  994. Color polygon_line_color = Color(0.5, 0.5, 0.9);
  995. Color polygon_fill_color = polygon_line_color;
  996. polygon_fill_color.a *= 0.5;
  997. Color prev_color = Color(0.5, 0.5, 0.5);
  998. int uv_draw_max = uvs.size();
  999. uv_draw_max -= node->get_internal_vertex_count();
  1000. if (uv_draw_max < 0) {
  1001. uv_draw_max = 0;
  1002. }
  1003. for (int i = 0; i < uvs.size(); i++) {
  1004. int next = uv_draw_max > 0 ? (i + 1) % uv_draw_max : 0;
  1005. if (i < uv_draw_max && is_dragging && current_action == ACTION_EDIT_POINT && EDITOR_GET("editors/polygon_editor/show_previous_outline")) {
  1006. canvas->draw_line(mtx.xform(editing_points[i]), mtx.xform(editing_points[next]), prev_color, Math::round(EDSCALE));
  1007. }
  1008. Vector2 next_point = uvs[next];
  1009. if (is_creating && i == uvs.size() - 1) {
  1010. next_point = create_to;
  1011. }
  1012. if (i < uv_draw_max) { // If using or creating polygons, do not show outline (will show polygons instead).
  1013. canvas->draw_line(mtx.xform(uvs[i]), mtx.xform(next_point), poly_line_color, Math::round(EDSCALE));
  1014. }
  1015. }
  1016. for (int i = 0; i < polygons.size(); i++) {
  1017. Vector<int> points = polygons[i];
  1018. Vector<Vector2> polypoints;
  1019. for (int j = 0; j < points.size(); j++) {
  1020. int next = (j + 1) % points.size();
  1021. int idx = points[j];
  1022. int idx_next = points[next];
  1023. if (idx < 0 || idx >= uvs.size()) {
  1024. continue;
  1025. }
  1026. polypoints.push_back(mtx.xform(uvs[idx]));
  1027. if (idx_next < 0 || idx_next >= uvs.size()) {
  1028. continue;
  1029. }
  1030. canvas->draw_line(mtx.xform(uvs[idx]), mtx.xform(uvs[idx_next]), polygon_line_color, Math::round(EDSCALE));
  1031. }
  1032. if (points.size() >= 3) {
  1033. canvas->draw_colored_polygon(polypoints, polygon_fill_color);
  1034. }
  1035. }
  1036. for (int i = 0; i < uvs.size(); i++) {
  1037. if (weight_r) {
  1038. Vector2 draw_pos = mtx.xform(uvs[i]);
  1039. float weight = weight_r[i];
  1040. canvas->draw_rect(Rect2(draw_pos - Vector2(2, 2) * EDSCALE, Vector2(5, 5) * EDSCALE), Color(weight, weight, weight, 1.0), Math::round(EDSCALE));
  1041. } else {
  1042. if (i < uv_draw_max) {
  1043. canvas->draw_texture(handle, mtx.xform(uvs[i]) - handle->get_size() * 0.5);
  1044. } else {
  1045. // Internal vertex
  1046. canvas->draw_texture(handle, mtx.xform(uvs[i]) - handle->get_size() * 0.5, Color(0.6, 0.8, 1));
  1047. }
  1048. }
  1049. }
  1050. if (polygon_create.size()) {
  1051. for (int i = 0; i < polygon_create.size(); i++) {
  1052. Vector2 from = uvs[polygon_create[i]];
  1053. Vector2 to = (i + 1) < polygon_create.size() ? uvs[polygon_create[i + 1]] : create_to;
  1054. canvas->draw_line(mtx.xform(from), mtx.xform(to), polygon_line_color, Math::round(EDSCALE));
  1055. }
  1056. }
  1057. if (selected_action == ACTION_PAINT_WEIGHT || selected_action == ACTION_CLEAR_WEIGHT) {
  1058. NodePath bone_path;
  1059. for (int i = 0; i < bone_scroll_vb->get_child_count(); i++) {
  1060. CheckBox *c = Object::cast_to<CheckBox>(bone_scroll_vb->get_child(i));
  1061. if (c && c->is_pressed()) {
  1062. bone_path = node->get_bone_path(i);
  1063. break;
  1064. }
  1065. }
  1066. //draw skeleton
  1067. NodePath skeleton_path = node->get_skeleton();
  1068. Skeleton2D *skeleton = Object::cast_to<Skeleton2D>(node->get_node_or_null(skeleton_path));
  1069. if (skeleton) {
  1070. Transform2D skeleton_xform = node->get_global_transform().affine_inverse().translated(-node->get_offset()) * skeleton->get_global_transform();
  1071. for (int i = 0; i < skeleton->get_bone_count(); i++) {
  1072. Bone2D *bone = skeleton->get_bone(i);
  1073. if (bone->get_rest() == Transform2D(0, 0, 0, 0, 0, 0)) {
  1074. continue; //not set
  1075. }
  1076. bool current = bone_path == skeleton->get_path_to(bone);
  1077. bool found_child = false;
  1078. for (int j = 0; j < bone->get_child_count(); j++) {
  1079. Bone2D *n = Object::cast_to<Bone2D>(bone->get_child(j));
  1080. if (!n) {
  1081. continue;
  1082. }
  1083. found_child = true;
  1084. Transform2D bone_xform = skeleton_xform * bone->get_skeleton_rest();
  1085. Transform2D endpoint_xform = bone_xform * n->get_transform();
  1086. Color color = current ? Color(1, 1, 1) : Color(0.5, 0.5, 0.5);
  1087. canvas->draw_line(mtx.xform(bone_xform.get_origin()), mtx.xform(endpoint_xform.get_origin()), Color(0, 0, 0), Math::round((current ? 5 : 4) * EDSCALE));
  1088. canvas->draw_line(mtx.xform(bone_xform.get_origin()), mtx.xform(endpoint_xform.get_origin()), color, Math::round((current ? 3 : 2) * EDSCALE));
  1089. }
  1090. if (!found_child) {
  1091. //draw normally
  1092. Transform2D bone_xform = skeleton_xform * bone->get_skeleton_rest();
  1093. Transform2D endpoint_xform = bone_xform * Transform2D(0, Vector2(bone->get_length(), 0)).rotated(bone->get_bone_angle());
  1094. Color color = current ? Color(1, 1, 1) : Color(0.5, 0.5, 0.5);
  1095. canvas->draw_line(mtx.xform(bone_xform.get_origin()), mtx.xform(endpoint_xform.get_origin()), Color(0, 0, 0), Math::round((current ? 5 : 4) * EDSCALE));
  1096. canvas->draw_line(mtx.xform(bone_xform.get_origin()), mtx.xform(endpoint_xform.get_origin()), color, Math::round((current ? 3 : 2) * EDSCALE));
  1097. }
  1098. }
  1099. }
  1100. //draw paint circle
  1101. canvas->draw_circle(bone_paint_pos, bone_paint_radius->get_value() * EDSCALE, Color(1, 1, 1, 0.1));
  1102. }
  1103. }
  1104. void Polygon2DEditor::_bind_methods() {
  1105. ClassDB::bind_method(D_METHOD("_update_bone_list"), &Polygon2DEditor::_update_bone_list);
  1106. ClassDB::bind_method(D_METHOD("_update_polygon_editing_state"), &Polygon2DEditor::_update_polygon_editing_state);
  1107. }
  1108. Vector2 Polygon2DEditor::snap_point(Vector2 p_target) const {
  1109. if (use_snap) {
  1110. p_target.x = Math::snap_scalar((snap_offset.x - draw_offset.x) * draw_zoom, snap_step.x * draw_zoom, p_target.x);
  1111. p_target.y = Math::snap_scalar((snap_offset.y - draw_offset.y) * draw_zoom, snap_step.y * draw_zoom, p_target.y);
  1112. }
  1113. return p_target;
  1114. }
  1115. Polygon2DEditor::Polygon2DEditor() {
  1116. snap_offset = EditorSettings::get_singleton()->get_project_metadata("polygon_2d_uv_editor", "snap_offset", Vector2());
  1117. // A power-of-two value works better as a default grid size.
  1118. snap_step = EditorSettings::get_singleton()->get_project_metadata("polygon_2d_uv_editor", "snap_step", Vector2(8, 8));
  1119. use_snap = EditorSettings::get_singleton()->get_project_metadata("polygon_2d_uv_editor", "snap_enabled", false);
  1120. snap_show_grid = EditorSettings::get_singleton()->get_project_metadata("polygon_2d_uv_editor", "show_grid", false);
  1121. selected_action = ACTION_EDIT_POINT;
  1122. polygon_edit = memnew(VBoxContainer);
  1123. HBoxContainer *toolbar = memnew(HBoxContainer);
  1124. Ref<ButtonGroup> mode_button_group;
  1125. mode_button_group.instantiate();
  1126. for (int i = 0; i < MODE_MAX; i++) {
  1127. mode_buttons[i] = memnew(Button);
  1128. toolbar->add_child(mode_buttons[i]);
  1129. mode_buttons[i]->set_toggle_mode(true);
  1130. mode_buttons[i]->set_button_group(mode_button_group);
  1131. mode_buttons[i]->connect(SceneStringName(pressed), callable_mp(this, &Polygon2DEditor::_select_mode).bind(i));
  1132. }
  1133. mode_buttons[MODE_POINTS]->set_text(TTR("Points"));
  1134. mode_buttons[MODE_POLYGONS]->set_text(TTR("Polygons"));
  1135. mode_buttons[MODE_UV]->set_text(TTR("UV"));
  1136. mode_buttons[MODE_BONES]->set_text(TTR("Bones"));
  1137. toolbar->add_child(memnew(VSeparator));
  1138. polygon_edit->add_child(toolbar);
  1139. for (int i = 0; i < ACTION_MAX; i++) {
  1140. action_buttons[i] = memnew(Button);
  1141. action_buttons[i]->set_theme_type_variation(SceneStringName(FlatButton));
  1142. action_buttons[i]->set_toggle_mode(true);
  1143. toolbar->add_child(action_buttons[i]);
  1144. action_buttons[i]->connect(SceneStringName(pressed), callable_mp(this, &Polygon2DEditor::_set_action).bind(i));
  1145. action_buttons[i]->set_focus_mode(FOCUS_NONE);
  1146. }
  1147. action_buttons[ACTION_CREATE]->set_tooltip_text(TTR("Create Polygon"));
  1148. action_buttons[ACTION_CREATE_INTERNAL]->set_tooltip_text(TTR("Create Internal Vertex"));
  1149. action_buttons[ACTION_REMOVE_INTERNAL]->set_tooltip_text(TTR("Remove Internal Vertex"));
  1150. Key key = (OS::get_singleton()->has_feature("macos") || OS::get_singleton()->has_feature("web_macos") || OS::get_singleton()->has_feature("web_ios")) ? Key::META : Key::CTRL;
  1151. // TRANSLATORS: %s is Control or Command key name.
  1152. action_buttons[ACTION_EDIT_POINT]->set_tooltip_text(TTR("Move Points") + "\n" + vformat(TTR("%s: Rotate"), find_keycode_name(key)) + "\n" + TTR("Shift: Move All") + "\n" + vformat(TTR("%s + Shift: Scale"), find_keycode_name(key)));
  1153. action_buttons[ACTION_MOVE]->set_tooltip_text(TTR("Move Polygon"));
  1154. action_buttons[ACTION_ROTATE]->set_tooltip_text(TTR("Rotate Polygon"));
  1155. action_buttons[ACTION_SCALE]->set_tooltip_text(TTR("Scale Polygon"));
  1156. action_buttons[ACTION_ADD_POLYGON]->set_tooltip_text(TTR("Create a custom polygon. Enables custom polygon rendering."));
  1157. action_buttons[ACTION_REMOVE_POLYGON]->set_tooltip_text(TTR("Remove a custom polygon. If none remain, custom polygon rendering is disabled."));
  1158. action_buttons[ACTION_PAINT_WEIGHT]->set_tooltip_text(TTR("Paint weights with specified intensity."));
  1159. action_buttons[ACTION_CLEAR_WEIGHT]->set_tooltip_text(TTR("Unpaint weights with specified intensity."));
  1160. bone_paint_strength = memnew(HSlider);
  1161. toolbar->add_child(bone_paint_strength);
  1162. bone_paint_strength->set_custom_minimum_size(Size2(75 * EDSCALE, 0));
  1163. bone_paint_strength->set_v_size_flags(SIZE_SHRINK_CENTER);
  1164. bone_paint_strength->set_min(0);
  1165. bone_paint_strength->set_max(1);
  1166. bone_paint_strength->set_step(0.01);
  1167. bone_paint_strength->set_value(0.5);
  1168. bone_paint_radius_label = memnew(Label(TTR("Radius:")));
  1169. toolbar->add_child(bone_paint_radius_label);
  1170. bone_paint_radius = memnew(SpinBox);
  1171. toolbar->add_child(bone_paint_radius);
  1172. bone_paint_radius->set_min(1);
  1173. bone_paint_radius->set_max(100);
  1174. bone_paint_radius->set_step(1);
  1175. bone_paint_radius->set_value(32);
  1176. HSplitContainer *uv_main_hsc = memnew(HSplitContainer);
  1177. polygon_edit->add_child(uv_main_hsc);
  1178. uv_main_hsc->set_v_size_flags(SIZE_EXPAND_FILL);
  1179. canvas_background = memnew(Panel);
  1180. uv_main_hsc->add_child(canvas_background);
  1181. canvas_background->set_h_size_flags(SIZE_EXPAND_FILL);
  1182. canvas_background->set_custom_minimum_size(Size2(200, 200) * EDSCALE);
  1183. canvas_background->set_clip_contents(true);
  1184. preview_polygon = memnew(Polygon2D);
  1185. canvas_background->add_child(preview_polygon);
  1186. canvas = memnew(Control);
  1187. canvas_background->add_child(canvas);
  1188. canvas->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
  1189. Control *space = memnew(Control);
  1190. toolbar->add_child(space);
  1191. space->set_h_size_flags(SIZE_EXPAND_FILL);
  1192. edit_menu = memnew(MenuButton);
  1193. toolbar->add_child(edit_menu);
  1194. edit_menu->set_flat(false);
  1195. edit_menu->set_theme_type_variation("FlatMenuButton");
  1196. edit_menu->set_text(TTR("Edit"));
  1197. edit_menu->get_popup()->add_item(TTR("Copy Polygon to UV"), MENU_POLYGON_TO_UV);
  1198. edit_menu->get_popup()->add_item(TTR("Copy UV to Polygon"), MENU_UV_TO_POLYGON);
  1199. edit_menu->get_popup()->add_separator();
  1200. edit_menu->get_popup()->add_item(TTR("Clear UV"), MENU_UV_CLEAR);
  1201. edit_menu->get_popup()->add_separator();
  1202. edit_menu->get_popup()->add_item(TTR("Grid Settings"), MENU_GRID_SETTINGS);
  1203. edit_menu->get_popup()->connect(SceneStringName(id_pressed), callable_mp(this, &Polygon2DEditor::_edit_menu_option));
  1204. toolbar->add_child(memnew(VSeparator));
  1205. b_snap_enable = memnew(Button);
  1206. b_snap_enable->set_theme_type_variation(SceneStringName(FlatButton));
  1207. toolbar->add_child(b_snap_enable);
  1208. b_snap_enable->set_text(TTR("Snap"));
  1209. b_snap_enable->set_focus_mode(FOCUS_NONE);
  1210. b_snap_enable->set_toggle_mode(true);
  1211. b_snap_enable->set_pressed(use_snap);
  1212. b_snap_enable->set_tooltip_text(TTR("Enable Snap"));
  1213. b_snap_enable->connect(SceneStringName(toggled), callable_mp(this, &Polygon2DEditor::_set_use_snap));
  1214. b_snap_grid = memnew(Button);
  1215. b_snap_grid->set_theme_type_variation(SceneStringName(FlatButton));
  1216. toolbar->add_child(b_snap_grid);
  1217. b_snap_grid->set_text(TTR("Grid"));
  1218. b_snap_grid->set_focus_mode(FOCUS_NONE);
  1219. b_snap_grid->set_toggle_mode(true);
  1220. b_snap_grid->set_pressed(snap_show_grid);
  1221. b_snap_grid->set_tooltip_text(TTR("Show Grid"));
  1222. b_snap_grid->connect(SceneStringName(toggled), callable_mp(this, &Polygon2DEditor::_set_show_grid));
  1223. grid_settings = memnew(AcceptDialog);
  1224. grid_settings->set_title(TTR("Configure Grid:"));
  1225. polygon_edit->add_child(grid_settings);
  1226. VBoxContainer *grid_settings_vb = memnew(VBoxContainer);
  1227. grid_settings->add_child(grid_settings_vb);
  1228. SpinBox *sb_off_x = memnew(SpinBox);
  1229. sb_off_x->set_min(-256);
  1230. sb_off_x->set_max(256);
  1231. sb_off_x->set_step(1);
  1232. sb_off_x->set_value(snap_offset.x);
  1233. sb_off_x->set_suffix("px");
  1234. sb_off_x->connect(SceneStringName(value_changed), callable_mp(this, &Polygon2DEditor::_set_snap_off_x));
  1235. grid_settings_vb->add_margin_child(TTR("Grid Offset X:"), sb_off_x);
  1236. SpinBox *sb_off_y = memnew(SpinBox);
  1237. sb_off_y->set_min(-256);
  1238. sb_off_y->set_max(256);
  1239. sb_off_y->set_step(1);
  1240. sb_off_y->set_value(snap_offset.y);
  1241. sb_off_y->set_suffix("px");
  1242. sb_off_y->connect(SceneStringName(value_changed), callable_mp(this, &Polygon2DEditor::_set_snap_off_y));
  1243. grid_settings_vb->add_margin_child(TTR("Grid Offset Y:"), sb_off_y);
  1244. SpinBox *sb_step_x = memnew(SpinBox);
  1245. sb_step_x->set_min(-256);
  1246. sb_step_x->set_max(256);
  1247. sb_step_x->set_step(1);
  1248. sb_step_x->set_value(snap_step.x);
  1249. sb_step_x->set_suffix("px");
  1250. sb_step_x->connect(SceneStringName(value_changed), callable_mp(this, &Polygon2DEditor::_set_snap_step_x));
  1251. grid_settings_vb->add_margin_child(TTR("Grid Step X:"), sb_step_x);
  1252. SpinBox *sb_step_y = memnew(SpinBox);
  1253. sb_step_y->set_min(-256);
  1254. sb_step_y->set_max(256);
  1255. sb_step_y->set_step(1);
  1256. sb_step_y->set_value(snap_step.y);
  1257. sb_step_y->set_suffix("px");
  1258. sb_step_y->connect(SceneStringName(value_changed), callable_mp(this, &Polygon2DEditor::_set_snap_step_y));
  1259. grid_settings_vb->add_margin_child(TTR("Grid Step Y:"), sb_step_y);
  1260. zoom_widget = memnew(EditorZoomWidget);
  1261. canvas->add_child(zoom_widget);
  1262. zoom_widget->set_anchors_and_offsets_preset(Control::PRESET_TOP_LEFT, Control::PRESET_MODE_MINSIZE, 2 * EDSCALE);
  1263. zoom_widget->connect("zoom_changed", callable_mp(this, &Polygon2DEditor::_update_zoom_and_pan).unbind(1).bind(true));
  1264. zoom_widget->set_shortcut_context(nullptr);
  1265. vscroll = memnew(VScrollBar);
  1266. vscroll->set_step(0.001);
  1267. canvas->add_child(vscroll);
  1268. vscroll->connect(SceneStringName(value_changed), callable_mp(this, &Polygon2DEditor::_update_zoom_and_pan).unbind(1).bind(false));
  1269. hscroll = memnew(HScrollBar);
  1270. hscroll->set_step(0.001);
  1271. canvas->add_child(hscroll);
  1272. hscroll->connect(SceneStringName(value_changed), callable_mp(this, &Polygon2DEditor::_update_zoom_and_pan).unbind(1).bind(false));
  1273. bone_scroll_main_vb = memnew(VBoxContainer);
  1274. bone_scroll_main_vb->set_custom_minimum_size(Size2(150 * EDSCALE, 0));
  1275. sync_bones = memnew(Button(TTR("Sync Bones to Polygon")));
  1276. bone_scroll_main_vb->add_child(sync_bones);
  1277. sync_bones->set_h_size_flags(0);
  1278. sync_bones->connect(SceneStringName(pressed), callable_mp(this, &Polygon2DEditor::_sync_bones));
  1279. uv_main_hsc->add_child(bone_scroll_main_vb);
  1280. bone_scroll = memnew(ScrollContainer);
  1281. bone_scroll->set_v_scroll(true);
  1282. bone_scroll->set_h_scroll(false);
  1283. bone_scroll_main_vb->add_child(bone_scroll);
  1284. bone_scroll->set_v_size_flags(SIZE_EXPAND_FILL);
  1285. bone_scroll_vb = memnew(VBoxContainer);
  1286. bone_scroll->add_child(bone_scroll_vb);
  1287. panner.instantiate();
  1288. panner->set_callbacks(callable_mp(this, &Polygon2DEditor::_pan_callback), callable_mp(this, &Polygon2DEditor::_zoom_callback));
  1289. canvas->connect(SceneStringName(draw), callable_mp(this, &Polygon2DEditor::_canvas_draw));
  1290. canvas->connect(SceneStringName(gui_input), callable_mp(this, &Polygon2DEditor::_canvas_input));
  1291. canvas->connect(SceneStringName(focus_exited), callable_mp(panner.ptr(), &ViewPanner::release_pan_key));
  1292. canvas->set_focus_mode(FOCUS_CLICK);
  1293. error = memnew(AcceptDialog);
  1294. add_child(error);
  1295. dock_button = EditorNode::get_bottom_panel()->add_item(TTR("Polygon"), polygon_edit, ED_SHORTCUT_AND_COMMAND("bottom_panels/toggle_polygon_2d_bottom_panel", TTR("Toggle Polygon Bottom Panel")));
  1296. dock_button->hide();
  1297. }
  1298. Polygon2DEditorPlugin::Polygon2DEditorPlugin() :
  1299. AbstractPolygon2DEditorPlugin(memnew(Polygon2DEditor), "Polygon2D") {
  1300. }