[gtk/new-style-menu: 2/6] Introduce a popover bar
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/new-style-menu: 2/6] Introduce a popover bar
- Date: Sat, 8 Jun 2019 03:49:40 +0000 (UTC)
commit 8613265cf75d38bb8e01acf84e1fe5e53e4b5a55
Author: Matthias Clasen <mclasen redhat com>
Date: Fri Jun 7 23:27:24 2019 +0000
Introduce a popover bar
This is meant to grow into a menubar replacement
with popovers. For now, it is just a box of menubuttons,
and not very much like a menubar at all.
gtk/gtk.h | 1 +
gtk/gtkpopoverbar.c | 216 ++++++++++++++++++++++++++++++++++++++++++++++++++++
gtk/gtkpopoverbar.h | 47 ++++++++++++
gtk/meson.build | 1 +
4 files changed, 265 insertions(+)
---
diff --git a/gtk/gtk.h b/gtk/gtk.h
index 2f6e7e59be..9bb5145c3d 100644
--- a/gtk/gtk.h
+++ b/gtk/gtk.h
@@ -173,6 +173,7 @@
#include <gtk/gtkpasswordentry.h>
#include <gtk/gtkpicture.h>
#include <gtk/gtkpopover.h>
+#include <gtk/gtkpopoverbar.h>
#include <gtk/gtkpopovermenu.h>
#include <gtk/gtkprintcontext.h>
#include <gtk/gtkprintoperation.h>
diff --git a/gtk/gtkpopoverbar.c b/gtk/gtkpopoverbar.c
new file mode 100644
index 0000000000..327379df39
--- /dev/null
+++ b/gtk/gtkpopoverbar.c
@@ -0,0 +1,216 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2019 Red Hat, Inc.
+ *
+ * Authors:
+ * - Matthias Clasen <mclasen redhat 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "gtkpopoverbar.h"
+#include "gtkpopovermenu.h"
+
+#include "gtkbox.h"
+#include "gtklabel.h"
+#include "gtkmenubutton.h"
+#include "gtkintl.h"
+#include "gtkprivate.h"
+#include "gtkmarshalers.h"
+#include "gtkstylecontext.h"
+#include "gtkgestureclick.h"
+#include "gtkeventcontrollerkey.h"
+#include "gtkactionmuxerprivate.h"
+#include "gtkmenutracker.h"
+#include "gtkwidgetprivate.h"
+
+struct _GtkPopoverBar
+{
+ GtkWidget parent;
+
+ GtkMenuTracker *tracker;
+ GtkWidget *box;
+};
+
+typedef struct _GtkPopoverBarClass GtkPopoverBarClass;
+struct _GtkPopoverBarClass
+{
+ GtkWidgetClass parent_class;
+};
+
+G_DEFINE_TYPE (GtkPopoverBar, gtk_popover_bar, GTK_TYPE_WIDGET)
+
+static void
+gtk_popover_bar_init (GtkPopoverBar *bar)
+{
+ bar->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+ gtk_widget_set_parent (bar->box, GTK_WIDGET (bar));
+}
+
+static void
+gtk_popover_bar_dispose (GObject *object)
+{
+ GtkPopoverBar *bar = GTK_POPOVER_BAR (object);
+
+ g_clear_pointer (&bar->tracker, gtk_menu_tracker_free);
+ g_clear_pointer (&bar->box, gtk_widget_unparent);
+
+ G_OBJECT_CLASS (gtk_popover_bar_parent_class)->dispose (object);
+}
+
+static void
+gtk_popover_bar_finalize (GObject *object)
+{
+ G_OBJECT_CLASS (gtk_popover_bar_parent_class)->finalize (object);
+}
+
+static void
+gtk_popover_bar_measure (GtkWidget *widget,
+ GtkOrientation orientation,
+ int for_size,
+ int *minimum,
+ int *natural,
+ int *minimum_baseline,
+ int *natural_baseline)
+{
+ GtkPopoverBar *bar = GTK_POPOVER_BAR (widget);
+
+ gtk_widget_measure (bar->box, orientation, for_size,
+ minimum, natural,
+ minimum_baseline, natural_baseline);
+}
+
+static void
+gtk_popover_bar_size_allocate (GtkWidget *widget,
+ int width,
+ int height,
+ int baseline)
+{
+ GtkPopoverBar *bar = GTK_POPOVER_BAR (widget);
+
+ gtk_widget_size_allocate (bar->box,
+ &(GtkAllocation) { 0, 0, width, height },
+ baseline);
+}
+
+static void
+gtk_popover_bar_class_init (GtkPopoverBarClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->dispose = gtk_popover_bar_dispose;
+ object_class->finalize = gtk_popover_bar_finalize;
+
+ widget_class->measure = gtk_popover_bar_measure;
+ widget_class->size_allocate = gtk_popover_bar_size_allocate;
+
+ gtk_widget_class_set_css_name (widget_class, I_("menubar"));
+}
+
+static void
+tracker_remove (gint position,
+ gpointer user_data)
+{
+ GtkPopoverBar *bar = user_data;
+ GtkWidget *child;
+ int i;
+
+ for (child = gtk_widget_get_first_child (bar->box), i = 0;
+ child;
+ child = gtk_widget_get_next_sibling (child), i++)
+ {
+ if (i == position)
+ {
+ gtk_widget_destroy (child);
+ break;
+ }
+ }
+}
+
+static void
+tracker_insert (GtkMenuTrackerItem *item,
+ gint position,
+ gpointer user_data)
+{
+ GtkPopoverBar *bar = user_data;
+
+ if (gtk_menu_tracker_item_get_has_link (item, G_MENU_LINK_SUBMENU))
+ {
+ GtkWidget *widget;
+ GMenuModel *model;
+ GtkWidget *sibling;
+ GtkWidget *child;
+ GtkWidget *popover;
+ int i;
+
+#if 0
+ widget = gtk_label_new (NULL);
+#else
+ widget = gtk_menu_button_new ();
+ gtk_menu_button_set_relief (GTK_MENU_BUTTON (widget), GTK_RELIEF_NONE);
+#endif
+ g_object_bind_property (item, "label", widget, "label", G_BINDING_SYNC_CREATE);
+
+ model = _gtk_menu_tracker_item_get_link (item, G_MENU_LINK_SUBMENU);
+#if 0
+ popover = gtk_popover_menu_new_from_model (GTK_WIDGET (bar), model);
+#else
+ gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (widget), model);
+ gtk_menu_button_set_direction (GTK_MENU_BUTTON (widget), GTK_ARROW_NONE);
+ popover = gtk_menu_button_get_popover (GTK_MENU_BUTTON (widget));
+#endif
+ gtk_popover_set_has_arrow (GTK_POPOVER (popover), FALSE);
+
+ sibling = NULL;
+ for (child = gtk_widget_get_first_child (bar->box), i = 1;
+ child;
+ child = gtk_widget_get_next_sibling (child), i++)
+ {
+ if (i == position)
+ {
+ sibling = child;
+ break;
+ }
+ }
+ gtk_box_insert_child_after (GTK_BOX (bar->box), widget, sibling);
+ }
+ else
+ g_warning ("Don't know how to handle this item");
+}
+
+GtkWidget *
+gtk_popover_bar_new_from_model (GMenuModel *model)
+{
+ GtkWidget *bar;
+ GtkActionMuxer *muxer;
+
+ bar = g_object_new (GTK_TYPE_POPOVER_BAR, NULL);
+
+ muxer = _gtk_widget_get_action_muxer (bar, TRUE);
+
+ GTK_POPOVER_BAR (bar)->tracker =
+ gtk_menu_tracker_new (GTK_ACTION_OBSERVABLE (muxer),
+ model,
+ FALSE,
+ TRUE,
+ FALSE,
+ NULL,
+ tracker_insert,
+ tracker_remove,
+ bar);
+
+ return bar;
+}
diff --git a/gtk/gtkpopoverbar.h b/gtk/gtkpopoverbar.h
new file mode 100644
index 0000000000..5b74e0bd96
--- /dev/null
+++ b/gtk/gtkpopoverbar.h
@@ -0,0 +1,47 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2019 Red Hat, Inc.
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GTK_POPOVER_BAR_H__
+#define __GTK_POPOVER_BAR_H__
+
+
+#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
+#error "Only <gtk/gtk.h> can be included directly."
+#endif
+
+#include <gtk/gtkpopover.h>
+
+
+G_BEGIN_DECLS
+
+
+#define GTK_TYPE_POPOVER_BAR (gtk_popover_bar_get_type ())
+#define GTK_POPOVER_BAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_POPOVER_BAR,
GtkPopoverBar))
+#define GTK_IS_POPOVER_BAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_POPOVER_BAR))
+
+typedef struct _GtkPopoverBar GtkPopoverBar;
+
+GDK_AVAILABLE_IN_ALL
+GType gtk_popover_bar_get_type (void) G_GNUC_CONST;
+
+GDK_AVAILABLE_IN_ALL
+GtkWidget* gtk_popover_bar_new_from_model (GMenuModel *model);
+
+G_END_DECLS
+
+
+#endif /* __GTK_POPOVER_BAR_H__ */
diff --git a/gtk/meson.build b/gtk/meson.build
index 8d7285ed7b..2c844edbef 100644
--- a/gtk/meson.build
+++ b/gtk/meson.build
@@ -296,6 +296,7 @@ gtk_public_sources = files([
'gtkpasswordentry.c',
'gtkpicture.c',
'gtkpopover.c',
+ 'gtkpopoverbar.c',
'gtkpopovermenu.c',
'gtkprintcontext.c',
'gtkprintoperation.c',
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]