ezgl  1.0.1
An Easy Graphics & GUI Library
application.hpp
1 /*
2  * Copyright 2019-2024 University of Toronto
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * Authors: Mario Badr, Sameh Attia, Tanner Young-Schultz,
17  * Sebastian Lievano Arzayus and Vaughn Betz
18  */
19 
20 #ifndef EZGL_APPLICATION_HPP
21 #define EZGL_APPLICATION_HPP
22 
23 #include "ezgl/canvas.hpp"
24 #include "ezgl/control.hpp"
25 #include "ezgl/callback.hpp"
26 #include "ezgl/graphics.hpp"
27 #include "ezgl/color.hpp"
28 
29 #include <map>
30 #include <memory>
31 #include <string>
32 #include <ctime>
33 #include <vector>
34 
35 #include <gtk/gtk.h>
36 
40 namespace ezgl {
41 
42 // A flag to specify whether the GUI is built from an XML file or an XML resource
43 #ifndef ECE297
44 const bool build_ui_from_file = false;
45 #else
46 const bool build_ui_from_file = true;
47 #endif
48 
49 class application;
50 
56 using connect_g_objects_fn = void (*)(application *app);
57 
61 using setup_callback_fn = void (*)(application *app, bool new_window);
62 
66 using button_callback_fn = void (*)(GtkWidget *widget, application *app);
67 
71 using mouse_callback_fn = void (*)(application *app, GdkEventButton *event, double x, double y);
72 
76 using key_callback_fn = void (*)(application *app, GdkEventKey *event, char *key_name);
77 
81 using combo_box_callback_fn = void (*)(GtkComboBoxText* self, application* app);
82 
86 using dialog_callback_fn = void (*)(GtkDialog* self, gint response_id, application* app);
87 
95 class application {
96 public:
103  struct settings {
107  std::string main_ui_resource;
108 
112  std::string window_identifier;
113 
117  std::string canvas_identifier;
118 
127 
140 
145  : main_ui_resource(build_ui_from_file ? "main_ui" : "/ezgl/main.ui"), window_identifier("MainWindow"), canvas_identifier("MainCanvas"), application_identifier("ezgl.app"),
146  setup_callbacks(nullptr)
147  {
148  // Uniquify the application_identifier by appending a time stamp,
149  // so that each instance of the same program has a different application ID.
150  // This allows multiple instances of the program to run independelty.
151  application_identifier += ".t" + std::to_string(std::time(nullptr));
152  }
153 
157  settings(std::string m_resource, std::string w_identifier, std::string c_identifier, std::string a_identifier = "ezgl.app",
158  connect_g_objects_fn s_callbacks = nullptr)
159  : main_ui_resource(m_resource), window_identifier(w_identifier), canvas_identifier(c_identifier), application_identifier(a_identifier),
160  setup_callbacks(s_callbacks)
161  {
162  // Uniquify the application_identifier by appending a time stamp,
163  // so that each instance of the same program has a different application ID.
164  // This allows multiple instance of the program to run independelty.
165  application_identifier += ".t" + std::to_string(std::time(nullptr));
166  }
167  };
168 
169 public:
176 
191  canvas *add_canvas(std::string const &canvas_id,
192  draw_canvas_fn draw_callback,
193  rectangle coordinate_system,
194  color background_color = WHITE);
195 
214  void create_button(const char *button_text,
215  int left,
216  int top,
217  int width,
218  int height,
219  button_callback_fn button_func);
220 
233  void create_button(const char *button_text, int insert_row, button_callback_fn button_func);
234 
243  bool destroy_button(const char *button_text_to_destroy);
244 
245 
254  void change_button_text(const char *button_text, const char *new_button_text);
255 
256 
267  void create_label(int insert_row, const char *label_text);
268 
280  int left,
281  int top,
282  int width,
283  int height,
284  const char *label_text
285  );
286 
306  const char* id_string,
307  int insert_row,
308  combo_box_callback_fn combo_box_fn,
309  std::vector<std::string> options);
310 
332  const char* id_string,
333  int left,
334  int top,
335  int width,
336  int height,
337  combo_box_callback_fn combo_box_fn,
338  std::vector<std::string> options);
339 
349  void change_combo_box_text_options(const char* name, std::vector<std::string> new_options);
350 
367  void create_dialog_window(dialog_callback_fn cbk_fn, const char* dialog_title, const char *window_text);
368 
378  void create_popup_message(const char* title, const char *message);
379 
391  void create_popup_message_with_callback(dialog_callback_fn cbk_fn, const char* title, const char *message);
392 
399  bool destroy_widget(const char* widget_name);
400 
413  GtkWidget* find_widget(const char* widget_name);
414 
422  void update_message(std::string const &message);
423 
433  void change_canvas_world_coordinates(std::string const &canvas_id, rectangle coordinate_system);
434 
441 
448 
456 
474  int run(setup_callback_fn initial_setup_user_callback,
475  mouse_callback_fn mouse_press_user_callback,
476  mouse_callback_fn mouse_move_user_callback,
477  key_callback_fn key_press_user_callback);
478 
483 
487  application(application const &) = delete;
488 
492  application &operator=(application const &) = delete;
493 
497  application(application &&) = default;
498 
503 
515  canvas *get_canvas(std::string const &canvas_id) const;
516 
528  GObject *get_object(gchar const *name) const;
529 
533  std::string get_main_window_id() const
534  {
535  return m_window_id;
536  }
537 
541  std::string get_main_canvas_id() const
542  {
543  return m_canvas_id;
544  }
545 
549  void quit();
550 
551 private:
552  // The package path to the XML file that describes the UI.
553  std::string m_main_ui;
554 
555  // The ID of the main window to add to our GTK application.
556  std::string m_window_id;
557 
558  // The ID of the main canvas. This canvas is where ezgl renderer calls (e.g. draw_line) display
559  std::string m_canvas_id;
560 
561  // The ID of the GTK application
562  std::string m_application_id;
563 
564  // The GTK application.
565  GtkApplication *m_application;
566 
567  // The GUI builder that parses an XML user interface.
568  GtkBuilder *m_builder;
569 
570  // The function to call when the application is starting up.
571  connect_g_objects_fn m_register_callbacks;
572 
573  // The collection of canvases added to the application.
574  std::map<std::string, std::unique_ptr<canvas>> m_canvases;
575 
576  // A flag that indicates if the run() was called before or not to allow multiple reruns
577  bool first_run;
578 
579  // A flag that indicates if we are resuming an older run to allow proper quitting
580  bool resume_run;
581 
582 private:
583  // Called when our GtkApplication is initialized for the first time.
584  static void startup(GtkApplication *gtk_app, gpointer user_data);
585 
586  // Called when GTK activates our application for the first time.
587  static void activate(GtkApplication *gtk_app, gpointer user_data);
588 
589  // Called during application activation to setup the default callbacks for the prebuilt buttons
590  static void register_default_buttons_callbacks(application *application);
591 
592  // Called during application activation to setup the default callbacks for the mouse and key events
593  static void register_default_events_callbacks(application *application);
594 
595 public:
596  // The user-defined initial setup callback function
597  setup_callback_fn initial_setup_callback;
598 
599  // The user-defined callback function for handling mouse press
600  mouse_callback_fn mouse_press_callback;
601 
602  // The user-defined callback function for handling mouse move
603  mouse_callback_fn mouse_move_callback;
604 
605  // The user-defined callback function for handling keyboard press
606  key_callback_fn key_press_callback;
607 };
608 
616 void set_disable_event_loop(bool new_setting);
617 }
618 
619 #endif //EZGL_APPLICATION_HPP
The core application.
Definition: application.hpp:95
application(application const &)=delete
Copies are disabled.
void create_combo_box_text(const char *id_string, int left, int top, int width, int height, combo_box_callback_fn combo_box_fn, std::vector< std::string > options)
Create a combo box text object.
application(application &&)=default
Ownership of an application is transferrable.
void create_dialog_window(dialog_callback_fn cbk_fn, const char *dialog_title, const char *window_text)
Creates a simple dialog window with "OK" and "CANCEL" buttons.
GtkWidget * find_widget(const char *widget_name)
Searches inner grid for widget with given name.
~application()
Destructor.
renderer * get_renderer()
Get a renderer that can be used to draw on top of the main canvas.
std::string get_main_canvas_id() const
Get the ID of the main canvas.
Definition: application.hpp:541
int run(setup_callback_fn initial_setup_user_callback, mouse_callback_fn mouse_press_user_callback, mouse_callback_fn mouse_move_user_callback, key_callback_fn key_press_user_callback)
Run the application.
void change_canvas_world_coordinates(std::string const &canvas_id, rectangle coordinate_system)
Change the coordinate system of a previously created canvas.
void create_popup_message_with_callback(dialog_callback_fn cbk_fn, const char *title, const char *message)
Creates a popup message with a "DONE" button.
void create_label(int left, int top, int width, int height, const char *label_text)
Create a label object in Inner Grid at specified position/dimensions.
std::string get_main_window_id() const
Get the ID of the main window.
Definition: application.hpp:533
void quit()
Quit the application.
canvas * add_canvas(std::string const &canvas_id, draw_canvas_fn draw_callback, rectangle coordinate_system, color background_color=WHITE)
Add a canvas to the application.
bool destroy_button(const char *button_text_to_destroy)
Deletes a button by its label (displayed text)
void change_combo_box_text_options(const char *name, std::vector< std::string > new_options)
changes list of options to new given vector.
void update_message(std::string const &message)
Update the message in the status bar.
void flush_drawing()
Flush the drawing done by the renderer to the on-screen buffer.
void refresh_drawing()
redraw the main canvas
application & operator=(application const &)=delete
Copies are disabled.
bool destroy_widget(const char *widget_name)
Destroys widget.
GObject * get_object(gchar const *name) const
Retrieve a GLib Object (i.e., a GObject).
void create_button(const char *button_text, int insert_row, button_callback_fn button_func)
Add a button convenience Adds a button at a given row index (assuming buttons in the right bar use 1 ...
application & operator=(application &&)=default
Ownership of an application is transferrable.
void change_button_text(const char *button_text, const char *new_button_text)
Change the label of the button (displayed text)
application(application::settings s)
Create an application.
void create_label(int insert_row, const char *label_text)
Creates a label object (a text label) in the Inner Grid.
void create_popup_message(const char *title, const char *message)
Creates a popup message with a "DONE" button.
void create_button(const char *button_text, int left, int top, int width, int height, button_callback_fn button_func)
Add a button that you can click on to call its callback function.
canvas * get_canvas(std::string const &canvas_id) const
Retrieve a pointer to a canvas that was previously added to the application.
void create_combo_box_text(const char *id_string, int insert_row, combo_box_callback_fn combo_box_fn, std::vector< std::string > options)
Creates a GTK combo box object in Inner Grid A combo box is a dropdown menu with different options.
Responsible for creating, destroying, and maintaining the rendering context of a GtkWidget.
Definition: canvas.hpp:54
Represents a rectangle as two diagonally opposite points.
Definition: rectangle.hpp:31
Provides functions to draw primitives (e.g., lines, shapes) to a rendering context (the MainCanvas).
Definition: graphics.hpp:173
A library for creating a graphical user interface.
Definition: application.hpp:40
void(*)(application *app) connect_g_objects_fn
The signature of a function that connects GObject to functions via signals.
Definition: application.hpp:56
void(*)(application *app, GdkEventButton *event, double x, double y) mouse_callback_fn
The signature of a user-defined callback function for mouse events.
Definition: application.hpp:71
void(*)(application *app, GdkEventKey *event, char *key_name) key_callback_fn
The signature of a user-defined callback function for keyboard events.
Definition: application.hpp:76
void set_disable_event_loop(bool new_setting)
Set the disable_event_loop flag to new_setting Call with new_setting == true to make the event_loop i...
void(*)(application *app, bool new_window) setup_callback_fn
The signature of a setup callback function.
Definition: application.hpp:61
void(*)(GtkComboBoxText *self, application *app) combo_box_callback_fn
The signature of a user-defined callback function for the combo-box "changed" signal.
Definition: application.hpp:81
void(*)(GtkDialog *self, gint response_id, application *app) dialog_callback_fn
The signature of a user-defined callback function for a dialog window.
Definition: application.hpp:86
void(*)(renderer *) draw_canvas_fn
The signature of a function that draws to an ezgl::canvas.
Definition: canvas.hpp:43
void(*)(GtkWidget *widget, application *app) button_callback_fn
The signature of a button callback function.
Definition: application.hpp:66
Configuration settings for the application.
Definition: application.hpp:103
std::string application_identifier
A user-defined name of the GTK application.
Definition: application.hpp:126
std::string window_identifier
The name of the main window in the XML file.
Definition: application.hpp:112
std::string canvas_identifier
The name of the main canvas in the XML file.
Definition: application.hpp:117
connect_g_objects_fn setup_callbacks
Specify the function that will connect GUI objects to user-defined callbacks.
Definition: application.hpp:139
settings(std::string m_resource, std::string w_identifier, std::string c_identifier, std::string a_identifier="ezgl.app", connect_g_objects_fn s_callbacks=nullptr)
Create the settings structure with user-defined values.
Definition: application.hpp:157
std::string main_ui_resource
The resource/file path that contains the XML file, which describes the GUI.
Definition: application.hpp:107
settings()
Create the settings structure with default values.
Definition: application.hpp:144
Represents a color as a mixture or red, green, and blue as well as the transparency level.
Definition: color.hpp:31