--- a/gplugin-gtk4/data/gplugin-gtk.gresource.xml Mon Sep 26 00:03:15 2022 -0500
+++ b/gplugin-gtk4/data/gplugin-gtk.gresource.xml Mon Sep 26 00:42:07 2022 -0500
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresource prefix="/org/imfreedom/keep/gplugin/gplugin-gtk/">
+ <file compressed="true">plugin-page.ui</file> <file compressed="true">plugin-row.ui</file>
<file compressed="true">view.ui</file>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gplugin-gtk4/data/plugin-page.ui Mon Sep 26 00:42:07 2022 -0500
@@ -0,0 +1,451 @@
+<?xml version="1.0" encoding="UTF-8"?> + <requires lib="gtk" version="4.0"/> + <template class="GPluginGtkPluginPage" parent="GtkBox"> + <property name="orientation">vertical</property> + <property name="spacing">12</property> + <object class="GtkBox"> + <property name="orientation">vertical</property> + <object class="GtkBox"> + <property name="orientation">horizontal</property> + <property name="valign">center</property> + <object class="GtkLabel"> + <property name="css-classes">title-1</property> + <property name="hexpand">1</property> + <closure type="gchararray" function="gplugin_gtk_lookup_plugin_name"> + <lookup name="info" type="GPluginPlugin"> + <lookup name="plugin">GPluginGtkPluginPage</lookup> + <lookup name="filename" type="GPluginPlugin"> + <lookup name="plugin">GPluginGtkPluginPage</lookup> + <property name="wrap">1</property> + <property name="wrap-mode">word-char</property> + <property name="xalign">0</property> + <property name="yalign">0</property> + <object class="GtkSwitch"> + <property name="halign">end</property> + <property name="valign">center</property> + <binding name="sensitive"> + <closure type="gboolean" function="gplugin_gtk_lookup_plugin_state_sensitivity"> + <lookup name="state" type="GPluginPlugin"> + <lookup name="plugin">GPluginGtkPluginPage</lookup> + <closure type="gboolean" function="gplugin_gtk_lookup_plugin_state"> + <lookup name="state" type="GPluginPlugin"> + <lookup name="plugin">GPluginGtkPluginPage</lookup> + <signal name="state-set" handler="gplugin_gtk_plugin_page_enable_state_set_cb"/> + <object class="GtkBox"> + <property name="orientation">horizontal</property> + <object class="GtkLabel"> + <property name="css-classes">dim-label</property> + <property name="halign">start</property> + <property name="hexpand">1</property> + <lookup name="summary" type="GPluginPluginInfo"> + <lookup name="info" type="GPluginPlugin"> + <lookup name="plugin">GPluginGtkPluginPage</lookup> + <property name="wrap">1</property> + <property name="wrap-mode">word-char</property> + <property name="ellipsize">end</property> + <property name="xalign">0</property> + <object class="GtkLabel"> + <property name="css-classes">dim-label</property> + <property name="halign">end</property> + <lookup name="version" type="GPluginPluginInfo"> + <lookup name="info" type="GPluginPlugin"> + <lookup name="plugin">GPluginGtkPluginPage</lookup> + <object class="GtkLabel" id="description"> + <lookup name="description" type="GPluginPluginInfo"> + <lookup name="info" type="GPluginPlugin"> + <lookup name="plugin">GPluginGtkPluginPage</lookup> + <property name="wrap">1</property> + <property name="xalign">0</property> + <object class="GtkFrame"> + <property name="child"> + <object class="GtkListBox"> + <property name="css-classes">rich-list</property> + <property name="selection-mode">none</property> + <property name="show-separators">1</property> + <object class="GtkListBoxRow"> + <property name="activatable">0</property> + <property name="child"> + <object class="GtkBox"> + <property name="spacing">12</property> + <object class="GtkLabel" id="authors-label"> + <property name="label" translatable="1">Authors</property> + <property name="xalign">0</property> + <object class="GtkLabel"> + <property name="selectable">1</property> + <closure type="gchararray" function="gplugin_gtk_plugin_page_newline_strjoinv_cb"> + <lookup name="authors" type="GPluginPluginInfo"> + <lookup name="info" type="GPluginPlugin"> + <lookup name="plugin">GPluginGtkPluginPage</lookup> + <relation name="labelled-by">authors-label</relation> + <object class="GtkListBoxRow"> + <property name="activatable">0</property> + <property name="child"> + <object class="GtkBox"> + <property name="spacing">12</property> + <object class="GtkLabel" id="website-label"> + <property name="label" translatable="1">Website</property> + <property name="xalign">0</property> + <object class="GtkLabel"> + <property name="use-markup">1</property> + <closure type="gchararray" function="gplugin_gtk_plugin_page_lookup_website_cb"> + <lookup name="website" type="GPluginPluginInfo"> + <lookup name="info" type="GPluginPlugin"> + <lookup name="plugin">GPluginGtkPluginPage</lookup> + <relation name="labelled-by">website-label</relation> + <object class="GtkListBoxRow"> + <property name="activatable">0</property> + <property name="child"> + <object class="GtkBox"> + <property name="spacing">12</property> + <object class="GtkLabel" id="dependencies-label"> + <property name="label" translatable="1">Dependencies</property> + <property name="xalign">0</property> + <object class="GtkLabel"> + <property name="selectable">1</property> + <closure type="gchararray" function="gplugin_gtk_plugin_page_newline_strjoinv_cb"> + <lookup name="dependencies" type="GPluginPluginInfo"> + <lookup name="info" type="GPluginPlugin"> + <lookup name="plugin">GPluginGtkPluginPage</lookup> + <relation name="labelled-by">dependencies-label</relation> + <object class="GtkListBoxRow"> + <property name="activatable">0</property> + <property name="child"> + <object class="GtkBox"> + <property name="spacing">12</property> + <object class="GtkLabel" id="error-label"> + <property name="label" translatable="1">Error</property> + <property name="xalign">0</property> + <object class="GtkLabel"> + <property name="selectable">1</property> + <property name="wrap">1</property> + <closure type="gchararray" function="gplugin_gtk_plugin_page_lookup_error_cb"> + <lookup name="error" type="GPluginPlugin"> + <lookup name="plugin">GPluginGtkPluginPage</lookup> + <relation name="labelled-by">error-label</relation> + <object class="GtkListBoxRow"> + <property name="activatable">0</property> + <property name="child"> + <object class="GtkBox"> + <property name="spacing">12</property> + <object class="GtkLabel" id="id-label"> + <property name="label" translatable="1">ID</property> + <property name="xalign">0</property> + <object class="GtkLabel"> + <property name="selectable">1</property> + <lookup name="id" type="GPluginPluginInfo"> + <lookup name="info" type="GPluginPlugin"> + <lookup name="plugin">GPluginGtkPluginPage</lookup> + <relation name="labelled-by">id-label</relation> + <object class="GtkListBoxRow"> + <property name="activatable">0</property> + <property name="child"> + <object class="GtkBox"> + <property name="spacing">12</property> + <object class="GtkLabel" id="filename-label"> + <property name="label" translatable="1">Filename</property> + <property name="xalign">0</property> + <object class="GtkLabel"> + <property name="selectable">1</property> + <property name="ellipsize">start</property> + <lookup name="filename" type="GPluginPlugin"> + <lookup name="plugin">GPluginGtkPluginPage</lookup> + <relation name="labelled-by">filename-label</relation> + <object class="GtkListBoxRow"> + <property name="activatable">0</property> + <property name="child"> + <object class="GtkBox"> + <property name="spacing">12</property> + <object class="GtkLabel" id="abi-version-label"> + <property name="label" translatable="1">ABI Version</property> + <property name="xalign">0</property> + <object class="GtkLabel"> + <property name="selectable">1</property> + <closure type="gchararray" function="gplugin_gtk_plugin_page_lookup_abi_version_cb"> + <lookup name="abi-version" type="GPluginPluginInfo"> + <lookup name="info" type="GPluginPlugin"> + <lookup name="plugin">GPluginGtkPluginPage</lookup> + <relation name="labelled-by">abi-version-label</relation> + <object class="GtkListBoxRow"> + <property name="activatable">0</property> + <property name="child"> + <object class="GtkBox"> + <property name="spacing">12</property> + <object class="GtkLabel" id="loader-label"> + <property name="label" translatable="1">Loader</property> + <property name="xalign">0</property> + <object class="GtkLabel"> + <property name="selectable">1</property> + <closure type="gchararray" function="gplugin_gtk_plugin_page_lookup_loader_cb"> + <lookup name="plugin">GPluginGtkPluginPage</lookup> + <relation name="labelled-by">loader-label</relation> + <object class="GtkListBoxRow"> + <property name="activatable">0</property> + <property name="child"> + <object class="GtkBox"> + <property name="spacing">12</property> + <object class="GtkLabel" id="internal-label"> + <property name="label" translatable="1">Internal</property> + <property name="xalign">0</property> + <object class="GtkImage"> + <property name="icon-name">object-select-symbolic</property> + <binding name="visible"> + <lookup name="internal" type="GPluginPluginInfo"> + <lookup name="info" type="GPluginPlugin"> + <lookup name="plugin">GPluginGtkPluginPage</lookup> + <relation name="labelled-by">internal-label</relation> + <object class="GtkListBoxRow"> + <property name="activatable">0</property> + <property name="child"> + <object class="GtkBox"> + <property name="spacing">12</property> + <object class="GtkLabel" id="load-on-query-label"> + <property name="label" translatable="1">Load on Query</property> + <property name="xalign">0</property> + <object class="GtkImage"> + <property name="icon-name">object-select-symbolic</property> + <binding name="visible"> + <lookup name="load-on-query" type="GPluginPluginInfo"> + <lookup name="info" type="GPluginPlugin"> + <lookup name="plugin">GPluginGtkPluginPage</lookup> + <relation name="labelled-by">load-on-query-label</relation> + <object class="GtkSizeGroup"> + <property name="mode">horizontal</property> + <widget name="authors-label"/> + <widget name="website-label"/> + <widget name="dependencies-label"/> + <widget name="error-label"/> + <widget name="id-label"/> + <widget name="filename-label"/> + <widget name="abi-version-label"/> + <widget name="loader-label"/> + <widget name="internal-label"/> + <widget name="load-on-query-label"/> --- a/gplugin-gtk4/data/plugin-row.ui Mon Sep 26 00:03:15 2022 -0500
+++ b/gplugin-gtk4/data/plugin-row.ui Mon Sep 26 00:42:07 2022 -0500
@@ -94,333 +94,12 @@
- <object class="GtkButton" id="config">
- <property name="css-classes">circular</property>
- <property name="receives-default">1</property>
- <property name="valign">center</property>
- <property name="child">
- <object class="GtkImage">
- <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="icon-name">preferences-system-symbolic</property>
- <object class="GtkSeparator">
- <property name="orientation">vertical</property>
- <object class="GtkExpander" id="expander">
- <property name="halign">center</property>
- <property name="valign">center</property>
+ <object class="GtkImage"> + <property name="icon-name">go-next-symbolic</property>
- <object class="GtkRevealer" id="revealer">
- <property name="reveal-child" bind-source="expander" bind-property="expanded" bind-flags="bidirectional|sync-create"/>
- <property name="child">
- <object class="GtkBox">
- <property name="orientation">vertical</property>
- <property name="spacing">12</property>
- <object class="GtkLabel" id="description">
- <property name="margin-start">12</property>
- <property name="margin-end">12</property>
- <property name="margin-top">12</property>
- <property name="margin-bottom">12</property>
- <property name="label">A longer description of what this plugin does.</property>
- <property name="wrap">1</property>
- <property name="xalign">0</property>
- <object class="GtkListBox">
- <property name="css-classes">nested</property>
- <object class="GtkListBoxRow">
- <property name="activatable">0</property>
- <property name="selectable">0</property>
- <property name="child">
- <object class="GtkBox">
- <property name="margin-start">12</property>
- <property name="margin-end">12</property>
- <property name="margin-top">12</property>
- <property name="margin-bottom">12</property>
- <property name="spacing">12</property>
- <object class="GtkLabel" id="authors_label">
- <property name="label" translatable="1">Authors</property>
- <property name="xalign">0</property>
- <object class="GtkBox" id="authors_box">
- <property name="orientation">vertical</property>
- <object class="GtkLabel">
- <property name="label">An Author <author@example.com></property>
- <object class="GtkListBoxRow">
- <property name="activatable">0</property>
- <property name="selectable">0</property>
- <property name="child">
- <object class="GtkBox">
- <property name="margin-start">12</property>
- <property name="margin-end">12</property>
- <property name="margin-top">12</property>
- <property name="margin-bottom">12</property>
- <property name="spacing">12</property>
- <object class="GtkLabel" id="website_label">
- <property name="label" translatable="1">Website</property>
- <property name="xalign">0</property>
- <object class="GtkLabel" id="website">
- <property name="label"><a href="https://pidgin.im">https://pidgin.im</a></property>
- <property name="use-markup">1</property>
- <object class="GtkListBoxRow">
- <property name="activatable">0</property>
- <property name="selectable">0</property>
- <property name="child">
- <object class="GtkBox">
- <property name="margin-start">12</property>
- <property name="margin-end">12</property>
- <property name="margin-top">12</property>
- <property name="margin-bottom">12</property>
- <property name="spacing">12</property>
- <object class="GtkLabel" id="dependencies_label">
- <property name="label" translatable="1">Dependencies</property>
- <property name="xalign">0</property>
- <object class="GtkBox" id="dependencies_box">
- <property name="orientation">vertical</property>
- <object class="GtkLabel">
- <property name="label">(none)</property>
- <object class="GtkListBoxRow">
- <property name="activatable">0</property>
- <property name="selectable">0</property>
- <property name="child">
- <object class="GtkBox">
- <property name="margin-start">12</property>
- <property name="margin-end">12</property>
- <property name="margin-top">12</property>
- <property name="margin-bottom">12</property>
- <property name="spacing">12</property>
- <object class="GtkLabel" id="error_label">
- <property name="label" translatable="1">Error</property>
- <property name="xalign">0</property>
- <object class="GtkLabel" id="error">
- <property name="label">(none)</property>
- <object class="GtkListBoxRow">
- <property name="activatable">0</property>
- <property name="selectable">0</property>
- <property name="child">
- <object class="GtkBox">
- <property name="margin-start">12</property>
- <property name="margin-end">12</property>
- <property name="margin-top">12</property>
- <property name="margin-bottom">12</property>
- <property name="spacing">12</property>
- <object class="GtkLabel" id="id_label">
- <property name="label" translatable="1">ID</property>
- <property name="xalign">0</property>
- <object class="GtkLabel" id="id">
- <property name="label">gplugin/example-plugin</property>
- <object class="GtkListBoxRow">
- <property name="activatable">0</property>
- <property name="selectable">0</property>
- <property name="child">
- <object class="GtkBox">
- <property name="margin-start">12</property>
- <property name="margin-end">12</property>
- <property name="margin-top">12</property>
- <property name="margin-bottom">12</property>
- <property name="spacing">12</property>
- <object class="GtkLabel" id="filename_label">
- <property name="label" translatable="1">Filename</property>
- <property name="xalign">0</property>
- <object class="GtkLabel" id="filename">
- <property name="label">/the/full/path/to/plugin.so</property>
- <property name="ellipsize">start</property>
- <object class="GtkListBoxRow">
- <property name="activatable">0</property>
- <property name="selectable">0</property>
- <property name="child">
- <object class="GtkBox">
- <property name="margin-start">12</property>
- <property name="margin-end">12</property>
- <property name="margin-top">12</property>
- <property name="margin-bottom">12</property>
- <property name="spacing">12</property>
- <object class="GtkLabel" id="abi_version_label">
- <property name="label" translatable="1">ABI Version</property>
- <property name="xalign">0</property>
- <object class="GtkLabel" id="abi_version">
- <property name="label">DEADC0DE</property>
- <object class="GtkListBoxRow">
- <property name="activatable">0</property>
- <property name="selectable">0</property>
- <property name="child">
- <object class="GtkBox">
- <property name="margin-start">12</property>
- <property name="margin-end">12</property>
- <property name="margin-top">12</property>
- <property name="margin-bottom">12</property>
- <property name="spacing">12</property>
- <object class="GtkLabel" id="loader_label">
- <property name="label" translatable="1">Loader</property>
- <property name="xalign">0</property>
- <object class="GtkLabel" id="loader">
- <property name="label">GPluginExampleLoader</property>
- <object class="GtkListBoxRow">
- <property name="activatable">0</property>
- <property name="selectable">0</property>
- <property name="child">
- <object class="GtkBox">
- <property name="margin-start">12</property>
- <property name="margin-end">12</property>
- <property name="margin-top">12</property>
- <property name="margin-bottom">12</property>
- <property name="spacing">12</property>
- <object class="GtkLabel" id="internal_label">
- <property name="label" translatable="1">Internal</property>
- <property name="xalign">0</property>
- <object class="GtkLabel" id="internal">
- <property name="label">Maybe</property>
- <object class="GtkListBoxRow">
- <property name="activatable">0</property>
- <property name="selectable">0</property>
- <property name="child">
- <object class="GtkBox">
- <property name="margin-start">12</property>
- <property name="margin-end">12</property>
- <property name="margin-top">12</property>
- <property name="margin-bottom">12</property>
- <property name="spacing">12</property>
- <object class="GtkLabel" id="load_on_query_label">
- <property name="label" translatable="1">Load on Query</property>
- <property name="xalign">0</property>
- <object class="GtkLabel" id="load_on_query">
- <property name="label">Maybe</property>
@@ -428,19 +107,4 @@
- <object class="GtkSizeGroup">
- <property name="mode">horizontal</property>
- <widget name="authors_label"/>
- <widget name="website_label"/>
- <widget name="dependencies_label"/>
- <widget name="error_label"/>
- <widget name="id_label"/>
- <widget name="filename_label"/>
- <widget name="abi_version_label"/>
- <widget name="loader_label"/>
- <widget name="internal_label"/>
- <widget name="load_on_query_label"/>
--- a/gplugin-gtk4/data/view.ui Mon Sep 26 00:03:15 2022 -0500
+++ b/gplugin-gtk4/data/view.ui Mon Sep 26 00:42:07 2022 -0500
@@ -2,46 +2,96 @@
<requires lib="gtk" version="4.0"/>
<template class="GPluginGtkView" parent="GtkBox">
- <property name="orientation">vertical</property>
- <object class="GtkSearchBar" id="search_bar">
- <property name="key-capture-widget">list_box</property>
- <property name="show-close-button">1</property>
+ <object class="GtkStack" id="stack"> + <property name="transition-type">slide-left-right</property> + <property name="vhomogeneous">0</property> - <object class="GtkSearchEntry" id="search_entry">
- <signal name="search-changed" handler="gplugin_gtk_view_search_changed"/>
+ <object class="GtkStackPage"> + <property name="name">overview</property> + <property name="child"> + <object class="GtkScrolledWindow"> + <property name="hscrollbar_policy">never</property> + <property name="vexpand">1</property> + <object class="GtkBox"> + <property name="orientation">vertical</property> + <object class="GtkSearchBar" id="search_bar"> + <property name="key-capture-widget">list_box</property> + <property name="show-close-button">1</property> + <object class="GtkSearchEntry" id="search_entry"> + <signal name="search-changed" handler="gplugin_gtk_view_search_changed"/> + <object class="GtkFrame"> + <property name="margin-bottom">24</property> + <property name="margin-end">24</property> + <property name="margin-start">24</property> + <property name="margin-top">24</property> + <object class="GtkListBox" id="list_box"> + <property name="css-classes">rich-list</property> + <property name="selection-mode">none</property> + <property name="show-separators">1</property> + <signal name="row-activated" handler="gplugin_gtk_view_row_activated"/> + <child type="placeholder"> + <object class="GtkLabel"> + <property name="css-classes">large-title</property> + <property name="label" translatable="1">No plugins found</property> + <property name="margin-bottom">24</property> + <property name="margin-end">24</property> + <property name="margin-start">24</property> + <property name="margin-top">24</property>
- <object class="GtkScrolledWindow">
- <property name="hscrollbar_policy">never</property>
- <property name="vexpand">1</property>
- <object class="GtkFrame">
- <property name="margin-bottom">24</property>
- <property name="margin-end">24</property>
- <property name="margin-start">24</property>
- <property name="margin-top">24</property>
- <object class="GtkListBox" id="list_box">
- <property name="css-classes">rich-list</property>
- <property name="selection-mode">none</property>
- <property name="show-separators">1</property>
- <signal name="row-activated" handler="gplugin_gtk_view_row_activated"/>
- <child type="placeholder">
- <object class="GtkLabel">
- <property name="css-classes">large-title</property>
- <property name="label" translatable="1">No plugins found</property>
+ <object class="GtkStackPage"> + <property name="name">plugin-page</property> + <property name="child"> + <object class="GtkScrolledWindow"> + <property name="hscrollbar_policy">never</property> + <property name="vexpand">1</property> + <object class="GtkBox"> <property name="margin-bottom">24</property>
<property name="margin-end">24</property>
<property name="margin-start">24</property>
<property name="margin-top">24</property>
+ <property name="orientation">horizontal</property> + <property name="spacing">12</property> + <object class="GtkButton"> + <property name="css-classes">flat</property> + <property name="halign">start</property> + <property name="valign">start</property> + <property name="icon-name">go-previous-symbolic</property> + <signal name="clicked" handler="gplugin_gtk_view_back_clicked_cb" object="GPluginGtkView" swapped="no"/> + <object class="GPluginGtkPluginPage" id="plugin_page"> + <signal name="plugin-state-set" handler="gplugin_gtk_view_plugin_state_set_cb" object="GPluginGtkView" swapped="no"/>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gplugin-gtk4/gplugin-gtk-plugin-page.c Mon Sep 26 00:42:07 2022 -0500
@@ -0,0 +1,348 @@
+ * Copyright (C) 2022 Elliott Sales de Andrade <quantum.analyst@gmail.com> + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This library 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 + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <https://www.gnu.org/licenses/>. +#include <glib/gi18n-lib.h> +#include <gplugin-gtk-plugin-closures.h> +#include <gplugin-gtk-plugin-page.h> + * GPluginGtkPluginPage: + * A widget that displays a single [iface@GPlugin.Plugin] in a user friendly + * way, intended to be placed in a [class@GPluginGtk4.View]. +/****************************************************************************** + *****************************************************************************/ +struct _GPluginGtkPluginPage { +/****************************************************************************** + *****************************************************************************/ +static GParamSpec *properties[N_PROPERTIES] = { +static guint signals[N_SIGNALS] = { +/****************************************************************************** + *****************************************************************************/ +gplugin_gtk_plugin_page_enable_state_set_cb( + G_GNUC_UNUSED GtkSwitch *widget, + GPluginGtkPluginPage *page = GPLUGIN_GTK_PLUGIN_PAGE(data); + g_signal_emit(G_OBJECT(page), signals[SIG_PLUGIN_STATE_SET], 0, state); +gplugin_gtk_plugin_page_newline_strjoinv_cb( + G_GNUC_UNUSED GtkClosureExpression *expression, + G_GNUC_UNUSED gpointer data) + if(str_array == NULL) { + return g_strdup(_("(none)")); + return g_strjoinv("\n", str_array); +gplugin_gtk_plugin_page_lookup_website_cb( + G_GNUC_UNUSED GtkClosureExpression *expression, + G_GNUC_UNUSED gpointer data) + return g_markup_printf_escaped("<a href=\"%s\">%s</a>", website, website); +gplugin_gtk_plugin_page_lookup_error_cb( + G_GNUC_UNUSED GtkClosureExpression *expression, + G_GNUC_UNUSED gpointer data) + return g_strdup(_("(none)")); + return g_strdup(error->message); +gplugin_gtk_plugin_page_lookup_abi_version_cb( + G_GNUC_UNUSED GtkClosureExpression *expression, + G_GNUC_UNUSED gpointer data) + return g_strdup_printf("%08x", abi_version); +gplugin_gtk_plugin_page_lookup_loader_cb( + G_GNUC_UNUSED GtkClosureExpression *expression, + G_GNUC_UNUSED gpointer data) + if(GPLUGIN_IS_PLUGIN(plugin)) { + GPluginLoader *plugin_loader = gplugin_plugin_get_loader(plugin); + if(GPLUGIN_IS_LOADER(plugin_loader)) { + return g_strdup(G_OBJECT_TYPE_NAME(plugin_loader)); + return g_strdup(_("Unknown")); +/****************************************************************************** + * GObject Implementation + *****************************************************************************/ +G_DEFINE_TYPE(GPluginGtkPluginPage, gplugin_gtk_plugin_page, GTK_TYPE_BOX) +gplugin_gtk_plugin_page_set_property( + GPluginGtkPluginPage *page = GPLUGIN_GTK_PLUGIN_PAGE(obj); + gplugin_gtk_plugin_page_set_plugin(page, g_value_get_object(value)); + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec); +gplugin_gtk_plugin_page_get_property( + GPluginGtkPluginPage *page = GPLUGIN_GTK_PLUGIN_PAGE(obj); + g_value_set_object(value, gplugin_gtk_plugin_page_get_plugin(page)); + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec); +gplugin_gtk_plugin_page_dispose(GObject *obj) + GPluginGtkPluginPage *page = GPLUGIN_GTK_PLUGIN_PAGE(obj); + g_clear_object(&page->plugin); + G_OBJECT_CLASS(gplugin_gtk_plugin_page_parent_class)->dispose(obj); +gplugin_gtk_plugin_page_init(GPluginGtkPluginPage *page) + gtk_widget_init_template(GTK_WIDGET(page)); +gplugin_gtk_plugin_page_class_init(GPluginGtkPluginPageClass *klass) + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); + GObjectClass *obj_class = G_OBJECT_CLASS(klass); + obj_class->get_property = gplugin_gtk_plugin_page_get_property; + obj_class->set_property = gplugin_gtk_plugin_page_set_property; + obj_class->dispose = gplugin_gtk_plugin_page_dispose; + * GPluginGtkPluginPage:plugin: + * The [iface@GPlugin.Plugin] whose info should be displayed. + properties[PROP_PLUGIN] = g_param_spec_object( + "The GPluginPlugin whose info should be displayed", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); + g_object_class_install_properties(obj_class, N_PROPERTIES, properties); + * GPluginGtkPluginPage::plugin-state-set: + * @page: The [class@GPluginGtk.PluginPage] instance. + * @enabled: Whether the plugin was requested to be enabled or disabled. + * Emitted when the plugin page enable switch is toggled. + signals[SIG_PLUGIN_STATE_SET] = g_signal_new_class_handler( + G_OBJECT_CLASS_TYPE(klass), + gtk_widget_class_set_template_from_resource( + "/org/imfreedom/keep/gplugin/gplugin-gtk/plugin-page.ui"); + gtk_widget_class_bind_template_callback( + gplugin_gtk_lookup_plugin_name); + gtk_widget_class_bind_template_callback( + gplugin_gtk_lookup_plugin_state); + gtk_widget_class_bind_template_callback( + gplugin_gtk_lookup_plugin_state_sensitivity); + gtk_widget_class_bind_template_callback( + gplugin_gtk_plugin_page_enable_state_set_cb); + gtk_widget_class_bind_template_callback( + gplugin_gtk_plugin_page_newline_strjoinv_cb); + gtk_widget_class_bind_template_callback( + gplugin_gtk_plugin_page_lookup_website_cb); + gtk_widget_class_bind_template_callback( + gplugin_gtk_plugin_page_lookup_error_cb); + gtk_widget_class_bind_template_callback( + gplugin_gtk_plugin_page_lookup_abi_version_cb); + gtk_widget_class_bind_template_callback( + gplugin_gtk_plugin_page_lookup_loader_cb); +/****************************************************************************** + *****************************************************************************/ + * gplugin_gtk_plugin_page_new: + * Create a new [class@GPluginGtk4.PluginPage] which can be used to display + * info about a [iface@GPlugin.Plugin]. + * Returns: (transfer full): The new widget. +gplugin_gtk_plugin_page_new(void) + return g_object_new(GPLUGIN_GTK_TYPE_PLUGIN_PAGE, NULL); + * gplugin_gtk_plugin_page_set_plugin: + * @page: The plugin page instance. + * @plugin: (nullable): The plugin instance. + * Sets the [iface@GPlugin.Plugin] that should be displayed. + * A @plugin value of %NULL will clear the widget. +gplugin_gtk_plugin_page_set_plugin( + GPluginGtkPluginPage *page, + g_return_if_fail(GPLUGIN_GTK_IS_PLUGIN_PAGE(page)); + if(g_set_object(&page->plugin, plugin)) { + g_object_notify_by_pspec(G_OBJECT(page), properties[PROP_PLUGIN]); + * gplugin_gtk_plugin_page_get_plugin: + * @page: The plugin page instance. + * Gets the [iface@GPlugin.Plugin] that's being displayed. + * Returns: (transfer none) (nullable): The plugin that's being displayed, or + * %NULL if the page is empty. +gplugin_gtk_plugin_page_get_plugin(GPluginGtkPluginPage *page) + g_return_val_if_fail(GPLUGIN_GTK_IS_PLUGIN_PAGE(page), NULL); --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gplugin-gtk4/gplugin-gtk-plugin-page.h Mon Sep 26 00:42:07 2022 -0500
@@ -0,0 +1,52 @@
+ * Copyright (C) 2022 Elliott Sales de Andrade <quantum.analyst@gmail.com> + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This library 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 + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <https://www.gnu.org/licenses/>. +#if !defined(GPLUGIN_GTK_GLOBAL_HEADER_INSIDE) && \ + !defined(GPLUGIN_GTK_COMPILATION) +#error "only <gplugin-gtk.h> may be included directly" +#ifndef GPLUGIN_GTK_PLUGIN_PAGE_H +#define GPLUGIN_GTK_PLUGIN_PAGE_H +#include <glib-object.h> +#define GPLUGIN_GTK_TYPE_PLUGIN_PAGE (gplugin_gtk_plugin_page_get_type()) + gplugin_gtk_plugin_page, +GtkWidget *gplugin_gtk_plugin_page_new(void); +void gplugin_gtk_plugin_page_set_plugin( + GPluginGtkPluginPage *page, + GPluginPlugin *plugin); +GPluginPlugin *gplugin_gtk_plugin_page_get_plugin(GPluginGtkPluginPage *page); +#endif /* GPLUGIN_GTK_PLUGIN_PAGE_H */ --- a/gplugin-gtk4/gplugin-gtk-plugin-row.c Mon Sep 26 00:03:15 2022 -0500
+++ b/gplugin-gtk4/gplugin-gtk-plugin-row.c Mon Sep 26 00:42:07 2022 -0500
@@ -1,5 +1,5 @@
- * Copyright (C) 2021 Elliott Sales de Andrade <quantum.analyst@gmail.com>
+ * Copyright (C) 2021-2022 Elliott Sales de Andrade <quantum.analyst@gmail.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -40,21 +40,6 @@
- GtkWidget *description;
- GtkWidget *authors_box;
- GtkWidget *dependencies_box;
- GtkWidget *abi_version;
- GtkWidget *load_on_query;
/******************************************************************************
@@ -63,7 +48,6 @@
static GParamSpec *properties[N_PROPERTIES] = {
@@ -79,136 +63,6 @@
/******************************************************************************
- *****************************************************************************/
-_gplugin_gtk_plugin_row_refresh(GPluginGtkPluginRow *row)
- GtkWidget *widget = NULL;
- gchar *description = NULL, *id = NULL, *abi_version = NULL;
- gchar **authors = NULL;
- gchar **dependencies = NULL;
- guint32 abi_version_uint;
- gboolean loq = FALSE, internal = FALSE;
- const gchar *filename = NULL;
- /* Remove all the children from the authors box. */
- while((widget = gtk_widget_get_first_child(row->authors_box)) != NULL) {
- gtk_box_remove(GTK_BOX(row->authors_box), widget);
- /* Remove all the children from the dependencies box. */
- while((widget = gtk_widget_get_first_child(row->dependencies_box)) !=
- gtk_box_remove(GTK_BOX(row->dependencies_box), widget);
- /* Now get the info if we can. */
- if(GPLUGIN_IS_PLUGIN(row->plugin)) {
- GPluginPluginInfo *plugin_info = gplugin_plugin_get_info(row->plugin);
- GPluginLoader *plugin_loader = gplugin_plugin_get_loader(row->plugin);
- filename = gplugin_plugin_get_filename(row->plugin);
- error = gplugin_plugin_get_error(row->plugin);
- if(GPLUGIN_IS_LOADER(plugin_loader)) {
- loader = g_strdup(G_OBJECT_TYPE_NAME(plugin_loader));
- "abi_version", &abi_version_uint,
- "description", &description,
- "dependencies", &dependencies,
- /* Finagle the website. */
- gchar *markup = g_markup_printf_escaped(
- "<a href=\"%s\">%s</a>",
- /* Finagle the abi_version. */
- abi_version = g_strdup_printf("%08x", abi_version_uint);
- g_clear_object(&plugin_loader);
- g_clear_object(&plugin_info);
- gtk_label_set_markup(GTK_LABEL(row->website), website);
- gtk_label_set_text(GTK_LABEL(row->description), description);
- gtk_widget_set_visible(row->description, description != NULL);
- gtk_label_set_text(GTK_LABEL(row->id), id);
- (error != NULL) ? error->message : "(none)");
- gtk_label_set_text(GTK_LABEL(row->filename), filename);
- gtk_label_set_text(GTK_LABEL(row->abi_version), abi_version);
- GTK_LABEL(row->loader),
- (loader != NULL) ? loader : _("Unknown"));
- gtk_label_set_text(GTK_LABEL(row->internal), internal ? _("Yes") : _("No"));
- gtk_label_set_text(GTK_LABEL(row->load_on_query), loq ? _("Yes") : _("No"));
- /* FIXME: Set this correctly when plugins get proper configuration. */
- gtk_widget_set_sensitive(row->config, FALSE);
- for(i = 0; authors[i]; i++) {
- widget = gtk_label_new(authors[i]);
- gtk_widget_set_halign(widget, GTK_ALIGN_START);
- gtk_widget_set_valign(widget, GTK_ALIGN_START);
- gtk_box_append(GTK_BOX(row->authors_box), widget);
- widget = gtk_label_new(_("(none)"));
- gtk_box_append(GTK_BOX(row->authors_box), widget);
- /* Set the dependencies. */
- for(i = 0; dependencies[i]; i++) {
- widget = gtk_label_new(dependencies[i]);
- gtk_widget_set_halign(widget, GTK_ALIGN_START);
- gtk_widget_set_valign(widget, GTK_ALIGN_START);
- gtk_box_append(GTK_BOX(row->dependencies_box), widget);
- widget = gtk_label_new(_("(none)"));
- gtk_box_append(GTK_BOX(row->dependencies_box), widget);
- g_strfreev(dependencies);
- gtk_list_box_row_changed(GTK_LIST_BOX_ROW(row));
-/******************************************************************************
*****************************************************************************/
@@ -245,11 +99,6 @@
gplugin_gtk_plugin_row_set_plugin(row, g_value_get_object(value));
- gplugin_gtk_plugin_row_set_expanded(
- g_value_get_boolean(value));
G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
@@ -269,11 +118,6 @@
g_value_set_object(value, gplugin_gtk_plugin_row_get_plugin(row));
- gplugin_gtk_plugin_row_get_expanded(row));
G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
@@ -322,13 +166,6 @@
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
- properties[PROP_EXPANDED] = g_param_spec_boolean(
- "Whether the row has been opened to show details",
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
@@ -368,14 +205,6 @@
- gtk_widget_class_bind_template_child(
- gtk_widget_class_bind_template_child(
gtk_widget_class_bind_template_callback(
gplugin_gtk_plugin_row_enable_state_set_cb);
@@ -388,49 +217,6 @@
gtk_widget_class_bind_template_callback(
gplugin_gtk_lookup_plugin_state_sensitivity);
- gtk_widget_class_bind_template_child(
- gtk_widget_class_bind_template_child(
- gtk_widget_class_bind_template_child(
- gtk_widget_class_bind_template_child(
- gtk_widget_class_bind_template_child(
- gtk_widget_class_bind_template_child(widget_class, GPluginGtkPluginRow, id);
- gtk_widget_class_bind_template_child(
- gtk_widget_class_bind_template_child(
- gtk_widget_class_bind_template_child(
- gtk_widget_class_bind_template_child(
- gtk_widget_class_bind_template_child(
/******************************************************************************
@@ -472,8 +258,6 @@
g_return_if_fail(GPLUGIN_GTK_IS_PLUGIN_ROW(row));
if(g_set_object(&row->plugin, plugin)) {
- _gplugin_gtk_plugin_row_refresh(row);
g_object_notify_by_pspec(G_OBJECT(row), properties[PROP_PLUGIN]);
@@ -498,42 +282,6 @@
- * gplugin_gtk_plugin_row_get_expanded:
- * @row: The plugin row instance.
- * Returns whether the plugin row is showing detailed information.
- * Returns: %TRUE if the plugin row is expanded, %FALSE otherwise.
-gplugin_gtk_plugin_row_get_expanded(GPluginGtkPluginRow *row)
- g_return_val_if_fail(GPLUGIN_GTK_IS_PLUGIN_ROW(row), FALSE);
- return gtk_revealer_get_reveal_child(GTK_REVEALER(row->revealer));
- * gplugin_gtk_plugin_row_set_expanded:
- * @row: The plugin row instance.
- * @expanded: Whether the plugin row is expanded.
- * Sets whether the plugin row is showing detailed information.
-gplugin_gtk_plugin_row_set_expanded(GPluginGtkPluginRow *row, gboolean expanded)
- g_return_if_fail(GPLUGIN_GTK_IS_PLUGIN_ROW(row));
- gtk_revealer_set_reveal_child(GTK_REVEALER(row->revealer), expanded);
- g_object_notify_by_pspec(G_OBJECT(row), properties[PROP_EXPANDED]);
* gplugin_gtk_plugin_row_get_sort_key:
* @row: The plugin row instance.
@@ -581,14 +329,23 @@
- value = gtk_label_get_text(GTK_LABEL(row->description));
- if(g_strstr_len(value, -1, text)) {
+ if(GPLUGIN_IS_PLUGIN(row->plugin)) { + GPluginPluginInfo *plugin_info = NULL; + gchar *filename = NULL; - value = gtk_label_get_text(GTK_LABEL(row->filename));
- if(g_strstr_len(value, -1, text)) {
+ plugin_info = gplugin_plugin_get_info(row->plugin); + value = gplugin_plugin_info_get_description(plugin_info); + g_clear_object(&plugin_info); + if(value != NULL && g_strstr_len(value, -1, text)) { + filename = gplugin_plugin_get_filename(row->plugin); + if(filename != NULL && g_strstr_len(filename, -1, text)) { --- a/gplugin-gtk4/gplugin-gtk-plugin-row.h Mon Sep 26 00:03:15 2022 -0500
+++ b/gplugin-gtk4/gplugin-gtk-plugin-row.h Mon Sep 26 00:42:07 2022 -0500
@@ -1,5 +1,5 @@
- * Copyright (C) 2021 Elliott Sales de Andrade <quantum.analyst@gmail.com>
+ * Copyright (C) 2021-2022 Elliott Sales de Andrade <quantum.analyst@gmail.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -46,10 +46,6 @@
GPluginGtkPluginRow *row,
GPluginPlugin *gplugin_gtk_plugin_row_get_plugin(GPluginGtkPluginRow *row);
-gboolean gplugin_gtk_plugin_row_get_expanded(GPluginGtkPluginRow *row);
-void gplugin_gtk_plugin_row_set_expanded(
- GPluginGtkPluginRow *row,
gchar *gplugin_gtk_plugin_row_get_sort_key(GPluginGtkPluginRow *row);
gboolean gplugin_gtk_plugin_row_matches_search(
GPluginGtkPluginRow *row,
--- a/gplugin-gtk4/gplugin-gtk-view.c Mon Sep 26 00:03:15 2022 -0500
+++ b/gplugin-gtk4/gplugin-gtk-view.c Mon Sep 26 00:42:07 2022 -0500
@@ -1,5 +1,5 @@
- * Copyright (C) 2021 Elliott Sales de Andrade <quantum.analyst@gmail.com>
+ * Copyright (C) 2021-2022 Elliott Sales de Andrade <quantum.analyst@gmail.com> * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -17,14 +17,15 @@
+#include <gplugin-gtk-plugin-page.h> #include <gplugin-gtk-plugin-row.h>
#include <gplugin-gtk-view.h>
- * A [class@Gtk.ListBox] widget that displays all the plugins and some basic
- * information about them.
+ * A widget that displays all the plugins and some basic information about /******************************************************************************
@@ -33,12 +34,17 @@
+ GPluginManager *manager; + gboolean show_internal; - GPluginManager *manager;
- gboolean show_internal;
+ GtkWidget *plugin_page; /******************************************************************************
@@ -61,25 +67,27 @@
gplugin_gtk_view_row_activated(
G_GNUC_UNUSED GtkListBox *box,
- G_GNUC_UNUSED gpointer data)
+ GPluginGtkView *view = GPLUGIN_GTK_VIEW(data); GPluginGtkPluginRow *plugin_row = GPLUGIN_GTK_PLUGIN_ROW(row);
+ GPluginPlugin *plugin = NULL; - gplugin_gtk_plugin_row_set_expanded(
- !gplugin_gtk_plugin_row_get_expanded(plugin_row));
+ plugin = gplugin_gtk_plugin_row_get_plugin(plugin_row); + gplugin_gtk_view_show_plugin(view, plugin); gplugin_gtk_view_plugin_state_set_cb(
- GPluginGtkPluginRow *row,
GPluginGtkView *view = GPLUGIN_GTK_VIEW(data);
- GPluginPlugin *plugin = gplugin_gtk_plugin_row_get_plugin(row);
+ GPluginPlugin *plugin = NULL; + g_object_get(row_or_page, "plugin", &plugin, NULL); gplugin_manager_load_plugin(view->manager, plugin, &error);
@@ -97,6 +105,8 @@
+ g_clear_object(&plugin); @@ -173,6 +183,14 @@
gtk_list_box_invalidate_filter(GTK_LIST_BOX(view->list_box));
+gplugin_gtk_view_back_clicked_cb(G_GNUC_UNUSED GtkButton *button, gpointer data) + GPluginGtkView *view = GPLUGIN_GTK_VIEW(data); + gplugin_gtk_view_show_overview(view); /******************************************************************************
*****************************************************************************/
@@ -250,6 +268,8 @@
"/org/imfreedom/keep/gplugin/gplugin-gtk/view.ui");
+ gtk_widget_class_bind_template_child(widget_class, GPluginGtkView, stack); gtk_widget_class_bind_template_child(
@@ -263,12 +283,23 @@
+ gtk_widget_class_bind_template_child( gtk_widget_class_bind_template_callback(
gplugin_gtk_view_row_activated);
gtk_widget_class_bind_template_callback(
gplugin_gtk_view_search_changed);
+ gtk_widget_class_bind_template_callback( + gplugin_gtk_view_back_clicked_cb); + gtk_widget_class_bind_template_callback( + gplugin_gtk_view_plugin_state_set_cb); @@ -418,3 +449,43 @@
return view->show_internal;
+ * gplugin_gtk_view_show_overview: + * @view: The GTK view instance. + * Shows the plugin list overview. +gplugin_gtk_view_show_overview(GPluginGtkView *view) + g_return_if_fail(GPLUGIN_GTK_IS_VIEW(view)); + gplugin_gtk_plugin_page_set_plugin( + GPLUGIN_GTK_PLUGIN_PAGE(view->plugin_page), + gtk_stack_set_visible_child_name(GTK_STACK(view->stack), "overview"); + * gplugin_gtk_view_show_plugin: + * @view: The GTK view instance. + * @plugin: (transfer none): The plugin to show. + * Shows a page for a single plugin. +gplugin_gtk_view_show_plugin(GPluginGtkView *view, GPluginPlugin *plugin) + g_return_if_fail(GPLUGIN_GTK_IS_VIEW(view)); + g_return_if_fail(GPLUGIN_IS_PLUGIN(plugin)); + gplugin_gtk_plugin_page_set_plugin( + GPLUGIN_GTK_PLUGIN_PAGE(view->plugin_page), + gtk_stack_set_visible_child_name(GTK_STACK(view->stack), "plugin-page"); --- a/gplugin-gtk4/gplugin-gtk-view.h Mon Sep 26 00:03:15 2022 -0500
+++ b/gplugin-gtk4/gplugin-gtk-view.h Mon Sep 26 00:42:07 2022 -0500
@@ -52,6 +52,9 @@
gboolean gplugin_gtk_view_get_show_internal(GPluginGtkView *view);
+void gplugin_gtk_view_show_overview(GPluginGtkView *view); +void gplugin_gtk_view_show_plugin(GPluginGtkView *view, GPluginPlugin *plugin); #endif /* GPLUGIN_GTK_VIEW_H */
--- a/gplugin-gtk4/meson.build Mon Sep 26 00:03:15 2022 -0500
+++ b/gplugin-gtk4/meson.build Mon Sep 26 00:42:07 2022 -0500
@@ -9,11 +9,13 @@
GPLUGIN_GTK4_LIBRARY_VERSION = '0.1.0'
+ 'gplugin-gtk-plugin-page.c', 'gplugin-gtk-plugin-row.c',
+ 'gplugin-gtk-plugin-page.h', 'gplugin-gtk-plugin-row.h',
--- a/po/POTFILES Mon Sep 26 00:03:15 2022 -0500
+++ b/po/POTFILES Mon Sep 26 00:42:07 2022 -0500
@@ -1,5 +1,7 @@
+gplugin-gtk4/data/plugin-page.ui gplugin-gtk4/data/plugin-row.ui
gplugin-gtk4/data/view.ui
+gplugin-gtk4/gplugin-gtk-plugin-page.c gplugin-gtk4/gplugin-gtk-plugin-row.c
gplugin-gtk4/gplugin-gtk-view.c
gplugin-gtk4-viewer/data/window.ui