WMBuilder.Mod 108 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463
  1. MODULE WMBuilder; (** AUTHOR "staubesv"; PURPOSE "GUI builder"; *)
  2. IMPORT
  3. Modules, Kernel, KernelLog, Streams, Commands, Inputs, Strings, Files, XML, XMLObjects, XMLScanner, XMLParser,
  4. Math, Repositories, WMRepositories, WMUtilities,
  5. WMRectangles, WMGraphics, WMMessages, WMWindowManager, WMRestorable, WMProperties, WMComponents, WMStandardComponents, WMEditors,
  6. WMTrees, WMInspectionComponents, WMDialogs, Models;
  7. CONST
  8. WindowWidth = 128; WindowHeight = 320;
  9. EditWindowWidth = 640; EditWindowHeight = 480;
  10. Invalid = MIN(LONGINT);
  11. (* ComponentEditor.Mode *)
  12. UseMode = 0;
  13. EditMode = 1;
  14. (* ComponentEditor:IsInFrameHandle/IsInCurrentFrame result codes *)
  15. No = -1;
  16. Left = 0;
  17. TopLeft = 1;
  18. Top = 2;
  19. TopRight = 3;
  20. Right = 4;
  21. BottomRight = 5;
  22. Bottom = 6;
  23. BottomLeft = 7;
  24. Inside = 8;
  25. Paint = 999;
  26. (* ComponentEditor:pointerMode *)
  27. None = 0;
  28. SelectComponent = 1;
  29. ResizeMove = 2;
  30. Spawn = 3;
  31. PaintComponent = 5;
  32. (* ComponentEditor.state *)
  33. State_Running = 0;
  34. State_Terminating = 99;
  35. State_Terminated = 100;
  36. (* Frame types *)
  37. Frame_Selection = 0;
  38. Frame_Selection_InsertAt = 1;
  39. DistanceLimit = 4;
  40. DarkYellow = 505000FFH;
  41. (* Colors *)
  42. ColorLocked = DarkYellow;
  43. ColorSelected = WMGraphics.Red;
  44. TYPE
  45. KillerMsg = OBJECT
  46. END KillerMsg;
  47. TYPE
  48. HelperWindow = OBJECT(WMComponents.FormWindow)
  49. PROCEDURE &New(CONST windowTitle : ARRAY OF CHAR; component : WMComponents.VisualComponent; x, y, width, height : LONGINT; alpha : BOOLEAN);
  50. BEGIN
  51. Init(width, height, alpha);
  52. component.alignment.Set(WMComponents.AlignClient);
  53. SetContent(component);
  54. SetTitle(Strings.NewString(windowTitle));
  55. WMWindowManager.ExtAddWindow(SELF, x, y, {WMWindowManager.FlagFrame, WMWindowManager.FlagHidden});
  56. END New;
  57. END HelperWindow;
  58. TYPE
  59. ComponentWindow = OBJECT(WMComponents.FormWindow)
  60. VAR
  61. repositories : WMRepositories.RepositoriesView;
  62. repository : WMRepositories.RepositoryView;
  63. loadBtn, storeBtn, unloadBtn : WMStandardComponents.Button;
  64. filenameEditor : WMEditors.Editor;
  65. statusLabel : WMStandardComponents.Label;
  66. selection : WMRepositories.EntryWrapper;
  67. opNum : LONGINT;
  68. PROCEDURE &Init*(width, height : LONGINT; alpha : BOOLEAN);
  69. VAR slib : Repositories.Repository;
  70. BEGIN
  71. Init^(width, height, FALSE);
  72. SetContent(CreateForm());
  73. repository.UpdateGridSpacings;
  74. slib := Repositories.ThisRepository("Standard");
  75. IF (slib # NIL) THEN
  76. repositories.SelectByRepository(slib);
  77. END;
  78. SetTitle(Strings.NewString("Repositories"));
  79. SetIcon(WMGraphics.LoadImage("WMRepositories.Tar://WMRepositories.png", TRUE));
  80. selection := NIL;
  81. opNum := 1;
  82. END Init;
  83. PROCEDURE CreateForm() : WMComponents.VisualComponent;
  84. VAR panel, treePanel, toolbar : WMStandardComponents.Panel; resizer : WMStandardComponents.Resizer;
  85. BEGIN
  86. NEW(panel); panel.alignment.Set(WMComponents.AlignClient);
  87. panel.fillColor.Set(WMGraphics.White);
  88. NEW(statusLabel); statusLabel.alignment.Set(WMComponents.AlignBottom);
  89. statusLabel.bounds.SetHeight(20);
  90. statusLabel.fillColor.Set(0CCCCCCCCH);
  91. statusLabel.caption.SetAOC("0: OK");
  92. panel.AddContent(statusLabel);
  93. NEW(toolbar); toolbar.alignment.Set(WMComponents.AlignTop);
  94. toolbar.bounds.SetHeight(20);
  95. panel.AddContent(toolbar);
  96. NEW(loadBtn); loadBtn.alignment.Set(WMComponents.AlignLeft);
  97. loadBtn.caption.SetAOC("Load");
  98. loadBtn.onClick.Add(HandleButtons);
  99. toolbar.AddContent(loadBtn);
  100. NEW(filenameEditor); filenameEditor.alignment.Set(WMComponents.AlignClient);
  101. filenameEditor.multiLine.Set(FALSE);
  102. filenameEditor.tv.textAlignV.Set(WMGraphics.AlignCenter);
  103. filenameEditor.tv.showBorder.Set(TRUE);
  104. filenameEditor.onEnter.Add(OnEnter);
  105. toolbar.AddContent(filenameEditor);
  106. NEW(unloadBtn); unloadBtn.alignment.Set(WMComponents.AlignRight);
  107. unloadBtn.caption.SetAOC("Unload");
  108. unloadBtn.onClick.Add(HandleButtons);
  109. toolbar.AddContent(unloadBtn);
  110. NEW(storeBtn); storeBtn.alignment.Set(WMComponents.AlignRight);
  111. storeBtn.caption.SetAOC("Store");
  112. storeBtn.onClick.Add(HandleButtons);
  113. toolbar.AddContent(storeBtn);
  114. NEW(treePanel); treePanel.alignment.Set(WMComponents.AlignLeft);
  115. treePanel.bounds.SetWidth(100);
  116. panel.AddContent(treePanel);
  117. NEW(resizer); resizer.alignment.Set(WMComponents.AlignRight);
  118. resizer.bounds.SetWidth(5);
  119. treePanel.AddContent(resizer);
  120. NEW(repositories); repositories.alignment.Set(WMComponents.AlignClient);
  121. treePanel.AddContent(repositories);
  122. repositories.grid.onClick.Add(OnRepositoriesClicked);
  123. NEW(repository); repository.alignment.Set(WMComponents.AlignClient);
  124. panel.AddContent(repository);
  125. repository.showDetails.Set(FALSE);
  126. repository.grid.onClick.Add(OnComponentClicked);
  127. repository.grid.onClickSelected.Add(OnClickedSelected);
  128. RETURN panel;
  129. END CreateForm;
  130. PROCEDURE SetStatusLabel(CONST m1, m2, m3 : ARRAY OF CHAR);
  131. VAR caption : ARRAY 256 OF CHAR; nbr : ARRAY 8 OF CHAR;
  132. BEGIN
  133. caption := " ";
  134. Strings.IntToStr(opNum, nbr); INC(opNum);
  135. Strings.Append(caption, nbr);
  136. Strings.Append(caption, ": ");
  137. Strings.Append(caption, m1);
  138. Strings.Append(caption, m2);
  139. Strings.Append(caption, m3);
  140. statusLabel.caption.SetAOC(caption);
  141. END SetStatusLabel;
  142. PROCEDURE LoadRepository(CONST filename : ARRAY OF CHAR);
  143. VAR repository : Repositories.Repository; timer : Kernel.Timer;
  144. BEGIN
  145. repository := Repositories.ThisRepository(filename);
  146. IF (repository # NIL) THEN
  147. NEW(timer); timer.Sleep(200);
  148. repositories.SelectByRepository(repository);
  149. SetStatusLabel("Repository '", filename, "' loaded");
  150. ELSE
  151. SetStatusLabel("Repository '", filename, "' not found");
  152. END;
  153. END LoadRepository;
  154. PROCEDURE HandleButtons(sender, data : ANY);
  155. VAR filename : ARRAY 256 OF CHAR; res : WORD;
  156. BEGIN
  157. IF (sender = loadBtn) THEN
  158. filenameEditor.GetAsString(filename);
  159. LoadRepository(filename);
  160. ELSIF (sender = storeBtn) THEN
  161. filenameEditor.GetAsString(filename);
  162. Repositories.StoreRepository(filename, res);
  163. IF (res # Repositories.Ok) THEN
  164. SetStatusLabel("Could not store repository '", filename, "'");
  165. WMDialogs.Error("Error", "Could not store repository");
  166. ELSE
  167. SetStatusLabel("Repository '", filename, "' stored");
  168. END;
  169. ELSIF (sender = unloadBtn) THEN
  170. filenameEditor.GetAsString(filename);
  171. Repositories.UnloadRepository(filename, res);
  172. IF (res # Repositories.Ok) THEN
  173. SetStatusLabel("Could not unload repository '", filename, "'");
  174. WMDialogs.Error("Error", "Could not unload repository");
  175. ELSE
  176. SetStatusLabel("Repository '", filename, "' unloaded");
  177. END;
  178. END;
  179. END HandleButtons;
  180. PROCEDURE OnEnter(sender, data : ANY);
  181. VAR filename : ARRAY 256 OF CHAR;
  182. BEGIN
  183. filenameEditor.GetAsString(filename);
  184. LoadRepository(filename);
  185. END OnEnter;
  186. PROCEDURE GetSelectedComponent() : Repositories.Component;
  187. VAR component : Repositories.Component; string : Strings.String; id : LONGINT;
  188. BEGIN
  189. component := NIL;
  190. IF (selection # NIL) & (selection.repository # NIL) & (selection.element # NIL) THEN
  191. string := selection.element.GetAttributeValue("id");
  192. IF (string # NIL) THEN Strings.StrToInt(string^, id); ELSE id := 0; END;
  193. string := selection.element.GetAttributeValue("name");
  194. IF (string # NIL) THEN
  195. component := selection.repository.GetComponent(string^, id);
  196. END;
  197. END;
  198. RETURN component;
  199. END GetSelectedComponent;
  200. PROCEDURE OnRepositoriesClicked(sender, data : ANY);
  201. BEGIN
  202. IF (data # NIL) & (data IS Repositories.Repository) THEN
  203. repository.SetThisRepository(data(Repositories.Repository));
  204. filenameEditor.SetAsString(data(Repositories.Repository).name);
  205. END;
  206. END OnRepositoriesClicked;
  207. PROCEDURE OnComponentClicked(sender, data : ANY);
  208. BEGIN
  209. IF (data # NIL) & (data IS WMRepositories.EntryWrapper) & (data(WMRepositories.EntryWrapper).repository # NIL) THEN
  210. selection := data (WMRepositories.EntryWrapper);
  211. ELSE
  212. selection := NIL;
  213. END;
  214. END OnComponentClicked;
  215. PROCEDURE OnClickedSelected(sender, data : ANY);
  216. VAR command, msg : ARRAY 384 OF CHAR; res : WORD; string : Strings.String;
  217. BEGIN
  218. IF (data # NIL) & (data IS WMRepositories.EntryWrapper) THEN
  219. IF (data(WMRepositories.EntryWrapper).repository # NIL) & (data(WMRepositories.EntryWrapper).element # NIL) THEN
  220. string := data(WMRepositories.EntryWrapper).element.GetAttributeValue("source");
  221. IF (string # NIL) THEN
  222. command := "PET.Open ";
  223. Strings.Append(command, data(WMRepositories.EntryWrapper).repository.filename);
  224. Strings.Append(command, "://");
  225. Strings.Append(command, string^);
  226. Commands.Call(command, {}, res, msg);
  227. IF (res # Commands.Ok) THEN KernelLog.String(msg); END;
  228. END;
  229. END;
  230. END;
  231. END OnClickedSelected;
  232. END ComponentWindow;
  233. TYPE
  234. TreeNode = OBJECT(WMTrees.TreeNode)
  235. VAR
  236. color, bgColor : LONGINT;
  237. PROCEDURE &Init*;
  238. BEGIN
  239. Init^;
  240. color := 0FFH; bgColor := 0;
  241. END Init;
  242. END TreeNode;
  243. TYPE
  244. (** Tree component that displays all window instances and their component hierarchies *)
  245. ComponentTree = OBJECT(WMComponents.VisualComponent)
  246. VAR
  247. refreshBtn : WMStandardComponents.Button;
  248. treeView : WMTrees.TreeView;
  249. tree : WMTrees.Tree;
  250. (* the two fields below are protected by the tree lock *)
  251. rootComponent : Repositories.Component;
  252. selection : Selection;
  253. insertAtObj : ANY;
  254. PROCEDURE &Init*;
  255. BEGIN
  256. Init^;
  257. NEW(refreshBtn); refreshBtn.alignment.Set(WMComponents.AlignTop);
  258. refreshBtn.bounds.SetHeight(20);
  259. refreshBtn.caption.SetAOC("Refresh");
  260. refreshBtn.onClick.Add(Refresh);
  261. AddContent(refreshBtn);
  262. NEW(treeView); treeView.alignment.Set(WMComponents.AlignClient);
  263. treeView.SetDrawNodeProc(DrawNode);
  264. treeView.clSelected.Set(0);
  265. tree := treeView.GetTree();
  266. AddContent(treeView);
  267. rootComponent := NIL;
  268. selection := NIL; insertAtObj := NIL;
  269. END Init;
  270. PROCEDURE AddComponents(component : Repositories.Component; parent : WMTrees.TreeNode);
  271. VAR
  272. node : WMTrees.TreeNode;
  273. n : TreeNode;
  274. name : Strings.String;
  275. caption, value : ARRAY 256 OF CHAR;
  276. enum : XMLObjects.Enumerator;
  277. p : ANY;
  278. BEGIN
  279. IF ~((component IS WMComponents.Component) & (component(WMComponents.Component).internal)) THEN
  280. name := component.GetName();
  281. IF (name # NIL) THEN
  282. COPY(name^, caption);
  283. ELSE
  284. caption := "NoName";
  285. END;
  286. IF (component IS WMComponents.Component) THEN
  287. value := "";
  288. IF component(WMComponents.Component).properties.GetPropertyValue("caption", value) THEN
  289. Strings.Append(caption, " (");
  290. Strings.Append(caption, value);
  291. Strings.Append(caption, ")");
  292. END;
  293. END;
  294. NEW(n);
  295. tree.SetNodeCaption(n, Strings.NewString(caption));
  296. tree.SetNodeData(n, component);
  297. tree.AddChildNode(parent, n);
  298. tree.InclNodeState(n, WMTrees.NodeExpanded);
  299. tree.ExpandToRoot(n);
  300. node := n;
  301. ELSE
  302. node := parent;
  303. END;
  304. enum := component.GetContents();
  305. WHILE enum.HasMoreElements() DO
  306. p := enum.GetNext();
  307. IF (p IS Repositories.Component) THEN
  308. AddComponents(p(Repositories.Component), node);
  309. END;
  310. END;
  311. END AddComponents;
  312. PROCEDURE Refresh(sender, data : ANY);
  313. VAR root : WMTrees.TreeNode;
  314. BEGIN
  315. ASSERT(tree # NIL);
  316. tree.Acquire;
  317. NEW(root);
  318. tree.SetRoot(root);
  319. tree.SetNodeCaption(root, Strings.NewString("Root"));
  320. tree.InclNodeState(root, WMTrees.NodeExpanded);
  321. IF (rootComponent # NIL) THEN
  322. AddComponents(rootComponent, root);
  323. END;
  324. UpdateColors;
  325. tree.Release;
  326. END Refresh;
  327. PROCEDURE UpdateNodeColor(node : WMTrees.TreeNode);
  328. VAR ptr : ANY; n : TreeNode;
  329. BEGIN
  330. ASSERT(node # NIL);
  331. IF (node IS TreeNode) THEN
  332. n := node( TreeNode);
  333. ptr := tree.GetNodeData(node);
  334. IF (ptr # NIL) THEN
  335. IF (ptr IS Repositories.Component) & selection.Contains(ptr (Repositories.Component)) THEN
  336. n.color := ColorSelected;
  337. IF (ptr = insertAtObj) THEN n.bgColor := 0FF60H; ELSE n.bgColor := 0; END;
  338. ELSIF (ptr IS Repositories.Component) & ptr(Repositories.Component).IsLocked() THEN
  339. n.color := ColorLocked;
  340. ELSIF (ptr = insertAtObj) THEN
  341. n.color := WMGraphics.White; n.bgColor := 0FF60H;
  342. ELSE
  343. n.color := WMGraphics.Black; n.bgColor := 0;
  344. END;
  345. ELSE
  346. n.color := WMGraphics.Black; n.bgColor := 0;
  347. END;
  348. END;
  349. END UpdateNodeColor;
  350. PROCEDURE TraverseNodes(parent : WMTrees.TreeNode);
  351. VAR n : WMTrees.TreeNode;
  352. BEGIN
  353. ASSERT(parent # NIL);
  354. UpdateNodeColor(parent);
  355. n := tree.GetChildren(parent);
  356. WHILE (n # NIL) DO
  357. TraverseNodes(n);
  358. n := tree.GetNextSibling(n);
  359. END;
  360. END TraverseNodes;
  361. PROCEDURE UpdateColors;
  362. VAR root : WMTrees.TreeNode;
  363. BEGIN
  364. tree.Acquire;
  365. root := tree.GetRoot();
  366. TraverseNodes(root);
  367. tree.Release;
  368. Invalidate;
  369. END UpdateColors;
  370. PROCEDURE DrawNode(canvas: WMGraphics.Canvas; w, h: LONGINT; node: WMTrees.TreeNode; state: SET);
  371. VAR
  372. dx, tdx, tdy, bgColor : LONGINT; f : WMGraphics.Font; image : WMGraphics.Image;
  373. caption: Strings.String;
  374. BEGIN
  375. dx := 0;
  376. f := treeView.GetFont();
  377. image := tree.GetNodeImage(node);
  378. IF image # NIL THEN
  379. canvas.DrawImage(0, 0, image, WMGraphics.ModeSrcOverDst); dx := image.width + 5;
  380. END;
  381. IF (node IS TreeNode) THEN
  382. IF (node(TreeNode).color # 0) THEN
  383. canvas.SetColor(node(TreeNode).color);
  384. ELSE
  385. canvas.SetColor(treeView.clTextDefault.Get());
  386. END;
  387. bgColor := node(TreeNode).bgColor;
  388. ELSE
  389. canvas.SetColor(treeView.clTextDefault.Get());
  390. bgColor := 0;
  391. END;
  392. caption := tree.GetNodeCaption(node);
  393. f.GetStringSize(caption^, tdx, tdy);
  394. IF (bgColor # 0) THEN
  395. canvas.Fill(WMGraphics.MakeRectangle(0, 0, dx + tdx, h), bgColor, WMGraphics.ModeSrcOverDst)
  396. END;
  397. IF WMTrees.StateSelected IN state THEN
  398. canvas.Fill(WMGraphics.MakeRectangle(0, 0, dx + tdx, h), treeView.clSelected.Get(), WMGraphics.ModeSrcOverDst)
  399. ELSIF WMTrees.StateHover IN state THEN
  400. canvas.Fill(WMGraphics.MakeRectangle(0, 0, dx + tdx, h), treeView.clHover.Get(), WMGraphics.ModeSrcOverDst)
  401. END;
  402. IF caption # NIL THEN canvas.DrawString(dx, h - f.descent - 1 , caption^); END;
  403. END DrawNode;
  404. PROCEDURE SetComponent(rootComponent : Repositories.Component; selection : Selection);
  405. BEGIN
  406. tree.Acquire;
  407. SELF.rootComponent := rootComponent;
  408. SELF.selection := selection;
  409. tree.Release;
  410. Refresh(NIL, NIL);
  411. Invalidate;
  412. END SetComponent;
  413. PROCEDURE SetInsertAtObj(insertAtObj : ANY);
  414. BEGIN
  415. IF (SELF.insertAtObj # insertAtObj) THEN
  416. SELF.insertAtObj := insertAtObj;
  417. UpdateColors;
  418. END;
  419. END SetInsertAtObj;
  420. END ComponentTree;
  421. TYPE
  422. Indicator = OBJECT(WMStandardComponents.Panel)
  423. VAR
  424. value : ARRAY 128 OF CHAR;
  425. textColor : LONGINT;
  426. PROCEDURE &Init*;
  427. BEGIN
  428. Init^;
  429. value := "";
  430. textColor := 0;
  431. END Init;
  432. PROCEDURE SetCaption(CONST x : ARRAY OF CHAR);
  433. BEGIN
  434. Acquire; COPY(x, value); Release;
  435. Invalidate;
  436. END SetCaption;
  437. PROCEDURE DrawBackground*(canvas : WMGraphics.Canvas);
  438. BEGIN
  439. DrawBackground^(canvas);
  440. canvas.SetColor(textColor);
  441. Acquire;
  442. WMGraphics.DrawStringInRect(canvas, GetClientRect(), FALSE, WMComponents.AlignNone, WMGraphics.AlignCenter, value);
  443. Release;
  444. END DrawBackground;
  445. END Indicator;
  446. TYPE
  447. PropertyWindow = OBJECT(WMComponents.FormWindow)
  448. VAR
  449. propertyPanel : WMInspectionComponents.PropertyPanel;
  450. PROCEDURE &Init*(width, height : LONGINT; alpha : BOOLEAN);
  451. BEGIN
  452. Init^(width, height, alpha);
  453. NEW(propertyPanel); propertyPanel.alignment.Set(WMComponents.AlignClient);
  454. propertyPanel.fillColor.Set(WMGraphics.White);
  455. SetContent(propertyPanel);
  456. SetTitle(Strings.NewString("Component Properties"));
  457. END Init;
  458. PROCEDURE SetComponent(sender, component : ANY);
  459. BEGIN
  460. propertyPanel.SetComponent(SELF, component);
  461. END SetComponent;
  462. END PropertyWindow;
  463. TYPE
  464. ComponentArray = POINTER TO ARRAY OF Repositories.Component;
  465. BufferArray = POINTER TO ARRAY OF Strings.String;
  466. Clipboard = OBJECT
  467. VAR
  468. nofComponents : LONGINT;
  469. buffers : BufferArray;
  470. PROCEDURE &Init;
  471. VAR i : LONGINT;
  472. BEGIN
  473. nofComponents := 0;
  474. NEW(buffers, 32);
  475. FOR i := 0 TO LEN(buffers) - 1 DO buffers[i] := NIL; END;
  476. END Init;
  477. PROCEDURE Put(components : ComponentArray);
  478. VAR buf : Strings.Buffer; writer : Streams.Writer; i : LONGINT;
  479. BEGIN {EXCLUSIVE}
  480. ASSERT(components # NIL);
  481. Clear;
  482. i := 0;
  483. WHILE (i < LEN(components)) DO
  484. IF (components[i] # NIL) THEN
  485. INC(nofComponents);
  486. IF (i >= LEN(buffers)) THEN Resize; END;
  487. NEW(buf, 1024);
  488. writer := buf.GetWriter();
  489. components[i].Write(writer, NIL,0);
  490. writer.Update;
  491. buffers[i] := buf.GetString();
  492. END;
  493. INC(i);
  494. END;
  495. END Put;
  496. PROCEDURE Get() : ComponentArray;
  497. VAR components : ComponentArray; content : XML.Content; i : LONGINT;
  498. BEGIN {EXCLUSIVE}
  499. components := NIL;
  500. IF (nofComponents > 0) THEN
  501. NEW(components, nofComponents);
  502. i := 0;
  503. WHILE (i < LEN(buffers)) DO
  504. IF (buffers[i] # NIL) THEN
  505. content := LoadContent(buffers[i]);
  506. IF (content # NIL) & (content IS Repositories.Component) THEN
  507. components[i] := content (Repositories.Component);
  508. ELSE
  509. components[i] := NIL;
  510. END;
  511. END;
  512. INC(i);
  513. END;
  514. END;
  515. RETURN components;
  516. END Get;
  517. PROCEDURE LoadContent(buffer : Strings.String) : XML.Content;
  518. VAR content : XML.Content; parser : Parser; document : XML.Document; reader : Streams.StringReader;
  519. BEGIN
  520. content := NIL;
  521. IF (buffer # NIL) THEN
  522. NEW(reader, LEN(buffer)); reader.Set(buffer^);
  523. NEW(parser);
  524. IF parser.Parse(reader, document) THEN
  525. content := document.GetRoot();
  526. END;
  527. END;
  528. RETURN content;
  529. END LoadContent;
  530. PROCEDURE Clear;
  531. VAR i : LONGINT;
  532. BEGIN
  533. FOR i := 0 TO LEN(buffers) - 1 DO buffers[i] := NIL; END;
  534. END Clear;
  535. PROCEDURE Resize;
  536. VAR newBuffers : BufferArray; i : LONGINT;
  537. BEGIN
  538. NEW(newBuffers, 2 * LEN(buffers));
  539. FOR i := 0 TO LEN(buffers) - 1 DO newBuffers[i] := buffers[i]; END;
  540. WHILE (i < LEN(newBuffers)) DO newBuffers[i] := NIL; INC(i); END;
  541. buffers := newBuffers;
  542. END Resize;
  543. END Clipboard;
  544. TYPE
  545. Parser = OBJECT
  546. VAR
  547. hasError : BOOLEAN;
  548. PROCEDURE &Init;
  549. BEGIN
  550. hasError := FALSE;
  551. END Init;
  552. PROCEDURE ReportError(pos, line, col: LONGINT; CONST msg: ARRAY OF CHAR);
  553. BEGIN
  554. hasError := TRUE;
  555. KernelLog.String("WMBuilder.Clipboard.Parser.Parse: line = "); KernelLog.Int(line, 0);
  556. KernelLog.String(", col = "); KernelLog.Int(col, 0); KernelLog.String(", pos = "); KernelLog.Int(pos, 0);
  557. KernelLog.String(": "); KernelLog.String(msg); KernelLog.Ln;
  558. END ReportError;
  559. PROCEDURE Parse(reader : Streams.Reader; VAR document : XML.Document) : BOOLEAN;
  560. VAR scanner : XMLScanner.Scanner; parser : XMLParser.Parser;
  561. BEGIN
  562. ASSERT(reader # NIL);
  563. NEW(scanner, reader);
  564. NEW(parser, scanner);
  565. parser.reportError := ReportError;
  566. parser.elemReg := Repositories.registry;
  567. document := parser.Parse();
  568. RETURN ~hasError;
  569. END Parse;
  570. END Parser;
  571. TYPE
  572. ComponentInfo = RECORD
  573. originX, originY : LONGINT;
  574. END;
  575. SnapGrid = OBJECT
  576. VAR
  577. offsetX, offsetY : LONGINT;
  578. deltaX, deltaY : LONGINT;
  579. nX, nY : LONGINT;
  580. PROCEDURE &Init;
  581. BEGIN
  582. offsetX := 0; offsetY := 0;
  583. deltaX := 5; deltaY := 5;
  584. nX := 8; nY := 4;
  585. END Init;
  586. PROCEDURE Snap(x, y : LONGINT; VAR snapX, snapY : LONGINT);
  587. VAR r : REAL; f : LONGINT;
  588. BEGIN
  589. x := x - offsetX;
  590. y := y - offsetY;
  591. r := (x / deltaX);
  592. f := ENTIER(r);
  593. IF (r - f <= 0.5) THEN snapX := offsetX + f * deltaX;
  594. ELSIF (r - f > 0.5) THEN snapX := offsetX + (f + 1) * deltaX;
  595. END;
  596. r := (y / deltaY);
  597. f := ENTIER(r);
  598. IF (r - f <= 0.5) THEN snapY := offsetY + f * deltaY;
  599. ELSIF (r - f > 0.5) THEN snapY := offsetY + (f + 1) * deltaY;
  600. END;
  601. END Snap;
  602. END SnapGrid;
  603. Frame = OBJECT
  604. VAR
  605. bounds : WMRectangles.Rectangle;
  606. activeHandles : SET;
  607. clLine0, clLine1, clActiveHandles, clInactiveHandles : LONGINT;
  608. PROCEDURE &Init;
  609. BEGIN
  610. Clear;
  611. SetFrameType(Frame_Selection);
  612. END Init;
  613. PROCEDURE GetWidth() : LONGINT;
  614. BEGIN
  615. RETURN bounds.r - bounds.l;
  616. END GetWidth;
  617. PROCEDURE GetHeight() : LONGINT;
  618. BEGIN
  619. RETURN bounds.b - bounds.t
  620. END GetHeight;
  621. PROCEDURE IsValid() : BOOLEAN;
  622. BEGIN
  623. RETURN (bounds.l # 0) OR (bounds.t # 0) OR (bounds.r # 0) OR (bounds.b # 0);
  624. END IsValid;
  625. PROCEDURE SetFrameType(type : LONGINT);
  626. BEGIN
  627. CASE type OF
  628. |Frame_Selection:
  629. clLine0 := WMGraphics.Black;
  630. clLine1 := WMGraphics.Green;
  631. clActiveHandles := WMGraphics.Green;
  632. clInactiveHandles := WMGraphics.Black;
  633. |Frame_Selection_InsertAt:
  634. clLine0 := WMGraphics.Black;
  635. clLine1 := WMGraphics.Blue;
  636. clActiveHandles := WMGraphics.Blue;
  637. clInactiveHandles := WMGraphics.Black;
  638. ELSE
  639. END;
  640. END SetFrameType;
  641. PROCEDURE Clear;
  642. BEGIN
  643. bounds := WMRectangles.MakeRect(0, 0, 0, 0);
  644. activeHandles := {};
  645. END Clear;
  646. PROCEDURE SetActiveHandlesFor(alignment : LONGINT);
  647. BEGIN
  648. CASE alignment OF
  649. |WMComponents.AlignNone: activeHandles := {0..31};
  650. |WMComponents.AlignLeft: activeHandles := {Right};
  651. |WMComponents.AlignRight: activeHandles := {Left};
  652. |WMComponents.AlignTop: activeHandles := {Bottom};
  653. |WMComponents.AlignBottom: activeHandles := {Top};
  654. |WMComponents.AlignClient: activeHandles := {};
  655. ELSE
  656. activeHandles := {0..31};
  657. END;
  658. END SetActiveHandlesFor;
  659. PROCEDURE SetActiveHandles(activeHandles : SET);
  660. BEGIN
  661. SELF.activeHandles := activeHandles;
  662. END SetActiveHandles;
  663. PROCEDURE FixBounds;
  664. BEGIN
  665. bounds := WMRectangles.MakeRect(
  666. MIN(bounds.l, bounds.r),
  667. MIN(bounds.t, bounds.b),
  668. MAX(bounds.l, bounds.r),
  669. MAX(bounds.t, bounds.b)
  670. );
  671. END FixBounds;
  672. PROCEDURE IsInActiveFrameHandle(x, y : LONGINT) : WORD;
  673. VAR res : WORD;
  674. BEGIN
  675. res := IsInFrameHandle(x, y);
  676. IF (res # No) & ~(res IN activeHandles) THEN
  677. res := No;
  678. END;
  679. RETURN res;
  680. END IsInActiveFrameHandle;
  681. PROCEDURE IsInFrameHandle(x, y : LONGINT): LONGINT;
  682. VAR xs, ys, xe, ye, res : LONGINT;
  683. BEGIN
  684. IF IsValid() THEN
  685. xs := bounds.l; ys := bounds.t; xe := bounds.r; ye := bounds.b;
  686. IF WMRectangles.PointInRect(x, y, WMRectangles.MakeRect(xs-4, ENTIER((ys+ye)/2)-2, xs+1, ENTIER((ys+ye)/2)+2)) THEN
  687. res := Left;
  688. ELSIF WMRectangles.PointInRect(x, y, WMRectangles.MakeRect(xs-4, ys-4, xs+1, ys+1)) THEN
  689. res := TopLeft;
  690. ELSIF WMRectangles.PointInRect(x, y, WMRectangles.MakeRect(ENTIER((xs+xe)/2)-1, ys-4, ENTIER((xs+xe)/2)+3, ys+1)) THEN
  691. res := Top;
  692. ELSIF WMRectangles.PointInRect(x, y, WMRectangles.MakeRect(xe, ys-4, xe+5, ys+1)) THEN
  693. res := TopRight;
  694. ELSIF WMRectangles.PointInRect(x, y, WMRectangles.MakeRect(xe, ENTIER((ys+ye)/2)-2, xe+5, ENTIER((ys+ye)/2)+2)) THEN
  695. res := Right;
  696. ELSIF WMRectangles.PointInRect(x, y, WMRectangles.MakeRect(xe, ye, xe+5, ye+5)) THEN
  697. res := BottomRight;
  698. ELSIF WMRectangles.PointInRect(x, y, WMRectangles.MakeRect(ENTIER((xs+xe)/2)-1, ye, ENTIER((xs+xe)/2)+3, ye+5)) THEN
  699. res := Bottom;
  700. ELSIF WMRectangles.PointInRect(x, y, WMRectangles.MakeRect(xs-4, ye, xs+1, ye+5)) THEN
  701. res := BottomLeft;
  702. ELSIF WMRectangles.PointInRect(x, y, WMRectangles.MakeRect(xs+1, ys+1, xe-1, ye-1)) THEN
  703. res := Inside;
  704. ELSE
  705. res := No;
  706. END;
  707. ELSE
  708. res := No;
  709. END;
  710. RETURN res;
  711. END IsInFrameHandle;
  712. PROCEDURE DrawFrameHandles(canvas: WMGraphics.Canvas; xs, ys, xe, ye , activeColor, inactiveColor : LONGINT; active : SET);
  713. VAR color : LONGINT;
  714. BEGIN
  715. IF (TopLeft IN active) THEN color := activeColor; ELSE color := inactiveColor; END;
  716. canvas.Fill(WMRectangles.MakeRect(xs-4, ys-4, xs+1, ys+1), color, WMGraphics.ModeSrcOverDst);
  717. IF (TopRight IN active) THEN color := activeColor; ELSE color := inactiveColor; END;
  718. canvas.Fill(WMRectangles.MakeRect(xe, ys-4, xe+5, ys+1), color, WMGraphics.ModeSrcOverDst);
  719. IF (BottomLeft IN active) THEN color := activeColor; ELSE color := inactiveColor; END;
  720. canvas.Fill(WMRectangles.MakeRect(xs-4, ye, xs+1, ye+5), color, WMGraphics.ModeSrcOverDst);
  721. IF (BottomRight IN active) THEN color := activeColor; ELSE color := inactiveColor; END;
  722. canvas.Fill(WMRectangles.MakeRect(xe, ye, xe+5, ye+5), color, WMGraphics.ModeSrcOverDst);
  723. IF (Left IN active) THEN color := activeColor; ELSE color := inactiveColor; END;
  724. canvas.Fill(WMRectangles.MakeRect(xs-4, ENTIER((ys+ye)/2)-2, xs+1, ENTIER((ys+ye)/2)+2), color, WMGraphics.ModeSrcOverDst);
  725. IF (Top IN active) THEN color := activeColor; ELSE color := inactiveColor; END;
  726. canvas.Fill(WMRectangles.MakeRect(ENTIER((xs+xe)/2)-1, ys-4, ENTIER((xs+xe)/2)+3, ys+1), color, WMGraphics.ModeSrcOverDst);
  727. IF (Right IN active) THEN color := activeColor; ELSE color := inactiveColor; END;
  728. canvas.Fill(WMRectangles.MakeRect(xe, ENTIER((ys+ye)/2)-2, xe+5, ENTIER((ys+ye)/2)+2), color, WMGraphics.ModeSrcOverDst);
  729. IF (Bottom IN active) THEN color := activeColor; ELSE color := inactiveColor; END;
  730. canvas.Fill(WMRectangles.MakeRect(ENTIER((xs+xe)/2)-1, ye, ENTIER((xs+xe)/2)+3, ye+5), color, WMGraphics.ModeSrcOverDst);
  731. END DrawFrameHandles;
  732. PROCEDURE Draw(canvas : WMGraphics.Canvas);
  733. BEGIN
  734. IF IsValid() THEN
  735. DrawDashedRectangle(canvas, bounds.l, bounds.t, bounds.r, bounds.b, clLine0, clLine1, 4, 2);
  736. IF (activeHandles # {}) THEN
  737. DrawFrameHandles(canvas, bounds.l, bounds.t, bounds.r, bounds.b, clActiveHandles, clInactiveHandles, activeHandles);
  738. END;
  739. END;
  740. END Draw;
  741. END Frame;
  742. TYPE
  743. RectangleReal = RECORD
  744. l, t, b, r : REAL;
  745. END;
  746. BoundsArray = POINTER TO ARRAY OF RectangleReal;
  747. Selection = OBJECT (** not thread-safe!*)
  748. VAR
  749. frame : WMRectangles.Rectangle;
  750. activeFrameHandles : SET;
  751. root : WMComponents.VisualComponent;
  752. parent : XML.Element;
  753. nofComponents : LONGINT;
  754. components : ComponentArray;
  755. bounds : BoundsArray;
  756. PROCEDURE &Init(root : WMComponents.VisualComponent);
  757. BEGIN
  758. ASSERT(root # NIL);
  759. SELF.root := root;
  760. parent := NIL;
  761. activeFrameHandles := {};
  762. NEW(components, 32);
  763. Clear;
  764. bounds := NIL;
  765. END Init;
  766. PROCEDURE NofComponents() : LONGINT;
  767. BEGIN
  768. RETURN nofComponents;
  769. END NofComponents;
  770. PROCEDURE NofVisualComponents() : LONGINT;
  771. VAR nofVisualComponents, i : LONGINT;
  772. BEGIN
  773. nofVisualComponents := 0;
  774. FOR i := 0 TO nofComponents - 1 DO
  775. IF (components[i] IS WMComponents.VisualComponent) THEN
  776. INC(nofVisualComponents);
  777. END;
  778. END;
  779. RETURN nofVisualComponents;
  780. END NofVisualComponents;
  781. PROCEDURE NofLockedComponents() : LONGINT;
  782. VAR nofLockedComponents, i : LONGINT;
  783. BEGIN
  784. nofLockedComponents := 0;
  785. FOR i := 0 TO nofComponents - 1 DO
  786. IF components[i].IsLocked() THEN INC(nofLockedComponents); END;
  787. END;
  788. RETURN nofLockedComponents;
  789. END NofLockedComponents;
  790. PROCEDURE GetParent() : XML.Element;
  791. BEGIN
  792. RETURN parent;
  793. END GetParent;
  794. PROCEDURE Contains(component : Repositories.Component) : BOOLEAN;
  795. VAR i : LONGINT;
  796. BEGIN
  797. i := 0;
  798. WHILE (i < nofComponents) & (components[i] # component) DO INC(i); END;
  799. RETURN (i < nofComponents);
  800. END Contains;
  801. PROCEDURE GetFirst() : Repositories.Component;
  802. VAR component : Repositories.Component;
  803. BEGIN
  804. IF (nofComponents > 0) THEN
  805. component := components[0];
  806. ELSE
  807. component := NIL;
  808. END;
  809. RETURN component;
  810. END GetFirst;
  811. PROCEDURE ModificationsAllowed() : BOOLEAN;
  812. BEGIN
  813. RETURN NofLockedComponents() = 0;
  814. END ModificationsAllowed;
  815. PROCEDURE Delete;
  816. VAR parent : XML.Element; i : LONGINT;
  817. BEGIN
  818. FOR i := 0 TO nofComponents - 1 DO
  819. IF (components[i] # root) THEN
  820. parent := components[i].GetParent();
  821. parent.RemoveContent(components[i]);
  822. END;
  823. END;
  824. Reset;
  825. END Delete;
  826. PROCEDURE ToFront;
  827. VAR parent : XML.Element; i : LONGINT;
  828. BEGIN
  829. FOR i := 0 TO nofComponents - 1 DO
  830. IF (components[i] # root) THEN
  831. parent := components[i].GetParent();
  832. parent.RemoveContent(components[i]);
  833. parent.AddContent(components[i]);
  834. END;
  835. END;
  836. END ToFront;
  837. PROCEDURE SetExtents(width, height : LONGINT);
  838. VAR i : LONGINT;
  839. BEGIN
  840. FOR i := 0 TO nofComponents - 1 DO
  841. IF (components[i] IS WMComponents.VisualComponent) THEN
  842. components[i](WMComponents.VisualComponent).bounds.SetExtents(width, height);
  843. END;
  844. END;
  845. END SetExtents;
  846. PROCEDURE SetLimit(rect : WMRectangles.Rectangle; mode : LONGINT);
  847. VAR bounds : WMRectangles.Rectangle; dx, dy, i : LONGINT;
  848. BEGIN
  849. FOR i := 0 TO nofComponents - 1 DO
  850. IF (components[i] # NIL) & (components[i] IS WMComponents.VisualComponent) THEN
  851. dx := 0; dy := 0;
  852. bounds := components[i](WMComponents.VisualComponent).bounds.Get();
  853. CASE mode OF
  854. |No: (* ignore *)
  855. |Left: dx := rect.l - bounds.l
  856. |TopLeft: dx := rect.l - bounds.l; dy := rect.t - bounds.t;
  857. |Top: dy := rect.t - bounds.t;
  858. |TopRight: dy := rect.t - bounds.t; dx := rect.r - bounds.r;
  859. |Right: dx := rect.r - bounds.r;
  860. |BottomRight: dy := rect.b - bounds.b; dx := rect.r - bounds.r;
  861. |Bottom: dy := rect.b - bounds.b;
  862. |BottomLeft: dy := rect.b - bounds.b; dx := rect.l - bounds.l;
  863. |Inside:
  864. ELSE
  865. END;
  866. WMRectangles.MoveRel(bounds, dx, dy);
  867. components[i](WMComponents.VisualComponent).bounds.Set(bounds);
  868. END;
  869. END;
  870. END SetLimit;
  871. PROCEDURE MoveRelative(dx, dy : LONGINT);
  872. VAR bounds : WMRectangles.Rectangle; i : LONGINT;
  873. BEGIN
  874. FOR i := 0 TO nofComponents - 1 DO
  875. IF (components[i] # NIL) & (components[i] IS WMComponents.VisualComponent) THEN
  876. bounds := components[i](WMComponents.VisualComponent).bounds.Get();
  877. WMRectangles.MoveRel(bounds, dx, dy);
  878. components[i](WMComponents.VisualComponent).bounds.Set(bounds);
  879. END;
  880. END;
  881. END MoveRelative;
  882. PROCEDURE InitResize(x0, y0, width0, height0 : LONGINT);
  883. VAR i : LONGINT; r, temp : WMRectangles.Rectangle;
  884. BEGIN
  885. IF (bounds = NIL) OR (LEN(bounds) < nofComponents) THEN NEW(bounds, nofComponents); END;
  886. FOR i := 0 TO nofComponents - 1 DO
  887. IF (components[i] IS WMComponents.VisualComponent) THEN
  888. temp.l := x0; temp.t := y0;
  889. ToComponentCoordinates(components[i](WMComponents.VisualComponent), temp);
  890. r := components[i](WMComponents.VisualComponent).bounds.Get();
  891. bounds[i].l := (r.l - temp.l) / width0;
  892. bounds[i].t := (r.t - temp.t) / height0;
  893. bounds[i].r := (r.r - temp.l) / width0;
  894. bounds[i].b := (r.b - temp.t) / height0;
  895. END;
  896. END;
  897. END InitResize;
  898. PROCEDURE ResizeProportional(x, y, width, height : LONGINT; snapX, snapY : LONGINT);
  899. VAR r, temp : WMRectangles.Rectangle; i : LONGINT;
  900. PROCEDURE Snap(r : WMRectangles.Rectangle; snapX, snapY : LONGINT);
  901. BEGIN
  902. END Snap;
  903. BEGIN
  904. FOR i := 0 TO nofComponents - 1 DO
  905. IF (components[i] # NIL) & (components[i] IS WMComponents.VisualComponent) THEN
  906. temp.l := x; temp.t := y;
  907. ToComponentCoordinates(components[i](WMComponents.VisualComponent), temp);
  908. r.l := temp.l + ENTIER(bounds[i].l * width);
  909. r.t := temp.t + ENTIER(bounds[i].t * height);
  910. r.r := temp.l + ENTIER(bounds[i].r * width);
  911. r.b := temp.t + ENTIER(bounds[i].b * height);
  912. IF (snapX # Invalid) & (snapY # Invalid) THEN
  913. Snap(r, snapX, snapY);
  914. END;
  915. components[i](WMComponents.VisualComponent).bounds.Set(r);
  916. END;
  917. END;
  918. END ResizeProportional;
  919. PROCEDURE Resize(mode : LONGINT; dx, dy : LONGINT);
  920. VAR bounds : WMRectangles.Rectangle; i : LONGINT;
  921. BEGIN
  922. FOR i := 0 TO nofComponents - 1 DO
  923. IF (components[i] # NIL) & (components[i] IS WMComponents.VisualComponent) THEN
  924. bounds := components[i](WMComponents.VisualComponent).bounds.Get();
  925. IF (mode = TopLeft) OR (mode = Left) OR (mode = BottomLeft) THEN
  926. bounds.l := bounds.l + dx;
  927. END;
  928. IF (mode = TopLeft) OR (mode = Top) OR (mode = TopRight) THEN
  929. bounds.t := bounds.t + dy;
  930. END;
  931. IF (mode = TopRight) OR (mode = Right) OR (mode = BottomRight) THEN
  932. bounds.r := bounds.r + dx;
  933. END;
  934. IF (mode = BottomLeft) OR (mode = Bottom) OR (mode = BottomRight) THEN
  935. bounds.b := bounds.b + dy;
  936. END;
  937. components[i](WMComponents.VisualComponent).bounds.Set(bounds);
  938. END;
  939. END;
  940. END Resize;
  941. PROCEDURE Get() : ComponentArray;
  942. VAR components : ComponentArray; i : LONGINT;
  943. BEGIN
  944. IF (nofComponents > 0) THEN
  945. NEW(components, nofComponents);
  946. FOR i := 0 TO nofComponents - 1 DO
  947. components[i] := SELF.components[i];
  948. END;
  949. ELSE
  950. components := NIL;
  951. END;
  952. RETURN components;
  953. END Get;
  954. PROCEDURE Set(component : Repositories.Component);
  955. BEGIN
  956. Reset;
  957. IF (component # NIL) THEN
  958. Add(component);
  959. IF (component IS WMComponents.Component) THEN parent := component.GetParent(); END;
  960. END;
  961. END Set;
  962. PROCEDURE Determine(rect : WMRectangles.Rectangle);
  963. VAR enum : XMLObjects.Enumerator; p : ANY; vc : WMComponents.VisualComponent; r : WMRectangles.Rectangle; valid : BOOLEAN;
  964. BEGIN
  965. IF (nofComponents = 0) THEN
  966. vc := FindVisualComponentInRectangle(root, rect);
  967. IF (vc # NIL) THEN
  968. parent := vc.GetParent();
  969. END;
  970. END;
  971. Clear;
  972. IF (parent # NIL) & (parent IS WMComponents.Component) THEN
  973. enum := parent.GetContents(); enum.Reset;
  974. WHILE enum.HasMoreElements() DO
  975. p := enum.GetNext();
  976. IF (p IS WMComponents.VisualComponent) THEN
  977. vc := p (WMComponents.VisualComponent);
  978. IF (vc # parent) & (parent = vc.GetParent()) THEN
  979. r := vc.bounds.Get();
  980. ToEditorCoordinates(vc, r);
  981. IF WMRectangles.IsContained(rect, r) & ~vc.internal THEN
  982. Add(vc);
  983. END;
  984. END;
  985. END;
  986. END;
  987. END;
  988. valid := nofComponents > 0;
  989. IF valid THEN
  990. GetBoundingBox(frame, activeFrameHandles);
  991. ELSE
  992. parent := NIL;
  993. END;
  994. END Determine;
  995. (* Find an element that rect in parent coordinate system *)
  996. PROCEDURE FindVisualComponentInRectangle(parent : XML.Element; rect : WMRectangles.Rectangle) : WMComponents.VisualComponent;
  997. VAR enum : XMLObjects.Enumerator; p : ANY; vc : WMComponents.VisualComponent; r, rP : WMRectangles.Rectangle;
  998. BEGIN
  999. ASSERT(parent # NIL);
  1000. vc := NIL;
  1001. enum := parent.GetContents(); enum.Reset;
  1002. WHILE (vc = NIL) & enum.HasMoreElements() DO
  1003. p := enum.GetNext();
  1004. IF (p IS WMComponents.VisualComponent) THEN
  1005. vc := p (WMComponents.VisualComponent);
  1006. r := vc.bounds.Get();
  1007. IF WMRectangles.IsContained(rect, r) & ~vc.internal THEN
  1008. (* found *)
  1009. ELSE
  1010. rP := rect;
  1011. WMRectangles.MoveRel(rP, -r.l, -r.t);
  1012. vc := FindVisualComponentInRectangle(vc, rP);
  1013. END;
  1014. END;
  1015. END;
  1016. RETURN vc;
  1017. END FindVisualComponentInRectangle;
  1018. PROCEDURE GetBoundingBox(VAR rect : WMRectangles.Rectangle; VAR active : SET);
  1019. VAR bounds : WMRectangles.Rectangle; alignment, i : LONGINT;
  1020. BEGIN
  1021. rect := WMRectangles.MakeRect(0, 0, 0, 0); active := {0..31};
  1022. FOR i := 0 TO nofComponents - 1 DO
  1023. IF (components[i] IS WMComponents.VisualComponent) THEN
  1024. IF (rect.l # 0) OR (rect.t # 0) OR (rect.r # 0) OR (rect.b # 0) THEN
  1025. bounds := components[i](WMComponents.VisualComponent).bounds.Get();
  1026. ToEditorCoordinates(components[i](WMComponents.VisualComponent), bounds);
  1027. rect.l := MIN(rect.l, bounds.l);
  1028. rect.t := MIN(rect.t, bounds.t);
  1029. rect.r := MAX(rect.r, bounds.r);
  1030. rect.b := MAX(rect.b, bounds.b);
  1031. ELSE
  1032. rect := components[i](WMComponents.VisualComponent).bounds.Get();
  1033. ToEditorCoordinates(components[i](WMComponents.VisualComponent), rect);
  1034. END;
  1035. alignment := components[i](WMComponents.VisualComponent).alignment.Get();
  1036. CASE alignment OF
  1037. |WMComponents.AlignNone: (* do nothing *)
  1038. |WMComponents.AlignLeft: active := active * {Right};
  1039. |WMComponents.AlignTop: active := active * {Bottom};
  1040. |WMComponents.AlignRight : active := active * {Left};
  1041. |WMComponents.AlignBottom: active := active * {Top};
  1042. |WMComponents.AlignClient: active := {};
  1043. ELSE
  1044. END;
  1045. END;
  1046. END;
  1047. IF ~ModificationsAllowed() THEN active := {}; END;
  1048. END GetBoundingBox;
  1049. (** Get bounds of component in ComponentEditor coordinates *)
  1050. PROCEDURE ToEditorCoordinates(component : WMComponents.Component; VAR rect : WMRectangles.Rectangle);
  1051. VAR c : XML.Element; bounds : WMRectangles.Rectangle;
  1052. BEGIN
  1053. ASSERT(component # NIL);
  1054. c := component.GetParent();
  1055. WHILE (c # NIL) & (c IS WMComponents.VisualComponent) & (c # root) DO
  1056. bounds := c(WMComponents.VisualComponent).bounds.Get();
  1057. WMRectangles.MoveRel(rect, bounds.l, bounds.t);
  1058. c := c.GetParent();
  1059. END;
  1060. END ToEditorCoordinates;
  1061. PROCEDURE ToComponentCoordinates(component : WMComponents.Component; VAR rect : WMRectangles.Rectangle);
  1062. VAR c : XML.Element; bounds : WMRectangles.Rectangle;
  1063. BEGIN
  1064. ASSERT(component # NIL);
  1065. IF (c # root) THEN
  1066. c := component.GetParent();
  1067. WHILE (c # NIL) & (c IS WMComponents.VisualComponent) & (c # root) DO
  1068. bounds := c(WMComponents.VisualComponent).bounds.Get();
  1069. WMRectangles.MoveRel(rect, -bounds.l, -bounds.t);
  1070. c := c.GetParent();
  1071. END;
  1072. END;
  1073. END ToComponentCoordinates;
  1074. PROCEDURE CanAdd(component : Repositories.Component) : BOOLEAN;
  1075. BEGIN
  1076. ASSERT(component # NIL);
  1077. RETURN (parent = NIL) OR (component.GetParent() = parent);
  1078. END CanAdd;
  1079. PROCEDURE Add(component : Repositories.Component);
  1080. BEGIN
  1081. ASSERT((component # NIL) & (~Contains(component)));
  1082. IF (nofComponents >= LEN(components)) THEN ResizeComponentsArray; END;
  1083. components[nofComponents] := component;
  1084. INC(nofComponents);
  1085. END Add;
  1086. PROCEDURE Remove(component : Repositories.Component);
  1087. VAR i, j, nofRemoved : LONGINT;
  1088. BEGIN
  1089. ASSERT(component # NIL);
  1090. nofRemoved := 0;
  1091. i := 0; j := 0;
  1092. WHILE (i < nofComponents) DO
  1093. IF (components[i] # component) THEN
  1094. components[j] := components[i];
  1095. INC(j);
  1096. ELSE
  1097. INC(nofRemoved);
  1098. END;
  1099. INC(i);
  1100. END;
  1101. nofComponents := nofComponents - nofRemoved;
  1102. END Remove;
  1103. PROCEDURE Clear;
  1104. VAR i : LONGINT;
  1105. BEGIN
  1106. nofComponents := 0;
  1107. FOR i := 0 TO LEN(components)-1 DO
  1108. components[i] := NIL;
  1109. END;
  1110. END Clear;
  1111. PROCEDURE Reset;
  1112. BEGIN
  1113. Clear;
  1114. parent := NIL;
  1115. END Reset;
  1116. PROCEDURE ResizeComponentsArray;
  1117. VAR newComponents : ComponentArray; i : LONGINT;
  1118. BEGIN
  1119. NEW(newComponents, 2 * LEN(components));
  1120. FOR i := 0 TO LEN(components)-1 DO
  1121. newComponents[i] := components[i];
  1122. END;
  1123. components := newComponents;
  1124. END ResizeComponentsArray;
  1125. END Selection;
  1126. TYPE
  1127. ComponentEditor = OBJECT(WMComponents.VisualComponent)
  1128. VAR
  1129. panel : WMComponents.VisualComponent;
  1130. mode : LONGINT;
  1131. selection : Selection;
  1132. selectionFrame : Frame;
  1133. frame, dragFrame : Frame;
  1134. limitMode : LONGINT;
  1135. insertObjAt : WMComponents.VisualComponent;
  1136. downX, downY, lastX, lastY, dragX, dragY : LONGINT;
  1137. oldPointerInfo: WORD;
  1138. selectInsertObjAt : BOOLEAN;
  1139. showSnapGrid : WMProperties.BooleanProperty;
  1140. showSnapGridI : BOOLEAN;
  1141. enableSnap : WMProperties.BooleanProperty;
  1142. enableSnapI : BOOLEAN;
  1143. showHelperLines : WMProperties.BooleanProperty;
  1144. showHelperLinesI : BOOLEAN;
  1145. showFrames : WMProperties.BooleanProperty;
  1146. showFramesI : BOOLEAN;
  1147. snapgrid : SnapGrid;
  1148. owner : MainWindow;
  1149. manager : WMWindowManager.WindowManager;
  1150. pointerMode : LONGINT;
  1151. frameResizeOrigin : WMRectangles.Rectangle;
  1152. frameResizeMode : LONGINT;
  1153. modifierFlags, mouseKeys : SET;
  1154. clipboard : Clipboard;
  1155. paint : BOOLEAN;
  1156. state : LONGINT;
  1157. timer : Kernel.Timer;
  1158. PROCEDURE &Init*;
  1159. BEGIN
  1160. Init^;
  1161. SetNameAsString(StrComponentEditor);
  1162. (*SetGenerator("WMBuilder.GenComponentEditor");*)
  1163. mode := EditMode;
  1164. SetExtGetPositionOwnerHandler(ExtGetPositionOwnerHandler);
  1165. takesFocus.Set(TRUE);
  1166. needsTab.Set(TRUE);
  1167. NEW(showSnapGrid, NIL, Strings.NewString("SnapGrid"), NIL); properties.Add(showSnapGrid);
  1168. showSnapGrid.Set(TRUE);
  1169. showSnapGridI := showSnapGrid.Get();
  1170. NEW(enableSnap, NIL, Strings.NewString("Snap"), NIL); properties.Add(enableSnap);
  1171. enableSnap.Set(TRUE);
  1172. enableSnapI := enableSnap.Get();
  1173. NEW(showHelperLines, NIL, Strings.NewString("HelperLines"), NIL); properties.Add(showHelperLines);
  1174. showHelperLines.Set(TRUE);
  1175. showHelperLinesI := showHelperLines.Get();
  1176. NEW(showFrames, NIL, Strings.NewString("Frames"), NIL); properties.Add(showFrames);
  1177. showFrames.Set(TRUE);
  1178. showFramesI := showFrames.Get();
  1179. NEW(snapgrid);
  1180. NEW(panel);
  1181. panel.SetName("VisualComponent");
  1182. panel.alignment.Set(WMComponents.AlignClient);
  1183. panel.takesFocus.Set(FALSE);
  1184. AddContent(panel);
  1185. NEW(selection, panel);
  1186. NEW(selectionFrame);
  1187. NEW(frame);
  1188. NEW(dragFrame);
  1189. SelectInsertAtObj(panel);
  1190. downX := Invalid; downY := Invalid;
  1191. lastX := Invalid; lastY := Invalid;
  1192. oldPointerInfo := No;
  1193. selectInsertObjAt := FALSE;
  1194. limitMode := No;
  1195. modifierFlags := {};
  1196. manager := WMWindowManager.GetDefaultManager();
  1197. pointerMode := None;
  1198. NEW(clipboard);
  1199. paint := FALSE;
  1200. state := State_Running;
  1201. NEW(timer);
  1202. END Init;
  1203. PROCEDURE SetPanel(panel : WMComponents.VisualComponent);
  1204. BEGIN
  1205. ASSERT(panel # NIL);
  1206. IF (SELF.panel # NIL) THEN RemoveContent(SELF.panel); END;
  1207. SELF.panel := panel;
  1208. NEW(selection, panel);
  1209. AddContent(panel);
  1210. SelectInsertAtObj(panel);
  1211. panel.Reset(NIL, NIL);
  1212. Reset(NIL, NIL);
  1213. Invalidate;
  1214. END SetPanel;
  1215. PROCEDURE PropertyChanged*(sender, property : ANY);
  1216. BEGIN
  1217. IF (property = showSnapGrid) OR (property = enableSnap) OR (property = showHelperLines) OR (property = showFrames) THEN
  1218. RecacheProperties;
  1219. ELSE
  1220. PropertyChanged^(sender, property);
  1221. END;
  1222. END PropertyChanged;
  1223. PROCEDURE RecacheProperties*;
  1224. BEGIN
  1225. RecacheProperties^;
  1226. showSnapGridI := showSnapGrid.Get();
  1227. enableSnapI := enableSnap.Get();
  1228. showHelperLinesI := showHelperLines.Get();
  1229. showFramesI := showFrames.Get();
  1230. Invalidate;
  1231. END RecacheProperties;
  1232. PROCEDURE SetPaint(paint : BOOLEAN);
  1233. BEGIN
  1234. SELF.paint := paint;
  1235. END SetPaint;
  1236. PROCEDURE SetMode(mode : LONGINT);
  1237. BEGIN {EXCLUSIVE}
  1238. ASSERT((mode = UseMode) OR (mode = EditMode));
  1239. IF (mode = UseMode) THEN
  1240. SetExtGetPositionOwnerHandler(NIL);
  1241. ELSE
  1242. SetExtGetPositionOwnerHandler(ExtGetPositionOwnerHandler);
  1243. END;
  1244. panel.SetFocus;
  1245. SELF.mode := mode;
  1246. UpdateFramePosition;
  1247. Invalidate;
  1248. END SetMode;
  1249. PROCEDURE GetMode() : LONGINT;
  1250. BEGIN
  1251. RETURN mode;
  1252. END GetMode;
  1253. PROCEDURE ExtGetPositionOwnerHandler(x, y : LONGINT; VAR pointerOwner : WMComponents.VisualComponent; VAR handled : BOOLEAN);
  1254. BEGIN
  1255. (* let editpanel handle all messages *)
  1256. pointerOwner := SELF; handled := TRUE;
  1257. END ExtGetPositionOwnerHandler;
  1258. PROCEDURE Delete;
  1259. BEGIN
  1260. IF selection.ModificationsAllowed() THEN
  1261. IF selection.Contains(insertObjAt) THEN
  1262. SelectInsertAtObj(panel);
  1263. END;
  1264. selection.Delete;
  1265. selectionFrame.Clear;
  1266. UpdateFramePosition;
  1267. panel.Invalidate;
  1268. IF (owner # NIL) THEN
  1269. IF (owner.componentTree # NIL) THEN owner.componentTree.Refresh(NIL, NIL); END;
  1270. IF (owner.propertyWindow # NIL) THEN owner.propertyWindow.SetComponent(SELF, NIL); END;
  1271. END;
  1272. END;
  1273. END Delete;
  1274. PROCEDURE ToFront;
  1275. BEGIN
  1276. IF selection.ModificationsAllowed() THEN
  1277. selection.ToFront;
  1278. UpdateFramePosition;
  1279. panel.Invalidate;
  1280. IF (owner # NIL) & (owner.componentTree # NIL) THEN owner.componentTree.Refresh(NIL, NIL); END;
  1281. END;
  1282. END ToFront;
  1283. PROCEDURE AddComponent(c :Repositories.Component; x, y : LONGINT);
  1284. VAR vc : WMComponents.VisualComponent; bounds : WMRectangles.Rectangle;
  1285. BEGIN
  1286. ASSERT(c # NIL);
  1287. ASSERT(insertObjAt # NIL);
  1288. IF c IS Models.Model THEN HALT(100) END;
  1289. IF (c IS WMComponents.VisualComponent) THEN
  1290. vc := c (WMComponents.VisualComponent);
  1291. vc.alignment.Set(WMComponents.AlignNone);
  1292. IF (vc.bounds.GetWidth() < 10) OR (vc.bounds.GetHeight() < 10) THEN
  1293. vc.bounds.SetExtents(40, 20);
  1294. END;
  1295. bounds := vc.bounds.Get();
  1296. WMRectangles.MoveRel(bounds, x, y);
  1297. vc.bounds.Set(bounds);
  1298. LabelComponent(vc);
  1299. insertObjAt.AddContent(vc);
  1300. vc.Reset(NIL, NIL);
  1301. insertObjAt.Invalidate;
  1302. panel.Invalidate;
  1303. Select(vc);
  1304. ELSE
  1305. insertObjAt.AddContent(c);
  1306. END;
  1307. IF (owner # NIL) & (owner.componentTree # NIL) THEN owner.componentTree.Refresh(NIL, NIL); END;
  1308. END AddComponent;
  1309. PROCEDURE Select(c : Repositories.Component);
  1310. VAR ci : ComponentInfo; vc : WMComponents.VisualComponent; alignment : LONGINT; bounds : WMRectangles.Rectangle;
  1311. BEGIN
  1312. selection.Reset;
  1313. IF (c # NIL) THEN selection.Set(c); END;
  1314. IF (c # NIL) & (c IS WMComponents.VisualComponent) THEN
  1315. vc := c(WMComponents.VisualComponent);
  1316. bounds := vc.bounds.Get();
  1317. alignment := vc.alignment.Get();
  1318. selectionFrame.SetFrameType(Frame_Selection);
  1319. IF vc.IsLocked() THEN
  1320. selectionFrame.SetActiveHandles({});
  1321. ELSE
  1322. selectionFrame.SetActiveHandlesFor(alignment);
  1323. END;
  1324. ci := GetComponentInfo(vc);
  1325. WMRectangles.MoveRel(bounds, ci.originX, ci.originY);
  1326. selectionFrame.bounds := bounds;
  1327. ELSE
  1328. InvalidateFrame(selectionFrame);
  1329. END;
  1330. owner.propertyWindow.SetComponent(SELF, c);
  1331. UpdateFramePosition;
  1332. IF (owner # NIL) & (owner.componentTree # NIL) THEN owner.componentTree.UpdateColors; END;
  1333. Invalidate;
  1334. END Select;
  1335. PROCEDURE SelectInsertAtObj(vc : WMComponents.VisualComponent);
  1336. BEGIN
  1337. ASSERT(vc # NIL);
  1338. IF ~vc.IsLocked() THEN
  1339. IF selection.Contains(vc) THEN
  1340. selection.Reset;
  1341. InvalidateFrame(selectionFrame);
  1342. UpdateFramePosition;
  1343. END;
  1344. insertObjAt := vc;
  1345. IF (owner # NIL) & (owner.componentTree # NIL) THEN owner.componentTree.SetInsertAtObj(insertObjAt); END;
  1346. Invalidate;
  1347. ELSE
  1348. END;
  1349. END SelectInsertAtObj;
  1350. PROCEDURE InvalidateRegion(frame, oldFrame : WMRectangles.Rectangle);
  1351. VAR invalidateRect : WMRectangles.Rectangle;
  1352. BEGIN
  1353. IF ~WMRectangles.IsEqual(frame, oldFrame) THEN
  1354. invalidateRect := oldFrame;
  1355. WMRectangles.ExtendRect(invalidateRect, frame);
  1356. invalidateRect := WMRectangles.ResizeRect(invalidateRect, 5);
  1357. InvalidateRect(invalidateRect);
  1358. END;
  1359. END InvalidateRegion;
  1360. PROCEDURE InvalidateFrame(frame : Frame);
  1361. VAR rect : WMRectangles.Rectangle;
  1362. BEGIN
  1363. ASSERT(frame # NIL);
  1364. IF frame.IsValid() THEN
  1365. rect := frame.bounds;
  1366. rect := WMRectangles.ResizeRect(rect, 5);
  1367. frame.Clear;
  1368. InvalidateRect(rect);
  1369. END;
  1370. END InvalidateFrame;
  1371. PROCEDURE GetLimitMode(x, y : LONGINT; VAR bounds : WMRectangles.Rectangle) : WORD;
  1372. VAR
  1373. vc : WMComponents.VisualComponent; mode : LONGINT;
  1374. ci : ComponentInfo;
  1375. PROCEDURE Near(x, xRef : LONGINT) : BOOLEAN;
  1376. BEGIN
  1377. RETURN (xRef - DistanceLimit <= x) & (x <= xRef + DistanceLimit);
  1378. END Near;
  1379. BEGIN
  1380. mode := No;
  1381. vc := FindPositionOwner(x, y);
  1382. IF (vc # NIL) & (vc # panel) THEN
  1383. bounds := vc.bounds.Get();
  1384. ci := GetComponentInfo(vc);
  1385. WMRectangles.MoveRel(bounds, -ci.originX, -ci.originY);
  1386. IF Near(x, bounds.l) THEN
  1387. IF Near(y, bounds.t) THEN mode := TopLeft;
  1388. ELSIF Near(y, bounds.b) THEN mode := BottomLeft;
  1389. ELSE mode := Left;
  1390. END;
  1391. ELSIF Near(x, bounds.r) THEN
  1392. IF Near(y, bounds.t) THEN mode := TopRight;
  1393. ELSIF Near(y, bounds.b) THEN mode := BottomRight;
  1394. ELSE mode := Right;
  1395. END;
  1396. ELSIF Near(y, bounds.t) THEN
  1397. mode := Top;
  1398. ELSIF Near(y, bounds.b) THEN
  1399. mode := Bottom;
  1400. ELSE
  1401. IF WMRectangles.PointInRect(x, y, WMRectangles.MakeRect(bounds.l + DistanceLimit, bounds.t + DistanceLimit, bounds.r - DistanceLimit, bounds.b - DistanceLimit)) THEN
  1402. mode := Inside;
  1403. END;
  1404. END;
  1405. END;
  1406. RETURN mode;
  1407. END GetLimitMode;
  1408. PROCEDURE MoveFrame(direction : LONGINT);
  1409. VAR oldFrame : WMRectangles.Rectangle; dx, dy : LONGINT;
  1410. BEGIN
  1411. ASSERT((direction = Left) OR (direction = Top) OR (direction = Right) OR (direction = Bottom));
  1412. IF selectionFrame.IsValid() & selection.ModificationsAllowed() THEN
  1413. oldFrame := selectionFrame.bounds;
  1414. IF enableSnapI & (Inputs.Alt * modifierFlags = {}) THEN
  1415. CASE direction OF
  1416. |Left:
  1417. dx := -(selectionFrame.bounds.l MOD snapgrid.deltaX); IF (dx = 0) THEN dx := -snapgrid.deltaX; END;
  1418. dy := 0;
  1419. |Top:
  1420. dx := 0;
  1421. dy := -(selectionFrame.bounds.t MOD snapgrid.deltaY); IF (dy = 0) THEN dy := -snapgrid.deltaY; END;
  1422. |Right:
  1423. dx := snapgrid.deltaX - (selectionFrame.bounds.r MOD snapgrid.deltaX); IF (dx = 0) THEN dx := snapgrid.deltaX; END;
  1424. dy := 0;
  1425. |Bottom:
  1426. dx := 0;
  1427. dy := snapgrid.deltaY - (selectionFrame.bounds.b MOD snapgrid.deltaY); IF (dy = 0) THEN dy := snapgrid.deltaY; END;
  1428. END;
  1429. ELSE
  1430. CASE direction OF
  1431. |Left: dx := -1; dy := 0;
  1432. |Top: dx := 0; dy := -1;
  1433. |Right: dx := 1; dy := 0;
  1434. |Bottom: dx := 0; dy := 1;
  1435. END;
  1436. END;
  1437. WMRectangles.MoveRel(selectionFrame.bounds, dx, dy);
  1438. IF (selection.NofVisualComponents() > 1) THEN
  1439. DisableUpdate;
  1440. selection.MoveRelative(dx, dy);
  1441. UpdateFramePosition;
  1442. EnableUpdate;
  1443. Invalidate;
  1444. ELSE
  1445. selection.MoveRelative(dx, dy);
  1446. UpdateFramePosition;
  1447. InvalidateRegion(oldFrame, selectionFrame.bounds);
  1448. END;
  1449. END;
  1450. END MoveFrame;
  1451. PROCEDURE CheckSelectionFrame;
  1452. VAR oldBounds, bounds : WMRectangles.Rectangle; activeHandles : SET;
  1453. BEGIN
  1454. selection.GetBoundingBox(bounds, activeHandles);
  1455. IF ~WMRectangles.IsEqual(selectionFrame.bounds, bounds) OR (selectionFrame.activeHandles # activeHandles) THEN
  1456. oldBounds := selectionFrame.bounds;
  1457. selectionFrame.bounds := bounds; selectionFrame.activeHandles := activeHandles;
  1458. InvalidateRegion(oldBounds, selectionFrame.bounds);
  1459. END;
  1460. END CheckSelectionFrame;
  1461. PROCEDURE CheckCursor(x, y : LONGINT; keys, modifierFlags : SET);
  1462. CONST ShiftValue = 256;
  1463. VAR ignore : WMRectangles.Rectangle; res : WORD;
  1464. BEGIN
  1465. IF paint THEN
  1466. IF (oldPointerInfo # Paint) THEN
  1467. SetPointerInfo(crosshair);
  1468. oldPointerInfo := Paint;
  1469. END;
  1470. ELSE
  1471. IF (Inputs.Alt * modifierFlags # {}) THEN
  1472. res := GetLimitMode(x, y, ignore);
  1473. IF (oldPointerInfo - ShiftValue # res) THEN
  1474. CASE res OF
  1475. | Left: SetPointerInfo(leftLimit);
  1476. | TopLeft: SetPointerInfo(topLeftLimit);
  1477. | Top: SetPointerInfo(topLimit);
  1478. | TopRight: SetPointerInfo(topRightLimit);
  1479. | Right: SetPointerInfo(rightLimit);
  1480. | BottomRight: SetPointerInfo(bottomRightLimit);
  1481. | Bottom: SetPointerInfo(bottomLimit);
  1482. | BottomLeft: SetPointerInfo(bottomLeftLimit);
  1483. | Inside: SetPointerInfo(sizeLimit);
  1484. ELSE
  1485. SetPointerInfo(manager.pointerStandard);
  1486. oldPointerInfo := No - ShiftValue;
  1487. END;
  1488. oldPointerInfo := res + ShiftValue;
  1489. END;
  1490. ELSE
  1491. IF selectionFrame.IsValid() THEN
  1492. (* change pointerinfo *)
  1493. res := selectionFrame.IsInActiveFrameHandle(x, y);
  1494. IF (oldPointerInfo # res) & ~(0 IN keys) THEN
  1495. CASE res OF
  1496. | Left: SetPointerInfo(manager.pointerLeftRight);
  1497. | TopLeft: SetPointerInfo(manager.pointerULDR);
  1498. | Top: SetPointerInfo(manager.pointerUpDown);
  1499. | TopRight: SetPointerInfo(manager.pointerURDL);
  1500. | Right: SetPointerInfo(manager.pointerLeftRight);
  1501. | BottomRight: SetPointerInfo(manager.pointerULDR);
  1502. | Bottom: SetPointerInfo(manager.pointerUpDown);
  1503. | BottomLeft: SetPointerInfo(manager.pointerURDL);
  1504. | Inside: SetPointerInfo(manager.pointerMove);
  1505. ELSE
  1506. SetPointerInfo(manager.pointerStandard);
  1507. END;
  1508. oldPointerInfo := res;
  1509. END;
  1510. ELSE
  1511. IF (oldPointerInfo # No) THEN
  1512. SetPointerInfo(manager.pointerStandard);
  1513. oldPointerInfo := res;
  1514. END;
  1515. END;
  1516. END;
  1517. END;
  1518. END CheckCursor;
  1519. PROCEDURE CheckSelection;
  1520. VAR component : Repositories.Component; nofComponents : LONGINT;
  1521. BEGIN
  1522. nofComponents := selection.NofComponents();
  1523. IF (nofComponents = 1) THEN
  1524. component := selection.GetFirst();
  1525. owner.propertyWindow.SetComponent(SELF, component);
  1526. ELSE
  1527. owner.propertyWindow.SetComponent(SELF, NIL);
  1528. END;
  1529. END CheckSelection;
  1530. PROCEDURE PointerMove*(x, y : LONGINT; keys : SET);
  1531. VAR
  1532. down : BOOLEAN; oldFrame : WMRectangles.Rectangle;
  1533. snapX, snapY, snapDownX, snapDownY, dx, dy : LONGINT; f : WMRectangles.Rectangle;
  1534. oldParent : XML.Element;
  1535. BEGIN
  1536. PointerMove^(x, y, keys);
  1537. down := 0 IN keys;
  1538. IF enableSnapI & (Inputs.Alt * modifierFlags = {}) THEN
  1539. snapgrid.Snap(x, y, snapX, snapY);
  1540. snapgrid.Snap(downX, downY, snapDownX, snapDownY);
  1541. ELSE
  1542. snapX := x; snapY := y;
  1543. snapDownX := downX; snapDownY := downY;
  1544. END;
  1545. IF down THEN
  1546. IF (pointerMode = SelectComponent) THEN
  1547. IF Distance(snapDownX, snapDownY, snapX, snapY) > 2.0 THEN
  1548. frame.bounds := WMRectangles.MakeRect(snapDownX, snapDownY, snapX, snapY);
  1549. frame.FixBounds;
  1550. pointerMode := Spawn;
  1551. selection.Reset;
  1552. IF (owner # NIL) & (owner.componentTree # NIL) THEN owner.componentTree.UpdateColors; END;
  1553. UpdateFramePosition;
  1554. END;
  1555. ELSIF (pointerMode = ResizeMove) THEN
  1556. oldFrame := selectionFrame.bounds;
  1557. f := frameResizeOrigin;
  1558. CASE frameResizeMode OF
  1559. |Left: f.l := snapX;
  1560. |TopLeft: f.l := snapX; f.t := snapY;
  1561. |Top: f.t := snapY;
  1562. |TopRight: f.t := snapY; f.r := snapX;
  1563. |Right: f.r := snapX;
  1564. |BottomRight: f.b := snapY; f.r := snapX;
  1565. |Bottom: f.b := snapY;
  1566. |BottomLeft: f.b := snapY; f.l := snapX;
  1567. |Inside: WMRectangles.MoveRel(f, snapX - snapDownX, snapY - snapDownY);
  1568. ELSE
  1569. END;
  1570. selectionFrame.bounds := f;
  1571. selectionFrame.FixBounds;
  1572. IF ~WMRectangles.IsEqual(oldFrame, selectionFrame.bounds) THEN
  1573. dx := 0; dy := 0;
  1574. IF (frameResizeMode = Inside) THEN
  1575. dx := selectionFrame.bounds.l - oldFrame.l; dy := selectionFrame.bounds.t - oldFrame.t;
  1576. DisableUpdate;
  1577. selection.MoveRelative(dx, dy);
  1578. EnableUpdate;
  1579. Invalidate;
  1580. ELSE
  1581. CASE frameResizeMode OF
  1582. |Left: dx := selectionFrame.bounds.l - oldFrame.l;
  1583. |TopLeft: dx := selectionFrame.bounds.l - oldFrame.l; dy := selectionFrame.bounds.t - oldFrame.t;
  1584. |Top: dy := selectionFrame.bounds.t - oldFrame.t;
  1585. |TopRight: dy := selectionFrame.bounds.t - oldFrame.t; dx := selectionFrame.bounds.r - oldFrame.r;
  1586. |Right: dx := selectionFrame.bounds.r - oldFrame.r;
  1587. |BottomRight: dy := selectionFrame.bounds.b - oldFrame.b; dx := selectionFrame.bounds.r - oldFrame.r;
  1588. |Bottom: dy := selectionFrame.bounds.b - oldFrame.b;
  1589. |BottomLeft: dy := selectionFrame.bounds.b - oldFrame.b; dx := selectionFrame.bounds.l - oldFrame.l;
  1590. ELSE
  1591. END;
  1592. (* selection.Resize(frameResizeMode, dx, dy); *)
  1593. DisableUpdate;
  1594. selection.ResizeProportional(selectionFrame.bounds.l, selectionFrame.bounds.t, selectionFrame.GetWidth(), selectionFrame.GetHeight(), 0, 0);
  1595. EnableUpdate;
  1596. Invalidate;
  1597. END;
  1598. UpdateFramePosition;
  1599. END;
  1600. (* InvalidateRegion(oldFrame, selectionFrame.bounds); *)
  1601. ELSIF (pointerMode = Spawn) THEN
  1602. IF frame.IsValid() THEN
  1603. oldFrame := frame.bounds;
  1604. frame.bounds := WMRectangles.MakeRect(snapDownX, snapDownY, snapX, snapY);
  1605. frame.FixBounds;
  1606. oldParent := selection.GetParent();
  1607. selection.Determine(frame.bounds);
  1608. IF (oldParent # selection.GetParent()) THEN Invalidate; END;
  1609. CheckSelection;
  1610. IF (owner # NIL) & (owner.componentTree # NIL) THEN owner.componentTree.UpdateColors; END;
  1611. IF (selection.NofComponents() > 0) THEN
  1612. selection.GetBoundingBox(selectionFrame.bounds, selectionFrame.activeHandles);
  1613. ELSE
  1614. InvalidateFrame(selectionFrame);
  1615. END;
  1616. UpdateFramePosition;
  1617. InvalidateRegion(oldFrame, frame.bounds);
  1618. END;
  1619. ELSIF (pointerMode = PaintComponent) THEN
  1620. oldFrame := frame.bounds;
  1621. frame.bounds := WMRectangles.MakeRect(snapDownX, snapDownY, snapX, snapY);
  1622. frame.FixBounds;
  1623. InvalidateRegion(oldFrame, frame.bounds);
  1624. UpdateFramePosition;
  1625. END;
  1626. END;
  1627. CheckCursor(x, y, keys, modifierFlags);
  1628. lastX := x; lastY := y;
  1629. IF (owner # NIL) THEN owner.UpdateCursorPosition(x, y); END;
  1630. END PointerMove;
  1631. PROCEDURE PointerLeave*;
  1632. BEGIN
  1633. PointerLeave^;
  1634. lastX := Invalid; lastY := Invalid;
  1635. IF (owner # NIL) THEN owner.UpdateCursorPosition(Invalid, Invalid); END;
  1636. END PointerLeave;
  1637. PROCEDURE PointerDown*(x, y : LONGINT; keys : SET);
  1638. VAR down : BOOLEAN; res: LONGINT; rect : WMRectangles.Rectangle;
  1639. BEGIN
  1640. PointerDown^(x, y, keys);
  1641. mouseKeys := keys;
  1642. selectInsertObjAt := selectInsertObjAt OR (2 IN keys);
  1643. down := (0 IN keys);
  1644. IF down THEN
  1645. IF (Inputs.Alt * modifierFlags = {}) THEN
  1646. downX := x; downY := y;
  1647. IF ~paint THEN
  1648. res := selectionFrame.IsInFrameHandle(x, y);
  1649. IF (res = No) THEN
  1650. pointerMode := SelectComponent;
  1651. UpdateFramePosition;
  1652. InvalidateFrame(selectionFrame);
  1653. ELSIF selection.ModificationsAllowed() THEN
  1654. frameResizeOrigin := selectionFrame.bounds;
  1655. frameResizeMode := res;
  1656. pointerMode := ResizeMove;
  1657. selection.InitResize(selectionFrame.bounds.l, selectionFrame.bounds.t, selectionFrame.GetWidth(), selectionFrame.GetHeight());
  1658. END;
  1659. ELSE
  1660. pointerMode := PaintComponent;
  1661. END;
  1662. ELSIF selection.ModificationsAllowed() THEN
  1663. res := GetLimitMode(x, y, rect);
  1664. IF (res = Inside) THEN
  1665. TakeOverSize(x, y);
  1666. ELSIF (res # No) THEN
  1667. selection.SetLimit(rect, res);
  1668. CheckSelectionFrame;
  1669. END;
  1670. END;
  1671. END;
  1672. END PointerDown;
  1673. PROCEDURE TakeOverSize(x, y : LONGINT);
  1674. VAR vc : WMComponents.VisualComponent; rect : WMRectangles.Rectangle;
  1675. BEGIN
  1676. IF selection.ModificationsAllowed() & (selection.NofVisualComponents() > 0) THEN
  1677. vc := FindPositionOwner(x, y);
  1678. IF (vc # NIL) THEN
  1679. InvalidateFrame(selectionFrame);
  1680. rect := vc.bounds.Get();
  1681. selection.SetExtents(rect.r - rect.l, rect.b - rect.t);
  1682. selection.GetBoundingBox(selectionFrame.bounds, selectionFrame.activeHandles);
  1683. UpdateFramePosition;
  1684. panel.Invalidate;
  1685. END;
  1686. END;
  1687. END TakeOverSize;
  1688. PROCEDURE PointerUp*(x, y : LONGINT; keys : SET);
  1689. VAR
  1690. vc : WMComponents.VisualComponent; down : BOOLEAN; oldParent : XML.Element;
  1691. component : Repositories.Component;
  1692. cx, cy : LONGINT;
  1693. BEGIN
  1694. PointerUp^(x, y, keys);
  1695. mouseKeys := keys;
  1696. down := 0 IN keys;
  1697. IF ~down THEN
  1698. IF paint THEN
  1699. IF frame.IsValid() THEN
  1700. component := owner.componentWindow.GetSelectedComponent();
  1701. IF (component # NIL) THEN
  1702. IF (component IS WMComponents.VisualComponent) THEN
  1703. ToComponentCoordinates(insertObjAt, frame.bounds.l, frame.bounds.t, cx, cy);
  1704. component(WMComponents.VisualComponent).bounds.Set(WMRectangles.MakeRect(cx, cy, cx + (frame.bounds.r - frame.bounds.l), cy + (frame.bounds.b - frame.bounds.t)));
  1705. END;
  1706. AddComponent(component, 0, 0);
  1707. END;
  1708. InvalidateFrame(frame);
  1709. END;
  1710. ELSE
  1711. IF (Inputs.Ctrl * modifierFlags = {}) THEN
  1712. IF (pointerMode = SelectComponent) THEN
  1713. InvalidateFrame(selectionFrame);
  1714. vc := FindPositionOwner(x, y);
  1715. IF (vc # panel) THEN
  1716. Select(vc);
  1717. ELSE
  1718. Select(NIL);
  1719. END;
  1720. ELSIF (pointerMode = Spawn) THEN
  1721. oldParent := selection.GetParent();
  1722. selection.Determine(frame.bounds);
  1723. IF (owner # NIL) & (owner.componentTree # NIL) THEN owner.componentTree.UpdateColors; END;
  1724. IF (oldParent # selection.GetParent()) THEN Invalidate; END;
  1725. IF (selection.NofComponents() > 0) THEN
  1726. selection.GetBoundingBox(selectionFrame.bounds, selectionFrame.activeHandles);
  1727. ELSE
  1728. selectionFrame.Clear;
  1729. END;
  1730. frame.Clear;
  1731. panel.Invalidate;
  1732. UpdateFramePosition;
  1733. END;
  1734. pointerMode := None;
  1735. ELSE
  1736. vc := FindPositionOwner(x, y);
  1737. IF (vc # panel) THEN
  1738. IF selection.Contains(vc) THEN
  1739. selection.Remove(vc);
  1740. ELSE
  1741. selection.Add(vc);
  1742. END;
  1743. CheckSelection;
  1744. CheckSelectionFrame;
  1745. IF (owner # NIL) & (owner.componentTree # NIL) THEN owner.componentTree.UpdateColors; END;
  1746. UpdateFramePosition;
  1747. END;
  1748. END;
  1749. END;
  1750. END;
  1751. IF selectInsertObjAt & ~(2 IN keys) THEN
  1752. selectInsertObjAt := FALSE;
  1753. vc := FindPositionOwner(x, y);
  1754. IF (vc # NIL) THEN
  1755. SelectInsertAtObj(vc);
  1756. END;
  1757. END;
  1758. END PointerUp;
  1759. PROCEDURE KeyEvent*(ucs : LONGINT; flags: SET; VAR keySym: LONGINT);
  1760. PROCEDURE ControlKey(flags : SET) : BOOLEAN;
  1761. BEGIN
  1762. RETURN (flags * Inputs.Ctrl # {}) & (flags - Inputs.Ctrl = {});
  1763. END ControlKey;
  1764. PROCEDURE Copy;
  1765. VAR components : ComponentArray;
  1766. BEGIN
  1767. components := selection.Get();
  1768. IF (components # NIL) THEN
  1769. clipboard.Put(components);
  1770. END;
  1771. END Copy;
  1772. PROCEDURE Paste;
  1773. VAR components : ComponentArray; i : LONGINT;
  1774. BEGIN
  1775. components := clipboard.Get();
  1776. IF (components # NIL) THEN
  1777. selection.Reset;
  1778. InvalidateFrame(selectionFrame);
  1779. FOR i := 0 TO LEN(components) - 1 DO
  1780. IF (components[i] # NIL) THEN
  1781. selection.Add(components[i]);
  1782. insertObjAt.AddContent(components[i]);
  1783. IF (components[i] IS WMComponents.VisualComponent) THEN
  1784. components[i](WMComponents.VisualComponent).Reset(NIL, NIL);
  1785. END;
  1786. END;
  1787. END;
  1788. CheckSelection;
  1789. IF (selection.NofComponents() > 0) THEN
  1790. selection.GetBoundingBox(selectionFrame.bounds, selectionFrame.activeHandles);
  1791. UpdateFramePosition;
  1792. panel.Invalidate;
  1793. Invalidate;
  1794. END;
  1795. END;
  1796. IF (owner # NIL) & (owner.componentTree # NIL) THEN owner.componentTree.Refresh(NIL, NIL); END;
  1797. END Paste;
  1798. PROCEDURE SelectAll;
  1799. VAR c : XML.Content;
  1800. BEGIN
  1801. ASSERT(insertObjAt # NIL);
  1802. selection.Reset;
  1803. c := insertObjAt.GetFirst();
  1804. WHILE (c # NIL) DO
  1805. IF (c IS Repositories.Component) THEN
  1806. selection.Add(c(Repositories.Component));
  1807. END;
  1808. c := insertObjAt.GetNext(c);
  1809. END;
  1810. CheckSelection;
  1811. CheckSelectionFrame;
  1812. IF (owner # NIL) & (owner.componentTree # NIL) THEN owner.componentTree.UpdateColors; END;
  1813. END SelectAll;
  1814. BEGIN
  1815. KeyEvent^(ucs, flags, keySym);
  1816. IF (flags # modifierFlags) THEN
  1817. modifierFlags := flags;
  1818. CheckCursor(lastX, lastY, mouseKeys, modifierFlags);
  1819. END;
  1820. IF Inputs.Release IN flags THEN RETURN; END;
  1821. IF (keySym = Inputs.KsLeft) THEN MoveFrame(Left);
  1822. ELSIF (keySym = Inputs.KsUp) THEN MoveFrame(Top);
  1823. ELSIF (keySym = Inputs.KsRight) THEN MoveFrame(Right);
  1824. ELSIF (keySym = Inputs.KsDown) THEN MoveFrame(Bottom);
  1825. ELSIF (keySym = Inputs.KsDelete) THEN Delete;
  1826. ELSIF ControlKey(flags) & (ucs = 20H) THEN (* CTRL-SPACE *)
  1827. SetPaint(~paint);
  1828. owner.paintBtn.SetPressed(paint);
  1829. ELSIF ControlKey(flags) & (ucs = 03H) THEN (* CTRL-C *)
  1830. Copy;
  1831. ELSIF ControlKey(flags) & (ucs = 16H) THEN (* CTRL-V *)
  1832. Paste;
  1833. ELSIF ControlKey(flags) & (ucs = 18H) THEN (* CTRL-X *)
  1834. Copy;
  1835. selection.Delete;
  1836. CheckSelection;
  1837. CheckSelectionFrame;
  1838. IF (owner # NIL) & (owner.componentTree # NIL) THEN owner.componentTree.Refresh(NIL, NIL); END;
  1839. panel.Invalidate;
  1840. ELSIF ControlKey(flags) & (ucs = 01H) THEN (* CTRL-A *)
  1841. SelectAll;
  1842. panel.Invalidate;
  1843. END;
  1844. END KeyEvent;
  1845. PROCEDURE FocusLost*;
  1846. BEGIN
  1847. FocusLost^;
  1848. modifierFlags := {};
  1849. downX := Invalid; downY := Invalid; lastX := Invalid; lastY := Invalid;
  1850. END FocusLost;
  1851. PROCEDURE DragOver*(x, y : LONGINT; dragInfo : WMWindowManager.DragInfo);
  1852. BEGIN
  1853. IF takesFocus.Get() THEN
  1854. dragX := x; dragY := y;
  1855. END;
  1856. END DragOver;
  1857. PROCEDURE DragAddComponent(component : Repositories.Component; VAR res : WORD); (* ! needs work work hierarchical buildup *)
  1858. VAR x, y : LONGINT; c: WMComponents.VisualComponent;
  1859. rect:WMRectangles.Rectangle; id:ARRAY 64 OF CHAR; b:BOOLEAN;
  1860. BEGIN
  1861. ASSERT(component # NIL);
  1862. IF (dragX < 0) OR (dragY < 0) THEN (*??*)
  1863. AddComponent(component, 0, 0);
  1864. ELSIF ~(component IS WMComponents.Component) THEN (*??*)
  1865. ELSIF ~(component IS WMComponents.VisualComponent) THEN
  1866. ToComponentCoordinates(insertObjAt, dragX, dragY, x, y);
  1867. c:=FindPositionOwner(x,y);
  1868. c.AddContent(component);
  1869. (* button/event pairs are connected implicitly *)
  1870. IF (c IS WMStandardComponents.Button) & ((component IS WMStandardComponents.SystemCommand)OR(component IS WMStandardComponents.Event)) THEN
  1871. id:="";
  1872. IF ~component(WMComponents.Component).properties.GetPropertyValue("ID",id) OR (id="") THEN id:="X"; b:=component(WMComponents.Component).properties.SetPropertyValue("ID",id) END;
  1873. id:="";
  1874. IF ~ c.properties.GetPropertyValue("OnClickHandler",id) OR (id="") THEN id:="X Run"; b:=c.properties.SetPropertyValue("OnClickHandler",id) END;
  1875. END;
  1876. ELSE
  1877. ToComponentCoordinates(insertObjAt, dragX, dragY, x, y);
  1878. rect:=component(WMComponents.VisualComponent).bounds.Get();
  1879. c:=FindPositionOwner(x,y);
  1880. c.AddContent(component);
  1881. WMRectangles.MoveRel(rect, x-c.bounds.GetLeft(), y-c.bounds.GetTop());
  1882. component(WMComponents.VisualComponent).bounds.Set(rect);
  1883. component(WMComponents.VisualComponent).Invalidate;
  1884. END;
  1885. END DragAddComponent;
  1886. PROCEDURE DragDropped*(x, y : LONGINT; dragInfo : WMWindowManager.DragInfo);
  1887. VAR dc : WMRepositories.DropTarget;
  1888. BEGIN
  1889. IF takesFocus.Get() THEN
  1890. NEW(dc, SELF, DragAddComponent);
  1891. dragInfo.data := dc;
  1892. ConfirmDrag(TRUE, dragInfo);
  1893. ELSE
  1894. ConfirmDrag(FALSE, dragInfo);
  1895. END;
  1896. END DragDropped;
  1897. PROCEDURE UpdateFramePosition;
  1898. BEGIN
  1899. IF (owner # NIL) THEN
  1900. IF frame.IsValid() THEN
  1901. owner.UpdateFramePosition(frame.IsValid(), frame.bounds);
  1902. ELSE
  1903. owner.UpdateFramePosition(selectionFrame.IsValid(), selectionFrame.bounds);
  1904. END;
  1905. END;
  1906. END UpdateFramePosition;
  1907. PROCEDURE FindPositionOwner(x, y : LONGINT) : WMComponents.VisualComponent;
  1908. VAR vc, po, positionOwner : WMComponents.VisualComponent; bounds : WMRectangles.Rectangle;
  1909. BEGIN
  1910. vc := SELF;
  1911. positionOwner := GetPositionOwner(x, y);
  1912. WHILE (vc # positionOwner) DO
  1913. vc := positionOwner;
  1914. bounds := vc.bounds.Get();
  1915. po := vc.GetPositionOwner(x - bounds.l, y - bounds.t);
  1916. IF ~po.internal THEN positionOwner := po; ELSE positionOwner := vc; END;
  1917. END;
  1918. RETURN positionOwner;
  1919. END FindPositionOwner;
  1920. PROCEDURE GetComponentInfo(component : WMComponents.VisualComponent) : ComponentInfo;
  1921. VAR ci : ComponentInfo;
  1922. BEGIN
  1923. ASSERT(component # NIL);
  1924. ToMyCoordinates(component, 0, 0, ci.originX, ci.originY);
  1925. RETURN ci;
  1926. END GetComponentInfo;
  1927. (** Get bounds of component in ComponentEditor coordinates *)
  1928. PROCEDURE ToMyCoordinates(component : WMComponents.VisualComponent; x, y : LONGINT; VAR myX,myY : LONGINT);
  1929. VAR c : XML.Element; bounds : WMRectangles.Rectangle;
  1930. BEGIN
  1931. ASSERT(component # NIL);
  1932. myX := x; myY := y;
  1933. c := component.GetParent();
  1934. WHILE (c # NIL) & (c IS WMComponents.VisualComponent) & (c # panel) DO
  1935. bounds := c(WMComponents.VisualComponent).bounds.Get();
  1936. INC(myX, bounds.l);
  1937. INC(myY, bounds.t);
  1938. c := c.GetParent();
  1939. END;
  1940. END ToMyCoordinates;
  1941. PROCEDURE ToComponentCoordinates(component : WMComponents.VisualComponent; x, y : LONGINT; VAR cx, cy : LONGINT);
  1942. VAR c : XML.Element; bounds : WMRectangles.Rectangle;
  1943. BEGIN
  1944. ASSERT(component # NIL);
  1945. cx := x; cy := y;
  1946. c := component;
  1947. WHILE (c # NIL) & (c # panel) DO
  1948. IF (c IS WMComponents.VisualComponent) THEN
  1949. bounds := c(WMComponents.VisualComponent).bounds.Get();
  1950. DEC(cx, bounds.l);
  1951. DEC(cy, bounds.t);
  1952. END;
  1953. c := c.GetParent();
  1954. END;
  1955. END ToComponentCoordinates;
  1956. PROCEDURE DrawHorizontalLine(canvas : WMGraphics.Canvas; y, color : LONGINT);
  1957. BEGIN
  1958. canvas.Line(0, y, bounds.GetWidth(), y, color, WMGraphics.ModeSrcOverDst);
  1959. END DrawHorizontalLine;
  1960. PROCEDURE DrawVerticalLine(canvas : WMGraphics.Canvas; x, color : LONGINT);
  1961. BEGIN
  1962. canvas.Line(x, 0, x, bounds.GetHeight(), color, WMGraphics.ModeSrcOverDst);
  1963. END DrawVerticalLine;
  1964. PROCEDURE DrawFrames(canvas : WMGraphics.Canvas; parent : WMComponents.VisualComponent; ofsX, ofsY : LONGINT);
  1965. VAR c : XML.Content; vc : WMComponents.VisualComponent; rect : WMRectangles.Rectangle; color : LONGINT;
  1966. BEGIN
  1967. ASSERT((canvas # NIL) & (parent # NIL));
  1968. c := parent.GetFirst();
  1969. WHILE (c # NIL) DO
  1970. IF (c IS WMComponents.VisualComponent) THEN
  1971. vc := c (WMComponents.VisualComponent);
  1972. rect := vc.bounds.Get();
  1973. DrawFrames(canvas, vc, ofsX + rect.l, ofsY + rect.t);
  1974. IF ~vc.internal THEN
  1975. WMRectangles.MoveRel(rect, ofsX, ofsY);
  1976. IF selection.Contains(vc) THEN
  1977. color := WMGraphics.Magenta;
  1978. ELSIF (vc = insertObjAt) THEN
  1979. color := WMGraphics.Blue;
  1980. ELSIF vc.IsLocked() THEN
  1981. color := ColorLocked;
  1982. ELSE
  1983. color := WMGraphics.Green;
  1984. END;
  1985. DrawRectangle(canvas, rect.l, rect.t, rect.r, rect.b, color);
  1986. END;
  1987. END;
  1988. c := parent.GetNext(c);
  1989. END;
  1990. END DrawFrames;
  1991. PROCEDURE DrawHelperLines(canvas : WMGraphics.Canvas; parent : WMComponents.VisualComponent; level : LONGINT; ofsX, ofsY : LONGINT);
  1992. VAR c : XML.Content; vc : WMComponents.VisualComponent; rect : WMRectangles.Rectangle;
  1993. CONST Color = LONGINT(0A0A0FFFFH);
  1994. BEGIN
  1995. ASSERT((canvas # NIL) & (parent # NIL));
  1996. c := parent.GetFirst();
  1997. WHILE (c # NIL) DO
  1998. IF (c IS WMComponents.VisualComponent) THEN
  1999. vc := c (WMComponents.VisualComponent);
  2000. rect := vc.bounds.Get();
  2001. DrawHelperLines(canvas, vc, level + 1, ofsX + rect.l, ofsY + rect.t);
  2002. IF ~vc.internal THEN
  2003. DrawHorizontalLine(canvas, rect.t + ofsY, Color);
  2004. DrawHorizontalLine(canvas, rect.b + ofsY, Color);
  2005. DrawVerticalLine(canvas, rect.l + ofsX, Color);
  2006. DrawVerticalLine(canvas, rect.r + ofsX, Color);
  2007. END;
  2008. END;
  2009. c := parent.GetNext(c);
  2010. END;
  2011. END DrawHelperLines;
  2012. PROCEDURE DrawForeground*(canvas : WMGraphics.Canvas);
  2013. VAR rect : WMRectangles.Rectangle; e : XML.Element; x0, y0 : LONGINT;
  2014. BEGIN
  2015. DrawForeground^(canvas);
  2016. IF (mode = EditMode) THEN
  2017. IF showSnapGridI THEN
  2018. DrawSnapGrid(canvas);
  2019. END;
  2020. IF showHelperLinesI THEN
  2021. DrawHelperLines(canvas, panel, 0, 0, 0);
  2022. END;
  2023. IF showFramesI THEN
  2024. DrawFrames(canvas, panel, 0, 0);
  2025. END;
  2026. selectionFrame.Draw(canvas);
  2027. frame.Draw(canvas);
  2028. dragFrame.Draw(canvas);
  2029. IF (insertObjAt # NIL) THEN
  2030. rect := insertObjAt.bounds.Get();
  2031. ToMyCoordinates(insertObjAt, rect.l, rect.t, x0, y0);
  2032. DrawIndication(canvas, x0, y0, x0 + (rect.r - rect.l), y0 + (rect.b - rect.t), 4, 0FF50H);
  2033. END;
  2034. e := selection.GetParent();
  2035. IF (e # NIL) & (e IS WMComponents.VisualComponent) THEN
  2036. rect := e(WMComponents.VisualComponent).bounds.Get();
  2037. ToMyCoordinates(e(WMComponents.VisualComponent), rect.l, rect.t, x0, y0);
  2038. DrawIndication(canvas, x0, y0, x0 + (rect.r - rect.l), y0 + (rect.b - rect.t), 2, LONGINT(0FF000090H));
  2039. END;
  2040. END;
  2041. END DrawForeground;
  2042. PROCEDURE DrawSnapGrid(canvas : WMGraphics.Canvas);
  2043. VAR x, y, width, height, count, deltaN: LONGINT;
  2044. BEGIN
  2045. width := bounds.GetWidth();
  2046. height := bounds.GetHeight();
  2047. count := 0; deltaN := snapgrid.deltaX * snapgrid.nX;
  2048. x := snapgrid.offsetX;
  2049. WHILE (x < width) DO
  2050. canvas.Line(x, 0, x, height, LONGINT(0D0D0D0FFH), WMGraphics.ModeSrcOverDst);
  2051. INC(x, deltaN);
  2052. END;
  2053. count := 0; deltaN := snapgrid.deltaY * snapgrid.nY;
  2054. y := snapgrid.offsetY;
  2055. WHILE (y < height) DO
  2056. canvas.Line(0, y, width, y, LONGINT(0D0D0D0FFH), WMGraphics.ModeSrcOverDst);
  2057. INC(y, deltaN);
  2058. END;
  2059. x := snapgrid.offsetX;
  2060. WHILE (x < width) DO
  2061. y := snapgrid.offsetY;
  2062. WHILE (y < height) DO
  2063. canvas.SetPixel(x, y, WMGraphics.Black, WMGraphics.ModeSrcOverDst);
  2064. INC(y, snapgrid.deltaY);
  2065. END;
  2066. INC(x, snapgrid.deltaX);
  2067. END;
  2068. END DrawSnapGrid;
  2069. PROCEDURE DrawBackground*(canvas : WMGraphics.Canvas);
  2070. BEGIN
  2071. DrawBackground^(canvas);
  2072. IF (mode = EditMode) THEN
  2073. FillWithRectangles(canvas, GetClientRect(), 10, LONGINT(0F0F0F0FFH), WMGraphics.White);
  2074. IF showSnapGridI THEN
  2075. DrawSnapGrid(canvas);
  2076. END;
  2077. END;
  2078. END DrawBackground;
  2079. PROCEDURE Finalize*;
  2080. BEGIN
  2081. Finalize^;
  2082. state := State_Terminating;
  2083. timer.Wakeup;
  2084. BEGIN {EXCLUSIVE} AWAIT(state = State_Terminated); END;
  2085. END Finalize;
  2086. PROCEDURE UpdateState;
  2087. VAR p : ANY; vc : WMComponents.VisualComponent; alignment : LONGINT; ci : ComponentInfo;
  2088. BEGIN
  2089. (* p := selectedObj;
  2090. IF (p # NIL) & (p IS WMComponents.VisualComponent) THEN
  2091. vc := p(WMComponents.VisualComponent);
  2092. alignment := vc.alignment.Get();
  2093. IF (alignment # selectedAlignment) THEN
  2094. selectedAlignment := alignment;
  2095. activeFrameHandles := GetActiveFrameHandles(alignment);
  2096. selectedBounds := vc.bounds.Get();
  2097. ci := GetComponentInfo(vc);
  2098. WMRectangles.MoveRel(selectedBounds, ci.originX, ci.originY);
  2099. frame := selectedBounds; (* LOCKING!! *)
  2100. frameIsValid := TRUE;
  2101. Invalidate;
  2102. END;
  2103. END; *)
  2104. END UpdateState;
  2105. BEGIN {ACTIVE}
  2106. WHILE (state = State_Running) DO
  2107. timer.Sleep(200);
  2108. UpdateState;
  2109. END;
  2110. BEGIN {EXCLUSIVE} state := State_Terminated; END;
  2111. END ComponentEditor;
  2112. TYPE
  2113. EditWindow = OBJECT(WMComponents.FormWindow)
  2114. VAR
  2115. editor : ComponentEditor;
  2116. filename : Files.FileName;
  2117. owner : MainWindow;
  2118. modified : BOOLEAN;
  2119. id : LONGINT;
  2120. next : EditWindow;
  2121. PROCEDURE FocusGot*;
  2122. BEGIN
  2123. FocusGot^;
  2124. owner.SetActiveEditor(SELF);
  2125. editor.CheckSelection;
  2126. END FocusGot;
  2127. PROCEDURE Close*;
  2128. BEGIN
  2129. Close^;
  2130. owner.RemoveEditor(SELF);
  2131. END Close;
  2132. PROCEDURE &New(owner : MainWindow; width, height : LONGINT; alpha : BOOLEAN);
  2133. BEGIN
  2134. ASSERT(owner # NIL);
  2135. SELF.owner := owner;
  2136. Init(width, height, alpha);
  2137. NEW(editor); editor.alignment.Set(WMComponents.AlignClient);
  2138. editor.fillColor.Set(0);
  2139. editor.owner := owner;
  2140. editor.SetFocus;
  2141. filename := "";
  2142. next := NIL;
  2143. modified := FALSE;
  2144. id := GetId();
  2145. SetContent(editor);
  2146. editor.Invalidate;
  2147. END New;
  2148. END EditWindow;
  2149. TYPE
  2150. WindowArray = POINTER TO ARRAY OF EditWindow;
  2151. WindowList = OBJECT
  2152. VAR
  2153. windows : EditWindow;
  2154. PROCEDURE &Init;
  2155. BEGIN
  2156. windows := NIL;
  2157. END Init;
  2158. PROCEDURE IsContained(window : EditWindow) : BOOLEAN;
  2159. VAR w : EditWindow;
  2160. BEGIN
  2161. ASSERT(window # NIL);
  2162. w := windows;
  2163. WHILE (w # NIL) & (w # window) DO w := w.next; END;
  2164. RETURN (w # NIL);
  2165. END IsContained;
  2166. PROCEDURE Add(window : EditWindow);
  2167. BEGIN {EXCLUSIVE}
  2168. ASSERT(window # NIL);
  2169. IF ~IsContained(window) THEN
  2170. window.next := windows;
  2171. windows := window;
  2172. END;
  2173. END Add;
  2174. PROCEDURE Remove(window : EditWindow);
  2175. VAR w : EditWindow;
  2176. BEGIN {EXCLUSIVE}
  2177. ASSERT(window # NIL);
  2178. IF (windows = window) THEN
  2179. windows := window.next;
  2180. ELSE
  2181. w := windows;
  2182. WHILE (w # NIL) & (w.next # window) DO w := w.next; END;
  2183. IF (w # NIL) THEN
  2184. w.next := w.next.next;
  2185. END;
  2186. END;
  2187. window.next := NIL;
  2188. END Remove;
  2189. PROCEDURE Get(id : LONGINT) : EditWindow;
  2190. VAR w : EditWindow;
  2191. BEGIN {EXCLUSIVE}
  2192. w := windows; WHILE(w # NIL) & (w.id # id) DO w := w.next; END;
  2193. RETURN w;
  2194. END Get;
  2195. PROCEDURE GetAll() : WindowArray;
  2196. VAR result : WindowArray; w, temp : EditWindow; nofWindows, i, j : LONGINT;
  2197. BEGIN {EXCLUSIVE}
  2198. nofWindows := 0;
  2199. w := windows; WHILE (w # NIL) DO INC(nofWindows); w := w.next; END;
  2200. IF (nofWindows > 0) THEN
  2201. NEW(result, nofWindows);
  2202. w := windows; i := 0;
  2203. WHILE (w # NIL) DO
  2204. result[i] := w;
  2205. w := w.next; INC(i);
  2206. END;
  2207. (* sort by ID *)
  2208. FOR i := 0 TO LEN(result)-1 DO
  2209. FOR j := 0 TO LEN(result)-2 DO
  2210. IF (result[j].id > result[j + 1].id) THEN
  2211. temp := result[j + 1];
  2212. result[j + 1] := result[j];
  2213. result[j] := temp;
  2214. END;
  2215. END;
  2216. END;
  2217. ELSE
  2218. result := NIL;
  2219. END;
  2220. RETURN result;
  2221. END GetAll;
  2222. PROCEDURE SetActive(window : EditWindow);
  2223. VAR w, temp : EditWindow;
  2224. BEGIN {EXCLUSIVE}
  2225. ASSERT(window # NIL);
  2226. IF (window # windows) THEN
  2227. w := windows;
  2228. WHILE (w # NIL) & (w.next # window) DO w := w.next; END;
  2229. IF (w # NIL) THEN
  2230. temp := w.next;
  2231. w.next := w.next.next;
  2232. temp.next := windows;
  2233. windows := temp;
  2234. END;
  2235. END;
  2236. END SetActive;
  2237. PROCEDURE GetActive() : EditWindow;
  2238. BEGIN {EXCLUSIVE}
  2239. RETURN windows;
  2240. END GetActive;
  2241. END WindowList;
  2242. TYPE
  2243. MainWindow = OBJECT(WMComponents.FormWindow)
  2244. VAR
  2245. openBtn, saveBtn, addBtn, paintBtn, loadBtn, deleteBtn, toFrontBtn, getXmlBtn, storeBtn : WMStandardComponents.Button;
  2246. positionXLbl, positionYLbl : Indicator;
  2247. frameTopLeft, frameBottomRight, frameSize : Indicator;
  2248. lastFrame : WMRectangles.Rectangle; lastValid : BOOLEAN;
  2249. toggleEditModeBtn : WMStandardComponents.Button;
  2250. toggleSnapGridBtn, toggleHelperLinesBtn, toggleFramesBtn : WMStandardComponents.Button;
  2251. (* window hide/unhide buttons *)
  2252. toggleEditBtn, toggleComponentsBtn, toggleStructureBtn, togglePropertiesBtn : WMStandardComponents.Button;
  2253. componentTree : ComponentTree;
  2254. windowList : WindowList;
  2255. componentWindow : ComponentWindow;
  2256. componentTreeWindow : HelperWindow;
  2257. propertyWindow : PropertyWindow;
  2258. windowInfo : WMWindowManager.WindowInfo;
  2259. PROCEDURE &New(c : WMRestorable.Context);
  2260. VAR vc : WMComponents.VisualComponent;
  2261. BEGIN
  2262. IncCount;
  2263. IF (c # NIL) THEN
  2264. Init(c.r - c.l, c.b - c.t, FALSE);
  2265. ELSE
  2266. Init(WindowWidth, WindowHeight, FALSE);
  2267. END;
  2268. vc := CreateForm();
  2269. SetContent(vc);
  2270. SetTitle(Strings.NewString("GUI Editor"));
  2271. SetIcon(WMGraphics.LoadImage("WMBuilder.tar://WMBuilder.png", TRUE));
  2272. lastFrame := WMRectangles.MakeRect(-1, -1, -1, -1);
  2273. lastValid := FALSE;
  2274. NEW(windowList);
  2275. NEW(componentWindow, 250, 300, FALSE);
  2276. componentWindow.SetIcon(WMGraphics.LoadImage("WMBuilder.tar://repositories.png", TRUE));
  2277. WMWindowManager.ExtAddWindow(componentWindow, 20, 100, {WMWindowManager.FlagFrame, WMWindowManager.FlagHidden});
  2278. NEW(propertyWindow, 600, 400, FALSE);
  2279. propertyWindow.SetIcon(WMGraphics.LoadImage("WMBuilder.tar://properties.png", TRUE));
  2280. WMWindowManager.ExtAddWindow(propertyWindow, 600, 100, {WMWindowManager.FlagFrame, WMWindowManager.FlagHidden});
  2281. NEW(componentTree);
  2282. componentTree.fillColor.Set(WMGraphics.White);
  2283. componentTree.treeView.onClickNode.Add(HandleNodeClicked);
  2284. componentTree.treeView.SetExtContextMenuHandler(HandleNodeContextMenu);
  2285. NEW(componentTreeWindow, "Structure", componentTree, 20, 600, 250, 200, FALSE);
  2286. componentTreeWindow.SetIcon(WMGraphics.LoadImage("WMBuilder.tar://structure.png", TRUE));
  2287. IF (c # NIL) THEN
  2288. WMRestorable.AddByContext(SELF, c);
  2289. IF (c.appData # NIL) THEN
  2290. LoadWindows(c.appData(XML.Element));
  2291. END;
  2292. ELSE
  2293. WMWindowManager.DefaultAddWindow(SELF);
  2294. END;
  2295. END New;
  2296. PROCEDURE CreateForm() : WMComponents.VisualComponent;
  2297. VAR
  2298. statusbar, toolbar : WMStandardComponents.Panel;
  2299. panel : WMStandardComponents.Panel;
  2300. PROCEDURE NewButton(CONST caption, image : ARRAY OF CHAR) : WMStandardComponents.Button;
  2301. VAR button : WMStandardComponents.Button;
  2302. BEGIN
  2303. NEW(button); button.alignment.Set(WMComponents.AlignLeft);
  2304. button.isToggle.Set(TRUE);
  2305. button.bounds.SetWidth(32);
  2306. button.SetPressed(TRUE);
  2307. button.imageName.SetAOC(image);
  2308. button.onClick.Add(ButtonHandler);
  2309. toolbar.AddContent(button);
  2310. RETURN button;
  2311. END NewButton;
  2312. BEGIN
  2313. NEW(panel); panel.alignment.Set(WMComponents.AlignClient);
  2314. panel.fillColor.Set(WMGraphics.White);
  2315. NEW(statusbar); statusbar.alignment.Set(WMComponents.AlignBottom);
  2316. statusbar.bounds.SetHeight(20);
  2317. panel.AddContent(statusbar);
  2318. NEW(frameSize); frameSize.alignment.Set(WMComponents.AlignClient);
  2319. frameSize.SetCaption("w = - / h = -");
  2320. statusbar.AddContent(frameSize);
  2321. NEW(statusbar); statusbar.alignment.Set(WMComponents.AlignBottom);
  2322. statusbar.bounds.SetHeight(20);
  2323. panel.AddContent(statusbar);
  2324. NEW(frameTopLeft); frameTopLeft.alignment.Set(WMComponents.AlignLeft);
  2325. frameTopLeft.bounds.SetWidth(70);
  2326. frameTopLeft.SetCaption("(-, -)");
  2327. statusbar.AddContent(frameTopLeft);
  2328. NEW(frameBottomRight); frameBottomRight.alignment.Set(WMComponents.AlignLeft);
  2329. frameBottomRight.bounds.SetWidth(50);
  2330. frameBottomRight.SetCaption("(-, -)");
  2331. statusbar.AddContent(frameBottomRight);
  2332. NEW(statusbar); statusbar.alignment.Set(WMComponents.AlignBottom);
  2333. statusbar.bounds.SetHeight(20);
  2334. panel.AddContent(statusbar);
  2335. statusbar.AddContent(WMInspectionComponents.CreateLabel("X:", 20, WMComponents.AlignLeft));
  2336. positionXLbl := CreateIndicator("-", 25, WMComponents.AlignLeft);
  2337. statusbar.AddContent(positionXLbl);
  2338. statusbar.AddContent(WMInspectionComponents.CreateLabel("Y:", 20, WMComponents.AlignLeft));
  2339. positionYLbl := CreateIndicator("-", 25, WMComponents.AlignLeft);
  2340. statusbar.AddContent(positionYLbl);
  2341. NEW(toolbar); toolbar.alignment.Set(WMComponents.AlignBottom);
  2342. toolbar.bounds.SetHeight(32);
  2343. panel.AddContent(toolbar);
  2344. toggleSnapGridBtn := NewButton("Grid", "WMBuilder.tar://grid.png");
  2345. toggleHelperLinesBtn := NewButton("HelperLines", "WMBuilder.tar://lines.png");
  2346. toggleFramesBtn := NewButton("Frames", "WMBuilder.tar://frames.png");
  2347. NEW(toolbar); toolbar.alignment.Set(WMComponents.AlignBottom);
  2348. toolbar.bounds.SetHeight(32);
  2349. panel.AddContent(toolbar);
  2350. toggleEditBtn := NewButton("Edit", "WMBuilder.tar://edit.png");
  2351. toggleComponentsBtn := NewButton("Components", "WMBuilder.tar://repositories.png");
  2352. toggleStructureBtn := NewButton("Structure", "WMBuilder.tar://structure.png");
  2353. togglePropertiesBtn := NewButton("Prop", "WMBuilder.tar://properties.png");
  2354. NEW(openBtn); openBtn.alignment.Set(WMComponents.AlignTop);
  2355. openBtn.caption.SetAOC("Open ...");
  2356. openBtn.onClick.Add(HandleOpenBtn);
  2357. panel.AddContent(openBtn);
  2358. NEW(saveBtn); saveBtn.alignment.Set(WMComponents.AlignTop);
  2359. saveBtn.caption.SetAOC("Save as ...");
  2360. saveBtn.onClick.Add(HandleSaveBtn);
  2361. panel.AddContent(saveBtn);
  2362. NEW(addBtn); addBtn.alignment.Set(WMComponents.AlignTop);
  2363. addBtn.caption.SetAOC("Add");
  2364. addBtn.onClick.Add(HandleAddBtn);
  2365. panel.AddContent(addBtn);
  2366. NEW(deleteBtn); deleteBtn.alignment.Set(WMComponents.AlignTop);
  2367. deleteBtn.caption.SetAOC("Delete");
  2368. deleteBtn.onClick.Add(HandleDeleteBtn);
  2369. panel.AddContent(deleteBtn);
  2370. NEW(toFrontBtn); toFrontBtn.alignment.Set(WMComponents.AlignTop);
  2371. toFrontBtn.caption.SetAOC("ToFront");
  2372. toFrontBtn.onClick.Add(HandleToFrontBtn);
  2373. panel.AddContent(toFrontBtn);
  2374. NEW(getXmlBtn); getXmlBtn.alignment.Set(WMComponents.AlignTop);
  2375. getXmlBtn.caption.SetAOC("GetXML");
  2376. getXmlBtn.onClick.Add(HandleGetXmlBtn);
  2377. panel.AddContent(getXmlBtn);
  2378. NEW(loadBtn); loadBtn.alignment.Set(WMComponents.AlignTop);
  2379. loadBtn.caption.SetAOC("Load");
  2380. loadBtn.onClick.Add(HandleLoadBtn);
  2381. panel.AddContent(loadBtn);
  2382. NEW(storeBtn); storeBtn.alignment.Set(WMComponents.AlignTop);
  2383. storeBtn.caption.SetAOC("Store");
  2384. storeBtn.onClick.Add(HandleStoreBtn);
  2385. panel.AddContent(storeBtn);
  2386. NEW(paintBtn); paintBtn.alignment.Set(WMComponents.AlignTop);
  2387. paintBtn.caption.SetAOC("Paint");
  2388. paintBtn.isToggle.Set(TRUE);
  2389. paintBtn.SetPressed(FALSE);
  2390. paintBtn.onClick.Add(HandlePaintBtn);
  2391. panel.AddContent(paintBtn);
  2392. NEW(toggleEditModeBtn); toggleEditModeBtn.alignment.Set(WMComponents.AlignTop);
  2393. toggleEditModeBtn.caption.SetAOC("Edit Mode");
  2394. toggleEditModeBtn.onClick.Add(HandleToggleEditModeBtn);
  2395. toggleEditModeBtn.isToggle.Set(TRUE);
  2396. toggleEditModeBtn.SetPressed(TRUE);
  2397. panel.AddContent(toggleEditModeBtn);
  2398. RETURN panel;
  2399. END CreateForm;
  2400. PROCEDURE UpdateInfo;
  2401. VAR i, j : LONGINT; windows : WindowArray; focusWindow : EditWindow;
  2402. BEGIN
  2403. FOR i := 0 TO LEN(windowInfo.openDocuments)-1 DO windowInfo.openDocuments[i].name := ""; END;
  2404. windowInfo.handleDocumentInfo := HandleDocumentInfo;
  2405. windowInfo.vc.generator := NIL;
  2406. windows := windowList.GetAll();
  2407. IF (windows # NIL) THEN
  2408. focusWindow := windowList.GetActive();
  2409. j := 0;
  2410. FOR i := 0 TO LEN(windows)-1 DO
  2411. IF (j < LEN(windowInfo.openDocuments)) THEN
  2412. windowInfo.openDocuments[j].id := windows[i].id;
  2413. COPY(windows[i].filename, windowInfo.openDocuments[j].name);
  2414. COPY(windows[i].filename, windowInfo.openDocuments[j].fullname);
  2415. windowInfo.openDocuments[j].modified := windows[i].modified;
  2416. windowInfo.openDocuments[j].hasFocus := windows[i] = focusWindow;
  2417. INC(j);
  2418. END;
  2419. END;
  2420. END;
  2421. SetInfo(windowInfo);
  2422. END UpdateInfo;
  2423. PROCEDURE HandleDocumentInfo(CONST info : WMWindowManager.DocumentInfo; new : BOOLEAN; VAR res : WORD);
  2424. VAR w : EditWindow;
  2425. BEGIN
  2426. w := windowList.Get(info.id);
  2427. IF (w # NIL) THEN
  2428. SetActiveEditor(w);
  2429. manager.ToFront(w);
  2430. manager.SetFocus(w);
  2431. END;
  2432. END HandleDocumentInfo;
  2433. PROCEDURE SetActiveEditor(window : EditWindow);
  2434. BEGIN
  2435. ASSERT(window # NIL);
  2436. windowList.SetActive(window);
  2437. componentTree.SetComponent(window.editor.panel, window.editor.selection);
  2438. toggleSnapGridBtn.SetPressed(window.editor.showSnapGrid.Get());
  2439. toggleHelperLinesBtn.SetPressed(window.editor.showHelperLines.Get());
  2440. toggleFramesBtn.SetPressed(window.editor.showFrames.Get());
  2441. toggleEditModeBtn.SetPressed(window.editor.GetMode() = EditMode);
  2442. UpdateInfo;
  2443. END SetActiveEditor;
  2444. PROCEDURE RemoveEditor(window : EditWindow);
  2445. VAR w : EditWindow; c : Repositories.Component; component : WMComponents.Component;
  2446. BEGIN
  2447. ASSERT(window # NIL);
  2448. windowList.Remove(window);
  2449. w := windowList.GetActive();
  2450. IF (w # NIL) THEN
  2451. toggleSnapGridBtn.SetPressed(w.editor.showSnapGrid.Get());
  2452. toggleHelperLinesBtn.SetPressed(w.editor.showHelperLines.Get());
  2453. toggleFramesBtn.SetPressed(w.editor.showFrames.Get());
  2454. componentTree.SetComponent(w.editor.panel, w.editor.selection);
  2455. component := NIL;
  2456. IF (w.editor.selection.NofComponents() = 1) THEN
  2457. c := w.editor.selection.GetFirst();
  2458. IF (c IS WMComponents.Component) THEN
  2459. component := c (WMComponents.Component);
  2460. END;
  2461. END;
  2462. propertyWindow.SetComponent(SELF, component);
  2463. ELSE
  2464. componentTree.SetComponent(NIL, NIL);
  2465. propertyWindow.SetComponent(SELF, NIL);
  2466. END;
  2467. UpdateInfo;
  2468. END RemoveEditor;
  2469. PROCEDURE ButtonHandler(sender, data : ANY);
  2470. VAR w : EditWindow;
  2471. BEGIN
  2472. w := windowList.GetActive();
  2473. IF (w # NIL) THEN
  2474. IF (sender = toggleEditBtn) THEN
  2475. manager.SetIsVisible(w, ~w.isVisible);
  2476. IF (w.isVisible) THEN manager.ToFront(w); END;
  2477. ELSIF (sender = toggleComponentsBtn) THEN
  2478. manager.SetIsVisible(componentWindow, ~componentWindow.isVisible);
  2479. IF (componentWindow.isVisible) THEN manager.ToFront(componentWindow); END;
  2480. ELSIF (sender = toggleStructureBtn) THEN
  2481. manager.SetIsVisible(componentTreeWindow, ~componentTreeWindow.isVisible);
  2482. IF (componentTreeWindow.isVisible) THEN manager.ToFront(componentTreeWindow); END;
  2483. ELSIF (sender = togglePropertiesBtn) THEN
  2484. manager.SetIsVisible(propertyWindow, ~propertyWindow.isVisible);
  2485. IF (propertyWindow.isVisible) THEN manager.ToFront(propertyWindow); END;
  2486. ELSIF (sender = toggleSnapGridBtn) THEN
  2487. w.editor.showSnapGrid.Set(~w.editor.showSnapGrid.Get());
  2488. ELSIF (sender = toggleHelperLinesBtn) THEN
  2489. w.editor.showHelperLines.Set(~w.editor.showHelperLines.Get());
  2490. ELSIF (sender = toggleFramesBtn) THEN
  2491. w.editor.showFrames.Set(~w.editor.showFrames.Get());
  2492. END;
  2493. END;
  2494. END ButtonHandler;
  2495. PROCEDURE HandleOpenBtn(sender, data : ANY);
  2496. VAR filename : Files.FileName; res: LONGINT; ignoreRes: WORD;
  2497. BEGIN
  2498. res := WMDialogs.QueryString("Open...", filename);
  2499. IF (res = WMDialogs.ResOk) THEN
  2500. Load(filename, ignoreRes);
  2501. END;
  2502. END HandleOpenBtn;
  2503. PROCEDURE HandleSaveBtn(sender, data : ANY);
  2504. VAR w : EditWindow; filename : Files.FileName; res : WORD;
  2505. BEGIN
  2506. w := windowList.GetActive();
  2507. IF (w # NIL) THEN
  2508. res := WMDialogs.QueryString("Save...", filename);
  2509. IF (res = WMDialogs.ResOk) THEN
  2510. Store(filename, w, res);
  2511. IF (res = 0) THEN
  2512. w.SetTitle(Strings.NewString(filename));
  2513. ELSE
  2514. WMDialogs.Error("Error", "Could not store");
  2515. END;
  2516. END;
  2517. ELSE
  2518. WMDialogs.Error("Error", "No active window");
  2519. END;
  2520. END HandleSaveBtn;
  2521. PROCEDURE HandleAddBtn(sender, data : ANY);
  2522. VAR c : Repositories.Component; w : EditWindow;
  2523. BEGIN
  2524. w := windowList.GetActive();
  2525. IF (w # NIL) THEN
  2526. c := componentWindow.GetSelectedComponent();
  2527. IF (c # NIL) THEN
  2528. w.editor.AddComponent(c, 0, 0);
  2529. componentTree.Refresh(NIL, NIL);
  2530. END;
  2531. END;
  2532. END HandleAddBtn;
  2533. PROCEDURE HandlePaintBtn(sender,data : ANY);
  2534. VAR w : EditWindow;
  2535. BEGIN
  2536. w := windowList.GetActive();
  2537. IF (w # NIL) THEN
  2538. w.editor.SetPaint(paintBtn.GetPressed());
  2539. END;
  2540. END HandlePaintBtn;
  2541. PROCEDURE HandleLoadBtn(sender, data : ANY);
  2542. VAR
  2543. c : Repositories.Component; width, height : LONGINT;
  2544. manager : WMWindowManager.WindowManager;
  2545. w : EditWindow;
  2546. BEGIN
  2547. w := windowList.GetActive();
  2548. IF (w # NIL) THEN
  2549. c := componentWindow.GetSelectedComponent();
  2550. IF (c # NIL) THEN
  2551. IF (c IS WMComponents.VisualComponent) THEN
  2552. width := c(WMComponents.VisualComponent).bounds.GetWidth();
  2553. height := c(WMComponents.VisualComponent).bounds.GetHeight();
  2554. IF (width < 20) THEN width := 640; END;
  2555. IF (height < 20) THEN height := 480; END;
  2556. w.editor.SetPanel(c(WMComponents.VisualComponent));
  2557. manager := WMWindowManager.GetDefaultManager();
  2558. manager.SetWindowSize(w, width, height);
  2559. ELSE
  2560. WMDialogs.Error("Error", "Can only load visual components");
  2561. END;
  2562. ELSE
  2563. WMDialogs.Error("Error", "Could not load component");
  2564. END;
  2565. END;
  2566. END HandleLoadBtn;
  2567. PROCEDURE HandleDeleteBtn(sender, data : ANY);
  2568. VAR w : EditWindow;
  2569. BEGIN
  2570. w := windowList.GetActive();
  2571. IF (w # NIL) THEN
  2572. w.editor.Delete;
  2573. componentTree.Refresh(NIL, NIL);
  2574. END;
  2575. END HandleDeleteBtn;
  2576. PROCEDURE HandleToFrontBtn(sender, data : ANY);
  2577. VAR w : EditWindow;
  2578. BEGIN
  2579. w := windowList.GetActive();
  2580. IF (w # NIL) THEN
  2581. w.editor.ToFront;
  2582. componentTree.Refresh(NIL, NIL);
  2583. END;
  2584. END HandleToFrontBtn;
  2585. PROCEDURE HandleGetXmlBtn(sender, data : ANY);
  2586. VAR w : EditWindow; writer : WMUtilities.WindowWriter;
  2587. BEGIN
  2588. w := windowList.GetActive();
  2589. IF (w # NIL) THEN
  2590. NEW(writer, "GUI Builder XML", 640, 480, FALSE);
  2591. IF (w.editor.insertObjAt # NIL) THEN
  2592. w.editor.insertObjAt.Write(writer, NIL, 0);
  2593. ELSE
  2594. w.editor.panel.Write(writer, NIL, 0);
  2595. END;
  2596. writer.Update;
  2597. END;
  2598. END HandleGetXmlBtn;
  2599. PROCEDURE HandleStoreBtn(sender, data : ANY);
  2600. VAR
  2601. w : EditWindow;
  2602. repositoryName, componentName : ARRAY 64 OF CHAR; refNum : LONGINT;
  2603. name, filename : Files.FileName;
  2604. repository : Repositories.Repository;
  2605. res : WORD;
  2606. BEGIN
  2607. w := windowList.GetActive();
  2608. IF (w = NIL) THEN RETURN; END;
  2609. res := WMDialogs.QueryString("Store as...", name);
  2610. IF (res = WMDialogs.ResOk) THEN
  2611. IF Repositories.SplitName(name, repositoryName, componentName, refNum) THEN
  2612. repository := Repositories.ThisRepository(repositoryName);
  2613. IF (repository = NIL) THEN
  2614. res := WMDialogs.Confirmation("Please choose...", "Repository not found, create new repository?");
  2615. IF (res = WMDialogs.ResYes) THEN
  2616. COPY(repositoryName, filename); Strings.Append(filename, "."); Strings.Append(filename, Repositories.DefaultFileExtension);
  2617. Repositories.CreateRepository(filename, res);
  2618. IF (res = Repositories.Ok) THEN
  2619. repository := Repositories.ThisRepository(repositoryName);
  2620. ELSE
  2621. WMDialogs.Error("Error", "Could not create repository");
  2622. END;
  2623. END;
  2624. END;
  2625. IF (repository # NIL) THEN
  2626. IF (w.editor.insertObjAt # NIL) THEN
  2627. repository.PutComponent(w.editor.insertObjAt, componentName, refNum, res);
  2628. ELSE
  2629. repository.PutComponent(w.editor.panel, componentName, refNum, res);
  2630. END;
  2631. IF (res = Repositories.Ok) THEN
  2632. repository.UnbindComponent(componentName, refNum, res);
  2633. IF (res # Repositories.Ok) THEN
  2634. WMDialogs.Warning("Warning", "Could not unbind component from repository...");
  2635. END;
  2636. ELSE
  2637. WMDialogs.Error("Error", "Could not put component into repository");
  2638. END;
  2639. END;
  2640. ELSE
  2641. WMDialogs.Error("Error", "Expected repositoryName:componentName:refNum");
  2642. END;
  2643. END;
  2644. END HandleStoreBtn;
  2645. PROCEDURE HandleToggleEditModeBtn(sender, data : ANY);
  2646. VAR w : EditWindow; mode : LONGINT;
  2647. BEGIN
  2648. w := windowList.GetActive();
  2649. IF (w # NIL) THEN
  2650. IF (sender = toggleEditModeBtn) THEN
  2651. mode := w.editor.GetMode();
  2652. IF (mode = EditMode) THEN mode := UseMode; ELSE mode := EditMode; END;
  2653. toggleEditModeBtn.SetPressed(mode = EditMode);
  2654. w.editor.SetMode(mode);
  2655. END;
  2656. END;
  2657. END HandleToggleEditModeBtn;
  2658. PROCEDURE HandleNodeClicked(sender, data : ANY);
  2659. VAR w : EditWindow; ptr : ANY;
  2660. BEGIN
  2661. w := windowList.GetActive();
  2662. IF (w # NIL) & (data # NIL) & (data IS WMTrees.TreeNode) THEN
  2663. componentTree.tree.Acquire;
  2664. ptr := componentTree.tree.GetNodeData(data(WMTrees.TreeNode));
  2665. componentTree.tree.Release;
  2666. IF (ptr # NIL) & (ptr IS Repositories.Component) THEN
  2667. w.editor.Select(ptr(Repositories.Component));
  2668. END;
  2669. END;
  2670. END HandleNodeClicked;
  2671. PROCEDURE HandleNodeContextMenu(sender : ANY; x, y : LONGINT);
  2672. VAR w : EditWindow; node : WMTrees.TreeNode; ptr : ANY;
  2673. BEGIN
  2674. w := windowList.GetActive();
  2675. IF (w # NIL) THEN
  2676. componentTree.treeView.Acquire;
  2677. node := componentTree.treeView.GetNodeAtPos(x, y);
  2678. componentTree.tree.Acquire;
  2679. IF (node # NIL) THEN
  2680. ptr := componentTree.tree.GetNodeData(node);
  2681. END;
  2682. componentTree.tree.Release;
  2683. componentTree.treeView.Release;
  2684. IF (ptr # NIL) & (ptr IS WMComponents.VisualComponent) THEN
  2685. w.editor.SelectInsertAtObj(ptr(WMComponents.VisualComponent));
  2686. END;
  2687. END;
  2688. END HandleNodeContextMenu;
  2689. PROCEDURE UpdateCursorPosition(x, y : LONGINT);
  2690. VAR nbr : ARRAY 16 OF CHAR;
  2691. BEGIN
  2692. IF (x # Invalid) THEN Strings.IntToStr(x, nbr); ELSE nbr := "-"; END;
  2693. positionXLbl.SetCaption(nbr);
  2694. IF (y # Invalid) THEN Strings.IntToStr(y, nbr); ELSE nbr := "-"; END;
  2695. positionYLbl.SetCaption(nbr);
  2696. END UpdateCursorPosition;
  2697. PROCEDURE UpdateFramePosition(valid : BOOLEAN; frame : WMRectangles.Rectangle);
  2698. VAR string : ARRAY 32 OF CHAR;
  2699. PROCEDURE AppendNumber(VAR string : ARRAY OF CHAR; number : LONGINT);
  2700. VAR nbr : ARRAY 8 OF CHAR;
  2701. BEGIN
  2702. Strings.IntToStr(number, nbr);
  2703. Strings.Append(string, nbr);
  2704. END AppendNumber;
  2705. BEGIN
  2706. IF ~WMRectangles.IsEqual(lastFrame, frame) OR (lastValid # valid) THEN
  2707. IF valid THEN
  2708. IF (lastFrame.l # frame.l) OR (lastFrame.t # frame.t) THEN
  2709. string := "("; AppendNumber(string, frame.l); Strings.Append(string, ", "); AppendNumber(string, frame.t); Strings.Append(string, ")");
  2710. frameTopLeft.SetCaption(string);
  2711. END;
  2712. IF (lastFrame.r # frame.r) OR (lastFrame.b # frame.b) THEN
  2713. string := "("; AppendNumber(string, frame.r); Strings.Append(string, ", "); AppendNumber(string, frame.b); Strings.Append(string, ")");
  2714. frameBottomRight.SetCaption(string);
  2715. END;
  2716. IF (lastFrame.r - lastFrame.l # frame.r - frame.l) OR (lastFrame.b - lastFrame.t # frame.b - frame.t) THEN
  2717. string := "w = "; AppendNumber(string, frame.r - frame.l); Strings.Append(string, ", h = "); AppendNumber(string, frame.b - frame.t);
  2718. frameSize.SetCaption(string);
  2719. END;
  2720. ELSE
  2721. frameTopLeft.SetCaption("(-, -)");
  2722. frameBottomRight.SetCaption("(-, -)");
  2723. frameSize.SetCaption("w = -, h = -");
  2724. END;
  2725. lastFrame := frame;
  2726. lastValid := valid;
  2727. END;
  2728. END UpdateFramePosition;
  2729. PROCEDURE Load(CONST filename : ARRAY OF CHAR; VAR res : WORD);
  2730. VAR window : EditWindow; content : XML.Content; panel : WMStandardComponents.Panel; width, height : LONGINT;
  2731. BEGIN
  2732. content := WMComponents.Load(filename);
  2733. IF (content # NIL) & (content IS WMStandardComponents.Panel) THEN
  2734. panel := content (WMStandardComponents.Panel);
  2735. width := panel.bounds.GetWidth(); height := panel.bounds.GetHeight();
  2736. IF (width > 0) & (height > 0) THEN
  2737. NEW(window, SELF, width, height, FALSE);
  2738. window.SetIcon(WMGraphics.LoadImage("WMBuilder.tar://edit.png", TRUE));
  2739. window.SetTitle(Strings.NewString(filename));
  2740. WMWindowManager.AddWindow(window, 100, 100);
  2741. windowList.Add(window);
  2742. window.editor.SetPanel(panel);
  2743. COPY(filename, window.filename);
  2744. SetActiveEditor(window);
  2745. ELSE
  2746. WMDialogs.Error("Error", "Expected valid width and height");
  2747. END;
  2748. res := 0;
  2749. ELSE
  2750. NEW(window, SELF, EditWindowWidth, EditWindowHeight, FALSE);
  2751. window.SetIcon(WMGraphics.LoadImage("WMBuilder.tar://edit.png", TRUE));
  2752. window.SetTitle(Strings.NewString(filename));
  2753. WMWindowManager.AddWindow(window, 100, 100);
  2754. COPY(filename, window.filename);
  2755. windowList.Add(window);
  2756. SetActiveEditor(window);
  2757. END;
  2758. END Load;
  2759. PROCEDURE Store(CONST filename : ARRAY OF CHAR; window : EditWindow; VAR res : WORD);
  2760. VAR file : Files.File; writer : Files.Writer;
  2761. BEGIN
  2762. ASSERT(window # NIL);
  2763. file := Files.New(filename);
  2764. IF (file # NIL) THEN
  2765. window.modified := FALSE;
  2766. NEW(writer, file, 0);
  2767. window.editor.panel.Write(writer, NIL, 0);
  2768. COPY(filename, window.filename);
  2769. writer.Update;
  2770. Files.Register(file);
  2771. res := 0;
  2772. UpdateInfo;
  2773. ELSE
  2774. res := 99;
  2775. END;
  2776. END Store;
  2777. PROCEDURE LoadWindows(data : XML.Element);
  2778. VAR c : XML.Content; e : XML.Element; s : Strings.String; bounds : WMRectangles.Rectangle; filename : Files.FileName; res : WORD;
  2779. BEGIN
  2780. ASSERT(data # NIL);
  2781. c := data.GetFirst();
  2782. WHILE (c # NIL) DO
  2783. IF (c IS XML.Element) THEN
  2784. e := c (XML.Element);
  2785. s := e.GetName();
  2786. IF (s # NIL) & (s^ = "Window") THEN
  2787. s := e.GetAttributeValue("l"); IF (s # NIL) THEN Strings.StrToInt(s^, bounds.l); END;
  2788. s := e.GetAttributeValue("t"); IF (s # NIL) THEN Strings.StrToInt(s^, bounds.t); END;
  2789. s := e.GetAttributeValue("r"); IF (s # NIL) THEN Strings.StrToInt(s^, bounds.r); END;
  2790. s := e.GetAttributeValue("b"); IF (s # NIL) THEN Strings.StrToInt(s^, bounds.b); END;
  2791. s := e.GetAttributeValue("file"); IF (s # NIL) THEN COPY(s^, filename); ELSE filename := "Unknown.wm"; END;
  2792. END;
  2793. Load(filename, res);
  2794. END;
  2795. c := data.GetNext(c);
  2796. END;
  2797. END LoadWindows;
  2798. PROCEDURE StoreWindows() : XML.Element;
  2799. VAR
  2800. windows : WindowArray; data, w : XML.Element;
  2801. string : ARRAY 32 OF CHAR; bounds : WMRectangles.Rectangle;
  2802. i : LONGINT;
  2803. BEGIN
  2804. windows := windowList.GetAll();
  2805. IF (windows # NIL) THEN
  2806. NEW(data); data.SetName("Data");
  2807. FOR i := 0 TO LEN(windows)-1 DO
  2808. bounds := windows[i].bounds;
  2809. NEW(w); w.SetName("Window");
  2810. Strings.IntToStr(bounds.l, string); w.SetAttributeValue("l", string);
  2811. Strings.IntToStr(bounds.t, string); w.SetAttributeValue("t", string);
  2812. Strings.IntToStr(bounds.r, string); w.SetAttributeValue("r", string);
  2813. Strings.IntToStr(bounds.b, string); w.SetAttributeValue("b", string);
  2814. w.SetAttributeValue("file", windows[i].filename);
  2815. data.AddContent(w);
  2816. END;
  2817. ELSE
  2818. data := NIL;
  2819. END;
  2820. RETURN data;
  2821. END StoreWindows;
  2822. PROCEDURE Handle*(VAR x : WMMessages.Message);
  2823. VAR data : WMRestorable.XmlElement;
  2824. BEGIN
  2825. IF (x.msgType = WMMessages.MsgExt) & (x.ext # NIL) THEN
  2826. IF (x.ext IS KillerMsg) THEN Close;
  2827. ELSIF (x.ext IS WMRestorable.Storage) THEN
  2828. data := StoreWindows();
  2829. x.ext(WMRestorable.Storage).Add("WMBuilder", "WMBuilder.Restore", SELF, data);
  2830. ELSE Handle^(x)
  2831. END
  2832. ELSE Handle^(x)
  2833. END
  2834. END Handle;
  2835. PROCEDURE Close*;
  2836. VAR windows : WindowArray; i : LONGINT;
  2837. BEGIN
  2838. windows := windowList.GetAll();
  2839. IF (windows # NIL) THEN
  2840. FOR i := 0 TO LEN(windows)-1 DO
  2841. windows[i].Close;
  2842. END;
  2843. END;
  2844. componentWindow.Close;
  2845. componentTreeWindow.Close;
  2846. propertyWindow.Close;
  2847. Close^;
  2848. DecCount;
  2849. END Close;
  2850. END MainWindow;
  2851. VAR
  2852. nofWindows, nextId : LONGINT;
  2853. StrComponentEditor : Strings.String;
  2854. (* cursors *)
  2855. leftLimit, topLeftLimit, topLimit, topRightLimit,
  2856. rightLimit, bottomRightLimit, bottomLimit, bottomLeftLimit, sizeLimit, crosshair : WMWindowManager.PointerInfo;
  2857. PROCEDURE CreateIndicator(CONST content : ARRAY OF CHAR; width, alignment : LONGINT) : Indicator;
  2858. VAR i : Indicator;
  2859. BEGIN
  2860. NEW(i); i.alignment.Set(alignment); i.bounds.SetWidth(width);
  2861. i.SetCaption(content);
  2862. RETURN i;
  2863. END CreateIndicator;
  2864. PROCEDURE Distance(x0, y0, x1, y1 : LONGINT) : REAL;
  2865. BEGIN
  2866. RETURN Math.sqrt((x0 - x1) * (x0 - x1) + (y0 - y1) * (y0 - y1));
  2867. END Distance;
  2868. PROCEDURE DrawDashedLine(canvas : WMGraphics.Canvas; xs, ys, xe, ye, color0, color1, width0, width1 : LONGINT);
  2869. VAR p0, p1, color, width : LONGINT;
  2870. BEGIN
  2871. ASSERT((width0 > 0) & (width1 > 0));
  2872. color := color0;
  2873. width := width0;
  2874. IF (xs = xe) THEN (* vertical line *)
  2875. p0 := ys;
  2876. WHILE (p0 <= ye) DO
  2877. p1 := p0 + width;
  2878. IF (p1 > ye) THEN p1 := ye; END;
  2879. canvas.Line(xs, p0, xs, p1, color, WMGraphics.ModeSrcOverDst);
  2880. IF (color = color0) THEN
  2881. color := color1; width := width1;
  2882. ELSE
  2883. color := color0; width := width0;
  2884. END;
  2885. p0 := p1 + 1;
  2886. END;
  2887. ELSIF (ys = ye) THEN (* horizontal line *)
  2888. p0 := xs;
  2889. WHILE (p0 <= xe) DO
  2890. p1 := p0 + width;
  2891. IF (p1 > xe) THEN p1 := xe; END;
  2892. canvas.Line(p0, ys, p1, ye, color, WMGraphics.ModeSrcOverDst);
  2893. IF (color = color0) THEN
  2894. color := color1; width := width1;
  2895. ELSE
  2896. color := color0; width := width0;
  2897. END;
  2898. p0 := p1 + 1;
  2899. END;
  2900. ELSE
  2901. HALT(99); (* only works for horizontal or vertical lines! *)
  2902. END;
  2903. END DrawDashedLine;
  2904. PROCEDURE DrawRectangle(canvas: WMGraphics.Canvas; xs, ys, xe, ye, color: LONGINT);
  2905. BEGIN
  2906. canvas.Line(xs, ys, xs, ye, color, WMGraphics.ModeSrcOverDst);
  2907. canvas.Line(xs, ys, xe, ys, color, WMGraphics.ModeSrcOverDst);
  2908. canvas.Line(xe, ys, xe, ye, color, WMGraphics.ModeSrcOverDst);
  2909. canvas.Line(xs, ye, xe, ye, color, WMGraphics.ModeSrcOverDst);
  2910. END DrawRectangle;
  2911. PROCEDURE DrawDashedRectangle(canvas : WMGraphics.Canvas; xs, ys, xe, ye, color0, color1, width0, width1 : LONGINT);
  2912. BEGIN
  2913. DrawDashedLine(canvas, xs, ys, xs, ye, color0, color1, width0, width1);
  2914. DrawDashedLine(canvas, xs, ys, xe, ys, color0, color1, width0, width1);
  2915. DrawDashedLine(canvas, xe, ys, xe, ye, color0, color1, width0, width1);
  2916. DrawDashedLine(canvas, xs, ye, xe, ye, color0, color1, width0, width1);
  2917. END DrawDashedRectangle;
  2918. PROCEDURE DrawIndication(canvas: WMGraphics.Canvas; xs, ys, xe, ye , width, color : LONGINT);
  2919. CONST CornerWidth = 8; EdgeWidth = 20;
  2920. BEGIN
  2921. (* top-left *)
  2922. canvas.Fill(WMRectangles.MakeRect(xs, ys, xs + width, ys + CornerWidth), color, WMGraphics.ModeSrcOverDst);
  2923. canvas.Fill(WMRectangles.MakeRect(xs, ys, xs + CornerWidth, ys + width), color, WMGraphics.ModeSrcOverDst);
  2924. (* top-right *)
  2925. canvas.Fill(WMRectangles.MakeRect(xe - width, ys, xe, ys + CornerWidth), color, WMGraphics.ModeSrcOverDst);
  2926. canvas.Fill(WMRectangles.MakeRect(xe - CornerWidth, ys, xe, ys + width), color, WMGraphics.ModeSrcOverDst);
  2927. (* bottom-left *)
  2928. canvas.Fill(WMRectangles.MakeRect(xs, ye - width, xs +CornerWidth, ye), color, WMGraphics.ModeSrcOverDst);
  2929. canvas.Fill(WMRectangles.MakeRect(xs, ye - CornerWidth, xs + width, ye), color, WMGraphics.ModeSrcOverDst);
  2930. (* bottom-right *)
  2931. canvas.Fill(WMRectangles.MakeRect(xe - CornerWidth, ye - width, xe, ye), color, WMGraphics.ModeSrcOverDst);
  2932. canvas.Fill(WMRectangles.MakeRect(xe - width, ye - CornerWidth, xe, ye), color, WMGraphics.ModeSrcOverDst);
  2933. IF (xe - xs > 50) THEN
  2934. (* top *)
  2935. canvas.Fill(WMRectangles.MakeRect(ENTIER((xs + xe) / 2) - EdgeWidth, ys, ENTIER((xs + xe) / 2) + EdgeWidth, ys + width), color, WMGraphics.ModeSrcOverDst);
  2936. (* bottom *)
  2937. canvas.Fill(WMRectangles.MakeRect(ENTIER((xs+xe)/2)-EdgeWidth, ye - width, ENTIER((xs+xe)/2)+EdgeWidth, ye), color, WMGraphics.ModeSrcOverDst);
  2938. END;
  2939. IF (ye - ys > 50) THEN
  2940. (* left *)
  2941. canvas.Fill(WMRectangles.MakeRect(xs, ENTIER((ys + ye) / 2) - EdgeWidth, xs + width, ENTIER((ys + ye) / 2) + EdgeWidth), color, WMGraphics.ModeSrcOverDst);
  2942. (* right *)
  2943. canvas.Fill(WMRectangles.MakeRect(xe - width, ENTIER((ys+ye)/2)-EdgeWidth, xe, ENTIER((ys+ye)/2)+EdgeWidth), color, WMGraphics.ModeSrcOverDst);
  2944. END;
  2945. END DrawIndication;
  2946. PROCEDURE FillWithRectangles(canvas : WMGraphics.Canvas; rectangle : WMRectangles.Rectangle; width : LONGINT; color1, color2 : LONGINT);
  2947. VAR column, row, nofColumns, nofRows : LONGINT; x, y : LONGINT; color : LONGINT;
  2948. BEGIN
  2949. nofColumns := (rectangle.r - rectangle.l) DIV width + 1;
  2950. nofRows := (rectangle.b - rectangle.t) DIV width + 1;
  2951. FOR column := 0 TO nofColumns - 1 DO
  2952. IF (column MOD 2 = 0) THEN color := color1; ELSE color := color2; END;
  2953. x := column * width;
  2954. FOR row := 0 TO nofRows - 1 DO
  2955. y := row * width;
  2956. canvas.Fill(WMRectangles.MakeRect(x, y, x + width, y + width), color, WMGraphics.ModeCopy);
  2957. IF (color = color1) THEN color := color2; ELSE color := color1; END;
  2958. END;
  2959. END;
  2960. END FillWithRectangles;
  2961. PROCEDURE ShowComponent*(component : WMComponents.Component);
  2962. VAR string : Strings.String;
  2963. BEGIN
  2964. IF (component # NIL) THEN
  2965. string := component.GetName();
  2966. IF (string # NIL) THEN KernelLog.String(string^); ELSE KernelLog.String("NoName"); END;
  2967. KernelLog.String(" [");
  2968. string := component.uid.Get();
  2969. IF (string # NIL) THEN KernelLog.String(string^); ELSE KernelLog.String("NIL"); END;
  2970. IF (component IS WMComponents.VisualComponent) THEN
  2971. KernelLog.String(", "); KernelLog.Boolean(component(WMComponents.VisualComponent).takesFocus.Get());
  2972. END;
  2973. KernelLog.String("]");
  2974. ELSE
  2975. KernelLog.String("NIL?");
  2976. END;
  2977. END ShowComponent;
  2978. PROCEDURE ShowRect*(CONST name : ARRAY OF CHAR; rect : WMRectangles.Rectangle);
  2979. BEGIN
  2980. KernelLog.String(name); KernelLog.String(": l=");
  2981. KernelLog.Int(rect.l, 0); KernelLog.String(", t="); KernelLog.Int(rect.t, 0); KernelLog.String(", r=");
  2982. KernelLog.Int(rect.r, 0); KernelLog.String(", b="); KernelLog.Int(rect.b, 0); KernelLog.String(" (w=");
  2983. KernelLog.Int(rect.r - rect.l, 0); KernelLog.String(", h="); KernelLog.Int(rect.b - rect.t, 0); KernelLog.String(")");
  2984. KernelLog.Ln;
  2985. END ShowRect;
  2986. PROCEDURE LabelComponent(vc : WMComponents.VisualComponent);
  2987. BEGIN
  2988. ASSERT(vc # NIL);
  2989. IF (vc IS WMStandardComponents.Button) THEN
  2990. IF (vc(WMStandardComponents.Button).caption.Get() = NIL) THEN
  2991. vc(WMStandardComponents.Button).caption.SetAOC("Button");
  2992. END;
  2993. ELSIF (vc IS WMStandardComponents.Label) THEN
  2994. IF (vc(WMStandardComponents.Label).caption.Get() = NIL) THEN
  2995. vc(WMStandardComponents.Label).caption.SetAOC("Label");
  2996. END;
  2997. ELSIF (vc IS WMStandardComponents.GroupPanel) THEN
  2998. IF (vc(WMStandardComponents.GroupPanel).caption.Get() = NIL) THEN
  2999. vc(WMStandardComponents.GroupPanel).caption.SetAOC("GroupPanel");
  3000. END;
  3001. END;
  3002. END LabelComponent;
  3003. PROCEDURE Open*(context : Commands.Context); (** {filename} ~ *)
  3004. VAR window : MainWindow; filename : Files.FileName; count: LONGINT; ignoreRes : WORD;
  3005. BEGIN
  3006. NEW(window, NIL);
  3007. count := 0;
  3008. WHILE context.arg.GetString(filename) DO
  3009. window.Load(filename, ignoreRes); INC(count)
  3010. END;
  3011. IF count = 0 THEN window.Load("untitled.wm", ignoreRes); END;
  3012. END Open;
  3013. PROCEDURE GenComponentEditor*(): XML.Element;
  3014. VAR editPanel: ComponentEditor;
  3015. BEGIN
  3016. NEW(editPanel); RETURN editPanel;
  3017. END GenComponentEditor;
  3018. PROCEDURE Restore*(context : WMRestorable.Context);
  3019. VAR w : MainWindow;
  3020. BEGIN
  3021. NEW(w, context)
  3022. END Restore;
  3023. PROCEDURE LoadCursors;
  3024. BEGIN
  3025. WMWindowManager.LoadCursor("WMBuilder.tar://leftlimit.png", 4, 14, leftLimit);
  3026. WMWindowManager.LoadCursor("WMBuilder.tar://topleftlimit.png", 7, 5, topLeftLimit);
  3027. WMWindowManager.LoadCursor("WMBuilder.tar://toplimit.png", 13, 3, topLimit);
  3028. WMWindowManager.LoadCursor("WMBuilder.tar://toprightlimit.png", 24, 5, topRightLimit);
  3029. WMWindowManager.LoadCursor("WMBuilder.tar://rightlimit.png", 27, 14, rightLimit);
  3030. WMWindowManager.LoadCursor("WMBuilder.tar://bottomrightlimit.png", 24, 26, bottomRightLimit);
  3031. WMWindowManager.LoadCursor("WMBuilder.tar://bottomlimit.png", 13, 28, bottomLimit);
  3032. WMWindowManager.LoadCursor("WMBuilder.tar://bottomleftlimit.png", 7, 26, bottomLeftLimit);
  3033. WMWindowManager.LoadCursor("WMBuilder.tar://sizelimit.png", 16, 17, sizeLimit);
  3034. WMWindowManager.LoadCursor("WMBuilder.tar://crosshair.png", 13, 12, crosshair);
  3035. END LoadCursors;
  3036. PROCEDURE LoadRepositories;
  3037. VAR ignore : Repositories.Repository;
  3038. BEGIN
  3039. ignore := Repositories.ThisRepository("Standard");
  3040. ignore := Repositories.ThisRepository("Models");
  3041. ignore := Repositories.ThisRepository("Shapes");
  3042. END LoadRepositories;
  3043. PROCEDURE GetId() : LONGINT;
  3044. BEGIN {EXCLUSIVE}
  3045. INC(nextId);
  3046. RETURN nextId;
  3047. END GetId;
  3048. PROCEDURE IncCount;
  3049. BEGIN {EXCLUSIVE}
  3050. INC(nofWindows)
  3051. END IncCount;
  3052. PROCEDURE DecCount;
  3053. BEGIN {EXCLUSIVE}
  3054. DEC(nofWindows)
  3055. END DecCount;
  3056. PROCEDURE Cleanup;
  3057. VAR die : KillerMsg;
  3058. msg : WMMessages.Message;
  3059. m : WMWindowManager.WindowManager;
  3060. BEGIN {EXCLUSIVE}
  3061. NEW(die);
  3062. msg.ext := die;
  3063. msg.msgType := WMMessages.MsgExt;
  3064. m := WMWindowManager.GetDefaultManager();
  3065. m.Broadcast(msg);
  3066. AWAIT(nofWindows = 0)
  3067. END Cleanup;
  3068. BEGIN
  3069. nofWindows := 0; nextId := 0;
  3070. StrComponentEditor := Strings.NewString("ComponentEditor");
  3071. LoadCursors;
  3072. LoadRepositories;
  3073. Modules.InstallTermHandler(Cleanup);
  3074. END WMBuilder.
  3075. WMBuilder.Open ~
  3076. System.Free WMBuilder WMInspector WMInspectionComponents ~
  3077. System.FreeDownTo WMBuilder ~
  3078. PC.Compile \s
  3079. Repositories.Mod WMRepositories.Mod
  3080. WMModels.Mod
  3081. WMInspectionComponents.Mod
  3082. WMBuilder.Mod
  3083. ~