Add a tab strip widget
This adds GtkTabStrip and GtkTab, which will eventually allow creating typical notebook scenarios with GtkStack. Inspired by the PnlTabStrip prototype that Christian Hergert wrote for gnome-builder.
This commit is contained in:
@@ -302,6 +302,8 @@ gtk_public_h_sources = \
|
||||
gtkstylecontext.h \
|
||||
gtkstyleprovider.h \
|
||||
gtkswitch.h \
|
||||
gtktab.h \
|
||||
gtktabstrip.h \
|
||||
gtktestutils.h \
|
||||
gtktextattributes.h \
|
||||
gtktextbuffer.h \
|
||||
@@ -900,6 +902,8 @@ gtk_base_c_sources = \
|
||||
gtkstyleprovider.c \
|
||||
gtkstyleproviderprivate.c \
|
||||
gtkswitch.c \
|
||||
gtktab.c \
|
||||
gtktabstrip.c \
|
||||
gtktestutils.c \
|
||||
gtktextattributes.c \
|
||||
gtktextbtree.c \
|
||||
|
||||
@@ -203,6 +203,8 @@
|
||||
#include <gtk/gtkstylecontext.h>
|
||||
#include <gtk/gtkstyleprovider.h>
|
||||
#include <gtk/gtkswitch.h>
|
||||
#include <gtk/gtktab.h>
|
||||
#include <gtk/gtktabstrip.h>
|
||||
#include <gtk/gtktextattributes.h>
|
||||
#include <gtk/gtktextbuffer.h>
|
||||
#include <gtk/gtktextbufferrichtext.h>
|
||||
|
||||
519
gtk/gtktab.c
Normal file
519
gtk/gtktab.c
Normal file
@@ -0,0 +1,519 @@
|
||||
/* gtktab.c
|
||||
*
|
||||
* Copyright (C) 2016 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 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 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 "gtktab.h"
|
||||
#include "gtkintl.h"
|
||||
#include "gtkprivate.h"
|
||||
#include "gtkenums.h"
|
||||
#include "gtktypebuiltins.h"
|
||||
#include "gtkboxgadgetprivate.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
|
||||
typedef struct _GtkTabPrivate GtkTabPrivate;
|
||||
|
||||
struct _GtkTabPrivate
|
||||
{
|
||||
gchar *title;
|
||||
GtkWidget *widget;
|
||||
|
||||
GtkWidget *child;
|
||||
GtkCssGadget *gadget;
|
||||
GdkWindow *event_window;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GtkTab, gtk_tab, GTK_TYPE_CONTAINER)
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_TITLE,
|
||||
PROP_WIDGET,
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
static GParamSpec *properties[N_PROPS];
|
||||
|
||||
enum {
|
||||
ACTIVATE,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL];
|
||||
|
||||
static void
|
||||
gtk_tab_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkTab *self = GTK_TAB (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_TITLE:
|
||||
g_value_set_string (value, gtk_tab_get_title (self));
|
||||
break;
|
||||
|
||||
case PROP_WIDGET:
|
||||
g_value_set_object (value, gtk_tab_get_widget (self));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tab_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkTab *self = GTK_TAB (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_TITLE:
|
||||
gtk_tab_set_title (self, g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_WIDGET:
|
||||
gtk_tab_set_widget (self, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tab_finalize (GObject *object)
|
||||
{
|
||||
GtkTab *self = GTK_TAB (object);
|
||||
GtkTabPrivate *priv = gtk_tab_get_instance_private (self);
|
||||
|
||||
g_free (priv->title);
|
||||
|
||||
g_clear_object (&priv->gadget);
|
||||
|
||||
G_OBJECT_CLASS (gtk_tab_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tab_destroy (GtkWidget *widget)
|
||||
{
|
||||
GtkTab *self = GTK_TAB (widget);
|
||||
GtkTabPrivate *priv = gtk_tab_get_instance_private (self);
|
||||
|
||||
if (priv->widget)
|
||||
{
|
||||
g_object_remove_weak_pointer (G_OBJECT (priv->widget), (gpointer *)&priv->widget);
|
||||
priv->widget = NULL;
|
||||
}
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_tab_parent_class)->destroy (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tab_realize (GtkWidget *widget)
|
||||
{
|
||||
GtkTab *self = GTK_TAB (widget);
|
||||
GtkTabPrivate *priv = gtk_tab_get_instance_private (self);
|
||||
GdkWindow *window;
|
||||
GdkWindowAttr attributes;
|
||||
gint attributes_mask;
|
||||
GtkAllocation allocation;
|
||||
|
||||
gtk_widget_set_realized (widget, TRUE);
|
||||
|
||||
gtk_widget_get_allocation (widget, &allocation);
|
||||
|
||||
window = gtk_widget_get_parent_window (widget);
|
||||
gtk_widget_set_window (widget, window);
|
||||
g_object_ref (window);
|
||||
|
||||
attributes.window_type = GDK_WINDOW_CHILD;
|
||||
attributes.x = allocation.x;
|
||||
attributes.y = allocation.y;
|
||||
attributes.width = allocation.width;
|
||||
attributes.height = allocation.height;
|
||||
attributes.wclass = GDK_INPUT_ONLY;
|
||||
attributes.event_mask = gtk_widget_get_events (widget);
|
||||
attributes.event_mask |= (GDK_BUTTON_PRESS_MASK |
|
||||
GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK |
|
||||
GDK_POINTER_MOTION_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
|
||||
attributes_mask = GDK_WA_X | GDK_WA_Y;
|
||||
|
||||
priv->event_window = gdk_window_new (gtk_widget_get_parent_window (widget),
|
||||
&attributes, attributes_mask);
|
||||
gtk_widget_register_window (widget, priv->event_window);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tab_unrealize (GtkWidget *widget)
|
||||
{
|
||||
GtkTab *self = GTK_TAB (widget);
|
||||
GtkTabPrivate *priv = gtk_tab_get_instance_private (self);
|
||||
|
||||
gtk_widget_unregister_window (widget, priv->event_window);
|
||||
gdk_window_destroy (priv->event_window);
|
||||
priv->event_window = NULL;
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_tab_parent_class)->unrealize (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tab_map (GtkWidget *widget)
|
||||
{
|
||||
GtkTab *self = GTK_TAB (widget);
|
||||
GtkTabPrivate *priv = gtk_tab_get_instance_private (self);
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_tab_parent_class)->map (widget);
|
||||
|
||||
gdk_window_show_unraised (priv->event_window);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tab_unmap (GtkWidget *widget)
|
||||
{
|
||||
GtkTab *self = GTK_TAB (widget);
|
||||
GtkTabPrivate *priv = gtk_tab_get_instance_private (self);
|
||||
|
||||
gdk_window_hide (priv->event_window);
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_tab_parent_class)->unmap (widget);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_tab_enter (GtkWidget *widget,
|
||||
GdkEventCrossing *event)
|
||||
{
|
||||
gtk_widget_set_state_flags (widget, GTK_STATE_FLAG_PRELIGHT, FALSE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_tab_leave (GtkWidget *widget,
|
||||
GdkEventCrossing *event)
|
||||
{
|
||||
gtk_widget_unset_state_flags (widget, GTK_STATE_FLAG_PRELIGHT);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_tab_button_press (GtkWidget *widget,
|
||||
GdkEventButton *event)
|
||||
{
|
||||
if (event->button != GDK_BUTTON_PRIMARY)
|
||||
return FALSE;
|
||||
|
||||
g_signal_emit (widget, signals[ACTIVATE], 0);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tab_get_preferred_width (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
GtkTab *self = GTK_TAB (widget);
|
||||
GtkTabPrivate *priv = gtk_tab_get_instance_private (self);
|
||||
|
||||
gtk_css_gadget_get_preferred_size (priv->gadget,
|
||||
GTK_ORIENTATION_HORIZONTAL,
|
||||
-1,
|
||||
minimum, natural,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tab_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
GtkTab *self = GTK_TAB (widget);
|
||||
GtkTabPrivate *priv = gtk_tab_get_instance_private (self);
|
||||
|
||||
gtk_css_gadget_get_preferred_size (priv->gadget,
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
-1,
|
||||
minimum, natural,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tab_get_preferred_width_for_height (GtkWidget *widget,
|
||||
gint height,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
GtkTab *self = GTK_TAB (widget);
|
||||
GtkTabPrivate *priv = gtk_tab_get_instance_private (self);
|
||||
|
||||
gtk_css_gadget_get_preferred_size (priv->gadget,
|
||||
GTK_ORIENTATION_HORIZONTAL,
|
||||
height,
|
||||
minimum, natural,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tab_get_preferred_height_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
GtkTab *self = GTK_TAB (widget);
|
||||
GtkTabPrivate *priv = gtk_tab_get_instance_private (self);
|
||||
|
||||
gtk_css_gadget_get_preferred_size (priv->gadget,
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
width,
|
||||
minimum, natural,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tab_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation)
|
||||
{
|
||||
GtkTab *self = GTK_TAB (widget);
|
||||
GtkTabPrivate *priv = gtk_tab_get_instance_private (self);
|
||||
GtkAllocation clip;
|
||||
|
||||
gtk_widget_set_allocation (widget, allocation);
|
||||
|
||||
gtk_css_gadget_allocate (priv->gadget,
|
||||
allocation,
|
||||
gtk_widget_get_allocated_baseline (widget),
|
||||
&clip);
|
||||
|
||||
gtk_widget_set_clip (widget, &clip);
|
||||
|
||||
if (gtk_widget_get_realized (widget))
|
||||
{
|
||||
GtkAllocation border_allocation;
|
||||
|
||||
gtk_css_gadget_get_border_allocation (priv->gadget, &border_allocation, NULL);
|
||||
gdk_window_move_resize (priv->event_window,
|
||||
border_allocation.x, border_allocation.y,
|
||||
border_allocation.width, border_allocation.height);
|
||||
if (gtk_widget_get_mapped (widget))
|
||||
gdk_window_show_unraised (priv->event_window);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_tab_draw (GtkWidget *widget,
|
||||
cairo_t *cr)
|
||||
{
|
||||
GtkTab *self = GTK_TAB (widget);
|
||||
GtkTabPrivate *priv = gtk_tab_get_instance_private (self);
|
||||
|
||||
gtk_css_gadget_draw (priv->gadget, cr);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tab_add (GtkContainer *container,
|
||||
GtkWidget *child)
|
||||
{
|
||||
GtkTab *self = GTK_TAB (container);
|
||||
GtkTabPrivate *priv = gtk_tab_get_instance_private (self);
|
||||
|
||||
if (priv->child)
|
||||
{
|
||||
g_warning ("GtkTab cannot have more than one child");
|
||||
return;
|
||||
}
|
||||
|
||||
priv->child = child;
|
||||
gtk_widget_set_parent (child, GTK_WIDGET (container));
|
||||
gtk_box_gadget_insert_widget (GTK_BOX_GADGET (priv->gadget), 0, child);
|
||||
gtk_box_gadget_set_gadget_expand (GTK_BOX_GADGET (priv->gadget), G_OBJECT (child), TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tab_remove (GtkContainer *container,
|
||||
GtkWidget *child)
|
||||
{
|
||||
GtkTab *self = GTK_TAB (container);
|
||||
GtkTabPrivate *priv = gtk_tab_get_instance_private (self);
|
||||
|
||||
if (priv->child == child)
|
||||
{
|
||||
gtk_box_gadget_remove_widget (GTK_BOX_GADGET (priv->gadget), child);
|
||||
gtk_widget_unparent (child);
|
||||
priv->child = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tab_forall (GtkContainer *container,
|
||||
gboolean include_internals,
|
||||
GtkCallback callback,
|
||||
gpointer data)
|
||||
{
|
||||
GtkTab *self = GTK_TAB (container);
|
||||
GtkTabPrivate *priv = gtk_tab_get_instance_private (self);
|
||||
|
||||
if (priv->child)
|
||||
(*callback) (priv->child, data);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tab_class_init (GtkTabClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
|
||||
|
||||
object_class->get_property = gtk_tab_get_property;
|
||||
object_class->set_property = gtk_tab_set_property;
|
||||
object_class->finalize = gtk_tab_finalize;
|
||||
|
||||
widget_class->destroy = gtk_tab_destroy;
|
||||
widget_class->realize = gtk_tab_realize;
|
||||
widget_class->unrealize = gtk_tab_unrealize;
|
||||
widget_class->map = gtk_tab_map;
|
||||
widget_class->unmap = gtk_tab_unmap;
|
||||
widget_class->enter_notify_event = gtk_tab_enter;
|
||||
widget_class->leave_notify_event = gtk_tab_leave;
|
||||
widget_class->button_press_event = gtk_tab_button_press;
|
||||
widget_class->get_preferred_width = gtk_tab_get_preferred_width;
|
||||
widget_class->get_preferred_height = gtk_tab_get_preferred_height;
|
||||
widget_class->get_preferred_width_for_height = gtk_tab_get_preferred_width_for_height;
|
||||
widget_class->get_preferred_height_for_width = gtk_tab_get_preferred_height_for_width;
|
||||
widget_class->size_allocate = gtk_tab_size_allocate;
|
||||
widget_class->draw = gtk_tab_draw;
|
||||
|
||||
container_class->add = gtk_tab_add;
|
||||
container_class->remove = gtk_tab_remove;
|
||||
container_class->forall = gtk_tab_forall;
|
||||
|
||||
gtk_widget_class_set_css_name (widget_class, "tab");
|
||||
|
||||
properties[PROP_TITLE] =
|
||||
g_param_spec_string ("title", P_("Title"), P_("Title"),
|
||||
NULL,
|
||||
GTK_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_WIDGET] =
|
||||
g_param_spec_object ("widget", P_("Widget"), P_("The widget the tab represents"),
|
||||
GTK_TYPE_WIDGET,
|
||||
GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||
|
||||
signals[ACTIVATE] =
|
||||
g_signal_new (I_("activate"),
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
|
||||
G_STRUCT_OFFSET (GtkTabClass, activate),
|
||||
NULL, NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
widget_class->activate_signal = signals[ACTIVATE];
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tab_init (GtkTab *self)
|
||||
{
|
||||
GtkTabPrivate *priv = gtk_tab_get_instance_private (self);
|
||||
GtkCssNode *widget_node;
|
||||
|
||||
gtk_widget_set_can_focus (GTK_WIDGET (self), TRUE);
|
||||
gtk_widget_set_has_window (GTK_WIDGET (self), FALSE);
|
||||
|
||||
widget_node = gtk_widget_get_css_node (GTK_WIDGET (self));
|
||||
priv->gadget = gtk_box_gadget_new_for_node (widget_node, GTK_WIDGET (self));
|
||||
gtk_box_gadget_set_draw_focus (GTK_BOX_GADGET (priv->gadget), TRUE);
|
||||
}
|
||||
|
||||
const gchar *
|
||||
gtk_tab_get_title (GtkTab *self)
|
||||
{
|
||||
GtkTabPrivate *priv = gtk_tab_get_instance_private (self);
|
||||
|
||||
g_return_val_if_fail (GTK_IS_TAB (self), NULL);
|
||||
|
||||
return priv->title;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_tab_set_title (GtkTab *self,
|
||||
const gchar *title)
|
||||
{
|
||||
GtkTabPrivate *priv = gtk_tab_get_instance_private (self);
|
||||
|
||||
g_return_if_fail (GTK_IS_TAB (self));
|
||||
|
||||
g_free (priv->title);
|
||||
priv->title = g_strdup (title);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_TITLE]);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
gtk_tab_get_widget (GtkTab *self)
|
||||
{
|
||||
GtkTabPrivate *priv = gtk_tab_get_instance_private (self);
|
||||
|
||||
g_return_val_if_fail (GTK_IS_TAB (self), NULL);
|
||||
|
||||
return priv->widget;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_tab_set_widget (GtkTab *self,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
GtkTabPrivate *priv = gtk_tab_get_instance_private (self);
|
||||
|
||||
g_return_if_fail (GTK_IS_TAB (self));
|
||||
|
||||
if (priv->widget == widget)
|
||||
return;
|
||||
|
||||
if (priv->widget)
|
||||
g_object_remove_weak_pointer (G_OBJECT (priv->widget), (gpointer *)&priv->widget);
|
||||
|
||||
priv->widget = widget;
|
||||
|
||||
if (widget)
|
||||
g_object_add_weak_pointer (G_OBJECT (priv->widget), (gpointer *)&priv->widget);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_WIDGET]);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_tab_set_child (GtkTab *self,
|
||||
GtkWidget *child)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_TAB (self));
|
||||
g_return_if_fail (GTK_IS_WIDGET (child));
|
||||
|
||||
gtk_tab_add (GTK_CONTAINER (self), child);
|
||||
}
|
||||
75
gtk/gtktab.h
Normal file
75
gtk/gtktab.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/* gtktab.h
|
||||
*
|
||||
* Copyright (C) 2016 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 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 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_TAB_H__
|
||||
#define __GTK_TAB_H__
|
||||
|
||||
#include <gtk/gtkcontainer.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_TAB (gtk_tab_get_type ())
|
||||
#define GTK_TAB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_TAB, GtkTab))
|
||||
#define GTK_IS_TAB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_TAB))
|
||||
#define GTK_TAB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_TAB, GtkTabClass))
|
||||
#define GTK_IS_TAB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_TAB))
|
||||
#define GTK_TAB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_TAB, GtkTabClass))
|
||||
|
||||
typedef struct _GtkTab GtkTab;
|
||||
typedef struct _GtkTabClass GtkTabClass;
|
||||
|
||||
struct _GtkTab
|
||||
{
|
||||
GtkContainer parent;
|
||||
};
|
||||
|
||||
struct _GtkTabClass
|
||||
{
|
||||
GtkContainerClass parent_class;
|
||||
|
||||
void (* activate) (GtkTab *tab);
|
||||
|
||||
/* Padding for future expansion */
|
||||
void (*_gtk_reserved1) (void);
|
||||
void (*_gtk_reserved2) (void);
|
||||
void (*_gtk_reserved3) (void);
|
||||
void (*_gtk_reserved4) (void);
|
||||
void (*_gtk_reserved5) (void);
|
||||
void (*_gtk_reserved6) (void);
|
||||
};
|
||||
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
GType gtk_tab_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
const gchar *gtk_tab_get_title (GtkTab *self);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
void gtk_tab_set_title (GtkTab *self,
|
||||
const gchar *title);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
GtkWidget *gtk_tab_get_widget (GtkTab *self);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
void gtk_tab_set_widget (GtkTab *self,
|
||||
GtkWidget *widget);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
void gtk_tab_set_child (GtkTab *self,
|
||||
GtkWidget *child);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_TAB_H__ */
|
||||
546
gtk/gtktabstrip.c
Normal file
546
gtk/gtktabstrip.c
Normal file
@@ -0,0 +1,546 @@
|
||||
/* gtktabstrip.c
|
||||
*
|
||||
* Copyright (C) 2016 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 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 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 "gtktabstrip.h"
|
||||
#include "gtktab.h"
|
||||
#include "gtksimpletab.h"
|
||||
#include "gtkintl.h"
|
||||
#include "gtkprivate.h"
|
||||
#include "gtkorientable.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GtkStack *stack;
|
||||
gboolean in_child_changed;
|
||||
GdkWindow *event_window;
|
||||
} GtkTabStripPrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GtkTabStrip, gtk_tab_strip, GTK_TYPE_BOX)
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_STACK,
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
static GParamSpec *properties[N_PROPS];
|
||||
|
||||
static void
|
||||
gtk_tab_strip_add (GtkContainer *container,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
GTK_CONTAINER_CLASS (gtk_tab_strip_parent_class)->add (container, widget);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tab_strip_destroy (GtkWidget *widget)
|
||||
{
|
||||
GtkTabStrip *self = GTK_TAB_STRIP (widget);
|
||||
GtkTabStripPrivate *priv = gtk_tab_strip_get_instance_private (self);
|
||||
|
||||
gtk_tab_strip_set_stack (self, NULL);
|
||||
|
||||
g_clear_object (&priv->stack);
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_tab_strip_parent_class)->destroy (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tab_strip_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkTabStrip *self = GTK_TAB_STRIP (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_STACK:
|
||||
g_value_set_object (value, gtk_tab_strip_get_stack (self));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tab_strip_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkTabStrip *self = GTK_TAB_STRIP (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_STACK:
|
||||
gtk_tab_strip_set_stack (self, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_widget_coordinates (GtkWidget *widget,
|
||||
GdkEvent *event,
|
||||
gdouble *x,
|
||||
gdouble *y)
|
||||
{
|
||||
GdkWindow *window = ((GdkEventAny *)event)->window;
|
||||
gdouble tx, ty;
|
||||
|
||||
if (!gdk_event_get_coords (event, &tx, &ty))
|
||||
return FALSE;
|
||||
|
||||
while (window && window != gtk_widget_get_window (widget))
|
||||
{
|
||||
gint window_x, window_y;
|
||||
|
||||
gdk_window_get_position (window, &window_x, &window_y);
|
||||
tx += window_x;
|
||||
ty += window_y;
|
||||
|
||||
window = gdk_window_get_parent (window);
|
||||
}
|
||||
|
||||
if (window)
|
||||
{
|
||||
*x = tx;
|
||||
*y = ty;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static GtkTab *
|
||||
get_tab_at_pos (GtkTabStrip *self,
|
||||
gdouble x,
|
||||
gdouble y)
|
||||
{
|
||||
GtkAllocation allocation;
|
||||
GList *children, *l;
|
||||
GtkTab *tab;
|
||||
|
||||
children = gtk_container_get_children (GTK_CONTAINER (self));
|
||||
|
||||
tab = NULL;
|
||||
for (l = children; l; l = l->next)
|
||||
{
|
||||
gtk_widget_get_allocation (GTK_WIDGET (l->data), &allocation);
|
||||
if ((x >= allocation.x) &&
|
||||
(y >= allocation.y) &&
|
||||
(x <= (allocation.x + allocation.width)) &&
|
||||
(y <= (allocation.y + allocation.height)))
|
||||
{
|
||||
tab = l->data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_list_free (children);
|
||||
|
||||
return tab;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_tab_strip_button_press (GtkWidget *widget,
|
||||
GdkEventButton *event)
|
||||
{
|
||||
GtkTabStrip *self = GTK_TAB_STRIP (widget);
|
||||
GtkTabStripPrivate *priv = gtk_tab_strip_get_instance_private (self);
|
||||
GtkTab *tab;
|
||||
GtkWidget *child;
|
||||
gdouble x, y;
|
||||
|
||||
if (!get_widget_coordinates (widget, (GdkEvent *)event, &x, &y))
|
||||
return FALSE;
|
||||
|
||||
if (event->button != GDK_BUTTON_PRIMARY)
|
||||
return FALSE;
|
||||
|
||||
tab = get_tab_at_pos (self, x, y);
|
||||
|
||||
if (tab == NULL)
|
||||
return FALSE;
|
||||
|
||||
child = gtk_tab_get_widget (tab);
|
||||
if (child == NULL)
|
||||
return FALSE;
|
||||
|
||||
gtk_stack_set_visible_child (priv->stack, child);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tab_strip_map (GtkWidget *widget)
|
||||
{
|
||||
GtkTabStrip *self = GTK_TAB_STRIP (widget);
|
||||
GtkTabStripPrivate *priv = gtk_tab_strip_get_instance_private (self);
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_tab_strip_parent_class)->map (widget);
|
||||
|
||||
gdk_window_show_unraised (priv->event_window);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tab_strip_unmap (GtkWidget *widget)
|
||||
{
|
||||
GtkTabStrip *self = GTK_TAB_STRIP (widget);
|
||||
GtkTabStripPrivate *priv = gtk_tab_strip_get_instance_private (self);
|
||||
|
||||
gdk_window_hide (priv->event_window);
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_tab_strip_parent_class)->unmap (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tab_strip_realize (GtkWidget *widget)
|
||||
{
|
||||
GtkTabStrip *self = GTK_TAB_STRIP (widget);
|
||||
GtkTabStripPrivate *priv = gtk_tab_strip_get_instance_private (self);
|
||||
GdkWindow *window;
|
||||
GdkWindowAttr attributes;
|
||||
gint attributes_mask;
|
||||
GtkAllocation allocation;
|
||||
|
||||
gtk_widget_set_realized (widget, TRUE);
|
||||
|
||||
gtk_widget_get_allocation (widget, &allocation);
|
||||
|
||||
window = gtk_widget_get_parent_window (widget);
|
||||
gtk_widget_set_window (widget, window);
|
||||
g_object_ref (window);
|
||||
|
||||
attributes.window_type = GDK_WINDOW_CHILD;
|
||||
attributes.x = allocation.x;
|
||||
attributes.y = allocation.y;
|
||||
attributes.width = allocation.width;
|
||||
attributes.height = allocation.height;
|
||||
attributes.wclass = GDK_INPUT_ONLY;
|
||||
attributes.event_mask = gtk_widget_get_events (widget);
|
||||
attributes.event_mask |= (GDK_BUTTON_PRESS_MASK |
|
||||
GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK |
|
||||
GDK_POINTER_MOTION_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
|
||||
attributes_mask = GDK_WA_X | GDK_WA_Y;
|
||||
|
||||
priv->event_window = gdk_window_new (gtk_widget_get_parent_window (widget),
|
||||
&attributes, attributes_mask);
|
||||
gtk_widget_register_window (widget, priv->event_window);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tab_strip_unrealize (GtkWidget *widget)
|
||||
{
|
||||
GtkTabStrip *self = GTK_TAB_STRIP (widget);
|
||||
GtkTabStripPrivate *priv = gtk_tab_strip_get_instance_private (self);
|
||||
|
||||
gtk_widget_unregister_window (widget, priv->event_window);
|
||||
gdk_window_destroy (priv->event_window);
|
||||
priv->event_window = NULL;
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_tab_strip_parent_class)->unrealize (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tab_strip_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation)
|
||||
{
|
||||
GtkTabStrip *self = GTK_TAB_STRIP (widget);
|
||||
GtkTabStripPrivate *priv = gtk_tab_strip_get_instance_private (self);
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_tab_strip_parent_class)->size_allocate (widget, allocation);
|
||||
|
||||
if (gtk_widget_get_realized (widget))
|
||||
{
|
||||
gdk_window_move_resize (priv->event_window,
|
||||
allocation->x, allocation->y,
|
||||
allocation->width, allocation->height);
|
||||
if (gtk_widget_get_mapped (widget))
|
||||
gdk_window_show_unraised (priv->event_window);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tab_strip_class_init (GtkTabStripClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
|
||||
|
||||
object_class->get_property = gtk_tab_strip_get_property;
|
||||
object_class->set_property = gtk_tab_strip_set_property;
|
||||
|
||||
widget_class->destroy = gtk_tab_strip_destroy;
|
||||
widget_class->map = gtk_tab_strip_map;
|
||||
widget_class->unmap = gtk_tab_strip_unmap;
|
||||
widget_class->realize = gtk_tab_strip_realize;
|
||||
widget_class->unrealize = gtk_tab_strip_unrealize;
|
||||
widget_class->size_allocate = gtk_tab_strip_size_allocate;
|
||||
widget_class->button_press_event = gtk_tab_strip_button_press;
|
||||
|
||||
container_class->add = gtk_tab_strip_add;
|
||||
|
||||
properties[PROP_STACK] =
|
||||
g_param_spec_object ("stack", P_("Stack"), P_("The stack of items to manage"),
|
||||
GTK_TYPE_STACK,
|
||||
GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||
|
||||
gtk_widget_class_set_css_name (widget_class, "tabs");
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tab_strip_init (GtkTabStrip *self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tab_strip_child_position_changed (GtkTabStrip *self,
|
||||
GParamSpec *pspec,
|
||||
GtkWidget *child)
|
||||
{
|
||||
GtkWidget *parent;
|
||||
GtkTab *tab;
|
||||
guint position;
|
||||
|
||||
tab = g_object_get_data (G_OBJECT (child), "GTK_TAB");
|
||||
|
||||
if (!tab || !GTK_IS_TAB (tab))
|
||||
return;
|
||||
|
||||
parent = gtk_widget_get_parent (child);
|
||||
|
||||
gtk_container_child_get (GTK_CONTAINER (parent), child,
|
||||
"position", &position,
|
||||
NULL);
|
||||
|
||||
gtk_container_child_set (GTK_CONTAINER (self), GTK_WIDGET (tab),
|
||||
"position", position,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tab_strip_child_title_changed (GtkTabStrip *self,
|
||||
GParamSpec *pspec,
|
||||
GtkWidget *child)
|
||||
{
|
||||
g_autofree gchar *title = NULL;
|
||||
GtkWidget *parent;
|
||||
GtkTab *tab;
|
||||
|
||||
tab = g_object_get_data (G_OBJECT (child), "GTK_TAB");
|
||||
|
||||
if (!GTK_IS_TAB (tab))
|
||||
return;
|
||||
|
||||
parent = gtk_widget_get_parent (child);
|
||||
|
||||
gtk_container_child_get (GTK_CONTAINER (parent), child,
|
||||
"title", &title,
|
||||
NULL);
|
||||
|
||||
gtk_tab_set_title (tab, title);
|
||||
}
|
||||
|
||||
static void
|
||||
update_visible_child (GtkWidget *tab,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *visible_child = user_data;
|
||||
|
||||
if (GTK_IS_TAB (tab))
|
||||
{
|
||||
if (gtk_tab_get_widget (GTK_TAB (tab)) == visible_child)
|
||||
gtk_widget_set_state_flags (tab, GTK_STATE_FLAG_CHECKED, FALSE);
|
||||
else
|
||||
gtk_widget_unset_state_flags (tab, GTK_STATE_FLAG_CHECKED);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tab_strip_stack_notify_visible_child (GtkTabStrip *self,
|
||||
GParamSpec *pspec,
|
||||
GtkStack *stack)
|
||||
{
|
||||
GtkTabStripPrivate *priv = gtk_tab_strip_get_instance_private (self);
|
||||
GtkWidget *visible_child;
|
||||
|
||||
visible_child = gtk_stack_get_visible_child (stack);
|
||||
|
||||
priv->in_child_changed = TRUE;
|
||||
gtk_container_foreach (GTK_CONTAINER (self), update_visible_child, visible_child);
|
||||
priv->in_child_changed = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
tab_activated (GtkTab *tab,
|
||||
GtkTabStrip *self)
|
||||
{
|
||||
GtkTabStripPrivate *priv = gtk_tab_strip_get_instance_private (self);
|
||||
GtkWidget *widget;
|
||||
|
||||
widget = gtk_tab_get_widget (tab);
|
||||
if (widget)
|
||||
gtk_stack_set_visible_child (priv->stack, widget);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tab_strip_stack_add (GtkTabStrip *self,
|
||||
GtkWidget *widget,
|
||||
GtkStack *stack)
|
||||
{
|
||||
GtkTab *tab;
|
||||
gint position = 0;
|
||||
|
||||
gtk_container_child_get (GTK_CONTAINER (stack), widget,
|
||||
"position", &position,
|
||||
NULL);
|
||||
|
||||
tab = g_object_new (GTK_TYPE_SIMPLE_TAB,
|
||||
"widget", widget,
|
||||
NULL);
|
||||
|
||||
g_object_set_data (G_OBJECT (widget), "GTK_TAB", tab);
|
||||
|
||||
g_signal_connect (tab, "activate",
|
||||
G_CALLBACK (tab_activated), self);
|
||||
|
||||
g_signal_connect_object (widget, "child-notify::position",
|
||||
G_CALLBACK (gtk_tab_strip_child_position_changed), self,
|
||||
G_CONNECT_SWAPPED);
|
||||
|
||||
g_signal_connect_object (widget, "child-notify::title",
|
||||
G_CALLBACK (gtk_tab_strip_child_title_changed), self,
|
||||
G_CONNECT_SWAPPED);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (self), GTK_WIDGET (tab), TRUE, TRUE, 0);
|
||||
|
||||
g_object_bind_property (widget, "visible", tab, "visible", G_BINDING_SYNC_CREATE);
|
||||
|
||||
gtk_tab_strip_child_title_changed (self, NULL, widget);
|
||||
gtk_tab_strip_stack_notify_visible_child (self, NULL, stack);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tab_strip_stack_remove (GtkTabStrip *self,
|
||||
GtkWidget *widget,
|
||||
GtkStack *stack)
|
||||
{
|
||||
GtkTab *tab;
|
||||
|
||||
tab = g_object_get_data (G_OBJECT (widget), "GTK_TAB");
|
||||
|
||||
if (GTK_IS_TAB (tab))
|
||||
gtk_container_remove (GTK_CONTAINER (self), GTK_WIDGET (tab));
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
gtk_tab_strip_new (void)
|
||||
{
|
||||
return g_object_new (GTK_TYPE_TAB_STRIP, NULL);
|
||||
}
|
||||
|
||||
GtkStack *
|
||||
gtk_tab_strip_get_stack (GtkTabStrip *self)
|
||||
{
|
||||
GtkTabStripPrivate *priv = gtk_tab_strip_get_instance_private (self);
|
||||
|
||||
g_return_val_if_fail (GTK_IS_TAB_STRIP (self), NULL);
|
||||
|
||||
return priv->stack;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tab_strip_cold_plug (GtkWidget *widget,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkTabStrip *self = user_data;
|
||||
GtkTabStripPrivate *priv = gtk_tab_strip_get_instance_private (self);
|
||||
|
||||
gtk_tab_strip_stack_add (self, widget, priv->stack);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_tab_strip_set_stack (GtkTabStrip *self,
|
||||
GtkStack *stack)
|
||||
{
|
||||
GtkTabStripPrivate *priv = gtk_tab_strip_get_instance_private (self);
|
||||
|
||||
g_return_if_fail (GTK_IS_TAB_STRIP (self));
|
||||
g_return_if_fail (!stack || GTK_IS_STACK (stack));
|
||||
|
||||
if (priv->stack == stack)
|
||||
return;
|
||||
|
||||
if (priv->stack != NULL)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (priv->stack,
|
||||
G_CALLBACK (gtk_tab_strip_stack_notify_visible_child),
|
||||
self);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (priv->stack,
|
||||
G_CALLBACK (gtk_tab_strip_stack_add),
|
||||
self);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (priv->stack,
|
||||
G_CALLBACK (gtk_tab_strip_stack_remove),
|
||||
self);
|
||||
|
||||
gtk_container_foreach (GTK_CONTAINER (self), (GtkCallback)gtk_widget_destroy, NULL);
|
||||
|
||||
g_clear_object (&priv->stack);
|
||||
}
|
||||
|
||||
if (stack != NULL)
|
||||
{
|
||||
priv->stack = g_object_ref (stack);
|
||||
|
||||
g_signal_connect_object (priv->stack,
|
||||
"notify::visible-child",
|
||||
G_CALLBACK (gtk_tab_strip_stack_notify_visible_child),
|
||||
self,
|
||||
G_CONNECT_SWAPPED);
|
||||
|
||||
g_signal_connect_object (priv->stack,
|
||||
"add",
|
||||
G_CALLBACK (gtk_tab_strip_stack_add),
|
||||
self,
|
||||
G_CONNECT_SWAPPED);
|
||||
|
||||
g_signal_connect_object (priv->stack,
|
||||
"remove",
|
||||
G_CALLBACK (gtk_tab_strip_stack_remove),
|
||||
self,
|
||||
G_CONNECT_SWAPPED);
|
||||
|
||||
gtk_container_foreach (GTK_CONTAINER (priv->stack),
|
||||
gtk_tab_strip_cold_plug,
|
||||
self);
|
||||
}
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_STACK]);
|
||||
}
|
||||
65
gtk/gtktabstrip.h
Normal file
65
gtk/gtktabstrip.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/* gtktabstrip.h
|
||||
*
|
||||
* Copyright (C) 2016 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 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 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/>.
|
||||
*/
|
||||
|
||||
#if !defined(__GTK_H_INSIDE__) && !defined(GTK_COMPILATION)
|
||||
# error "Only <gtk/gtk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __GTK_TAB_STRIP_H__
|
||||
#define __GTK_TAB_STRIP_H__
|
||||
|
||||
#include <gtk/gtkbox.h>
|
||||
#include <gtk/gtkstack.h>
|
||||
#include <gtk/gtktypebuiltins.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_TAB_STRIP (gtk_tab_strip_get_type ())
|
||||
#define GTK_TAB_STRIP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_TAB_STRIP, GtkTabStrip))
|
||||
#define GTK_IS_TAB_STRIP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_TAB_STRIP))
|
||||
#define GTK_TAB_STRIP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_TAB_STRIP, GtkTabStripClass))
|
||||
#define GTK_IS_TAB_STRIP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_TAB_STRIP))
|
||||
#define GTK_TAB_STRIP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_TAB_STRIP, GtkTabStripClass))
|
||||
|
||||
typedef struct _GtkTabStrip GtkTabStrip;
|
||||
typedef struct _GtkTabStripClass GtkTabStripClass;
|
||||
|
||||
struct _GtkTabStrip
|
||||
{
|
||||
GtkBox parent;
|
||||
};
|
||||
|
||||
struct _GtkTabStripClass
|
||||
{
|
||||
GtkBoxClass parent_class;
|
||||
};
|
||||
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
GType gtk_tab_strip_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
GtkWidget *gtk_tab_strip_new (void);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
GtkStack *gtk_tab_strip_get_stack (GtkTabStrip *self);
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
void gtk_tab_strip_set_stack (GtkTabStrip *self,
|
||||
GtkStack *stack);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_TAB_STRIP_H__ */
|
||||
Reference in New Issue
Block a user