Commit 26e3c508 authored by Christian Hergert's avatar Christian Hergert
Browse files

add priorty box to the header

parent f42d2ad3
......@@ -20,6 +20,7 @@ headers_DATA = \
egg-heap.h \
egg-menu-manager.h \
egg-pill-box.h \
egg-priority-box.h \
egg-private.h \
egg-search-bar.h \
egg-settings-flag-action.h \
......@@ -49,6 +50,7 @@ libegg_private_la_SOURCES = \
egg-heap.c \
egg-menu-manager.c \
egg-pill-box.c \
egg-priority-box.c \
egg-search-bar.c \
egg-settings-flag-action.c \
egg-settings-sandwich.c \
......
/* egg-priority-box.c
*
* Copyright (C) 2016 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/>.
*/
/**
* SECTION:egg-priority-box:
* @title: EggPriorityBox
*
* This is like a #GtkBox but uses stable priorities to sort.
*/
#define G_LOG_DOMAIN "egg-priority-box"
#include "egg-priority-box.h"
typedef struct
{
GtkWidget *widget;
gint priority;
} EggPriorityBoxChild;
typedef struct
{
GArray *children;
} EggPriorityBoxPrivate;
enum {
CHILD_PROP_0,
CHILD_PROP_PRIORITY,
N_CHILD_PROPS
};
G_DEFINE_TYPE_WITH_PRIVATE (EggPriorityBox, egg_priority_box, GTK_TYPE_BOX)
static GParamSpec *child_properties [N_CHILD_PROPS];
static gint
sort_by_priority (gconstpointer a,
gconstpointer b)
{
const EggPriorityBoxChild *child_a = a;
const EggPriorityBoxChild *child_b = b;
return child_a->priority - child_b->priority;
}
static void
egg_priority_box_resort (EggPriorityBox *self)
{
EggPriorityBoxPrivate *priv = egg_priority_box_get_instance_private (self);
guint i;
g_assert (EGG_IS_PRIORITY_BOX (self));
g_array_sort (priv->children, sort_by_priority);
for (i = 0; i < priv->children->len; i++)
{
EggPriorityBoxChild *child = &g_array_index (priv->children, EggPriorityBoxChild, i);
gtk_container_child_set (GTK_CONTAINER (self), child->widget,
"position", i,
NULL);
}
}
static gint
egg_priority_box_get_child_priority (EggPriorityBox *self,
GtkWidget *widget)
{
EggPriorityBoxPrivate *priv = egg_priority_box_get_instance_private (self);
guint i;
g_assert (EGG_IS_PRIORITY_BOX (self));
g_assert (GTK_IS_WIDGET (widget));
for (i = 0; i < priv->children->len; i++)
{
EggPriorityBoxChild *child = &g_array_index (priv->children, EggPriorityBoxChild, i);
if (child->widget == widget)
return child->priority;
}
g_warning ("No such child \"%s\" of \"%s\"",
G_OBJECT_TYPE_NAME (widget),
G_OBJECT_TYPE_NAME (self));
return 0;
}
static void
egg_priority_box_set_child_priority (EggPriorityBox *self,
GtkWidget *widget,
gint priority)
{
EggPriorityBoxPrivate *priv = egg_priority_box_get_instance_private (self);
guint i;
g_assert (EGG_IS_PRIORITY_BOX (self));
g_assert (GTK_IS_WIDGET (widget));
for (i = 0; i < priv->children->len; i++)
{
EggPriorityBoxChild *child = &g_array_index (priv->children, EggPriorityBoxChild, i);
if (child->widget == widget)
{
child->priority = priority;
egg_priority_box_resort (self);
return;
}
}
g_warning ("No such child \"%s\" of \"%s\"",
G_OBJECT_TYPE_NAME (widget),
G_OBJECT_TYPE_NAME (self));
}
static void
egg_priority_box_add (GtkContainer *container,
GtkWidget *widget)
{
EggPriorityBox *self = (EggPriorityBox *)container;
EggPriorityBoxPrivate *priv = egg_priority_box_get_instance_private (self);
EggPriorityBoxChild child;
g_assert (EGG_IS_PRIORITY_BOX (self));
g_assert (GTK_IS_WIDGET (widget));
child.widget = widget;
child.priority = 0;
g_array_append_val (priv->children, child);
GTK_CONTAINER_CLASS (egg_priority_box_parent_class)->add (container, widget);
egg_priority_box_resort (self);
}
static void
egg_priority_box_remove (GtkContainer *container,
GtkWidget *widget)
{
EggPriorityBox *self = (EggPriorityBox *)container;
EggPriorityBoxPrivate *priv = egg_priority_box_get_instance_private (self);
guint i;
g_assert (EGG_IS_PRIORITY_BOX (self));
g_assert (GTK_IS_WIDGET (widget));
for (i = 0; i < priv->children->len; i++)
{
EggPriorityBoxChild *child;
child = &g_array_index (priv->children, EggPriorityBoxChild, i);
if (child->widget == widget)
{
g_array_remove_index_fast (priv->children, i);
break;
}
}
GTK_CONTAINER_CLASS (egg_priority_box_parent_class)->remove (container, widget);
egg_priority_box_resort (self);
}
static void
egg_priority_box_finalize (GObject *object)
{
EggPriorityBox *self = (EggPriorityBox *)object;
EggPriorityBoxPrivate *priv = egg_priority_box_get_instance_private (self);
g_clear_pointer (&priv->children, g_array_unref);
G_OBJECT_CLASS (egg_priority_box_parent_class)->finalize (object);
}
static void
egg_priority_box_get_child_property (GtkContainer *container,
GtkWidget *child,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
EggPriorityBox *self = EGG_PRIORITY_BOX (container);
switch (prop_id)
{
case CHILD_PROP_PRIORITY:
g_value_set_int (value, egg_priority_box_get_child_priority (self, child));
break;
default:
GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, prop_id, pspec);
}
}
static void
egg_priority_box_set_child_property (GtkContainer *container,
GtkWidget *child,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
EggPriorityBox *self = EGG_PRIORITY_BOX (container);
switch (prop_id)
{
case CHILD_PROP_PRIORITY:
egg_priority_box_set_child_priority (self, child, g_value_get_int (value));
break;
default:
GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, prop_id, pspec);
}
}
static void
egg_priority_box_class_init (EggPriorityBoxClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
object_class->finalize = egg_priority_box_finalize;
container_class->add = egg_priority_box_add;
container_class->remove = egg_priority_box_remove;
container_class->get_child_property = egg_priority_box_get_child_property;
container_class->set_child_property = egg_priority_box_set_child_property;
child_properties [CHILD_PROP_PRIORITY] =
g_param_spec_int ("priority",
"Priority",
"Priority",
G_MININT,
G_MAXINT,
0,
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gtk_container_class_install_child_properties (container_class, N_CHILD_PROPS, child_properties);
}
static void
egg_priority_box_init (EggPriorityBox *self)
{
EggPriorityBoxPrivate *priv = egg_priority_box_get_instance_private (self);
priv->children = g_array_new (FALSE, FALSE, sizeof (EggPriorityBoxChild));
}
/* egg-priority-box.h
*
* Copyright (C) 2016 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 EGG_PRIORITY_BOX_H
#define EGG_PRIORITY_BOX_H
#include <gtk/gtk.h>
G_BEGIN_DECLS
G_DECLARE_DERIVABLE_TYPE (EggPriorityBox, egg_priority_box, EGG, PRIORITY_BOX, GtkBox)
struct _EggPriorityBoxClass
{
GtkBoxClass parent_class;
gpointer _reserved1;
gpointer _reserved2;
gpointer _reserved3;
gpointer _reserved4;
};
GtkWidget *egg_priority_box_new (void);
G_END_DECLS
#endif /* EGG_PRIORITY_BOX_H */
......@@ -18,6 +18,8 @@
#define G_LOG_DOMAIN "ide-workbench-header-bar"
#include <egg-priority-box.h>
#include "application/ide-application.h"
#include "util/ide-gtk.h"
#include "workbench/ide-perspective.h"
......@@ -27,11 +29,13 @@
typedef struct
{
GtkMenuButton *menu_button;
GtkListBox *perspectives_list_box;
GtkMenuButton *perspectives_menu_button;
GtkImage *perspectives_menu_button_image;
GtkPopover *perspectives_popover;
GtkMenuButton *menu_button;
GtkListBox *perspectives_list_box;
GtkMenuButton *perspectives_menu_button;
GtkImage *perspectives_menu_button_image;
GtkPopover *perspectives_popover;
EggPriorityBox *right_box;
EggPriorityBox *left_box;
} IdeWorkbenchHeaderBarPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (IdeWorkbenchHeaderBar, ide_workbench_header_bar, GTK_TYPE_HEADER_BAR)
......@@ -79,6 +83,8 @@ ide_workbench_header_bar_class_init (IdeWorkbenchHeaderBarClass *klass)
gtk_widget_class_bind_template_child_private (widget_class, IdeWorkbenchHeaderBar, perspectives_menu_button);
gtk_widget_class_bind_template_child_private (widget_class, IdeWorkbenchHeaderBar, perspectives_menu_button_image);
gtk_widget_class_bind_template_child_private (widget_class, IdeWorkbenchHeaderBar, perspectives_popover);
gtk_widget_class_bind_template_child_private (widget_class, IdeWorkbenchHeaderBar, left_box);
gtk_widget_class_bind_template_child_private (widget_class, IdeWorkbenchHeaderBar, right_box);
}
static void
......@@ -195,3 +201,39 @@ _ide_workbench_header_bar_set_perspective (IdeWorkbenchHeaderBar *self,
"icon-name", icon_name,
NULL);
}
void
ide_workbench_header_bar_insert_left (IdeWorkbenchHeaderBar *self,
GtkWidget *widget,
GtkPackType pack_type,
gint priority)
{
IdeWorkbenchHeaderBarPrivate *priv = ide_workbench_header_bar_get_instance_private (self);
g_return_if_fail (IDE_IS_WORKBENCH_HEADER_BAR (self));
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (pack_type == GTK_PACK_START || pack_type == GTK_PACK_END);
gtk_container_add_with_properties (GTK_CONTAINER (priv->left_box), widget,
"pack-type", pack_type,
"priority", priority,
NULL);
}
void
ide_workbench_header_bar_insert_right (IdeWorkbenchHeaderBar *self,
GtkWidget *widget,
GtkPackType pack_type,
gint priority)
{
IdeWorkbenchHeaderBarPrivate *priv = ide_workbench_header_bar_get_instance_private (self);
g_return_if_fail (IDE_IS_WORKBENCH_HEADER_BAR (self));
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (pack_type == GTK_PACK_START || pack_type == GTK_PACK_END);
gtk_container_add_with_properties (GTK_CONTAINER (priv->right_box), widget,
"pack-type", pack_type,
"priority", priority,
NULL);
}
......@@ -43,6 +43,14 @@ struct _IdeWorkbenchHeaderBarClass
GtkWidget *ide_workbench_header_bar_new (void);
void ide_workbench_header_bar_focus_search (IdeWorkbenchHeaderBar *self);
void ide_workbench_header_bar_insert_left (IdeWorkbenchHeaderBar *self,
GtkWidget *widget,
GtkPackType pack_type,
gint priority);
void ide_workbench_header_bar_insert_right (IdeWorkbenchHeaderBar *self,
GtkWidget *widget,
GtkPackType pack_type,
gint priority);
G_END_DECLS
......
......@@ -47,6 +47,16 @@
<property name="position">0</property>
</packing>
</child>
<child>
<object class="EggPriorityBox" id="left_box">
<property name="hexpand">true</property>
<property name="visible">true</property>
</object>
<packing>
<property name="pack-type">start</property>
<property name="position">1</property>
</packing>
</child>
<child type="title">
<object class="IdeOmniSearchEntry" id="search_entry">
<property name="tooltip-text" translatable="yes">Search for files. Shortcut: Ctrl + .</property>
......@@ -76,5 +86,15 @@
<property name="position">0</property>
</packing>
</child>
<child>
<object class="EggPriorityBox" id="right_box">
<property name="hexpand">true</property>
<property name="visible">true</property>
</object>
<packing>
<property name="pack-type">end</property>
<property name="position">1</property>
</packing>
</child>
</template>
</interface>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment