[gnome-builder] libide-gui: port run button to GTK 4 using split button
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] libide-gui: port run button to GTK 4 using split button
- Date: Tue, 12 Jul 2022 06:39:12 +0000 (UTC)
commit 1e51c5003f3c64bad22c4784d11a735a27d5bdf9
Author: Christian Hergert <chergert redhat com>
Date: Mon Jul 11 21:45:11 2022 -0700
libide-gui: port run button to GTK 4 using split button
src/libide/gui/ide-run-button.c | 165 +++++++++++++++------------------------
src/libide/gui/ide-run-button.h | 10 ++-
src/libide/gui/ide-run-button.ui | 47 +----------
3 files changed, 78 insertions(+), 144 deletions(-)
---
diff --git a/src/libide/gui/ide-run-button.c b/src/libide/gui/ide-run-button.c
index 9476a08af..f44f35f5e 100644
--- a/src/libide/gui/ide-run-button.c
+++ b/src/libide/gui/ide-run-button.c
@@ -22,63 +22,31 @@
#include "config.h"
-#include <dazzle.h>
#include <glib/gi18n.h>
+
#include <libide-foundry.h>
+#include <libide-gtk.h>
+
+#include "ide-device-private.h"
+#include "ide-application.h"
#include "ide-gui-global.h"
#include "ide-run-button.h"
-
#include "ide-run-manager-private.h"
struct _IdeRunButton
{
- GtkBox parent_instance;
-
- GtkButton *button;
- GtkImage *button_image;
- DzlMenuButton *menu_button;
- GtkShortcutsShortcut *run_shortcut;
- GtkLabel *run_tooltip_message;
- DzlShortcutTooltip *tooltip;
-
- char *run_handler_icon_name;
+ GtkWidget parent_instance;
+ AdwSplitButton *split_button;
+ IdeJoinedMenu *joined_menu;
};
-G_DEFINE_FINAL_TYPE (IdeRunButton, ide_run_button, GTK_TYPE_BOX)
-
-static void
-ide_run_button_handler_set (IdeRunButton *self,
- GParamSpec *pspec,
- IdeRunManager *run_manager)
-{
- const GList *list;
- const GList *iter;
- const gchar *handler;
-
- g_assert (IDE_IS_RUN_BUTTON (self));
- g_assert (IDE_IS_RUN_MANAGER (run_manager));
-
- handler = ide_run_manager_get_handler (run_manager);
- list = _ide_run_manager_get_handlers (run_manager);
-
- for (iter = list; iter; iter = iter->next)
- {
- const IdeRunHandlerInfo *info = iter->data;
-
- if (g_strcmp0 (info->id, handler) == 0)
- {
- self->run_handler_icon_name = g_strdup (info->icon_name);
- g_object_set (self->button_image, "icon-name", info->icon_name, NULL);
- break;
- }
- }
-}
+G_DEFINE_FINAL_TYPE (IdeRunButton, ide_run_button, GTK_TYPE_WIDGET)
static void
-on_run_busy_state_changed_cb (IdeRunButton *self,
- GParamSpec *pspec,
- IdeRunManager *run_manager)
+on_icon_state_changed_cb (IdeRunButton *self,
+ GParamSpec *pspec,
+ IdeRunManager *run_manager)
{
const char *icon_name;
const char *action_name;
@@ -88,7 +56,7 @@ on_run_busy_state_changed_cb (IdeRunButton *self,
if (!ide_run_manager_get_busy (run_manager))
{
- icon_name = self->run_handler_icon_name;
+ icon_name = ide_run_manager_get_icon_name (run_manager);
action_name = "run-manager.run";
}
else
@@ -97,34 +65,48 @@ on_run_busy_state_changed_cb (IdeRunButton *self,
action_name = "run-manager.stop";
}
- g_object_set (self->button_image, "icon-name", icon_name, NULL);
- gtk_actionable_set_action_name (GTK_ACTIONABLE (self->button), action_name);
+ g_object_set (self->split_button,
+ "action-name", action_name,
+ "icon-name", icon_name,
+ NULL);
}
static void
ide_run_button_load (IdeRunButton *self,
IdeContext *context)
{
+ IdeDeviceManager *device_manager;
IdeRunManager *run_manager;
+ GMenu *menu;
+
+ IDE_ENTRY;
g_assert (IDE_IS_RUN_BUTTON (self));
g_assert (IDE_IS_CONTEXT (context));
- run_manager = ide_run_manager_from_context (context);
+ if (!ide_context_has_project (context))
+ IDE_EXIT;
+ /* Setup button action/icon */
+ run_manager = ide_run_manager_from_context (context);
g_signal_connect_object (run_manager,
"notify::busy",
- G_CALLBACK (on_run_busy_state_changed_cb),
+ G_CALLBACK (on_icon_state_changed_cb),
self,
G_CONNECT_SWAPPED);
-
g_signal_connect_object (run_manager,
- "notify::handler",
- G_CALLBACK (ide_run_button_handler_set),
+ "notify::icon-name",
+ G_CALLBACK (on_icon_state_changed_cb),
self,
G_CONNECT_SWAPPED);
+ on_icon_state_changed_cb (self, NULL, run_manager);
+
+ /* Add devices section */
+ device_manager = ide_device_manager_from_context (context);
+ menu = _ide_device_manager_get_menu (device_manager);
+ ide_joined_menu_prepend_menu (self->joined_menu, G_MENU_MODEL (menu));
- ide_run_button_handler_set (self, NULL, run_manager);
+ IDE_EXIT;
}
static void
@@ -149,9 +131,6 @@ ide_run_button_query_tooltip (IdeRunButton *self,
GtkButton *button)
{
IdeRunManager *run_manager;
- const GList *list;
- const GList *iter;
- const gchar *handler;
IdeContext *context;
g_assert (IDE_IS_RUN_BUTTON (self));
@@ -160,69 +139,55 @@ ide_run_button_query_tooltip (IdeRunButton *self,
context = ide_widget_get_context (GTK_WIDGET (self));
run_manager = ide_run_manager_from_context (context);
- handler = ide_run_manager_get_handler (run_manager);
- list = _ide_run_manager_get_handlers (run_manager);
if (ide_run_manager_get_busy (run_manager))
- {
- gtk_tooltip_set_text (tooltip, _("Stop running"));
- return TRUE;
- }
+ gtk_tooltip_set_text (tooltip, _("Stop running"));
+ else
+ gtk_tooltip_set_text (tooltip, _("Run project"));
- for (iter = list; iter; iter = iter->next)
- {
- const IdeRunHandlerInfo *info = iter->data;
-
- if (g_strcmp0 (info->id, handler) == 0)
- {
- gboolean enabled;
- /* Figure out if the run action is enabled. If it
- * is not, then we should inform the user that
- * the project cannot be run yet because the
- * build pipeline is not yet configured. */
- g_action_group_query_action (G_ACTION_GROUP (run_manager),
- "run",
- &enabled,
- NULL,
- NULL,
- NULL,
- NULL);
-
- if (!enabled)
- {
- gtk_tooltip_set_custom (tooltip, GTK_WIDGET (self->run_tooltip_message));
- return TRUE;
- }
-
- /* The shortcut tooltip will set this up after us */
- dzl_shortcut_tooltip_set_accel (self->tooltip, info->accel);
- dzl_shortcut_tooltip_set_title (self->tooltip, info->title);
- }
- }
+ return TRUE;
+}
- return FALSE;
+static void
+ide_run_button_dispose (GObject *object)
+{
+ IdeRunButton *self = (IdeRunButton *)object;
+
+ g_clear_pointer ((GtkWidget **)&self->split_button, gtk_widget_unparent);
+ g_clear_object (&self->joined_menu);
+
+ G_OBJECT_CLASS (ide_run_button_parent_class)->dispose (object);
}
static void
ide_run_button_class_init (IdeRunButtonClass *klass)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->dispose = ide_run_button_dispose;
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/libide-gui/ui/ide-run-button.ui");
- gtk_widget_class_bind_template_child (widget_class, IdeRunButton, button);
- gtk_widget_class_bind_template_child (widget_class, IdeRunButton, button_image);
- gtk_widget_class_bind_template_child (widget_class, IdeRunButton, menu_button);
- gtk_widget_class_bind_template_child (widget_class, IdeRunButton, run_shortcut);
- gtk_widget_class_bind_template_child (widget_class, IdeRunButton, run_tooltip_message);
- gtk_widget_class_bind_template_child (widget_class, IdeRunButton, tooltip);
+ gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
+ gtk_widget_class_bind_template_child (widget_class, IdeRunButton, split_button);
}
static void
ide_run_button_init (IdeRunButton *self)
{
+ GMenu *menu;
+
gtk_widget_init_template (GTK_WIDGET (self));
- g_signal_connect_object (self->button,
+ self->joined_menu = ide_joined_menu_new ();
+
+ menu = ide_application_get_menu_by_id (IDE_APPLICATION_DEFAULT, "run-menu");
+ ide_joined_menu_append_menu (self->joined_menu, G_MENU_MODEL (menu));
+
+ adw_split_button_set_menu_model (self->split_button,
+ G_MENU_MODEL (self->joined_menu));
+
+ g_signal_connect_object (self->split_button,
"query-tooltip",
G_CALLBACK (ide_run_button_query_tooltip),
self,
diff --git a/src/libide/gui/ide-run-button.h b/src/libide/gui/ide-run-button.h
index f758c3adc..ac05a0ddc 100644
--- a/src/libide/gui/ide-run-button.h
+++ b/src/libide/gui/ide-run-button.h
@@ -20,14 +20,22 @@
#pragma once
+#if !defined (IDE_GUI_INSIDE) && !defined (IDE_GUI_COMPILATION)
+# error "Only <libide-gui.h> can be included directly."
+#endif
+
#include <gtk/gtk.h>
+#include <libide-core.h>
+
G_BEGIN_DECLS
#define IDE_TYPE_RUN_BUTTON (ide_run_button_get_type())
-G_DECLARE_FINAL_TYPE (IdeRunButton, ide_run_button, IDE, RUN_BUTTON, GtkBox)
+IDE_AVAILABLE_IN_ALL
+G_DECLARE_FINAL_TYPE (IdeRunButton, ide_run_button, IDE, RUN_BUTTON, GtkWidget)
+IDE_AVAILABLE_IN_ALL
GtkWidget *ide_run_button_new (void);
G_END_DECLS
diff --git a/src/libide/gui/ide-run-button.ui b/src/libide/gui/ide-run-button.ui
index f75308b9f..fadbd879d 100644
--- a/src/libide/gui/ide-run-button.ui
+++ b/src/libide/gui/ide-run-button.ui
@@ -1,51 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
- <object class="GtkShortcutsShortcut" id="run_shortcut">
- </object>
- <object class="GtkLabel" id="run_tooltip_message">
- <property name="label" translatable="yes">The project cannot be run while the build pipeline is being
set up</property>
- <property name="visible">true</property>
- </object>
- <template class="IdeRunButton" parent="GtkBox">
- <property name="orientation">horizontal</property>
- <style>
- <class name="linked"/>
- </style>
+ <requires lib="gtk" version="4.0"/>
+ <template class="IdeRunButton" parent="GtkWidget">
<child>
- <object class="GtkButton" id="button">
- <property name="focus-on-click">false</property>
- <property name="has-tooltip">true</property>
- <property name="visible">true</property>
+ <object class="AdwSplitButton" id="split_button">
<property name="action-name">run-manager.run</property>
- <style>
- <class name="image-button"/>
- </style>
- <child>
- <object class="GtkImage" id="button_image">
- <property name="icon-name">builder-run-start-symbolic</property>
- <property name="visible">true</property>
- </object>
- </child>
- </object>
- </child>
- <child>
- <object class="DzlMenuButton" id="menu_button">
- <property name="focus-on-click">false</property>
- <property name="icon-name">pan-down-symbolic</property>
- <property name="menu-id">run-menu</property>
- <property name="show-accels">true</property>
- <property name="show-arrow">false</property>
- <property name="show-icons">true</property>
- <property name="tooltip-text" translatable="yes">Change run options</property>
- <property name="visible">true</property>
- <style>
- <class name="image-button"/>
- <class name="run-arrow-button"/>
- </style>
+ <property name="icon-name">builder-run-start-symbolic</property>
</object>
</child>
</template>
- <object class="DzlShortcutTooltip" id="tooltip">
- <property name="widget">button</property>
- </object>
</interface>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]