CP_IPS.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. // Gtk C code implementing a
  2. // Contact Process model
  3. // in a Gtk3 written GUI
  4. // _________________________
  5. // Juan E. Keymer
  6. //
  7. // Institute for Advanced Studies
  8. // Shenzhen X-Institute
  9. // Shenzhen China, May 2024
  10. // Libraries
  11. #include <gtk/gtk.h> // GUI, Gtk Lib
  12. #include "CP_core_IPS.h" // Simulation Structures
  13. #include "IPS_graphics.h" // Graphics for IPS
  14. // Structure & pointer
  15. IPSmodel s, *ptr_s;
  16. // Update function
  17. // simulates the stochastic process
  18. // updates the lattice configuration
  19. int update_lattice(gpointer data)\
  20. {
  21. update_IPS(ptr_s); //Monte Carlo Step
  22. paint_lattice(data, ptr_s);
  23. g_print ("\tGeneration:\t%u\t\tOccupancy:\t%f\n", s.generation_time, (s.occupancy/(X_SIZE * Y_SIZE)));
  24. return 0;
  25. }
  26. // time handler
  27. // connects update function
  28. // to the Gtk loop for its computation
  29. gboolean time_handler (gpointer data)
  30. {
  31. update_lattice(data);
  32. return TRUE;
  33. }
  34. // callback to initialize the lattice
  35. static void init_lattice(GtkWidget *widget, gpointer data)
  36. {
  37. initialize_IPS(ptr_s);
  38. paint_lattice(data, ptr_s);
  39. // log to console
  40. g_print ("\tGeneration:\t%u\t\tOccupancy:\t%f\n", s.generation_time, (s.occupancy/(X_SIZE * Y_SIZE)));
  41. g_print ("Lattice initialized\n");
  42. }
  43. // callback to start the simulation
  44. static void start_simulation (GtkWidget *widget, gpointer data)
  45. {
  46. if(!s.running && s.initialized)
  47. {
  48. s.run = g_idle_add((GSourceFunc) (GSourceFunc) time_handler, GTK_IMAGE(data));
  49. s.running = TRUE;
  50. // log to console
  51. g_print ("Simulation started\n");
  52. }
  53. }
  54. // callback to stop simulation
  55. static void stop_simulation (GtkWidget *widget, gpointer data)
  56. {
  57. if(s.running)
  58. {
  59. g_source_remove(s.run);
  60. s.running = FALSE;
  61. // log to console
  62. g_print ("Simulation Stopped\n");
  63. }
  64. }
  65. // callback to respond parameter change scale
  66. static void mortality_scale_moved (GtkRange *range, gpointer data)
  67. {
  68. GtkWidget *label = data;
  69. gdouble pos = gtk_range_get_value (range);
  70. s.dead_rate = (float) pos;
  71. gchar *str = g_strdup_printf ("death = %.2f", pos);
  72. gtk_label_set_text (GTK_LABEL (label), str);
  73. g_free(str);
  74. }
  75. // to render parameter control
  76. GtkWidget * render_parameter(void)
  77. {
  78. // to control the parameter of the process
  79. GtkWidget *mortality_scale, *mortality_label;
  80. GtkWidget *box, *parameter_frame;
  81. // Container to pack: horizontal box
  82. box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
  83. // label for motality
  84. mortality_label = gtk_label_new ("death rate"); /* LABEL*/
  85. gtk_box_pack_start(GTK_BOX(box), mortality_label, TRUE, TRUE, 0);
  86. // Scale to set mortality
  87. mortality_scale = gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0,1,0.01);
  88. gtk_range_set_value (GTK_RANGE(mortality_scale), (gfloat) MORTALITY);
  89. gtk_box_pack_start(GTK_BOX(box), mortality_scale, TRUE, TRUE, 0);
  90. // connect scale and label to handler
  91. g_signal_connect (mortality_scale,"value-changed", G_CALLBACK (mortality_scale_moved), mortality_label);
  92. // put it all in a frame to return it
  93. parameter_frame = gtk_frame_new ("Parameters");
  94. gtk_container_add (GTK_CONTAINER (parameter_frame), box);
  95. return parameter_frame;
  96. }
  97. // to render an image display
  98. // for lattice configuration
  99. GtkWidget * render_image(void)
  100. {
  101. // Gtk image widget
  102. GtkWidget *image;
  103. // Gdk pixbuffer to make an image
  104. GdkPixbuf *pixbuf;
  105. // pixbuffer
  106. pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, 0, 8, X_SIZE, Y_SIZE);
  107. image = gtk_image_new_from_pixbuf(pixbuf);
  108. paint_a_background(image);
  109. return image;
  110. }
  111. // to render simulation controls
  112. // initialize, start, stop, about, quit
  113. GtkWidget * render_simulation_ctrls(GtkWidget *window, GtkWidget *image_lattice)
  114. {
  115. // Widgets
  116. GtkWidget *button, *button_box, *ctrl_frame;
  117. ctrl_frame = gtk_frame_new ("Simulation Control");
  118. button_box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
  119. // init
  120. button = gtk_button_new_with_label ("Init");
  121. g_signal_connect (button, "clicked", G_CALLBACK (init_lattice), GTK_IMAGE (image_lattice));
  122. gtk_container_add (GTK_CONTAINER (button_box), button);
  123. // start
  124. button = gtk_button_new_with_label ("Start");
  125. g_signal_connect (button, "clicked", G_CALLBACK (start_simulation), GTK_IMAGE (image_lattice));
  126. gtk_container_add (GTK_CONTAINER (button_box), button);
  127. // stop
  128. button = gtk_button_new_with_label ("Stop");
  129. g_signal_connect (button, "clicked", G_CALLBACK (stop_simulation), NULL /* (gpointer) ptr_s*/);
  130. gtk_container_add (GTK_CONTAINER (button_box), button);
  131. // about
  132. button = gtk_button_new_with_label ("About");
  133. g_signal_connect (button, "clicked", G_CALLBACK (show_about), NULL);
  134. gtk_container_add (GTK_CONTAINER (button_box), button);
  135. // quit
  136. button = gtk_button_new_with_label ("Quit");
  137. g_signal_connect (button, "clicked", G_CALLBACK (stop_simulation), NULL);
  138. g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_widget_destroy), window);
  139. gtk_container_add (GTK_CONTAINER (button_box), button);
  140. // Add all buttons into a frame
  141. gtk_container_add (GTK_CONTAINER (ctrl_frame), button_box);
  142. // Return the frame
  143. return ctrl_frame;
  144. };
  145. // ACTIVATE function with all Widget Initialization and creation
  146. static void activate (GtkApplication *app, gpointer user_data)
  147. {
  148. // get the address (pointer) of the global structure
  149. ptr_s = &s;
  150. // set up default values
  151. //(GUI--IPS_defult_Parameters + randomness)
  152. prepare_IPS(ptr_s);
  153. // declare a bunch of Gtk widgets for the GUI
  154. GtkWidget *window,*grid, *image_lattice,*frame;
  155. // Gdk Pixbuffer to draw an image
  156. GdkPixbuf *pixbuf;
  157. // Create a window and set its title
  158. window = gtk_application_window_new (app);
  159. gtk_window_set_title (GTK_WINDOW (window), "Langton Ant IPS");
  160. gtk_window_set_resizable (GTK_WINDOW(window), FALSE);
  161. // Make a grid to pack our Widgets
  162. grid = gtk_grid_new ();
  163. // Pack the grid in the window
  164. gtk_container_add (GTK_CONTAINER (window), grid);
  165. // Parameter control
  166. frame = render_parameter();
  167. gtk_grid_attach (GTK_GRID (grid), frame, 0, 0, 4, 1);
  168. // Lattice configuration image
  169. image_lattice = render_image();
  170. gtk_grid_attach (GTK_GRID (grid), image_lattice, 0, 1, 4, 1); // position (0,1) spanning 5 col and 1 raw)
  171. // Simulation Control
  172. frame = render_simulation_ctrls(window, image_lattice);
  173. gtk_grid_attach (GTK_GRID (grid), frame, 0, 2, 4, 1);
  174. // Show the window and all widgets
  175. gtk_widget_show_all (window);
  176. }
  177. // Main
  178. int main (int argc, char **argv)
  179. {
  180. GtkApplication *app;
  181. int status;
  182. app = gtk_application_new ("keymer.lab.CP_IPS", G_APPLICATION_FLAGS_NONE);
  183. g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
  184. status = g_application_run (G_APPLICATION (app), argc, argv);
  185. g_object_unref (app);
  186. return status;
  187. }