customwidget.mod 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. MODULE customwidget ;
  2. (*
  3. m2-GTK4 example - custom GObject subclasses via the C shim.
  4. A custom GtkWidget (concentric circles) and a custom GdkPaintable
  5. shown in a GtkPicture, both drawn from Modula-2 Cairo callbacks.
  6. Build: make examples
  7. Run: ./build/examples/customwidget
  8. *)
  9. FROM Gio IMPORT g_application_run;
  10. FROM GtkApplication IMPORT gtk_application_new;
  11. FROM GtkWindow IMPORT gtk_application_window_new, gtk_window_set_title,
  12. gtk_window_set_default_size, gtk_window_set_child, gtk_window_present;
  13. FROM GtkBox IMPORT gtk_box_new, gtk_box_append, gtk_box_set_spacing;
  14. FROM GtkEnums IMPORT GtkVertical;
  15. FROM GtkWidget IMPORT gtk_widget_set_size_request;
  16. FROM GtkPicture IMPORT gtk_picture_new, gtk_picture_set_paintable;
  17. FROM M2GtkShim IMPORT m2_gtk_widget_new, m2_paintable_new;
  18. FROM Cairo IMPORT cairo_set_source_rgb, cairo_rectangle, cairo_fill,
  19. cairo_arc, cairo_set_line_width, cairo_stroke;
  20. FROM GtkClosures IMPORT Connect2;
  21. FROM SYSTEM IMPORT ADDRESS, ADR;
  22. FROM libc IMPORT printf;
  23. CONST
  24. AppId = "org.example.m2gtk4.CustomWidget";
  25. PROCEDURE DrawCircles (widget: ADDRESS; cr: ADDRESS; width, height: INTEGER;
  26. user: ADDRESS);
  27. VAR
  28. i: INTEGER;
  29. cx, cy, radius: REAL;
  30. BEGIN
  31. cairo_set_source_rgb(cr, 0.95, 0.95, 0.97);
  32. cairo_rectangle(cr, 0.0, 0.0, VAL(REAL, width), VAL(REAL, height));
  33. cairo_fill(cr);
  34. cx := VAL(REAL, width DIV 2);
  35. cy := VAL(REAL, height DIV 2);
  36. FOR i := 0 TO 4 DO
  37. IF i MOD 2 = 0 THEN
  38. cairo_set_source_rgb(cr, 0.20, 0.50, 0.90)
  39. ELSE
  40. cairo_set_source_rgb(cr, 0.90, 0.30, 0.20)
  41. END;
  42. radius := VAL(REAL, 12 + i * 14);
  43. cairo_arc(cr, cx, cy, radius, 0.0, 6.2831853);
  44. cairo_fill(cr)
  45. END
  46. END DrawCircles;
  47. PROCEDURE DrawPaintable (cr: ADDRESS; width, height: INTEGER; user: ADDRESS);
  48. BEGIN
  49. cairo_set_source_rgb(cr, 0.14, 0.54, 0.34);
  50. cairo_rectangle(cr, 0.0, 0.0, VAL(REAL, width), VAL(REAL, height));
  51. cairo_fill(cr);
  52. cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
  53. cairo_set_line_width(cr, 3.0);
  54. cairo_rectangle(cr, 4.0, 4.0, VAL(REAL, width) - 8.0, VAL(REAL, height) - 8.0);
  55. cairo_stroke(cr)
  56. END DrawPaintable;
  57. PROCEDURE OnActivate (application: ADDRESS; data: ADDRESS);
  58. VAR
  59. window, box, custom, picture, paintable: ADDRESS;
  60. BEGIN
  61. custom := m2_gtk_widget_new(ADR(DrawCircles), NIL, NIL);
  62. gtk_widget_set_size_request(custom, 180, 180);
  63. paintable := m2_paintable_new(ADR(DrawPaintable), 120, 80, NIL, NIL);
  64. picture := gtk_picture_new();
  65. gtk_picture_set_paintable(picture, paintable);
  66. gtk_widget_set_size_request(picture, 120, 80);
  67. box := gtk_box_new(GtkVertical, 12);
  68. gtk_box_set_spacing(box, 12);
  69. gtk_box_append(box, custom);
  70. gtk_box_append(box, picture);
  71. window := gtk_application_window_new(application);
  72. gtk_window_set_title(window, "m2-GTK4 Custom Widget");
  73. gtk_window_set_default_size(window, 320, 340);
  74. gtk_window_set_child(window, box);
  75. gtk_window_present(window)
  76. END OnActivate;
  77. VAR
  78. app: ADDRESS;
  79. BEGIN
  80. app := gtk_application_new(AppId, 0);
  81. IF app = NIL THEN
  82. printf("gtk_application_new failed\n");
  83. HALT(1)
  84. END;
  85. Connect2(app, "activate", OnActivate, NIL);
  86. g_application_run(app, 0, NIL)
  87. END customwidget.