gplugin/gplugin

Use expression lookups to populate plugin rows

19 months ago, Elliott Sales de Andrade
741b8a475cb7
Parents 5d5f6f079fc1
Children 7cd3caa3f514
Use expression lookups to populate plugin rows

This is only applied to the main display items, as the details will be moving to a separate page anyway.

Testing Done:
Compiled and opened demo, toggled enabled state for a few plugins.

Reviewed at https://reviews.imfreedom.org/r/1835/
--- a/gplugin-gtk4/data/plugin-row.ui Sat Sep 24 22:48:24 2022 -0500
+++ b/gplugin-gtk4/data/plugin-row.ui Sat Sep 24 22:51:47 2022 -0500
@@ -18,6 +18,20 @@
<child>
<object class="GtkSwitch" id="enable">
<property name="valign">center</property>
+ <binding name="sensitive">
+ <closure type="gboolean" function="gplugin_gtk_plugin_row_lookup_sensitive_cb">
+ <lookup name="state" type="GPluginPlugin">
+ <lookup name="plugin">GPluginGtkPluginRow</lookup>
+ </lookup>
+ </closure>
+ </binding>
+ <binding name="state">
+ <closure type="gboolean" function="gplugin_gtk_plugin_row_lookup_state_cb">
+ <lookup name="state" type="GPluginPlugin">
+ <lookup name="plugin">GPluginGtkPluginRow</lookup>
+ </lookup>
+ </closure>
+ </binding>
<signal name="state-set" handler="gplugin_gtk_plugin_row_enable_state_set_cb"/>
</object>
</child>
@@ -31,7 +45,16 @@
<property name="accessible-role">row-header</property>
<property name="css-classes">heading</property>
<property name="hexpand">1</property>
- <property name="label">Plugin Name</property>
+ <binding name="label">
+ <closure type="gchararray" function="gplugin_gtk_plugin_row_lookup_name_cb">
+ <lookup name="info" type="GPluginPlugin">
+ <lookup name="plugin">GPluginGtkPluginRow</lookup>
+ </lookup>
+ <lookup name="filename" type="GPluginPlugin">
+ <lookup name="plugin">GPluginGtkPluginRow</lookup>
+ </lookup>
+ </closure>
+ </binding>
<property name="wrap">1</property>
<property name="wrap-mode">word-char</property>
<property name="xalign">0</property>
@@ -42,7 +65,13 @@
<object class="GtkLabel" id="summary">
<property name="css-classes">subtitle</property>
<property name="halign">start</property>
- <property name="label">The plugin short summary</property>
+ <binding name="label">
+ <lookup name="summary" type="GPluginPluginInfo">
+ <lookup name="info" type="GPluginPlugin">
+ <lookup name="plugin">GPluginGtkPluginRow</lookup>
+ </lookup>
+ </lookup>
+ </binding>
<property name="wrap">1</property>
<property name="wrap-mode">word-char</property>
<property name="ellipsize">end</property>
@@ -55,7 +84,13 @@
<object class="GtkLabel" id="version">
<property name="css-classes">dim-label</property>
<property name="halign">end</property>
- <property name="label">1337.0.0</property>
+ <binding name="label">
+ <lookup name="version" type="GPluginPluginInfo">
+ <lookup name="info" type="GPluginPlugin">
+ <lookup name="plugin">GPluginGtkPluginRow</lookup>
+ </lookup>
+ </lookup>
+ </binding>
</object>
</child>
<child>
--- a/gplugin-gtk4/gplugin-gtk-plugin-row.c Sat Sep 24 22:48:24 2022 -0500
+++ b/gplugin-gtk4/gplugin-gtk-plugin-row.c Sat Sep 24 22:51:47 2022 -0500
@@ -35,13 +35,10 @@
GtkListBoxRow parent;
GPluginPlugin *plugin;
- gulong signal_id;
/* Header */
- GtkWidget *enable;
GtkWidget *title;
GtkWidget *summary;
- GtkWidget *version;
GtkWidget *config;
GtkWidget *revealer;
@@ -87,10 +84,9 @@
_gplugin_gtk_plugin_row_refresh(GPluginGtkPluginRow *row)
{
GtkWidget *widget = NULL;
- GPluginPluginState state = GPLUGIN_PLUGIN_STATE_UNKNOWN;
GError *error = NULL;
- gchar *name = NULL, *version = NULL, *website = NULL;
- gchar *summary = NULL, *description = NULL, *id = NULL, *abi_version = NULL;
+ gchar *website = NULL;
+ gchar *description = NULL, *id = NULL, *abi_version = NULL;
gchar *loader = NULL;
gchar **authors = NULL;
gchar **dependencies = NULL;
@@ -116,7 +112,6 @@
filename = gplugin_plugin_get_filename(row->plugin);
error = gplugin_plugin_get_error(row->plugin);
- state = gplugin_plugin_get_state(row->plugin);
if(GPLUGIN_IS_LOADER(plugin_loader)) {
loader = g_strdup(G_OBJECT_TYPE_NAME(plugin_loader));
@@ -127,14 +122,11 @@
G_OBJECT(plugin_info),
"abi_version", &abi_version_uint,
"authors", &authors,
- "summary", &summary,
"description", &description,
"dependencies", &dependencies,
"id", &id,
"internal", &internal,
"load-on-query", &loq,
- "name", &name,
- "version", &version,
"website", &website,
NULL);
/* clang-format on */
@@ -156,44 +148,7 @@
g_clear_object(&plugin_info);
}
- /* Add a default name if unavailable. */
- if(name == NULL) {
- gchar *basename = g_path_get_basename(filename);
- name = g_strdup_printf(_("Unnamed Plugin: %s"), basename);
- g_free(basename);
- }
-
- /* Set state of enable switch. */
- switch(state) {
- case GPLUGIN_PLUGIN_STATE_QUERIED:
- case GPLUGIN_PLUGIN_STATE_REQUERY:
- gtk_switch_set_state(GTK_SWITCH(row->enable), FALSE);
- gtk_widget_set_sensitive(row->enable, TRUE);
- break;
-
- case GPLUGIN_PLUGIN_STATE_LOADED:
- gtk_switch_set_state(GTK_SWITCH(row->enable), TRUE);
- gtk_widget_set_sensitive(row->enable, TRUE);
- break;
-
- case GPLUGIN_PLUGIN_STATE_UNLOAD_FAILED:
- gtk_switch_set_state(GTK_SWITCH(row->enable), TRUE);
- gtk_widget_set_sensitive(row->enable, FALSE);
- break;
-
- case GPLUGIN_PLUGIN_STATE_ERROR:
- case GPLUGIN_PLUGIN_STATE_LOAD_FAILED:
- case GPLUGIN_PLUGIN_STATE_UNKNOWN:
- default:
- gtk_switch_set_state(GTK_SWITCH(row->enable), FALSE);
- gtk_widget_set_sensitive(row->enable, FALSE);
- break;
- }
-
- gtk_label_set_text(GTK_LABEL(row->title), name);
- gtk_label_set_text(GTK_LABEL(row->version), version);
gtk_label_set_markup(GTK_LABEL(row->website), website);
- gtk_label_set_text(GTK_LABEL(row->summary), summary);
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);
@@ -244,12 +199,9 @@
g_free(loader);
g_free(abi_version);
g_strfreev(authors);
- g_free(summary);
g_free(description);
g_strfreev(dependencies);
g_free(id);
- g_free(name);
- g_free(version);
g_free(website);
gtk_list_box_row_changed(GTK_LIST_BOX_ROW(row));
@@ -258,15 +210,6 @@
/******************************************************************************
* Callbacks
*****************************************************************************/
-static void
-gplugin_gtk_plugin_row_state_cb(
- G_GNUC_UNUSED GObject *obj,
- G_GNUC_UNUSED GParamSpec *pspec,
- gpointer data)
-{
- _gplugin_gtk_plugin_row_refresh(GPLUGIN_GTK_PLUGIN_ROW(data));
-}
-
static gboolean
gplugin_gtk_plugin_row_enable_state_set_cb(
G_GNUC_UNUSED GtkSwitch *widget,
@@ -280,6 +223,84 @@
return TRUE;
}
+static gchar *
+gplugin_gtk_plugin_row_lookup_name_cb(
+ G_GNUC_UNUSED GtkClosureExpression *expression,
+ GPluginPluginInfo *info,
+ const gchar *filename,
+ G_GNUC_UNUSED gpointer data)
+{
+ const gchar *name = NULL;
+ gchar *basename = NULL;
+ gchar *unnamed = NULL;
+
+ name = gplugin_plugin_info_get_name(info);
+ if(name != NULL) {
+ return g_strdup(name);
+ }
+
+ /* Add a default name if unavailable. */
+ basename = g_path_get_basename(filename);
+ unnamed = g_strdup_printf(_("Unnamed Plugin: %s"), basename);
+ g_free(basename);
+
+ return unnamed;
+}
+
+static gboolean
+gplugin_gtk_plugin_row_lookup_sensitive_cb(
+ G_GNUC_UNUSED GtkClosureExpression *expression,
+ GPluginPluginState state,
+ G_GNUC_UNUSED gpointer data)
+{
+ gboolean result = FALSE;
+
+ switch(state) {
+ case GPLUGIN_PLUGIN_STATE_QUERIED:
+ case GPLUGIN_PLUGIN_STATE_REQUERY:
+ case GPLUGIN_PLUGIN_STATE_LOADED:
+ result = TRUE;
+ break;
+
+ case GPLUGIN_PLUGIN_STATE_UNLOAD_FAILED:
+ case GPLUGIN_PLUGIN_STATE_ERROR:
+ case GPLUGIN_PLUGIN_STATE_LOAD_FAILED:
+ case GPLUGIN_PLUGIN_STATE_UNKNOWN:
+ default:
+ result = FALSE;
+ break;
+ }
+
+ return result;
+}
+
+static gboolean
+gplugin_gtk_plugin_row_lookup_state_cb(
+ G_GNUC_UNUSED GtkClosureExpression *expression,
+ GPluginPluginState state,
+ G_GNUC_UNUSED gpointer data)
+{
+ gboolean result = FALSE;
+
+ switch(state) {
+ case GPLUGIN_PLUGIN_STATE_LOADED:
+ case GPLUGIN_PLUGIN_STATE_UNLOAD_FAILED:
+ result = TRUE;
+ break;
+
+ case GPLUGIN_PLUGIN_STATE_QUERIED:
+ case GPLUGIN_PLUGIN_STATE_REQUERY:
+ case GPLUGIN_PLUGIN_STATE_ERROR:
+ case GPLUGIN_PLUGIN_STATE_LOAD_FAILED:
+ case GPLUGIN_PLUGIN_STATE_UNKNOWN:
+ default:
+ result = FALSE;
+ break;
+ }
+
+ return result;
+}
+
/******************************************************************************
* GObject Implementation
*****************************************************************************/
@@ -341,10 +362,6 @@
{
GPluginGtkPluginRow *row = GPLUGIN_GTK_PLUGIN_ROW(obj);
- if(row->signal_id != 0 && GPLUGIN_IS_PLUGIN(row->plugin)) {
- g_signal_handler_disconnect(G_OBJECT(row->plugin), row->signal_id);
- }
-
g_clear_object(&row->plugin);
G_OBJECT_CLASS(gplugin_gtk_plugin_row_parent_class)->finalize(obj);
@@ -354,8 +371,6 @@
gplugin_gtk_plugin_row_init(GPluginGtkPluginRow *row)
{
gtk_widget_init_template(GTK_WIDGET(row));
-
- row->signal_id = 0;
}
static void
@@ -417,10 +432,6 @@
gtk_widget_class_bind_template_child(
widget_class,
GPluginGtkPluginRow,
- enable);
- gtk_widget_class_bind_template_child(
- widget_class,
- GPluginGtkPluginRow,
title);
gtk_widget_class_bind_template_child(
widget_class,
@@ -429,10 +440,6 @@
gtk_widget_class_bind_template_child(
widget_class,
GPluginGtkPluginRow,
- version);
- gtk_widget_class_bind_template_child(
- widget_class,
- GPluginGtkPluginRow,
config);
gtk_widget_class_bind_template_child(
widget_class,
@@ -441,6 +448,15 @@
gtk_widget_class_bind_template_callback(
widget_class,
gplugin_gtk_plugin_row_enable_state_set_cb);
+ gtk_widget_class_bind_template_callback(
+ widget_class,
+ gplugin_gtk_plugin_row_lookup_name_cb);
+ gtk_widget_class_bind_template_callback(
+ widget_class,
+ gplugin_gtk_plugin_row_lookup_sensitive_cb);
+ gtk_widget_class_bind_template_callback(
+ widget_class,
+ gplugin_gtk_plugin_row_lookup_state_cb);
/* Details */
gtk_widget_class_bind_template_child(
@@ -520,29 +536,9 @@
{
g_return_if_fail(GPLUGIN_GTK_IS_PLUGIN_ROW(row));
- if(row->signal_id != 0 && GPLUGIN_IS_PLUGIN(row->plugin)) {
- g_signal_handler_disconnect(row->plugin, row->signal_id);
- row->signal_id = 0;
- }
-
if(g_set_object(&row->plugin, plugin)) {
_gplugin_gtk_plugin_row_refresh(row);
- if(GPLUGIN_IS_PLUGIN(plugin)) {
- /* Connect a signal to refresh when the plugin's state changes. We
- * can't use g_signal_connect_object because the plugin object never
- * gets destroyed, as the manager and the loader both keep a
- * reference to it and the GPluginGtkPluginRow widget is reused for
- * all plugins so that all means that we just have to manage the
- * callback ourselves.
- */
- row->signal_id = g_signal_connect(
- G_OBJECT(plugin),
- "notify::state",
- G_CALLBACK(gplugin_gtk_plugin_row_state_cb),
- row);
- }
-
g_object_notify_by_pspec(G_OBJECT(row), properties[PROP_PLUGIN]);
}
}