]> git.plutz.net Git - gladerunner/commitdiff
initial commit
authorPaul Hänsch <paul@plutz.net>
Sun, 12 Jul 2026 17:01:40 +0000 (19:01 +0200)
committerPaul Hänsch <paul@plutz.net>
Sun, 12 Jul 2026 17:01:40 +0000 (19:01 +0200)
.gitignore [new file with mode: 0644]
Makefile [new file with mode: 0644]
glade1.c [new file with mode: 0644]
glade1.glade [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..e4edb2d
--- /dev/null
@@ -0,0 +1 @@
+glade1
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..639b938
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,8 @@
+default: glade1
+.PHONY: default
+
+CFLAGS = $(shell pkg-config --cflags --libs gtk+-3.0)
+CFLAGS += -rdynamic
+
+%: %.c
+       cc -o "$@" "$<" ${CFLAGS}
diff --git a/glade1.c b/glade1.c
new file mode 100644 (file)
index 0000000..2a2d79d
--- /dev/null
+++ b/glade1.c
@@ -0,0 +1,151 @@
+#include <gtk/gtk.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+static GtkBuilder *builder;
+
+// typedef struct wdg_command {
+//   GType wdg;
+//   const char *cmd;
+//   void (*action)(GtkTextView*, char*);
+// } wdg_command;
+// 
+// const wdg_command action[] = {
+//   { GTK_TYPE_TEXT_VIEW, "set", &ca_text_view }
+// };
+
+void app_quit(GtkWidget *wdg, gpointer user_data) {
+  exit(0);
+}
+
+void text_content(GtkWidget *wdg, gpointer user_data) {
+  GtkEntry *e;
+  if (GTK_IS_ENTRY(wdg)) {
+    e = GTK_ENTRY( wdg );
+    printf( "ENTRY:%s:%s\n",
+            gtk_buildable_get_name(GTK_BUILDABLE(wdg)),
+            gtk_entry_buffer_get_text(  gtk_entry_get_buffer( e ) )
+          );
+  }
+}
+
+void button_click(GtkWidget *wdg, gpointer d) {
+  printf( "BUTTON:%s:clicked\n",
+          gtk_buildable_get_name(GTK_BUILDABLE(wdg))
+        );
+}
+
+// ====== CLI ACTIONS =======
+
+void a_widget_enable(GtkWidget *w) {
+  gtk_widget_set_sensitive(w, TRUE);
+}
+void a_widget_disable(GtkWidget *w) {
+  gtk_widget_set_sensitive(w, FALSE);
+}
+
+void a_text_view_set(GtkTextView *v, char *c) {
+  gtk_text_buffer_set_text(
+    gtk_text_view_get_buffer( v ), c, -1
+  );
+}
+
+void a_button(GtkButton *w, char *cli) {
+  char *cmd = strtok(cli, "    \n");
+
+  if (!w || !cmd || !cmd[0]) return;
+  else if (!strcmp(cli, "enable"))   a_widget_enable(GTK_WIDGET(w));
+  else if (!strcmp(cli, "disable")) a_widget_disable(GTK_WIDGET(w));
+}
+void a_entry(GtkEntry *w, char *cli) {
+  char *cmd = strtok(cli, "    \n");
+
+  if (!w || !cmd || !cmd[0]) return;
+  else if (!strcmp(cli, "enable"))   a_widget_enable(GTK_WIDGET(w));
+  else if (!strcmp(cli, "disable")) a_widget_disable(GTK_WIDGET(w));
+  else if (!strcmp(cli, "lock"))   gtk_editable_set_editable(GTK_EDITABLE(w), FALSE);
+  else if (!strcmp(cli, "unlock")) gtk_editable_set_editable(GTK_EDITABLE(w), TRUE);
+}
+void a_window(GtkWindow *w, char *cli) {
+  char *cmd = strtok(cli, "    \n");
+
+  if (!w || !cmd || !cmd[0]) return;
+  else if (!strcmp(cli, "enable"))   a_widget_enable(GTK_WIDGET(w));
+  else if (!strcmp(cli, "disable")) a_widget_disable(GTK_WIDGET(w));
+}
+void a_text_view(GtkTextView *w, char *cli) {
+  char *cmd = strtok(cli, "    \n");
+
+  if (!w || !cmd || !cmd[0]) return;
+  else if (!strcmp(cli, "set"))      a_text_view_set(w, strtok(NULL, ""));
+  else if (!strcmp(cli, "enable"))  a_widget_enable(GTK_WIDGET(w));
+  else if (!strcmp(cli, "disable")) a_widget_disable(GTK_WIDGET(w));
+  else if (!strcmp(cli, "lock"))   gtk_text_view_set_editable(w, FALSE);
+  else if (!strcmp(cli, "unlock")) gtk_text_view_set_editable(w, TRUE);
+}
+
+void a_widget(GtkWidget *wdg, char *cli) {
+  if (!wdg) return;
+  else if (GTK_IS_BUTTON(wdg))       a_button( GTK_BUTTON(wdg),    cli );
+  else if (GTK_IS_ENTRY(wdg))         a_entry( GTK_ENTRY(wdg),     cli );
+  else if (GTK_IS_WINDOW(wdg))       a_window( GTK_WINDOW(wdg),    cli );
+  else if (GTK_IS_TEXT_VIEW(wdg)) a_text_view( GTK_TEXT_VIEW(wdg), cli );
+}
+
+void a_command(char *cli) {
+  GtkWidget *wdg;
+  char *wid = strtok(cli, "    \n");  // Separator: Space, Tab
+
+  if ( wdg = GTK_WIDGET(gtk_builder_get_object(builder, wid)) ) {
+    a_widget(wdg, strtok(NULL, ""));
+  }
+}
+
+gboolean idle_readline(gpointer d) {
+  // GtkBuilder *bld = GTK_BUILDER(d);
+  static char buf[128];
+  int len;
+
+  if ( (len = read(0, &buf, 127)) > 0 ) {
+    buf[len] = 0;
+    a_command(buf);
+  }
+  return 1;
+}
+
+void init_widgets(gpointer wp, gpointer data) {
+  GtkWidget *wdg;
+
+  fcntl(0, F_SETFL, fcntl(0, F_GETFL) | O_NONBLOCK);
+
+  if (GTK_IS_WIDGET(wp)) { 
+    wdg = GTK_WIDGET(wp);
+    printf("WIDGET:%s:load\n", gtk_widget_get_name(wdg));
+
+    if      (GTK_IS_BUTTON(wdg)) g_signal_connect(wdg, "clicked", G_CALLBACK(button_click), NULL);
+    else if (GTK_IS_ENTRY(wdg) ) g_signal_connect(wdg, "changed", G_CALLBACK(text_content), NULL);
+    else if (GTK_IS_WINDOW(wdg)) g_signal_connect(wdg, "destroy", G_CALLBACK(app_quit), NULL);
+
+  } else if (GTK_IS_STATUS_ICON(wp)) {
+    // printf("WIDGET:%s:load\n", gtk_status_icon_get_title(GTK_STATUS_ICON(wp)));
+    printf("WIDGET:StatusIcon:load\n");
+    g_signal_connect(wp, "activate", G_CALLBACK(button_click), NULL);
+  }
+}
+
+int main(int argc, char *argv[]) {
+  GSList *widgets;
+
+  gtk_init(&argc, &argv);
+  builder = gtk_builder_new_from_file("glade1.glade");
+  widgets = gtk_builder_get_objects(builder);
+  g_slist_foreach(widgets, *init_widgets, NULL);
+  g_slist_free(widgets);
+
+  g_idle_add(idle_readline, builder);
+  // gtk_builder_connect_signals(builder, NULL);
+
+  gtk_main();
+  return 0;
+}
diff --git a/glade1.glade b/glade1.glade
new file mode 100644 (file)
index 0000000..dcc665c
--- /dev/null
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.40.0 -->
+<interface>
+  <requires lib="gtk+" version="3.24"/>
+  <object class="GtkStatusIcon" id="tray">
+    <property name="icon-name">applications-science</property>
+    <property name="title" translatable="yes">LLameAss</property>
+  </object>
+  <object class="GtkWindow" id="win1">
+    <property name="visible">True</property>
+    <property name="can-focus">False</property>
+    <property name="icon-name">applications-science</property>
+    <signal name="destroy" handler="app_quit" swapped="no"/>
+    <child>
+      <object class="GtkBox">
+        <property name="visible">True</property>
+        <property name="can-focus">False</property>
+        <property name="orientation">vertical</property>
+        <child>
+          <object class="GtkTextView" id="view">
+            <property name="visible">True</property>
+            <property name="can-focus">True</property>
+            <property name="vexpand">True</property>
+            <property name="editable">False</property>
+          </object>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="input">
+            <property name="name">input</property>
+            <property name="visible">True</property>
+            <property name="can-focus">True</property>
+            <signal name="changed" handler="foo" swapped="no"/>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkButton" id="button">
+            <property name="label" translatable="yes">button</property>
+            <property name="visible">True</property>
+            <property name="can-focus">True</property>
+            <property name="receives-default">True</property>
+            <signal name="clicked" handler="app_quit" swapped="no"/>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">2</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+  </object>
+</interface>