[gnome-builder] messages: add IdeWorkbenchMessage
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] messages: add IdeWorkbenchMessage
- Date: Fri, 10 Mar 2017 08:34:55 +0000 (UTC)
commit 75e1e5468a899c61f42dc13163b944a2468ea45d
Author: Christian Hergert <chergert redhat com>
Date: Fri Mar 10 00:30:02 2017 -0800
messages: add IdeWorkbenchMessage
This is a new widget that can be pushed onto a workbench so that toplevel
messages are visible to the user. You might use this to show a warning
that a package needs to be installed, such as flatpak-builder.
libide/Makefile.am | 2 +
libide/ide.h | 1 +
libide/resources/libide.gresource.xml | 1 +
libide/workbench/ide-workbench-message.c | 222 +++++++++++++++++++++++++++++
libide/workbench/ide-workbench-message.h | 46 ++++++
libide/workbench/ide-workbench-message.ui | 43 ++++++
libide/workbench/ide-workbench-private.h | 1 +
libide/workbench/ide-workbench.c | 74 ++++++++++
libide/workbench/ide-workbench.h | 5 +
libide/workbench/ide-workbench.ui | 26 +++-
10 files changed, 416 insertions(+), 5 deletions(-)
---
diff --git a/libide/Makefile.am b/libide/Makefile.am
index c25561d..ca1d0ca 100644
--- a/libide/Makefile.am
+++ b/libide/Makefile.am
@@ -191,6 +191,7 @@ libide_1_0_la_public_headers = \
workbench/ide-omni-bar.h \
workbench/ide-perspective.h \
workbench/ide-workbench-addin.h \
+ workbench/ide-workbench-message.h \
workbench/ide-workbench-header-bar.h \
workbench/ide-workbench.h \
workers/ide-worker.h \
@@ -370,6 +371,7 @@ libide_1_0_la_public_sources = \
workbench/ide-perspective.c \
workbench/ide-workbench-addin.c \
workbench/ide-workbench-header-bar.c \
+ workbench/ide-workbench-message.c \
workbench/ide-workbench-open.c \
workbench/ide-workbench.c \
workers/ide-worker.c \
diff --git a/libide/ide.h b/libide/ide.h
index 38b2c9f..587201b 100644
--- a/libide/ide.h
+++ b/libide/ide.h
@@ -172,6 +172,7 @@ G_BEGIN_DECLS
#include "workbench/ide-layout.h"
#include "workbench/ide-perspective.h"
#include "workbench/ide-workbench-addin.h"
+#include "workbench/ide-workbench-message.h"
#include "workbench/ide-workbench-header-bar.h"
#include "workbench/ide-workbench.h"
diff --git a/libide/resources/libide.gresource.xml b/libide/resources/libide.gresource.xml
index 775f112..c6dd809 100644
--- a/libide/resources/libide.gresource.xml
+++ b/libide/resources/libide.gresource.xml
@@ -83,6 +83,7 @@
<file compressed="true" alias="ide-shortcuts-window.ui">../keybindings/ide-shortcuts-window.ui</file>
<file compressed="true"
alias="ide-workbench-header-bar.ui">../workbench/ide-workbench-header-bar.ui</file>
<file compressed="true" alias="ide-workbench.ui">../workbench/ide-workbench.ui</file>
+ <file compressed="true" alias="ide-workbench-message.ui">../workbench/ide-workbench-message.ui</file>
</gresource>
<gresource prefix="/org/gnome/builder/plugins/buildconfig">
diff --git a/libide/workbench/ide-workbench-message.c b/libide/workbench/ide-workbench-message.c
new file mode 100644
index 0000000..fb319c8
--- /dev/null
+++ b/libide/workbench/ide-workbench-message.c
@@ -0,0 +1,222 @@
+/* ide-workbench-message.c
+ *
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
+ *
+ * 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/>.
+ */
+
+#define G_LOG_DOMAIN "ide-workbench-message"
+
+#include "ide-workbench-message.h"
+
+struct _IdeWorkbenchMessage
+{
+ GtkInfoBar parent_instance;
+
+ gchar *id;
+
+ GtkLabel *title;
+ GtkLabel *subtitle;
+};
+
+enum {
+ PROP_0,
+ PROP_ID,
+ PROP_TITLE,
+ PROP_SUBTITLE,
+ N_PROPS
+};
+
+G_DEFINE_TYPE (IdeWorkbenchMessage, ide_workbench_message, GTK_TYPE_INFO_BAR)
+
+static GParamSpec *properties [N_PROPS];
+
+static void
+ide_workbench_message_finalize (GObject *object)
+{
+ IdeWorkbenchMessage *self = (IdeWorkbenchMessage *)object;
+
+ g_clear_pointer (&self->id, g_free);
+
+ G_OBJECT_CLASS (ide_workbench_message_parent_class)->finalize (object);
+}
+
+static void
+ide_workbench_message_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ IdeWorkbenchMessage *self = IDE_WORKBENCH_MESSAGE (object);
+
+ switch (prop_id)
+ {
+ case PROP_ID:
+ g_value_set_string (value, ide_workbench_message_get_id (self));
+ break;
+
+ case PROP_TITLE:
+ g_value_set_string (value, ide_workbench_message_get_title (self));
+ break;
+
+ case PROP_SUBTITLE:
+ g_value_set_string (value, ide_workbench_message_get_subtitle (self));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ide_workbench_message_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ IdeWorkbenchMessage *self = IDE_WORKBENCH_MESSAGE (object);
+
+ switch (prop_id)
+ {
+ case PROP_ID:
+ ide_workbench_message_set_id (self, g_value_get_string (value));
+ break;
+
+ case PROP_TITLE:
+ ide_workbench_message_set_title (self, g_value_get_string (value));
+ break;
+
+ case PROP_SUBTITLE:
+ ide_workbench_message_set_subtitle (self, g_value_get_string (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ide_workbench_message_class_init (IdeWorkbenchMessageClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->finalize = ide_workbench_message_finalize;
+ object_class->get_property = ide_workbench_message_get_property;
+ object_class->set_property = ide_workbench_message_set_property;
+
+ properties [PROP_ID] =
+ g_param_spec_string ("id", NULL, NULL, NULL,
+ (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ properties [PROP_TITLE] =
+ g_param_spec_string ("title", NULL, NULL, NULL,
+ (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ properties [PROP_SUBTITLE] =
+ g_param_spec_string ("subtitle", NULL, NULL, NULL,
+ (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_properties (object_class, N_PROPS, properties);
+
+ gtk_widget_class_set_template_from_resource (widget_class,
"/org/gnome/builder/ui/ide-workbench-message.ui");
+
+ gtk_widget_class_bind_template_child (widget_class, IdeWorkbenchMessage, title);
+ gtk_widget_class_bind_template_child (widget_class, IdeWorkbenchMessage, subtitle);
+}
+
+static void
+ide_workbench_message_init (IdeWorkbenchMessage *self)
+{
+ gtk_widget_init_template (GTK_WIDGET (self));
+}
+
+const gchar *
+ide_workbench_message_get_id (IdeWorkbenchMessage *self)
+{
+ g_return_val_if_fail (IDE_IS_WORKBENCH_MESSAGE (self), NULL);
+
+ return self->id;
+}
+
+void
+ide_workbench_message_set_id (IdeWorkbenchMessage *self,
+ const gchar *id)
+{
+ g_return_if_fail (IDE_IS_WORKBENCH_MESSAGE (self));
+
+ if (g_strcmp0 (id, self->id) != 0)
+ {
+ g_free (self->id);
+ self->id = g_strdup (id);
+ g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_ID]);
+ }
+}
+
+const gchar *
+ide_workbench_message_get_title (IdeWorkbenchMessage *self)
+{
+ g_return_val_if_fail (IDE_IS_WORKBENCH_MESSAGE (self), NULL);
+
+ return gtk_label_get_label (self->title);
+}
+
+void
+ide_workbench_message_set_title (IdeWorkbenchMessage *self,
+ const gchar *title)
+{
+ g_return_if_fail (IDE_IS_WORKBENCH_MESSAGE (self));
+
+ gtk_label_set_label (self->title, title);
+ gtk_widget_set_visible (GTK_WIDGET (self->title), title || *title);
+ g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_TITLE]);
+}
+
+const gchar *
+ide_workbench_message_get_subtitle (IdeWorkbenchMessage *self)
+{
+ g_return_val_if_fail (IDE_IS_WORKBENCH_MESSAGE (self), NULL);
+
+ return gtk_label_get_label (self->subtitle);
+}
+
+void
+ide_workbench_message_set_subtitle (IdeWorkbenchMessage *self,
+ const gchar *subtitle)
+{
+ g_return_if_fail (IDE_IS_WORKBENCH_MESSAGE (self));
+
+ gtk_label_set_label (self->subtitle, subtitle);
+ gtk_widget_set_visible (GTK_WIDGET (self->subtitle), subtitle || *subtitle);
+ g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_SUBTITLE]);
+}
+
+void
+ide_workbench_message_add_action (IdeWorkbenchMessage *self,
+ const gchar *title,
+ const gchar *action_name)
+{
+ GtkWidget *button;
+
+ g_return_if_fail (IDE_IS_WORKBENCH_MESSAGE (self));
+ g_return_if_fail (title);
+
+ button = g_object_new (GTK_TYPE_BUTTON,
+ "action-name", action_name,
+ "label", title,
+ "visible", TRUE,
+ NULL);
+
+ gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_action_area (GTK_INFO_BAR (self))), button);
+}
diff --git a/libide/workbench/ide-workbench-message.h b/libide/workbench/ide-workbench-message.h
new file mode 100644
index 0000000..10069a3
--- /dev/null
+++ b/libide/workbench/ide-workbench-message.h
@@ -0,0 +1,46 @@
+/* ide-workbench-message.h
+ *
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
+ *
+ * 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/>.
+ */
+
+#ifndef IDE_WORKBENCH_MESSAGE_H
+#define IDE_WORKBENCH_MESSAGE_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_WORKBENCH_MESSAGE (ide_workbench_message_get_type())
+
+G_DECLARE_FINAL_TYPE (IdeWorkbenchMessage, ide_workbench_message, IDE, WORKBENCH_MESSAGE, GtkInfoBar)
+
+GtkWidget *ide_workbench_message_new (void);
+const gchar *ide_workbench_message_get_id (IdeWorkbenchMessage *self);
+void ide_workbench_message_set_id (IdeWorkbenchMessage *self,
+ const gchar *id);
+const gchar *ide_workbench_message_get_title (IdeWorkbenchMessage *self);
+void ide_workbench_message_set_title (IdeWorkbenchMessage *self,
+ const gchar *title);
+const gchar *ide_workbench_message_get_subtitle (IdeWorkbenchMessage *self);
+void ide_workbench_message_set_subtitle (IdeWorkbenchMessage *self,
+ const gchar *subtitle);
+void ide_workbench_message_add_action (IdeWorkbenchMessage *self,
+ const gchar *label,
+ const gchar *action_name);
+
+G_END_DECLS
+
+#endif /* IDE_WORKBENCH_MESSAGE_H */
diff --git a/libide/workbench/ide-workbench-message.ui b/libide/workbench/ide-workbench-message.ui
new file mode 100644
index 0000000..f9e9ac1
--- /dev/null
+++ b/libide/workbench/ide-workbench-message.ui
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.22 -->
+ <template class="IdeWorkbenchMessage" parent="GtkInfoBar">
+ <property name="show-close-button">true</property>
+ <child internal-child="content_area">
+ <object class="GtkBox" id="hbox">
+ <property name="orientation">horizontal</property>
+ <property name="hexpand">true</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkBox">
+ <property name="orientation">vertical</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkLabel" id="title">
+ <property name="visible">true</property>
+ <property name="xalign">0.0</property>
+ <property name="wrap">true</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel" id="subtitle">
+ <property name="visible">true</property>
+ <property name="xalign">0.0</property>
+ <property name="wrap">true</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ <attributes>
+ <attribute name="scale" value="0.833333"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/libide/workbench/ide-workbench-private.h b/libide/workbench/ide-workbench-private.h
index 4f738e6..f761168 100644
--- a/libide/workbench/ide-workbench-private.h
+++ b/libide/workbench/ide-workbench-private.h
@@ -51,6 +51,7 @@ struct _IdeWorkbench
IdePerspectiveMenuButton *perspective_menu_button;
GtkStack *perspectives_stack;
GtkSizeGroup *header_size_group;
+ GtkBox *message_box;
GObject *selection_owner;
};
diff --git a/libide/workbench/ide-workbench.c b/libide/workbench/ide-workbench.c
index 3f49f4b..dc92319 100644
--- a/libide/workbench/ide-workbench.c
+++ b/libide/workbench/ide-workbench.c
@@ -409,6 +409,7 @@ ide_workbench_class_init (IdeWorkbenchClass *klass)
gtk_widget_class_bind_template_child (widget_class, IdeWorkbench, header_bar);
gtk_widget_class_bind_template_child (widget_class, IdeWorkbench, header_size_group);
gtk_widget_class_bind_template_child (widget_class, IdeWorkbench, header_stack);
+ gtk_widget_class_bind_template_child (widget_class, IdeWorkbench, message_box);
gtk_widget_class_bind_template_child (widget_class, IdeWorkbench, perspective_menu_button);
gtk_widget_class_bind_template_child (widget_class, IdeWorkbench, perspectives_stack);
}
@@ -979,3 +980,76 @@ ide_workbench_get_headerbar (IdeWorkbench *self)
return self->header_bar;
}
+
+static void
+ide_workbench_message_response (IdeWorkbench *self,
+ gint response_id,
+ IdeWorkbenchMessage *message)
+{
+ g_assert (IDE_IS_WORKBENCH (self));
+ g_assert (IDE_IS_WORKBENCH_MESSAGE (message));
+
+ if (response_id == GTK_RESPONSE_CLOSE)
+ gtk_widget_hide (GTK_WIDGET (message));
+}
+
+void
+ide_workbench_push_message (IdeWorkbench *self,
+ IdeWorkbenchMessage *message)
+{
+ g_return_if_fail (IDE_IS_WORKBENCH (self));
+ g_return_if_fail (IDE_IS_WORKBENCH_MESSAGE (message));
+
+ g_signal_connect_object (message,
+ "response",
+ G_CALLBACK (ide_workbench_message_response),
+ self,
+ G_CONNECT_SWAPPED);
+
+ gtk_container_add (GTK_CONTAINER (self->message_box), GTK_WIDGET (message));
+}
+
+static void
+locate_widget_for_message_id (GtkWidget *widget,
+ gpointer user_data)
+{
+ struct {
+ const gchar *id;
+ GtkWidget *widget;
+ } *lookup = user_data;
+
+ if (IDE_IS_WORKBENCH_MESSAGE (widget))
+ {
+ const gchar *id;
+
+ id = ide_workbench_message_get_id (IDE_WORKBENCH_MESSAGE (widget));
+
+ if (g_strcmp0 (id, lookup->id) == 0)
+ lookup->widget = widget;
+ }
+}
+
+gboolean
+ide_workbench_pop_message (IdeWorkbench *self,
+ const gchar *message_id)
+{
+ struct {
+ const gchar *id;
+ GtkWidget *widget;
+ } lookup = { message_id };
+
+ g_return_val_if_fail (IDE_IS_WORKBENCH (self), FALSE);
+ g_return_val_if_fail (message_id != NULL, FALSE);
+
+ gtk_container_foreach (GTK_CONTAINER (self->message_box),
+ locate_widget_for_message_id,
+ &lookup);
+
+ if (lookup.widget)
+ {
+ gtk_widget_destroy (lookup.widget);
+ return TRUE;
+ }
+
+ return FALSE;
+}
diff --git a/libide/workbench/ide-workbench.h b/libide/workbench/ide-workbench.h
index b1493c7..dbf5515 100644
--- a/libide/workbench/ide-workbench.h
+++ b/libide/workbench/ide-workbench.h
@@ -26,6 +26,7 @@
#include "util/ide-uri.h"
#include "workbench/ide-perspective.h"
#include "workbench/ide-workbench-header-bar.h"
+#include "workbench/ide-workbench-message.h"
G_BEGIN_DECLS
@@ -98,6 +99,10 @@ void ide_workbench_views_foreach (IdeWorkbench
GtkCallback callback,
gpointer user_data);
IdeWorkbenchHeaderBar *ide_workbench_get_headerbar (IdeWorkbench *self);
+void ide_workbench_push_message (IdeWorkbench *self,
+ IdeWorkbenchMessage *message);
+gboolean ide_workbench_pop_message (IdeWorkbench *self,
+ const gchar *message_id);
G_END_DECLS
diff --git a/libide/workbench/ide-workbench.ui b/libide/workbench/ide-workbench.ui
index b7ec8e5..876e80d 100644
--- a/libide/workbench/ide-workbench.ui
+++ b/libide/workbench/ide-workbench.ui
@@ -33,12 +33,28 @@
<object class="GtkOverlay">
<property name="visible">true</property>
<child>
- <object class="GtkStack" id="perspectives_stack">
- <property name="hexpand">true</property>
- <property name="homogeneous">false</property>
- <property name="transition-type">crossfade</property>
- <property name="transition-duration">333</property>
+ <object class="GtkBox">
+ <property name="orientation">vertical</property>
<property name="visible">true</property>
+ <child>
+ <object class="GtkBox" id="message_box">
+ <property name="orientation">vertical</property>
+ <property name="hexpand">false</property>
+ <property name="visible">true</property>
+ <style>
+ <class name="message-box"/>
+ </style>
+ </object>
+ </child>
+ <child>
+ <object class="GtkStack" id="perspectives_stack">
+ <property name="hexpand">true</property>
+ <property name="homogeneous">false</property>
+ <property name="transition-type">crossfade</property>
+ <property name="transition-duration">333</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
</object>
</child>
</object>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]