background: Turn into a template class

This commit is contained in:
Georges Basile Stavracas Neto 2019-05-21 13:48:46 -03:00
parent c290dadf0c
commit ad740deeea
No known key found for this signature in database
GPG key ID: 886C17EE170D1385
2 changed files with 177 additions and 266 deletions

View file

@ -48,7 +48,6 @@ struct _CcBackgroundPanel
{ {
CcPanel parent_instance; CcPanel parent_instance;
GtkBuilder *builder;
GDBusConnection *connection; GDBusConnection *connection;
GSettings *settings; GSettings *settings;
@ -61,138 +60,18 @@ struct _CcBackgroundPanel
GCancellable *copy_cancellable; GCancellable *copy_cancellable;
GtkWidget *bottom_hbox;
GtkWidget *desktop_drawing_area;
GtkWidget *desktop_slide_image;
GtkWidget *lock_drawing_area;
GtkWidget *lock_slide_image;
GtkWidget *spinner; GtkWidget *spinner;
GtkWidget *chooser; GtkWidget *chooser;
}; };
CC_PANEL_REGISTER (CcBackgroundPanel, cc_background_panel) CC_PANEL_REGISTER (CcBackgroundPanel, cc_background_panel)
#define WID(y) (GtkWidget *) gtk_builder_get_object (panel->builder, y)
static const char *
cc_background_panel_get_help_uri (CcPanel *panel)
{
return "help:gnome-help/look-background";
}
static void
cc_background_panel_dispose (GObject *object)
{
CcBackgroundPanel *panel = CC_BACKGROUND_PANEL (object);
g_clear_object (&panel->builder);
/* destroying the builder object will also destroy the spinner */
panel->spinner = NULL;
g_clear_object (&panel->settings);
g_clear_object (&panel->lock_settings);
if (panel->copy_cancellable)
{
/* cancel any copy operation */
g_cancellable_cancel (panel->copy_cancellable);
g_clear_object (&panel->copy_cancellable);
}
if (panel->chooser)
{
gtk_widget_destroy (panel->chooser);
panel->chooser = NULL;
}
g_clear_object (&panel->thumb_factory);
G_OBJECT_CLASS (cc_background_panel_parent_class)->dispose (object);
}
static void
cc_background_panel_finalize (GObject *object)
{
CcBackgroundPanel *panel = CC_BACKGROUND_PANEL (object);
g_clear_object (&panel->current_background);
g_clear_object (&panel->current_lock_background);
G_OBJECT_CLASS (cc_background_panel_parent_class)->finalize (object);
}
static void
cc_background_panel_class_init (CcBackgroundPanelClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
CcPanelClass *panel_class = CC_PANEL_CLASS (klass);
panel_class->get_help_uri = cc_background_panel_get_help_uri;
object_class->dispose = cc_background_panel_dispose;
object_class->finalize = cc_background_panel_finalize;
}
static CcBackgroundItem *
get_current_background (CcBackgroundPanel *panel, GSettings *settings)
{
if (settings == panel->settings)
return panel->current_background;
else
return panel->current_lock_background;
}
static void
update_preview (CcBackgroundPanel *panel,
GSettings *settings,
CcBackgroundItem *item)
{
gboolean changes_with_time;
CcBackgroundItem *current_background;
current_background = get_current_background (panel, settings);
if (item && current_background)
{
g_object_unref (current_background);
current_background = cc_background_item_copy (item);
if (settings == panel->settings)
panel->current_background = current_background;
else
panel->current_lock_background = current_background;
cc_background_item_load (current_background, NULL);
}
changes_with_time = FALSE;
if (current_background)
{
changes_with_time = cc_background_item_changes_with_time (current_background);
}
if (settings == panel->settings)
{
gtk_widget_set_visible (WID ("slide_image"), changes_with_time);
gtk_widget_set_visible (WID ("slide-label"), changes_with_time);
gtk_widget_queue_draw (WID ("background-desktop-drawingarea"));
}
else
{
gtk_widget_set_visible (WID ("slide_image1"), changes_with_time);
gtk_widget_set_visible (WID ("slide-label1"), changes_with_time);
gtk_widget_queue_draw (WID ("background-lock-drawingarea"));
}
}
static gchar *
get_save_path (CcBackgroundPanel *panel, GSettings *settings)
{
return g_build_filename (g_get_user_config_dir (),
"gnome-control-center",
"backgrounds",
settings == panel->settings ? "last-edited.xml" : "last-edited-lock.xml",
NULL);
}
static GdkPixbuf* static GdkPixbuf*
get_or_create_cached_pixbuf (CcBackgroundPanel *panel, get_or_create_cached_pixbuf (CcBackgroundPanel *panel,
GtkWidget *widget, GtkWidget *widget,
@ -239,23 +118,64 @@ update_display_preview (CcBackgroundPanel *panel,
cairo_destroy (cr); cairo_destroy (cr);
} }
static gboolean static CcBackgroundItem *
on_preview_draw (GtkWidget *widget, get_current_background (CcBackgroundPanel *panel,
cairo_t *cr, GSettings *settings)
CcBackgroundPanel *panel)
{ {
update_display_preview (panel, widget, panel->current_background); if (settings == panel->settings)
return panel->current_background;
return TRUE; else
return panel->current_lock_background;
} }
static gboolean static void
on_lock_preview_draw (GtkWidget *widget, update_preview (CcBackgroundPanel *panel,
cairo_t *cr, GSettings *settings,
CcBackgroundPanel *panel) CcBackgroundItem *item)
{ {
update_display_preview (panel, widget, panel->current_lock_background); gboolean changes_with_time;
return TRUE; CcBackgroundItem *current_background;
current_background = get_current_background (panel, settings);
if (item && current_background)
{
g_object_unref (current_background);
current_background = cc_background_item_copy (item);
if (settings == panel->settings)
panel->current_background = current_background;
else
panel->current_lock_background = current_background;
cc_background_item_load (current_background, NULL);
}
changes_with_time = FALSE;
if (current_background)
{
changes_with_time = cc_background_item_changes_with_time (current_background);
}
if (settings == panel->settings)
{
gtk_widget_set_visible (panel->desktop_slide_image, changes_with_time);
gtk_widget_queue_draw (panel->desktop_drawing_area);
}
else
{
gtk_widget_set_visible (panel->lock_slide_image, changes_with_time);
gtk_widget_queue_draw (panel->lock_drawing_area);
}
}
static gchar *
get_save_path (CcBackgroundPanel *panel, GSettings *settings)
{
return g_build_filename (g_get_user_config_dir (),
"gnome-control-center",
"backgrounds",
settings == panel->settings ? "last-edited.xml" : "last-edited-lock.xml",
NULL);
} }
static void static void
@ -345,8 +265,9 @@ copy_finished_cb (GObject *source_object,
GAsyncResult *result, GAsyncResult *result,
gpointer pointer) gpointer pointer)
{ {
g_autoptr(GError) err = NULL;
g_autoptr(CcBackgroundPanel) panel = (CcBackgroundPanel *) pointer; g_autoptr(CcBackgroundPanel) panel = (CcBackgroundPanel *) pointer;
g_autoptr(GError) err = NULL;
g_autofree gchar *filename = NULL;
CcBackgroundItem *item; CcBackgroundItem *item;
CcBackgroundItem *current_background; CcBackgroundItem *current_background;
GSettings *settings; GSettings *settings;
@ -376,20 +297,14 @@ copy_finished_cb (GObject *source_object,
if (current_background) if (current_background)
cc_background_item_load (current_background, NULL); cc_background_item_load (current_background, NULL);
if (panel->builder) update_preview (panel, settings, item);
{ current_background = get_current_background (panel, settings);
g_autofree gchar *filename = NULL;
update_preview (panel, settings, item); /* Save the source XML if there is one */
current_background = get_current_background (panel, settings); filename = get_save_path (panel, settings);
if (create_save_dir ())
/* Save the source XML if there is one */ cc_background_xml_save (current_background, filename);
filename = get_save_path (panel, settings);
if (create_save_dir ())
cc_background_xml_save (current_background, filename);
}
} }
static void static void
set_background (CcBackgroundPanel *panel, set_background (CcBackgroundPanel *panel,
GSettings *settings, GSettings *settings,
@ -457,8 +372,7 @@ set_background (CcBackgroundPanel *panel,
/* create a spinner while the file downloads */ /* create a spinner while the file downloads */
panel->spinner = gtk_spinner_new (); panel->spinner = gtk_spinner_new ();
gtk_spinner_start (GTK_SPINNER (panel->spinner)); gtk_spinner_start (GTK_SPINNER (panel->spinner));
gtk_box_pack_start (GTK_BOX (WID ("bottom-hbox")), panel->spinner, FALSE, gtk_box_pack_start (GTK_BOX (panel->bottom_hbox), panel->spinner, FALSE, FALSE, 6);
FALSE, 6);
gtk_widget_show (panel->spinner); gtk_widget_show (panel->spinner);
/* reference the panel in case it is removed before the copy is /* reference the panel in case it is removed before the copy is
@ -541,9 +455,11 @@ static void
launch_chooser (CcBackgroundPanel *panel, launch_chooser (CcBackgroundPanel *panel,
GSettings *settings) GSettings *settings)
{ {
GtkWidget *toplevel;
GtkWidget *dialog; GtkWidget *dialog;
dialog = cc_background_chooser_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (WID ("background-panel")))); toplevel = gtk_widget_get_toplevel (GTK_WIDGET (panel));
dialog = cc_background_chooser_dialog_new (GTK_WINDOW (toplevel));
g_object_set_data (G_OBJECT (dialog), "settings", settings); g_object_set_data (G_OBJECT (dialog), "settings", settings);
gtk_widget_show (dialog); gtk_widget_show (dialog);
g_signal_connect (dialog, "response", G_CALLBACK (on_chooser_dialog_response), panel); g_signal_connect (dialog, "response", G_CALLBACK (on_chooser_dialog_response), panel);
@ -552,19 +468,98 @@ launch_chooser (CcBackgroundPanel *panel,
} }
static void static void
on_background_button_clicked (GtkButton *button, on_background_button_clicked_cb (GtkButton *button,
CcBackgroundPanel *panel) CcBackgroundPanel *panel)
{ {
launch_chooser (panel, panel->settings); launch_chooser (panel, panel->settings);
} }
static void static void
on_lock_button_clicked (GtkButton *button, on_lock_button_clicked_cb (GtkButton *button,
CcBackgroundPanel *panel) CcBackgroundPanel *panel)
{ {
launch_chooser (panel, panel->lock_settings); launch_chooser (panel, panel->lock_settings);
} }
static gboolean
on_preview_draw_cb (GtkWidget *widget,
cairo_t *cr,
CcBackgroundPanel *panel)
{
update_display_preview (panel, widget, panel->current_background);
return TRUE;
}
static gboolean
on_lock_preview_draw_cb (GtkWidget *widget,
cairo_t *cr,
CcBackgroundPanel *panel)
{
update_display_preview (panel, widget, panel->current_lock_background);
return TRUE;
}
static const char *
cc_background_panel_get_help_uri (CcPanel *panel)
{
return "help:gnome-help/look-background";
}
static void
cc_background_panel_dispose (GObject *object)
{
CcBackgroundPanel *panel = CC_BACKGROUND_PANEL (object);
/* cancel any copy operation */
g_cancellable_cancel (panel->copy_cancellable);
g_clear_object (&panel->settings);
g_clear_object (&panel->lock_settings);
g_clear_object (&panel->copy_cancellable);
g_clear_object (&panel->thumb_factory);
g_clear_pointer (&panel->chooser, gtk_widget_destroy);
G_OBJECT_CLASS (cc_background_panel_parent_class)->dispose (object);
}
static void
cc_background_panel_finalize (GObject *object)
{
CcBackgroundPanel *panel = CC_BACKGROUND_PANEL (object);
g_clear_object (&panel->current_background);
g_clear_object (&panel->current_lock_background);
G_OBJECT_CLASS (cc_background_panel_parent_class)->finalize (object);
}
static void
cc_background_panel_class_init (CcBackgroundPanelClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
CcPanelClass *panel_class = CC_PANEL_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
panel_class->get_help_uri = cc_background_panel_get_help_uri;
object_class->dispose = cc_background_panel_dispose;
object_class->finalize = cc_background_panel_finalize;
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/background/cc-background-panel.ui");
gtk_widget_class_bind_template_child (widget_class, CcBackgroundPanel, bottom_hbox);
gtk_widget_class_bind_template_child (widget_class, CcBackgroundPanel, desktop_drawing_area);
gtk_widget_class_bind_template_child (widget_class, CcBackgroundPanel, desktop_slide_image);
gtk_widget_class_bind_template_child (widget_class, CcBackgroundPanel, lock_drawing_area);
gtk_widget_class_bind_template_child (widget_class, CcBackgroundPanel, lock_slide_image);
gtk_widget_class_bind_template_callback (widget_class, on_background_button_clicked_cb);
gtk_widget_class_bind_template_callback (widget_class, on_lock_button_clicked_cb);
gtk_widget_class_bind_template_callback (widget_class, on_lock_preview_draw_cb);
gtk_widget_class_bind_template_callback (widget_class, on_preview_draw_cb);
}
static void static void
on_settings_changed (GSettings *settings, on_settings_changed (GSettings *settings,
gchar *key, gchar *key,
@ -577,23 +572,14 @@ on_settings_changed (GSettings *settings,
static void static void
cc_background_panel_init (CcBackgroundPanel *panel) cc_background_panel_init (CcBackgroundPanel *panel)
{ {
gchar *objects[] = {"background-panel", NULL };
g_autoptr(GError) err = NULL;
GtkWidget *widget;
panel->connection = g_application_get_dbus_connection (g_application_get_default ());
g_resources_register (cc_background_get_resource ()); g_resources_register (cc_background_get_resource ());
panel->builder = gtk_builder_new (); gtk_widget_init_template (GTK_WIDGET (panel));
gtk_builder_add_objects_from_resource (panel->builder,
"/org/gnome/control-center/background/cc-background-panel.ui",
objects, &err);
if (err) panel->connection = g_application_get_dbus_connection (g_application_get_default ());
{
g_warning ("Could not load ui: %s", err->message); panel->copy_cancellable = g_cancellable_new ();
return; panel->thumb_factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_LARGE);
}
panel->settings = g_settings_new (WP_PATH_ID); panel->settings = g_settings_new (WP_PATH_ID);
g_settings_delay (panel->settings); g_settings_delay (panel->settings);
@ -601,22 +587,6 @@ cc_background_panel_init (CcBackgroundPanel *panel)
panel->lock_settings = g_settings_new (WP_LOCK_PATH_ID); panel->lock_settings = g_settings_new (WP_LOCK_PATH_ID);
g_settings_delay (panel->lock_settings); g_settings_delay (panel->lock_settings);
/* add the top level widget */
widget = WID ("background-panel");
gtk_container_add (GTK_CONTAINER (panel), widget);
gtk_widget_show (GTK_WIDGET (panel));
/* setup preview area */
widget = WID ("background-desktop-drawingarea");
g_signal_connect (widget, "draw", G_CALLBACK (on_preview_draw), panel);
widget = WID ("background-lock-drawingarea");
g_signal_connect (widget, "draw", G_CALLBACK (on_lock_preview_draw), panel);
panel->copy_cancellable = g_cancellable_new ();
panel->thumb_factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_LARGE);
/* Load the backgrounds */ /* Load the backgrounds */
reload_current_bg (panel, panel->settings); reload_current_bg (panel, panel->settings);
update_preview (panel, panel->settings, NULL); update_preview (panel, panel->settings, NULL);
@ -626,10 +596,4 @@ cc_background_panel_init (CcBackgroundPanel *panel)
/* Background settings */ /* Background settings */
g_signal_connect (panel->settings, "changed", G_CALLBACK (on_settings_changed), panel); g_signal_connect (panel->settings, "changed", G_CALLBACK (on_settings_changed), panel);
g_signal_connect (panel->lock_settings, "changed", G_CALLBACK (on_settings_changed), panel); g_signal_connect (panel->lock_settings, "changed", G_CALLBACK (on_settings_changed), panel);
/* Background buttons */
widget = WID ("background-set-button");
g_signal_connect (widget, "clicked", G_CALLBACK (on_background_button_clicked), panel);
widget = WID ("background-lock-set-button");
g_signal_connect (widget, "clicked", G_CALLBACK (on_lock_button_clicked), panel);
} }

View file

@ -1,17 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<interface> <interface>
<!-- interface-requires gtk+ 3.0 --> <!-- interface-requires gtk+ 3.0 -->
<object class="GtkBox" id="background-panel"> <template class="CcBackgroundPanel" parent="CcPanel">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="margin">32</property>
<property name="spacing">12</property>
<property name="valign">center</property>
<child> <child>
<object class="GtkBox" id="box1"> <object class="GtkBox" id="box1">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="spacing">24</property> <property name="spacing">24</property>
<property name="margin">32</property>
<property name="valign">center</property>
<child> <child>
<object class="GtkBox" id="vbox3"> <object class="GtkBox" id="vbox3">
<property name="visible">True</property> <property name="visible">True</property>
@ -24,6 +23,7 @@
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">True</property> <property name="receives_default">True</property>
<signal name="clicked" handler="on_background_button_clicked_cb" object="CcBackgroundPanel" swapped="no" />
<child> <child>
<object class="GtkBox" id="box2"> <object class="GtkBox" id="box2">
<property name="visible">True</property> <property name="visible">True</property>
@ -32,7 +32,7 @@
<property name="spacing">6</property> <property name="spacing">6</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="GtkDrawingArea" id="background-desktop-drawingarea"> <object class="GtkDrawingArea" id="desktop_drawing_area">
<property name="width_request">310</property> <property name="width_request">310</property>
<property name="height_request">170</property> <property name="height_request">170</property>
<property name="visible">True</property> <property name="visible">True</property>
@ -40,6 +40,7 @@
<property name="valign">center</property> <property name="valign">center</property>
<property name="hexpand">True</property> <property name="hexpand">True</property>
<property name="vexpand">True</property> <property name="vexpand">True</property>
<signal name="draw" handler="on_preview_draw_cb" object="CcBackgroundPanel" swapped="no" />
</object> </object>
</child> </child>
<child> <child>
@ -56,7 +57,7 @@
</object> </object>
</child> </child>
<child> <child>
<object class="GtkBox" id="bottom-hbox"> <object class="GtkBox" id="bottom_hbox">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="spacing">12</property> <property name="spacing">12</property>
@ -68,7 +69,7 @@
<property name="margin_top">12</property> <property name="margin_top">12</property>
<property name="spacing">2</property> <property name="spacing">2</property>
<child> <child>
<object class="GtkImage" id="slide_image"> <object class="GtkImage" id="desktop_slide_image">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="icon_name">slideshow-symbolic</property> <property name="icon_name">slideshow-symbolic</property>
@ -92,8 +93,8 @@
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkLabel" id="slide-label"> <object class="GtkLabel" id="desktop_slide_label">
<property name="visible">True</property> <property name="visible" bind-source="desktop_slide_image" bind-property="visible" bind-flags="default|sync-create" />
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="xalign">0</property> <property name="xalign">0</property>
<property name="label" translatable="yes" comments="This refers to a slideshow background">Changes throughout the day</property> <property name="label" translatable="yes" comments="This refers to a slideshow background">Changes throughout the day</property>
@ -137,6 +138,7 @@
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">True</property> <property name="receives_default">True</property>
<signal name="clicked" handler="on_lock_button_clicked_cb" object="CcBackgroundPanel" swapped="no" />
<child> <child>
<object class="GtkBox" id="box3"> <object class="GtkBox" id="box3">
<property name="visible">True</property> <property name="visible">True</property>
@ -145,7 +147,7 @@
<property name="spacing">6</property> <property name="spacing">6</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="GtkDrawingArea" id="background-lock-drawingarea"> <object class="GtkDrawingArea" id="lock_drawing_area">
<property name="width_request">310</property> <property name="width_request">310</property>
<property name="height_request">170</property> <property name="height_request">170</property>
<property name="visible">True</property> <property name="visible">True</property>
@ -153,6 +155,7 @@
<property name="valign">center</property> <property name="valign">center</property>
<property name="hexpand">True</property> <property name="hexpand">True</property>
<property name="vexpand">True</property> <property name="vexpand">True</property>
<signal name="draw" handler="on_lock_preview_draw_cb" object="CcBackgroundPanel" swapped="no" />
</object> </object>
</child> </child>
<child> <child>
@ -181,7 +184,7 @@
<property name="margin_top">12</property> <property name="margin_top">12</property>
<property name="spacing">2</property> <property name="spacing">2</property>
<child> <child>
<object class="GtkImage" id="slide_image1"> <object class="GtkImage" id="lock_slide_image">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="icon_name">slideshow-symbolic</property> <property name="icon_name">slideshow-symbolic</property>
@ -205,8 +208,8 @@
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkLabel" id="slide-label1"> <object class="GtkLabel">
<property name="visible">True</property> <property name="visible" bind-source="lock_slide_image" bind-property="visible" bind-flags="default|sync-create" />
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="xalign">0</property> <property name="xalign">0</property>
<property name="label" translatable="yes" comments="This refers to a slideshow background">Changes throughout the day</property> <property name="label" translatable="yes" comments="This refers to a slideshow background">Changes throughout the day</property>
@ -239,62 +242,6 @@
</packing> </packing>
</child> </child>
</object> </object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child> </child>
</object> </template>
<object class="GtkListStore" id="sources-liststore">
<columns>
<!-- column-name source-name -->
<column type="gchararray"/>
<!-- column-name source-id -->
<column type="guint"/>
<!-- column-name source-pointer -->
<column type="gpointer"/>
</columns>
</object>
<object class="GtkListStore" id="style-liststore">
<columns>
<!-- column-name name -->
<column type="gchararray"/>
<!-- column-name value -->
<column type="gint"/>
</columns>
<data>
<row>
<col id="0" translatable="yes" context="background, style">Tile</col>
<col id="1">1</col>
</row>
<row>
<col id="0" translatable="yes" context="background, style">Zoom</col>
<col id="1">5</col>
</row>
<row>
<col id="0" translatable="yes" context="background, style">Center</col>
<col id="1">2</col>
</row>
<row>
<col id="0" translatable="yes" context="background, style">Scale</col>
<col id="1">3</col>
</row>
<row>
<col id="0" translatable="yes" context="background, style">Fill</col>
<col id="1">4</col>
</row>
<row>
<col id="0" translatable="yes" context="background, style">Span</col>
<col id="1">6</col>
</row>
</data>
</object>
<object class="GtkSizeGroup" id="sizegroup">
<property name="mode">vertical</property>
<widgets>
<widget name="slide-label"/>
<widget name="strut"/>
</widgets>
</object>
</interface> </interface>