October 03, 2022

Creating a GUI with Ansi-C


 

The dominant cause for the upraising of object oriented programming language was the introduction of GUI operating systems like Windows. Since the 1990, the amount of dedicated OOP languages like Java, C#, Python and Ruby have grown exponentially and many programmers are convinced that they need the ability to create classes.
But from a technical point it is possible to create a gui app with the imperative C language as well. There are some prerequisites needed for example a tutorial about creating the widgets itself. [1] Also the programmer has to make sure that all the needed libraries are installed and that the correct compiler settings where chosen.
/* 	
  gcc -ansi 2_ansic.c $(pkg-config --cflags --libs gtk+-3.0) && ./a.out

*/
#include <stdio.h>
#include <gtk/gtk.h>

void show_about(GtkWidget *widget, gpointer data) {
  GtkWidget *dialog = gtk_about_dialog_new();
  gtk_about_dialog_set_program_name(GTK_ABOUT_DIALOG(dialog), "Sample program");
  gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(dialog), "0.1");
  gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(dialog),
     "The quick brown fox jumps over the lazy dog");
  gtk_dialog_run(GTK_DIALOG (dialog));
  gtk_widget_destroy(dialog);
}

void button_clicked(GtkWidget *widget, gpointer data) {
  printf("clicked\n");
}

void initwindow() {
  gtk_init(NULL, NULL);

  GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title(GTK_WINDOW(window), "Hello World");
  gtk_window_set_default_size(GTK_WINDOW(window), 400, 300);

  GtkWidget *fixed = gtk_fixed_new();
  gtk_container_add(GTK_CONTAINER(window), fixed);

  GtkWidget *btn1 = gtk_button_new_with_label("Button");
  gtk_fixed_put(GTK_FIXED(fixed), btn1, 150, 50);
  gtk_widget_set_size_request(btn1, 80, 30);

  GtkWidget *entry1 = gtk_entry_new();
  gtk_fixed_put(GTK_FIXED(fixed), entry1, 150, 5);

  /* events */
  /*g_signal_connect(G_OBJECT(btn1), "clicked", G_CALLBACK(button_clicked), NULL);*/
  g_signal_connect(G_OBJECT(btn1), "clicked", G_CALLBACK(show_about), NULL);
  g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
  gtk_widget_show_all(window);
  gtk_main();
}

int main() {
  initwindow();
  return 0;
}
Then it is possible to create a simple window on the screen which includes the ability to show a message box.
There are some differences available to a normal python script which is producing the same result. The main difference is, that the C language is working with pointers. The second difference is, that it is not possible to create any sort of classes. In theory there is a workaround available. C has a built in module mechanism, which means to define variables in files and use functions in the same file to get access to the variable. And the pointer arithmetic is some sort of extra effort which has to be done by the programmer to make sure that the source code is working.
The main advantage of the shown ansi-c code in contrast to a python script is, that the program can be executed in a production environment. The created binary file has a size of only 18kb and runs with the maximum performance.
The open question is what will happen if the programs becomes larger. The main cause why OOP languages were introduced is to manage the complexity. In theory the same purpose can be realized with the mentioned module concept of C, but the amount of literature about the topic is very little.