/*
* Copyright ( c ) 2013 - 2014 Red Hat , Inc .
*
* This program 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 program ; if not , write to the Free Software Foundation ,
* Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 USA
*
*/
#include "config.h"
#include "gtkactionbar.h"
#include "gtkbuildable.h"
#include "gtktypebuiltins.h"
#include "gtkbox.h"
#include "gtkrevealer.h"
#include "gtkwidgetprivate.h"
#include "gtkprivate.h"
#include "gtkcenterbox.h"
#include "gtkbinlayout.h"
#include <string.h>
/**
* GtkActionBar :
*
* Presents contextual actions .
*
* < picture >
* < source srcset = " action - bar - dark . png " media = " ( prefers - color - scheme : dark ) " >
* < img alt = " An example GtkActionBar " src = " action - bar . png " >
* < / picture >
*
* ` GtkActionBar ` is expected to be displayed below the content and expand
* horizontally to fill the area .
*
* It allows placing children at the start or the end . In addition , it
* contains an internal centered box which is centered with respect to
* the full width of the box , even if the children at either side take
* up different amounts of space .
*
* # GtkActionBar as GtkBuildable
*
* The ` GtkActionBar ` implementation of the ` GtkBuildable ` interface supports
* adding children at the start or end sides by specifying “ start ” or “ end ” as
* the “ type ” attribute of a ` < child > ` element , or setting the center widget
* by specifying “ center ” value .
*
* # CSS nodes
*
* ` ` `
* actionbar
* ╰ ─ ─ revealer
* ╰ ─ ─ box
* ├ ─ ─ box . start
* │ ╰ ─ ─ [ start children ]
* ├ ─ ─ [ center widget ]
* ╰ ─ ─ box . end
* ╰ ─ ─ [ end children ]
* ` ` `
*
* A ` GtkActionBar ` ' s CSS node is called ` actionbar ` . It contains a ` revealer `
* subnode , which contains a ` box ` subnode , which contains two ` box ` subnodes at
* the start and end of the action bar , with ` start ` and ` end ` style classes
* respectively , as well as a center node that represents the center child .
*
* Each of the boxes contains children packed for that side .
*/
typedef struct _GtkActionBarClass GtkActionBarClass;
struct _GtkActionBar
{
GtkWidget parent;
GtkWidget *center_box;
GtkWidget *start_box;
GtkWidget *end_box;
GtkWidget *revealer;
};
struct _GtkActionBarClass
{
GtkWidgetClass parent_class;
};
enum {
PROP_0,
PROP_REVEALED,
LAST_PROP
};
static GParamSpec *props[LAST_PROP] = { NULL, };
static void gtk_action_bar_buildable_interface_init (GtkBuildableIface *iface);
G_DEFINE_TYPE_WITH_CODE (GtkActionBar, gtk_action_bar, GTK_TYPE_WIDGET,
G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
gtk_action_bar_buildable_interface_init))
static void
gtk_action_bar_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkActionBar *self = GTK_ACTION_BAR (object);
switch (prop_id)
{
case PROP_REVEALED:
gtk_action_bar_set_revealed (self, g_value_get_boolean (value));
break ;
default :
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break ;
}
}
static void
gtk_action_bar_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkActionBar *self = GTK_ACTION_BAR (object);
switch (prop_id)
{
case PROP_REVEALED:
g_value_set_boolean (value, gtk_action_bar_get_revealed (self));
break ;
default :
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break ;
}
}
static void
gtk_action_bar_dispose (GObject *object)
{
GtkActionBar *self = GTK_ACTION_BAR (object);
g_clear_pointer (&self->revealer, gtk_widget_unparent);
self->center_box = NULL;
self->start_box = NULL;
self->end_box = NULL;
G_OBJECT_CLASS (gtk_action_bar_parent_class)->dispose (object);
}
static void
gtk_action_bar_class_init (GtkActionBarClass *klass)
{
GObjectClass *object_class;
GtkWidgetClass *widget_class;
object_class = G_OBJECT_CLASS (klass);
widget_class = GTK_WIDGET_CLASS (klass);
object_class->set_property = gtk_action_bar_set_property;
object_class->get_property = gtk_action_bar_get_property;
object_class->dispose = gtk_action_bar_dispose;
widget_class->focus = gtk_widget_focus_child;
/**
* GtkActionBar : revealed :
*
* Controls whether the action bar shows its contents .
*/
props[PROP_REVEALED] =
g_param_spec_boolean ("revealed" , NULL, NULL,
TRUE ,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_EXPLICIT_NOTIFY);
g_object_class_install_properties (object_class, LAST_PROP, props);
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
gtk_widget_class_set_css_name (widget_class, I_("actionbar" ));
}
static void
gtk_action_bar_init (GtkActionBar *self)
{
GtkWidget *widget = GTK_WIDGET (self);
self->revealer = gtk_revealer_new ();
gtk_widget_set_parent (self->revealer, widget);
gtk_revealer_set_reveal_child (GTK_REVEALER (self->revealer), TRUE );
gtk_revealer_set_transition_type (GTK_REVEALER (self->revealer), GTK_REVEALER_TRANSITION_TYPE_SLIDE_UP);
self->start_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0 );
self->end_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0 );
gtk_widget_add_css_class (self->start_box, "start" );
gtk_widget_add_css_class (self->end_box, "end" );
self->center_box = gtk_center_box_new ();
gtk_center_box_set_start_widget (GTK_CENTER_BOX (self->center_box), self->start_box);
gtk_center_box_set_end_widget (GTK_CENTER_BOX (self->center_box), self->end_box);
gtk_revealer_set_child (GTK_REVEALER (self->revealer), self->center_box);
}
static GtkBuildableIface *parent_buildable_iface;
static void
gtk_action_bar_buildable_add_child (GtkBuildable *buildable,
GtkBuilder *builder,
GObject *child,
const char *type)
{
GtkActionBar *self = GTK_ACTION_BAR (buildable);
if (g_strcmp0 (type, "start" ) == 0 )
gtk_action_bar_pack_start (self, GTK_WIDGET (child));
else if (g_strcmp0 (type, "center" ) == 0 )
gtk_action_bar_set_center_widget (self, GTK_WIDGET (child));
else if (g_strcmp0 (type, "end" ) == 0 )
gtk_action_bar_pack_end (self, GTK_WIDGET (child));
else if (type == NULL && GTK_IS_WIDGET (child))
gtk_action_bar_pack_start (self, GTK_WIDGET (child));
else
parent_buildable_iface->add_child (buildable, builder, child, type);
}
static void
gtk_action_bar_buildable_interface_init (GtkBuildableIface *iface)
{
parent_buildable_iface = g_type_interface_peek_parent (iface);
iface->add_child = gtk_action_bar_buildable_add_child;
}
/**
* gtk_action_bar_pack_start :
* @ action_bar : an action bar
* @ child : the widget to be added
*
* Adds a child to the action , packed with reference to the
* start of the action bar .
*/
void
gtk_action_bar_pack_start (GtkActionBar *action_bar,
GtkWidget *child)
{
gtk_box_append (GTK_BOX (action_bar->start_box), child);
}
/**
* gtk_action_bar_pack_end :
* @ action_bar : an action bar
* @ child : the widget to be added
*
* Adds a child to the action bar , packed with reference to the
* end of the action bar .
*/
void
gtk_action_bar_pack_end (GtkActionBar *action_bar,
GtkWidget *child)
{
gtk_box_insert_child_after (GTK_BOX (action_bar->end_box), child, NULL);
}
/**
* gtk_action_bar_remove :
* @ action_bar : an action bar
* @ child : the widget to be removed
*
* Removes a child from the action bar .
*/
void
gtk_action_bar_remove (GtkActionBar *action_bar,
GtkWidget *child)
{
if (gtk_widget_get_parent (child) == action_bar->start_box)
gtk_box_remove (GTK_BOX (action_bar->start_box), child);
else if (gtk_widget_get_parent (child) == action_bar->end_box)
gtk_box_remove (GTK_BOX (action_bar->end_box), child);
else if (child == gtk_center_box_get_center_widget (GTK_CENTER_BOX (action_bar->center_box)))
gtk_center_box_set_center_widget (GTK_CENTER_BOX (action_bar->center_box), NULL);
else
g_warning ("Can't remove non-child %s %p from GtkActionBar %p" ,
G_OBJECT_TYPE_NAME (child), child, action_bar);
}
/**
* gtk_action_bar_set_center_widget :
* @ action_bar : an action bar
* @ center_widget : ( nullable ) : a widget to use for the center
*
* Sets the center widget for the action bar .
*/
void
gtk_action_bar_set_center_widget (GtkActionBar *action_bar,
GtkWidget *center_widget)
{
gtk_center_box_set_center_widget (GTK_CENTER_BOX (action_bar->center_box), center_widget);
}
/**
* gtk_action_bar_get_center_widget :
* @ action_bar : an action bsar
*
* Retrieves the center bar widget of the bar .
*
* Returns : ( transfer none ) ( nullable ) : the center widget
*/
GtkWidget *
gtk_action_bar_get_center_widget (GtkActionBar *action_bar)
{
g_return_val_if_fail (GTK_IS_ACTION_BAR (action_bar), NULL);
return gtk_center_box_get_center_widget (GTK_CENTER_BOX (action_bar->center_box));
}
/**
* gtk_action_bar_new :
*
* Creates a new action bar widget .
*
* Returns : a new ` GtkActionBar `
*/
GtkWidget *
gtk_action_bar_new (void )
{
return GTK_WIDGET (g_object_new (GTK_TYPE_ACTION_BAR, NULL));
}
/**
* gtk_action_bar_set_revealed :
* @ action_bar : an action bar
* @ revealed : the new value for the property
*
* Reveals or conceals the content of the action bar .
*
* Note : this does not show or hide the action bar in the
* [ property @ Gtk . Widget : visible ] sense , so revealing has
* no effect if the action bar is hidden .
*/
void
gtk_action_bar_set_revealed (GtkActionBar *action_bar,
gboolean revealed)
{
g_return_if_fail (GTK_IS_ACTION_BAR (action_bar));
if (revealed == gtk_revealer_get_reveal_child (GTK_REVEALER (action_bar->revealer)))
return ;
gtk_revealer_set_reveal_child (GTK_REVEALER (action_bar->revealer), revealed);
g_object_notify_by_pspec (G_OBJECT (action_bar), props[PROP_REVEALED]);
}
/**
* gtk_action_bar_get_revealed :
* @ action_bar : an action bar
*
* Gets whether the contents of the action bar are revealed .
*
* Returns : the current value of the [ property @ Gtk . ActionBar : revealed ]
* property
*/
gboolean
gtk_action_bar_get_revealed (GtkActionBar *action_bar)
{
g_return_val_if_fail (GTK_IS_ACTION_BAR (action_bar), FALSE );
return gtk_revealer_get_reveal_child (GTK_REVEALER (action_bar->revealer));
}
Messung V0.5 in Prozent C=98 H=94 G=95
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-07-03)
¤
*© Formatika GbR, Deutschland