Verified Commit 0706f60c authored by Zander Brown's avatar Zander Brown
Browse files

example: Add to example application

Silly simple demo of HdyDialog

dialog: Add example with actions

dialog: Fix examples

dialog: Fix tests & update docs

dialog: Fix initial sizing

Fixes an edge case show by the tests
parent 92237113
Pipeline #3513 passed with stage
in 3 minutes and 52 seconds
......@@ -229,6 +229,57 @@ adj_arrows_duration_value_changed_cb (GtkAdjustment *adj,
hdy_arrows_animate (HDY_ARROWS (self->arrows));
}
static void
dialog_close_cb (GtkDialog *self)
{
gtk_widget_destroy (GTK_WIDGET (self));
}
static void
dialog_clicked_cb (GtkButton *btn,
ExampleWindow *self)
{
GtkWidget *dlg;
GtkWidget *lbl;
dlg = hdy_dialog_new (GTK_WINDOW (self));
gtk_window_set_title (GTK_WINDOW (dlg), "HdyDialog");
lbl = gtk_label_new ("Hello, World!");
gtk_widget_set_vexpand (lbl, TRUE);
gtk_widget_set_valign (lbl, GTK_ALIGN_CENTER);
gtk_widget_set_halign (lbl, GTK_ALIGN_CENTER);
gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (dlg))),
lbl);
gtk_widget_show (lbl);
gtk_widget_show (dlg);
}
static void
dialog_action_clicked_cb (GtkButton *btn,
ExampleWindow *self)
{
GtkWidget *dlg;
GtkWidget *lbl;
dlg = hdy_dialog_new (GTK_WINDOW (self));
gtk_window_set_title (GTK_WINDOW (dlg), "HdyDialog");
gtk_dialog_add_buttons (GTK_DIALOG (dlg),
"Done", GTK_RESPONSE_ACCEPT,
"Cancel", GTK_RESPONSE_CANCEL,
NULL);
gtk_dialog_set_default_response (GTK_DIALOG (dlg), GTK_RESPONSE_ACCEPT);
g_signal_connect (G_OBJECT (dlg), "response", G_CALLBACK (dialog_close_cb), NULL);
lbl = gtk_label_new ("Hello, World!");
gtk_widget_set_vexpand (lbl, TRUE);
gtk_widget_set_valign (lbl, GTK_ALIGN_CENTER);
gtk_widget_set_halign (lbl, GTK_ALIGN_CENTER);
gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (dlg))),
lbl);
gtk_widget_show (lbl);
gtk_widget_show (dlg);
}
ExampleWindow *
example_window_new (GtkApplication *application)
......@@ -304,6 +355,8 @@ example_window_class_init (ExampleWindowClass *klass)
gtk_widget_class_bind_template_callback_full (widget_class, "btn_arrows_right_toggled_cb", G_CALLBACK(btn_arrows_right_toggled_cb));
gtk_widget_class_bind_template_callback_full (widget_class, "adj_arrows_count_value_changed_cb", G_CALLBACK(adj_arrows_count_value_changed_cb));
gtk_widget_class_bind_template_callback_full (widget_class, "adj_arrows_duration_value_changed_cb", G_CALLBACK(adj_arrows_duration_value_changed_cb));
gtk_widget_class_bind_template_callback_full (widget_class, "dialog_clicked_cb", G_CALLBACK(dialog_clicked_cb));
gtk_widget_class_bind_template_callback_full (widget_class, "dialog_action_clicked_cb", G_CALLBACK(dialog_action_clicked_cb));
}
static gchar *
......
......@@ -990,6 +990,66 @@
<property name="title">Search bar</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="margin_start">12</property>
<property name="margin_end">12</property>
<property name="valign">center</property>
<property name="halign">center</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="opacity">0.5</property>
<property name="halign">center</property>
<property name="margin_bottom">12</property>
<property name="label" translatable="yes">Dialog</property>
<property name="justify">center</property>
<property name="wrap">True</property>
<attributes>
<attribute name="weight" value="bold"/>
<attribute name="scale" value="2"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton">
<property name="visible">True</property>
<property name="label" translatable="yes">Presentation Dialog</property>
<signal name="clicked" handler="dialog_clicked_cb" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton">
<property name="visible">True</property>
<property name="label" translatable="yes">Action Dialog</property>
<signal name="clicked" handler="dialog_action_clicked_cb" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="name">dialog</property>
<property name="title">Dialog</property>
</packing>
</child>
</object>
</child>
</object>
......
......@@ -29,13 +29,15 @@
* to ensure they don't overflow the screen
*
* #HdyDialog works best when #GtkDialog:use-header-bar is %TRUE (which is
* the case when using #hdy_dialog_new)
* the case when using hdy_dialog_new())
*
* Design Information: [GitLab Issue](https://source.puri.sm/Librem5/libhandy/issues/52)
*
* Ideally when using #HdyDialog you shouldn't need to know you are using
* it rather than #GtkDialog however there are some notable differences:
* #GtkWindow:modal is %TRUE by default as is #GtkWindow:destroy-with-parent
* #GtkWindow:modal is %TRUE by default as is #GtkWindow:destroy-with-parent as
* the behaviour demonstrated by #HdyDialog would be a bad user experiance
* when not moda
*/
/* Point at which we switch to mobile view */
......@@ -50,11 +52,8 @@ typedef struct {
gboolean no_actions;
} HdyDialogPrivate;
static void hdy_dialog_buildable_init (GtkBuildableIface *iface);
G_DEFINE_TYPE_WITH_CODE (HdyDialog, hdy_dialog, GTK_TYPE_DIALOG,
G_ADD_PRIVATE (HdyDialog)
G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, hdy_dialog_buildable_init))
G_ADD_PRIVATE (HdyDialog))
static void
update_titlebar (HdyDialog *self,
......@@ -87,6 +86,50 @@ update_titlebar (HdyDialog *self,
}
}
/* Controls the dialog size, called in reposnse to a GtkWidget::size-allocate
* on the parent of GtkWidget::realize on the dialog */
static void
handle_size (HdyDialog *self, GtkWindow *parent)
{
HdyDialogPrivate *priv = hdy_dialog_get_instance_private (self);
gint width, height;
gboolean maximized;
gboolean is_small;
if (parent == NULL) return;
/* Get the size of the parent */
gtk_window_get_size (parent, &width, &height);
maximized = gtk_window_is_maximized (parent);
/* The "Should we use mobile view™" logic
* Basically: When tall & narrow (but possibly desktop) or
* when short & long (but only mobile)
* Of course we are assuming being short & long &
* maximised only happens on mobile
*/
is_small = (( width <= SNAP_POINT_A && height <= SNAP_POINT_B) ||
(maximized && width <= SNAP_POINT_B && height <= SNAP_POINT_A));
/* When we are below the snap point */
if (is_small) {
/* When no size is cached, cache the current size */
if (!priv->old_width || !priv->old_height) {
gtk_window_get_size (GTK_WINDOW (self), &priv->old_width, &priv->old_height);
update_titlebar (self, is_small);
}
/* Resize the dialog to match the parent */
gtk_window_resize (GTK_WINDOW (self), width, height);
} else if (priv->old_width || priv->old_height) {
/* Restore the cached size */
gtk_window_resize (GTK_WINDOW (self), priv->old_width, priv->old_height);
update_titlebar (self, is_small);
/* Clear cached size */
priv->old_width = 0;
priv->old_height = 0;
}
}
static void
hdy_dialog_realize (GtkWidget *widget)
{
......@@ -114,6 +157,8 @@ hdy_dialog_realize (GtkWidget *widget)
}
}
handle_size (self, gtk_window_get_transient_for (GTK_WINDOW (self)));
/* If this is null things are very bad, but check anyway */
if (GTK_WIDGET_CLASS (hdy_dialog_parent_class)->realize) {
GTK_WIDGET_CLASS (hdy_dialog_parent_class)->realize (widget);
......@@ -218,42 +263,9 @@ size_cb (GtkWidget *widget,
GdkRectangle *allocation,
gpointer user_data)
{
HdyDialog *self = HDY_DIALOG (user_data);
HdyDialogPrivate *priv = hdy_dialog_get_instance_private (self);
gint width, height;
gboolean maximized;
gboolean is_small;
/* Get the size of the parent */
gtk_window_get_size (GTK_WINDOW (widget), &width, &height);
maximized = gtk_window_is_maximized (GTK_WINDOW (widget));
/* The "Should we use mobile view™" logic
* Basically: When tall & narrow (but possibly desktop) or
* when short & long (but only mobile)
* Of course we are assuming being short & long &
* maximised only happens on mobile
*/
is_small = (( width <= SNAP_POINT_A && height <= SNAP_POINT_B) ||
(maximized && width <= SNAP_POINT_B && height <= SNAP_POINT_A));
HdyDialog *self = HDY_DIALOG (user_data);
/* When we are below the snap point */
if (is_small) {
/* When no size is cached, cache the current size */
if (!priv->old_width || !priv->old_height) {
gtk_window_get_size (GTK_WINDOW (self), &priv->old_width, &priv->old_height);
update_titlebar (self, is_small);
}
/* Resize the dialog to match the parent */
gtk_window_resize (GTK_WINDOW (self), width, height);
} else if (priv->old_width || priv->old_height) {
/* Restore the cached size */
gtk_window_resize (GTK_WINDOW (self), priv->old_width, priv->old_height);
update_titlebar (self, is_small);
/* Clear cached size */
priv->old_width = 0;
priv->old_height = 0;
}
handle_size (self, GTK_WINDOW (widget));
}
/* Handle (HdyDialog) GObject::notify::transient-for */
......@@ -327,12 +339,6 @@ hdy_dialog_init (HdyDialog *self)
NULL);
}
static void
hdy_dialog_buildable_init (GtkBuildableIface *iface)
{
/* Nothing to do here */
}
/**
* hdy_dialog_new:
* @parent: #GtkWindow this dialog is a child of
......
......@@ -49,7 +49,7 @@ test_hdy_dialog_is_small (void)
gtk_widget_show (dialog);
g_assert_cmpint (win_height, ==, dlg_height);
g_assert_cmpint (win_height, ==, dlg_width);
g_assert_cmpint (win_width, ==, dlg_width);
}
static void
......@@ -73,7 +73,7 @@ test_hdy_dialog_normal (void)
gtk_widget_show (dialog);
g_assert_cmpint (win_height, !=, dlg_height);
g_assert_cmpint (win_height, !=, dlg_width);
g_assert_cmpint (win_width, !=, dlg_width);
}
gint
......
Supports Markdown
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