canvas_item_editor_plugin.cpp 170 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798
  1. /*************************************************************************/
  2. /* canvas_item_editor_plugin.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
  9. /* Copyright (c) 2014-2017 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. #include "canvas_item_editor_plugin.h"
  31. #include "editor/animation_editor.h"
  32. #include "editor/editor_node.h"
  33. #include "editor/editor_settings.h"
  34. #include "editor/plugins/animation_player_editor_plugin.h"
  35. #include "editor/plugins/script_editor_plugin.h"
  36. #include "editor/script_editor_debugger.h"
  37. #include "os/input.h"
  38. #include "os/keyboard.h"
  39. #include "print_string.h"
  40. #include "project_settings.h"
  41. #include "scene/2d/light_2d.h"
  42. #include "scene/2d/particles_2d.h"
  43. #include "scene/2d/polygon_2d.h"
  44. #include "scene/2d/screen_button.h"
  45. #include "scene/2d/sprite.h"
  46. #include "scene/gui/grid_container.h"
  47. #include "scene/gui/nine_patch_rect.h"
  48. #include "scene/main/canvas_layer.h"
  49. #include "scene/main/viewport.h"
  50. #include "scene/resources/packed_scene.h"
  51. #define MIN_ZOOM 0.01
  52. #define MAX_ZOOM 100
  53. #define RULER_WIDTH 15 * EDSCALE
  54. class SnapDialog : public ConfirmationDialog {
  55. GDCLASS(SnapDialog, ConfirmationDialog);
  56. friend class CanvasItemEditor;
  57. SpinBox *grid_offset_x;
  58. SpinBox *grid_offset_y;
  59. SpinBox *grid_step_x;
  60. SpinBox *grid_step_y;
  61. SpinBox *rotation_offset;
  62. SpinBox *rotation_step;
  63. public:
  64. SnapDialog()
  65. : ConfirmationDialog() {
  66. const int SPIN_BOX_GRID_RANGE = 256;
  67. const int SPIN_BOX_ROTATION_RANGE = 360;
  68. Label *label;
  69. VBoxContainer *container;
  70. GridContainer *child_container;
  71. set_title(TTR("Configure Snap"));
  72. get_ok()->set_text(TTR("Close"));
  73. container = memnew(VBoxContainer);
  74. add_child(container);
  75. //set_child_rect(container);
  76. child_container = memnew(GridContainer);
  77. child_container->set_columns(3);
  78. container->add_child(child_container);
  79. label = memnew(Label);
  80. label->set_text(TTR("Grid Offset:"));
  81. child_container->add_child(label);
  82. label->set_h_size_flags(SIZE_EXPAND_FILL);
  83. grid_offset_x = memnew(SpinBox);
  84. grid_offset_x->set_min(-SPIN_BOX_GRID_RANGE);
  85. grid_offset_x->set_max(SPIN_BOX_GRID_RANGE);
  86. grid_offset_x->set_suffix("px");
  87. child_container->add_child(grid_offset_x);
  88. grid_offset_y = memnew(SpinBox);
  89. grid_offset_y->set_min(-SPIN_BOX_GRID_RANGE);
  90. grid_offset_y->set_max(SPIN_BOX_GRID_RANGE);
  91. grid_offset_y->set_suffix("px");
  92. child_container->add_child(grid_offset_y);
  93. label = memnew(Label);
  94. label->set_text(TTR("Grid Step:"));
  95. child_container->add_child(label);
  96. label->set_h_size_flags(SIZE_EXPAND_FILL);
  97. grid_step_x = memnew(SpinBox);
  98. grid_step_x->set_min(0.01);
  99. grid_step_x->set_max(SPIN_BOX_GRID_RANGE);
  100. grid_step_x->set_suffix("px");
  101. child_container->add_child(grid_step_x);
  102. grid_step_y = memnew(SpinBox);
  103. grid_step_y->set_min(0.01);
  104. grid_step_y->set_max(SPIN_BOX_GRID_RANGE);
  105. grid_step_y->set_suffix("px");
  106. child_container->add_child(grid_step_y);
  107. container->add_child(memnew(HSeparator));
  108. child_container = memnew(GridContainer);
  109. child_container->set_columns(2);
  110. container->add_child(child_container);
  111. label = memnew(Label);
  112. label->set_text(TTR("Rotation Offset:"));
  113. child_container->add_child(label);
  114. label->set_h_size_flags(SIZE_EXPAND_FILL);
  115. rotation_offset = memnew(SpinBox);
  116. rotation_offset->set_min(-SPIN_BOX_ROTATION_RANGE);
  117. rotation_offset->set_max(SPIN_BOX_ROTATION_RANGE);
  118. rotation_offset->set_suffix("deg");
  119. child_container->add_child(rotation_offset);
  120. label = memnew(Label);
  121. label->set_text(TTR("Rotation Step:"));
  122. child_container->add_child(label);
  123. label->set_h_size_flags(SIZE_EXPAND_FILL);
  124. rotation_step = memnew(SpinBox);
  125. rotation_step->set_min(-SPIN_BOX_ROTATION_RANGE);
  126. rotation_step->set_max(SPIN_BOX_ROTATION_RANGE);
  127. rotation_step->set_suffix("deg");
  128. child_container->add_child(rotation_step);
  129. }
  130. void set_fields(const Point2 p_grid_offset, const Point2 p_grid_step, const float p_rotation_offset, const float p_rotation_step) {
  131. grid_offset_x->set_value(p_grid_offset.x);
  132. grid_offset_y->set_value(p_grid_offset.y);
  133. grid_step_x->set_value(p_grid_step.x);
  134. grid_step_y->set_value(p_grid_step.y);
  135. rotation_offset->set_value(p_rotation_offset * (180 / Math_PI));
  136. rotation_step->set_value(p_rotation_step * (180 / Math_PI));
  137. }
  138. void get_fields(Point2 &p_grid_offset, Point2 &p_grid_step, float &p_rotation_offset, float &p_rotation_step) {
  139. p_grid_offset = Point2(grid_offset_x->get_value(), grid_offset_y->get_value());
  140. p_grid_step = Point2(grid_step_x->get_value(), grid_step_y->get_value());
  141. p_rotation_offset = rotation_offset->get_value() / (180 / Math_PI);
  142. p_rotation_step = rotation_step->get_value() / (180 / Math_PI);
  143. }
  144. };
  145. void CanvasItemEditor::_edit_set_pivot(const Vector2 &mouse_pos) {
  146. List<Node *> &selection = editor_selection->get_selected_node_list();
  147. undo_redo->create_action(TTR("Move Pivot"));
  148. for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
  149. Node2D *n2d = Object::cast_to<Node2D>(E->get());
  150. if (n2d && n2d->edit_has_pivot()) {
  151. Vector2 offset = n2d->edit_get_pivot();
  152. Vector2 gpos = n2d->get_global_position();
  153. Vector2 local_mouse_pos = n2d->get_canvas_transform().affine_inverse().xform(mouse_pos);
  154. Vector2 motion_ofs = gpos - local_mouse_pos;
  155. undo_redo->add_do_method(n2d, "set_global_position", local_mouse_pos);
  156. undo_redo->add_do_method(n2d, "edit_set_pivot", offset + n2d->get_global_transform().affine_inverse().basis_xform(motion_ofs));
  157. undo_redo->add_undo_method(n2d, "set_global_position", gpos);
  158. undo_redo->add_undo_method(n2d, "edit_set_pivot", offset);
  159. for (int i = 0; i < n2d->get_child_count(); i++) {
  160. Node2D *n2dc = Object::cast_to<Node2D>(n2d->get_child(i));
  161. if (!n2dc)
  162. continue;
  163. undo_redo->add_do_method(n2dc, "set_global_position", n2dc->get_global_position());
  164. undo_redo->add_undo_method(n2dc, "set_global_position", n2dc->get_global_position());
  165. }
  166. }
  167. Control *cnt = Object::cast_to<Control>(E->get());
  168. if (cnt) {
  169. Vector2 old_pivot = cnt->get_pivot_offset();
  170. Vector2 new_pivot = cnt->get_global_transform_with_canvas().affine_inverse().xform(mouse_pos);
  171. Vector2 old_pos = cnt->get_position();
  172. Vector2 top_pos = cnt->get_transform().get_origin(); //remember where top pos was
  173. cnt->set_pivot_offset(new_pivot);
  174. Vector2 new_top_pos = cnt->get_transform().get_origin(); //check where it is now
  175. Vector2 new_pos = old_pos - (new_top_pos - top_pos); //offset it back
  176. undo_redo->add_do_method(cnt, "set_pivot_offset", new_pivot);
  177. undo_redo->add_do_method(cnt, "set_position", new_pos);
  178. undo_redo->add_undo_method(cnt, "set_pivot_offset", old_pivot);
  179. undo_redo->add_undo_method(cnt, "set_position", old_pos);
  180. }
  181. }
  182. undo_redo->commit_action();
  183. }
  184. void CanvasItemEditor::_snap_if_closer_float(float p_value, float p_target_snap, float &r_current_snap, bool &r_snapped, float p_radius) {
  185. float radius = p_radius / zoom;
  186. float dist = Math::abs(p_value - p_target_snap);
  187. if (p_radius < 0 || dist < radius && (!r_snapped || dist < Math::abs(r_current_snap - p_value))) {
  188. r_current_snap = p_target_snap;
  189. r_snapped = true;
  190. }
  191. }
  192. void CanvasItemEditor::_snap_if_closer_point(Point2 p_value, Point2 p_target_snap, Point2 &r_current_snap, bool (&r_snapped)[2], real_t rotation, float p_radius) {
  193. Transform2D rot_trans = Transform2D(rotation, Point2());
  194. p_value = rot_trans.inverse().xform(p_value);
  195. p_target_snap = rot_trans.inverse().xform(p_target_snap);
  196. r_current_snap = rot_trans.inverse().xform(r_current_snap);
  197. _snap_if_closer_float(p_value.x, p_target_snap.x, r_current_snap.x, r_snapped[0], p_radius);
  198. _snap_if_closer_float(p_value.y, p_target_snap.y, r_current_snap.y, r_snapped[1], p_radius);
  199. r_current_snap = rot_trans.xform(r_current_snap);
  200. }
  201. void CanvasItemEditor::_snap_other_nodes(Point2 p_value, Point2 &r_current_snap, bool (&r_snapped)[2], const Node *p_current, const CanvasItem *p_to_snap) {
  202. const CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_current);
  203. if (canvas_item && (!p_to_snap || p_current != p_to_snap)) {
  204. Transform2D ci_transform = canvas_item->get_global_transform_with_canvas();
  205. Transform2D to_snap_transform = p_to_snap ? p_to_snap->get_global_transform_with_canvas() : Transform2D();
  206. if (fmod(ci_transform.get_rotation() - to_snap_transform.get_rotation(), (real_t)360.0) == 0.0) {
  207. Point2 begin = ci_transform.xform(canvas_item->get_item_rect().get_position());
  208. Point2 end = ci_transform.xform(canvas_item->get_item_rect().get_position() + canvas_item->get_item_rect().get_size());
  209. _snap_if_closer_point(p_value, begin, r_current_snap, r_snapped, ci_transform.get_rotation());
  210. _snap_if_closer_point(p_value, end, r_current_snap, r_snapped, ci_transform.get_rotation());
  211. }
  212. }
  213. for (int i = 0; i < p_current->get_child_count(); i++) {
  214. _snap_other_nodes(p_value, r_current_snap, r_snapped, p_current->get_child(i), p_to_snap);
  215. }
  216. }
  217. Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, const CanvasItem *p_canvas_item, unsigned int p_forced_modes) {
  218. Point2 dist[2];
  219. bool snapped[2] = { false, false };
  220. // Smart snap using the canvas position
  221. Vector2 output = p_target;
  222. real_t rotation = 0.0;
  223. if (p_canvas_item) {
  224. Point2 begin;
  225. Point2 end;
  226. rotation = p_canvas_item->get_global_transform_with_canvas().get_rotation();
  227. if ((snap_active && snap_node_parent && (p_modes & SNAP_NODE_PARENT)) || (p_forced_modes & SNAP_NODE_PARENT)) {
  228. // Parent sides and center
  229. bool can_snap = false;
  230. if (const Control *c = Object::cast_to<Control>(p_canvas_item)) {
  231. begin = p_canvas_item->get_global_transform_with_canvas().xform(_anchor_to_position(c, Point2(0, 0)));
  232. end = p_canvas_item->get_global_transform_with_canvas().xform(_anchor_to_position(c, Point2(1, 1)));
  233. can_snap = true;
  234. } else if (const CanvasItem *parent_ci = Object::cast_to<CanvasItem>(p_canvas_item->get_parent())) {
  235. begin = p_canvas_item->get_transform().affine_inverse().xform(parent_ci->get_item_rect().get_position());
  236. end = p_canvas_item->get_transform().affine_inverse().xform(parent_ci->get_item_rect().get_position() + parent_ci->get_item_rect().get_size());
  237. can_snap = true;
  238. }
  239. if (can_snap) {
  240. _snap_if_closer_point(p_target, begin, output, snapped, rotation);
  241. _snap_if_closer_point(p_target, (begin + end) / 2.0, output, snapped, rotation);
  242. _snap_if_closer_point(p_target, end, output, snapped, rotation);
  243. }
  244. }
  245. // Self anchors (for sides)
  246. if ((snap_active && snap_node_anchors && (p_modes & SNAP_NODE_ANCHORS)) || (p_forced_modes & SNAP_NODE_ANCHORS)) {
  247. if (const Control *c = Object::cast_to<Control>(p_canvas_item)) {
  248. begin = p_canvas_item->get_global_transform_with_canvas().xform(_anchor_to_position(c, Point2(c->get_anchor(MARGIN_LEFT), c->get_anchor(MARGIN_TOP))));
  249. end = p_canvas_item->get_global_transform_with_canvas().xform(_anchor_to_position(c, Point2(c->get_anchor(MARGIN_RIGHT), c->get_anchor(MARGIN_BOTTOM))));
  250. _snap_if_closer_point(p_target, begin, output, snapped, rotation);
  251. _snap_if_closer_point(p_target, end, output, snapped, rotation);
  252. }
  253. }
  254. // Self sides (for anchors)
  255. if ((snap_active && snap_node_sides && (p_modes & SNAP_NODE_SIDES)) || (p_forced_modes & SNAP_NODE_SIDES)) {
  256. begin = p_canvas_item->get_global_transform_with_canvas().xform(p_canvas_item->get_item_rect().get_position());
  257. end = p_canvas_item->get_global_transform_with_canvas().xform(p_canvas_item->get_item_rect().get_position() + p_canvas_item->get_item_rect().get_size());
  258. _snap_if_closer_point(p_target, begin, output, snapped, rotation);
  259. _snap_if_closer_point(p_target, end, output, snapped, rotation);
  260. }
  261. }
  262. // Other nodes sides
  263. if ((snap_active && snap_other_nodes && (p_modes & SNAP_OTHER_NODES)) || (p_forced_modes & SNAP_OTHER_NODES)) {
  264. _snap_other_nodes(p_target, output, snapped, get_tree()->get_edited_scene_root(), p_canvas_item);
  265. }
  266. if (((snap_active && snap_guides && (p_modes & SNAP_GUIDES)) || (p_forced_modes & SNAP_GUIDES)) && fmod(rotation, (real_t)360.0) == 0.0) {
  267. // Guides
  268. if (EditorNode::get_singleton()->get_edited_scene() && EditorNode::get_singleton()->get_edited_scene()->has_meta("_edit_vertical_guides_")) {
  269. Array vguides = EditorNode::get_singleton()->get_edited_scene()->get_meta("_edit_vertical_guides_");
  270. for (int i = 0; i < vguides.size(); i++) {
  271. _snap_if_closer_float(p_target.x, vguides[i], output.x, snapped[0]);
  272. }
  273. }
  274. if (EditorNode::get_singleton()->get_edited_scene() && EditorNode::get_singleton()->get_edited_scene()->has_meta("_edit_horizontal_guides_")) {
  275. Array hguides = EditorNode::get_singleton()->get_edited_scene()->get_meta("_edit_horizontal_guides_");
  276. for (int i = 0; i < hguides.size(); i++) {
  277. _snap_if_closer_float(p_target.y, hguides[i], output.y, snapped[1]);
  278. }
  279. }
  280. }
  281. if (((snap_active && snap_grid && (p_modes & SNAP_GRID)) || (p_forced_modes & SNAP_GRID)) && fmod(rotation, (real_t)360.0) == 0.0) {
  282. // Grid
  283. Point2 offset = grid_offset;
  284. if (snap_relative) {
  285. List<Node *> &selection = editor_selection->get_selected_node_list();
  286. if (selection.size() == 1 && Object::cast_to<Node2D>(selection[0])) {
  287. offset = Object::cast_to<Node2D>(selection[0])->get_global_position();
  288. } else {
  289. offset = _find_topleftmost_point();
  290. }
  291. }
  292. Point2 grid_output;
  293. grid_output.x = Math::stepify(p_target.x - offset.x, grid_step.x * Math::pow(2.0, grid_step_multiplier)) + offset.x;
  294. grid_output.y = Math::stepify(p_target.y - offset.y, grid_step.y * Math::pow(2.0, grid_step_multiplier)) + offset.y;
  295. _snap_if_closer_point(p_target, grid_output, output, snapped, 0.0, -1.0);
  296. }
  297. if (((snap_pixel && (p_modes & SNAP_PIXEL)) || (p_forced_modes & SNAP_PIXEL)) && rotation == 0.0) {
  298. // Pixel
  299. output = output.snapped(Size2(1, 1));
  300. }
  301. return output;
  302. }
  303. float CanvasItemEditor::snap_angle(float p_target, float p_start) const {
  304. float offset = snap_relative ? p_start : p_target;
  305. return (snap_rotation && snap_rotation_step != 0) ? Math::stepify(p_target - snap_rotation_offset, snap_rotation_step) + snap_rotation_offset : p_target;
  306. }
  307. void CanvasItemEditor::_unhandled_key_input(const Ref<InputEvent> &p_ev) {
  308. Ref<InputEventKey> k = p_ev;
  309. if (!is_visible_in_tree() || get_viewport()->gui_has_modal_stack())
  310. return;
  311. if (k->get_control())
  312. return;
  313. if (k->is_pressed() && !k->is_echo()) {
  314. if (drag_pivot_shortcut.is_valid() && drag_pivot_shortcut->is_shortcut(p_ev) && drag == DRAG_NONE && can_move_pivot) {
  315. //move drag pivot
  316. drag = DRAG_PIVOT;
  317. } else if (set_pivot_shortcut.is_valid() && set_pivot_shortcut->is_shortcut(p_ev) && drag == DRAG_NONE && can_move_pivot) {
  318. if (!Input::get_singleton()->is_mouse_button_pressed(0)) {
  319. List<Node *> &selection = editor_selection->get_selected_node_list();
  320. Vector2 mouse_pos = viewport->get_local_mouse_position();
  321. if (selection.size() && viewport->get_rect().has_point(mouse_pos)) {
  322. //just in case, make it work if over viewport
  323. mouse_pos = transform.affine_inverse().xform(mouse_pos);
  324. mouse_pos = snap_point(mouse_pos, SNAP_DEFAULT, _get_single_item());
  325. _edit_set_pivot(mouse_pos);
  326. }
  327. }
  328. } else if ((snap_grid || show_grid) && multiply_grid_step_shortcut.is_valid() && multiply_grid_step_shortcut->is_shortcut(p_ev)) {
  329. // Multiply the grid size
  330. grid_step_multiplier = MIN(grid_step_multiplier + 1, 12);
  331. viewport_base->update();
  332. viewport->update();
  333. } else if ((snap_grid || show_grid) && divide_grid_step_shortcut.is_valid() && divide_grid_step_shortcut->is_shortcut(p_ev)) {
  334. // Divide the grid size
  335. Point2 new_grid_step = grid_step * Math::pow(2.0, grid_step_multiplier - 1);
  336. if (new_grid_step.x >= 1.0 && new_grid_step.y >= 1.0)
  337. grid_step_multiplier--;
  338. viewport_base->update();
  339. viewport->update();
  340. }
  341. }
  342. }
  343. void CanvasItemEditor::_tool_select(int p_index) {
  344. ToolButton *tb[TOOL_MAX] = { select_button, list_select_button, move_button, rotate_button, pivot_button, pan_button };
  345. for (int i = 0; i < TOOL_MAX; i++) {
  346. tb[i]->set_pressed(i == p_index);
  347. }
  348. viewport->update();
  349. tool = (Tool)p_index;
  350. }
  351. Object *CanvasItemEditor::_get_editor_data(Object *p_what) {
  352. CanvasItem *ci = Object::cast_to<CanvasItem>(p_what);
  353. if (!ci)
  354. return NULL;
  355. return memnew(CanvasItemEditorSelectedItem);
  356. }
  357. Dictionary CanvasItemEditor::get_state() const {
  358. Dictionary state;
  359. state["zoom"] = zoom;
  360. state["ofs"] = Point2(h_scroll->get_value(), v_scroll->get_value());
  361. //state["ofs"]=-transform.get_origin();
  362. state["grid_offset"] = grid_offset;
  363. state["grid_step"] = grid_step;
  364. state["snap_rotation_offset"] = snap_rotation_offset;
  365. state["snap_rotation_step"] = snap_rotation_step;
  366. state["snap_active"] = snap_active;
  367. state["snap_node_parent"] = snap_node_parent;
  368. state["snap_node_anchors"] = snap_node_anchors;
  369. state["snap_node_sides"] = snap_node_sides;
  370. state["snap_other_nodes"] = snap_other_nodes;
  371. state["snap_grid"] = snap_grid;
  372. state["snap_guides"] = snap_guides;
  373. state["show_grid"] = show_grid;
  374. state["show_rulers"] = show_rulers;
  375. state["show_guides"] = show_guides;
  376. state["show_helpers"] = show_helpers;
  377. state["snap_rotation"] = snap_rotation;
  378. state["snap_relative"] = snap_relative;
  379. state["snap_pixel"] = snap_pixel;
  380. state["skeleton_show_bones"] = skeleton_show_bones;
  381. return state;
  382. }
  383. void CanvasItemEditor::set_state(const Dictionary &p_state) {
  384. Dictionary state = p_state;
  385. if (state.has("zoom")) {
  386. zoom = p_state["zoom"];
  387. }
  388. if (state.has("ofs")) {
  389. _update_scrollbars(); // i wonder how safe is calling this here..
  390. Point2 ofs = p_state["ofs"];
  391. h_scroll->set_value(ofs.x);
  392. v_scroll->set_value(ofs.y);
  393. }
  394. if (state.has("grid_offset")) {
  395. grid_offset = state["grid_offset"];
  396. }
  397. if (state.has("grid_step")) {
  398. grid_step = state["grid_step"];
  399. }
  400. if (state.has("snap_rotation_step")) {
  401. snap_rotation_step = state["snap_rotation_step"];
  402. }
  403. if (state.has("snap_rotation_offset")) {
  404. snap_rotation_offset = state["snap_rotation_offset"];
  405. }
  406. if (state.has("snap_active")) {
  407. snap_active = state["snap_active"];
  408. snap_button->set_pressed(snap_active);
  409. }
  410. if (state.has("snap_node_parent")) {
  411. snap_node_parent = state["snap_node_parent"];
  412. int idx = smartsnap_config_popup->get_item_index(SNAP_USE_NODE_PARENT);
  413. smartsnap_config_popup->set_item_checked(idx, snap_node_parent);
  414. }
  415. if (state.has("snap_node_anchors")) {
  416. snap_node_anchors = state["snap_node_anchors"];
  417. int idx = smartsnap_config_popup->get_item_index(SNAP_USE_NODE_ANCHORS);
  418. smartsnap_config_popup->set_item_checked(idx, snap_node_anchors);
  419. }
  420. if (state.has("snap_node_sides")) {
  421. snap_node_sides = state["snap_node_sides"];
  422. int idx = smartsnap_config_popup->get_item_index(SNAP_USE_NODE_SIDES);
  423. smartsnap_config_popup->set_item_checked(idx, snap_node_sides);
  424. }
  425. if (state.has("snap_other_nodes")) {
  426. snap_other_nodes = state["snap_other_nodes"];
  427. int idx = smartsnap_config_popup->get_item_index(SNAP_USE_OTHER_NODES);
  428. smartsnap_config_popup->set_item_checked(idx, snap_other_nodes);
  429. }
  430. if (state.has("snap_guides")) {
  431. snap_guides = state["snap_guides"];
  432. int idx = smartsnap_config_popup->get_item_index(SNAP_USE_GUIDES);
  433. smartsnap_config_popup->set_item_checked(idx, snap_guides);
  434. }
  435. if (state.has("snap_grid")) {
  436. snap_grid = state["snap_grid"];
  437. int idx = snap_config_menu->get_popup()->get_item_index(SNAP_USE_GRID);
  438. snap_config_menu->get_popup()->set_item_checked(idx, snap_grid);
  439. }
  440. if (state.has("show_grid")) {
  441. show_grid = state["show_grid"];
  442. int idx = view_menu->get_popup()->get_item_index(SHOW_GRID);
  443. view_menu->get_popup()->set_item_checked(idx, show_grid);
  444. }
  445. if (state.has("show_rulers")) {
  446. show_rulers = state["show_rulers"];
  447. int idx = view_menu->get_popup()->get_item_index(SHOW_RULERS);
  448. view_menu->get_popup()->set_item_checked(idx, show_rulers);
  449. }
  450. if (state.has("show_guides")) {
  451. show_guides = state["show_guides"];
  452. int idx = view_menu->get_popup()->get_item_index(SHOW_GUIDES);
  453. view_menu->get_popup()->set_item_checked(idx, show_guides);
  454. }
  455. if (state.has("show_helpers")) {
  456. show_helpers = state["show_helpers"];
  457. int idx = view_menu->get_popup()->get_item_index(SHOW_HELPERS);
  458. view_menu->get_popup()->set_item_checked(idx, show_helpers);
  459. }
  460. if (state.has("snap_rotation")) {
  461. snap_rotation = state["snap_rotation"];
  462. int idx = snap_config_menu->get_popup()->get_item_index(SNAP_USE_ROTATION);
  463. snap_config_menu->get_popup()->set_item_checked(idx, snap_rotation);
  464. }
  465. if (state.has("snap_relative")) {
  466. snap_relative = state["snap_relative"];
  467. int idx = snap_config_menu->get_popup()->get_item_index(SNAP_RELATIVE);
  468. snap_config_menu->get_popup()->set_item_checked(idx, snap_relative);
  469. }
  470. if (state.has("snap_pixel")) {
  471. snap_pixel = state["snap_pixel"];
  472. int idx = snap_config_menu->get_popup()->get_item_index(SNAP_USE_PIXEL);
  473. snap_config_menu->get_popup()->set_item_checked(idx, snap_pixel);
  474. }
  475. if (state.has("skeleton_show_bones")) {
  476. skeleton_show_bones = state["skeleton_show_bones"];
  477. int idx = skeleton_menu->get_popup()->get_item_index(SKELETON_SHOW_BONES);
  478. skeleton_menu->get_popup()->set_item_checked(idx, skeleton_show_bones);
  479. }
  480. viewport->update();
  481. }
  482. void CanvasItemEditor::_add_canvas_item(CanvasItem *p_canvas_item) {
  483. editor_selection->add_node(p_canvas_item);
  484. }
  485. void CanvasItemEditor::_remove_canvas_item(CanvasItem *p_canvas_item) {
  486. editor_selection->remove_node(p_canvas_item);
  487. }
  488. void CanvasItemEditor::_clear_canvas_items() {
  489. editor_selection->clear();
  490. }
  491. void CanvasItemEditor::_keying_changed() {
  492. if (AnimationPlayerEditor::singleton->get_key_editor()->is_visible_in_tree())
  493. animation_hb->show();
  494. else
  495. animation_hb->hide();
  496. }
  497. bool CanvasItemEditor::_is_part_of_subscene(CanvasItem *p_item) {
  498. Node *scene_node = get_tree()->get_edited_scene_root();
  499. Node *item_owner = p_item->get_owner();
  500. return item_owner && item_owner != scene_node && p_item != scene_node && item_owner->get_filename() != "";
  501. }
  502. void CanvasItemEditor::_find_canvas_items_at_pos(const Point2 &p_pos, Node *p_node, const Transform2D &p_parent_xform, const Transform2D &p_canvas_xform, Vector<_SelectResult> &r_items, int limit) {
  503. if (!p_node)
  504. return;
  505. if (Object::cast_to<Viewport>(p_node))
  506. return;
  507. CanvasItem *c = Object::cast_to<CanvasItem>(p_node);
  508. for (int i = p_node->get_child_count() - 1; i >= 0; i--) {
  509. if (c && !c->is_set_as_toplevel())
  510. _find_canvas_items_at_pos(p_pos, p_node->get_child(i), p_parent_xform * c->get_transform(), p_canvas_xform, r_items);
  511. else {
  512. CanvasLayer *cl = Object::cast_to<CanvasLayer>(p_node);
  513. _find_canvas_items_at_pos(p_pos, p_node->get_child(i), transform, cl ? cl->get_transform() : p_canvas_xform, r_items); //use base transform
  514. }
  515. if (limit != 0 && r_items.size() >= limit)
  516. return;
  517. }
  518. if (c && c->is_visible_in_tree() && !c->has_meta("_edit_lock_") && !Object::cast_to<CanvasLayer>(c)) {
  519. Rect2 rect = c->get_item_rect();
  520. Point2 local_pos = (p_parent_xform * p_canvas_xform * c->get_transform()).affine_inverse().xform(p_pos);
  521. if (rect.has_point(local_pos)) {
  522. Node2D *node = Object::cast_to<Node2D>(c);
  523. _SelectResult res;
  524. res.item = c;
  525. res.z = node ? node->get_z() : 0;
  526. res.has_z = node;
  527. r_items.push_back(res);
  528. }
  529. }
  530. return;
  531. }
  532. void CanvasItemEditor::_find_canvas_items_at_rect(const Rect2 &p_rect, Node *p_node, const Transform2D &p_parent_xform, const Transform2D &p_canvas_xform, List<CanvasItem *> *r_items) {
  533. if (!p_node)
  534. return;
  535. if (Object::cast_to<Viewport>(p_node))
  536. return;
  537. CanvasItem *c = Object::cast_to<CanvasItem>(p_node);
  538. bool inherited = p_node != get_tree()->get_edited_scene_root() && p_node->get_filename() != "";
  539. bool editable = false;
  540. if (inherited) {
  541. editable = EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(p_node);
  542. }
  543. bool lock_children = p_node->has_meta("_edit_group_") && p_node->get_meta("_edit_group_");
  544. if (!lock_children && (!inherited || editable)) {
  545. for (int i = p_node->get_child_count() - 1; i >= 0; i--) {
  546. if (c && !c->is_set_as_toplevel())
  547. _find_canvas_items_at_rect(p_rect, p_node->get_child(i), p_parent_xform * c->get_transform(), p_canvas_xform, r_items);
  548. else {
  549. CanvasLayer *cl = Object::cast_to<CanvasLayer>(p_node);
  550. _find_canvas_items_at_rect(p_rect, p_node->get_child(i), transform, cl ? cl->get_transform() : p_canvas_xform, r_items);
  551. }
  552. }
  553. }
  554. if (c && c->is_visible_in_tree() && !c->has_meta("_edit_lock_") && !Object::cast_to<CanvasLayer>(c)) {
  555. Rect2 rect = c->get_item_rect();
  556. Transform2D xform = p_parent_xform * p_canvas_xform * c->get_transform();
  557. if (p_rect.has_point(xform.xform(rect.position)) &&
  558. p_rect.has_point(xform.xform(rect.position + Vector2(rect.size.x, 0))) &&
  559. p_rect.has_point(xform.xform(rect.position + Vector2(rect.size.x, rect.size.y))) &&
  560. p_rect.has_point(xform.xform(rect.position + Vector2(0, rect.size.y)))) {
  561. r_items->push_back(c);
  562. }
  563. }
  564. }
  565. void CanvasItemEditor::_select_click_on_empty_area(Point2 p_click_pos, bool p_append, bool p_box_selection) {
  566. if (!p_append) {
  567. editor_selection->clear();
  568. viewport->update();
  569. viewport_base->update();
  570. };
  571. if (p_box_selection) {
  572. // Start a box selection
  573. drag_from = transform.affine_inverse().xform(p_click_pos);
  574. box_selecting = true;
  575. box_selecting_to = drag_from;
  576. }
  577. }
  578. bool CanvasItemEditor::_select_click_on_item(CanvasItem *item, Point2 p_click_pos, bool p_append, bool p_drag) {
  579. bool still_selected = true;
  580. if (p_append) {
  581. if (editor_selection->is_selected(item)) {
  582. // Already in the selection, remove it from the selected nodes
  583. editor_selection->remove_node(item);
  584. still_selected = false;
  585. } else {
  586. // Add the item to the selection
  587. _append_canvas_item(item);
  588. }
  589. } else {
  590. if (!editor_selection->is_selected(item)) {
  591. // Select a new one and clear previous selection
  592. editor_selection->clear();
  593. editor_selection->add_node(item);
  594. // Reselect
  595. if (Engine::get_singleton()->is_editor_hint()) {
  596. editor->call("edit_node", item);
  597. }
  598. }
  599. }
  600. if (still_selected && p_drag) {
  601. // Drag the node(s) if requested
  602. _prepare_drag(p_click_pos);
  603. }
  604. viewport->update();
  605. viewport_base->update();
  606. return still_selected;
  607. }
  608. void CanvasItemEditor::_key_move(const Vector2 &p_dir, bool p_snap, KeyMoveMODE p_move_mode) {
  609. if (drag != DRAG_NONE)
  610. return;
  611. if (editor_selection->get_selected_node_list().empty())
  612. return;
  613. undo_redo->create_action(TTR("Move Action"), UndoRedo::MERGE_ENDS);
  614. List<Node *> &selection = editor_selection->get_selected_node_list();
  615. for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
  616. CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->get());
  617. if (!canvas_item || !canvas_item->is_visible_in_tree())
  618. continue;
  619. if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root())
  620. continue;
  621. CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item);
  622. if (!se)
  623. continue;
  624. if (canvas_item->has_meta("_edit_lock_"))
  625. continue;
  626. Vector2 drag = p_dir;
  627. if (p_snap)
  628. drag *= grid_step * Math::pow(2.0, grid_step_multiplier);
  629. undo_redo->add_undo_method(canvas_item, "edit_set_state", canvas_item->edit_get_state());
  630. if (p_move_mode == MOVE_VIEW_BASE) {
  631. // drag = transform.affine_inverse().basis_xform(p_dir); // zoom sensitive
  632. drag = canvas_item->get_global_transform_with_canvas().affine_inverse().basis_xform(drag);
  633. Rect2 local_rect = canvas_item->get_item_rect();
  634. local_rect.position += drag;
  635. undo_redo->add_do_method(canvas_item, "edit_set_rect", local_rect);
  636. } else { // p_move_mode==MOVE_LOCAL_BASE || p_move_mode==MOVE_LOCAL_WITH_ROT
  637. Node2D *node_2d = Object::cast_to<Node2D>(canvas_item);
  638. if (node_2d) {
  639. if (p_move_mode == MOVE_LOCAL_WITH_ROT) {
  640. Transform2D m;
  641. m.rotate(node_2d->get_rotation());
  642. drag = m.xform(drag);
  643. }
  644. node_2d->set_position(node_2d->get_position() + drag);
  645. } else {
  646. Control *control = Object::cast_to<Control>(canvas_item);
  647. if (control)
  648. control->set_position(control->get_position() + drag);
  649. }
  650. }
  651. }
  652. undo_redo->commit_action();
  653. }
  654. Point2 CanvasItemEditor::_find_topleftmost_point() {
  655. Vector2 tl = Point2(1e10, 1e10);
  656. Rect2 r2;
  657. r2.position = tl;
  658. List<Node *> &selection = editor_selection->get_selected_node_list();
  659. for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
  660. CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->get());
  661. if (!canvas_item || !canvas_item->is_visible_in_tree())
  662. continue;
  663. if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root())
  664. continue;
  665. Rect2 rect = canvas_item->get_item_rect();
  666. Transform2D xform = canvas_item->get_global_transform_with_canvas();
  667. r2.expand_to(xform.xform(rect.position));
  668. r2.expand_to(xform.xform(rect.position + Vector2(rect.size.x, 0)));
  669. r2.expand_to(xform.xform(rect.position + rect.size));
  670. r2.expand_to(xform.xform(rect.position + Vector2(0, rect.size.y)));
  671. }
  672. return r2.position;
  673. }
  674. int CanvasItemEditor::get_item_count() {
  675. List<Node *> &selection = editor_selection->get_selected_node_list();
  676. int ic = 0;
  677. for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
  678. CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->get());
  679. if (!canvas_item || !canvas_item->is_visible_in_tree())
  680. continue;
  681. if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root())
  682. continue;
  683. ic++;
  684. };
  685. return ic;
  686. }
  687. CanvasItem *CanvasItemEditor::_get_single_item() {
  688. Map<Node *, Object *> &selection = editor_selection->get_selection();
  689. CanvasItem *single_item = NULL;
  690. for (Map<Node *, Object *>::Element *E = selection.front(); E; E = E->next()) {
  691. CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->key());
  692. if (!canvas_item || !canvas_item->is_visible_in_tree())
  693. continue;
  694. if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root())
  695. continue;
  696. if (single_item)
  697. return NULL; //morethan one
  698. single_item = canvas_item;
  699. };
  700. return single_item;
  701. }
  702. CanvasItemEditor::DragType CanvasItemEditor::_get_resize_handle_drag_type(const Point2 &p_click, Vector2 &r_point) {
  703. // Returns a drag type if a resize handle is clicked
  704. CanvasItem *canvas_item = _get_single_item();
  705. ERR_FAIL_COND_V(!canvas_item, DRAG_NONE);
  706. Rect2 rect = canvas_item->get_item_rect();
  707. Transform2D xforml = canvas_item->get_global_transform_with_canvas();
  708. Transform2D xform = transform * xforml;
  709. Vector2 endpoints[4] = {
  710. xform.xform(rect.position),
  711. xform.xform(rect.position + Vector2(rect.size.x, 0)),
  712. xform.xform(rect.position + rect.size),
  713. xform.xform(rect.position + Vector2(0, rect.size.y))
  714. };
  715. Vector2 endpointsl[4] = {
  716. xforml.xform(rect.position),
  717. xforml.xform(rect.position + Vector2(rect.size.x, 0)),
  718. xforml.xform(rect.position + rect.size),
  719. xforml.xform(rect.position + Vector2(0, rect.size.y))
  720. };
  721. DragType dragger[] = {
  722. DRAG_TOP_LEFT,
  723. DRAG_TOP,
  724. DRAG_TOP_RIGHT,
  725. DRAG_RIGHT,
  726. DRAG_BOTTOM_RIGHT,
  727. DRAG_BOTTOM,
  728. DRAG_BOTTOM_LEFT,
  729. DRAG_LEFT
  730. };
  731. float radius = (select_handle->get_size().width / 2) * 1.5;
  732. for (int i = 0; i < 4; i++) {
  733. int prev = (i + 3) % 4;
  734. int next = (i + 1) % 4;
  735. r_point = endpointsl[i];
  736. Vector2 ofs = ((endpoints[i] - endpoints[prev]).normalized() + ((endpoints[i] - endpoints[next]).normalized())).normalized();
  737. ofs *= 1.4144 * (select_handle->get_size().width / 2);
  738. ofs += endpoints[i];
  739. if (ofs.distance_to(p_click) < radius)
  740. return dragger[i * 2];
  741. ofs = (endpoints[i] + endpoints[next]) / 2;
  742. ofs += (endpoints[next] - endpoints[i]).tangent().normalized() * (select_handle->get_size().width / 2);
  743. r_point = (endpointsl[i] + endpointsl[next]) / 2;
  744. if (ofs.distance_to(p_click) < radius)
  745. return dragger[i * 2 + 1];
  746. }
  747. return DRAG_NONE;
  748. }
  749. Vector2 CanvasItemEditor::_anchor_to_position(const Control *p_control, Vector2 anchor) {
  750. ERR_FAIL_COND_V(!p_control, Vector2());
  751. Transform2D parent_transform = p_control->get_transform().affine_inverse();
  752. Size2 parent_size = p_control->get_parent_area_size();
  753. return parent_transform.xform(Vector2(parent_size.x * anchor.x, parent_size.y * anchor.y));
  754. }
  755. Vector2 CanvasItemEditor::_position_to_anchor(const Control *p_control, Vector2 position) {
  756. ERR_FAIL_COND_V(!p_control, Vector2());
  757. Size2 parent_size = p_control->get_parent_area_size();
  758. return p_control->get_transform().xform(position) / parent_size;
  759. }
  760. CanvasItemEditor::DragType CanvasItemEditor::_get_anchor_handle_drag_type(const Point2 &p_click, Vector2 &r_point) {
  761. // Returns a drag type if an anchor handle is clicked
  762. CanvasItem *canvas_item = _get_single_item();
  763. ERR_FAIL_COND_V(!canvas_item, DRAG_NONE);
  764. Control *control = Object::cast_to<Control>(canvas_item);
  765. ERR_FAIL_COND_V(!control, DRAG_NONE);
  766. Vector2 anchor_pos[4];
  767. anchor_pos[0] = Vector2(control->get_anchor(MARGIN_LEFT), control->get_anchor(MARGIN_TOP));
  768. anchor_pos[1] = Vector2(control->get_anchor(MARGIN_RIGHT), control->get_anchor(MARGIN_TOP));
  769. anchor_pos[2] = Vector2(control->get_anchor(MARGIN_RIGHT), control->get_anchor(MARGIN_BOTTOM));
  770. anchor_pos[3] = Vector2(control->get_anchor(MARGIN_LEFT), control->get_anchor(MARGIN_BOTTOM));
  771. Rect2 anchor_rects[4];
  772. for (int i = 0; i < 4; i++) {
  773. anchor_pos[i] = (transform * control->get_global_transform_with_canvas()).xform(_anchor_to_position(control, anchor_pos[i]));
  774. anchor_rects[i] = Rect2(anchor_pos[i], anchor_handle->get_size());
  775. anchor_rects[i].position -= anchor_handle->get_size() * Vector2(i == 0 || i == 3, i <= 1);
  776. }
  777. DragType dragger[] = {
  778. DRAG_ANCHOR_TOP_LEFT,
  779. DRAG_ANCHOR_TOP_RIGHT,
  780. DRAG_ANCHOR_BOTTOM_RIGHT,
  781. DRAG_ANCHOR_BOTTOM_LEFT,
  782. };
  783. for (int i = 0; i < 4; i++) {
  784. if (anchor_rects[i].has_point(p_click)) {
  785. r_point = transform.affine_inverse().xform(anchor_pos[i]);
  786. if ((anchor_pos[0] == anchor_pos[2]) && (anchor_pos[0].distance_to(p_click) < anchor_handle->get_size().length() / 3.0)) {
  787. return DRAG_ANCHOR_ALL;
  788. } else {
  789. return dragger[i];
  790. }
  791. }
  792. }
  793. return DRAG_NONE;
  794. }
  795. void CanvasItemEditor::_prepare_drag(const Point2 &p_click_pos) {
  796. List<Node *> &selection = editor_selection->get_selected_node_list();
  797. for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
  798. CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->get());
  799. if (!canvas_item || !canvas_item->is_visible_in_tree())
  800. continue;
  801. if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root())
  802. continue;
  803. CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item);
  804. if (!se)
  805. continue;
  806. se->undo_state = canvas_item->edit_get_state();
  807. if (Object::cast_to<Node2D>(canvas_item))
  808. se->undo_pivot = Object::cast_to<Node2D>(canvas_item)->edit_get_pivot();
  809. if (Object::cast_to<Control>(canvas_item))
  810. se->undo_pivot = Object::cast_to<Control>(canvas_item)->get_pivot_offset();
  811. se->pre_drag_xform = canvas_item->get_global_transform_with_canvas();
  812. se->pre_drag_rect = canvas_item->get_item_rect();
  813. }
  814. if (selection.size() == 1 && Object::cast_to<Node2D>(selection[0]) && bone_ik_list.size() == 0) {
  815. drag = DRAG_NODE_2D;
  816. drag_point_from = Object::cast_to<Node2D>(selection[0])->get_global_position();
  817. } else {
  818. drag = DRAG_ALL;
  819. drag_point_from = _find_topleftmost_point();
  820. }
  821. drag_from = transform.affine_inverse().xform(p_click_pos);
  822. }
  823. void CanvasItemEditor::incbeg(float &beg, float &end, float inc, float minsize, bool p_symmetric) {
  824. if (minsize < 0) {
  825. beg += inc;
  826. if (p_symmetric)
  827. end -= inc;
  828. } else {
  829. if (p_symmetric) {
  830. beg += inc;
  831. end -= inc;
  832. if (end - beg < minsize) {
  833. float center = (beg + end) / 2.0;
  834. beg = center - minsize / 2.0;
  835. end = center + minsize / 2.0;
  836. }
  837. } else {
  838. if (end - (beg + inc) < minsize)
  839. beg = end - minsize;
  840. else
  841. beg += inc;
  842. }
  843. }
  844. }
  845. void CanvasItemEditor::incend(float &beg, float &end, float inc, float minsize, bool p_symmetric) {
  846. if (minsize < 0) {
  847. end += inc;
  848. if (p_symmetric)
  849. beg -= inc;
  850. } else {
  851. if (p_symmetric) {
  852. end += inc;
  853. beg -= inc;
  854. if (end - beg < minsize) {
  855. float center = (beg + end) / 2.0;
  856. beg = center - minsize / 2.0;
  857. end = center + minsize / 2.0;
  858. }
  859. } else {
  860. if ((end + inc) - beg < minsize)
  861. end = beg + minsize;
  862. else
  863. end += inc;
  864. }
  865. }
  866. }
  867. void CanvasItemEditor::_append_canvas_item(CanvasItem *p_item) {
  868. editor_selection->add_node(p_item);
  869. }
  870. void CanvasItemEditor::_snap_changed() {
  871. ((SnapDialog *)snap_dialog)->get_fields(grid_offset, grid_step, snap_rotation_offset, snap_rotation_step);
  872. grid_step_multiplier = 0;
  873. viewport_base->update();
  874. viewport->update();
  875. }
  876. void CanvasItemEditor::_selection_result_pressed(int p_result) {
  877. if (selection_results.size() <= p_result)
  878. return;
  879. CanvasItem *item = selection_results[p_result].item;
  880. if (item)
  881. _select_click_on_item(item, Point2(), additive_selection, false);
  882. }
  883. void CanvasItemEditor::_selection_menu_hide() {
  884. selection_results.clear();
  885. selection_menu->clear();
  886. selection_menu->set_size(Vector2(0, 0));
  887. }
  888. void CanvasItemEditor::_list_select(const Ref<InputEventMouseButton> &b) {
  889. Point2 click = viewport_scrollable->get_transform().affine_inverse().xform(b->get_position());
  890. Node *scene = editor->get_edited_scene();
  891. if (!scene)
  892. return;
  893. _find_canvas_items_at_pos(click, scene, transform, Transform2D(), selection_results);
  894. for (int i = 0; i < selection_results.size(); i++) {
  895. CanvasItem *item = selection_results[i].item;
  896. if (item != scene && item->get_owner() != scene && !scene->is_editable_instance(item->get_owner())) {
  897. //invalid result
  898. selection_results.remove(i);
  899. i--;
  900. }
  901. }
  902. if (selection_results.size() == 1) {
  903. CanvasItem *item = selection_results[0].item;
  904. selection_results.clear();
  905. additive_selection = b->get_shift();
  906. if (!_select_click_on_item(item, click, additive_selection, false))
  907. return;
  908. } else if (!selection_results.empty()) {
  909. selection_results.sort();
  910. NodePath root_path = get_tree()->get_edited_scene_root()->get_path();
  911. StringName root_name = root_path.get_name(root_path.get_name_count() - 1);
  912. for (int i = 0; i < selection_results.size(); i++) {
  913. CanvasItem *item = selection_results[i].item;
  914. Ref<Texture> icon;
  915. if (item->has_meta("_editor_icon"))
  916. icon = item->get_meta("_editor_icon");
  917. else
  918. icon = get_icon(has_icon(item->get_class(), "EditorIcons") ? item->get_class() : String("Object"), "EditorIcons");
  919. String node_path = "/" + root_name + "/" + root_path.rel_path_to(item->get_path());
  920. selection_menu->add_item(item->get_name());
  921. selection_menu->set_item_icon(i, icon);
  922. selection_menu->set_item_metadata(i, node_path);
  923. selection_menu->set_item_tooltip(i, String(item->get_name()) + "\nType: " + item->get_class() + "\nPath: " + node_path);
  924. }
  925. additive_selection = b->get_shift();
  926. selection_menu->set_global_position(b->get_global_position());
  927. selection_menu->popup();
  928. selection_menu->call_deferred("grab_click_focus");
  929. selection_menu->set_invalidate_click_until_motion();
  930. return;
  931. }
  932. }
  933. void CanvasItemEditor::_update_cursor() {
  934. CursorShape c = CURSOR_ARROW;
  935. switch (drag) {
  936. case DRAG_NONE:
  937. if (Input::get_singleton()->is_mouse_button_pressed(BUTTON_MIDDLE) || Input::get_singleton()->is_key_pressed(KEY_SPACE)) {
  938. c = CURSOR_DRAG;
  939. } else {
  940. switch (tool) {
  941. case TOOL_MOVE:
  942. c = CURSOR_MOVE;
  943. break;
  944. case TOOL_EDIT_PIVOT:
  945. c = CURSOR_CROSS;
  946. break;
  947. case TOOL_PAN:
  948. c = CURSOR_DRAG;
  949. break;
  950. }
  951. }
  952. break;
  953. case DRAG_LEFT:
  954. case DRAG_RIGHT:
  955. c = CURSOR_HSIZE;
  956. break;
  957. case DRAG_TOP:
  958. case DRAG_BOTTOM:
  959. c = CURSOR_VSIZE;
  960. break;
  961. case DRAG_TOP_LEFT:
  962. case DRAG_BOTTOM_RIGHT:
  963. c = CURSOR_FDIAGSIZE;
  964. break;
  965. case DRAG_TOP_RIGHT:
  966. case DRAG_BOTTOM_LEFT:
  967. c = CURSOR_BDIAGSIZE;
  968. break;
  969. case DRAG_ALL:
  970. case DRAG_NODE_2D:
  971. c = CURSOR_MOVE;
  972. break;
  973. }
  974. viewport->set_default_cursor_shape(c);
  975. }
  976. void CanvasItemEditor::_gui_input_viewport_base(const Ref<InputEvent> &p_event) {
  977. Ref<InputEventMouseButton> b = p_event;
  978. if (b.is_valid()) {
  979. if (b->get_button_index() == BUTTON_LEFT && b->is_pressed()) {
  980. if (show_guides && show_rulers && EditorNode::get_singleton()->get_edited_scene()) {
  981. Transform2D xform = viewport_scrollable->get_transform() * transform;
  982. // Retreive the guide lists
  983. Array vguides;
  984. if (EditorNode::get_singleton()->get_edited_scene()->has_meta("_edit_vertical_guides_")) {
  985. vguides = EditorNode::get_singleton()->get_edited_scene()->get_meta("_edit_vertical_guides_");
  986. }
  987. Array hguides;
  988. if (EditorNode::get_singleton()->get_edited_scene()->has_meta("_edit_horizontal_guides_")) {
  989. hguides = EditorNode::get_singleton()->get_edited_scene()->get_meta("_edit_horizontal_guides_");
  990. }
  991. // Press button
  992. if (b->get_position().x < RULER_WIDTH && b->get_position().y < RULER_WIDTH) {
  993. // Drag a new double guide
  994. drag = DRAG_DOUBLE_GUIDE;
  995. edited_guide_index = -1;
  996. } else if (b->get_position().x < RULER_WIDTH) {
  997. // Check if we drag an existing horizontal guide
  998. float minimum = 1e20;
  999. edited_guide_index = -1;
  1000. for (int i = 0; i < hguides.size(); i++) {
  1001. if (ABS(xform.xform(Point2(0, hguides[i])).y - b->get_position().y) < MIN(minimum, 8)) {
  1002. edited_guide_index = i;
  1003. }
  1004. }
  1005. if (edited_guide_index >= 0) {
  1006. // Drag an existing horizontal guide
  1007. drag = DRAG_H_GUIDE;
  1008. } else {
  1009. // Drag a new vertical guide
  1010. drag = DRAG_V_GUIDE;
  1011. }
  1012. } else if (b->get_position().y < RULER_WIDTH) {
  1013. // Check if we drag an existing vertical guide
  1014. float minimum = 1e20;
  1015. edited_guide_index = -1;
  1016. for (int i = 0; i < vguides.size(); i++) {
  1017. if (ABS(xform.xform(Point2(vguides[i], 0)).x - b->get_position().x) < MIN(minimum, 8)) {
  1018. edited_guide_index = i;
  1019. }
  1020. }
  1021. if (edited_guide_index >= 0) {
  1022. // Drag an existing vertical guide
  1023. drag = DRAG_V_GUIDE;
  1024. } else {
  1025. // Drag a new vertical guide
  1026. drag = DRAG_H_GUIDE;
  1027. }
  1028. }
  1029. }
  1030. }
  1031. if (b->get_button_index() == BUTTON_LEFT && !b->is_pressed()) {
  1032. // Release button
  1033. if (show_guides && EditorNode::get_singleton()->get_edited_scene()) {
  1034. Transform2D xform = viewport_scrollable->get_transform() * transform;
  1035. // Retreive the guide lists
  1036. Array vguides;
  1037. if (EditorNode::get_singleton()->get_edited_scene()->has_meta("_edit_vertical_guides_")) {
  1038. vguides = EditorNode::get_singleton()->get_edited_scene()->get_meta("_edit_vertical_guides_");
  1039. }
  1040. Array hguides;
  1041. if (EditorNode::get_singleton()->get_edited_scene()->has_meta("_edit_horizontal_guides_")) {
  1042. hguides = EditorNode::get_singleton()->get_edited_scene()->get_meta("_edit_horizontal_guides_");
  1043. }
  1044. Point2 edited = snap_point(xform.affine_inverse().xform(b->get_position()), SNAP_GRID | SNAP_PIXEL | SNAP_OTHER_NODES);
  1045. if (drag == DRAG_V_GUIDE) {
  1046. Array prev_vguides = vguides.duplicate();
  1047. if (b->get_position().x > RULER_WIDTH) {
  1048. // Adds a new vertical guide
  1049. if (edited_guide_index >= 0) {
  1050. vguides[edited_guide_index] = edited.x;
  1051. undo_redo->create_action(TTR("Move vertical guide"));
  1052. undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_vertical_guides_", vguides);
  1053. undo_redo->add_undo_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_vertical_guides_", prev_vguides);
  1054. undo_redo->add_undo_method(viewport_base, "update");
  1055. undo_redo->commit_action();
  1056. } else {
  1057. vguides.push_back(edited.x);
  1058. undo_redo->create_action(TTR("Create new vertical guide"));
  1059. undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_vertical_guides_", vguides);
  1060. undo_redo->add_undo_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_vertical_guides_", prev_vguides);
  1061. undo_redo->add_undo_method(viewport_base, "update");
  1062. undo_redo->commit_action();
  1063. }
  1064. } else {
  1065. if (edited_guide_index >= 0) {
  1066. vguides.remove(edited_guide_index);
  1067. undo_redo->create_action(TTR("Remove vertical guide"));
  1068. undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_vertical_guides_", vguides);
  1069. undo_redo->add_undo_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_vertical_guides_", prev_vguides);
  1070. undo_redo->add_undo_method(viewport_base, "update");
  1071. undo_redo->commit_action();
  1072. }
  1073. }
  1074. } else if (drag == DRAG_H_GUIDE) {
  1075. Array prev_hguides = hguides.duplicate();
  1076. if (b->get_position().y > RULER_WIDTH) {
  1077. // Adds a new horizontal guide
  1078. if (edited_guide_index >= 0) {
  1079. hguides[edited_guide_index] = edited.y;
  1080. undo_redo->create_action(TTR("Move horizontal guide"));
  1081. undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_horizontal_guides_", hguides);
  1082. undo_redo->add_undo_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_horizontal_guides_", prev_hguides);
  1083. undo_redo->add_undo_method(viewport_base, "update");
  1084. undo_redo->commit_action();
  1085. } else {
  1086. hguides.push_back(edited.y);
  1087. undo_redo->create_action(TTR("Create new horizontal guide"));
  1088. undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_horizontal_guides_", hguides);
  1089. undo_redo->add_undo_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_horizontal_guides_", prev_hguides);
  1090. undo_redo->add_undo_method(viewport_base, "update");
  1091. undo_redo->commit_action();
  1092. }
  1093. } else {
  1094. if (edited_guide_index >= 0) {
  1095. hguides.remove(edited_guide_index);
  1096. undo_redo->create_action(TTR("Remove horizontal guide"));
  1097. undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_horizontal_guides_", hguides);
  1098. undo_redo->add_undo_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_horizontal_guides_", prev_hguides);
  1099. undo_redo->add_undo_method(viewport_base, "update");
  1100. undo_redo->commit_action();
  1101. }
  1102. }
  1103. } else if (drag == DRAG_DOUBLE_GUIDE) {
  1104. Array prev_hguides = hguides.duplicate();
  1105. Array prev_vguides = vguides.duplicate();
  1106. if (b->get_position().x > RULER_WIDTH && b->get_position().y > RULER_WIDTH) {
  1107. // Adds a new horizontal guide a new vertical guide
  1108. vguides.push_back(edited.x);
  1109. hguides.push_back(edited.y);
  1110. undo_redo->create_action(TTR("Create new horizontal and vertical guides"));
  1111. undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_vertical_guides_", vguides);
  1112. undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_horizontal_guides_", hguides);
  1113. undo_redo->add_undo_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_vertical_guides_", prev_vguides);
  1114. undo_redo->add_undo_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_horizontal_guides_", prev_hguides);
  1115. undo_redo->add_undo_method(viewport_base, "update");
  1116. undo_redo->commit_action();
  1117. }
  1118. }
  1119. }
  1120. if (drag == DRAG_DOUBLE_GUIDE || drag == DRAG_V_GUIDE || drag == DRAG_H_GUIDE) {
  1121. drag = DRAG_NONE;
  1122. viewport_base->update();
  1123. }
  1124. }
  1125. }
  1126. Ref<InputEventMouseMotion> m = p_event;
  1127. if (m.is_valid()) {
  1128. if (!viewport_base->has_focus() && (!get_focus_owner() || !get_focus_owner()->is_text_field())) {
  1129. viewport_base->call_deferred("grab_focus");
  1130. }
  1131. if (drag == DRAG_DOUBLE_GUIDE || drag == DRAG_H_GUIDE || drag == DRAG_V_GUIDE) {
  1132. Transform2D xform = viewport_scrollable->get_transform() * transform;
  1133. Point2 mouse_pos = m->get_position();
  1134. mouse_pos = xform.affine_inverse().xform(mouse_pos);
  1135. mouse_pos = xform.xform(snap_point(mouse_pos, SNAP_GRID | SNAP_PIXEL | SNAP_OTHER_NODES));
  1136. edited_guide_pos = mouse_pos;
  1137. viewport_base->update();
  1138. }
  1139. }
  1140. Ref<InputEventKey> k = p_event;
  1141. if (k.is_valid()) {
  1142. if (k->is_pressed() && drag == DRAG_NONE) {
  1143. // Move the object with the arrow keys
  1144. KeyMoveMODE move_mode = MOVE_VIEW_BASE;
  1145. if (k->get_alt()) move_mode = MOVE_LOCAL_BASE;
  1146. if (k->get_control() || k->get_metakey()) move_mode = MOVE_LOCAL_WITH_ROT;
  1147. if (k->get_scancode() == KEY_UP)
  1148. _key_move(Vector2(0, -1), k->get_shift(), move_mode);
  1149. else if (k->get_scancode() == KEY_DOWN)
  1150. _key_move(Vector2(0, 1), k->get_shift(), move_mode);
  1151. else if (k->get_scancode() == KEY_LEFT)
  1152. _key_move(Vector2(-1, 0), k->get_shift(), move_mode);
  1153. else if (k->get_scancode() == KEY_RIGHT)
  1154. _key_move(Vector2(1, 0), k->get_shift(), move_mode);
  1155. else if (k->get_scancode() == KEY_ESCAPE) {
  1156. editor_selection->clear();
  1157. viewport->update();
  1158. } else
  1159. return;
  1160. accept_event();
  1161. }
  1162. }
  1163. }
  1164. void CanvasItemEditor::_gui_input_viewport(const Ref<InputEvent> &p_event) {
  1165. {
  1166. EditorNode *en = editor;
  1167. EditorPluginList *over_plugin_list = en->get_editor_plugins_over();
  1168. if (!over_plugin_list->empty()) {
  1169. bool discard = over_plugin_list->forward_gui_input(p_event);
  1170. if (discard) {
  1171. accept_event();
  1172. return;
  1173. }
  1174. }
  1175. }
  1176. Ref<InputEventMouseButton> b = p_event;
  1177. if (b.is_valid()) {
  1178. // Button event
  1179. if (b->get_button_index() == BUTTON_WHEEL_DOWN) {
  1180. // Scroll or pan down
  1181. if (bool(EditorSettings::get_singleton()->get("editors/2d/scroll_to_pan"))) {
  1182. v_scroll->set_value(v_scroll->get_value() + int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor());
  1183. _update_scroll(0);
  1184. viewport->update();
  1185. } else {
  1186. _zoom_on_position(zoom * (1 - (0.05 * b->get_factor())), b->get_position());
  1187. }
  1188. return;
  1189. }
  1190. if (b->get_button_index() == BUTTON_WHEEL_UP) {
  1191. // Scroll or pan up
  1192. if (bool(EditorSettings::get_singleton()->get("editors/2d/scroll_to_pan"))) {
  1193. v_scroll->set_value(v_scroll->get_value() - int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor());
  1194. _update_scroll(0);
  1195. viewport->update();
  1196. } else {
  1197. _zoom_on_position(zoom * ((0.95 + (0.05 * b->get_factor())) / 0.95), b->get_position());
  1198. }
  1199. return;
  1200. }
  1201. if (b->get_button_index() == BUTTON_WHEEL_LEFT) {
  1202. // Pan left
  1203. if (bool(EditorSettings::get_singleton()->get("editors/2d/scroll_to_pan"))) {
  1204. h_scroll->set_value(h_scroll->get_value() - int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor());
  1205. }
  1206. }
  1207. if (b->get_button_index() == BUTTON_WHEEL_RIGHT) {
  1208. // Pan right
  1209. if (bool(EditorSettings::get_singleton()->get("editors/2d/scroll_to_pan"))) {
  1210. h_scroll->set_value(h_scroll->get_value() + int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor());
  1211. }
  1212. }
  1213. if (b->get_button_index() == BUTTON_RIGHT) {
  1214. if (b->is_pressed() && (tool == TOOL_SELECT && b->get_alt())) {
  1215. // Open the selection list
  1216. _list_select(b);
  1217. return;
  1218. }
  1219. if (get_item_count() > 0 && drag != DRAG_NONE) {
  1220. // Cancel a drag
  1221. if (bone_ik_list.size()) {
  1222. for (List<BoneIK>::Element *E = bone_ik_list.back(); E; E = E->prev()) {
  1223. E->get().node->edit_set_state(E->get().orig_state);
  1224. }
  1225. bone_ik_list.clear();
  1226. } else {
  1227. List<Node *> &selection = editor_selection->get_selected_node_list();
  1228. for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
  1229. CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->get());
  1230. if (!canvas_item || !canvas_item->is_visible_in_tree())
  1231. continue;
  1232. if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root())
  1233. continue;
  1234. CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item);
  1235. if (!se)
  1236. continue;
  1237. canvas_item->edit_set_state(se->undo_state);
  1238. if (Object::cast_to<Node2D>(canvas_item))
  1239. Object::cast_to<Node2D>(canvas_item)->edit_set_pivot(se->undo_pivot);
  1240. if (Object::cast_to<Control>(canvas_item))
  1241. Object::cast_to<Control>(canvas_item)->set_pivot_offset(se->undo_pivot);
  1242. }
  1243. }
  1244. drag = DRAG_NONE;
  1245. viewport->update();
  1246. can_move_pivot = false;
  1247. } else if (box_selecting) {
  1248. // Cancel box selection
  1249. box_selecting = false;
  1250. viewport->update();
  1251. }
  1252. return;
  1253. }
  1254. if (b->get_button_index() == BUTTON_LEFT && tool == TOOL_LIST_SELECT) {
  1255. if (b->is_pressed())
  1256. // Open the selection list
  1257. _list_select(b);
  1258. return;
  1259. }
  1260. if (b->get_button_index() == BUTTON_LEFT && tool == TOOL_EDIT_PIVOT) {
  1261. if (b->is_pressed()) {
  1262. // Set the pivot point
  1263. Point2 mouse_pos = b->get_position();
  1264. mouse_pos = transform.affine_inverse().xform(mouse_pos);
  1265. mouse_pos = snap_point(mouse_pos, SNAP_DEFAULT, _get_single_item());
  1266. _edit_set_pivot(mouse_pos);
  1267. }
  1268. return;
  1269. }
  1270. if (tool == TOOL_PAN || b->get_button_index() != BUTTON_LEFT || Input::get_singleton()->is_key_pressed(KEY_SPACE))
  1271. // Pan the view
  1272. return;
  1273. // -- From now we consider that the button is BUTTON_LEFT --
  1274. if (!b->is_pressed()) {
  1275. if (drag != DRAG_NONE) {
  1276. // Stop dragging
  1277. if (undo_redo) {
  1278. if (bone_ik_list.size()) {
  1279. undo_redo->create_action(TTR("Edit IK Chain"));
  1280. for (List<BoneIK>::Element *E = bone_ik_list.back(); E; E = E->prev()) {
  1281. undo_redo->add_do_method(E->get().node, "edit_set_state", E->get().node->edit_get_state());
  1282. undo_redo->add_undo_method(E->get().node, "edit_set_state", E->get().orig_state);
  1283. }
  1284. undo_redo->add_do_method(viewport, "update");
  1285. undo_redo->add_undo_method(viewport, "update");
  1286. bone_ik_list.clear();
  1287. undo_redo->commit_action();
  1288. } else {
  1289. undo_redo->create_action(TTR("Edit CanvasItem"));
  1290. List<Node *> &selection = editor_selection->get_selected_node_list();
  1291. for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
  1292. CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->get());
  1293. if (!canvas_item || !canvas_item->is_visible_in_tree())
  1294. continue;
  1295. if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root())
  1296. continue;
  1297. CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item);
  1298. if (!se)
  1299. continue;
  1300. Variant state = canvas_item->edit_get_state();
  1301. undo_redo->add_do_method(canvas_item, "edit_set_state", state);
  1302. undo_redo->add_undo_method(canvas_item, "edit_set_state", se->undo_state);
  1303. {
  1304. Node2D *pvt = Object::cast_to<Node2D>(canvas_item);
  1305. if (pvt && pvt->edit_has_pivot()) {
  1306. undo_redo->add_do_method(canvas_item, "edit_set_pivot", pvt->edit_get_pivot());
  1307. undo_redo->add_undo_method(canvas_item, "edit_set_pivot", se->undo_pivot);
  1308. }
  1309. Control *cnt = Object::cast_to<Control>(canvas_item);
  1310. if (cnt) {
  1311. undo_redo->add_do_method(canvas_item, "set_pivot_offset", cnt->get_pivot_offset());
  1312. undo_redo->add_undo_method(canvas_item, "set_pivot_offset", se->undo_pivot);
  1313. }
  1314. }
  1315. }
  1316. undo_redo->commit_action();
  1317. }
  1318. }
  1319. drag = DRAG_NONE;
  1320. viewport->update();
  1321. can_move_pivot = false;
  1322. }
  1323. if (box_selecting) {
  1324. // Stop box selection
  1325. Node *scene = editor->get_edited_scene();
  1326. if (scene) {
  1327. List<CanvasItem *> selitems;
  1328. Point2 bsfrom = transform.xform(drag_from);
  1329. Point2 bsto = transform.xform(box_selecting_to);
  1330. if (bsfrom.x > bsto.x)
  1331. SWAP(bsfrom.x, bsto.x);
  1332. if (bsfrom.y > bsto.y)
  1333. SWAP(bsfrom.y, bsto.y);
  1334. _find_canvas_items_at_rect(Rect2(bsfrom, bsto - bsfrom), scene, transform, Transform2D(), &selitems);
  1335. for (List<CanvasItem *>::Element *E = selitems.front(); E; E = E->next()) {
  1336. _append_canvas_item(E->get());
  1337. }
  1338. }
  1339. box_selecting = false;
  1340. viewport->update();
  1341. }
  1342. return;
  1343. }
  1344. // -- From now we consider that the button is BUTTON_LEFT and that it is pressed --
  1345. Map<ObjectID, BoneList>::Element *Cbone = NULL; //closest
  1346. {
  1347. bone_ik_list.clear();
  1348. float closest_dist = 1e20;
  1349. int bone_width = EditorSettings::get_singleton()->get("editors/2d/bone_width");
  1350. for (Map<ObjectID, BoneList>::Element *E = bone_list.front(); E; E = E->next()) {
  1351. if (E->get().from == E->get().to)
  1352. continue;
  1353. Vector2 s[2] = {
  1354. E->get().from,
  1355. E->get().to
  1356. };
  1357. Vector2 p = Geometry::get_closest_point_to_segment_2d(b->get_position(), s);
  1358. float d = p.distance_to(b->get_position());
  1359. if (d < bone_width && d < closest_dist) {
  1360. Cbone = E;
  1361. closest_dist = d;
  1362. }
  1363. }
  1364. if (Cbone) {
  1365. Node2D *b = Object::cast_to<Node2D>(ObjectDB::get_instance(Cbone->get().bone));
  1366. if (b) {
  1367. bool ik_found = false;
  1368. bool first = true;
  1369. while (b) {
  1370. CanvasItem *pi = b->get_parent_item();
  1371. if (!pi)
  1372. break;
  1373. float len = pi->get_global_transform().get_origin().distance_to(b->get_global_position());
  1374. b = Object::cast_to<Node2D>(pi);
  1375. if (!b)
  1376. break;
  1377. if (first) {
  1378. bone_orig_xform = b->get_global_transform();
  1379. first = false;
  1380. }
  1381. BoneIK bik;
  1382. bik.node = b;
  1383. bik.len = len;
  1384. bik.orig_state = b->edit_get_state();
  1385. bone_ik_list.push_back(bik);
  1386. if (b->has_meta("_edit_ik_")) {
  1387. ik_found = bone_ik_list.size() > 1;
  1388. break;
  1389. }
  1390. if (!pi->has_meta("_edit_bone_"))
  1391. break;
  1392. }
  1393. if (!ik_found)
  1394. bone_ik_list.clear();
  1395. }
  1396. }
  1397. }
  1398. // Single selected item
  1399. CanvasItem *canvas_item = _get_single_item();
  1400. if (canvas_item) {
  1401. CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item);
  1402. ERR_FAIL_COND(!se);
  1403. Point2 click = b->get_position();
  1404. // Rotation
  1405. if ((b->get_control() && tool == TOOL_SELECT) || tool == TOOL_ROTATE) {
  1406. drag = DRAG_ROTATE;
  1407. drag_from = transform.affine_inverse().xform(click);
  1408. se->undo_state = canvas_item->edit_get_state();
  1409. if (Object::cast_to<Node2D>(canvas_item))
  1410. se->undo_pivot = Object::cast_to<Node2D>(canvas_item)->edit_get_pivot();
  1411. if (Object::cast_to<Control>(canvas_item))
  1412. se->undo_pivot = Object::cast_to<Control>(canvas_item)->get_pivot_offset();
  1413. se->pre_drag_xform = canvas_item->get_global_transform_with_canvas();
  1414. se->pre_drag_rect = canvas_item->get_item_rect();
  1415. return;
  1416. }
  1417. if (tool == TOOL_SELECT) {
  1418. // Open a sub-scene on double-click
  1419. if (b->is_doubleclick()) {
  1420. if (canvas_item->get_filename() != "" && canvas_item != editor->get_edited_scene()) {
  1421. editor->open_request(canvas_item->get_filename());
  1422. return;
  1423. }
  1424. }
  1425. // Drag resize handles
  1426. drag = _get_resize_handle_drag_type(click, drag_point_from);
  1427. if (drag != DRAG_NONE) {
  1428. drag_from = transform.affine_inverse().xform(click);
  1429. se->undo_state = canvas_item->edit_get_state();
  1430. if (Object::cast_to<Node2D>(canvas_item))
  1431. se->undo_pivot = Object::cast_to<Node2D>(canvas_item)->edit_get_pivot();
  1432. if (Object::cast_to<Control>(canvas_item))
  1433. se->undo_pivot = Object::cast_to<Control>(canvas_item)->get_pivot_offset();
  1434. se->pre_drag_xform = canvas_item->get_global_transform_with_canvas();
  1435. se->pre_drag_rect = canvas_item->get_item_rect();
  1436. return;
  1437. }
  1438. // Drag anchor handles
  1439. Control *control = Object::cast_to<Control>(canvas_item);
  1440. if (control && show_helpers && !Object::cast_to<Container>(control->get_parent())) {
  1441. drag = _get_anchor_handle_drag_type(click, drag_point_from);
  1442. if (drag != DRAG_NONE) {
  1443. drag_from = transform.affine_inverse().xform(click);
  1444. se->undo_state = canvas_item->edit_get_state();
  1445. se->pre_drag_xform = canvas_item->get_global_transform_with_canvas();
  1446. se->pre_drag_rect = canvas_item->get_item_rect();
  1447. return;
  1448. }
  1449. }
  1450. }
  1451. }
  1452. // Multiple selected items
  1453. Point2 click = b->get_position();
  1454. if ((b->get_alt() || tool == TOOL_MOVE) && get_item_count()) {
  1455. // Drag the nodes
  1456. _prepare_drag(click);
  1457. viewport->update();
  1458. return;
  1459. }
  1460. CanvasItem *c = NULL;
  1461. if (Cbone) {
  1462. c = Object::cast_to<CanvasItem>(ObjectDB::get_instance(Cbone->get().bone));
  1463. if (c)
  1464. c = c->get_parent_item();
  1465. }
  1466. Node *scene = editor->get_edited_scene();
  1467. if (!scene)
  1468. return;
  1469. // Find the item to select
  1470. if (!c) {
  1471. Vector<_SelectResult> selection;
  1472. _find_canvas_items_at_pos(click, scene, transform, Transform2D(), selection, 1);
  1473. if (!selection.empty())
  1474. c = selection[0].item;
  1475. CanvasItem *cn = c;
  1476. while (cn) {
  1477. if (cn->has_meta("_edit_group_")) {
  1478. c = cn;
  1479. }
  1480. cn = cn->get_parent_item();
  1481. }
  1482. }
  1483. Node *n = c;
  1484. while ((n && n != scene && n->get_owner() != scene) || (n && !n->is_class("CanvasItem"))) {
  1485. n = n->get_parent();
  1486. };
  1487. if (n) {
  1488. c = Object::cast_to<CanvasItem>(n);
  1489. } else {
  1490. c = NULL;
  1491. }
  1492. // Select the item
  1493. additive_selection = b->get_shift();
  1494. if (!c) {
  1495. _select_click_on_empty_area(click, additive_selection, true);
  1496. } else if (!_select_click_on_item(c, click, additive_selection, true)) {
  1497. return;
  1498. }
  1499. }
  1500. Ref<InputEventMouseMotion> m = p_event;
  1501. if (m.is_valid()) {
  1502. // Mouse motion event
  1503. _update_cursor();
  1504. if (box_selecting) {
  1505. // Update box selection
  1506. box_selecting_to = transform.affine_inverse().xform(m->get_position());
  1507. viewport->update();
  1508. return;
  1509. }
  1510. if (drag == DRAG_NONE) {
  1511. if (((m->get_button_mask() & BUTTON_MASK_LEFT) && tool == TOOL_PAN) || (m->get_button_mask() & BUTTON_MASK_MIDDLE) || ((m->get_button_mask() & BUTTON_MASK_LEFT) && Input::get_singleton()->is_key_pressed(KEY_SPACE))) {
  1512. // Pan the viewport
  1513. Point2i relative;
  1514. if (bool(EditorSettings::get_singleton()->get("editors/2d/warped_mouse_panning"))) {
  1515. relative = Input::get_singleton()->warp_mouse_motion(m, viewport->get_global_rect());
  1516. } else {
  1517. relative = m->get_relative();
  1518. }
  1519. h_scroll->set_value(h_scroll->get_value() - relative.x / zoom);
  1520. v_scroll->set_value(v_scroll->get_value() - relative.y / zoom);
  1521. }
  1522. return;
  1523. }
  1524. List<Node *> &selection = editor_selection->get_selected_node_list();
  1525. for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
  1526. CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->get());
  1527. if (!canvas_item || !canvas_item->is_visible_in_tree())
  1528. continue;
  1529. if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root())
  1530. continue;
  1531. CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item);
  1532. if (!se)
  1533. continue;
  1534. bool dragging_bone = drag == DRAG_ALL && selection.size() == 1 && bone_ik_list.size();
  1535. if (!dragging_bone) {
  1536. canvas_item->edit_set_state(se->undo_state); //reset state and reapply
  1537. if (Object::cast_to<Node2D>(canvas_item))
  1538. Object::cast_to<Node2D>(canvas_item)->edit_set_pivot(se->undo_pivot);
  1539. if (Object::cast_to<Control>(canvas_item))
  1540. Object::cast_to<Control>(canvas_item)->set_pivot_offset(se->undo_pivot);
  1541. }
  1542. Vector2 dfrom = drag_from;
  1543. Vector2 dto = transform.affine_inverse().xform(m->get_position());
  1544. if (canvas_item->has_meta("_edit_lock_"))
  1545. continue;
  1546. if (drag == DRAG_ROTATE) {
  1547. // Rotate the node
  1548. Vector2 center = canvas_item->get_global_transform_with_canvas().get_origin();
  1549. {
  1550. Node2D *node = Object::cast_to<Node2D>(canvas_item);
  1551. if (node) {
  1552. real_t angle = node->get_rotation();
  1553. node->set_rotation(snap_angle(angle + (dfrom - center).angle_to(dto - center), angle));
  1554. display_rotate_to = dto;
  1555. display_rotate_from = center;
  1556. viewport->update();
  1557. }
  1558. }
  1559. {
  1560. Control *node = Object::cast_to<Control>(canvas_item);
  1561. if (node) {
  1562. real_t angle = node->get_rotation();
  1563. node->set_rotation(snap_angle(angle + (dfrom - center).angle_to(dto - center), angle));
  1564. display_rotate_to = dto;
  1565. display_rotate_from = center;
  1566. viewport->update();
  1567. }
  1568. }
  1569. continue;
  1570. }
  1571. bool uniform = m->get_shift();
  1572. bool symmetric = m->get_alt();
  1573. Vector2 drag_vector =
  1574. canvas_item->get_global_transform_with_canvas().affine_inverse().xform(dto) -
  1575. canvas_item->get_global_transform_with_canvas().affine_inverse().xform(dfrom);
  1576. switch (drag) {
  1577. case DRAG_ALL:
  1578. case DRAG_NODE_2D:
  1579. dto -= drag_from - drag_point_from;
  1580. if (uniform) {
  1581. if (ABS(dto.x - drag_point_from.x) > ABS(dto.y - drag_point_from.y)) {
  1582. dto.y = drag_point_from.y;
  1583. } else {
  1584. dto.x = drag_point_from.x;
  1585. }
  1586. }
  1587. break;
  1588. }
  1589. Control *control = Object::cast_to<Control>(canvas_item);
  1590. if (control) {
  1591. // Drag and snap the anchor
  1592. Transform2D c_trans_rev = canvas_item->get_global_transform_with_canvas().affine_inverse();
  1593. Vector2 anchor = c_trans_rev.xform(dto - drag_from + drag_point_from);
  1594. anchor = _position_to_anchor(control, anchor);
  1595. Vector2 anchor_snapped = c_trans_rev.xform(snap_point(dto - drag_from + drag_point_from, SNAP_GRID | SNAP_GUIDES | SNAP_OTHER_NODES, _get_single_item(), SNAP_NODE_PARENT | SNAP_NODE_SIDES));
  1596. anchor_snapped = _position_to_anchor(control, anchor_snapped).snapped(Vector2(0.00001, 0.00001));
  1597. bool use_y = Math::abs(drag_vector.y) > Math::abs(drag_vector.x);
  1598. switch (drag) {
  1599. case DRAG_ANCHOR_TOP_LEFT:
  1600. if (!uniform || (uniform && !use_y)) control->set_anchor(MARGIN_LEFT, anchor_snapped.x);
  1601. if (!uniform || (uniform && use_y)) control->set_anchor(MARGIN_TOP, anchor_snapped.y);
  1602. continue;
  1603. break;
  1604. case DRAG_ANCHOR_TOP_RIGHT:
  1605. if (!uniform || (uniform && !use_y)) control->set_anchor(MARGIN_RIGHT, anchor_snapped.x);
  1606. if (!uniform || (uniform && use_y)) control->set_anchor(MARGIN_TOP, anchor_snapped.y);
  1607. continue;
  1608. break;
  1609. case DRAG_ANCHOR_BOTTOM_RIGHT:
  1610. if (!uniform || (uniform && !use_y)) control->set_anchor(MARGIN_RIGHT, anchor_snapped.x);
  1611. if (!uniform || (uniform && use_y)) control->set_anchor(MARGIN_BOTTOM, anchor_snapped.y);
  1612. break;
  1613. case DRAG_ANCHOR_BOTTOM_LEFT:
  1614. if (!uniform || (uniform && !use_y)) control->set_anchor(MARGIN_LEFT, anchor_snapped.x);
  1615. if (!uniform || (uniform && use_y)) control->set_anchor(MARGIN_BOTTOM, anchor_snapped.y);
  1616. continue;
  1617. break;
  1618. case DRAG_ANCHOR_ALL:
  1619. if (!uniform || (uniform && !use_y)) control->set_anchor(MARGIN_LEFT, anchor_snapped.x);
  1620. if (!uniform || (uniform && !use_y)) control->set_anchor(MARGIN_RIGHT, anchor_snapped.x);
  1621. if (!uniform || (uniform && use_y)) control->set_anchor(MARGIN_TOP, anchor_snapped.y);
  1622. if (!uniform || (uniform && use_y)) control->set_anchor(MARGIN_BOTTOM, anchor_snapped.y);
  1623. continue;
  1624. break;
  1625. }
  1626. }
  1627. dfrom = drag_point_from;
  1628. dto = snap_point(dto, SNAP_NODE_ANCHORS | SNAP_NODE_PARENT | SNAP_OTHER_NODES | SNAP_GRID | SNAP_GUIDES | SNAP_PIXEL, _get_single_item());
  1629. drag_vector =
  1630. canvas_item->get_global_transform_with_canvas().affine_inverse().xform(dto) -
  1631. canvas_item->get_global_transform_with_canvas().affine_inverse().xform(dfrom);
  1632. Rect2 local_rect = canvas_item->get_item_rect();
  1633. Vector2 begin = local_rect.position;
  1634. Vector2 end = local_rect.position + local_rect.size;
  1635. Vector2 minsize = canvas_item->edit_get_minimum_size();
  1636. if (uniform) {
  1637. // Keep the height/width ratio of the item
  1638. float aspect = local_rect.size.aspect();
  1639. switch (drag) {
  1640. case DRAG_LEFT:
  1641. drag_vector.y = -drag_vector.x / aspect;
  1642. break;
  1643. case DRAG_RIGHT:
  1644. drag_vector.y = drag_vector.x / aspect;
  1645. break;
  1646. case DRAG_TOP:
  1647. drag_vector.x = -drag_vector.y * aspect;
  1648. break;
  1649. case DRAG_BOTTOM:
  1650. drag_vector.x = drag_vector.y * aspect;
  1651. break;
  1652. case DRAG_BOTTOM_LEFT:
  1653. case DRAG_TOP_RIGHT:
  1654. if (aspect > 1.0) { // width > height, take x as reference
  1655. drag_vector.y = -drag_vector.x / aspect;
  1656. } else { // height > width, take y as reference
  1657. drag_vector.x = -drag_vector.y * aspect;
  1658. }
  1659. break;
  1660. case DRAG_BOTTOM_RIGHT:
  1661. case DRAG_TOP_LEFT:
  1662. if (aspect > 1.0) { // width > height, take x as reference
  1663. drag_vector.y = drag_vector.x / aspect;
  1664. } else { // height > width, take y as reference
  1665. drag_vector.x = drag_vector.y * aspect;
  1666. }
  1667. break;
  1668. }
  1669. } else {
  1670. switch (drag) {
  1671. case DRAG_RIGHT:
  1672. case DRAG_LEFT:
  1673. drag_vector.y = 0;
  1674. break;
  1675. case DRAG_TOP:
  1676. case DRAG_BOTTOM:
  1677. drag_vector.x = 0;
  1678. break;
  1679. }
  1680. }
  1681. switch (drag) {
  1682. case DRAG_ALL:
  1683. begin += drag_vector;
  1684. end += drag_vector;
  1685. break;
  1686. case DRAG_RIGHT:
  1687. case DRAG_BOTTOM:
  1688. case DRAG_BOTTOM_RIGHT:
  1689. incend(begin.x, end.x, drag_vector.x, minsize.x, symmetric);
  1690. incend(begin.y, end.y, drag_vector.y, minsize.y, symmetric);
  1691. break;
  1692. case DRAG_TOP_LEFT:
  1693. incbeg(begin.x, end.x, drag_vector.x, minsize.x, symmetric);
  1694. incbeg(begin.y, end.y, drag_vector.y, minsize.y, symmetric);
  1695. break;
  1696. case DRAG_TOP:
  1697. case DRAG_TOP_RIGHT:
  1698. incbeg(begin.y, end.y, drag_vector.y, minsize.y, symmetric);
  1699. incend(begin.x, end.x, drag_vector.x, minsize.x, symmetric);
  1700. break;
  1701. case DRAG_LEFT:
  1702. case DRAG_BOTTOM_LEFT:
  1703. incbeg(begin.x, end.x, drag_vector.x, minsize.x, symmetric);
  1704. incend(begin.y, end.y, drag_vector.y, minsize.y, symmetric);
  1705. break;
  1706. case DRAG_PIVOT:
  1707. if (Object::cast_to<Node2D>(canvas_item)) {
  1708. Node2D *n2d = Object::cast_to<Node2D>(canvas_item);
  1709. n2d->edit_set_pivot(se->undo_pivot + drag_vector);
  1710. }
  1711. if (Object::cast_to<Control>(canvas_item)) {
  1712. Object::cast_to<Control>(canvas_item)->set_pivot_offset(se->undo_pivot + drag_vector);
  1713. }
  1714. continue;
  1715. break;
  1716. case DRAG_NODE_2D:
  1717. ERR_FAIL_COND(!Object::cast_to<Node2D>(canvas_item));
  1718. Object::cast_to<Node2D>(canvas_item)->set_global_position(dto);
  1719. continue;
  1720. break;
  1721. }
  1722. if (!dragging_bone) {
  1723. local_rect.position = begin;
  1724. local_rect.size = end - begin;
  1725. canvas_item->edit_set_rect(local_rect);
  1726. } else {
  1727. //ok, all that had to be done was done, now solve IK
  1728. Node2D *n2d = Object::cast_to<Node2D>(canvas_item);
  1729. Transform2D final_xform = bone_orig_xform;
  1730. if (n2d) {
  1731. float total_len = 0;
  1732. for (List<BoneIK>::Element *E = bone_ik_list.front(); E; E = E->next()) {
  1733. if (E->prev())
  1734. total_len += E->get().len;
  1735. E->get().pos = E->get().node->get_global_transform().get_origin();
  1736. }
  1737. {
  1738. final_xform.elements[2] += dto - dfrom; //final_xform.affine_inverse().basis_xform_inv(drag_vector);
  1739. //n2d->set_global_transform(final_xform);
  1740. }
  1741. CanvasItem *last = bone_ik_list.back()->get().node;
  1742. if (!last)
  1743. break;
  1744. Vector2 root_pos = last->get_global_transform().get_origin();
  1745. Vector2 leaf_pos = final_xform.get_origin();
  1746. if ((leaf_pos.distance_to(root_pos)) > total_len) {
  1747. //oops dude you went too far
  1748. //print_line("TOO FAR!");
  1749. Vector2 rel = leaf_pos - root_pos;
  1750. rel = rel.normalized() * total_len;
  1751. leaf_pos = root_pos + rel;
  1752. }
  1753. bone_ik_list.front()->get().pos = leaf_pos;
  1754. //print_line("BONE IK LIST "+itos(bone_ik_list.size()));
  1755. if (bone_ik_list.size() > 2) {
  1756. int solver_iterations = 64;
  1757. float solver_k = 0.3;
  1758. for (int i = 0; i < solver_iterations; i++) {
  1759. for (List<BoneIK>::Element *E = bone_ik_list.front(); E; E = E->next()) {
  1760. if (E == bone_ik_list.back()) {
  1761. break;
  1762. }
  1763. float len = E->next()->get().len;
  1764. if (E->next() == bone_ik_list.back()) {
  1765. //print_line("back");
  1766. Vector2 rel = E->get().pos - E->next()->get().pos;
  1767. //print_line("PREV "+E->get().pos);
  1768. Vector2 desired = E->next()->get().pos + rel.normalized() * len;
  1769. //print_line("DESIRED "+desired);
  1770. E->get().pos = E->get().pos.linear_interpolate(desired, solver_k);
  1771. //print_line("POST "+E->get().pos);
  1772. } else if (E == bone_ik_list.front()) {
  1773. //only adjust parent
  1774. //print_line("front");
  1775. Vector2 rel = E->next()->get().pos - E->get().pos;
  1776. //print_line("PREV "+E->next()->get().pos);
  1777. Vector2 desired = E->get().pos + rel.normalized() * len;
  1778. //print_line("DESIRED "+desired);
  1779. E->next()->get().pos = E->next()->get().pos.linear_interpolate(desired, solver_k);
  1780. //print_line("POST "+E->next()->get().pos);
  1781. } else {
  1782. Vector2 rel = E->next()->get().pos - E->get().pos;
  1783. Vector2 cen = (E->next()->get().pos + E->get().pos) * 0.5;
  1784. rel = rel.linear_interpolate(rel.normalized() * len, solver_k);
  1785. rel *= 0.5;
  1786. E->next()->get().pos = cen + rel;
  1787. E->get().pos = cen - rel;
  1788. //print_line("mid");
  1789. }
  1790. }
  1791. }
  1792. }
  1793. }
  1794. for (List<BoneIK>::Element *E = bone_ik_list.back(); E; E = E->prev()) {
  1795. Node2D *n = E->get().node;
  1796. if (!E->prev()) {
  1797. //last goes to what it was
  1798. final_xform.set_origin(n->get_global_position());
  1799. n->set_global_transform(final_xform);
  1800. } else {
  1801. Vector2 rel = (E->prev()->get().node->get_global_position() - n->get_global_position()).normalized();
  1802. Vector2 rel2 = (E->prev()->get().pos - E->get().pos).normalized();
  1803. float rot = rel.angle_to(rel2);
  1804. if (n->get_global_transform().basis_determinant() < 0) {
  1805. //mirrored, rotate the other way
  1806. rot = -rot;
  1807. }
  1808. n->rotate(rot);
  1809. }
  1810. }
  1811. break;
  1812. }
  1813. }
  1814. }
  1815. }
  1816. void CanvasItemEditor::_draw_text_at_position(Point2 p_position, String p_string, Margin p_side) {
  1817. Color color = get_color("font_color", "Editor");
  1818. color.a = 0.8;
  1819. Ref<Font> font = get_font("font", "Label");
  1820. Size2 text_size = font->get_string_size(p_string);
  1821. switch (p_side) {
  1822. case MARGIN_LEFT:
  1823. p_position += Vector2(-text_size.x - 5, text_size.y / 2);
  1824. break;
  1825. case MARGIN_TOP:
  1826. p_position += Vector2(-text_size.x / 2, -5);
  1827. break;
  1828. case MARGIN_RIGHT:
  1829. p_position += Vector2(5, text_size.y / 2);
  1830. break;
  1831. case MARGIN_BOTTOM:
  1832. p_position += Vector2(-text_size.x / 2, text_size.y + 5);
  1833. break;
  1834. }
  1835. viewport->draw_string(font, p_position, p_string, color);
  1836. }
  1837. void CanvasItemEditor::_draw_margin_at_position(int p_value, Point2 p_position, Margin p_side) {
  1838. String str = vformat("%d px", p_value);
  1839. if (p_value != 0) {
  1840. _draw_text_at_position(p_position, str, p_side);
  1841. }
  1842. }
  1843. void CanvasItemEditor::_draw_percentage_at_position(float p_value, Point2 p_position, Margin p_side) {
  1844. String str = vformat("%.1f %%", p_value * 100.0);
  1845. if (p_value != 0) {
  1846. _draw_text_at_position(p_position, str, p_side);
  1847. }
  1848. }
  1849. void CanvasItemEditor::_draw_focus() {
  1850. // Draw the focus around the base viewport
  1851. if (viewport_base->has_focus()) {
  1852. get_stylebox("Focus", "EditorStyles")->draw(viewport_base->get_canvas_item(), Rect2(Point2(), viewport_base->get_size()));
  1853. }
  1854. }
  1855. void CanvasItemEditor::_draw_guides() {
  1856. Color guide_color = Color(0.6, 0.0, 0.8);
  1857. Transform2D xform = viewport_scrollable->get_transform() * transform;
  1858. // Guides already there
  1859. if (EditorNode::get_singleton()->get_edited_scene() && EditorNode::get_singleton()->get_edited_scene()->has_meta("_edit_vertical_guides_")) {
  1860. Array vguides = EditorNode::get_singleton()->get_edited_scene()->get_meta("_edit_vertical_guides_");
  1861. for (int i = 0; i < vguides.size(); i++) {
  1862. if (drag == DRAG_V_GUIDE && i == edited_guide_index)
  1863. continue;
  1864. float x = xform.xform(Point2(vguides[i], 0)).x;
  1865. viewport_base->draw_line(Point2(x, 0), Point2(x, viewport_base->get_size().y), guide_color);
  1866. }
  1867. }
  1868. if (EditorNode::get_singleton()->get_edited_scene() && EditorNode::get_singleton()->get_edited_scene()->has_meta("_edit_horizontal_guides_")) {
  1869. Array hguides = EditorNode::get_singleton()->get_edited_scene()->get_meta("_edit_horizontal_guides_");
  1870. for (int i = 0; i < hguides.size(); i++) {
  1871. if (drag == DRAG_H_GUIDE && i == edited_guide_index)
  1872. continue;
  1873. float y = xform.xform(Point2(0, hguides[i])).y;
  1874. viewport_base->draw_line(Point2(0, y), Point2(viewport_base->get_size().x, y), guide_color);
  1875. }
  1876. }
  1877. // Dragged guide
  1878. Color text_color = get_color("font_color", "Editor");
  1879. text_color.a = 0.5;
  1880. if (drag == DRAG_DOUBLE_GUIDE || drag == DRAG_V_GUIDE) {
  1881. String str = vformat("%d px", xform.affine_inverse().xform(edited_guide_pos).x);
  1882. Ref<Font> font = get_font("font", "Label");
  1883. Size2 text_size = font->get_string_size(str);
  1884. viewport_base->draw_string(font, Point2(edited_guide_pos.x + 10, RULER_WIDTH + text_size.y / 2 + 10), str, text_color);
  1885. viewport_base->draw_line(Point2(edited_guide_pos.x, 0), Point2(edited_guide_pos.x, viewport_base->get_size().y), guide_color);
  1886. }
  1887. if (drag == DRAG_DOUBLE_GUIDE || drag == DRAG_H_GUIDE) {
  1888. String str = vformat("%d px", xform.affine_inverse().xform(edited_guide_pos).y);
  1889. Ref<Font> font = get_font("font", "Label");
  1890. Size2 text_size = font->get_string_size(str);
  1891. viewport_base->draw_string(font, Point2(RULER_WIDTH + 10, edited_guide_pos.y + text_size.y / 2 + 10), str, text_color);
  1892. viewport_base->draw_line(Point2(0, edited_guide_pos.y), Point2(viewport_base->get_size().x, edited_guide_pos.y), guide_color);
  1893. }
  1894. }
  1895. void CanvasItemEditor::_draw_rulers() {
  1896. Color graduation_color = get_color("font_color", "Editor");
  1897. graduation_color.a = 0.5;
  1898. Color bg_color = get_color("dark_color_2", "Editor");
  1899. Color font_color = get_color("font_color", "Editor");
  1900. font_color.a = 0.8;
  1901. Ref<Font> font = get_font("rulers", "EditorFonts");
  1902. // The rule transform
  1903. Transform2D ruler_transform;
  1904. if (show_grid || snap_grid) {
  1905. ruler_transform = Transform2D();
  1906. if (snap_relative && get_item_count() > 0) {
  1907. ruler_transform.translate(_find_topleftmost_point());
  1908. ruler_transform.scale_basis(grid_step * Math::pow(2.0, grid_step_multiplier));
  1909. } else {
  1910. ruler_transform.translate(grid_offset);
  1911. ruler_transform.scale_basis(grid_step * Math::pow(2.0, grid_step_multiplier));
  1912. }
  1913. while ((transform * ruler_transform).get_scale().x < 50 || (transform * ruler_transform).get_scale().y < 50) {
  1914. ruler_transform.scale_basis(Point2(2, 2));
  1915. }
  1916. } else {
  1917. float basic_rule = 100;
  1918. for (int i = 0; basic_rule * zoom > 100; i++) {
  1919. basic_rule /= (i % 2) ? 5.0 : 2.0;
  1920. }
  1921. for (int i = 0; basic_rule * zoom < 100; i++) {
  1922. basic_rule *= (i % 2) ? 2.0 : 5.0;
  1923. }
  1924. ruler_transform = Transform2D();
  1925. ruler_transform.scale(Size2(basic_rule, basic_rule));
  1926. }
  1927. // Subdivisions
  1928. int major_subdivision = 2;
  1929. Transform2D major_subdivide = Transform2D();
  1930. major_subdivide.scale(Size2(1.0 / major_subdivision, 1.0 / major_subdivision));
  1931. int minor_subdivision = 5;
  1932. Transform2D minor_subdivide = Transform2D();
  1933. minor_subdivide.scale(Size2(1.0 / minor_subdivision, 1.0 / minor_subdivision));
  1934. // First and last graduations to draw (in the ruler space)
  1935. Point2 first = (transform * ruler_transform * major_subdivide * minor_subdivide).affine_inverse().xform(Point2());
  1936. Point2 last = (transform * ruler_transform * major_subdivide * minor_subdivide).affine_inverse().xform(viewport->get_size());
  1937. // Draw top ruler
  1938. viewport_base->draw_rect(Rect2(Point2(RULER_WIDTH, 0), Size2(viewport->get_size().x, RULER_WIDTH)), bg_color);
  1939. for (int i = Math::ceil(first.x); i < last.x; i++) {
  1940. Point2 position = (transform * ruler_transform * major_subdivide * minor_subdivide).xform(Point2(i, 0));
  1941. if (i % (major_subdivision * minor_subdivision) == 0) {
  1942. viewport_base->draw_line(Point2(position.x + RULER_WIDTH, 0), Point2(position.x + RULER_WIDTH, RULER_WIDTH), graduation_color);
  1943. float val = (ruler_transform * major_subdivide * minor_subdivide).xform(Point2(i, 0)).x;
  1944. viewport_base->draw_string(font, Point2(position.x + RULER_WIDTH + 2, font->get_height()), vformat(((int)val == val) ? "%d" : "%.1f", val), font_color);
  1945. } else {
  1946. if (i % minor_subdivision == 0) {
  1947. viewport_base->draw_line(Point2(position.x + RULER_WIDTH, RULER_WIDTH * 0.33), Point2(position.x + RULER_WIDTH, RULER_WIDTH), graduation_color);
  1948. } else {
  1949. viewport_base->draw_line(Point2(position.x + RULER_WIDTH, RULER_WIDTH * 0.66), Point2(position.x + RULER_WIDTH, RULER_WIDTH), graduation_color);
  1950. }
  1951. }
  1952. }
  1953. // Draw left ruler
  1954. viewport_base->draw_rect(Rect2(Point2(0, RULER_WIDTH), Size2(RULER_WIDTH, viewport->get_size().y)), bg_color);
  1955. for (int i = Math::ceil(first.y); i < last.y; i++) {
  1956. Point2 position = (transform * ruler_transform * major_subdivide * minor_subdivide).xform(Point2(0, i));
  1957. if (i % (major_subdivision * minor_subdivision) == 0) {
  1958. viewport_base->draw_line(Point2(0, position.y + RULER_WIDTH), Point2(RULER_WIDTH, position.y + RULER_WIDTH), graduation_color);
  1959. float val = (ruler_transform * major_subdivide * minor_subdivide).xform(Point2(0, i)).y;
  1960. viewport_base->draw_string(font, Point2(2, position.y + RULER_WIDTH + 2 + font->get_height()), vformat(((int)val == val) ? "%d" : "%.1f", val), font_color);
  1961. } else {
  1962. if (i % minor_subdivision == 0) {
  1963. viewport_base->draw_line(Point2(RULER_WIDTH * 0.33, position.y + RULER_WIDTH), Point2(RULER_WIDTH, position.y + RULER_WIDTH), graduation_color);
  1964. } else {
  1965. viewport_base->draw_line(Point2(RULER_WIDTH * 0.66, position.y + RULER_WIDTH), Point2(RULER_WIDTH, position.y + RULER_WIDTH), graduation_color);
  1966. }
  1967. }
  1968. }
  1969. viewport_base->draw_rect(Rect2(Point2(), Size2(RULER_WIDTH, RULER_WIDTH)), graduation_color);
  1970. }
  1971. void CanvasItemEditor::_draw_grid() {
  1972. if (show_grid) {
  1973. //Draw the grid
  1974. Size2 s = viewport->get_size();
  1975. int last_cell = 0;
  1976. Transform2D xform = transform.affine_inverse();
  1977. Vector2 real_grid_offset;
  1978. if (snap_relative && get_item_count() > 0) {
  1979. Vector2 topleft = _find_topleftmost_point();
  1980. real_grid_offset.x = fmod(topleft.x, grid_step.x * (real_t)Math::pow(2.0, grid_step_multiplier));
  1981. real_grid_offset.y = fmod(topleft.y, grid_step.y * (real_t)Math::pow(2.0, grid_step_multiplier));
  1982. } else {
  1983. real_grid_offset = grid_offset;
  1984. }
  1985. const Color grid_minor_color = get_color("grid_minor_color", "Editor");
  1986. if (grid_step.x != 0) {
  1987. for (int i = 0; i < s.width; i++) {
  1988. int cell = Math::fast_ftoi(Math::floor((xform.xform(Vector2(i, 0)).x - real_grid_offset.x) / (grid_step.x * Math::pow(2.0, grid_step_multiplier))));
  1989. if (i == 0)
  1990. last_cell = cell;
  1991. if (last_cell != cell)
  1992. viewport->draw_line(Point2(i, 0), Point2(i, s.height), grid_minor_color);
  1993. last_cell = cell;
  1994. }
  1995. }
  1996. if (grid_step.y != 0) {
  1997. for (int i = 0; i < s.height; i++) {
  1998. int cell = Math::fast_ftoi(Math::floor((xform.xform(Vector2(0, i)).y - real_grid_offset.y) / (grid_step.y * Math::pow(2.0, grid_step_multiplier))));
  1999. if (i == 0)
  2000. last_cell = cell;
  2001. if (last_cell != cell)
  2002. viewport->draw_line(Point2(0, i), Point2(s.width, i), grid_minor_color);
  2003. last_cell = cell;
  2004. }
  2005. }
  2006. }
  2007. }
  2008. void CanvasItemEditor::_draw_selection() {
  2009. bool pivot_found = false;
  2010. Ref<Texture> pivot_icon = get_icon("EditorPivot", "EditorIcons");
  2011. bool single = _get_single_item() != NULL;
  2012. RID ci = viewport->get_canvas_item();
  2013. Map<Node *, Object *> &selection = editor_selection->get_selection();
  2014. for (Map<Node *, Object *>::Element *E = selection.front(); E; E = E->next()) {
  2015. CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->key());
  2016. if (!canvas_item || !canvas_item->is_visible_in_tree())
  2017. continue;
  2018. if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root())
  2019. continue;
  2020. CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item);
  2021. if (!se)
  2022. continue;
  2023. Rect2 rect = canvas_item->get_item_rect();
  2024. if (show_helpers && drag != DRAG_NONE && drag != DRAG_PIVOT) {
  2025. const Transform2D pre_drag_xform = transform * se->pre_drag_xform;
  2026. const Color pre_drag_color = Color(0.4, 0.6, 1, 0.7);
  2027. Vector2 pre_drag_endpoints[4] = {
  2028. pre_drag_xform.xform(se->pre_drag_rect.position),
  2029. pre_drag_xform.xform(se->pre_drag_rect.position + Vector2(se->pre_drag_rect.size.x, 0)),
  2030. pre_drag_xform.xform(se->pre_drag_rect.position + se->pre_drag_rect.size),
  2031. pre_drag_xform.xform(se->pre_drag_rect.position + Vector2(0, se->pre_drag_rect.size.y))
  2032. };
  2033. for (int i = 0; i < 4; i++) {
  2034. viewport->draw_line(pre_drag_endpoints[i], pre_drag_endpoints[(i + 1) % 4], pre_drag_color, 2);
  2035. }
  2036. }
  2037. Transform2D xform = transform * canvas_item->get_global_transform_with_canvas();
  2038. VisualServer::get_singleton()->canvas_item_add_set_transform(ci, xform);
  2039. Vector2 endpoints[4] = {
  2040. xform.xform(rect.position),
  2041. xform.xform(rect.position + Vector2(rect.size.x, 0)),
  2042. xform.xform(rect.position + rect.size),
  2043. xform.xform(rect.position + Vector2(0, rect.size.y))
  2044. };
  2045. Color c = Color(1, 0.6, 0.4, 0.7);
  2046. VisualServer::get_singleton()->canvas_item_add_set_transform(ci, Transform2D());
  2047. for (int i = 0; i < 4; i++) {
  2048. viewport->draw_line(endpoints[i], endpoints[(i + 1) % 4], c, 2);
  2049. }
  2050. if (single && (tool == TOOL_SELECT || tool == TOOL_MOVE || tool == TOOL_ROTATE || tool == TOOL_EDIT_PIVOT)) { //kind of sucks
  2051. Node2D *node2d = Object::cast_to<Node2D>(canvas_item);
  2052. if (node2d) {
  2053. if (node2d->edit_has_pivot()) {
  2054. viewport->draw_texture(pivot_icon, xform.get_origin() + (-pivot_icon->get_size() / 2).floor());
  2055. can_move_pivot = true;
  2056. pivot_found = true;
  2057. }
  2058. }
  2059. Control *control = Object::cast_to<Control>(canvas_item);
  2060. if (control) {
  2061. Vector2 pivot_ofs = control->get_pivot_offset();
  2062. if (pivot_ofs != Vector2()) {
  2063. viewport->draw_texture(pivot_icon, xform.xform(pivot_ofs) + (-pivot_icon->get_size() / 2).floor());
  2064. }
  2065. can_move_pivot = true;
  2066. pivot_found = true;
  2067. if (tool == TOOL_SELECT && show_helpers && !Object::cast_to<Container>(control->get_parent())) {
  2068. // Draw the helpers
  2069. Color color_base = Color(0.8, 0.8, 0.8, 0.5);
  2070. float anchors_values[4];
  2071. anchors_values[0] = control->get_anchor(MARGIN_LEFT);
  2072. anchors_values[1] = control->get_anchor(MARGIN_TOP);
  2073. anchors_values[2] = control->get_anchor(MARGIN_RIGHT);
  2074. anchors_values[3] = control->get_anchor(MARGIN_BOTTOM);
  2075. // Draw the anchors
  2076. Vector2 anchors[4];
  2077. Vector2 anchors_pos[4];
  2078. for (int i = 0; i < 4; i++) {
  2079. anchors[i] = Vector2((i % 2 == 0) ? anchors_values[i] : anchors_values[(i + 1) % 4], (i % 2 == 1) ? anchors_values[i] : anchors_values[(i + 1) % 4]);
  2080. anchors_pos[i] = xform.xform(_anchor_to_position(control, anchors[i]));
  2081. }
  2082. Map<Node *, Object *> &selection = editor_selection->get_selection();
  2083. // Get which anchor is dragged
  2084. int dragged_anchor = -1;
  2085. switch (drag) {
  2086. case DRAG_ANCHOR_ALL:
  2087. case DRAG_ANCHOR_TOP_LEFT:
  2088. dragged_anchor = 0;
  2089. break;
  2090. case DRAG_ANCHOR_TOP_RIGHT:
  2091. dragged_anchor = 1;
  2092. break;
  2093. case DRAG_ANCHOR_BOTTOM_RIGHT:
  2094. dragged_anchor = 2;
  2095. break;
  2096. case DRAG_ANCHOR_BOTTOM_LEFT:
  2097. dragged_anchor = 3;
  2098. break;
  2099. }
  2100. if (dragged_anchor >= 0) {
  2101. // Draw the 4 lines when dragged
  2102. bool snapped;
  2103. Color color_snapped = Color(0.64, 0.93, 0.67, 0.5);
  2104. Vector2 corners_pos[4];
  2105. for (int i = 0; i < 4; i++) {
  2106. corners_pos[i] = xform.xform(_anchor_to_position(control, Vector2((i == 0 || i == 3) ? ANCHOR_BEGIN : ANCHOR_END, (i <= 1) ? ANCHOR_BEGIN : ANCHOR_END)));
  2107. }
  2108. Vector2 line_starts[4];
  2109. Vector2 line_ends[4];
  2110. for (int i = 0; i < 4; i++) {
  2111. float anchor_val = (i >= 2) ? ANCHOR_END - anchors_values[i] : anchors_values[i];
  2112. line_starts[i] = Vector2::linear_interpolate(corners_pos[i], corners_pos[(i + 1) % 4], anchor_val);
  2113. line_ends[i] = Vector2::linear_interpolate(corners_pos[(i + 3) % 4], corners_pos[(i + 2) % 4], anchor_val);
  2114. snapped = anchors_values[i] == 0.0 || anchors_values[i] == 0.5 || anchors_values[i] == 1.0;
  2115. viewport->draw_line(line_starts[i], line_ends[i], snapped ? color_snapped : color_base, (i == dragged_anchor || (i + 3) % 4 == dragged_anchor) ? 2 : 1);
  2116. }
  2117. // Display the percentages next to the lines
  2118. float percent_val;
  2119. percent_val = anchors_values[(dragged_anchor + 2) % 4] - anchors_values[dragged_anchor];
  2120. percent_val = (dragged_anchor >= 2) ? -percent_val : percent_val;
  2121. _draw_percentage_at_position(percent_val, (anchors_pos[dragged_anchor] + anchors_pos[(dragged_anchor + 1) % 4]) / 2, (Margin)((dragged_anchor + 1) % 4));
  2122. percent_val = anchors_values[(dragged_anchor + 3) % 4] - anchors_values[(dragged_anchor + 1) % 4];
  2123. percent_val = ((dragged_anchor + 1) % 4 >= 2) ? -percent_val : percent_val;
  2124. _draw_percentage_at_position(percent_val, (anchors_pos[dragged_anchor] + anchors_pos[(dragged_anchor + 3) % 4]) / 2, (Margin)(dragged_anchor));
  2125. percent_val = anchors_values[(dragged_anchor + 1) % 4];
  2126. percent_val = ((dragged_anchor + 1) % 4 >= 2) ? ANCHOR_END - percent_val : percent_val;
  2127. _draw_percentage_at_position(percent_val, (line_starts[dragged_anchor] + anchors_pos[dragged_anchor]) / 2, (Margin)(dragged_anchor));
  2128. percent_val = anchors_values[dragged_anchor];
  2129. percent_val = (dragged_anchor >= 2) ? ANCHOR_END - percent_val : percent_val;
  2130. _draw_percentage_at_position(percent_val, (line_ends[(dragged_anchor + 1) % 4] + anchors_pos[dragged_anchor]) / 2, (Margin)((dragged_anchor + 1) % 4));
  2131. }
  2132. Rect2 anchor_rects[4];
  2133. anchor_rects[0] = Rect2(anchors_pos[0] - anchor_handle->get_size(), anchor_handle->get_size());
  2134. anchor_rects[1] = Rect2(anchors_pos[1] - Vector2(0.0, anchor_handle->get_size().y), Point2(-anchor_handle->get_size().x, anchor_handle->get_size().y));
  2135. anchor_rects[2] = Rect2(anchors_pos[2], -anchor_handle->get_size());
  2136. anchor_rects[3] = Rect2(anchors_pos[3] - Vector2(anchor_handle->get_size().x, 0.0), Point2(anchor_handle->get_size().x, -anchor_handle->get_size().y));
  2137. for (int i = 0; i < 4; i++) {
  2138. anchor_handle->draw_rect(ci, anchor_rects[i]);
  2139. }
  2140. // Draw the margin values and the node width/height when dragging control side
  2141. float ratio = 0.33;
  2142. Transform2D parent_transform = xform * control->get_transform().affine_inverse();
  2143. float node_pos_in_parent[4];
  2144. node_pos_in_parent[0] = control->get_anchor(MARGIN_LEFT) * control->get_parent_area_size().width + control->get_margin(MARGIN_LEFT);
  2145. node_pos_in_parent[1] = control->get_anchor(MARGIN_TOP) * control->get_parent_area_size().height + control->get_margin(MARGIN_TOP);
  2146. node_pos_in_parent[2] = control->get_anchor(MARGIN_RIGHT) * control->get_parent_area_size().width + control->get_margin(MARGIN_RIGHT);
  2147. node_pos_in_parent[3] = control->get_anchor(MARGIN_BOTTOM) * control->get_parent_area_size().height + control->get_margin(MARGIN_BOTTOM);
  2148. switch (drag) {
  2149. case DRAG_LEFT:
  2150. case DRAG_TOP_LEFT:
  2151. case DRAG_BOTTOM_LEFT:
  2152. _draw_margin_at_position(control->get_size().width, parent_transform.xform(Vector2((node_pos_in_parent[0] + node_pos_in_parent[2]) / 2, node_pos_in_parent[3])) + Vector2(0, 5), MARGIN_BOTTOM);
  2153. case DRAG_ALL:
  2154. Point2 start = Vector2(node_pos_in_parent[0], Math::lerp(node_pos_in_parent[1], node_pos_in_parent[3], ratio));
  2155. Point2 end = start - Vector2(control->get_margin(MARGIN_LEFT), 0);
  2156. _draw_margin_at_position(control->get_margin(MARGIN_LEFT), parent_transform.xform((start + end) / 2), MARGIN_TOP);
  2157. viewport->draw_line(parent_transform.xform(start), parent_transform.xform(end), color_base, 1);
  2158. break;
  2159. }
  2160. switch (drag) {
  2161. case DRAG_RIGHT:
  2162. case DRAG_TOP_RIGHT:
  2163. case DRAG_BOTTOM_RIGHT:
  2164. _draw_margin_at_position(control->get_size().width, parent_transform.xform(Vector2((node_pos_in_parent[0] + node_pos_in_parent[2]) / 2, node_pos_in_parent[3])) + Vector2(0, 5), MARGIN_BOTTOM);
  2165. case DRAG_ALL:
  2166. Point2 start = Vector2(node_pos_in_parent[2], Math::lerp(node_pos_in_parent[3], node_pos_in_parent[1], ratio));
  2167. Point2 end = start - Vector2(control->get_margin(MARGIN_RIGHT), 0);
  2168. _draw_margin_at_position(control->get_margin(MARGIN_RIGHT), parent_transform.xform((start + end) / 2), MARGIN_BOTTOM);
  2169. viewport->draw_line(parent_transform.xform(start), parent_transform.xform(end), color_base, 1);
  2170. break;
  2171. }
  2172. switch (drag) {
  2173. case DRAG_TOP:
  2174. case DRAG_TOP_LEFT:
  2175. case DRAG_TOP_RIGHT:
  2176. _draw_margin_at_position(control->get_size().height, parent_transform.xform(Vector2(node_pos_in_parent[2], (node_pos_in_parent[1] + node_pos_in_parent[3]) / 2)) + Vector2(5, 0), MARGIN_RIGHT);
  2177. case DRAG_ALL:
  2178. Point2 start = Vector2(Math::lerp(node_pos_in_parent[0], node_pos_in_parent[2], ratio), node_pos_in_parent[1]);
  2179. Point2 end = start - Vector2(0, control->get_margin(MARGIN_TOP));
  2180. _draw_margin_at_position(control->get_margin(MARGIN_TOP), parent_transform.xform((start + end) / 2), MARGIN_LEFT);
  2181. viewport->draw_line(parent_transform.xform(start), parent_transform.xform(end), color_base, 1);
  2182. break;
  2183. }
  2184. switch (drag) {
  2185. case DRAG_BOTTOM:
  2186. case DRAG_BOTTOM_LEFT:
  2187. case DRAG_BOTTOM_RIGHT:
  2188. _draw_margin_at_position(control->get_size().height, parent_transform.xform(Vector2(node_pos_in_parent[2], (node_pos_in_parent[1] + node_pos_in_parent[3]) / 2) + Vector2(5, 0)), MARGIN_RIGHT);
  2189. case DRAG_ALL:
  2190. Point2 start = Vector2(Math::lerp(node_pos_in_parent[2], node_pos_in_parent[0], ratio), node_pos_in_parent[3]);
  2191. Point2 end = start - Vector2(0, control->get_margin(MARGIN_BOTTOM));
  2192. _draw_margin_at_position(control->get_margin(MARGIN_BOTTOM), parent_transform.xform((start + end) / 2), MARGIN_RIGHT);
  2193. viewport->draw_line(parent_transform.xform(start), parent_transform.xform(end), color_base, 1);
  2194. break;
  2195. }
  2196. switch (drag) {
  2197. //Draw the ghost rect if the node if rotated/scaled
  2198. case DRAG_LEFT:
  2199. case DRAG_TOP_LEFT:
  2200. case DRAG_TOP:
  2201. case DRAG_TOP_RIGHT:
  2202. case DRAG_RIGHT:
  2203. case DRAG_BOTTOM_RIGHT:
  2204. case DRAG_BOTTOM:
  2205. case DRAG_BOTTOM_LEFT:
  2206. case DRAG_ALL:
  2207. if (control->get_rotation() != 0.0 || control->get_scale() != Vector2(1, 1)) {
  2208. Rect2 rect = Rect2(Vector2(node_pos_in_parent[0], node_pos_in_parent[1]), control->get_size());
  2209. viewport->draw_rect(parent_transform.xform(rect), color_base, false);
  2210. }
  2211. break;
  2212. }
  2213. }
  2214. }
  2215. if (tool == TOOL_SELECT) {
  2216. for (int i = 0; i < 4; i++) {
  2217. int prev = (i + 3) % 4;
  2218. int next = (i + 1) % 4;
  2219. Vector2 ofs = ((endpoints[i] - endpoints[prev]).normalized() + ((endpoints[i] - endpoints[next]).normalized())).normalized();
  2220. ofs *= 1.4144 * (select_handle->get_size().width / 2);
  2221. select_handle->draw(ci, (endpoints[i] + ofs - (select_handle->get_size() / 2)).floor());
  2222. ofs = (endpoints[i] + endpoints[next]) / 2;
  2223. ofs += (endpoints[next] - endpoints[i]).tangent().normalized() * (select_handle->get_size().width / 2);
  2224. select_handle->draw(ci, (ofs - (select_handle->get_size() / 2)).floor());
  2225. }
  2226. }
  2227. }
  2228. }
  2229. pivot_button->set_disabled(!pivot_found);
  2230. if (box_selecting) {
  2231. Point2 bsfrom = transform.xform(drag_from);
  2232. Point2 bsto = transform.xform(box_selecting_to);
  2233. VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(bsfrom, bsto - bsfrom), Color(0.7, 0.7, 1.0, 0.3));
  2234. }
  2235. Color rotate_color(0.4, 0.7, 1.0, 0.8);
  2236. if (drag == DRAG_ROTATE) {
  2237. VisualServer::get_singleton()->canvas_item_add_line(ci, transform.xform(display_rotate_from), transform.xform(display_rotate_to), rotate_color);
  2238. }
  2239. }
  2240. void CanvasItemEditor::_draw_axis() {
  2241. RID ci = viewport->get_canvas_item();
  2242. Color x_axis_color(1.0, 0.4, 0.4, 0.6);
  2243. Color y_axis_color(0.4, 1.0, 0.4, 0.6);
  2244. Color area_axis_color(0.4, 0.4, 1.0, 0.4);
  2245. Point2 origin = transform.get_origin();
  2246. VisualServer::get_singleton()->canvas_item_add_line(ci, Point2(0, origin.y), Point2(viewport->get_size().x, origin.y), x_axis_color);
  2247. VisualServer::get_singleton()->canvas_item_add_line(ci, Point2(origin.x, 0), Point2(origin.x, viewport->get_size().y), y_axis_color);
  2248. Size2 screen_size = Size2(ProjectSettings::get_singleton()->get("display/window/size/width"), ProjectSettings::get_singleton()->get("display/window/size/height"));
  2249. Vector2 screen_endpoints[4] = {
  2250. transform.xform(Vector2(0, 0)),
  2251. transform.xform(Vector2(screen_size.width, 0)),
  2252. transform.xform(Vector2(screen_size.width, screen_size.height)),
  2253. transform.xform(Vector2(0, screen_size.height))
  2254. };
  2255. for (int i = 0; i < 4; i++) {
  2256. VisualServer::get_singleton()->canvas_item_add_line(ci, screen_endpoints[i], screen_endpoints[(i + 1) % 4], area_axis_color);
  2257. }
  2258. }
  2259. void CanvasItemEditor::_draw_bones() {
  2260. RID ci = viewport->get_canvas_item();
  2261. if (skeleton_show_bones) {
  2262. int bone_width = EditorSettings::get_singleton()->get("editors/2d/bone_width");
  2263. Color bone_color1 = EditorSettings::get_singleton()->get("editors/2d/bone_color1");
  2264. Color bone_color2 = EditorSettings::get_singleton()->get("editors/2d/bone_color2");
  2265. Color bone_ik_color = EditorSettings::get_singleton()->get("editors/2d/bone_ik_color");
  2266. Color bone_selected_color = EditorSettings::get_singleton()->get("editors/2d/bone_selected_color");
  2267. for (Map<ObjectID, BoneList>::Element *E = bone_list.front(); E; E = E->next()) {
  2268. E->get().from = Vector2();
  2269. E->get().to = Vector2();
  2270. Node2D *n2d = Object::cast_to<Node2D>(ObjectDB::get_instance(E->get().bone));
  2271. if (!n2d)
  2272. continue;
  2273. if (!n2d->get_parent())
  2274. continue;
  2275. CanvasItem *pi = n2d->get_parent_item();
  2276. Node2D *pn2d = Object::cast_to<Node2D>(n2d->get_parent());
  2277. if (!pn2d)
  2278. continue;
  2279. Vector2 from = transform.xform(pn2d->get_global_position());
  2280. Vector2 to = transform.xform(n2d->get_global_position());
  2281. E->get().from = from;
  2282. E->get().to = to;
  2283. Vector2 rel = to - from;
  2284. Vector2 relt = rel.tangent().normalized() * bone_width;
  2285. Vector<Vector2> bone_shape;
  2286. bone_shape.push_back(from);
  2287. bone_shape.push_back(from + rel * 0.2 + relt);
  2288. bone_shape.push_back(to);
  2289. bone_shape.push_back(from + rel * 0.2 - relt);
  2290. Vector<Color> colors;
  2291. if (pi->has_meta("_edit_ik_")) {
  2292. colors.push_back(bone_ik_color);
  2293. colors.push_back(bone_ik_color);
  2294. colors.push_back(bone_ik_color);
  2295. colors.push_back(bone_ik_color);
  2296. } else {
  2297. colors.push_back(bone_color1);
  2298. colors.push_back(bone_color2);
  2299. colors.push_back(bone_color1);
  2300. colors.push_back(bone_color2);
  2301. }
  2302. VisualServer::get_singleton()->canvas_item_add_primitive(ci, bone_shape, colors, Vector<Vector2>(), RID());
  2303. if (editor_selection->is_selected(pi)) {
  2304. for (int i = 0; i < bone_shape.size(); i++) {
  2305. VisualServer::get_singleton()->canvas_item_add_line(ci, bone_shape[i], bone_shape[(i + 1) % bone_shape.size()], bone_selected_color, 2);
  2306. }
  2307. }
  2308. }
  2309. }
  2310. }
  2311. void CanvasItemEditor::_draw_locks_and_groups(Node *p_node, const Transform2D &p_xform) {
  2312. ERR_FAIL_COND(!p_node);
  2313. RID viewport_ci = viewport->get_canvas_item();
  2314. Transform2D transform_ci = p_xform;
  2315. CanvasItem *ci = Object::cast_to<CanvasItem>(p_node);
  2316. if (ci)
  2317. transform_ci = transform_ci * ci->get_transform();
  2318. for (int i = p_node->get_child_count() - 1; i >= 0; i--) {
  2319. _draw_locks_and_groups(p_node->get_child(i), transform_ci);
  2320. }
  2321. if (ci) {
  2322. Ref<Texture> lock = get_icon("LockViewport", "EditorIcons");
  2323. if (p_node->has_meta("_edit_lock_")) {
  2324. lock->draw(viewport_ci, transform_ci.xform(Point2(0, 0)));
  2325. }
  2326. Ref<Texture> group = get_icon("GroupViewport", "EditorIcons");
  2327. if (ci->has_meta("_edit_group_")) {
  2328. Vector2 ofs = transform_ci.xform(Point2(0, 0));
  2329. if (ci->has_meta("_edit_lock_"))
  2330. ofs = Point2(ofs.x + lock->get_size().x, ofs.y);
  2331. group->draw(viewport_ci, ofs);
  2332. }
  2333. }
  2334. }
  2335. void CanvasItemEditor::_build_bones_list(Node *p_node) {
  2336. ERR_FAIL_COND(!p_node);
  2337. for (int i = 0; i < p_node->get_child_count(); i++) {
  2338. _build_bones_list(p_node->get_child(i));
  2339. }
  2340. CanvasItem *c = Object::cast_to<CanvasItem>(p_node);
  2341. if (c && c->is_visible_in_tree()) {
  2342. if (c->has_meta("_edit_bone_")) {
  2343. ObjectID id = c->get_instance_id();
  2344. if (!bone_list.has(id)) {
  2345. BoneList bone;
  2346. bone.bone = id;
  2347. bone_list[id] = bone;
  2348. }
  2349. bone_list[id].last_pass = bone_last_frame;
  2350. }
  2351. }
  2352. }
  2353. void CanvasItemEditor::_get_encompassing_rect(Node *p_node, Rect2 &r_rect, const Transform2D &p_xform) {
  2354. ERR_FAIL_COND(!p_node);
  2355. for (int i = 0; i < p_node->get_child_count(); i++) {
  2356. _get_encompassing_rect(p_node->get_child(i), r_rect, p_xform);
  2357. }
  2358. CanvasItem *c = Object::cast_to<CanvasItem>(p_node);
  2359. if (c && c->is_visible_in_tree()) {
  2360. Rect2 rect = c->get_item_rect();
  2361. Transform2D xform = p_xform * c->get_transform();
  2362. r_rect.expand_to(xform.xform(rect.position));
  2363. r_rect.expand_to(xform.xform(rect.position + Point2(rect.size.x, 0)));
  2364. r_rect.expand_to(xform.xform(rect.position + Point2(0, rect.size.y)));
  2365. r_rect.expand_to(xform.xform(rect.position + rect.size));
  2366. }
  2367. }
  2368. void CanvasItemEditor::_draw_viewport_base() {
  2369. if (show_rulers)
  2370. _draw_rulers();
  2371. if (show_guides)
  2372. _draw_guides();
  2373. _draw_focus();
  2374. }
  2375. void CanvasItemEditor::_draw_viewport() {
  2376. // hide/show buttons depending on the selection
  2377. bool all_locked = true;
  2378. bool all_group = true;
  2379. List<Node *> &selection = editor_selection->get_selected_node_list();
  2380. if (selection.empty()) {
  2381. all_locked = false;
  2382. all_group = false;
  2383. } else {
  2384. for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
  2385. if (Object::cast_to<CanvasItem>(E->get()) && !Object::cast_to<CanvasItem>(E->get())->has_meta("_edit_lock_")) {
  2386. all_locked = false;
  2387. break;
  2388. }
  2389. }
  2390. for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
  2391. if (Object::cast_to<CanvasItem>(E->get()) && !Object::cast_to<CanvasItem>(E->get())->has_meta("_edit_group_")) {
  2392. all_group = false;
  2393. break;
  2394. }
  2395. }
  2396. }
  2397. lock_button->set_visible(!all_locked);
  2398. lock_button->set_disabled(selection.empty());
  2399. unlock_button->set_visible(all_locked);
  2400. group_button->set_visible(!all_group);
  2401. group_button->set_disabled(selection.empty());
  2402. ungroup_button->set_visible(all_group);
  2403. _update_scrollbars();
  2404. _draw_grid();
  2405. _draw_selection();
  2406. _draw_axis();
  2407. if (editor->get_edited_scene())
  2408. _draw_locks_and_groups(editor->get_edited_scene(), transform);
  2409. RID ci = viewport->get_canvas_item();
  2410. VisualServer::get_singleton()->canvas_item_add_set_transform(ci, Transform2D());
  2411. EditorPluginList *over_plugin_list = editor->get_editor_plugins_over();
  2412. if (!over_plugin_list->empty()) {
  2413. over_plugin_list->forward_draw_over_canvas(viewport);
  2414. }
  2415. _draw_bones();
  2416. }
  2417. void CanvasItemEditor::_notification(int p_what) {
  2418. if (p_what == NOTIFICATION_PHYSICS_PROCESS) {
  2419. EditorNode::get_singleton()->get_scene_root()->set_snap_controls_to_pixels(GLOBAL_GET("gui/common/snap_controls_to_pixels"));
  2420. List<Node *> &selection = editor_selection->get_selected_node_list();
  2421. bool all_control = true;
  2422. bool has_control = false;
  2423. for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
  2424. CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->get());
  2425. if (!canvas_item || !canvas_item->is_visible_in_tree())
  2426. continue;
  2427. if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root())
  2428. continue;
  2429. if (Object::cast_to<Control>(canvas_item))
  2430. has_control = true;
  2431. else
  2432. all_control = false;
  2433. CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item);
  2434. if (!se)
  2435. continue;
  2436. Rect2 r = canvas_item->get_item_rect();
  2437. Transform2D xform = canvas_item->get_transform();
  2438. if (r != se->prev_rect || xform != se->prev_xform) {
  2439. viewport->update();
  2440. se->prev_rect = r;
  2441. se->prev_xform = xform;
  2442. }
  2443. if (Object::cast_to<Control>(canvas_item)) {
  2444. float anchors[4];
  2445. Vector2 pivot;
  2446. pivot = Object::cast_to<Control>(canvas_item)->get_pivot_offset();
  2447. anchors[MARGIN_LEFT] = Object::cast_to<Control>(canvas_item)->get_anchor(MARGIN_LEFT);
  2448. anchors[MARGIN_RIGHT] = Object::cast_to<Control>(canvas_item)->get_anchor(MARGIN_RIGHT);
  2449. anchors[MARGIN_TOP] = Object::cast_to<Control>(canvas_item)->get_anchor(MARGIN_TOP);
  2450. anchors[MARGIN_BOTTOM] = Object::cast_to<Control>(canvas_item)->get_anchor(MARGIN_BOTTOM);
  2451. if (pivot != se->prev_pivot || anchors[MARGIN_LEFT] != se->prev_anchors[MARGIN_LEFT] || anchors[MARGIN_RIGHT] != se->prev_anchors[MARGIN_RIGHT] || anchors[MARGIN_TOP] != se->prev_anchors[MARGIN_TOP] || anchors[MARGIN_BOTTOM] != se->prev_anchors[MARGIN_BOTTOM]) {
  2452. viewport->update();
  2453. viewport_base->update();
  2454. se->prev_pivot = pivot;
  2455. se->prev_anchors[MARGIN_LEFT] = anchors[MARGIN_LEFT];
  2456. se->prev_anchors[MARGIN_RIGHT] = anchors[MARGIN_RIGHT];
  2457. se->prev_anchors[MARGIN_TOP] = anchors[MARGIN_TOP];
  2458. se->prev_anchors[MARGIN_BOTTOM] = anchors[MARGIN_BOTTOM];
  2459. }
  2460. }
  2461. }
  2462. if (all_control && has_control)
  2463. presets_menu->show();
  2464. else
  2465. presets_menu->hide();
  2466. for (Map<ObjectID, BoneList>::Element *E = bone_list.front(); E; E = E->next()) {
  2467. Object *b = ObjectDB::get_instance(E->get().bone);
  2468. if (!b) {
  2469. viewport->update();
  2470. break;
  2471. }
  2472. Node2D *b2 = Object::cast_to<Node2D>(b);
  2473. if (!b2) {
  2474. continue;
  2475. }
  2476. if (b2->get_global_transform() != E->get().xform) {
  2477. E->get().xform = b2->get_global_transform();
  2478. viewport->update();
  2479. }
  2480. }
  2481. }
  2482. if (p_what == NOTIFICATION_ENTER_TREE) {
  2483. select_sb->set_texture(get_icon("EditorRect2D", "EditorIcons"));
  2484. for (int i = 0; i < 4; i++) {
  2485. select_sb->set_margin_size(Margin(i), 4);
  2486. select_sb->set_default_margin(Margin(i), 4);
  2487. }
  2488. AnimationPlayerEditor::singleton->get_key_editor()->connect("visibility_changed", this, "_keying_changed");
  2489. _keying_changed();
  2490. } else if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
  2491. select_sb->set_texture(get_icon("EditorRect2D", "EditorIcons"));
  2492. }
  2493. if (p_what == NOTIFICATION_ENTER_TREE || p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
  2494. select_button->set_icon(get_icon("ToolSelect", "EditorIcons"));
  2495. list_select_button->set_icon(get_icon("ListSelect", "EditorIcons"));
  2496. move_button->set_icon(get_icon("ToolMove", "EditorIcons"));
  2497. rotate_button->set_icon(get_icon("ToolRotate", "EditorIcons"));
  2498. snap_button->set_icon(get_icon("Snap", "EditorIcons"));
  2499. snap_config_menu->set_icon(get_icon("GuiMiniTabMenu", "EditorIcons"));
  2500. skeleton_menu->set_icon(get_icon("Bone", "EditorIcons"));
  2501. pan_button->set_icon(get_icon("ToolPan", "EditorIcons"));
  2502. pivot_button->set_icon(get_icon("EditPivot", "EditorIcons"));
  2503. select_handle = get_icon("EditorHandle", "EditorIcons");
  2504. anchor_handle = get_icon("EditorControlAnchor", "EditorIcons");
  2505. lock_button->set_icon(get_icon("Lock", "EditorIcons"));
  2506. unlock_button->set_icon(get_icon("Unlock", "EditorIcons"));
  2507. group_button->set_icon(get_icon("Group", "EditorIcons"));
  2508. ungroup_button->set_icon(get_icon("Ungroup", "EditorIcons"));
  2509. key_loc_button->set_icon(get_icon("KeyPosition", "EditorIcons"));
  2510. key_rot_button->set_icon(get_icon("KeyRotation", "EditorIcons"));
  2511. key_scale_button->set_icon(get_icon("KeyScale", "EditorIcons"));
  2512. key_insert_button->set_icon(get_icon("Key", "EditorIcons"));
  2513. zoom_minus->set_icon(get_icon("ZoomLess", "EditorIcons"));
  2514. zoom_reset->set_icon(get_icon("ZoomReset", "EditorIcons"));
  2515. zoom_plus->set_icon(get_icon("ZoomMore", "EditorIcons"));
  2516. presets_menu->set_icon(get_icon("ControlLayout", "EditorIcons"));
  2517. PopupMenu *p = presets_menu->get_popup();
  2518. p->clear();
  2519. p->add_icon_item(get_icon("ControlAlignTopLeft", "EditorIcons"), "Top Left", ANCHORS_AND_MARGINS_PRESET_TOP_LEFT);
  2520. p->add_icon_item(get_icon("ControlAlignTopRight", "EditorIcons"), "Top Right", ANCHORS_AND_MARGINS_PRESET_TOP_RIGHT);
  2521. p->add_icon_item(get_icon("ControlAlignBottomRight", "EditorIcons"), "Bottom Right", ANCHORS_AND_MARGINS_PRESET_BOTTOM_RIGHT);
  2522. p->add_icon_item(get_icon("ControlAlignBottomLeft", "EditorIcons"), "Bottom Left", ANCHORS_AND_MARGINS_PRESET_BOTTOM_LEFT);
  2523. p->add_separator();
  2524. p->add_icon_item(get_icon("ControlAlignLeftCenter", "EditorIcons"), "Center Left", ANCHORS_AND_MARGINS_PRESET_CENTER_LEFT);
  2525. p->add_icon_item(get_icon("ControlAlignTopCenter", "EditorIcons"), "Center Top", ANCHORS_AND_MARGINS_PRESET_CENTER_TOP);
  2526. p->add_icon_item(get_icon("ControlAlignRightCenter", "EditorIcons"), "Center Right", ANCHORS_AND_MARGINS_PRESET_CENTER_RIGHT);
  2527. p->add_icon_item(get_icon("ControlAlignBottomCenter", "EditorIcons"), "Center Bottom", ANCHORS_AND_MARGINS_PRESET_CENTER_BOTTOM);
  2528. p->add_icon_item(get_icon("ControlAlignCenter", "EditorIcons"), "Center", ANCHORS_AND_MARGINS_PRESET_CENTER);
  2529. p->add_separator();
  2530. p->add_icon_item(get_icon("ControlAlignLeftWide", "EditorIcons"), "Left Wide", ANCHORS_AND_MARGINS_PRESET_LEFT_WIDE);
  2531. p->add_icon_item(get_icon("ControlAlignTopWide", "EditorIcons"), "Top Wide", ANCHORS_AND_MARGINS_PRESET_TOP_WIDE);
  2532. p->add_icon_item(get_icon("ControlAlignRightWide", "EditorIcons"), "Right Wide", ANCHORS_AND_MARGINS_PRESET_RIGHT_WIDE);
  2533. p->add_icon_item(get_icon("ControlAlignBottomWide", "EditorIcons"), "Bottom Wide", ANCHORS_AND_MARGINS_PRESET_BOTTOM_WIDE);
  2534. p->add_icon_item(get_icon("ControlVcenterWide", "EditorIcons"), "VCenter Wide ", ANCHORS_AND_MARGINS_PRESET_VCENTER_WIDE);
  2535. p->add_icon_item(get_icon("ControlHcenterWide", "EditorIcons"), "HCenter Wide ", ANCHORS_AND_MARGINS_PRESET_HCENTER_WIDE);
  2536. p->add_separator();
  2537. p->add_icon_item(get_icon("ControlAlignWide", "EditorIcons"), "Full Rect", ANCHORS_AND_MARGINS_PRESET_WIDE);
  2538. p->add_separator();
  2539. p->add_submenu_item(TTR("Anchors only"), "Anchors");
  2540. p->set_item_icon(20, get_icon("Anchor", "EditorIcons"));
  2541. anchors_popup->clear();
  2542. anchors_popup->add_icon_item(get_icon("ControlAlignTopLeft", "EditorIcons"), "Top Left", ANCHORS_PRESET_TOP_LEFT);
  2543. anchors_popup->add_icon_item(get_icon("ControlAlignTopRight", "EditorIcons"), "Top Right", ANCHORS_PRESET_TOP_RIGHT);
  2544. anchors_popup->add_icon_item(get_icon("ControlAlignBottomRight", "EditorIcons"), "Bottom Right", ANCHORS_PRESET_BOTTOM_RIGHT);
  2545. anchors_popup->add_icon_item(get_icon("ControlAlignBottomLeft", "EditorIcons"), "Bottom Left", ANCHORS_PRESET_BOTTOM_LEFT);
  2546. anchors_popup->add_separator();
  2547. anchors_popup->add_icon_item(get_icon("ControlAlignLeftCenter", "EditorIcons"), "Center Left", ANCHORS_PRESET_CENTER_LEFT);
  2548. anchors_popup->add_icon_item(get_icon("ControlAlignTopCenter", "EditorIcons"), "Center Top", ANCHORS_PRESET_CENTER_TOP);
  2549. anchors_popup->add_icon_item(get_icon("ControlAlignRightCenter", "EditorIcons"), "Center Right", ANCHORS_PRESET_CENTER_RIGHT);
  2550. anchors_popup->add_icon_item(get_icon("ControlAlignBottomCenter", "EditorIcons"), "Center Bottom", ANCHORS_PRESET_CENTER_BOTTOM);
  2551. anchors_popup->add_icon_item(get_icon("ControlAlignCenter", "EditorIcons"), "Center", ANCHORS_PRESET_CENTER);
  2552. anchors_popup->add_separator();
  2553. anchors_popup->add_icon_item(get_icon("ControlAlignLeftWide", "EditorIcons"), "Left Wide", ANCHORS_PRESET_LEFT_WIDE);
  2554. anchors_popup->add_icon_item(get_icon("ControlAlignTopWide", "EditorIcons"), "Top Wide", ANCHORS_PRESET_TOP_WIDE);
  2555. anchors_popup->add_icon_item(get_icon("ControlAlignRightWide", "EditorIcons"), "Right Wide", ANCHORS_PRESET_RIGHT_WIDE);
  2556. anchors_popup->add_icon_item(get_icon("ControlAlignBottomWide", "EditorIcons"), "Bottom Wide", ANCHORS_PRESET_BOTTOM_WIDE);
  2557. anchors_popup->add_icon_item(get_icon("ControlVcenterWide", "EditorIcons"), "VCenter Wide ", ANCHORS_PRESET_VCENTER_WIDE);
  2558. anchors_popup->add_icon_item(get_icon("ControlHcenterWide", "EditorIcons"), "HCenter Wide ", ANCHORS_PRESET_HCENTER_WIDE);
  2559. anchors_popup->add_separator();
  2560. anchors_popup->add_icon_item(get_icon("ControlAlignWide", "EditorIcons"), "Full Rect", ANCHORS_PRESET_WIDE);
  2561. }
  2562. }
  2563. void CanvasItemEditor::edit(CanvasItem *p_canvas_item) {
  2564. drag = DRAG_NONE;
  2565. // Clear the selection
  2566. editor_selection->clear(); //_clear_canvas_items();
  2567. editor_selection->add_node(p_canvas_item);
  2568. //_add_canvas_item(p_canvas_item);
  2569. viewport->update();
  2570. viewport_base->update();
  2571. }
  2572. void CanvasItemEditor::_update_scrollbars() {
  2573. updating_scroll = true;
  2574. if (show_rulers)
  2575. viewport_scrollable->set_begin(Point2(RULER_WIDTH, RULER_WIDTH));
  2576. else
  2577. viewport_scrollable->set_begin(Point2());
  2578. Size2 size = viewport->get_size();
  2579. Size2 hmin = h_scroll->get_minimum_size();
  2580. Size2 vmin = v_scroll->get_minimum_size();
  2581. v_scroll->set_begin(Point2(size.width - vmin.width, 0));
  2582. v_scroll->set_end(Point2(size.width, size.height));
  2583. h_scroll->set_begin(Point2(0, size.height - hmin.height));
  2584. h_scroll->set_end(Point2(size.width - vmin.width, size.height));
  2585. Size2 screen_rect = Size2(ProjectSettings::get_singleton()->get("display/window/size/width"), ProjectSettings::get_singleton()->get("display/window/size/height"));
  2586. Rect2 local_rect = Rect2(Point2(), viewport->get_size() - Size2(vmin.width, hmin.height));
  2587. Rect2 canvas_item_rect = Rect2(Point2(), screen_rect);
  2588. bone_last_frame++;
  2589. if (editor->get_edited_scene()) {
  2590. _build_bones_list(editor->get_edited_scene());
  2591. _get_encompassing_rect(editor->get_edited_scene(), canvas_item_rect, Transform2D());
  2592. }
  2593. List<Map<ObjectID, BoneList>::Element *> bone_to_erase;
  2594. for (Map<ObjectID, BoneList>::Element *E = bone_list.front(); E; E = E->next()) {
  2595. if (E->get().last_pass != bone_last_frame) {
  2596. bone_to_erase.push_back(E);
  2597. }
  2598. }
  2599. while (bone_to_erase.size()) {
  2600. bone_list.erase(bone_to_erase.front()->get());
  2601. bone_to_erase.pop_front();
  2602. }
  2603. //expand area so it's easier to do animations and stuff at 0,0
  2604. canvas_item_rect.size += screen_rect * 2;
  2605. canvas_item_rect.position -= screen_rect;
  2606. Point2 ofs;
  2607. if (canvas_item_rect.size.height <= (local_rect.size.y / zoom)) {
  2608. v_scroll->hide();
  2609. ofs.y = canvas_item_rect.position.y;
  2610. } else {
  2611. v_scroll->show();
  2612. v_scroll->set_min(canvas_item_rect.position.y);
  2613. v_scroll->set_max(canvas_item_rect.position.y + canvas_item_rect.size.y);
  2614. v_scroll->set_page(local_rect.size.y / zoom);
  2615. if (first_update) {
  2616. //so 0,0 is visible
  2617. v_scroll->set_value(-10);
  2618. h_scroll->set_value(-10);
  2619. first_update = false;
  2620. }
  2621. ofs.y = v_scroll->get_value();
  2622. }
  2623. if (canvas_item_rect.size.width <= (local_rect.size.x / zoom)) {
  2624. h_scroll->hide();
  2625. ofs.x = canvas_item_rect.position.x;
  2626. } else {
  2627. h_scroll->show();
  2628. h_scroll->set_min(canvas_item_rect.position.x);
  2629. h_scroll->set_max(canvas_item_rect.position.x + canvas_item_rect.size.x);
  2630. h_scroll->set_page(local_rect.size.x / zoom);
  2631. ofs.x = h_scroll->get_value();
  2632. }
  2633. //transform=Matrix32();
  2634. transform.elements[2] = -ofs * zoom;
  2635. editor->get_scene_root()->set_global_canvas_transform(transform);
  2636. updating_scroll = false;
  2637. //transform.scale_basis(Vector2(zoom,zoom));
  2638. }
  2639. void CanvasItemEditor::_update_scroll(float) {
  2640. if (updating_scroll)
  2641. return;
  2642. Point2 ofs;
  2643. ofs.x = h_scroll->get_value();
  2644. ofs.y = v_scroll->get_value();
  2645. //current_window->set_scroll(-ofs);
  2646. transform = Transform2D();
  2647. transform.scale_basis(Size2(zoom, zoom));
  2648. transform.elements[2] = -ofs;
  2649. editor->get_scene_root()->set_global_canvas_transform(transform);
  2650. viewport->update();
  2651. viewport_base->update();
  2652. }
  2653. void CanvasItemEditor::_set_anchors_and_margins_preset(Control::LayoutPreset p_preset) {
  2654. List<Node *> &selection = editor_selection->get_selected_node_list();
  2655. undo_redo->create_action(TTR("Change Anchors and Margins"));
  2656. for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
  2657. Control *c = Object::cast_to<Control>(E->get());
  2658. undo_redo->add_do_method(c, "set_anchors_preset", p_preset);
  2659. switch (p_preset) {
  2660. case PRESET_TOP_LEFT:
  2661. case PRESET_TOP_RIGHT:
  2662. case PRESET_BOTTOM_LEFT:
  2663. case PRESET_BOTTOM_RIGHT:
  2664. case PRESET_CENTER_LEFT:
  2665. case PRESET_CENTER_TOP:
  2666. case PRESET_CENTER_RIGHT:
  2667. case PRESET_CENTER_BOTTOM:
  2668. case PRESET_CENTER:
  2669. undo_redo->add_do_method(c, "set_margins_preset", p_preset, Control::PRESET_MODE_KEEP_SIZE);
  2670. break;
  2671. case PRESET_LEFT_WIDE:
  2672. case PRESET_TOP_WIDE:
  2673. case PRESET_RIGHT_WIDE:
  2674. case PRESET_BOTTOM_WIDE:
  2675. case PRESET_VCENTER_WIDE:
  2676. case PRESET_HCENTER_WIDE:
  2677. case PRESET_WIDE:
  2678. undo_redo->add_do_method(c, "set_margins_preset", p_preset, Control::PRESET_MODE_MINSIZE);
  2679. break;
  2680. }
  2681. undo_redo->add_undo_method(c, "set_anchor", MARGIN_LEFT, c->get_anchor(MARGIN_LEFT));
  2682. undo_redo->add_undo_method(c, "set_anchor", MARGIN_TOP, c->get_anchor(MARGIN_TOP));
  2683. undo_redo->add_undo_method(c, "set_anchor", MARGIN_RIGHT, c->get_anchor(MARGIN_RIGHT));
  2684. undo_redo->add_undo_method(c, "set_anchor", MARGIN_BOTTOM, c->get_anchor(MARGIN_BOTTOM));
  2685. undo_redo->add_undo_method(c, "set_margin", MARGIN_LEFT, c->get_margin(MARGIN_LEFT));
  2686. undo_redo->add_undo_method(c, "set_margin", MARGIN_TOP, c->get_margin(MARGIN_TOP));
  2687. undo_redo->add_undo_method(c, "set_margin", MARGIN_RIGHT, c->get_margin(MARGIN_RIGHT));
  2688. undo_redo->add_undo_method(c, "set_margin", MARGIN_BOTTOM, c->get_margin(MARGIN_BOTTOM));
  2689. }
  2690. undo_redo->commit_action();
  2691. }
  2692. void CanvasItemEditor::_set_anchors_preset(Control::LayoutPreset p_preset) {
  2693. List<Node *> &selection = editor_selection->get_selected_node_list();
  2694. undo_redo->create_action(TTR("Change Anchors"));
  2695. for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
  2696. Control *c = Object::cast_to<Control>(E->get());
  2697. undo_redo->add_do_method(c, "set_anchors_preset", p_preset);
  2698. undo_redo->add_undo_method(c, "set_anchor", MARGIN_LEFT, c->get_anchor(MARGIN_LEFT));
  2699. undo_redo->add_undo_method(c, "set_anchor", MARGIN_TOP, c->get_anchor(MARGIN_TOP));
  2700. undo_redo->add_undo_method(c, "set_anchor", MARGIN_RIGHT, c->get_anchor(MARGIN_RIGHT));
  2701. undo_redo->add_undo_method(c, "set_anchor", MARGIN_BOTTOM, c->get_anchor(MARGIN_BOTTOM));
  2702. }
  2703. undo_redo->commit_action();
  2704. }
  2705. void CanvasItemEditor::_zoom_on_position(float p_zoom, Point2 p_position) {
  2706. if (p_zoom < MIN_ZOOM || p_zoom > MAX_ZOOM)
  2707. return;
  2708. float prev_zoom = zoom;
  2709. zoom = p_zoom;
  2710. Point2 ofs = p_position;
  2711. ofs = ofs / prev_zoom - ofs / zoom;
  2712. h_scroll->set_value(h_scroll->get_value() + ofs.x);
  2713. v_scroll->set_value(v_scroll->get_value() + ofs.y);
  2714. _update_scroll(0);
  2715. viewport->update();
  2716. viewport_base->update();
  2717. }
  2718. void CanvasItemEditor::_zoom_minus() {
  2719. _zoom_on_position(zoom / 2.0, viewport_scrollable->get_size() / 2.0);
  2720. }
  2721. void CanvasItemEditor::_zoom_reset() {
  2722. _zoom_on_position(1.0, viewport_scrollable->get_size() / 2.0);
  2723. }
  2724. void CanvasItemEditor::_zoom_plus() {
  2725. _zoom_on_position(zoom * 2.0, viewport_scrollable->get_size() / 2.0);
  2726. }
  2727. void CanvasItemEditor::_toggle_snap(bool p_status) {
  2728. snap_active = p_status;
  2729. viewport->update();
  2730. viewport_base->update();
  2731. }
  2732. void CanvasItemEditor::_popup_callback(int p_op) {
  2733. last_option = MenuOption(p_op);
  2734. switch (p_op) {
  2735. case SHOW_GRID: {
  2736. show_grid = !show_grid;
  2737. int idx = view_menu->get_popup()->get_item_index(SHOW_GRID);
  2738. view_menu->get_popup()->set_item_checked(idx, show_grid);
  2739. viewport->update();
  2740. viewport_base->update();
  2741. } break;
  2742. case SNAP_USE_NODE_PARENT: {
  2743. snap_node_parent = !snap_node_parent;
  2744. int idx = smartsnap_config_popup->get_item_index(SNAP_USE_NODE_PARENT);
  2745. smartsnap_config_popup->set_item_checked(idx, snap_node_parent);
  2746. } break;
  2747. case SNAP_USE_NODE_ANCHORS: {
  2748. snap_node_anchors = !snap_node_anchors;
  2749. int idx = smartsnap_config_popup->get_item_index(SNAP_USE_NODE_ANCHORS);
  2750. smartsnap_config_popup->set_item_checked(idx, snap_node_anchors);
  2751. } break;
  2752. case SNAP_USE_NODE_SIDES: {
  2753. snap_node_sides = !snap_node_sides;
  2754. int idx = smartsnap_config_popup->get_item_index(SNAP_USE_NODE_SIDES);
  2755. smartsnap_config_popup->set_item_checked(idx, snap_node_sides);
  2756. } break;
  2757. case SNAP_USE_OTHER_NODES: {
  2758. snap_other_nodes = !snap_other_nodes;
  2759. int idx = smartsnap_config_popup->get_item_index(SNAP_USE_OTHER_NODES);
  2760. smartsnap_config_popup->set_item_checked(idx, snap_other_nodes);
  2761. } break;
  2762. case SNAP_USE_GUIDES: {
  2763. snap_guides = !snap_guides;
  2764. int idx = smartsnap_config_popup->get_item_index(SNAP_USE_GUIDES);
  2765. smartsnap_config_popup->set_item_checked(idx, snap_guides);
  2766. } break;
  2767. case SNAP_USE_GRID: {
  2768. snap_grid = !snap_grid;
  2769. int idx = snap_config_menu->get_popup()->get_item_index(SNAP_USE_GRID);
  2770. snap_config_menu->get_popup()->set_item_checked(idx, snap_grid);
  2771. } break;
  2772. case SNAP_USE_ROTATION: {
  2773. snap_rotation = !snap_rotation;
  2774. int idx = snap_config_menu->get_popup()->get_item_index(SNAP_USE_ROTATION);
  2775. snap_config_menu->get_popup()->set_item_checked(idx, snap_rotation);
  2776. } break;
  2777. case SNAP_RELATIVE: {
  2778. snap_relative = !snap_relative;
  2779. int idx = snap_config_menu->get_popup()->get_item_index(SNAP_RELATIVE);
  2780. snap_config_menu->get_popup()->set_item_checked(idx, snap_relative);
  2781. viewport->update();
  2782. viewport_base->update();
  2783. } break;
  2784. case SNAP_USE_PIXEL: {
  2785. snap_pixel = !snap_pixel;
  2786. int idx = snap_config_menu->get_popup()->get_item_index(SNAP_USE_PIXEL);
  2787. snap_config_menu->get_popup()->set_item_checked(idx, snap_pixel);
  2788. } break;
  2789. case SNAP_CONFIGURE: {
  2790. ((SnapDialog *)snap_dialog)->set_fields(grid_offset, grid_step, snap_rotation_offset, snap_rotation_step);
  2791. snap_dialog->popup_centered(Size2(220, 160));
  2792. } break;
  2793. case SKELETON_SHOW_BONES: {
  2794. skeleton_show_bones = !skeleton_show_bones;
  2795. int idx = skeleton_menu->get_popup()->get_item_index(SKELETON_SHOW_BONES);
  2796. skeleton_menu->get_popup()->set_item_checked(idx, skeleton_show_bones);
  2797. viewport->update();
  2798. } break;
  2799. case SHOW_HELPERS: {
  2800. show_helpers = !show_helpers;
  2801. int idx = view_menu->get_popup()->get_item_index(SHOW_HELPERS);
  2802. view_menu->get_popup()->set_item_checked(idx, show_helpers);
  2803. viewport->update();
  2804. } break;
  2805. case SHOW_RULERS: {
  2806. show_rulers = !show_rulers;
  2807. int idx = view_menu->get_popup()->get_item_index(SHOW_RULERS);
  2808. view_menu->get_popup()->set_item_checked(idx, show_rulers);
  2809. viewport->update();
  2810. viewport_base->update();
  2811. } break;
  2812. case SHOW_GUIDES: {
  2813. show_guides = !show_guides;
  2814. int idx = view_menu->get_popup()->get_item_index(SHOW_GUIDES);
  2815. view_menu->get_popup()->set_item_checked(idx, show_guides);
  2816. viewport->update();
  2817. viewport_base->update();
  2818. } break;
  2819. case LOCK_SELECTED: {
  2820. List<Node *> &selection = editor_selection->get_selected_node_list();
  2821. for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
  2822. CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->get());
  2823. if (!canvas_item || !canvas_item->is_visible_in_tree())
  2824. continue;
  2825. if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root())
  2826. continue;
  2827. canvas_item->set_meta("_edit_lock_", true);
  2828. emit_signal("item_lock_status_changed");
  2829. }
  2830. viewport->update();
  2831. } break;
  2832. case UNLOCK_SELECTED: {
  2833. List<Node *> &selection = editor_selection->get_selected_node_list();
  2834. for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
  2835. CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->get());
  2836. if (!canvas_item || !canvas_item->is_visible_in_tree())
  2837. continue;
  2838. if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root())
  2839. continue;
  2840. canvas_item->set_meta("_edit_lock_", Variant());
  2841. emit_signal("item_lock_status_changed");
  2842. }
  2843. viewport->update();
  2844. } break;
  2845. case GROUP_SELECTED: {
  2846. List<Node *> &selection = editor_selection->get_selected_node_list();
  2847. for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
  2848. CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->get());
  2849. if (!canvas_item || !canvas_item->is_visible_in_tree())
  2850. continue;
  2851. if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root())
  2852. continue;
  2853. canvas_item->set_meta("_edit_group_", true);
  2854. emit_signal("item_group_status_changed");
  2855. }
  2856. viewport->update();
  2857. } break;
  2858. case UNGROUP_SELECTED: {
  2859. List<Node *> &selection = editor_selection->get_selected_node_list();
  2860. for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
  2861. CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->get());
  2862. if (!canvas_item || !canvas_item->is_visible_in_tree())
  2863. continue;
  2864. if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root())
  2865. continue;
  2866. canvas_item->set_meta("_edit_group_", Variant());
  2867. emit_signal("item_group_status_changed");
  2868. }
  2869. viewport->update();
  2870. } break;
  2871. case ANCHORS_AND_MARGINS_PRESET_TOP_LEFT: {
  2872. _set_anchors_and_margins_preset(PRESET_TOP_LEFT);
  2873. } break;
  2874. case ANCHORS_AND_MARGINS_PRESET_TOP_RIGHT: {
  2875. _set_anchors_and_margins_preset(PRESET_TOP_RIGHT);
  2876. } break;
  2877. case ANCHORS_AND_MARGINS_PRESET_BOTTOM_LEFT: {
  2878. _set_anchors_and_margins_preset(PRESET_BOTTOM_LEFT);
  2879. } break;
  2880. case ANCHORS_AND_MARGINS_PRESET_BOTTOM_RIGHT: {
  2881. _set_anchors_and_margins_preset(PRESET_BOTTOM_RIGHT);
  2882. } break;
  2883. case ANCHORS_AND_MARGINS_PRESET_CENTER_LEFT: {
  2884. _set_anchors_and_margins_preset(PRESET_CENTER_LEFT);
  2885. } break;
  2886. case ANCHORS_AND_MARGINS_PRESET_CENTER_RIGHT: {
  2887. _set_anchors_and_margins_preset(PRESET_CENTER_RIGHT);
  2888. } break;
  2889. case ANCHORS_AND_MARGINS_PRESET_CENTER_TOP: {
  2890. _set_anchors_and_margins_preset(PRESET_CENTER_TOP);
  2891. } break;
  2892. case ANCHORS_AND_MARGINS_PRESET_CENTER_BOTTOM: {
  2893. _set_anchors_and_margins_preset(PRESET_CENTER_BOTTOM);
  2894. } break;
  2895. case ANCHORS_AND_MARGINS_PRESET_CENTER: {
  2896. _set_anchors_and_margins_preset(PRESET_CENTER);
  2897. } break;
  2898. case ANCHORS_AND_MARGINS_PRESET_TOP_WIDE: {
  2899. _set_anchors_and_margins_preset(PRESET_TOP_WIDE);
  2900. } break;
  2901. case ANCHORS_AND_MARGINS_PRESET_LEFT_WIDE: {
  2902. _set_anchors_and_margins_preset(PRESET_LEFT_WIDE);
  2903. } break;
  2904. case ANCHORS_AND_MARGINS_PRESET_RIGHT_WIDE: {
  2905. _set_anchors_and_margins_preset(PRESET_RIGHT_WIDE);
  2906. } break;
  2907. case ANCHORS_AND_MARGINS_PRESET_BOTTOM_WIDE: {
  2908. _set_anchors_and_margins_preset(PRESET_BOTTOM_WIDE);
  2909. } break;
  2910. case ANCHORS_AND_MARGINS_PRESET_VCENTER_WIDE: {
  2911. _set_anchors_and_margins_preset(PRESET_VCENTER_WIDE);
  2912. } break;
  2913. case ANCHORS_AND_MARGINS_PRESET_HCENTER_WIDE: {
  2914. _set_anchors_and_margins_preset(PRESET_HCENTER_WIDE);
  2915. } break;
  2916. case ANCHORS_AND_MARGINS_PRESET_WIDE: {
  2917. _set_anchors_and_margins_preset(Control::PRESET_WIDE);
  2918. } break;
  2919. case ANCHORS_PRESET_TOP_LEFT: {
  2920. _set_anchors_preset(PRESET_TOP_LEFT);
  2921. } break;
  2922. case ANCHORS_PRESET_TOP_RIGHT: {
  2923. _set_anchors_preset(PRESET_TOP_RIGHT);
  2924. } break;
  2925. case ANCHORS_PRESET_BOTTOM_LEFT: {
  2926. _set_anchors_preset(PRESET_BOTTOM_LEFT);
  2927. } break;
  2928. case ANCHORS_PRESET_BOTTOM_RIGHT: {
  2929. _set_anchors_preset(PRESET_BOTTOM_RIGHT);
  2930. } break;
  2931. case ANCHORS_PRESET_CENTER_LEFT: {
  2932. _set_anchors_preset(PRESET_CENTER_LEFT);
  2933. } break;
  2934. case ANCHORS_PRESET_CENTER_RIGHT: {
  2935. _set_anchors_preset(PRESET_CENTER_RIGHT);
  2936. } break;
  2937. case ANCHORS_PRESET_CENTER_TOP: {
  2938. _set_anchors_preset(PRESET_CENTER_TOP);
  2939. } break;
  2940. case ANCHORS_PRESET_CENTER_BOTTOM: {
  2941. _set_anchors_preset(PRESET_CENTER_BOTTOM);
  2942. } break;
  2943. case ANCHORS_PRESET_CENTER: {
  2944. _set_anchors_preset(PRESET_CENTER);
  2945. } break;
  2946. case ANCHORS_PRESET_TOP_WIDE: {
  2947. _set_anchors_preset(PRESET_TOP_WIDE);
  2948. } break;
  2949. case ANCHORS_PRESET_LEFT_WIDE: {
  2950. _set_anchors_preset(PRESET_LEFT_WIDE);
  2951. } break;
  2952. case ANCHORS_PRESET_RIGHT_WIDE: {
  2953. _set_anchors_preset(PRESET_RIGHT_WIDE);
  2954. } break;
  2955. case ANCHORS_PRESET_BOTTOM_WIDE: {
  2956. _set_anchors_preset(PRESET_BOTTOM_WIDE);
  2957. } break;
  2958. case ANCHORS_PRESET_VCENTER_WIDE: {
  2959. _set_anchors_preset(PRESET_VCENTER_WIDE);
  2960. } break;
  2961. case ANCHORS_PRESET_HCENTER_WIDE: {
  2962. _set_anchors_preset(PRESET_HCENTER_WIDE);
  2963. } break;
  2964. case ANCHORS_PRESET_WIDE: {
  2965. _set_anchors_preset(Control::PRESET_WIDE);
  2966. } break;
  2967. case ANIM_INSERT_KEY:
  2968. case ANIM_INSERT_KEY_EXISTING: {
  2969. bool existing = p_op == ANIM_INSERT_KEY_EXISTING;
  2970. Map<Node *, Object *> &selection = editor_selection->get_selection();
  2971. for (Map<Node *, Object *>::Element *E = selection.front(); E; E = E->next()) {
  2972. CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->key());
  2973. if (!canvas_item || !canvas_item->is_visible_in_tree())
  2974. continue;
  2975. if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root())
  2976. continue;
  2977. if (Object::cast_to<Node2D>(canvas_item)) {
  2978. Node2D *n2d = Object::cast_to<Node2D>(canvas_item);
  2979. if (key_pos)
  2980. AnimationPlayerEditor::singleton->get_key_editor()->insert_node_value_key(n2d, "position", n2d->get_position(), existing);
  2981. if (key_rot)
  2982. AnimationPlayerEditor::singleton->get_key_editor()->insert_node_value_key(n2d, "rotation_deg", Math::rad2deg(n2d->get_rotation()), existing);
  2983. if (key_scale)
  2984. AnimationPlayerEditor::singleton->get_key_editor()->insert_node_value_key(n2d, "scale", n2d->get_scale(), existing);
  2985. if (n2d->has_meta("_edit_bone_") && n2d->get_parent_item()) {
  2986. //look for an IK chain
  2987. List<Node2D *> ik_chain;
  2988. Node2D *n = Object::cast_to<Node2D>(n2d->get_parent_item());
  2989. bool has_chain = false;
  2990. while (n) {
  2991. ik_chain.push_back(n);
  2992. if (n->has_meta("_edit_ik_")) {
  2993. has_chain = true;
  2994. break;
  2995. }
  2996. if (!n->get_parent_item())
  2997. break;
  2998. n = Object::cast_to<Node2D>(n->get_parent_item());
  2999. }
  3000. if (has_chain && ik_chain.size()) {
  3001. for (List<Node2D *>::Element *F = ik_chain.front(); F; F = F->next()) {
  3002. if (key_pos)
  3003. AnimationPlayerEditor::singleton->get_key_editor()->insert_node_value_key(F->get(), "position", F->get()->get_position(), existing);
  3004. if (key_rot)
  3005. AnimationPlayerEditor::singleton->get_key_editor()->insert_node_value_key(F->get(), "rotation_deg", Math::rad2deg(F->get()->get_rotation()), existing);
  3006. if (key_scale)
  3007. AnimationPlayerEditor::singleton->get_key_editor()->insert_node_value_key(F->get(), "scale", F->get()->get_scale(), existing);
  3008. }
  3009. }
  3010. }
  3011. } else if (Object::cast_to<Control>(canvas_item)) {
  3012. Control *ctrl = Object::cast_to<Control>(canvas_item);
  3013. if (key_pos)
  3014. AnimationPlayerEditor::singleton->get_key_editor()->insert_node_value_key(ctrl, "rect_position", ctrl->get_position(), existing);
  3015. if (key_rot)
  3016. AnimationPlayerEditor::singleton->get_key_editor()->insert_node_value_key(ctrl, "rect_rotation", ctrl->get_rotation_deg(), existing);
  3017. if (key_scale)
  3018. AnimationPlayerEditor::singleton->get_key_editor()->insert_node_value_key(ctrl, "rect_size", ctrl->get_size(), existing);
  3019. }
  3020. }
  3021. } break;
  3022. case ANIM_INSERT_POS: {
  3023. key_pos = key_loc_button->is_pressed();
  3024. } break;
  3025. case ANIM_INSERT_ROT: {
  3026. key_rot = key_rot_button->is_pressed();
  3027. } break;
  3028. case ANIM_INSERT_SCALE: {
  3029. key_scale = key_scale_button->is_pressed();
  3030. } break;
  3031. /*
  3032. case ANIM_INSERT_POS_ROT
  3033. case ANIM_INSERT_POS_SCALE:
  3034. case ANIM_INSERT_ROT_SCALE:
  3035. case ANIM_INSERT_POS_ROT_SCALE: {
  3036. static const bool key_toggles[7][3]={
  3037. {true,false,false},
  3038. {false,true,false},
  3039. {false,false,true},
  3040. {true,true,false},
  3041. {true,false,true},
  3042. {false,true,true},
  3043. {true,true,true}
  3044. };
  3045. key_pos=key_toggles[p_op-ANIM_INSERT_POS][0];
  3046. key_rot=key_toggles[p_op-ANIM_INSERT_POS][1];
  3047. key_scale=key_toggles[p_op-ANIM_INSERT_POS][2];
  3048. for(int i=ANIM_INSERT_POS;i<=ANIM_INSERT_POS_ROT_SCALE;i++) {
  3049. int idx = animation_menu->get_popup()->get_item_index(i);
  3050. animation_menu->get_popup()->set_item_checked(idx,i==p_op);
  3051. }
  3052. } break;*/
  3053. case ANIM_COPY_POSE: {
  3054. pose_clipboard.clear();
  3055. Map<Node *, Object *> &selection = editor_selection->get_selection();
  3056. for (Map<Node *, Object *>::Element *E = selection.front(); E; E = E->next()) {
  3057. CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->key());
  3058. if (!canvas_item || !canvas_item->is_visible_in_tree())
  3059. continue;
  3060. if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root())
  3061. continue;
  3062. if (Object::cast_to<Node2D>(canvas_item)) {
  3063. Node2D *n2d = Object::cast_to<Node2D>(canvas_item);
  3064. PoseClipboard pc;
  3065. pc.pos = n2d->get_position();
  3066. pc.rot = n2d->get_rotation();
  3067. pc.scale = n2d->get_scale();
  3068. pc.id = n2d->get_instance_id();
  3069. pose_clipboard.push_back(pc);
  3070. }
  3071. }
  3072. } break;
  3073. case ANIM_PASTE_POSE: {
  3074. if (!pose_clipboard.size())
  3075. break;
  3076. undo_redo->create_action(TTR("Paste Pose"));
  3077. for (List<PoseClipboard>::Element *E = pose_clipboard.front(); E; E = E->next()) {
  3078. Node2D *n2d = Object::cast_to<Node2D>(ObjectDB::get_instance(E->get().id));
  3079. if (!n2d)
  3080. continue;
  3081. undo_redo->add_do_method(n2d, "set_position", E->get().pos);
  3082. undo_redo->add_do_method(n2d, "set_rotation", E->get().rot);
  3083. undo_redo->add_do_method(n2d, "set_scale", E->get().scale);
  3084. undo_redo->add_undo_method(n2d, "set_position", n2d->get_position());
  3085. undo_redo->add_undo_method(n2d, "set_rotation", n2d->get_rotation());
  3086. undo_redo->add_undo_method(n2d, "set_scale", n2d->get_scale());
  3087. }
  3088. undo_redo->commit_action();
  3089. } break;
  3090. case ANIM_CLEAR_POSE: {
  3091. Map<Node *, Object *> &selection = editor_selection->get_selection();
  3092. for (Map<Node *, Object *>::Element *E = selection.front(); E; E = E->next()) {
  3093. CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->key());
  3094. if (!canvas_item || !canvas_item->is_visible_in_tree())
  3095. continue;
  3096. if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root())
  3097. continue;
  3098. if (Object::cast_to<Node2D>(canvas_item)) {
  3099. Node2D *n2d = Object::cast_to<Node2D>(canvas_item);
  3100. if (key_pos)
  3101. n2d->set_position(Vector2());
  3102. if (key_rot)
  3103. n2d->set_rotation(0);
  3104. if (key_scale)
  3105. n2d->set_scale(Vector2(1, 1));
  3106. } else if (Object::cast_to<Control>(canvas_item)) {
  3107. Control *ctrl = Object::cast_to<Control>(canvas_item);
  3108. if (key_pos)
  3109. ctrl->set_position(Point2());
  3110. /*
  3111. if (key_scale)
  3112. AnimationPlayerEditor::singleton->get_key_editor()->insert_node_value_key(ctrl,"rect/size",ctrl->get_size());
  3113. */
  3114. }
  3115. }
  3116. } break;
  3117. case VIEW_CENTER_TO_SELECTION:
  3118. case VIEW_FRAME_TO_SELECTION: {
  3119. _focus_selection(p_op);
  3120. } break;
  3121. case SKELETON_MAKE_BONES: {
  3122. Map<Node *, Object *> &selection = editor_selection->get_selection();
  3123. for (Map<Node *, Object *>::Element *E = selection.front(); E; E = E->next()) {
  3124. Node2D *n2d = Object::cast_to<Node2D>(E->key());
  3125. if (!n2d)
  3126. continue;
  3127. if (!n2d->is_visible_in_tree())
  3128. continue;
  3129. if (!n2d->get_parent_item())
  3130. continue;
  3131. n2d->set_meta("_edit_bone_", true);
  3132. if (!skeleton_show_bones)
  3133. skeleton_menu->get_popup()->activate_item(skeleton_menu->get_popup()->get_item_index(SKELETON_SHOW_BONES));
  3134. }
  3135. viewport->update();
  3136. } break;
  3137. case SKELETON_CLEAR_BONES: {
  3138. Map<Node *, Object *> &selection = editor_selection->get_selection();
  3139. for (Map<Node *, Object *>::Element *E = selection.front(); E; E = E->next()) {
  3140. Node2D *n2d = Object::cast_to<Node2D>(E->key());
  3141. if (!n2d)
  3142. continue;
  3143. if (!n2d->is_visible_in_tree())
  3144. continue;
  3145. n2d->set_meta("_edit_bone_", Variant());
  3146. if (!skeleton_show_bones)
  3147. skeleton_menu->get_popup()->activate_item(skeleton_menu->get_popup()->get_item_index(SKELETON_SHOW_BONES));
  3148. }
  3149. viewport->update();
  3150. } break;
  3151. case SKELETON_SET_IK_CHAIN: {
  3152. List<Node *> &selection = editor_selection->get_selected_node_list();
  3153. for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
  3154. CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->get());
  3155. if (!canvas_item || !canvas_item->is_visible_in_tree())
  3156. continue;
  3157. if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root())
  3158. continue;
  3159. canvas_item->set_meta("_edit_ik_", true);
  3160. if (!skeleton_show_bones)
  3161. skeleton_menu->get_popup()->activate_item(skeleton_menu->get_popup()->get_item_index(SKELETON_SHOW_BONES));
  3162. }
  3163. viewport->update();
  3164. } break;
  3165. case SKELETON_CLEAR_IK_CHAIN: {
  3166. Map<Node *, Object *> &selection = editor_selection->get_selection();
  3167. for (Map<Node *, Object *>::Element *E = selection.front(); E; E = E->next()) {
  3168. CanvasItem *n2d = Object::cast_to<CanvasItem>(E->key());
  3169. if (!n2d)
  3170. continue;
  3171. if (!n2d->is_visible_in_tree())
  3172. continue;
  3173. n2d->set_meta("_edit_ik_", Variant());
  3174. if (!skeleton_show_bones)
  3175. skeleton_menu->get_popup()->activate_item(skeleton_menu->get_popup()->get_item_index(SKELETON_SHOW_BONES));
  3176. }
  3177. viewport->update();
  3178. } break;
  3179. }
  3180. }
  3181. void CanvasItemEditor::_focus_selection(int p_op) {
  3182. Vector2 center(0.f, 0.f);
  3183. Rect2 rect;
  3184. int count = 0;
  3185. Map<Node *, Object *> &selection = editor_selection->get_selection();
  3186. for (Map<Node *, Object *>::Element *E = selection.front(); E; E = E->next()) {
  3187. CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->key());
  3188. if (!canvas_item) continue;
  3189. if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root())
  3190. continue;
  3191. // counting invisible items, for now
  3192. //if (!canvas_item->is_visible_in_tree()) continue;
  3193. ++count;
  3194. Rect2 item_rect = canvas_item->get_item_rect();
  3195. Vector2 pos = canvas_item->get_global_transform().get_origin();
  3196. Vector2 scale = canvas_item->get_global_transform().get_scale();
  3197. real_t angle = canvas_item->get_global_transform().get_rotation();
  3198. Transform2D t(angle, Vector2(0.f, 0.f));
  3199. item_rect = t.xform(item_rect);
  3200. Rect2 canvas_item_rect(pos + scale * item_rect.position, scale * item_rect.size);
  3201. if (count == 1) {
  3202. rect = canvas_item_rect;
  3203. } else {
  3204. rect = rect.merge(canvas_item_rect);
  3205. }
  3206. };
  3207. if (count == 0) return;
  3208. if (p_op == VIEW_CENTER_TO_SELECTION) {
  3209. center = rect.position + rect.size / 2;
  3210. Vector2 offset = viewport->get_size() / 2 - editor->get_scene_root()->get_global_canvas_transform().xform(center);
  3211. h_scroll->set_value(h_scroll->get_value() - offset.x / zoom);
  3212. v_scroll->set_value(v_scroll->get_value() - offset.y / zoom);
  3213. } else { // VIEW_FRAME_TO_SELECTION
  3214. if (rect.size.x > CMP_EPSILON && rect.size.y > CMP_EPSILON) {
  3215. float scale_x = viewport->get_size().x / rect.size.x;
  3216. float scale_y = viewport->get_size().y / rect.size.y;
  3217. zoom = scale_x < scale_y ? scale_x : scale_y;
  3218. zoom *= 0.90;
  3219. _update_scroll(0);
  3220. call_deferred("_popup_callback", VIEW_CENTER_TO_SELECTION);
  3221. }
  3222. }
  3223. }
  3224. void CanvasItemEditor::_bind_methods() {
  3225. ClassDB::bind_method("_zoom_minus", &CanvasItemEditor::_zoom_minus);
  3226. ClassDB::bind_method("_zoom_reset", &CanvasItemEditor::_zoom_reset);
  3227. ClassDB::bind_method("_zoom_plus", &CanvasItemEditor::_zoom_plus);
  3228. ClassDB::bind_method("_toggle_snap", &CanvasItemEditor::_toggle_snap);
  3229. ClassDB::bind_method("_update_scroll", &CanvasItemEditor::_update_scroll);
  3230. ClassDB::bind_method("_popup_callback", &CanvasItemEditor::_popup_callback);
  3231. ClassDB::bind_method("_get_editor_data", &CanvasItemEditor::_get_editor_data);
  3232. ClassDB::bind_method("_tool_select", &CanvasItemEditor::_tool_select);
  3233. ClassDB::bind_method("_keying_changed", &CanvasItemEditor::_keying_changed);
  3234. ClassDB::bind_method("_unhandled_key_input", &CanvasItemEditor::_unhandled_key_input);
  3235. ClassDB::bind_method("_draw_viewport", &CanvasItemEditor::_draw_viewport);
  3236. ClassDB::bind_method("_draw_viewport_base", &CanvasItemEditor::_draw_viewport_base);
  3237. ClassDB::bind_method("_gui_input_viewport", &CanvasItemEditor::_gui_input_viewport);
  3238. ClassDB::bind_method("_gui_input_viewport_base", &CanvasItemEditor::_gui_input_viewport_base);
  3239. ClassDB::bind_method("_snap_changed", &CanvasItemEditor::_snap_changed);
  3240. ClassDB::bind_method(D_METHOD("_selection_result_pressed"), &CanvasItemEditor::_selection_result_pressed);
  3241. ClassDB::bind_method(D_METHOD("_selection_menu_hide"), &CanvasItemEditor::_selection_menu_hide);
  3242. ADD_SIGNAL(MethodInfo("item_lock_status_changed"));
  3243. ADD_SIGNAL(MethodInfo("item_group_status_changed"));
  3244. }
  3245. void CanvasItemEditor::add_control_to_menu_panel(Control *p_control) {
  3246. hb->add_child(p_control);
  3247. }
  3248. HSplitContainer *CanvasItemEditor::get_palette_split() {
  3249. return palette_split;
  3250. }
  3251. VSplitContainer *CanvasItemEditor::get_bottom_split() {
  3252. return bottom_split;
  3253. }
  3254. void CanvasItemEditor::focus_selection() {
  3255. _focus_selection(VIEW_CENTER_TO_SELECTION);
  3256. }
  3257. CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
  3258. tool = TOOL_SELECT;
  3259. undo_redo = p_editor->get_undo_redo();
  3260. editor = p_editor;
  3261. editor_selection = p_editor->get_editor_selection();
  3262. editor_selection->add_editor_plugin(this);
  3263. editor_selection->connect("selection_changed", this, "update");
  3264. hb = memnew(HBoxContainer);
  3265. add_child(hb);
  3266. hb->set_anchors_and_margins_preset(Control::PRESET_WIDE);
  3267. bottom_split = memnew(VSplitContainer);
  3268. add_child(bottom_split);
  3269. bottom_split->set_v_size_flags(SIZE_EXPAND_FILL);
  3270. palette_split = memnew(HSplitContainer);
  3271. bottom_split->add_child(palette_split);
  3272. palette_split->set_v_size_flags(SIZE_EXPAND_FILL);
  3273. viewport_base = memnew(Control);
  3274. palette_split->add_child(viewport_base);
  3275. viewport_base->set_clip_contents(true);
  3276. viewport_base->connect("draw", this, "_draw_viewport_base");
  3277. viewport_base->connect("gui_input", this, "_gui_input_viewport_base");
  3278. viewport_base->set_focus_mode(FOCUS_ALL);
  3279. viewport_base->set_v_size_flags(SIZE_EXPAND_FILL);
  3280. viewport_base->set_h_size_flags(SIZE_EXPAND_FILL);
  3281. viewport_scrollable = memnew(Control);
  3282. viewport_base->add_child(viewport_scrollable);
  3283. viewport_scrollable->set_mouse_filter(MOUSE_FILTER_PASS);
  3284. viewport_scrollable->set_draw_behind_parent(true);
  3285. viewport_scrollable->set_anchors_and_margins_preset(Control::PRESET_WIDE);
  3286. viewport_scrollable->set_begin(Point2(RULER_WIDTH, RULER_WIDTH));
  3287. ViewportContainer *scene_tree = memnew(ViewportContainer);
  3288. viewport_scrollable->add_child(scene_tree);
  3289. scene_tree->set_stretch(true);
  3290. scene_tree->set_anchors_and_margins_preset(Control::PRESET_WIDE);
  3291. scene_tree->add_child(p_editor->get_scene_root());
  3292. viewport = memnew(CanvasItemEditorViewport(p_editor, this));
  3293. viewport_scrollable->add_child(viewport);
  3294. viewport->set_mouse_filter(MOUSE_FILTER_PASS);
  3295. viewport->set_anchors_and_margins_preset(Control::PRESET_WIDE);
  3296. viewport->set_clip_contents(true);
  3297. viewport->connect("draw", this, "_draw_viewport");
  3298. viewport->connect("gui_input", this, "_gui_input_viewport");
  3299. h_scroll = memnew(HScrollBar);
  3300. viewport->add_child(h_scroll);
  3301. h_scroll->connect("value_changed", this, "_update_scroll", Vector<Variant>(), Object::CONNECT_DEFERRED);
  3302. h_scroll->hide();
  3303. v_scroll = memnew(VScrollBar);
  3304. viewport->add_child(v_scroll);
  3305. v_scroll->connect("value_changed", this, "_update_scroll", Vector<Variant>(), Object::CONNECT_DEFERRED);
  3306. v_scroll->hide();
  3307. HBoxContainer *zoom_hb = memnew(HBoxContainer);
  3308. viewport->add_child(zoom_hb);
  3309. zoom_hb->set_begin(Point2(5, 5));
  3310. zoom_minus = memnew(ToolButton);
  3311. zoom_hb->add_child(zoom_minus);
  3312. zoom_minus->connect("pressed", this, "_zoom_minus");
  3313. zoom_minus->set_focus_mode(FOCUS_NONE);
  3314. zoom_reset = memnew(ToolButton);
  3315. zoom_hb->add_child(zoom_reset);
  3316. zoom_reset->connect("pressed", this, "_zoom_reset");
  3317. zoom_reset->set_focus_mode(FOCUS_NONE);
  3318. zoom_plus = memnew(ToolButton);
  3319. zoom_hb->add_child(zoom_plus);
  3320. zoom_plus->connect("pressed", this, "_zoom_plus");
  3321. zoom_plus->set_focus_mode(FOCUS_NONE);
  3322. updating_scroll = false;
  3323. handle_len = 10;
  3324. first_update = true;
  3325. select_button = memnew(ToolButton);
  3326. hb->add_child(select_button);
  3327. select_button->set_toggle_mode(true);
  3328. select_button->connect("pressed", this, "_tool_select", make_binds(TOOL_SELECT));
  3329. select_button->set_pressed(true);
  3330. select_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/select_mode", TTR("Select Mode"), KEY_Q));
  3331. select_button->set_tooltip(TTR("Select Mode") + " $sc\n" + keycode_get_string(KEY_MASK_CMD) + TTR("Drag: Rotate") + "\n" + TTR("Alt+Drag: Move") + "\n" + TTR("Press 'v' to Change Pivot, 'Shift+v' to Drag Pivot (while moving).") + "\n" + TTR("Alt+RMB: Depth list selection"));
  3332. move_button = memnew(ToolButton);
  3333. hb->add_child(move_button);
  3334. move_button->set_toggle_mode(true);
  3335. move_button->connect("pressed", this, "_tool_select", make_binds(TOOL_MOVE));
  3336. move_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/move_mode", TTR("Move Mode"), KEY_W));
  3337. move_button->set_tooltip(TTR("Move Mode"));
  3338. rotate_button = memnew(ToolButton);
  3339. hb->add_child(rotate_button);
  3340. rotate_button->set_toggle_mode(true);
  3341. rotate_button->connect("pressed", this, "_tool_select", make_binds(TOOL_ROTATE));
  3342. rotate_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/rotate_mode", TTR("Rotate Mode"), KEY_E));
  3343. rotate_button->set_tooltip(TTR("Rotate Mode"));
  3344. hb->add_child(memnew(VSeparator));
  3345. list_select_button = memnew(ToolButton);
  3346. hb->add_child(list_select_button);
  3347. list_select_button->set_toggle_mode(true);
  3348. list_select_button->connect("pressed", this, "_tool_select", make_binds(TOOL_LIST_SELECT));
  3349. list_select_button->set_tooltip(TTR("Show a list of all objects at the position clicked\n(same as Alt+RMB in select mode)."));
  3350. pivot_button = memnew(ToolButton);
  3351. hb->add_child(pivot_button);
  3352. pivot_button->set_toggle_mode(true);
  3353. pivot_button->connect("pressed", this, "_tool_select", make_binds(TOOL_EDIT_PIVOT));
  3354. pivot_button->set_tooltip(TTR("Click to change object's rotation pivot."));
  3355. pan_button = memnew(ToolButton);
  3356. hb->add_child(pan_button);
  3357. pan_button->set_toggle_mode(true);
  3358. pan_button->connect("pressed", this, "_tool_select", make_binds(TOOL_PAN));
  3359. pan_button->set_tooltip(TTR("Pan Mode"));
  3360. hb->add_child(memnew(VSeparator));
  3361. snap_button = memnew(ToolButton);
  3362. hb->add_child(snap_button);
  3363. snap_button->set_toggle_mode(true);
  3364. snap_button->connect("toggled", this, "_toggle_snap");
  3365. snap_button->set_tooltip(TTR("Toggles snapping"));
  3366. snap_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/use_snap", TTR("Use Snap"), KEY_S));
  3367. snap_config_menu = memnew(MenuButton);
  3368. hb->add_child(snap_config_menu);
  3369. snap_config_menu->set_h_size_flags(SIZE_SHRINK_END);
  3370. snap_config_menu->set_tooltip(TTR("Snapping options"));
  3371. PopupMenu *p = snap_config_menu->get_popup();
  3372. p->connect("id_pressed", this, "_popup_callback");
  3373. p->set_hide_on_checkable_item_selection(false);
  3374. p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_grid", TTR("Snap to grid")), SNAP_USE_GRID);
  3375. p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/use_rotation_snap", TTR("Use Rotation Snap")), SNAP_USE_ROTATION);
  3376. p->add_shortcut(ED_SHORTCUT("canvas_item_editor/configure_snap", TTR("Configure Snap...")), SNAP_CONFIGURE);
  3377. p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_relative", TTR("Snap Relative")), SNAP_RELATIVE);
  3378. p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/use_pixel_snap", TTR("Use Pixel Snap")), SNAP_USE_PIXEL);
  3379. p->add_submenu_item(TTR("Smart snapping"), "SmartSnapping");
  3380. smartsnap_config_popup = memnew(PopupMenu);
  3381. p->add_child(smartsnap_config_popup);
  3382. smartsnap_config_popup->set_name("SmartSnapping");
  3383. smartsnap_config_popup->connect("id_pressed", this, "_popup_callback");
  3384. smartsnap_config_popup->set_hide_on_checkable_item_selection(false);
  3385. smartsnap_config_popup->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_node_parent", TTR("Snap to parent")), SNAP_USE_NODE_PARENT);
  3386. smartsnap_config_popup->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_node_anchors", TTR("Snap to node anchor")), SNAP_USE_NODE_ANCHORS);
  3387. smartsnap_config_popup->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_node_sides", TTR("Snap to node sides")), SNAP_USE_NODE_SIDES);
  3388. smartsnap_config_popup->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_other_nodes", TTR("Snap to other nodes")), SNAP_USE_OTHER_NODES);
  3389. smartsnap_config_popup->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_guides", TTR("Snap to guides")), SNAP_USE_GUIDES);
  3390. hb->add_child(memnew(VSeparator));
  3391. lock_button = memnew(ToolButton);
  3392. hb->add_child(lock_button);
  3393. lock_button->connect("pressed", this, "_popup_callback", varray(LOCK_SELECTED));
  3394. lock_button->set_tooltip(TTR("Lock the selected object in place (can't be moved)."));
  3395. unlock_button = memnew(ToolButton);
  3396. hb->add_child(unlock_button);
  3397. unlock_button->connect("pressed", this, "_popup_callback", varray(UNLOCK_SELECTED));
  3398. unlock_button->set_tooltip(TTR("Unlock the selected object (can be moved)."));
  3399. group_button = memnew(ToolButton);
  3400. hb->add_child(group_button);
  3401. group_button->connect("pressed", this, "_popup_callback", varray(GROUP_SELECTED));
  3402. group_button->set_tooltip(TTR("Makes sure the object's children are not selectable."));
  3403. ungroup_button = memnew(ToolButton);
  3404. hb->add_child(ungroup_button);
  3405. ungroup_button->connect("pressed", this, "_popup_callback", varray(UNGROUP_SELECTED));
  3406. ungroup_button->set_tooltip(TTR("Restores the object's children's ability to be selected."));
  3407. hb->add_child(memnew(VSeparator));
  3408. skeleton_menu = memnew(MenuButton);
  3409. hb->add_child(skeleton_menu);
  3410. p = skeleton_menu->get_popup();
  3411. p->set_hide_on_checkable_item_selection(false);
  3412. p->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_make_bones", TTR("Make Bones"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_B), SKELETON_MAKE_BONES);
  3413. p->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_clear_bones", TTR("Clear Bones")), SKELETON_CLEAR_BONES);
  3414. p->add_separator();
  3415. p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_show_bones", TTR("Show Bones")), SKELETON_SHOW_BONES);
  3416. p->add_separator();
  3417. p->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_set_ik_chain", TTR("Make IK Chain")), SKELETON_SET_IK_CHAIN);
  3418. p->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_clear_ik_chain", TTR("Clear IK Chain")), SKELETON_CLEAR_IK_CHAIN);
  3419. p->connect("id_pressed", this, "_popup_callback");
  3420. hb->add_child(memnew(VSeparator));
  3421. view_menu = memnew(MenuButton);
  3422. view_menu->set_text(TTR("View"));
  3423. hb->add_child(view_menu);
  3424. view_menu->get_popup()->connect("id_pressed", this, "_popup_callback");
  3425. p = view_menu->get_popup();
  3426. p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_grid", TTR("Show Grid"), KEY_G), SHOW_GRID);
  3427. p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_helpers", TTR("Show helpers"), KEY_H), SHOW_HELPERS);
  3428. p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_rulers", TTR("Show rulers"), KEY_R), SHOW_RULERS);
  3429. p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_guides", TTR("Show guides"), KEY_Y), SHOW_GUIDES);
  3430. p->add_separator();
  3431. p->add_shortcut(ED_SHORTCUT("canvas_item_editor/center_selection", TTR("Center Selection"), KEY_F), VIEW_CENTER_TO_SELECTION);
  3432. p->add_shortcut(ED_SHORTCUT("canvas_item_editor/frame_selection", TTR("Frame Selection"), KEY_MASK_SHIFT | KEY_F), VIEW_FRAME_TO_SELECTION);
  3433. presets_menu = memnew(MenuButton);
  3434. presets_menu->set_text(TTR("Layout"));
  3435. hb->add_child(presets_menu);
  3436. presets_menu->hide();
  3437. p = presets_menu->get_popup();
  3438. p->connect("id_pressed", this, "_popup_callback");
  3439. anchors_popup = memnew(PopupMenu);
  3440. p->add_child(anchors_popup);
  3441. anchors_popup->set_name("Anchors");
  3442. anchors_popup->connect("id_pressed", this, "_popup_callback");
  3443. animation_hb = memnew(HBoxContainer);
  3444. hb->add_child(animation_hb);
  3445. animation_hb->add_child(memnew(VSeparator));
  3446. animation_hb->hide();
  3447. key_loc_button = memnew(Button);
  3448. key_loc_button->set_toggle_mode(true);
  3449. key_loc_button->set_flat(true);
  3450. key_loc_button->set_pressed(true);
  3451. key_loc_button->set_focus_mode(FOCUS_NONE);
  3452. key_loc_button->connect("pressed", this, "_popup_callback", varray(ANIM_INSERT_POS));
  3453. animation_hb->add_child(key_loc_button);
  3454. key_rot_button = memnew(Button);
  3455. key_rot_button->set_toggle_mode(true);
  3456. key_rot_button->set_flat(true);
  3457. key_rot_button->set_pressed(true);
  3458. key_rot_button->set_focus_mode(FOCUS_NONE);
  3459. key_rot_button->connect("pressed", this, "_popup_callback", varray(ANIM_INSERT_ROT));
  3460. animation_hb->add_child(key_rot_button);
  3461. key_scale_button = memnew(Button);
  3462. key_scale_button->set_toggle_mode(true);
  3463. key_scale_button->set_flat(true);
  3464. key_scale_button->set_focus_mode(FOCUS_NONE);
  3465. key_scale_button->connect("pressed", this, "_popup_callback", varray(ANIM_INSERT_SCALE));
  3466. animation_hb->add_child(key_scale_button);
  3467. key_insert_button = memnew(Button);
  3468. key_insert_button->set_flat(true);
  3469. key_insert_button->set_focus_mode(FOCUS_NONE);
  3470. key_insert_button->connect("pressed", this, "_popup_callback", varray(ANIM_INSERT_KEY));
  3471. key_insert_button->set_tooltip(TTR("Insert Keys"));
  3472. key_insert_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/anim_insert_key", TTR("Insert Key"), KEY_INSERT));
  3473. animation_hb->add_child(key_insert_button);
  3474. animation_menu = memnew(MenuButton);
  3475. animation_menu->set_text(TTR("Animation"));
  3476. animation_hb->add_child(animation_menu);
  3477. animation_menu->get_popup()->connect("id_pressed", this, "_popup_callback");
  3478. p = animation_menu->get_popup();
  3479. p->add_shortcut(ED_GET_SHORTCUT("canvas_item_editor/anim_insert_key"), ANIM_INSERT_KEY);
  3480. p->add_shortcut(ED_SHORTCUT("canvas_item_editor/anim_insert_key_existing_tracks", TTR("Insert Key (Existing Tracks)"), KEY_MASK_CMD + KEY_INSERT), ANIM_INSERT_KEY_EXISTING);
  3481. p->add_separator();
  3482. p->add_shortcut(ED_SHORTCUT("canvas_item_editor/anim_copy_pose", TTR("Copy Pose")), ANIM_COPY_POSE);
  3483. p->add_shortcut(ED_SHORTCUT("canvas_item_editor/anim_paste_pose", TTR("Paste Pose")), ANIM_PASTE_POSE);
  3484. p->add_shortcut(ED_SHORTCUT("canvas_item_editor/anim_clear_pose", TTR("Clear Pose"), KEY_MASK_SHIFT | KEY_K), ANIM_CLEAR_POSE);
  3485. snap_dialog = memnew(SnapDialog);
  3486. snap_dialog->connect("confirmed", this, "_snap_changed");
  3487. add_child(snap_dialog);
  3488. select_sb = Ref<StyleBoxTexture>(memnew(StyleBoxTexture));
  3489. selection_menu = memnew(PopupMenu);
  3490. add_child(selection_menu);
  3491. selection_menu->set_custom_minimum_size(Vector2(100, 0));
  3492. selection_menu->connect("id_pressed", this, "_selection_result_pressed");
  3493. selection_menu->connect("popup_hide", this, "_selection_menu_hide");
  3494. drag_pivot_shortcut = ED_SHORTCUT("canvas_item_editor/drag_pivot", TTR("Drag pivot from mouse position"), KEY_MASK_SHIFT | KEY_V);
  3495. set_pivot_shortcut = ED_SHORTCUT("canvas_item_editor/set_pivot", TTR("Set pivot at mouse position"), KEY_V);
  3496. multiply_grid_step_shortcut = ED_SHORTCUT("canvas_item_editor/multiply_grid_step", TTR("Multiply grid step by 2"), KEY_KP_MULTIPLY);
  3497. divide_grid_step_shortcut = ED_SHORTCUT("canvas_item_editor/divide_grid_step", TTR("Divide grid step by 2"), KEY_KP_DIVIDE);
  3498. key_pos = true;
  3499. key_rot = true;
  3500. key_scale = false;
  3501. edited_guide_pos = Point2();
  3502. edited_guide_index = -1;
  3503. show_grid = false;
  3504. show_helpers = false;
  3505. show_rulers = false;
  3506. show_guides = true;
  3507. zoom = 1;
  3508. grid_offset = Point2();
  3509. grid_step = Point2(10, 10);
  3510. grid_step_multiplier = 0;
  3511. snap_rotation_offset = 0;
  3512. snap_rotation_step = 15 / (180 / Math_PI);
  3513. snap_active = false;
  3514. snap_node_parent = true;
  3515. snap_node_anchors = true;
  3516. snap_node_sides = true;
  3517. snap_other_nodes = true;
  3518. snap_grid = true;
  3519. snap_guides = true;
  3520. snap_rotation = false;
  3521. snap_pixel = false;
  3522. skeleton_show_bones = true;
  3523. skeleton_menu->get_popup()->set_item_checked(skeleton_menu->get_popup()->get_item_index(SKELETON_SHOW_BONES), true);
  3524. box_selecting = false;
  3525. //zoom=0.5;
  3526. singleton = this;
  3527. set_process_unhandled_key_input(true);
  3528. can_move_pivot = false;
  3529. drag = DRAG_NONE;
  3530. bone_last_frame = 0;
  3531. additive_selection = false;
  3532. }
  3533. CanvasItemEditor *CanvasItemEditor::singleton = NULL;
  3534. void CanvasItemEditorPlugin::edit(Object *p_object) {
  3535. canvas_item_editor->set_undo_redo(&get_undo_redo());
  3536. canvas_item_editor->edit(Object::cast_to<CanvasItem>(p_object));
  3537. }
  3538. bool CanvasItemEditorPlugin::handles(Object *p_object) const {
  3539. return p_object->is_class("CanvasItem");
  3540. }
  3541. void CanvasItemEditorPlugin::make_visible(bool p_visible) {
  3542. if (p_visible) {
  3543. canvas_item_editor->show();
  3544. canvas_item_editor->set_physics_process(true);
  3545. VisualServer::get_singleton()->viewport_set_hide_canvas(editor->get_scene_root()->get_viewport_rid(), false);
  3546. canvas_item_editor->viewport_base->grab_focus();
  3547. } else {
  3548. canvas_item_editor->hide();
  3549. canvas_item_editor->set_physics_process(false);
  3550. VisualServer::get_singleton()->viewport_set_hide_canvas(editor->get_scene_root()->get_viewport_rid(), true);
  3551. }
  3552. }
  3553. Dictionary CanvasItemEditorPlugin::get_state() const {
  3554. return canvas_item_editor->get_state();
  3555. }
  3556. void CanvasItemEditorPlugin::set_state(const Dictionary &p_state) {
  3557. canvas_item_editor->set_state(p_state);
  3558. }
  3559. CanvasItemEditorPlugin::CanvasItemEditorPlugin(EditorNode *p_node) {
  3560. editor = p_node;
  3561. canvas_item_editor = memnew(CanvasItemEditor(editor));
  3562. canvas_item_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL);
  3563. editor->get_viewport()->add_child(canvas_item_editor);
  3564. canvas_item_editor->set_anchors_and_margins_preset(Control::PRESET_WIDE);
  3565. canvas_item_editor->hide();
  3566. }
  3567. CanvasItemEditorPlugin::~CanvasItemEditorPlugin() {
  3568. }
  3569. void CanvasItemEditorViewport::_on_mouse_exit() {
  3570. if (!selector->is_visible()) {
  3571. _remove_preview();
  3572. }
  3573. }
  3574. void CanvasItemEditorViewport::_on_select_type(Object *selected) {
  3575. CheckBox *check = Object::cast_to<CheckBox>(selected);
  3576. String type = check->get_text();
  3577. selector_label->set_text(vformat(TTR("Add %s"), type));
  3578. label->set_text(vformat(TTR("Adding %s..."), type));
  3579. }
  3580. void CanvasItemEditorViewport::_on_change_type() {
  3581. if (!button_group->get_pressed_button())
  3582. return;
  3583. CheckBox *check = Object::cast_to<CheckBox>(button_group->get_pressed_button());
  3584. default_type = check->get_text();
  3585. _perform_drop_data();
  3586. selector->hide();
  3587. }
  3588. void CanvasItemEditorViewport::_create_preview(const Vector<String> &files) const {
  3589. label->set_position(get_global_position() + Point2(14, 14) * EDSCALE);
  3590. label_desc->set_position(label->get_position() + Point2(0, label->get_size().height));
  3591. for (int i = 0; i < files.size(); i++) {
  3592. String path = files[i];
  3593. RES res = ResourceLoader::load(path);
  3594. Ref<Texture> texture = Ref<Texture>(Object::cast_to<Texture>(*res));
  3595. Ref<PackedScene> scene = Ref<PackedScene>(Object::cast_to<PackedScene>(*res));
  3596. if (texture != NULL || scene != NULL) {
  3597. if (texture != NULL) {
  3598. Sprite *sprite = memnew(Sprite);
  3599. sprite->set_texture(texture);
  3600. sprite->set_modulate(Color(1, 1, 1, 0.7f));
  3601. preview_node->add_child(sprite);
  3602. label->show();
  3603. label_desc->show();
  3604. } else {
  3605. if (scene.is_valid()) {
  3606. Node *instance = scene->instance();
  3607. if (instance) {
  3608. preview_node->add_child(instance);
  3609. }
  3610. }
  3611. }
  3612. editor->get_scene_root()->add_child(preview_node);
  3613. }
  3614. }
  3615. }
  3616. void CanvasItemEditorViewport::_remove_preview() {
  3617. if (preview_node->get_parent()) {
  3618. for (int i = preview_node->get_child_count() - 1; i >= 0; i--) {
  3619. Node *node = preview_node->get_child(i);
  3620. node->queue_delete();
  3621. preview_node->remove_child(node);
  3622. }
  3623. editor->get_scene_root()->remove_child(preview_node);
  3624. label->hide();
  3625. label_desc->hide();
  3626. }
  3627. }
  3628. bool CanvasItemEditorViewport::_cyclical_dependency_exists(const String &p_target_scene_path, Node *p_desired_node) {
  3629. if (p_desired_node->get_filename() == p_target_scene_path) {
  3630. return true;
  3631. }
  3632. int childCount = p_desired_node->get_child_count();
  3633. for (int i = 0; i < childCount; i++) {
  3634. Node *child = p_desired_node->get_child(i);
  3635. if (_cyclical_dependency_exists(p_target_scene_path, child)) {
  3636. return true;
  3637. }
  3638. }
  3639. return false;
  3640. }
  3641. void CanvasItemEditorViewport::_create_nodes(Node *parent, Node *child, String &path, const Point2 &p_point) {
  3642. child->set_name(path.get_file().get_basename());
  3643. Ref<Texture> texture = Ref<Texture>(Object::cast_to<Texture>(ResourceCache::get(path)));
  3644. Size2 texture_size = texture->get_size();
  3645. editor_data->get_undo_redo().add_do_method(parent, "add_child", child);
  3646. editor_data->get_undo_redo().add_do_method(child, "set_owner", editor->get_edited_scene());
  3647. editor_data->get_undo_redo().add_do_reference(child);
  3648. editor_data->get_undo_redo().add_undo_method(parent, "remove_child", child);
  3649. String new_name = parent->validate_child_name(child);
  3650. ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger();
  3651. editor_data->get_undo_redo().add_do_method(sed, "live_debug_create_node", editor->get_edited_scene()->get_path_to(parent), child->get_class(), new_name);
  3652. editor_data->get_undo_redo().add_undo_method(sed, "live_debug_remove_node", NodePath(String(editor->get_edited_scene()->get_path_to(parent)) + "/" + new_name));
  3653. // handle with different property for texture
  3654. String property = "texture";
  3655. List<PropertyInfo> props;
  3656. child->get_property_list(&props);
  3657. for (const List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
  3658. if (E->get().name == "config/texture") { // Particles2D
  3659. property = "config/texture";
  3660. break;
  3661. } else if (E->get().name == "texture/texture") { // Polygon2D
  3662. property = "texture/texture";
  3663. break;
  3664. } else if (E->get().name == "normal") { // TouchScreenButton
  3665. property = "normal";
  3666. break;
  3667. }
  3668. }
  3669. editor_data->get_undo_redo().add_do_property(child, property, texture);
  3670. // make visible for certain node type
  3671. if (default_type == "NinePatchRect") {
  3672. editor_data->get_undo_redo().add_do_property(child, "rect/size", texture_size);
  3673. } else if (default_type == "Polygon2D") {
  3674. PoolVector<Vector2> list;
  3675. list.push_back(Vector2(0, 0));
  3676. list.push_back(Vector2(texture_size.width, 0));
  3677. list.push_back(Vector2(texture_size.width, texture_size.height));
  3678. list.push_back(Vector2(0, texture_size.height));
  3679. editor_data->get_undo_redo().add_do_property(child, "polygon", list);
  3680. }
  3681. // locate at preview position
  3682. Point2 pos;
  3683. if (parent->has_method("get_global_position")) {
  3684. pos = parent->call("get_global_position");
  3685. }
  3686. Transform2D trans = canvas->get_canvas_transform();
  3687. Point2 target_position = (p_point - trans.get_origin()) / trans.get_scale().x - pos;
  3688. if (default_type == "Polygon2D" || default_type == "TouchScreenButton" || default_type == "TextureRect" || default_type == "NinePatchRect") {
  3689. target_position -= texture_size / 2;
  3690. }
  3691. // there's nothing to be used as source position so snapping will work as absolute if enabled
  3692. target_position = canvas->snap_point(target_position);
  3693. editor_data->get_undo_redo().add_do_method(child, "set_position", target_position);
  3694. }
  3695. bool CanvasItemEditorViewport::_create_instance(Node *parent, String &path, const Point2 &p_point) {
  3696. Ref<PackedScene> sdata = ResourceLoader::load(path);
  3697. if (!sdata.is_valid()) { // invalid scene
  3698. return false;
  3699. }
  3700. Node *instanced_scene = sdata->instance(PackedScene::GEN_EDIT_STATE_INSTANCE);
  3701. if (!instanced_scene) { // error on instancing
  3702. return false;
  3703. }
  3704. if (editor->get_edited_scene()->get_filename() != "") { // cyclical instancing
  3705. if (_cyclical_dependency_exists(editor->get_edited_scene()->get_filename(), instanced_scene)) {
  3706. memdelete(instanced_scene);
  3707. return false;
  3708. }
  3709. }
  3710. instanced_scene->set_filename(ProjectSettings::get_singleton()->localize_path(path));
  3711. editor_data->get_undo_redo().add_do_method(parent, "add_child", instanced_scene);
  3712. editor_data->get_undo_redo().add_do_method(instanced_scene, "set_owner", editor->get_edited_scene());
  3713. editor_data->get_undo_redo().add_do_reference(instanced_scene);
  3714. editor_data->get_undo_redo().add_undo_method(parent, "remove_child", instanced_scene);
  3715. String new_name = parent->validate_child_name(instanced_scene);
  3716. ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger();
  3717. editor_data->get_undo_redo().add_do_method(sed, "live_debug_instance_node", editor->get_edited_scene()->get_path_to(parent), path, new_name);
  3718. editor_data->get_undo_redo().add_undo_method(sed, "live_debug_remove_node", NodePath(String(editor->get_edited_scene()->get_path_to(parent)) + "/" + new_name));
  3719. CanvasItem *parent_ci = Object::cast_to<CanvasItem>(parent);
  3720. if (parent_ci) {
  3721. Vector2 target_pos = canvas->get_canvas_transform().affine_inverse().xform(p_point);
  3722. target_pos = canvas->snap_point(target_pos);
  3723. target_pos = parent_ci->get_global_transform_with_canvas().affine_inverse().xform(target_pos);
  3724. editor_data->get_undo_redo().add_do_method(instanced_scene, "set_position", target_pos);
  3725. }
  3726. return true;
  3727. }
  3728. void CanvasItemEditorViewport::_perform_drop_data() {
  3729. _remove_preview();
  3730. Vector<String> error_files;
  3731. editor_data->get_undo_redo().create_action(TTR("Create Node"));
  3732. for (int i = 0; i < selected_files.size(); i++) {
  3733. String path = selected_files[i];
  3734. RES res = ResourceLoader::load(path);
  3735. if (res.is_null()) {
  3736. continue;
  3737. }
  3738. Ref<Texture> texture = Ref<Texture>(Object::cast_to<Texture>(*res));
  3739. Ref<PackedScene> scene = Ref<PackedScene>(Object::cast_to<PackedScene>(*res));
  3740. if (texture != NULL) {
  3741. Node *child;
  3742. if (default_type == "Light2D")
  3743. child = memnew(Light2D);
  3744. else if (default_type == "Particles2D")
  3745. child = memnew(Particles2D);
  3746. else if (default_type == "Polygon2D")
  3747. child = memnew(Polygon2D);
  3748. else if (default_type == "TouchScreenButton")
  3749. child = memnew(TouchScreenButton);
  3750. else if (default_type == "TextureRect")
  3751. child = memnew(TextureRect);
  3752. else if (default_type == "NinePatchRect")
  3753. child = memnew(NinePatchRect);
  3754. else
  3755. child = memnew(Sprite); // default
  3756. _create_nodes(target_node, child, path, drop_pos);
  3757. } else if (scene != NULL) {
  3758. bool success = _create_instance(target_node, path, drop_pos);
  3759. if (!success) {
  3760. error_files.push_back(path);
  3761. }
  3762. }
  3763. }
  3764. editor_data->get_undo_redo().commit_action();
  3765. if (error_files.size() > 0) {
  3766. String files_str;
  3767. for (int i = 0; i < error_files.size(); i++) {
  3768. files_str += error_files[i].get_file().get_basename() + ",";
  3769. }
  3770. files_str = files_str.substr(0, files_str.length() - 1);
  3771. accept->get_ok()->set_text(TTR("Ugh"));
  3772. accept->set_text(vformat(TTR("Error instancing scene from %s"), files_str.c_str()));
  3773. accept->popup_centered_minsize();
  3774. }
  3775. }
  3776. bool CanvasItemEditorViewport::can_drop_data(const Point2 &p_point, const Variant &p_data) const {
  3777. Dictionary d = p_data;
  3778. if (d.has("type")) {
  3779. if (String(d["type"]) == "files") {
  3780. Vector<String> files = d["files"];
  3781. bool can_instance = false;
  3782. for (int i = 0; i < files.size(); i++) { // check if dragged files contain resource or scene can be created at least one
  3783. RES res = ResourceLoader::load(files[i]);
  3784. if (res.is_null()) {
  3785. continue;
  3786. }
  3787. String type = res->get_class();
  3788. if (type == "PackedScene") {
  3789. Ref<PackedScene> sdata = ResourceLoader::load(files[i]);
  3790. Node *instanced_scene = sdata->instance(PackedScene::GEN_EDIT_STATE_INSTANCE);
  3791. if (!instanced_scene) {
  3792. continue;
  3793. }
  3794. memdelete(instanced_scene);
  3795. } else if (type == "Texture" ||
  3796. type == "ImageTexture" ||
  3797. type == "ViewportTexture" ||
  3798. type == "CurveTexture" ||
  3799. type == "GradientTexture" ||
  3800. type == "StreamTexture" ||
  3801. type == "AtlasTexture" ||
  3802. type == "LargeTexture") {
  3803. Ref<Texture> texture = ResourceLoader::load(files[i]);
  3804. if (texture.is_valid() == false) {
  3805. continue;
  3806. }
  3807. } else {
  3808. continue;
  3809. }
  3810. can_instance = true;
  3811. break;
  3812. }
  3813. if (can_instance) {
  3814. if (!preview_node->get_parent()) { // create preview only once
  3815. _create_preview(files);
  3816. }
  3817. Transform2D trans = canvas->get_canvas_transform();
  3818. preview_node->set_position((p_point - trans.get_origin()) / trans.get_scale().x);
  3819. label->set_text(vformat(TTR("Adding %s..."), default_type));
  3820. }
  3821. return can_instance;
  3822. }
  3823. }
  3824. label->hide();
  3825. return false;
  3826. }
  3827. void CanvasItemEditorViewport::drop_data(const Point2 &p_point, const Variant &p_data) {
  3828. bool is_shift = Input::get_singleton()->is_key_pressed(KEY_SHIFT);
  3829. bool is_alt = Input::get_singleton()->is_key_pressed(KEY_ALT);
  3830. selected_files.clear();
  3831. Dictionary d = p_data;
  3832. if (d.has("type") && String(d["type"]) == "files") {
  3833. selected_files = d["files"];
  3834. }
  3835. List<Node *> list = editor->get_editor_selection()->get_selected_node_list();
  3836. if (list.size() == 0) {
  3837. Node *root_node = editor->get_edited_scene();
  3838. if (root_node) {
  3839. list.push_back(root_node);
  3840. } else {
  3841. accept->get_ok()->set_text(TTR("OK :("));
  3842. accept->set_text(TTR("No parent to instance a child at."));
  3843. accept->popup_centered_minsize();
  3844. _remove_preview();
  3845. return;
  3846. }
  3847. }
  3848. if (list.size() != 1) {
  3849. accept->get_ok()->set_text(TTR("I see.."));
  3850. accept->set_text(TTR("This operation requires a single selected node."));
  3851. accept->popup_centered_minsize();
  3852. _remove_preview();
  3853. return;
  3854. }
  3855. target_node = list[0];
  3856. if (is_shift && target_node != editor->get_edited_scene()) {
  3857. target_node = target_node->get_parent();
  3858. }
  3859. drop_pos = p_point;
  3860. if (is_alt) {
  3861. List<BaseButton *> btn_list;
  3862. button_group->get_buttons(&btn_list);
  3863. for (int i = 0; i < btn_list.size(); i++) {
  3864. CheckBox *check = Object::cast_to<CheckBox>(btn_list[i]);
  3865. check->set_pressed(check->get_text() == default_type);
  3866. }
  3867. selector_label->set_text(vformat(TTR("Add %s"), default_type));
  3868. selector->popup_centered_minsize();
  3869. } else {
  3870. _perform_drop_data();
  3871. }
  3872. }
  3873. void CanvasItemEditorViewport::_notification(int p_what) {
  3874. switch (p_what) {
  3875. case NOTIFICATION_ENTER_TREE: {
  3876. connect("mouse_exited", this, "_on_mouse_exit");
  3877. label->add_color_override("font_color", get_color("warning_color", "Editor"));
  3878. } break;
  3879. case NOTIFICATION_EXIT_TREE: {
  3880. disconnect("mouse_exited", this, "_on_mouse_exit");
  3881. } break;
  3882. default: break;
  3883. }
  3884. }
  3885. void CanvasItemEditorViewport::_bind_methods() {
  3886. ClassDB::bind_method(D_METHOD("_on_select_type"), &CanvasItemEditorViewport::_on_select_type);
  3887. ClassDB::bind_method(D_METHOD("_on_change_type"), &CanvasItemEditorViewport::_on_change_type);
  3888. ClassDB::bind_method(D_METHOD("_on_mouse_exit"), &CanvasItemEditorViewport::_on_mouse_exit);
  3889. }
  3890. CanvasItemEditorViewport::CanvasItemEditorViewport(EditorNode *p_node, CanvasItemEditor *p_canvas) {
  3891. default_type = "Sprite";
  3892. // Node2D
  3893. types.push_back("Sprite");
  3894. types.push_back("Light2D");
  3895. types.push_back("Particles2D");
  3896. types.push_back("Polygon2D");
  3897. types.push_back("TouchScreenButton");
  3898. // Control
  3899. types.push_back("TextureRect");
  3900. types.push_back("NinePatchRect");
  3901. target_node = NULL;
  3902. editor = p_node;
  3903. editor_data = editor->get_scene_tree_dock()->get_editor_data();
  3904. canvas = p_canvas;
  3905. preview_node = memnew(Node2D);
  3906. accept = memnew(AcceptDialog);
  3907. editor->get_gui_base()->add_child(accept);
  3908. selector = memnew(AcceptDialog);
  3909. editor->get_gui_base()->add_child(selector);
  3910. selector->set_title(TTR("Change default type"));
  3911. selector->connect("confirmed", this, "_on_change_type");
  3912. VBoxContainer *vbc = memnew(VBoxContainer);
  3913. selector->add_child(vbc);
  3914. vbc->set_h_size_flags(SIZE_EXPAND_FILL);
  3915. vbc->set_v_size_flags(SIZE_EXPAND_FILL);
  3916. vbc->set_custom_minimum_size(Size2(200, 260) * EDSCALE);
  3917. selector_label = memnew(Label);
  3918. vbc->add_child(selector_label);
  3919. selector_label->set_align(Label::ALIGN_CENTER);
  3920. selector_label->set_valign(Label::VALIGN_BOTTOM);
  3921. selector_label->set_custom_minimum_size(Size2(0, 30) * EDSCALE);
  3922. btn_group = memnew(VBoxContainer);
  3923. vbc->add_child(btn_group);
  3924. btn_group->set_h_size_flags(0);
  3925. button_group.instance();
  3926. for (int i = 0; i < types.size(); i++) {
  3927. CheckBox *check = memnew(CheckBox);
  3928. btn_group->add_child(check);
  3929. check->set_text(types[i]);
  3930. check->connect("button_down", this, "_on_select_type", varray(check));
  3931. check->set_button_group(button_group);
  3932. }
  3933. label = memnew(Label);
  3934. label->add_color_override("font_color_shadow", Color(0, 0, 0, 1));
  3935. label->add_constant_override("shadow_as_outline", 1 * EDSCALE);
  3936. label->hide();
  3937. editor->get_gui_base()->add_child(label);
  3938. label_desc = memnew(Label);
  3939. label_desc->set_text(TTR("Drag & drop + Shift : Add node as sibling\nDrag & drop + Alt : Change node type"));
  3940. label_desc->add_color_override("font_color", Color(0.6f, 0.6f, 0.6f, 1));
  3941. label_desc->add_color_override("font_color_shadow", Color(0.2f, 0.2f, 0.2f, 1));
  3942. label_desc->add_constant_override("shadow_as_outline", 1 * EDSCALE);
  3943. label_desc->add_constant_override("line_spacing", 0);
  3944. label_desc->hide();
  3945. editor->get_gui_base()->add_child(label_desc);
  3946. }
  3947. CanvasItemEditorViewport::~CanvasItemEditorViewport() {
  3948. memdelete(preview_node);
  3949. }