Controllers.txt 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426
  1. MODULE Controllers;
  2. (* THIS IS TEXT COPY OF BlackBox 1.6-rc6 System/Mod/Controllers.odc *)
  3. (* DO NOT EDIT *)
  4. IMPORT Kernel, Services, Ports, Stores, Models, Views;
  5. CONST
  6. (** Forward target **)
  7. targetPath* = TRUE; frontPath* = FALSE;
  8. (** ScrollMsg.op **)
  9. decLine* = 0; incLine* = 1; decPage* = 2; incPage* = 3; gotoPos* = 4;
  10. (** PageMsg.op **)
  11. nextPageX* = 0; nextPageY* = 1; gotoPageX* = 2; gotoPageY* = 3;
  12. (** PollOpsMsg.valid, EditMsg.op **)
  13. cut* = 0; copy* = 1;
  14. pasteChar* = 2; (* pasteLChar* = 3; *) paste* = 4; (* pasteView* = 5; *)
  15. (** TrackMsg.modifiers, EditMsg.modifiers **)
  16. doubleClick* = 0; (** clicking history **)
  17. extend* = 1; modify* = 2; (** modifier keys **)
  18. (* extend = Sub.extend; modify = Sub.modify *)
  19. (** PollDropMsg.mark, PollDrop mark **)
  20. noMark* = FALSE; mark* = TRUE;
  21. (** PollDropMsg.show, PollDrop show **)
  22. hide* = FALSE; show* = TRUE;
  23. minVersion = 0; maxVersion = 0;
  24. TYPE
  25. (** messages **)
  26. Message* = Views.CtrlMessage;
  27. PollFocusMsg* = EXTENSIBLE RECORD (Message)
  28. focus*: Views.Frame (** OUT, preset to NIL **)
  29. END;
  30. PollSectionMsg* = RECORD (Message)
  31. focus*, vertical*: BOOLEAN; (** IN **)
  32. wholeSize*: INTEGER; (** OUT, preset to 1 **)
  33. partSize*: INTEGER; (** OUT, preset to 1 **)
  34. partPos*: INTEGER; (** OUT, preset to 0 **)
  35. valid*, done*: BOOLEAN (** OUT, preset to (FALSE, FALSE) **)
  36. END;
  37. PollOpsMsg* = RECORD (Message)
  38. type*: Stores.TypeName; (** OUT, preset to "" **)
  39. pasteType*: Stores.TypeName; (** OUT, preset to "" **)
  40. singleton*: Views.View; (** OUT, preset to NIL **)
  41. selectable*: BOOLEAN; (** OUT, preset to FALSE **)
  42. valid*: SET (** OUT, preset to {} **)
  43. END;
  44. ScrollMsg* = RECORD (Message)
  45. focus*, vertical*: BOOLEAN; (** IN **)
  46. op*: INTEGER; (** IN **)
  47. pos*: INTEGER; (** IN **)
  48. done*: BOOLEAN (** OUT, preset to FALSE **)
  49. END;
  50. PageMsg* = RECORD (Message)
  51. op*: INTEGER; (** IN **)
  52. pageX*, pageY*: INTEGER; (** IN **)
  53. done*, eox*, eoy*: BOOLEAN (** OUT, preset to (FALSE, FALSE, FALSE) **)
  54. END;
  55. TickMsg* = RECORD (Message)
  56. tick*: INTEGER (** IN **)
  57. END;
  58. MarkMsg* = RECORD (Message)
  59. show*: BOOLEAN; (** IN **)
  60. focus*: BOOLEAN (** IN **)
  61. END;
  62. SelectMsg* = RECORD (Message)
  63. set*: BOOLEAN (** IN **)
  64. END;
  65. RequestMessage* = ABSTRACT RECORD (Message)
  66. requestFocus*: BOOLEAN (** OUT, preset (by framework) to FALSE **)
  67. END;
  68. EditMsg* = RECORD (RequestMessage)
  69. op*: INTEGER; (** IN **)
  70. modifiers*: SET; (** IN, valid if op IN {pasteChar, pasteLchar} **)
  71. char*: CHAR; (** IN, valid if op = pasteChar **)
  72. view*: Views.View; w*, h*: INTEGER; (** IN, valid if op = paste **)
  73. (** OUT, valid if op IN {cut, copy} **)
  74. isSingle*: BOOLEAN; (** dito **)
  75. clipboard*: BOOLEAN (** IN, valid if op IN {cut, copy, paste} **)
  76. END;
  77. ReplaceViewMsg* = RECORD (RequestMessage)
  78. old*, new*: Views.View (** IN **)
  79. END;
  80. CursorMessage* = ABSTRACT RECORD (RequestMessage)
  81. x*, y*: INTEGER (** IN, needs translation when passed on **)
  82. END;
  83. PollCursorMsg* = RECORD (CursorMessage)
  84. cursor*: INTEGER; (** OUT, preset to Ports.arrowCursor **)
  85. modifiers*: SET (** IN **)
  86. END;
  87. TrackMsg* = RECORD (CursorMessage)
  88. modifiers*: SET (** IN **)
  89. END;
  90. WheelMsg* = RECORD (CursorMessage)
  91. done*: BOOLEAN; (** must be set if the message is handled **)
  92. op*, nofLines*: INTEGER;
  93. END;
  94. TransferMessage* = ABSTRACT RECORD (CursorMessage)
  95. source*: Views.Frame; (** IN, home frame of transfer originator, may be NIL if unknown **)
  96. sourceX*, sourceY*: INTEGER (** IN, reference point in source frame, defined if source # NIL **)
  97. END;
  98. PollDropMsg* = RECORD (TransferMessage)
  99. mark*: BOOLEAN; (** IN, request to mark drop target **)
  100. show*: BOOLEAN; (** IN, if mark then show/hide target mark **)
  101. type*: Stores.TypeName; (** IN, type of view to drop **)
  102. isSingle*: BOOLEAN; (** IN, view to drop is singleton **)
  103. w*, h*: INTEGER; (** IN, size of view to drop, may be 0, 0 **)
  104. rx*, ry*: INTEGER; (** IN, reference point in view **)
  105. dest*: Views.Frame (** OUT, preset to NIL, set if DropMsg is acceptable **)
  106. END;
  107. DropMsg* = RECORD (TransferMessage)
  108. view*: Views.View; (** IN, drop this *)
  109. isSingle*: BOOLEAN; (** IN, view to drop is singleton **)
  110. w*, h*: INTEGER; (** IN, proposed size *)
  111. rx*, ry*: INTEGER (** IN, reference point in view **)
  112. END;
  113. (** controllers **)
  114. Controller* = POINTER TO ABSTRACT RECORD (Stores.Store) END;
  115. (** forwarders **)
  116. Forwarder* = POINTER TO ABSTRACT RECORD
  117. next: Forwarder
  118. END;
  119. TrapCleaner = POINTER TO RECORD (Kernel.TrapCleaner) END;
  120. PathInfo = POINTER TO RECORD
  121. path: BOOLEAN; prev: PathInfo
  122. END;
  123. BalanceCheckAction = POINTER TO RECORD (Services.Action)
  124. wait: WaitAction
  125. END;
  126. WaitAction = POINTER TO RECORD (Services.Action)
  127. check: BalanceCheckAction
  128. END;
  129. VAR
  130. path-: BOOLEAN;
  131. list: Forwarder;
  132. cleaner: TrapCleaner;
  133. prevPath, cache: PathInfo;
  134. (** BalanceCheckAction **)
  135. PROCEDURE (a: BalanceCheckAction) Do;
  136. BEGIN
  137. Services.DoLater(a.wait, Services.resolution);
  138. ASSERT(prevPath = NIL, 100);
  139. END Do;
  140. PROCEDURE (a: WaitAction) Do;
  141. BEGIN
  142. Services.DoLater(a.check, Services.immediately)
  143. END Do;
  144. (** Cleaner **)
  145. PROCEDURE (c: TrapCleaner) Cleanup;
  146. BEGIN
  147. path := frontPath;
  148. prevPath := NIL
  149. END Cleanup;
  150. PROCEDURE NewPathInfo(): PathInfo;
  151. VAR c: PathInfo;
  152. BEGIN
  153. IF cache = NIL THEN NEW(c)
  154. ELSE c := cache; cache := cache.prev
  155. END;
  156. RETURN c
  157. END NewPathInfo;
  158. PROCEDURE DisposePathInfo(c: PathInfo);
  159. BEGIN
  160. c.prev := cache; cache := c
  161. END DisposePathInfo;
  162. (** Controller **)
  163. PROCEDURE (c: Controller) Internalize- (VAR rd: Stores.Reader), EXTENSIBLE;
  164. (** pre: ~c.init **)
  165. (** post: c.init **)
  166. VAR thisVersion: INTEGER;
  167. BEGIN
  168. c.Internalize^(rd);
  169. rd.ReadVersion(minVersion, maxVersion, thisVersion)
  170. END Internalize;
  171. PROCEDURE (c: Controller) Externalize- (VAR wr: Stores.Writer), EXTENSIBLE;
  172. (** pre: c.init **)
  173. BEGIN
  174. c.Externalize^(wr);
  175. wr.WriteVersion(maxVersion)
  176. END Externalize;
  177. (** Forwarder **)
  178. PROCEDURE (f: Forwarder) Forward* (target: BOOLEAN; VAR msg: Message), NEW, ABSTRACT;
  179. PROCEDURE (f: Forwarder) Transfer* (VAR msg: TransferMessage), NEW, ABSTRACT;
  180. PROCEDURE Register* (f: Forwarder);
  181. VAR t: Forwarder;
  182. BEGIN
  183. ASSERT(f # NIL, 20);
  184. t := list; WHILE (t # NIL) & (t # f) DO t := t.next END;
  185. IF t = NIL THEN f.next := list; list := f END
  186. END Register;
  187. PROCEDURE Delete* (f: Forwarder);
  188. VAR t: Forwarder;
  189. BEGIN
  190. ASSERT(f # NIL, 20);
  191. IF f = list THEN
  192. list := list.next
  193. ELSE
  194. t := list; WHILE (t # NIL) & (t.next # f) DO t := t.next END;
  195. IF t # NIL THEN t.next := f.next END
  196. END;
  197. f.next := NIL
  198. END Delete;
  199. PROCEDURE ForwardVia* (target: BOOLEAN; VAR msg: Message);
  200. VAR t: Forwarder;
  201. BEGIN
  202. t := list; WHILE t # NIL DO t.Forward(target, msg); t := t.next END
  203. END ForwardVia;
  204. PROCEDURE SetCurrentPath* (target: BOOLEAN);
  205. VAR p: PathInfo;
  206. BEGIN
  207. IF prevPath = NIL THEN Kernel.PushTrapCleaner(cleaner) END;
  208. p := NewPathInfo(); p.prev := prevPath; prevPath := p; p.path := path;
  209. path := target
  210. END SetCurrentPath;
  211. PROCEDURE ResetCurrentPath*;
  212. VAR p: PathInfo;
  213. BEGIN
  214. IF prevPath # NIL THEN (* otherwise trap cleaner may have already removed prefPath objects *)
  215. p := prevPath; prevPath := p.prev; path := p.path;
  216. IF prevPath = NIL THEN Kernel.PopTrapCleaner(cleaner) END;
  217. DisposePathInfo(p)
  218. END
  219. END ResetCurrentPath;
  220. PROCEDURE Forward* (VAR msg: Message);
  221. BEGIN
  222. ForwardVia(path, msg)
  223. END Forward;
  224. PROCEDURE PollOps* (VAR msg: PollOpsMsg);
  225. BEGIN
  226. msg.type := "";
  227. msg.pasteType := "";
  228. msg.singleton := NIL;
  229. msg.selectable := FALSE;
  230. msg.valid := {};
  231. Forward(msg)
  232. END PollOps;
  233. PROCEDURE PollCursor* (x, y: INTEGER; modifiers: SET; OUT cursor: INTEGER);
  234. VAR msg: PollCursorMsg;
  235. BEGIN
  236. msg.x := x; msg.y := y; msg.cursor := Ports.arrowCursor; msg.modifiers := modifiers;
  237. Forward(msg);
  238. cursor := msg.cursor
  239. END PollCursor;
  240. PROCEDURE Transfer* (x, y: INTEGER; source: Views.Frame; sourceX, sourceY: INTEGER; VAR msg: TransferMessage);
  241. VAR t: Forwarder;
  242. BEGIN
  243. ASSERT(source # NIL, 20);
  244. msg.x := x; msg.y := y;
  245. msg.source := source; msg.sourceX := sourceX; msg.sourceY := sourceY;
  246. t := list; WHILE t # NIL DO t.Transfer(msg); t := t.next END
  247. END Transfer;
  248. PROCEDURE PollDrop* (x, y: INTEGER;
  249. source: Views.Frame; sourceX, sourceY: INTEGER;
  250. mark, show: BOOLEAN;
  251. type: Stores.TypeName;
  252. isSingle: BOOLEAN;
  253. w, h, rx, ry: INTEGER;
  254. OUT dest: Views.Frame; OUT destX, destY: INTEGER);
  255. VAR msg: PollDropMsg;
  256. BEGIN
  257. ASSERT(source # NIL, 20);
  258. msg.mark := mark; msg.show := show; msg.type := type; msg.isSingle := isSingle;
  259. msg.w := w; msg.h := h; msg.rx := rx; msg.ry := ry; msg.dest := NIL;
  260. Transfer(x, y, source, sourceX, sourceY, msg);
  261. dest := msg.dest; destX := msg.x; destY := msg.y
  262. END PollDrop;
  263. PROCEDURE Drop* (x, y: INTEGER; source: Views.Frame; sourceX, sourceY: INTEGER;
  264. view: Views.View; isSingle: BOOLEAN; w, h, rx, ry: INTEGER);
  265. VAR msg: DropMsg;
  266. BEGIN
  267. ASSERT(source # NIL, 20); ASSERT(view # NIL, 21);
  268. msg.view := view; msg.isSingle := isSingle;
  269. msg.w := w; msg.h := h; msg.rx := rx; msg.ry := ry;
  270. Transfer(x, y, source, sourceX, sourceY, msg)
  271. END Drop;
  272. PROCEDURE PasteView* (view: Views.View; w, h: INTEGER; clipboard: BOOLEAN);
  273. VAR msg: EditMsg;
  274. BEGIN
  275. ASSERT(view # NIL, 20);
  276. msg.op := paste; msg.isSingle := TRUE;
  277. msg.clipboard := clipboard;
  278. msg.view := view; msg.w := w; msg.h := h;
  279. Forward(msg)
  280. END PasteView;
  281. PROCEDURE FocusFrame* (): Views.Frame;
  282. VAR msg: PollFocusMsg;
  283. BEGIN
  284. msg.focus := NIL; Forward(msg); RETURN msg.focus
  285. END FocusFrame;
  286. PROCEDURE FocusView* (): Views.View;
  287. VAR focus: Views.Frame;
  288. BEGIN
  289. focus := FocusFrame();
  290. IF focus # NIL THEN RETURN focus.view ELSE RETURN NIL END
  291. END FocusView;
  292. PROCEDURE FocusModel* (): Models.Model;
  293. VAR focus: Views.Frame;
  294. BEGIN
  295. focus := FocusFrame();
  296. IF focus # NIL THEN RETURN focus.view.ThisModel() ELSE RETURN NIL END
  297. END FocusModel;
  298. PROCEDURE HandleCtrlMsgs (op: INTEGER; f, g: Views.Frame; VAR msg: Message; VAR mark, front, req: BOOLEAN);
  299. (* g = f.up OR g = NIL *)
  300. CONST pre = 0; translate = 1; backoff = 2; final = 3;
  301. BEGIN
  302. CASE op OF
  303. pre:
  304. WITH msg: MarkMsg DO
  305. IF msg.show & (g # NIL) THEN mark := TRUE; front := g.front END
  306. | msg: RequestMessage DO
  307. msg.requestFocus := FALSE
  308. ELSE
  309. END
  310. | translate:
  311. WITH msg: CursorMessage DO
  312. msg.x := msg.x + f.gx - g.gx;
  313. msg.y := msg.y + f.gy - g.gy
  314. ELSE
  315. END
  316. | backoff:
  317. WITH msg: MarkMsg DO
  318. IF ~msg.show THEN mark := FALSE; front := FALSE END
  319. | msg: RequestMessage DO
  320. req := msg.requestFocus
  321. ELSE
  322. END
  323. | final:
  324. WITH msg: PollFocusMsg DO
  325. IF msg.focus = NIL THEN msg.focus := f END
  326. | msg: MarkMsg DO
  327. IF ~msg.show THEN mark := FALSE; front := FALSE END
  328. | msg: RequestMessage DO
  329. req := msg.requestFocus
  330. ELSE
  331. END
  332. END
  333. END HandleCtrlMsgs;
  334. PROCEDURE Init;
  335. VAR action: BalanceCheckAction; w: WaitAction;
  336. BEGIN
  337. Views.InitCtrl(HandleCtrlMsgs);
  338. NEW(cleaner);
  339. NEW(action); NEW(w); action.wait := w; w.check := action; Services.DoLater(action, Services.immediately);
  340. END Init;
  341. BEGIN
  342. Init
  343. END Controllers.