Selectors.txt 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. MODULE DevSelectors;
  2. (* THIS IS TEXT COPY OF BlackBox 1.6-rc6 Dev/Mod/Selectors.odc *)
  3. (* DO NOT EDIT *)
  4. IMPORT
  5. Ports, Stores, Models, Views, Controllers, Fonts, Properties, TextModels, TextViews, TextSetters;
  6. CONST
  7. left* = 1; middle* = 2; right* = 3;
  8. minVersion = 0; currentVersion = 0;
  9. changeSelectorsKey = "#Dev:Change Selectors";
  10. TYPE
  11. Selector* = POINTER TO RECORD (Views.View)
  12. position-: INTEGER; (* left, middle, right *)
  13. leftHidden: TextModels.Model; (* valid iff (position = left) *)
  14. rightHidden: TextModels.Model (* valid iff (position = left) *)
  15. END;
  16. Directory* = POINTER TO ABSTRACT RECORD END;
  17. StdDirectory = POINTER TO RECORD (Directory) END;
  18. VAR
  19. dir-, stdDir-: Directory;
  20. PROCEDURE (d: Directory) New* (position: INTEGER): Selector, NEW, ABSTRACT;
  21. PROCEDURE GetFirst (selector: Selector; OUT first: Selector; OUT pos: INTEGER);
  22. VAR c: Models.Context; rd: TextModels.Reader; v: Views.View; nest: INTEGER;
  23. BEGIN
  24. c := selector.context; first := NIL; pos := 0;
  25. WITH c: TextModels.Context DO
  26. IF selector.position = left THEN
  27. first := selector
  28. ELSE
  29. rd := c.ThisModel().NewReader(NIL); rd.SetPos(c.Pos());
  30. nest := 1; pos := 1; rd.ReadPrevView(v);
  31. WHILE (v # NIL) & (nest > 0) DO
  32. WITH v: Selector DO
  33. IF v.position = left THEN DEC(nest);
  34. IF nest = 0 THEN first := v END
  35. ELSIF v.position = right THEN INC(nest)
  36. ELSIF nest = 1 THEN INC(pos)
  37. END
  38. ELSE
  39. END;
  40. rd.ReadPrevView(v)
  41. END
  42. END
  43. ELSE (* selector not embedded in a text *)
  44. END;
  45. ASSERT((first = NIL) OR (first.position = left), 100)
  46. END GetFirst;
  47. PROCEDURE GetNext (rd: TextModels.Reader; OUT next: Selector);
  48. VAR nest: INTEGER; v: Views.View;
  49. BEGIN
  50. nest := 1; next := NIL; rd.ReadView(v);
  51. WHILE v # NIL DO
  52. WITH v: Selector DO
  53. IF v.position = left THEN INC(nest)
  54. ELSIF nest = 1 THEN next := v; RETURN
  55. ELSIF v.position = right THEN DEC(nest)
  56. END
  57. ELSE
  58. END;
  59. rd.ReadView(v)
  60. END
  61. END GetNext;
  62. PROCEDURE CalcSize (f: Selector; OUT w, h: INTEGER);
  63. VAR c: Models.Context; a: TextModels.Attributes; font: Fonts.Font; asc, dsc, fw: INTEGER;
  64. BEGIN
  65. c := f.context;
  66. IF (c # NIL) & (c IS TextModels.Context) THEN
  67. a := c(TextModels.Context).Attr();
  68. font := a.font
  69. ELSE font := Fonts.dir.Default();
  70. END;
  71. font.GetBounds(asc, dsc, fw);
  72. h := asc + dsc; w := 3 * h DIV 4
  73. END CalcSize;
  74. PROCEDURE GetSection (first: Selector; rd: TextModels.Reader; n: INTEGER; OUT name: ARRAY OF CHAR);
  75. VAR i, p0, p1: INTEGER; ch: CHAR; sel: Selector;
  76. BEGIN
  77. sel := first;
  78. IF first.leftHidden.Length() > 0 THEN
  79. rd := first.leftHidden.NewReader(rd); rd.SetPos(0);
  80. REPEAT p0 := rd.Pos(); GetNext(rd, sel); DEC(n) UNTIL (n < 0) OR (sel = NIL);
  81. IF sel = NIL THEN INC(n) END;
  82. p1 := rd.Pos() - 1
  83. END;
  84. IF n >= 0 THEN
  85. rd := first.context(TextModels.Context).ThisModel().NewReader(rd);
  86. rd.SetPos(first.context(TextModels.Context).Pos() + 1);
  87. REPEAT p0 := rd.Pos(); GetNext(rd, sel); DEC(n) UNTIL (n < 0) OR (sel = NIL) OR (sel.position = right);
  88. p1 := rd.Pos() - 1
  89. END;
  90. IF (n >= 0) & (first.rightHidden.Length() > 0) THEN
  91. rd := first.rightHidden.NewReader(rd); rd.SetPos(1);
  92. REPEAT p0 := rd.Pos(); GetNext(rd, sel); DEC(n) UNTIL (n < 0) OR (sel = NIL);
  93. p1 := rd.Pos() - 1;
  94. IF sel = NIL THEN p1 := first.rightHidden.Length() END
  95. END;
  96. IF n < 0 THEN
  97. rd.SetPos(p0); rd.ReadChar(ch); i := 0;
  98. WHILE (ch <= " ") & (rd.Pos() <= p1) DO rd.ReadChar(ch) END;
  99. WHILE (i < LEN(name) - 1) & (rd.Pos() <= p1) & (ch # 0X) DO
  100. IF ch >= " " THEN name[i] := ch; INC(i) END;
  101. rd.ReadChar(ch)
  102. END;
  103. WHILE (i > 0) & (name[i - 1] = " ") DO DEC(i) END;
  104. name[i] := 0X
  105. ELSE
  106. name := 7FX + ""
  107. END
  108. END GetSection;
  109. PROCEDURE ChangeSelector (first: Selector; rd: TextModels.Reader; selection: INTEGER);
  110. VAR pos, p0, len, s: INTEGER; text: TextModels.Model; sel: Selector;
  111. BEGIN
  112. text := rd.Base();
  113. pos := first.context(TextModels.Context).Pos() + 1;
  114. (* expand *)
  115. rd.SetPos(pos);
  116. REPEAT GetNext(rd, sel) UNTIL (sel = NIL) OR (sel.position = right);
  117. IF sel # NIL THEN
  118. len := first.rightHidden.Length();
  119. IF len > 0 THEN text.Insert(rd.Pos() - 1, first.rightHidden, 0, len) END;
  120. len := first.leftHidden.Length();
  121. IF len > 0 THEN text.Insert(pos, first.leftHidden, 0, len) END;
  122. IF selection # 0 THEN (* collapse *)
  123. rd.SetPos(pos); s := 0;
  124. REPEAT GetNext(rd, sel); INC(s) UNTIL (s = selection) OR (sel = NIL) OR (sel.position = right);
  125. IF (sel # NIL) & (sel.position = middle) THEN
  126. first.leftHidden.Insert(0, text, pos, rd.Pos());
  127. rd.SetPos(pos); GetNext(rd, sel);
  128. p0 := rd.Pos() - 1;
  129. WHILE (sel # NIL) & (sel.position # right) DO GetNext(rd, sel) END;
  130. IF sel # NIL THEN
  131. first.rightHidden.Insert(0, text, p0, rd.Pos() - 1)
  132. END
  133. END
  134. END
  135. END;
  136. rd.SetPos(pos)
  137. END ChangeSelector;
  138. PROCEDURE ChangeThis (
  139. text: TextModels.Model; rd, rd1: TextModels.Reader; title: ARRAY OF CHAR; selection: INTEGER
  140. );
  141. VAR v: Views.View; str: ARRAY 256 OF CHAR;
  142. BEGIN
  143. rd := text.NewReader(rd);
  144. rd.SetPos(0); rd.ReadView(v);
  145. WHILE v # NIL DO
  146. WITH v: Selector DO
  147. IF v.position = left THEN
  148. GetSection(v, rd1, 0, str);
  149. IF str = title THEN
  150. ChangeSelector(v, rd, selection)
  151. END;
  152. IF v.leftHidden.Length() > 0 THEN ChangeThis(v.leftHidden, NIL, rd1, title, selection) END;
  153. IF v.rightHidden.Length() > 0 THEN ChangeThis(v.rightHidden, NIL, rd1, title, selection) END
  154. END
  155. ELSE
  156. END;
  157. rd.ReadView(v)
  158. END
  159. END ChangeThis;
  160. PROCEDURE Change* (text: TextModels.Model; title: ARRAY OF CHAR; selection: INTEGER);
  161. VAR rd, rd1: TextModels.Reader; script: Stores.Operation;
  162. BEGIN
  163. rd := text.NewReader(NIL);
  164. rd1 := text.NewReader(NIL);
  165. Models.BeginModification(Models.clean, text);
  166. Models.BeginScript(text, changeSelectorsKey, script);
  167. ChangeThis(text, rd, rd1, title, selection);
  168. Models.EndScript(text, script);
  169. Models.EndModification(Models.clean, text);
  170. END Change;
  171. PROCEDURE ChangeTo* (text: TextModels.Model; title, entry: ARRAY OF CHAR);
  172. VAR rd, rd1: TextModels.Reader; str: ARRAY 256 OF CHAR; v: Views.View; sel: INTEGER;
  173. BEGIN
  174. rd := text.NewReader(NIL);
  175. rd1 := text.NewReader(NIL);
  176. rd.SetPos(0); rd.ReadView(v);
  177. WHILE v # NIL DO
  178. WITH v: Selector DO
  179. IF v.position = left THEN
  180. GetSection(v, rd1, 0, str);
  181. IF title = str THEN
  182. sel := 0;
  183. REPEAT
  184. INC(sel); GetSection(v, rd1, sel, str)
  185. UNTIL (str[0] = 7FX) OR (str = entry);
  186. IF str[0] # 7FX THEN
  187. Change(text, title, sel);
  188. RETURN
  189. END
  190. END
  191. END
  192. ELSE
  193. END;
  194. rd.ReadView(v)
  195. END
  196. END ChangeTo;
  197. PROCEDURE (selector: Selector) HandlePropMsg- (VAR msg: Properties.Message);
  198. VAR c: Models.Context; a: TextModels.Attributes; asc, w: INTEGER;
  199. BEGIN
  200. WITH msg: Properties.SizePref DO CalcSize(selector, msg.w, msg.h)
  201. | msg: Properties.ResizePref DO msg.fixed := TRUE;
  202. | msg: Properties.FocusPref DO msg.hotFocus := TRUE;
  203. | msg: TextSetters.Pref DO c := selector.context;
  204. IF (c # NIL) & (c IS TextModels.Context) THEN
  205. a := c(TextModels.Context).Attr();
  206. a.font.GetBounds(asc, msg.dsc, w)
  207. END
  208. ELSE (*selector.HandlePropMsg^(msg);*)
  209. END
  210. END HandlePropMsg;
  211. PROCEDURE Track (selector: Selector; f: Views.Frame; x, y: INTEGER; buttons: SET; VAR hit: BOOLEAN);
  212. VAR a: TextModels.Attributes; font: Fonts.Font; c: Models.Context;
  213. w, h, asc, dsc, fw: INTEGER; isDown, in, in0: BOOLEAN; modifiers: SET;
  214. BEGIN
  215. c := selector.context; hit := FALSE;
  216. WITH c: TextModels.Context DO
  217. a := c.Attr(); font := a.font;
  218. c.GetSize(w, h); in0 := FALSE;
  219. in := (0 <= x) & (x < w) & (0 <= y) & (y < h);
  220. REPEAT
  221. IF in # in0 THEN
  222. f.MarkRect(0, 0, w, h, Ports.fill, Ports.hilite, FALSE); in0 := in
  223. END;
  224. f.Input(x, y, modifiers, isDown);
  225. in := (0 <= x) & (x < w) & (0 <= y) & (y < h)
  226. UNTIL ~isDown;
  227. IF in0 THEN hit := TRUE;
  228. font.GetBounds(asc, dsc, fw);
  229. f.MarkRect(0, 0, w, asc + dsc, Ports.fill, Ports.hilite, FALSE);
  230. END
  231. ELSE
  232. END
  233. END Track;
  234. PROCEDURE (selector: Selector) HandleCtrlMsg* (
  235. f: Views.Frame; VAR msg: Views.CtrlMessage; VAR focus: Views.View
  236. );
  237. VAR hit: BOOLEAN; sel, pos: INTEGER; text: TextModels.Model; title: ARRAY 256 OF CHAR; first: Selector;
  238. BEGIN
  239. WITH msg: Controllers.TrackMsg DO
  240. IF selector.context IS TextModels.Context THEN
  241. Track(selector, f, msg.x, msg.y, msg.modifiers, hit);
  242. IF hit THEN
  243. text := selector.context(TextModels.Context).ThisModel();
  244. GetFirst(selector, first, pos);
  245. IF first # NIL THEN
  246. GetSection(first, NIL, 0, title);
  247. IF selector.position = middle THEN sel := pos ELSE sel := 0 END;
  248. Change(text, title, sel);
  249. text := selector.context(TextModels.Context).ThisModel();
  250. IF TextViews.FocusText() = text THEN
  251. pos := selector.context(TextModels.Context).Pos();
  252. TextViews.ShowRange(text, pos, pos+1, TRUE)
  253. END
  254. END
  255. END
  256. END
  257. | msg: Controllers.PollCursorMsg DO
  258. msg.cursor := Ports.refCursor;
  259. ELSE
  260. END
  261. END HandleCtrlMsg;
  262. PROCEDURE (selector: Selector) Restore* (f: Views.Frame; l, t, r, b: INTEGER);
  263. VAR w, h, d: INTEGER;
  264. BEGIN
  265. selector.context.GetSize(w, h);
  266. (*
  267. GetFirst(selector, first, pos);
  268. *)
  269. w := w - w MOD f.unit; d := 2 * f.dot;
  270. f.DrawLine(d, d, w - d, d, d, Ports.grey25);
  271. f.DrawLine(d, h - d, w - d, h - d, d, Ports.grey25);
  272. IF selector.position # right THEN f.DrawLine(d, d, d, h - d, d, Ports.grey25) END;
  273. IF selector.position # left THEN f.DrawLine(w - d, d, w - d, h - d, d, Ports.grey25) END
  274. END Restore;
  275. PROCEDURE (selector: Selector) CopyFromSimpleView- (source: Views.View);
  276. BEGIN
  277. (* selector.CopyFrom^(source); *)
  278. WITH source: Selector DO
  279. selector.position := source.position;
  280. IF source.leftHidden # NIL THEN
  281. selector.leftHidden := TextModels.CloneOf(source.leftHidden);
  282. selector.leftHidden.InsertCopy(0, source.leftHidden, 0, source.leftHidden.Length())
  283. END;
  284. IF source.rightHidden # NIL THEN
  285. selector.rightHidden := TextModels.CloneOf(source.rightHidden);
  286. selector.rightHidden.InsertCopy(0, source.rightHidden, 0, source.rightHidden.Length())
  287. END
  288. END
  289. END CopyFromSimpleView;
  290. PROCEDURE (selector: Selector) InitContext* (context: Models.Context);
  291. BEGIN
  292. selector.InitContext^(context);
  293. IF selector.position = left THEN
  294. WITH context: TextModels.Context DO
  295. IF selector.leftHidden = NIL THEN
  296. selector.leftHidden := TextModels.CloneOf(context.ThisModel());
  297. Stores.Join(selector, selector.leftHidden);
  298. END;
  299. IF selector.rightHidden = NIL THEN
  300. selector.rightHidden := TextModels.CloneOf(context.ThisModel());
  301. Stores.Join(selector, selector.rightHidden)
  302. END
  303. ELSE
  304. END
  305. END
  306. END InitContext;
  307. PROCEDURE (selector: Selector) Internalize- (VAR rd: Stores.Reader);
  308. VAR version: INTEGER; store: Stores.Store;
  309. BEGIN
  310. selector.Internalize^(rd);
  311. IF rd.cancelled THEN RETURN END;
  312. rd.ReadVersion(minVersion, currentVersion, version);
  313. IF rd.cancelled THEN RETURN END;
  314. rd.ReadInt(selector.position);
  315. rd.ReadStore(store);
  316. IF store # NIL THEN selector.leftHidden := store(TextModels.Model)
  317. ELSE selector.leftHidden := NIL
  318. END;
  319. rd.ReadStore(store);
  320. IF store # NIL THEN selector.rightHidden := store(TextModels.Model)
  321. ELSE selector.rightHidden := NIL
  322. END
  323. END Internalize;
  324. PROCEDURE (selector: Selector) Externalize- (VAR wr: Stores.Writer);
  325. BEGIN
  326. selector.Externalize^(wr);
  327. wr.WriteVersion(currentVersion);
  328. wr.WriteInt(selector.position);
  329. wr.WriteStore(selector.leftHidden);
  330. wr.WriteStore(selector.rightHidden)
  331. END Externalize;
  332. PROCEDURE (d: StdDirectory) New (position: INTEGER): Selector;
  333. VAR selector: Selector;
  334. BEGIN
  335. NEW(selector);
  336. selector.position := position;
  337. RETURN selector
  338. END New;
  339. PROCEDURE SetDir* (d: Directory);
  340. BEGIN
  341. ASSERT(d # NIL, 20);
  342. dir := d
  343. END SetDir;
  344. PROCEDURE DepositLeft*;
  345. BEGIN
  346. Views.Deposit(dir.New(left))
  347. END DepositLeft;
  348. PROCEDURE DepositMiddle*;
  349. BEGIN
  350. Views.Deposit(dir.New(middle))
  351. END DepositMiddle;
  352. PROCEDURE DepositRight*;
  353. BEGIN
  354. Views.Deposit(dir.New(right))
  355. END DepositRight;
  356. PROCEDURE InitMod;
  357. VAR d: StdDirectory;
  358. BEGIN
  359. NEW(d); dir := d; stdDir := d;
  360. END InitMod;
  361. BEGIN
  362. InitMod
  363. END DevSelectors.
  364. "Insert Left" "*F5" "DevSelectors.DepositLeft; StdCmds.PasteView" "StdCmds.PasteViewGuard"
  365. "Insert Middle" "*F6" "DevSelectors.DepositMiddle; StdCmds.PasteView" "StdCmds.PasteViewGuard"
  366. "Insert Right" "*F7" "DevSelectors.DepositRight; StdCmds.PasteView" "StdCmds.PasteViewGuard"