WMGrids.Mod 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938
  1. MODULE WMGrids; (** AUTHOR "TF"; PURPOSE "Generic grid component"; *)
  2. IMPORT
  3. Inputs, XML, WMComponents,
  4. WMStandardComponents, Strings, Graphics := WMGraphics, WMRectangles,
  5. WMProperties, WMEvents,
  6. WM := WMWindowManager;
  7. TYPE
  8. (* Local type - alias for convenience *)
  9. String = Strings.String;
  10. (* return the desired size of the cell. Only used for auto-sizing. *)
  11. MeasureCellProc* = PROCEDURE {DELEGATE} (x, y : LONGINT; VAR width, height : LONGINT);
  12. (** Draw the cell (from 0, 0 to w, h) into canvas. state may include ??? *)
  13. DrawCellProc* = PROCEDURE {DELEGATE} (canvas : Graphics.Canvas; w, h : LONGINT; state : SET; x, y : LONGINT);
  14. (** Return the number of cells spaned in x an d y direction. *)
  15. GetCellSpansProc* = PROCEDURE {DELEGATE} (x, y : LONGINT; VAR spanx, spany : LONGINT);
  16. GetCellStateProc* = PROCEDURE {DELEGATE} (x, y : LONGINT) : SET;
  17. Spacings* = POINTER TO ARRAY OF LONGINT;
  18. CONST
  19. CellHighlighted* = 0; CellSelected* = 1; CellFocused* = 2; CellFixed* = 3;
  20. GridSelectNone* = 0; (** not selectable *)
  21. GridSelectSingleCell* = 1; (** only a single cell can be selected *)
  22. GridSelectSingleCol* = 2; (** only a single column can be selected *)
  23. GridSelectSingleRow* = 3; (** only a single row can be selected *)
  24. GridSelectHorizontal = 4; (** horizontal strips can be selected *)
  25. GridSelectVertical = 5; (** vertical strips can be selected *)
  26. GridSelectCols* = 6; (** only columns can be selected *)
  27. GridSelectRows* = 7; (** only rows can be selected *)
  28. GridSelectBlock* = 8;
  29. CONST
  30. PixelRange = 2; (* sensitive pixels left and right of a column/row separation *)
  31. DragDist = 10;
  32. TYPE
  33. CellPos* = RECORD col*, row* : LONGINT END;
  34. CellPositionInfo* = OBJECT
  35. VAR
  36. pos* : CellPos;
  37. END CellPositionInfo;
  38. (** Generic grid component. Supports :
  39. Spacing : equal/variable row / column spacing
  40. Number of fixed rows/colums (Fixed cells may NOT span multiple colums or rows)
  41. Cells can span multiple rows and/or colums
  42. *)
  43. GenericGrid* = OBJECT(WMComponents.VisualComponent)
  44. VAR
  45. getCellSpans : GetCellSpansProc;
  46. drawCell : DrawCellProc;
  47. getCellState : GetCellStateProc;
  48. tableStart* : CellPos;
  49. state, tempState : Graphics.CanvasState;
  50. scrollx-, scrolly- : WMStandardComponents.Scrollbar;
  51. showScrollX-, showScrollY- : WMProperties.BooleanProperty; (* show scrollbars if needed *)
  52. showScrollXC, showScrollYC : BOOLEAN;
  53. alwaysShowScrollX-, alwaysShowScrollY- : WMProperties.BooleanProperty; (* always show scrollbars even if not needed, overruled by showScroll *)
  54. alwaysShowScrollXC, alwaysShowScrollYC : BOOLEAN;
  55. nofRows-, nofCols-, cellDist- : WMProperties.Int32Property;
  56. nofRowsC, nofColsC, cellDistC : LONGINT; (* internal count of rows and colums *)
  57. rowHeights, colWidths : Spacings; (* variable sizes of rows and cols *)
  58. fixedCols-, fixedRows- : WMProperties.Int32Property; (* number of cols/rows that are fixed *)
  59. fixedColsC, fixedRowsC : LONGINT; (* internal cache of the respective property values *)
  60. defaultColWidth-, defaultRowHeight- : WMProperties.Int32Property;
  61. defaultColWidthC, defaultRowHeightC : LONGINT; (* internal cache of the respective property values *)
  62. allowColResize-, allowRowResize- : WMProperties.BooleanProperty;
  63. (**
  64. * If set to TRUE,
  65. * - clicking on a cell which is not completely visible will scroll the grid so it's visible
  66. * - when dragging and the pointer leaves the visible part of the grid, the grid is scrolled
  67. * default : TRUE;
  68. *)
  69. adjustFocusPosition- : WMProperties.BooleanProperty;
  70. focus, focusCell, highlight : CellPos; (* focusCell is the master Cell of focus *)
  71. selectionMode : LONGINT;
  72. selStart, selEnd : CellPos;
  73. selA : CellPos;
  74. selecting : BOOLEAN;
  75. drag : BOOLEAN;
  76. pointerInside : BOOLEAN; (* the last position of the pointer is needed for correct highlighting when scrolling with kb *)
  77. lastPointerX, lastPointerY :LONGINT;
  78. wasSelected- : BOOLEAN;
  79. onSelect- : WMEvents.EventSource;
  80. onClick- : WMEvents.EventSource;
  81. onClickSelected- : WMEvents.EventSource;
  82. shiftDown : BOOLEAN;
  83. hasOldPointer : BOOLEAN;
  84. prevPointerInfo : WM.PointerInfo;
  85. (* drag cell spacing *)
  86. dragCellSpacingNr : LONGINT;
  87. dragCellSpacingPos : LONGINT;
  88. dragCellSpacingWidth : BOOLEAN;
  89. dragCellSpacingHeight : BOOLEAN;
  90. downX, downY : LONGINT;
  91. dragPossible : BOOLEAN;
  92. selectOnPointerOver : BOOLEAN;
  93. lastkeys : SET;
  94. PROCEDURE &Init*;
  95. BEGIN
  96. Init^;
  97. SetNameAsString(GSGenericGrid);
  98. takesFocus.Set(TRUE);
  99. NEW(scrollx); NEW(scrolly);
  100. AddInternalComponent(scrollx); AddInternalComponent(scrolly);
  101. scrollx.alignment.Set(WMComponents.AlignBottom);
  102. scrollx.vertical.Set(FALSE);
  103. scrolly.alignment.Set(WMComponents.AlignRight);
  104. scrolly.vertical.Set(TRUE);
  105. scrollx.onPositionChanged.Add(Scrolled);
  106. scrolly.onPositionChanged.Add(Scrolled);
  107. scrollx.pageSize.Set(1);
  108. scrolly.pageSize.Set(1);
  109. selectionMode := GridSelectSingleCell;
  110. selStart.col := -1; selStart.row := -1;
  111. selEnd.col := -1; selEnd.row := -1;
  112. highlight.col := -1; highlight.row := -1;
  113. (* properites *)
  114. NEW(defaultColWidth, defaultColWidthProto, NIL, NIL); properties.Add(defaultColWidth);
  115. NEW(defaultRowHeight, defaultRowHeightProto, NIL, NIL); properties.Add(defaultRowHeight);
  116. NEW(fixedCols, fixedColsProto, NIL, NIL); properties.Add(fixedCols);
  117. NEW(fixedRows, fixedRowsProto, NIL, NIL); properties.Add(fixedRows);
  118. NEW(allowColResize, allowColResizeProto, NIL, NIL); properties.Add(allowColResize);
  119. NEW(allowRowResize, allowRowResizeProto, NIL, NIL); properties.Add(allowRowResize);
  120. NEW(nofRows, nofRowsProto, NIL, NIL); properties.Add(nofRows);
  121. NEW(nofCols, nofColsProto, NIL, NIL); properties.Add(nofCols);
  122. NEW(cellDist, cellDistProto, NIL, NIL); properties.Add(cellDist);
  123. NEW(showScrollX, showScrollXProto, NIL, NIL); properties.Add(showScrollX);
  124. NEW(showScrollY, showScrollYProto, NIL, NIL); properties.Add(showScrollY);
  125. NEW(alwaysShowScrollX, alwaysShowScrollXProto, NIL, NIL); properties.Add(alwaysShowScrollX);
  126. NEW(alwaysShowScrollY, alwaysShowScrollYProto, NIL, NIL); properties.Add(alwaysShowScrollY);
  127. NEW(adjustFocusPosition, adjustFocusPositionProto, NIL, NIL); properties.Add(adjustFocusPosition);
  128. pointerInside := FALSE;
  129. selectOnPointerOver := FALSE;
  130. (* events *)
  131. NEW(onSelect, SELF, GSonSelect, GSonSelectInfo, SELF.StringToCompCommand); events.Add(onSelect);
  132. NEW(onClick, SELF, GSonClick, GSonClickInfo, SELF.StringToCompCommand); events.Add(onClick);
  133. NEW(onClickSelected, SELF, GSonClickSelected, GSonClickSelectedInfo, SELF.StringToCompCommand); events.Add(onClickSelected);
  134. END Init;
  135. PROCEDURE Initialize*; (*to do: drop this altogether*)
  136. BEGIN
  137. Initialize^;
  138. (*RecacheAllProperties*)
  139. END Initialize;
  140. PROCEDURE RecacheAllProperties;
  141. BEGIN
  142. defaultColWidthC := defaultColWidth.Get();
  143. defaultRowHeightC := defaultRowHeight.Get();
  144. fixedColsC := fixedCols.Get();
  145. fixedRowsC := fixedRows.Get();
  146. tableStart.row := Strings.Max(tableStart.row, fixedRowsC);
  147. tableStart.col := Strings.Max(tableStart.col, fixedColsC);
  148. nofRowsC := nofRows.Get();
  149. nofColsC := nofCols.Get();
  150. IF nofColsC = 1 THEN defaultColWidthC := bounds.GetWidth() END; (* list case *)
  151. cellDistC := cellDist.Get();
  152. showScrollXC := showScrollX.Get();
  153. showScrollYC := showScrollY.Get();
  154. alwaysShowScrollXC := alwaysShowScrollX.Get();
  155. alwaysShowScrollYC := alwaysShowScrollY.Get();
  156. CheckScrollbarsNeeded;
  157. AlignSubComponents
  158. END RecacheAllProperties;
  159. PROCEDURE RecacheProperties;
  160. BEGIN
  161. RecacheProperties^;
  162. RecacheAllProperties
  163. END RecacheProperties;
  164. PROCEDURE PropertyChanged*(sender, property : ANY);
  165. BEGIN
  166. RecacheAllProperties;
  167. Invalidate;
  168. PropertyChanged^(sender, property)
  169. END PropertyChanged;
  170. PROCEDURE GetColWidth*(i : LONGINT) : LONGINT;
  171. BEGIN
  172. CheckReadLock;
  173. IF colWidths = NIL THEN RETURN defaultColWidthC
  174. ELSIF (i < 0) OR (i > nofColsC) THEN RETURN 0
  175. ELSE
  176. IF i >= LEN(colWidths^) THEN RETURN defaultColWidthC ELSE RETURN colWidths[i] END
  177. END
  178. END GetColWidth;
  179. (** Set the width of columns. IF NIL, all columns have the default column width. If the spacings
  180. array is smaller than the number of columns, the additional columns have the default column width *)
  181. PROCEDURE SetColSpacings*(colWidths : Spacings);
  182. BEGIN
  183. Acquire;
  184. SELF.colWidths := colWidths;
  185. Invalidate();
  186. Release
  187. END SetColSpacings;
  188. (** returns a spacings array filled with the column width. The array contains only so many elements
  189. as the one set with SetColSpacings. The result is NIL, if not set with SetColSpacings *)
  190. PROCEDURE GetColSpacings*() : Spacings;
  191. VAR t : Spacings; i : LONGINT;
  192. BEGIN
  193. Acquire;
  194. IF colWidths # NIL THEN NEW(t, LEN(colWidths)); FOR i := 0 TO LEN(colWidths) - 1 DO t[i] := colWidths[i] END END;
  195. Release;
  196. RETURN t
  197. END GetColSpacings;
  198. (** Set the height of rows. IF NIL, all rows have the default row height. If the spacings
  199. array is smaller than the number of rows, the additional rows have the default row height *)
  200. PROCEDURE SetRowSpacings*(rowHeights : Spacings);
  201. BEGIN
  202. Acquire;
  203. SELF.rowHeights := rowHeights;
  204. Invalidate();
  205. Release
  206. END SetRowSpacings;
  207. (** returns a spacings array filled with the row heights. The array contains only so many elements
  208. as the one set with SetRowSpacings. The result is NIL, if not set with SetRowSpacings *)
  209. PROCEDURE GetRowSpacings*() : Spacings;
  210. VAR t : Spacings; i : LONGINT;
  211. BEGIN
  212. Acquire;
  213. IF rowHeights # NIL THEN NEW(t, LEN(rowHeights)); FOR i := 0 TO LEN(rowHeights) - 1 DO t[i] := rowHeights[i] END END;
  214. Release;
  215. RETURN t
  216. END GetRowSpacings;
  217. PROCEDURE SetSelectOnPointerOver*(select : BOOLEAN);
  218. BEGIN
  219. selectOnPointerOver := select;
  220. END SetSelectOnPointerOver;
  221. (** Scrollbars *)
  222. (** Define if the scrollbars should always be visible, if not needed. Overruled by ShowScrollbars *)
  223. PROCEDURE GetRowHeight*(i : LONGINT) : LONGINT;
  224. BEGIN
  225. CheckReadLock;
  226. IF rowHeights = NIL THEN RETURN defaultRowHeightC
  227. ELSIF (i < 0) OR (i > nofRowsC) THEN RETURN 0
  228. ELSE
  229. IF i >= LEN(rowHeights^) THEN RETURN defaultRowHeightC ELSE RETURN rowHeights[i] END
  230. END
  231. END GetRowHeight;
  232. PROCEDURE SetSelectionMode*(mode : LONGINT);
  233. BEGIN
  234. Acquire;
  235. IF mode # selectionMode THEN
  236. selectionMode := mode;
  237. Invalidate()
  238. END;
  239. Release
  240. END SetSelectionMode;
  241. PROCEDURE GetSelectionMode*():LONGINT;
  242. BEGIN
  243. RETURN selectionMode
  244. END GetSelectionMode;
  245. PROCEDURE SetDrawCellProc*(dcp :DrawCellProc);
  246. BEGIN
  247. Acquire;
  248. IF SELF.drawCell # dcp THEN
  249. SELF.drawCell := dcp;
  250. Invalidate()
  251. END;
  252. Release
  253. END SetDrawCellProc;
  254. PROCEDURE GetFixedPixels*(VAR w, h :LONGINT);
  255. VAR i : LONGINT;
  256. BEGIN
  257. w := 0; h := 0;
  258. FOR i := 0 TO fixedColsC - 1 DO INC(w, GetColWidth(i) + cellDistC) END;
  259. FOR i := 0 TO fixedRowsC - 1 DO INC(h, GetRowHeight(i) + cellDistC) END;
  260. END GetFixedPixels;
  261. PROCEDURE SetCellSpansProc*(gcsp : GetCellSpansProc); (* Dan *)
  262. BEGIN
  263. IF getCellSpans # gcsp THEN
  264. Acquire;
  265. getCellSpans := gcsp;
  266. Release
  267. END
  268. END SetCellSpansProc;
  269. PROCEDURE GetCellSpans(x, y : LONGINT; VAR spanx, spany : LONGINT);
  270. BEGIN
  271. IF getCellSpans # NIL THEN getCellSpans(x, y, spanx, spany)
  272. ELSE spanx := 1; spany := 1
  273. END
  274. END GetCellSpans;
  275. PROCEDURE IsSkipCell*(x, y : LONGINT) : BOOLEAN;
  276. VAR spanx, spany : LONGINT;
  277. BEGIN
  278. GetCellSpans(x, y, spanx, spany);
  279. RETURN (spanx = 0) OR (spany = 0)
  280. END IsSkipCell;
  281. PROCEDURE GetCellDimensions*(x, y : LONGINT; VAR width, height : LONGINT);
  282. VAR spanx, spany, i : LONGINT;
  283. BEGIN
  284. GetCellSpans(x, y, spanx, spany);
  285. width := -cellDistC; height := -cellDistC;
  286. FOR i := 0 TO spanx - 1 DO width := width + GetColWidth(x) + cellDistC END;
  287. FOR i := 0 TO spany - 1 DO height := height + GetRowHeight(y) + cellDistC END
  288. END GetCellDimensions;
  289. (* override by subclass *)
  290. PROCEDURE GetCellData*(col, row : LONGINT) : ANY;
  291. VAR position : CellPositionInfo;
  292. BEGIN
  293. NEW(position); position.pos.row := row; position.pos.col := col;
  294. RETURN position
  295. END GetCellData;
  296. PROCEDURE GetCellState(x, y : LONGINT) : SET;
  297. VAR state : SET;
  298. BEGIN
  299. IF getCellState # NIL THEN RETURN getCellState(x, y)
  300. ELSE
  301. state := {};
  302. IF (x = focus.col) & (y = focus.row) THEN state := state + {CellFocused} END;
  303. IF (x < fixedColsC) OR (y < fixedRowsC) THEN state := state + {CellFixed} END;
  304. CASE selectionMode OF
  305. | GridSelectSingleCell :
  306. IF (x = selStart.col) & (y = selStart.row) THEN state := state + {CellSelected} END;
  307. IF (x = highlight.col) & (y = highlight.row) THEN state := state + {CellHighlighted} END
  308. | GridSelectSingleCol, GridSelectCols :
  309. IF (x >= selStart.col) & (x <= selEnd.col) THEN state := state + {CellSelected} END;
  310. IF (x = highlight.col) THEN state := state + {CellHighlighted} END
  311. | GridSelectSingleRow, GridSelectRows :
  312. IF (y >= selStart.row) & (y <= selEnd.row) THEN state := state + {CellSelected} END;
  313. IF (y = highlight.row) THEN state := state + {CellHighlighted} END
  314. | GridSelectBlock, GridSelectHorizontal, GridSelectVertical :
  315. IF (x >= selStart.col) & (x <= selEnd.col) &(y >= selStart.row) & (y <= selEnd.row) THEN state := state + {CellSelected} END;
  316. IF (x = highlight.col) & (y = highlight.row) THEN state := state + {CellHighlighted} END;
  317. ELSE
  318. END;
  319. RETURN state
  320. END
  321. END GetCellState;
  322. (** col, row point to the master cell of (x, y). dx, dy are decreased by the respective decrement *)
  323. PROCEDURE FindMasterCell*(x, y : LONGINT; VAR col, row, xpos, ypos : LONGINT);
  324. VAR cw, ch : LONGINT;
  325. BEGIN
  326. col := x; row := y;
  327. GetCellSpans(col, row, cw, ch);
  328. WHILE (cw = 0) OR (ch = 0) DO
  329. IF cw = 0 THEN DEC(col); DEC(xpos, GetColWidth(col) + cellDistC) END;
  330. IF ch = 0 THEN DEC(row); DEC(ypos, GetRowHeight(row) + cellDistC) END;
  331. GetCellSpans(col, row, cw, ch)
  332. END
  333. END FindMasterCell;
  334. (* Find the cell at position x, y (also fixed cells are returned) *)
  335. PROCEDURE FindCellXY* (x, y : LONGINT; VAR col, row : LONGINT);
  336. VAR tx, ty, dummy : LONGINT;
  337. BEGIN
  338. GetFixedPixels(tx, ty);
  339. IF (x < tx) & (y < ty) THEN (* row and column fixed *)
  340. col := 0; row := 0; tx := 0; ty := 0;
  341. REPEAT tx := tx + GetColWidth(col) + cellDistC; INC(col) UNTIL (col >= fixedColsC) OR (tx >= x); DEC(col);
  342. REPEAT ty := ty + GetRowHeight(row) + cellDistC; INC(row) UNTIL (row >= fixedRowsC) OR (ty >= y); DEC(row);
  343. ELSIF (x < tx) THEN (* column fixed *)
  344. col := 0; row := tableStart.row; tx := 0;
  345. REPEAT tx := tx + GetColWidth(col) + cellDistC; INC(col) UNTIL (col >= fixedColsC) OR (tx >= x); DEC(col);
  346. REPEAT ty := ty + GetRowHeight(row) + cellDistC; INC(row) UNTIL (row >= nofRowsC) OR (ty >= y); DEC(row);
  347. ELSIF (y < ty) THEN (* row fixed *)
  348. col := tableStart.col; row := 0; ty := 0;
  349. REPEAT tx := tx + GetColWidth(col) + cellDistC; INC(col) UNTIL (col >= nofColsC) OR (tx >= x); DEC(col);
  350. REPEAT ty := ty + GetRowHeight(row) + cellDistC; INC(row) UNTIL (row >= fixedRowsC) OR (ty >= y); DEC(row);
  351. ELSE (* normal cells *)
  352. col := tableStart.col; row := tableStart.row;
  353. REPEAT tx := tx + GetColWidth(col) + cellDistC; INC(col) UNTIL (col >= nofColsC) OR (tx >= x); DEC(col);
  354. REPEAT ty := ty + GetRowHeight(row) + cellDistC; INC(row) UNTIL (row >= nofRowsC) OR (ty >= y); DEC(row);
  355. END;
  356. FindMasterCell(col, row, col, row, dummy, dummy)
  357. END FindCellXY;
  358. PROCEDURE CheckScrollbarsNeeded;
  359. VAR xmax, ymax : LONGINT;
  360. BEGIN
  361. xmax := nofColsC - 1; ymax := nofRowsC - 1;
  362. scrollx.max.Set(xmax); scrolly.max.Set(ymax);
  363. scrollx.visible.Set((alwaysShowScrollXC OR (xmax > 1)) & showScrollXC);
  364. scrolly.visible.Set((alwaysShowScrollYC OR (ymax > 1)) & showScrollYC)
  365. END CheckScrollbarsNeeded;
  366. PROCEDURE GetVisibleCellRect(col, row : LONGINT): WMRectangles.Rectangle;
  367. VAR x, y, i, tc, tr, tx, ty, w, h: LONGINT; rect : WMRectangles.Rectangle;
  368. BEGIN
  369. GetFixedPixels(tx, ty);
  370. IF (col < fixedColsC) & (row < fixedRowsC) THEN
  371. x := 0; FOR i := 0 TO col - 1 DO INC(x, GetColWidth(i) + cellDistC) END;
  372. y := 0; FOR i := 0 TO row -1 DO INC(y, GetRowHeight(i) + cellDistC) END
  373. ELSIF col < fixedColsC THEN
  374. x := 0; FOR i := 0 TO col - 1 DO INC(x, GetColWidth(i) + cellDistC) END;
  375. y := ty; FOR i := tableStart.row TO row -1 DO INC(y, GetRowHeight(i) + cellDistC) END
  376. ELSIF row < fixedRowsC THEN
  377. x := tx; FOR i := tableStart.col TO col - 1 DO INC(x, GetColWidth(i) + cellDistC) END;
  378. y := 0; FOR i := 0 TO row -1 DO INC(y, GetRowHeight(i) + cellDistC) END
  379. ELSE
  380. x := tx; FOR i := tableStart.col TO col - 1 DO INC(x, GetColWidth(i) + cellDistC) END;
  381. y := ty; FOR i := tableStart.row TO row -1 DO INC(y, GetRowHeight(i) + cellDistC) END;
  382. END;
  383. FindMasterCell(col, row, tc, tr, x, y);
  384. rect.l := x; rect.t := y;
  385. GetCellDimensions(tc, tr, w, h); rect.r := rect.l + w; rect.b := rect.t + h;
  386. RETURN rect
  387. END GetVisibleCellRect;
  388. PROCEDURE DrawBackground(canvas : Graphics.Canvas);
  389. VAR i, j, x, y, w, h, cw, ch, ti, tj, tx, ty, fx, fy : LONGINT;
  390. skip : BOOLEAN;
  391. r, clip : WMRectangles.Rectangle;
  392. BEGIN
  393. DrawBackground^(canvas);
  394. tableStart.row := Strings.Max(tableStart.row, fixedRowsC);
  395. tableStart.col := Strings.Max(tableStart.col, fixedColsC);
  396. canvas.GetClipRect(clip);
  397. canvas.SaveState(state); (* save the current clip-state for the scrollbars *)
  398. GetFixedPixels(fx, fy);
  399. (* draw both side fixed area *)
  400. y := 0;
  401. FOR j := 0 TO fixedRowsC - 1 DO
  402. x := 0; h := GetRowHeight(j);
  403. FOR i := 0 TO fixedColsC - 1 DO
  404. w := GetColWidth(i);
  405. r := WMRectangles.MakeRect(x, y, x + w, y + h);
  406. IF WMRectangles.Intersect(r, clip) THEN
  407. canvas.SetClipRect(r);
  408. canvas.ClipRectAsNewLimits(x, y);
  409. IF drawCell # NIL THEN drawCell(canvas, w, h, GetCellState(i, j), i, j) END;
  410. canvas.RestoreState(state)
  411. END;
  412. INC(x, w + cellDistC)
  413. END;
  414. INC(y, h + cellDistC)
  415. END;
  416. (* draw the fixed rows *)
  417. y := 0;
  418. FOR j := 0 TO fixedRowsC - 1 DO
  419. h := GetRowHeight(j);
  420. i := tableStart.col; x := fx;
  421. WHILE (i < nofColsC) & (x < bounds.GetWidth()) DO
  422. w := GetColWidth(i);
  423. r := WMRectangles.MakeRect(x, y, x + w, y + h);
  424. IF WMRectangles.Intersect(r, clip) THEN
  425. canvas.SetClipRect(r);
  426. canvas.ClipRectAsNewLimits(x, y);
  427. IF drawCell # NIL THEN drawCell(canvas, w, h, GetCellState(i, j), i, j) END;
  428. canvas.RestoreState(state)
  429. END;
  430. INC(i);
  431. INC(x, w + cellDistC)
  432. END;
  433. INC(y, h + cellDistC)
  434. END;
  435. (* draw the fixed columns *)
  436. y := fy;
  437. j := tableStart.row;
  438. WHILE (j < nofRowsC) & (y < bounds.GetHeight()) DO
  439. h := GetRowHeight(j);
  440. i := 0; x := 0;
  441. FOR i := 0 TO fixedColsC - 1 DO
  442. w := GetColWidth(i);
  443. r := WMRectangles.MakeRect(x, y, x + w, y + h);
  444. IF WMRectangles.Intersect(r, clip) THEN
  445. canvas.SetClipRect(r);
  446. canvas.ClipRectAsNewLimits(x, y);
  447. IF drawCell # NIL THEN drawCell(canvas, w, h, GetCellState(i, j), i, j) END;
  448. canvas.RestoreState(state)
  449. END;
  450. INC(x, w + cellDistC)
  451. END;
  452. INC(j);
  453. INC(y, h + cellDistC)
  454. END;
  455. (* draw the table *)
  456. canvas.SetClipRect(WMRectangles.MakeRect(fx, fy, bounds.GetWidth(), bounds.GetHeight()));
  457. canvas.ClipRectAsNewLimits(0, 0);canvas.SaveState(tempState);
  458. j := tableStart.row; y := fy;
  459. WHILE (j < nofRowsC) & (y < bounds.GetHeight()) DO
  460. i := tableStart.col; x := fx;
  461. h := GetRowHeight(j);
  462. WHILE (i < nofColsC) & (x < bounds.GetWidth()) DO
  463. w := GetColWidth(i);
  464. tx := x; ty := y; ti := i; tj := j;
  465. skip := IsSkipCell(ti, tj);
  466. IF (~skip) OR (i = tableStart.col) OR (j = tableStart.row) THEN
  467. IF skip THEN (* handle spans that leap in *)
  468. FindMasterCell(ti, tj, ti, tj, tx, ty);
  469. END;
  470. GetCellDimensions(ti, tj, cw, ch);
  471. r := WMRectangles.MakeRect(tx, ty, tx + cw, ty + ch);
  472. IF WMRectangles.Intersect(r, clip) THEN
  473. canvas.SetClipRect(r);
  474. canvas.ClipRectAsNewLimits(tx, ty);
  475. IF drawCell # NIL THEN drawCell(canvas, w, h, GetCellState(i, j), i, j) END;
  476. canvas.RestoreState(tempState)
  477. END
  478. END;
  479. INC(i); INC(x, w + cellDistC)
  480. END;
  481. INC(j); INC(y, h + cellDistC)
  482. END;
  483. canvas.RestoreState(state) (* restore the original clip-state *)
  484. END DrawBackground;
  485. PROCEDURE InvalidateCell*(col, row : LONGINT);
  486. BEGIN
  487. Acquire;
  488. InvalidateRect(GetVisibleCellRect(col, row));
  489. Release
  490. END InvalidateCell;
  491. PROCEDURE SetTopPosition*(col, row : LONGINT; updateScrollbar : BOOLEAN);
  492. BEGIN
  493. Acquire;
  494. col := Strings.Min(Strings.Max(col, fixedColsC), nofColsC - 1);
  495. row := Strings.Min(Strings.Max(row, fixedRowsC), nofRowsC - 1);
  496. IF (col # tableStart.col) OR (row # tableStart.row) THEN
  497. tableStart.col := col; tableStart.row := row;
  498. IF pointerInside THEN FindCellXY(lastPointerX, lastPointerY, highlight.col, highlight.row) END;
  499. Invalidate();
  500. IF updateScrollbar THEN scrollx.pos.Set(col); scrolly.pos.Set(row) END
  501. END;
  502. Release
  503. END SetTopPosition;
  504. PROCEDURE GetTopPosition*(VAR col, row : LONGINT);
  505. BEGIN
  506. Acquire;
  507. col := tableStart.col; row := tableStart.row;
  508. Release
  509. END GetTopPosition;
  510. PROCEDURE ScrollCellVisible(col, row : LONGINT);
  511. VAR cur : CellPos; r : WMRectangles.Rectangle; w, h: LONGINT;
  512. BEGIN
  513. cur := tableStart;
  514. w := bounds.GetWidth(); h := bounds.GetHeight();
  515. r := GetVisibleCellRect(col, row);
  516. WHILE (r.r > w) & (cur.col < col) DO DEC(r.r, GetColWidth(cur.col)); INC(cur.col) END;
  517. WHILE (r.b > h) & (cur.row < row) DO DEC(r.b, GetRowHeight(cur.row)); INC(cur.row) END;
  518. cur.col := Strings.Min(cur.col, col);
  519. cur.row := Strings.Min(cur.row, row);
  520. SetTopPosition(cur.col, cur.row, TRUE)
  521. END ScrollCellVisible;
  522. (* set the focus pos to col, row. The acutal focusCell is the master cell of col, row *)
  523. PROCEDURE SetFocusPos(col, row : LONGINT);
  524. VAR oldfocus : CellPos; dummy : LONGINT;
  525. BEGIN
  526. IF ~adjustFocusPosition.Get() THEN RETURN; END;
  527. oldfocus := focus; focus.col := col; focus.row := row;
  528. FindMasterCell(focus.col, focus.row, focusCell.col, focusCell.row, dummy, dummy);
  529. InvalidateCell(oldfocus.col, oldfocus.row); InvalidateCell(focusCell.col, focusCell.row);
  530. ScrollCellVisible(focusCell.col, focusCell.row)
  531. END SetFocusPos;
  532. PROCEDURE KeyEvent(ucs : LONGINT; flags: SET; VAR keysym: LONGINT);
  533. PROCEDURE AdjustSelection;
  534. BEGIN
  535. IF shiftDown THEN SetSelection(selA.col, selA.row, focus.col, focus.row)
  536. ELSE selA := focus; SetSelection(focus.col, focus.row, focus.col, focus.row)
  537. END
  538. END AdjustSelection;
  539. BEGIN
  540. shiftDown := Inputs.Shift * flags # {};
  541. IF (keysym = 0FF51H) & (focus.col > fixedColsC) THEN SetFocusPos(focus.col - 1, focus.row); AdjustSelection
  542. ELSIF (keysym = 0FF53H) & (focus.col < nofColsC - 1) THEN SetFocusPos(focus.col + 1, focus.row); AdjustSelection
  543. ELSIF (keysym = 0FF52H) & (focus.row > fixedRowsC) THEN SetFocusPos(focus.col, focus.row - 1); AdjustSelection
  544. ELSIF (keysym = 0FF54H) & (focus.row < nofRowsC - 1) THEN SetFocusPos(focus.col, focus.row + 1); AdjustSelection
  545. END
  546. END KeyEvent;
  547. PROCEDURE Scrolled(sender, data : ANY);
  548. BEGIN
  549. IF ~IsCallFromSequencer() THEN sequencer.ScheduleEvent(SELF.Scrolled, sender, data)
  550. ELSE
  551. SetTopPosition(scrollx.pos.Get(), scrolly.pos.Get(), FALSE);
  552. AlignSubComponents
  553. END
  554. END Scrolled;
  555. PROCEDURE SetHighlight(col, row : LONGINT);
  556. VAR or, nr, cr : WMRectangles.Rectangle;
  557. BEGIN
  558. Acquire;
  559. IF (col = highlight.col) & (row = highlight.row)
  560. OR (selectionMode IN {GridSelectSingleCol, GridSelectCols}) & (col = highlight.col)
  561. OR (selectionMode IN {GridSelectSingleRow, GridSelectRows}) & (row = highlight.row)
  562. THEN Release; RETURN
  563. END;
  564. CASE selectionMode OF
  565. | GridSelectSingleCol, GridSelectCols : nr := GetVisibleColRect(col); or := GetVisibleColRect(highlight.col)
  566. | GridSelectSingleRow, GridSelectRows : nr := GetVisibleRowRect(row); or := GetVisibleRowRect(highlight.row)
  567. ELSE
  568. or := GetVisibleCellRect(highlight.col, highlight.row);
  569. nr := GetVisibleCellRect(col, row);
  570. END;
  571. highlight.col := col; highlight.row := row;
  572. cr := or; WMRectangles.ExtendRect(cr, nr);
  573. IF WMRectangles.Area(or) + WMRectangles.Area(nr) < WMRectangles.Area(cr) THEN InvalidateRect(or); InvalidateRect(nr)
  574. ELSE InvalidateRect(cr)
  575. END;
  576. Release
  577. END SetHighlight;
  578. PROCEDURE GetVisibleColRect(col : LONGINT) : WMRectangles.Rectangle;
  579. VAR r : WMRectangles.Rectangle;
  580. BEGIN
  581. r := GetVisibleCellRect(col, tableStart.row);
  582. r.t := 0; r.b := bounds.GetHeight();
  583. RETURN r
  584. END GetVisibleColRect;
  585. PROCEDURE GetVisibleRowRect(row: LONGINT) : WMRectangles.Rectangle;
  586. VAR r : WMRectangles.Rectangle;
  587. BEGIN
  588. r := GetVisibleCellRect(tableStart.col, row);
  589. r.l := 0; r.r := bounds.GetWidth();
  590. RETURN r
  591. END GetVisibleRowRect;
  592. PROCEDURE SetSelection*(scol, srow, ecol, erow : LONGINT);
  593. VAR or, nr, cr : WMRectangles.Rectangle; done : BOOLEAN;
  594. oldStart, oldEnd : CellPos;
  595. BEGIN
  596. Acquire;
  597. oldStart := selStart; oldEnd := selEnd;
  598. selStart.col := Strings.Min(scol, ecol); selStart.row := Strings.Min(srow, erow);
  599. selEnd.col := Strings.Max(scol, ecol); selEnd.row := Strings.Max(srow, erow);
  600. IF (oldStart.col = selStart.col) & (oldStart.row= selStart.row) &
  601. (oldEnd.col = selEnd.col) & (oldEnd.row= selEnd.row) THEN
  602. Release;
  603. RETURN
  604. END;
  605. done := FALSE;
  606. CASE selectionMode OF
  607. | GridSelectSingleCell :
  608. or := GetVisibleCellRect(oldStart.col, oldStart.row); nr := GetVisibleCellRect(selStart.col, selStart.row)
  609. | GridSelectSingleCol : or := GetVisibleColRect(oldStart.col); nr := GetVisibleColRect(selStart.col)
  610. | GridSelectSingleRow : or := GetVisibleRowRect(oldStart.row); nr := GetVisibleRowRect(selStart.row)
  611. ELSE
  612. Invalidate(); done := TRUE
  613. END;
  614. IF ~done THEN
  615. cr := or; WMRectangles.ExtendRect(cr, nr);
  616. IF WMRectangles.Area(or) + WMRectangles.Area(nr) < WMRectangles.Area(cr) THEN InvalidateRect(or); InvalidateRect(nr)
  617. ELSE InvalidateRect(cr)
  618. END;
  619. END;
  620. Release;
  621. onSelect.Call(NIL)
  622. END SetSelection;
  623. (** must be interpreted according to SelectionMode *)
  624. PROCEDURE GetSelection*(VAR scol, srow, ecol, erow : LONGINT);
  625. BEGIN
  626. Acquire;
  627. scol := selStart.col; srow := selStart.row;
  628. ecol := selEnd.col; erow := selEnd.row;
  629. Release
  630. END GetSelection;
  631. PROCEDURE OnFixedXGridLine(x, y : LONGINT; VAR xCell, pos : LONGINT) : BOOLEAN;
  632. VAR ty, tx : LONGINT;
  633. PROCEDURE Find(startX, endX, startCol, endCol : LONGINT; VAR col, xPos : LONGINT) : BOOLEAN;
  634. VAR cw : LONGINT;
  635. BEGIN
  636. col := startCol; xPos := startX;
  637. REPEAT
  638. cw := GetColWidth(col);
  639. IF ABS(xPos + cw + cellDistC - x) < PixelRange THEN RETURN TRUE END;
  640. xPos := xPos + cw + cellDistC; INC(col);
  641. UNTIL (col >= endCol) OR (xPos >= endX);
  642. RETURN FALSE
  643. END Find;
  644. BEGIN
  645. GetFixedPixels(tx, ty);
  646. IF (x < tx) & (y < ty) OR (x < tx) THEN (* column fixed *)
  647. RETURN Find(0, x + PixelRange, 0, fixedColsC, xCell, pos)
  648. ELSIF (y < ty) THEN (* row fixed *)
  649. RETURN Find(tx, x + PixelRange, tableStart.col, nofColsC, xCell, pos)
  650. ELSE (* normal cells *)
  651. RETURN FALSE
  652. END
  653. END OnFixedXGridLine;
  654. PROCEDURE OnFixedYGridLine(x, y : LONGINT; VAR yCell, pos : LONGINT) : BOOLEAN;
  655. VAR ty, tx : LONGINT;
  656. PROCEDURE Find(startY, endY, startRow, endRow : LONGINT; VAR row, yPos : LONGINT) : BOOLEAN;
  657. VAR ch : LONGINT;
  658. BEGIN
  659. row := startRow; yPos := startY;
  660. REPEAT
  661. ch := GetRowHeight(row);
  662. IF ABS(yPos + ch + cellDistC - y) < PixelRange THEN RETURN TRUE END;
  663. yPos := yPos + ch + cellDistC; INC(row);
  664. UNTIL (row >= endRow) OR (yPos >= endY);
  665. RETURN FALSE
  666. END Find;
  667. BEGIN
  668. GetFixedPixels(tx, ty);
  669. IF (y < ty) THEN (* column fixed *)
  670. RETURN Find(0, y + PixelRange, 0, fixedRowsC, yCell, pos)
  671. ELSIF (x < tx) THEN (* row fixed *)
  672. RETURN Find(ty, y + PixelRange, tableStart.row, nofRowsC, yCell, pos)
  673. ELSE (* normal cells *)
  674. RETURN FALSE
  675. END
  676. END OnFixedYGridLine;
  677. PROCEDURE PointerDown(x, y : LONGINT; keys : SET); (** PROTECTED *)
  678. VAR col, row : LONGINT; state : SET;
  679. BEGIN
  680. PointerDown^(x, y, keys);
  681. lastkeys := keys;
  682. IF keys * {0,1} # {} THEN
  683. IF allowColResize.Get() & (colWidths # NIL) & OnFixedXGridLine(x, y, dragCellSpacingNr, dragCellSpacingPos) THEN
  684. dragCellSpacingWidth := TRUE;
  685. ELSIF allowRowResize.Get() & (rowHeights # NIL) & OnFixedYGridLine(x, y, dragCellSpacingNr, dragCellSpacingPos) THEN
  686. dragCellSpacingHeight := TRUE;
  687. ELSE
  688. FindCellXY(x, y, col, row);
  689. state := GetCellState(col, row);
  690. wasSelected := CellSelected IN state;
  691. IF shiftDown & (0 IN keys) THEN
  692. SetSelection(selA.col, selA.row, col, row);
  693. dragPossible := FALSE; selecting := TRUE
  694. ELSE
  695. IF CellSelected IN state THEN selecting := FALSE; dragPossible := TRUE; downX := x; downY := y
  696. ELSE
  697. dragPossible := FALSE; selecting := TRUE;
  698. selA.col := col; selA.row := row; SetFocusPos(col, row);
  699. SetSelection(col, row, col, row)
  700. END
  701. END
  702. END
  703. END
  704. END PointerDown;
  705. PROCEDURE PointerLeave;
  706. BEGIN
  707. SetHighlight(-1, -1); pointerInside := FALSE
  708. END PointerLeave;
  709. PROCEDURE PointerMove(x, y : LONGINT; keys : SET); (** PROTECTED *)
  710. VAR col, row : LONGINT; manager : WM.WindowManager; cell, pos : LONGINT;
  711. BEGIN
  712. IF dragCellSpacingWidth THEN
  713. x := Strings.Min(x, bounds.GetWidth());
  714. IF (colWidths # NIL) & (dragCellSpacingNr < LEN(colWidths)) THEN
  715. colWidths[dragCellSpacingNr] := Strings.Max(x - dragCellSpacingPos, 1);
  716. Invalidate()
  717. END;
  718. ELSIF dragCellSpacingHeight THEN
  719. y := Strings.Min(y, bounds.GetHeight());
  720. IF (rowHeights # NIL) & (dragCellSpacingNr < LEN(rowHeights)) THEN
  721. rowHeights[dragCellSpacingNr] := Strings.Max(y - dragCellSpacingPos, 1);
  722. Invalidate()
  723. END;
  724. ELSIF dragPossible THEN
  725. IF (ABS(x - downX) > DragDist) OR (ABS(y - downY) > DragDist) THEN
  726. dragPossible := FALSE;
  727. drag := TRUE;
  728. AutoStartDrag
  729. END
  730. ELSE
  731. FindCellXY(x, y, col, row); pointerInside := TRUE; lastPointerX := x; lastPointerY := y;
  732. IF allowColResize.Get() & (colWidths # NIL) & OnFixedXGridLine(x, y, cell, pos) THEN
  733. IF ~hasOldPointer THEN
  734. prevPointerInfo := GetPointerInfo();
  735. hasOldPointer := TRUE;
  736. manager := WM.GetDefaultManager();
  737. SetPointerInfo(manager.pointerLeftRight)
  738. END;
  739. ELSIF allowRowResize.Get() & (rowHeights # NIL) & OnFixedYGridLine(x, y, cell, pos) THEN
  740. IF ~hasOldPointer THEN
  741. prevPointerInfo := GetPointerInfo();
  742. hasOldPointer := TRUE;
  743. manager := WM.GetDefaultManager();
  744. SetPointerInfo(manager.pointerUpDown)
  745. END;
  746. ELSE
  747. IF hasOldPointer THEN SetPointerInfo(prevPointerInfo); hasOldPointer := FALSE END;
  748. END;
  749. IF selecting THEN
  750. IF 0 IN keys THEN
  751. CASE selectionMode OF
  752. | GridSelectSingleCell, GridSelectSingleCol, GridSelectSingleRow : SetSelection(col, row, col, row)
  753. | GridSelectCols, GridSelectRows, GridSelectBlock, GridSelectHorizontal, GridSelectVertical:
  754. SetSelection(selA.col, selA.row, col, row)
  755. ELSE
  756. END;
  757. SetFocusPos(col, row)
  758. END
  759. END;
  760. IF selectOnPointerOver THEN SetSelection(col, row, col, row) END;
  761. SetHighlight(col, row)
  762. END;
  763. IF keys = {} THEN dragPossible := FALSE; selecting := FALSE END
  764. END PointerMove;
  765. PROCEDURE CellClicked*(col, row : LONGINT); (** PROTECTED *)
  766. BEGIN
  767. IF wasSelected & onClickSelected.HasListeners() THEN
  768. dragPossible := FALSE;
  769. onClickSelected.Call(GetCellData(col, row))
  770. END;
  771. IF onClick.HasListeners() THEN
  772. onClick.Call(GetCellData(col, row))
  773. END
  774. END CellClicked;
  775. PROCEDURE PointerUp(x, y : LONGINT; keys : SET); (** PROTECTED *)
  776. VAR col, row : LONGINT; d : BOOLEAN;
  777. BEGIN
  778. IF 2 IN lastkeys THEN lastkeys := keys; RETURN END;
  779. d := dragCellSpacingWidth OR dragCellSpacingHeight OR
  780. (selecting & (selStart.row # selEnd.row) OR (selStart.col # selEnd.col));
  781. IF ~d THEN
  782. FindCellXY(x, y, col, row);
  783. SetSelection(col, row, col, row); SetFocusPos(col, row);
  784. IF ~drag THEN CellClicked(col, row) END
  785. END;
  786. drag := FALSE;
  787. dragCellSpacingWidth := FALSE; dragCellSpacingHeight := FALSE;
  788. selecting := FALSE
  789. END PointerUp;
  790. PROCEDURE WheelMove*(dz: LONGINT); (** PROTECTED *)
  791. VAR t, l : LONGINT;
  792. BEGIN
  793. GetTopPosition(l, t); t := t + dz; SetTopPosition(l, t, TRUE)
  794. END WheelMove;
  795. END GenericGrid;
  796. VAR
  797. GSonSelect, GSonClick, GSonClickSelected,
  798. GSonSelectInfo, GSonClickInfo, GSonClickSelectedInfo: String;
  799. GSGenericGrid : String;
  800. fixedColsProto, fixedRowsProto : WMProperties.Int32Property;
  801. defaultColWidthProto, defaultRowHeightProto : WMProperties.Int32Property;
  802. allowColResizeProto, allowRowResizeProto, adjustFocusPositionProto : WMProperties.BooleanProperty;
  803. nofColsProto, nofRowsProto, cellDistProto : WMProperties.Int32Property;
  804. showScrollXProto, showScrollYProto, alwaysShowScrollXProto, alwaysShowScrollYProto : WMProperties.BooleanProperty;
  805. PROCEDURE Init;
  806. BEGIN
  807. GSonSelect := NewString("onSelect");
  808. GSonClick := NewString("onClick");
  809. GSonClickSelected := NewString("onClickSelected");
  810. GSonSelectInfo := NewString("Is called when a cell is selected");
  811. GSonClickInfo := NewString("is called on a click");
  812. GSonClickSelectedInfo := NewString("is called when a selected cell is clicked");
  813. GSGenericGrid := NewString("GenericGrid");
  814. END Init;
  815. PROCEDURE InitProto;
  816. BEGIN
  817. NEW(fixedColsProto, NIL, NewString("fixedCols"), NewString("number of fixed columns"));
  818. NEW(fixedRowsProto, NIL, NewString("fixedRows"), NewString("number of fixed rows"));
  819. NEW(defaultColWidthProto, NIL, NewString("defaultColWidth"), NewString("default width of a column"));
  820. NEW(defaultRowHeightProto, NIL, NewString("defaultRowHeight"), NewString("default height of a row"));
  821. defaultColWidthProto.Set(100); defaultRowHeightProto.Set(20);
  822. NEW(allowColResizeProto, NIL, NewString("allowColResize"), NewString("can columns be resized"));
  823. allowColResizeProto.Set(TRUE);
  824. NEW(allowRowResizeProto, NIL, NewString("allowRowResize"), NewString("can rows be resized"));
  825. allowRowResizeProto.Set(TRUE);
  826. NEW(adjustFocusPositionProto, NIL, NewString("adjustFocusPosition"), NewString("focus adjusting when clicking/dragging cells"));
  827. adjustFocusPositionProto.Set(TRUE);
  828. NEW(nofColsProto, NIL, NewString("nofCols"), NewString("number of columns in the table"));
  829. nofColsProto.Set(1);
  830. NEW(nofRowsProto, NIL, NewString("nofRows"), NewString("number of rows in the table"));
  831. nofRowsProto.Set(1);
  832. NEW(cellDistProto, NIL, NewString("cellDist"), NewString("distance between cells"));
  833. cellDistProto.Set(1);
  834. NEW(showScrollXProto, NIL, NewString("showScrollX"), NewString("horizontal scrollbar is displayed if needed"));
  835. showScrollXProto.Set(TRUE);
  836. NEW(showScrollYProto, NIL, NewString("showScrollY"), NewString("vertical scrollbar is displayed if needed"));
  837. showScrollYProto.Set(TRUE);
  838. NEW(alwaysShowScrollXProto, NIL, NewString("alwaysShowScrollX"), NewString("horizontal scrollbar is always displayed"));
  839. NEW(alwaysShowScrollYProto, NIL, NewString("alwaysShowScrollY"), NewString("vertical scrollbar is always displayed"));
  840. END InitProto;
  841. PROCEDURE GenGrid*() : XML.Element;
  842. VAR grid : GenericGrid;
  843. BEGIN
  844. NEW(grid);
  845. RETURN grid
  846. END GenGrid;
  847. PROCEDURE NewString*(CONST x : ARRAY OF CHAR) : String;
  848. BEGIN
  849. RETURN Strings.NewString(x)
  850. END NewString;
  851. BEGIN
  852. Init;
  853. InitProto;
  854. END WMGrids.
  855. SystemTools.Free WMGrids ~
  856. History:
  857. 03.04.2006 Added AlignSubComponents in last line for GenericGrid.RecacheAllProperties