DemosLayout.mod 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. IMPLEMENTATION MODULE DemosLayout ;
  2. (*
  3. m2-GTK4 - the layout-related gtk-demo demos: Size Groups, Fixed Layout
  4. Transformations and Layout Manager/Transition. Ported from the GTK C
  5. demo sources in gtk/demos/gtk-demo (sizegroup.c, fixed2.c,
  6. layoutmanager.c).
  7. Bindings that are not (yet) exposed under src/ forced a few faithful
  8. simplifications; each one is marked with a "SIMPLIFIED" note below.
  9. *)
  10. FROM SYSTEM IMPORT ADDRESS;
  11. FROM GtkWindow IMPORT gtk_window_new, gtk_window_set_title,
  12. gtk_window_set_default_size, gtk_window_set_resizable,
  13. gtk_window_set_child, gtk_window_destroy;
  14. FROM GtkWidget IMPORT gtk_widget_set_visible, gtk_widget_get_visible,
  15. gtk_widget_set_margin_start, gtk_widget_set_margin_end,
  16. gtk_widget_set_margin_top, gtk_widget_set_margin_bottom,
  17. gtk_widget_set_halign, gtk_widget_set_valign, gtk_widget_set_hexpand;
  18. FROM GtkBox IMPORT gtk_box_new, gtk_box_append;
  19. FROM GtkGrid IMPORT gtk_grid_new, gtk_grid_attach,
  20. gtk_grid_set_row_spacing, gtk_grid_set_column_spacing;
  21. FROM GtkFrame IMPORT gtk_frame_new, gtk_frame_set_child;
  22. FROM GtkLabel IMPORT gtk_label_new;
  23. FROM GtkDropDown IMPORT gtk_drop_down_new;
  24. FROM GtkStringList IMPORT gtk_string_list_new, gtk_string_list_append;
  25. FROM GtkSizeGroup IMPORT gtk_size_group_new, gtk_size_group_add_widget,
  26. GtkSizeGroupHorizontal;
  27. FROM GtkCheckButton IMPORT gtk_check_button_new_with_label,
  28. gtk_check_button_set_active;
  29. FROM GtkScrolledWindow IMPORT gtk_scrolled_window_new,
  30. gtk_scrolled_window_set_child;
  31. FROM GtkFixed IMPORT gtk_fixed_new, gtk_fixed_put;
  32. FROM GtkEnums IMPORT GtkVertical, GtkAlignStart, GtkAlignEnd,
  33. GtkAlignBaseline;
  34. (* ------------------------------------------------------------------ *)
  35. (* Size Groups *)
  36. (* ------------------------------------------------------------------ *)
  37. VAR
  38. sizeGroupWindow: ADDRESS;
  39. (* Build a drop-down from three literal labels. The C demo passes a
  40. NULL-terminated const char * array to gtk_drop_down_new_from_strings();
  41. this binding favours a GtkStringList model, which is the equivalent
  42. route exposed under src/. *)
  43. PROCEDURE MakeDropDown (a, b, c: ARRAY OF CHAR) : ADDRESS;
  44. VAR
  45. list: ADDRESS;
  46. BEGIN
  47. list := gtk_string_list_new(NIL);
  48. gtk_string_list_append(list, a);
  49. gtk_string_list_append(list, b);
  50. gtk_string_list_append(list, c);
  51. RETURN gtk_drop_down_new(list, NIL)
  52. END MakeDropDown;
  53. (* add_row(): one mnemonic label plus a drop-down in a grid row.
  54. SIMPLIFIED: gtk_label_new_with_mnemonic() and
  55. gtk_label_set_mnemonic_widget() are not bound, so a plain label is
  56. used (the underscores are dropped rather than shown literally). *)
  57. PROCEDURE AddRow (group, table: ADDRESS; row: INTEGER;
  58. labelText, a, b, c: ARRAY OF CHAR);
  59. VAR
  60. label, dropdown: ADDRESS;
  61. BEGIN
  62. label := gtk_label_new(labelText);
  63. gtk_widget_set_halign(label, GtkAlignStart);
  64. gtk_widget_set_valign(label, GtkAlignBaseline);
  65. gtk_widget_set_hexpand(label, 1);
  66. IF group # NIL THEN gtk_size_group_add_widget(group, label) END;
  67. gtk_grid_attach(table, label, 0, row, 1, 1);
  68. dropdown := MakeDropDown(a, b, c);
  69. gtk_widget_set_halign(dropdown, GtkAlignEnd);
  70. gtk_widget_set_valign(dropdown, GtkAlignBaseline);
  71. gtk_grid_attach(table, dropdown, 1, row, 1, 1)
  72. END AddRow;
  73. PROCEDURE DoSizeGroup (doWidget: ADDRESS) : ADDRESS;
  74. VAR
  75. vbox, frame, table, checkButton, group: ADDRESS;
  76. BEGIN
  77. IF sizeGroupWindow = NIL THEN
  78. sizeGroupWindow := gtk_window_new();
  79. gtk_window_set_title(sizeGroupWindow, "Size Groups");
  80. gtk_window_set_resizable(sizeGroupWindow, 0);
  81. vbox := gtk_box_new(GtkVertical, 5);
  82. gtk_widget_set_margin_start(vbox, 5);
  83. gtk_widget_set_margin_end(vbox, 5);
  84. gtk_widget_set_margin_top(vbox, 5);
  85. gtk_widget_set_margin_bottom(vbox, 5);
  86. gtk_window_set_child(sizeGroupWindow, vbox);
  87. (* the labels in both grids share one horizontal size group *)
  88. group := gtk_size_group_new(GtkSizeGroupHorizontal);
  89. (* Color options *)
  90. frame := gtk_frame_new("Color Options");
  91. gtk_box_append(vbox, frame);
  92. table := gtk_grid_new();
  93. gtk_widget_set_margin_start(table, 5);
  94. gtk_widget_set_margin_end(table, 5);
  95. gtk_widget_set_margin_top(table, 5);
  96. gtk_widget_set_margin_bottom(table, 5);
  97. gtk_grid_set_row_spacing(table, 5);
  98. gtk_grid_set_column_spacing(table, 10);
  99. gtk_frame_set_child(frame, table);
  100. AddRow(group, table, 0, "Foreground", "Red", "Green", "Blue");
  101. AddRow(group, table, 1, "Background", "Red", "Green", "Blue");
  102. (* Line options *)
  103. frame := gtk_frame_new("Line Options");
  104. gtk_box_append(vbox, frame);
  105. table := gtk_grid_new();
  106. gtk_widget_set_margin_start(table, 5);
  107. gtk_widget_set_margin_end(table, 5);
  108. gtk_widget_set_margin_top(table, 5);
  109. gtk_widget_set_margin_bottom(table, 5);
  110. gtk_grid_set_row_spacing(table, 5);
  111. gtk_grid_set_column_spacing(table, 10);
  112. gtk_frame_set_child(frame, table);
  113. AddRow(group, table, 0, "Dashing", "Solid", "Dashed", "Dotted");
  114. AddRow(group, table, 1, "Line ends", "Square", "Round", "Double Arrow");
  115. checkButton := gtk_check_button_new_with_label("Enable grouping");
  116. gtk_box_append(vbox, checkButton);
  117. gtk_check_button_set_active(checkButton, 1)
  118. END;
  119. IF gtk_widget_get_visible(sizeGroupWindow) = 0 THEN
  120. gtk_widget_set_visible(sizeGroupWindow, 1)
  121. ELSE
  122. gtk_window_destroy(sizeGroupWindow);
  123. sizeGroupWindow := NIL
  124. END;
  125. RETURN sizeGroupWindow
  126. END DoSizeGroup;
  127. (* ------------------------------------------------------------------ *)
  128. (* Fixed Layout / Transformations *)
  129. (* ------------------------------------------------------------------ *)
  130. VAR
  131. fixed2Window: ADDRESS;
  132. PROCEDURE DoFixed2 (doWidget: ADDRESS) : ADDRESS;
  133. VAR
  134. sw, fixed, child: ADDRESS;
  135. BEGIN
  136. IF fixed2Window = NIL THEN
  137. fixed2Window := gtk_window_new();
  138. gtk_window_set_title(fixed2Window, "Fixed Layout - Transformations");
  139. gtk_window_set_default_size(fixed2Window, 400, 300);
  140. sw := gtk_scrolled_window_new();
  141. gtk_window_set_child(fixed2Window, sw);
  142. fixed := gtk_fixed_new();
  143. gtk_scrolled_window_set_child(sw, fixed);
  144. child := gtk_label_new("All fixed?");
  145. gtk_fixed_put(fixed, child, 0.0, 0.0)
  146. (* SIMPLIFIED: the C demo animates the child with a frame-clock
  147. tick callback (gtk_widget_add_tick_callback), a transform on the
  148. fixed child (gtk_fixed_set_child_transform) and
  149. gtk_widget_set_overflow(); none of those are bound under src/.
  150. The widget hierarchy is kept, the rotation/scale animation is
  151. omitted. *)
  152. END;
  153. IF gtk_widget_get_visible(fixed2Window) = 0 THEN
  154. gtk_widget_set_visible(fixed2Window, 1)
  155. ELSE
  156. gtk_window_destroy(fixed2Window);
  157. fixed2Window := NIL
  158. END;
  159. RETURN fixed2Window
  160. END DoFixed2;
  161. (* ------------------------------------------------------------------ *)
  162. (* Layout Manager / Transition *)
  163. (* ------------------------------------------------------------------ *)
  164. VAR
  165. layoutManagerWindow: ADDRESS;
  166. layoutColors: ARRAY [0..15] OF ARRAY [0..9] OF CHAR;
  167. (* SIMPLIFIED: the C demo builds a bespoke DemoWidget whose custom
  168. GtkLayoutManager animates its 16 DemoChild() squares between a grid
  169. and a circle. Neither that C widget pair nor a GtkLayoutManager /
  170. GtkCustomLayout binding exists under src/. The bound equivalent used
  171. here is a GtkGrid holding the same 16 coloured children; the names
  172. are shown as label text (the animation and the drawn colour fill are
  173. omitted). *)
  174. PROCEDURE InitColors;
  175. BEGIN
  176. layoutColors[0] := "red";
  177. layoutColors[1] := "orange";
  178. layoutColors[2] := "yellow";
  179. layoutColors[3] := "green";
  180. layoutColors[4] := "blue";
  181. layoutColors[5] := "grey";
  182. layoutColors[6] := "magenta";
  183. layoutColors[7] := "lime";
  184. layoutColors[8] := "yellow";
  185. layoutColors[9] := "firebrick";
  186. layoutColors[10] := "aqua";
  187. layoutColors[11] := "purple";
  188. layoutColors[12] := "tomato";
  189. layoutColors[13] := "pink";
  190. layoutColors[14] := "thistle";
  191. layoutColors[15] := "maroon"
  192. END InitColors;
  193. PROCEDURE DoLayoutManager (doWidget: ADDRESS) : ADDRESS;
  194. VAR
  195. grid, child: ADDRESS;
  196. i: INTEGER;
  197. BEGIN
  198. IF layoutManagerWindow = NIL THEN
  199. layoutManagerWindow := gtk_window_new();
  200. gtk_window_set_title(layoutManagerWindow,
  201. "Layout Manager - Transition");
  202. gtk_window_set_default_size(layoutManagerWindow, 600, 600);
  203. InitColors;
  204. grid := gtk_grid_new();
  205. FOR i := 0 TO 15 DO
  206. child := gtk_label_new(layoutColors[i]);
  207. gtk_widget_set_margin_start(child, 4);
  208. gtk_widget_set_margin_end(child, 4);
  209. gtk_widget_set_margin_top(child, 4);
  210. gtk_widget_set_margin_bottom(child, 4);
  211. gtk_grid_attach(grid, child, i MOD 4, i DIV 4, 1, 1)
  212. END;
  213. gtk_window_set_child(layoutManagerWindow, grid)
  214. END;
  215. IF gtk_widget_get_visible(layoutManagerWindow) = 0 THEN
  216. gtk_widget_set_visible(layoutManagerWindow, 1)
  217. ELSE
  218. gtk_window_destroy(layoutManagerWindow);
  219. layoutManagerWindow := NIL
  220. END;
  221. RETURN layoutManagerWindow
  222. END DoLayoutManager;
  223. END DemosLayout.