[librest] examples: rest demo gui application



commit 0e742cc5aef96081abff847a3a2979f2d4def6b3
Author: Günther Wagner <info gunibert de>
Date:   Tue Jan 18 22:51:18 2022 +0100

    examples: rest demo gui application

 examples/demo/demo-main.c                      |  54 ++++++++
 examples/demo/demo-rest-page.c                 | 173 +++++++++++++++++++++++++
 examples/demo/demo-rest-page.h                 |  34 +++++
 examples/demo/demo-rest-page.ui                |  59 +++++++++
 examples/demo/demo-window.c                    |  84 ++++++++++++
 examples/demo/demo-window.h                    |  33 +++++
 examples/demo/demo-window.ui                   |  51 ++++++++
 examples/demo/meson.build                      |  25 ++++
 examples/demo/org.gnome.RestDemo.gresource.xml |   7 +
 examples/demo/org.gnome.RestDemo.json          |  44 +++++++
 examples/meson.build                           |   2 +
 meson.build                                    |   1 +
 12 files changed, 567 insertions(+)
---
diff --git a/examples/demo/demo-main.c b/examples/demo/demo-main.c
new file mode 100644
index 0000000..b31d7dc
--- /dev/null
+++ b/examples/demo/demo-main.c
@@ -0,0 +1,54 @@
+/* main.c
+ *
+ * Copyright 2022 Günther Wagner <info gunibert de>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <gtk/gtk.h>
+#include <adwaita.h>
+#include <gtksourceview/gtksource.h>
+#include "demo-window.h"
+
+static void
+on_activate (GApplication *app, gpointer user_data)
+{
+  GtkWindow *active_window;
+
+  active_window = gtk_application_get_active_window (GTK_APPLICATION (app));
+  if (active_window == NULL)
+    {
+      active_window = demo_window_new (GTK_APPLICATION (app));
+    }
+
+  gtk_window_present (active_window);
+}
+
+gint
+main (gint   argc,
+      gchar *argv[])
+{
+  adw_init ();
+  gtk_source_init ();
+
+  g_set_prgname ("librest-demo");
+  g_set_application_name ("librest-demo");
+
+  GtkApplication *app = gtk_application_new ("org.gnome.RestDemo", G_APPLICATION_FLAGS_NONE);
+  g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL);
+
+  return g_application_run (G_APPLICATION (app), argc, argv);
+}
diff --git a/examples/demo/demo-rest-page.c b/examples/demo/demo-rest-page.c
new file mode 100644
index 0000000..05290c0
--- /dev/null
+++ b/examples/demo/demo-rest-page.c
@@ -0,0 +1,173 @@
+/* demo-rest-page.c
+ *
+ * Copyright 2022 Günther Wagner <info gunibert de>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "demo-rest-page.h"
+#include <rest/rest.h>
+#include <gtksourceview/gtksource.h>
+#include <json-glib/json-glib.h>
+
+struct _DemoRestPage
+{
+  GtkBox parent_instance;
+
+  GtkWidget *httpmethod;
+  GtkWidget *host;
+  GtkWidget *function;
+  GtkWidget *sourceview;
+  GtkWidget *body;
+  GtkWidget *notebook;
+};
+
+G_DEFINE_FINAL_TYPE (DemoRestPage, demo_rest_page, GTK_TYPE_BOX)
+
+DemoRestPage *
+demo_rest_page_new (void)
+{
+  return g_object_new (DEMO_TYPE_REST_PAGE, NULL);
+}
+
+static void
+demo_rest_page_finalize (GObject *object)
+{
+  DemoRestPage *self = (DemoRestPage *)object;
+
+  G_OBJECT_CLASS (demo_rest_page_parent_class)->finalize (object);
+}
+
+static void
+populate_http_method (DemoRestPage *self)
+{
+  GtkDropDown *dropdown = GTK_DROP_DOWN (self->httpmethod);
+
+  GtkStringList *model = gtk_string_list_new ((const char *[]){
+                                              "GET",
+                                              "POST",
+                                              "DELETE",
+                                              "UPDATE",
+                                              NULL});
+  gtk_drop_down_set_model (dropdown, G_LIST_MODEL (model));
+}
+
+static void
+set_json_response (DemoRestPage  *self,
+                   RestProxyCall *call)
+{
+  const gchar *payload = rest_proxy_call_get_payload (call);
+  goffset payload_length = rest_proxy_call_get_payload_length (call);
+
+  JsonParser *parser = json_parser_new ();
+  json_parser_load_from_data (parser, payload, payload_length, NULL);
+  JsonNode *root = json_parser_get_root (parser);
+
+  GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (self->sourceview));
+  gtk_text_buffer_set_text (buffer, json_to_string (root, TRUE), -1);
+
+  GtkSourceLanguageManager *manager = gtk_source_language_manager_get_default ();
+  GtkSourceLanguage *lang = gtk_source_language_manager_guess_language (manager, NULL, "application/json");
+  gtk_source_buffer_set_language (GTK_SOURCE_BUFFER (buffer), lang);
+}
+
+static void
+call_returned (GObject      *object,
+               GAsyncResult *result,
+               gpointer      user_data)
+{
+  DemoRestPage *self = (DemoRestPage *)user_data;
+  RestProxyCall *call = (RestProxyCall *)object;
+  g_autoptr(GError) error = NULL;
+
+  g_assert (G_IS_OBJECT (object));
+  g_assert (G_IS_ASYNC_RESULT (result));
+
+  rest_proxy_call_invoke_finish (call, result, &error);
+  GHashTable *response_headers = rest_proxy_call_get_response_headers (call);
+  gchar *content_type = g_hash_table_lookup (response_headers, "Content-Type");
+  if (content_type != NULL)
+    {
+      if (g_strcmp0 (content_type, "application/json") == 0)
+        set_json_response (self, call);
+    }
+}
+
+static void
+on_send_clicked (GtkButton *btn,
+                 gpointer   user_data)
+{
+  DemoRestPage *self = (DemoRestPage *)user_data;
+  const gchar *http;
+  const gchar *url;
+  const gchar *function;
+  guint selected_method;
+  GListModel *model;
+
+  g_return_if_fail (DEMO_IS_REST_PAGE (self));
+
+  selected_method = gtk_drop_down_get_selected (GTK_DROP_DOWN (self->httpmethod));
+  model = gtk_drop_down_get_model (GTK_DROP_DOWN (self->httpmethod));
+  http = gtk_string_list_get_string (GTK_STRING_LIST (model), selected_method);
+
+  url = gtk_editable_get_text (GTK_EDITABLE (self->host));
+  function = gtk_editable_get_text (GTK_EDITABLE (self->function));
+  RestProxy *proxy = rest_proxy_new (url, FALSE);
+
+  RestProxyCall *call = rest_proxy_new_call (proxy);
+  rest_proxy_call_set_method (call, http);
+  rest_proxy_call_set_function (call, function);
+  rest_proxy_call_invoke_async (call, NULL, call_returned, self);
+}
+
+static void
+demo_rest_page_class_init (DemoRestPageClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+  object_class->finalize = demo_rest_page_finalize;
+  gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/RestDemo/demo-rest-page.ui");
+  gtk_widget_class_bind_template_child (widget_class, DemoRestPage, httpmethod);
+  gtk_widget_class_bind_template_child (widget_class, DemoRestPage, host);
+  gtk_widget_class_bind_template_child (widget_class, DemoRestPage, function);
+  gtk_widget_class_bind_template_child (widget_class, DemoRestPage, sourceview);
+  gtk_widget_class_bind_template_child (widget_class, DemoRestPage, body);
+  gtk_widget_class_bind_template_child (widget_class, DemoRestPage, notebook);
+  gtk_widget_class_bind_template_callback (widget_class, on_send_clicked);
+}
+
+static void
+demo_rest_page_init (DemoRestPage *self)
+{
+  gtk_widget_init_template (GTK_WIDGET (self));
+  populate_http_method (self);
+
+  GtkSourceStyleSchemeManager *manager = gtk_source_style_scheme_manager_get_default ();
+  GtkSourceStyleScheme *style = gtk_source_style_scheme_manager_get_scheme (manager, "Adwaita");
+  GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (self->sourceview));
+  gtk_source_buffer_set_style_scheme (GTK_SOURCE_BUFFER (buffer), style);
+
+  gtk_notebook_set_tab_label_text (GTK_NOTEBOOK (self->notebook), self->body, "Body");
+}
+
+GtkWidget *
+demo_rest_page_get_entry (DemoRestPage *self)
+{
+  g_return_val_if_fail (DEMO_IS_REST_PAGE (self), NULL);
+
+  return self->host;
+}
diff --git a/examples/demo/demo-rest-page.h b/examples/demo/demo-rest-page.h
new file mode 100644
index 0000000..9b02982
--- /dev/null
+++ b/examples/demo/demo-rest-page.h
@@ -0,0 +1,34 @@
+/* demo-rest-page.h
+ *
+ * Copyright 2022 Günther Wagner <info gunibert de>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define DEMO_TYPE_REST_PAGE (demo_rest_page_get_type())
+
+G_DECLARE_FINAL_TYPE (DemoRestPage, demo_rest_page, DEMO, REST_PAGE, GtkBox)
+
+DemoRestPage *demo_rest_page_new (void);
+GtkWidget *demo_rest_page_get_entry (DemoRestPage *self);
+
+G_END_DECLS
diff --git a/examples/demo/demo-rest-page.ui b/examples/demo/demo-rest-page.ui
new file mode 100644
index 0000000..417a96c
--- /dev/null
+++ b/examples/demo/demo-rest-page.ui
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <requires lib="gtk" version="4.0"/>
+  <template class="DemoRestPage" parent="GtkBox">
+    <property name="orientation">vertical</property>
+    <property name="margin-start">6</property>
+    <property name="margin-end">6</property>
+    <property name="margin-top">6</property>
+    <property name="margin-bottom">6</property>
+    <property name="spacing">6</property>
+    <child>
+      <object class="GtkBox">
+        <property name="orientation">horizontal</property>
+        <property name="hexpand">true</property>
+        <child>
+          <object class="GtkDropDown" id="httpmethod">
+          </object>
+        </child>
+        <child>
+          <object class="GtkEntry" id="host">
+            <property name="hexpand">true</property>
+            <property name="placeholder-text">REST Host e. g. https://www.gitlab.com/api/v4/</property>
+          </object>
+        </child>
+        <child>
+          <object class="GtkEntry" id="function">
+            <property name="placeholder-text">REST Function</property>
+          </object>
+        </child>
+        <child>
+          <object class="GtkButton">
+            <property name="label">Send</property>
+            <signal name="clicked" handler="on_send_clicked" swapped="no" object="DemoRestPage"/>
+            <style>
+              <class name="suggested-action"/>
+            </style>
+          </object>
+        </child>
+        <style>
+          <class name="linked"/>
+        </style>
+      </object>
+    </child>
+    <child>
+      <object class="GtkNotebook" id="notebook">
+        <child>
+          <object class="GtkScrolledWindow" id="body">
+            <property name="vexpand">true</property>
+            <child>
+              <object class="GtkSourceView" id="sourceview">
+                <property name="monospace">true</property>
+              </object>
+            </child>
+          </object>
+        </child>
+      </object>
+    </child>
+  </template>
+</interface>
diff --git a/examples/demo/demo-window.c b/examples/demo/demo-window.c
new file mode 100644
index 0000000..32681d5
--- /dev/null
+++ b/examples/demo/demo-window.c
@@ -0,0 +1,84 @@
+/* demo-window.c
+ *
+ * Copyright 2022 Günther Wagner <info gunibert de>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "demo-window.h"
+#include "demo-rest-page.h"
+
+struct _DemoWindow
+{
+  AdwApplicationWindow parent_instance;
+  GtkWidget *tabview;
+};
+
+G_DEFINE_FINAL_TYPE (DemoWindow, demo_window, ADW_TYPE_APPLICATION_WINDOW)
+
+GtkWindow *
+demo_window_new (GtkApplication *app)
+{
+  return g_object_new (DEMO_TYPE_WINDOW,
+                       "application", app,
+                       NULL);
+}
+
+static void
+demo_window_finalize (GObject *object)
+{
+  DemoWindow *self = (DemoWindow *)object;
+
+  G_OBJECT_CLASS (demo_window_parent_class)->finalize (object);
+}
+
+static void
+on_add_tab_clicked (GtkButton *btn,
+                    gpointer   user_data)
+{
+  DemoWindow *self = (DemoWindow *)user_data;
+  DemoRestPage *page;
+  AdwTabPage *tabpage;
+  GtkWidget *entry;
+
+  g_return_if_fail (DEMO_IS_WINDOW (self));
+
+  page = demo_rest_page_new ();
+  adw_tab_view_append (ADW_TAB_VIEW (self->tabview), GTK_WIDGET (page));
+  tabpage = adw_tab_view_get_page (ADW_TAB_VIEW (self->tabview), GTK_WIDGET (page));
+  entry = demo_rest_page_get_entry (page);
+  g_object_bind_property (GTK_EDITABLE (entry), "text", tabpage, "title", G_BINDING_DEFAULT);
+}
+
+static void
+demo_window_class_init (DemoWindowClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+  object_class->finalize = demo_window_finalize;
+  gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/RestDemo/demo-window.ui");
+  gtk_widget_class_bind_template_child (widget_class, DemoWindow, tabview);
+  gtk_widget_class_bind_template_callback (widget_class, on_add_tab_clicked);
+}
+
+static void
+demo_window_init (DemoWindow *self)
+{
+  gtk_widget_init_template (GTK_WIDGET (self));
+
+  on_add_tab_clicked (NULL, self);
+}
diff --git a/examples/demo/demo-window.h b/examples/demo/demo-window.h
new file mode 100644
index 0000000..fc0e76a
--- /dev/null
+++ b/examples/demo/demo-window.h
@@ -0,0 +1,33 @@
+/* demo-window.h
+ *
+ * Copyright 2022 Günther Wagner <info gunibert de>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <adwaita.h>
+
+G_BEGIN_DECLS
+
+#define DEMO_TYPE_WINDOW (demo_window_get_type())
+
+G_DECLARE_FINAL_TYPE (DemoWindow, demo_window, DEMO, WINDOW, AdwApplicationWindow)
+
+GtkWindow *demo_window_new (GtkApplication *app);
+
+G_END_DECLS
diff --git a/examples/demo/demo-window.ui b/examples/demo/demo-window.ui
new file mode 100644
index 0000000..1216714
--- /dev/null
+++ b/examples/demo/demo-window.ui
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <requires lib="gtk" version="4.0"/>
+  <template class="DemoWindow" parent="AdwApplicationWindow">
+    <property name="title">Librest Demo</property>
+    <property name="default-width">900</property>
+    <property name="default-height">600</property>
+    <style>
+      <class name="devel"/>
+    </style>
+    <child>
+      <object class="GtkBox">
+        <property name="orientation">vertical</property>
+        <child>
+          <object class="GtkHeaderBar" id="headerbar">
+          </object>
+        </child>
+        <child>
+          <object class="GtkBox">
+            <property name="orientation">horizontal</property>
+            <child>
+              <object class="AdwTabBar">
+                <property name="view">tabview</property>
+                <property name="autohide">false</property>
+                <property name="end-action-widget">
+                  <object class="GtkButton">
+                    <signal name="clicked" handler="on_add_tab_clicked" object="DemoWindow" swapped="no"/>
+                    <child>
+                      <object class="GtkImage">
+                        <property name="icon-name">list-add-symbolic</property>
+                      </object>
+                    </child>
+                    <style>
+                      <class name="flat"/>
+                      <class name="end-action-widget"/>
+                    </style>
+                  </object>
+                </property>
+              </object>
+            </child>
+          </object>
+        </child>
+        <child>
+          <object class="AdwTabView" id="tabview">
+            <property name="vexpand">true</property>
+          </object>
+        </child>
+      </object>
+    </child>
+  </template>
+</interface>
diff --git a/examples/demo/meson.build b/examples/demo/meson.build
new file mode 100644
index 0000000..dae36b3
--- /dev/null
+++ b/examples/demo/meson.build
@@ -0,0 +1,25 @@
+demo_sources = [
+  'demo-main.c',
+  'demo-window.c',
+  'demo-rest-page.c',
+]
+
+demo_deps = [
+  dependency('libadwaita-1'),
+  dependency('gtksourceview-5'),
+  dependency('json-glib-1.0'),
+  librest_dep,
+]
+
+gnome = import('gnome')
+demo_gresources = gnome.compile_resources(
+  'demo-resources',
+  'org.gnome.RestDemo.gresource.xml',
+  c_name: 'demo'
+)
+
+executable('librest-demo',
+  demo_sources + demo_gresources,
+  dependencies: demo_deps,
+  install: true,
+)
diff --git a/examples/demo/org.gnome.RestDemo.gresource.xml b/examples/demo/org.gnome.RestDemo.gresource.xml
new file mode 100644
index 0000000..ecde4f3
--- /dev/null
+++ b/examples/demo/org.gnome.RestDemo.gresource.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gresources>
+  <gresource prefix="/org/gnome/RestDemo">
+    <file>demo-window.ui</file>
+    <file>demo-rest-page.ui</file>
+  </gresource>
+</gresources>
diff --git a/examples/demo/org.gnome.RestDemo.json b/examples/demo/org.gnome.RestDemo.json
new file mode 100644
index 0000000..a271a4b
--- /dev/null
+++ b/examples/demo/org.gnome.RestDemo.json
@@ -0,0 +1,44 @@
+{
+    "app-id" : "org.gnome.RestDemo",
+    "runtime" : "org.gnome.Platform",
+    "runtime-version" : "master",
+    "sdk" : "org.gnome.Sdk",
+    "command" : "librest-demo",
+    "finish-args" : [
+        "--share=network",
+        "--share=ipc",
+        "--socket=fallback-x11",
+        "--device=dri",
+        "--socket=wayland"
+    ],
+    "cleanup" : [
+        "/include",
+        "/lib/pkgconfig",
+        "/man",
+        "/share/doc",
+        "/share/gtk-doc",
+        "/share/man",
+        "/share/pkgconfig",
+        "*.la",
+        "*.a"
+    ],
+    "modules" : [
+        {
+            "name" : "librest-demo",
+            "builddir" : true,
+            "buildsystem" : "meson",
+            "sources" : [
+                {
+                    "type" : "git",
+                    "url" : "file:///var/home/gunibert/Projekte/librest"
+                }
+            ],
+            "config-opts" : [
+                "-Dgtk_doc=false"
+            ]
+        }
+    ],
+    "build-options" : {
+        "env" : {        }
+    }
+}
diff --git a/examples/meson.build b/examples/meson.build
index 375a72a..37ea0ca 100644
--- a/examples/meson.build
+++ b/examples/meson.build
@@ -24,3 +24,5 @@ foreach name : example_names
     include_directories: config_h_inc,
   )
 endforeach
+
+subdir('demo')
diff --git a/meson.build b/meson.build
index 2c6d4ba..9c08f05 100644
--- a/meson.build
+++ b/meson.build
@@ -119,6 +119,7 @@ summary({
     'Vapi': get_option('vapi'),
     'Documentation': get_option('gtk_doc'),
     'Tests': get_option('tests'),
+    'Examples': get_option('examples'),
     'Soup 2': get_option('soup2'),
   },
   section: 'Build',


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]