[geary: 6/8] composer: Use ReflowBox widget for toolbar



commit 68881434bf9a9addca7614d28c3a9aed663deb2c
Author: James Westman <james flyingpimonster net>
Date:   Mon Jan 20 19:11:36 2020 -0600

    composer: Use ReflowBox widget for toolbar
    
    This new widget replaces the size-allocate hack introduced a few commits ago.

 src/client/components/components-reflow-box.c | 495 +++++++++++++++++++++
 src/client/composer/composer-widget.vala      |  20 +-
 src/client/meson.build                        |   1 +
 ui/composer-widget.ui                         | 605 +++++++++++++-------------
 4 files changed, 793 insertions(+), 328 deletions(-)
---
diff --git a/src/client/components/components-reflow-box.c b/src/client/components/components-reflow-box.c
new file mode 100644
index 00000000..f9d9fbe4
--- /dev/null
+++ b/src/client/components/components-reflow-box.c
@@ -0,0 +1,495 @@
+/*
+ * Copyright (C) 2020 Alexander Mikhaylenko <exalm7659 gmail com>
+ * Copyright (C) 2020 James Westman <james flyingpimonster net>
+ *
+ * SPDX-License-Identifier: LGPL-2.1+
+ */
+
+#include "config.h"
+#include <glib/gi18n-lib.h>
+#include <gtk/gtk.h>
+
+
+#define COMPONENTS_TYPE_REFLOW_BOX (components_reflow_box_get_type())
+
+G_DECLARE_FINAL_TYPE (ComponentsReflowBox, components_reflow_box, COMPONENTS, REFLOW_BOX, GtkContainer)
+
+
+ComponentsReflowBox *components_reflow_box_new (void);
+
+guint components_reflow_box_get_spacing (ComponentsReflowBox *self);
+void  components_reflow_box_set_spacing (ComponentsReflowBox *self,
+                                         guint                spacing);
+
+guint components_reflow_box_get_row_spacing (ComponentsReflowBox *self);
+void  components_reflow_box_set_row_spacing (ComponentsReflowBox *self,
+                                             guint                row_spacing);
+
+
+struct _ComponentsReflowBox
+{
+  GtkContainer parent_instance;
+
+  GList *children;
+
+  guint spacing;
+  guint row_spacing;
+};
+
+G_DEFINE_TYPE (ComponentsReflowBox, components_reflow_box, GTK_TYPE_CONTAINER);
+
+enum {
+  PROP_0,
+  PROP_SPACING,
+  PROP_ROW_SPACING,
+  LAST_PROP,
+};
+
+static GParamSpec *props[LAST_PROP];
+
+
+static void
+components_reflow_box_init (ComponentsReflowBox *self)
+{
+  gtk_widget_set_has_window (GTK_WIDGET (self), FALSE);
+}
+
+static void
+components_reflow_box_get_property (GObject    *object,
+                             guint       prop_id,
+                             GValue     *value,
+                             GParamSpec *pspec)
+{
+  ComponentsReflowBox *self = COMPONENTS_REFLOW_BOX (object);
+
+  switch (prop_id) {
+  case PROP_SPACING:
+    g_value_set_uint (value, components_reflow_box_get_spacing (self));
+    break;
+
+  case PROP_ROW_SPACING:
+    g_value_set_uint (value, components_reflow_box_get_row_spacing (self));
+    break;
+
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+  }
+}
+
+static void
+components_reflow_box_set_property (GObject      *object,
+                             guint         prop_id,
+                             const GValue *value,
+                             GParamSpec   *pspec)
+{
+  ComponentsReflowBox *self = COMPONENTS_REFLOW_BOX (object);
+
+  switch (prop_id) {
+  case PROP_SPACING:
+    components_reflow_box_set_spacing (self, g_value_get_uint (value));
+    break;
+
+  case PROP_ROW_SPACING:
+    components_reflow_box_set_row_spacing (self, g_value_get_uint (value));
+    break;
+
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+  }
+}
+
+/**
+ * components_reflow_box_set_spacing:
+ * @self: a #ComponentsReflowBox
+ * @spacing: the spacing
+ *
+ * Sets the spacing for @self.
+ *
+ * Since: 0.0.14
+ */
+void
+components_reflow_box_set_spacing (ComponentsReflowBox *self,
+                            guint         spacing)
+{
+  if (self->spacing == spacing)
+    return;
+
+  self->spacing = spacing;
+  gtk_widget_queue_resize (GTK_WIDGET (self));
+
+  g_object_notify_by_pspec (G_OBJECT (self), props[PROP_SPACING]);
+}
+
+/**
+ * components_reflow_box_get_spacing:
+ * @self: a #ComponentsReflowBox
+ *
+ * Gets the spacing for @self.
+ *
+ * Returns: the spacing for @self.
+ *
+ * Since: 0.0.14
+ */
+guint
+components_reflow_box_get_spacing (ComponentsReflowBox *self)
+{
+  return self->spacing;
+}
+
+/**
+ * components_reflow_box_set_row_spacing:
+ * @self: a #ComponentsReflowBox
+ * @row_spacing: the row spacing
+ *
+ * Sets the row spacing for @self.
+ *
+ * Since: 0.0.14
+ */
+void
+components_reflow_box_set_row_spacing (ComponentsReflowBox *self,
+                                guint          row_spacing)
+{
+  if (self->row_spacing == row_spacing)
+    return;
+
+  self->row_spacing = row_spacing;
+  gtk_widget_queue_resize (GTK_WIDGET (self));
+
+  g_object_notify_by_pspec (G_OBJECT (self), props[PROP_ROW_SPACING]);
+}
+
+/**
+ * components_reflow_box_get_row_spacing:
+ * @self: a #ComponentsReflowBox
+ *
+ * Gets the row spacing for @self.
+ *
+ * Returns: the row spacing for @self.
+ *
+ * Since: 0.0.14
+ */
+guint
+components_reflow_box_get_row_spacing (ComponentsReflowBox *self)
+{
+  return self->row_spacing;
+}
+
+
+static void
+allocate_row (ComponentsReflowBox  *self,
+              GtkAllocation *allocation,
+              gint           y,
+              GList         *row_start,
+              GList         *next_row,
+              gint           row_height,
+              gint           extra_space,
+              gint           n_expand_children)
+{
+  gboolean rtl;
+  gint x = 0;
+  gint expand_per_child = 0;
+
+  if (row_start == NULL)
+    return;
+
+  rtl = gtk_widget_get_direction (GTK_WIDGET (self)) == GTK_TEXT_DIR_RTL;
+  if (rtl)
+    x = allocation->width;
+
+  if (n_expand_children > 0) {
+    expand_per_child = extra_space / n_expand_children;
+  } else {
+    GtkAlign align;
+    align = gtk_widget_get_halign (GTK_WIDGET (self));
+    if (align == GTK_ALIGN_CENTER) {
+      if (rtl)
+        x -= (extra_space / 2);
+      else
+        x += (extra_space / 2);
+    } else if (align == GTK_ALIGN_END) {
+      if (rtl)
+        x -= extra_space;
+      else
+        x += extra_space;
+    }
+  }
+
+  for (GList *l = row_start; l != NULL && l != next_row; l = l->next) {
+    GtkWidget *child = GTK_WIDGET (l->data);
+    int w, min_w;
+    GtkAllocation child_alloc;
+
+    if (!gtk_widget_get_visible (child))
+      continue;
+
+    gtk_widget_get_preferred_width (child, &min_w, &w);
+    w = CLAMP (w, min_w, allocation->width);
+
+    if (gtk_widget_get_hexpand (child)) {
+      w += expand_per_child;
+    }
+
+    if (rtl)
+      x -= w;
+
+    child_alloc.x = x + allocation->x;
+
+    if (rtl)
+      x -= self->spacing;
+    else
+      x += w + self->spacing;
+
+    child_alloc.y = y + allocation->y;
+    child_alloc.width = w;
+    child_alloc.height = row_height;
+
+    gtk_widget_size_allocate (child, &child_alloc);
+  }
+}
+
+static gint
+calculate_sizes (ComponentsReflowBox  *self,
+                 GtkAllocation *allocation,
+                 gboolean       dry_run)
+{
+  gint x = 0;
+  gint y = 0;
+  gint row_height = 0;
+
+  GList *row_start = self->children;
+  gint n_expand_children = 0;
+
+  for (GList *l = self->children; l != NULL; l = l->next) {
+    GtkWidget *child = GTK_WIDGET (l->data);
+    int w, h, min_w;
+
+    if (!gtk_widget_get_visible (child))
+      continue;
+
+    gtk_widget_get_preferred_width (child, &min_w, &w);
+    gtk_widget_get_preferred_height (child, NULL, &h);
+
+    w = CLAMP (w, min_w, allocation->width);
+
+    if (x + w > allocation->width) {
+      /* no more space on this row, create a new one */
+
+      /* first, do the allocations for the previous row, if needed */
+      if (!dry_run) {
+        allocate_row (self, allocation, y, row_start, l, row_height,
+                      allocation->width + self->spacing - x, n_expand_children);
+      }
+
+      /* now reset everything for the next row */
+      x = 0;
+      y += row_height + self->row_spacing;
+      row_height = 0;
+      n_expand_children = 0;
+      row_start = l;
+    }
+
+    if (gtk_widget_get_hexpand (child))
+      n_expand_children ++;
+
+    row_height = MAX (row_height, h);
+
+    x += w + self->spacing;
+  }
+
+  if (!dry_run) {
+    /* allocate the last row */
+    allocate_row (self, allocation, y, row_start, NULL, row_height,
+                  allocation->width + self->spacing - x, n_expand_children);
+  }
+
+  return y + row_height;
+}
+
+static void
+components_reflow_box_size_allocate(GtkWidget      *widget,
+                             GtkAllocation  *allocation)
+{
+  ComponentsReflowBox *self = COMPONENTS_REFLOW_BOX (widget);
+
+  calculate_sizes(self, allocation, FALSE);
+  GTK_WIDGET_CLASS (components_reflow_box_parent_class)->size_allocate (widget, allocation);
+}
+
+static GtkSizeRequestMode
+components_reflow_box_get_request_mode(GtkWidget *widget)
+{
+  return GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH;
+}
+
+static void
+components_reflow_box_get_preferred_width(GtkWidget *widget,
+                                   gint      *minimum_width,
+                                   gint      *natural_width)
+{
+  ComponentsReflowBox *self = COMPONENTS_REFLOW_BOX (widget);
+
+  gint min = 0;
+  gint nat = 0;
+
+  for (GList *l = self->children; l != NULL; l = l->next) {
+    GtkWidget *child = GTK_WIDGET (l->data);
+    int child_min, child_nat;
+
+    if (!gtk_widget_get_visible (child))
+      continue;
+
+    gtk_widget_get_preferred_width (child, &child_min, &child_nat);
+
+    min = MAX (min, child_min);
+    nat += child_nat + self->spacing;
+  }
+
+  /* remove the extra spacing, avoid off-by-one error */
+  if (self->children != NULL)
+    nat -= self->spacing;
+
+  if (minimum_width)
+    *minimum_width = min;
+  if (natural_width)
+    *natural_width = nat;
+}
+
+static void
+components_reflow_box_get_preferred_width_for_height (GtkWidget *widget,
+                                               gint       height,
+                                               gint      *minimum_width,
+                                               gint      *natural_width)
+{
+  components_reflow_box_get_preferred_width (widget, minimum_width, natural_width);
+}
+
+static void
+components_reflow_box_get_preferred_height_for_width (GtkWidget *widget,
+                                               gint       width,
+                                               gint      *minimum_height,
+                                               gint      *natural_height)
+{
+  ComponentsReflowBox *self = COMPONENTS_REFLOW_BOX (widget);
+
+  GtkAllocation allocation;
+  gint h;
+
+  allocation.width = width;
+  h = calculate_sizes (self, &allocation, TRUE);
+
+  if (minimum_height)
+    *minimum_height = h;
+  if (natural_height)
+    *natural_height = h;
+}
+
+
+static void
+components_reflow_box_add (GtkContainer *container,
+                    GtkWidget    *widget)
+{
+  ComponentsReflowBox *self = COMPONENTS_REFLOW_BOX (container);
+
+  self->children = g_list_append (self->children, widget);
+  gtk_widget_set_parent (widget, GTK_WIDGET (self));
+}
+
+static void
+components_reflow_box_remove (GtkContainer *container,
+                       GtkWidget    *widget)
+{
+  ComponentsReflowBox *self = COMPONENTS_REFLOW_BOX (container);
+
+  gtk_widget_unparent (widget);
+  self->children = g_list_remove (self->children, widget);
+}
+
+static void
+components_reflow_box_forall (GtkContainer *container,
+                       gboolean      include_internals,
+                       GtkCallback   callback,
+                       gpointer      callback_data)
+{
+  ComponentsReflowBox *self = COMPONENTS_REFLOW_BOX (container);
+
+  // while loop instead of for loop in case the callback removes children
+  GList *l = self->children;
+  while (l != NULL) {
+    GtkWidget *child = GTK_WIDGET (l->data);
+    l = l->next;
+    callback (child, callback_data);
+  }
+}
+
+static void
+components_reflow_box_class_init (ComponentsReflowBoxClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+  GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
+
+  object_class->set_property = components_reflow_box_set_property;
+  object_class->get_property = components_reflow_box_get_property;
+
+  widget_class->size_allocate = components_reflow_box_size_allocate;
+  widget_class->get_request_mode = components_reflow_box_get_request_mode;
+  widget_class->get_preferred_width = components_reflow_box_get_preferred_width;
+  widget_class->get_preferred_width_for_height = components_reflow_box_get_preferred_width_for_height;
+  widget_class->get_preferred_height_for_width = components_reflow_box_get_preferred_height_for_width;
+
+  container_class->add = components_reflow_box_add;
+  container_class->remove = components_reflow_box_remove;
+  container_class->forall = components_reflow_box_forall;
+
+  /**
+   * ComponentsReflowBox:spacing:
+   *
+   * The spacing between children
+   *
+   * Since: 0.0.14
+   */
+  props[PROP_SPACING] =
+    g_param_spec_uint ("spacing",
+                       _("Spacing"),
+                       _("Spacing between children"),
+                       0,
+                       G_MAXUINT,
+                       0,
+                       G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
+
+  /**
+   * ComponentsReflowBox:row-spacing:
+   *
+   * The spacing between rows of children
+   *
+   * Since: 0.0.14
+   */
+  props[PROP_ROW_SPACING] =
+    g_param_spec_uint ("row-spacing",
+                       _("Row spacing"),
+                       _("Spacing between rows of children"),
+                       0,
+                       G_MAXUINT,
+                       0,
+                       G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
+
+  g_object_class_install_properties (object_class, LAST_PROP, props);
+}
+
+/**
+ * components_reflow_box_new:
+ *
+ * Create a new #ComponentsReflowBox widget.
+ *
+ * Returns: The newly created #ComponentsReflowBox widget
+ *
+ * Since: 0.0.14
+ */
+ComponentsReflowBox *
+components_reflow_box_new (void)
+{
+  return g_object_new (COMPONENTS_TYPE_REFLOW_BOX, NULL);
+}
+
+
+
diff --git a/src/client/composer/composer-widget.vala b/src/client/composer/composer-widget.vala
index 6c490cf5..8c82f47c 100644
--- a/src/client/composer/composer-widget.vala
+++ b/src/client/composer/composer-widget.vala
@@ -11,6 +11,8 @@ private errordomain AttachmentError {
     DUPLICATE
 }
 
+[CCode (cname = "components_reflow_box_get_type")]
+private extern Type components_reflow_box_get_type();
 
 /**
  * A widget for editing an email message.
@@ -378,9 +380,6 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
     [GtkChild] private Gtk.Box conversation_attach_buttons;
 
     [GtkChild] private Gtk.Revealer formatting;
-    [GtkChild] private Gtk.Box toolbar_box;
-    [GtkChild] private Gtk.Box top_buttons;
-    [GtkChild] private Gtk.Box bottom_buttons;
     [GtkChild] private Gtk.MenuButton font_button;
     [GtkChild] private Gtk.Stack font_button_stack;
     [GtkChild] private Gtk.MenuButton font_size_button;
@@ -486,6 +485,7 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
     public Widget(Application.Client application,
                           Geary.Account initial_account,
                           ComposeType compose_type) {
+        components_reflow_box_get_type();
         base_ref();
         this.application = application;
         this.account = initial_account;
@@ -2895,18 +2895,4 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
         this.background_work_pulse.reset();
         this.show_background_work_timeout.reset();
     }
-
-    [GtkCallback]
-    private void on_toolbar_size_allocate(Gtk.Widget widget, Gtk.Allocation rect) {
-        int top_width = this.top_buttons.get_allocated_width();
-        int bottom_width = this.bottom_buttons.get_allocated_width();
-        // add 6 for spacing
-        int width = top_width + bottom_width + 6;
-
-        if (rect.width <= width) {
-            this.toolbar_box.orientation = VERTICAL;
-        } else {
-            this.toolbar_box.orientation = HORIZONTAL;
-        }
-    }
 }
diff --git a/src/client/meson.build b/src/client/meson.build
index ed99bacf..bb61d9f5 100644
--- a/src/client/meson.build
+++ b/src/client/meson.build
@@ -37,6 +37,7 @@ geary_client_vala_sources = files(
   'components/components-inspector-system-view.vala',
   'components/components-placeholder-pane.vala',
   'components/components-preferences-window.vala',
+  'components/components-reflow-box.c',
   'components/components-search-bar.vala',
   'components/components-validator.vala',
   'components/components-web-view.vala',
diff --git a/ui/composer-widget.ui b/ui/composer-widget.ui
index e48412ed..fb32a325 100644
--- a/ui/composer-widget.ui
+++ b/ui/composer-widget.ui
@@ -566,428 +566,411 @@
                   <object class="GtkActionBar">
                     <property name="visible">True</property>
                     <child>
-                      <object class="GtkBox" id="toolbar_box">
+                      <object class="ComponentsReflowBox" id="toolbar_box">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
-                        <property name="orientation">horizontal</property>
                         <property name="spacing">6</property>
+                        <property name="row_spacing">6</property>
                         <property name="hexpand">True</property>
-                        <signal name="size-allocate" handler="on_toolbar_size_allocate" swapped="no"/>
                         <child>
-                          <object class="GtkBox" id="top_buttons">
+                          <object class="GtkBox" id="font_style_buttons">
                             <property name="visible">True</property>
                             <property name="can_focus">False</property>
-                            <property name="spacing">6</property>
-                            <property name="halign">start</property>
                             <child>
-                              <object class="GtkBox" id="font_style_buttons">
+                              <object class="GtkToggleButton" id="bold_button">
                                 <property name="visible">True</property>
-                                <property name="can_focus">False</property>
-                                <child>
-                                  <object class="GtkToggleButton" id="bold_button">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="focus_on_click">False</property>
-                                    <property name="receives_default">False</property>
-                                    <property name="tooltip_text" translatable="yes">Bold text</property>
-                                    <property name="action_name">edt.bold</property>
-                                    <property name="always_show_image">True</property>
-                                    <child>
-                                      <object class="GtkImage" id="bold_image">
-                                        <property name="visible">True</property>
-                                        <property name="can_focus">False</property>
-                                        <property name="pixel_size">16</property>
-                                        <property name="icon_name">format-text-bold-symbolic</property>
-                                      </object>
-                                    </child>
-                                  </object>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">True</property>
-                                    <property name="position">0</property>
-                                  </packing>
-                                </child>
+                                <property name="can_focus">True</property>
+                                <property name="focus_on_click">False</property>
+                                <property name="receives_default">False</property>
+                                <property name="tooltip_text" translatable="yes">Bold text</property>
+                                <property name="action_name">edt.bold</property>
+                                <property name="always_show_image">True</property>
                                 <child>
-                                  <object class="GtkToggleButton" id="italics_button">
+                                  <object class="GtkImage" id="bold_image">
                                     <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="focus_on_click">False</property>
-                                    <property name="receives_default">False</property>
-                                    <property name="tooltip_text" translatable="yes">Italic text</property>
-                                    <property name="action_name">edt.italic</property>
-                                    <property name="always_show_image">True</property>
-                                    <child>
-                                      <object class="GtkImage" id="italics_image">
-                                        <property name="visible">True</property>
-                                        <property name="can_focus">False</property>
-                                        <property name="pixel_size">16</property>
-                                        <property name="icon_name">format-text-italic-symbolic</property>
-                                      </object>
-                                    </child>
+                                    <property name="can_focus">False</property>
+                                    <property name="pixel_size">16</property>
+                                    <property name="icon_name">format-text-bold-symbolic</property>
                                   </object>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">True</property>
-                                    <property name="position">1</property>
-                                  </packing>
                                 </child>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">0</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkToggleButton" id="italics_button">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="focus_on_click">False</property>
+                                <property name="receives_default">False</property>
+                                <property name="tooltip_text" translatable="yes">Italic text</property>
+                                <property name="action_name">edt.italic</property>
+                                <property name="always_show_image">True</property>
                                 <child>
-                                  <object class="GtkToggleButton" id="underline_button">
+                                  <object class="GtkImage" id="italics_image">
                                     <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="focus_on_click">False</property>
-                                    <property name="receives_default">False</property>
-                                    <property name="tooltip_text" translatable="yes">Underline 
text</property>
-                                    <property name="action_name">edt.underline</property>
-                                    <property name="always_show_image">True</property>
-                                    <child>
-                                      <object class="GtkImage" id="underline_image">
-                                        <property name="visible">True</property>
-                                        <property name="can_focus">False</property>
-                                        <property name="pixel_size">16</property>
-                                        <property name="icon_name">format-text-underline-symbolic</property>
-                                      </object>
-                                    </child>
+                                    <property name="can_focus">False</property>
+                                    <property name="pixel_size">16</property>
+                                    <property name="icon_name">format-text-italic-symbolic</property>
                                   </object>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">True</property>
-                                    <property name="position">2</property>
-                                  </packing>
                                 </child>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkToggleButton" id="underline_button">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="focus_on_click">False</property>
+                                <property name="receives_default">False</property>
+                                <property name="tooltip_text" translatable="yes">Underline text</property>
+                                <property name="action_name">edt.underline</property>
+                                <property name="always_show_image">True</property>
                                 <child>
-                                  <object class="GtkToggleButton" id="strikethrough_button">
+                                  <object class="GtkImage" id="underline_image">
                                     <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="focus_on_click">False</property>
-                                    <property name="receives_default">False</property>
-                                    <property name="tooltip_text" translatable="yes">Strikethrough 
text</property>
-                                    <property name="action_name">edt.strikethrough</property>
-                                    <property name="always_show_image">True</property>
-                                    <child>
-                                      <object class="GtkImage" id="strikethrough_image">
-                                        <property name="visible">True</property>
-                                        <property name="can_focus">False</property>
-                                        <property name="pixel_size">16</property>
-                                        <property 
name="icon_name">format-text-strikethrough-symbolic</property>
-                                      </object>
-                                    </child>
+                                    <property name="can_focus">False</property>
+                                    <property name="pixel_size">16</property>
+                                    <property name="icon_name">format-text-underline-symbolic</property>
                                   </object>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">True</property>
-                                    <property name="position">3</property>
-                                  </packing>
                                 </child>
-                                <style>
-                                  <class name="linked"/>
-                                </style>
                               </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">2</property>
+                              </packing>
                             </child>
                             <child>
-                              <object class="GtkBox" id="list_buttons">
+                              <object class="GtkToggleButton" id="strikethrough_button">
                                 <property name="visible">True</property>
-                                <property name="can_focus">False</property>
+                                <property name="can_focus">True</property>
+                                <property name="focus_on_click">False</property>
+                                <property name="receives_default">False</property>
+                                <property name="tooltip_text" translatable="yes">Strikethrough 
text</property>
+                                <property name="action_name">edt.strikethrough</property>
+                                <property name="always_show_image">True</property>
                                 <child>
-                                  <object class="GtkButton" id="ulist_button">
+                                  <object class="GtkImage" id="strikethrough_image">
                                     <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="focus_on_click">False</property>
-                                    <property name="receives_default">False</property>
-                                    <property name="tooltip_text" translatable="yes">Insert bulleted 
list</property>
-                                    <property name="action_name">edt.ulist</property>
-                                    <property name="always_show_image">True</property>
-                                    <child>
-                                      <object class="GtkImage" id="ulist_image">
-                                        <property name="visible">True</property>
-                                        <property name="can_focus">False</property>
-                                        <property name="pixel_size">16</property>
-                                        <property name="icon_name">format-unordered-list-symbolic</property>
-                                      </object>
-                                    </child>
+                                    <property name="can_focus">False</property>
+                                    <property name="pixel_size">16</property>
+                                    <property name="icon_name">format-text-strikethrough-symbolic</property>
                                   </object>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">True</property>
-                                    <property name="position">0</property>
-                                  </packing>
                                 </child>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">3</property>
+                              </packing>
+                            </child>
+                            <style>
+                              <class name="linked"/>
+                            </style>
+                          </object>
+                        </child>
+                        <child>
+                          <object class="GtkBox" id="list_buttons">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <child>
+                              <object class="GtkButton" id="ulist_button">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="focus_on_click">False</property>
+                                <property name="receives_default">False</property>
+                                <property name="tooltip_text" translatable="yes">Insert bulleted 
list</property>
+                                <property name="action_name">edt.ulist</property>
+                                <property name="always_show_image">True</property>
                                 <child>
-                                  <object class="GtkButton" id="olist_button">
+                                  <object class="GtkImage" id="ulist_image">
                                     <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="focus_on_click">False</property>
-                                    <property name="receives_default">False</property>
-                                    <property name="tooltip_text" translatable="yes">Insert numbered 
list</property>
-                                    <property name="action_name">edt.olist</property>
-                                    <property name="always_show_image">True</property>
-                                    <child>
-                                      <object class="GtkImage" id="olist_image">
-                                        <property name="visible">True</property>
-                                        <property name="can_focus">False</property>
-                                        <property name="pixel_size">16</property>
-                                        <property name="icon_name">format-ordered-list-symbolic</property>
-                                      </object>
-                                    </child>
+                                    <property name="can_focus">False</property>
+                                    <property name="pixel_size">16</property>
+                                    <property name="icon_name">format-unordered-list-symbolic</property>
                                   </object>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">True</property>
-                                    <property name="position">1</property>
-                                  </packing>
                                 </child>
-                                <style>
-                                  <class name="linked"/>
-                                </style>
                               </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">0</property>
+                              </packing>
                             </child>
                             <child>
-                              <object class="GtkBox" id="indentation_buttons">
+                              <object class="GtkButton" id="olist_button">
                                 <property name="visible">True</property>
-                                <property name="can_focus">False</property>
+                                <property name="can_focus">True</property>
+                                <property name="focus_on_click">False</property>
+                                <property name="receives_default">False</property>
+                                <property name="tooltip_text" translatable="yes">Insert numbered 
list</property>
+                                <property name="action_name">edt.olist</property>
+                                <property name="always_show_image">True</property>
                                 <child>
-                                  <object class="GtkButton" id="indent_button">
+                                  <object class="GtkImage" id="olist_image">
                                     <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="focus_on_click">False</property>
-                                    <property name="receives_default">False</property>
-                                    <property name="tooltip_text" translatable="yes">Indent or quote 
text</property>
-                                    <property name="action_name">edt.indent</property>
-                                    <property name="always_show_image">True</property>
-                                    <child>
-                                      <object class="GtkImage" id="indent_image">
-                                        <property name="visible">True</property>
-                                        <property name="can_focus">False</property>
-                                        <property name="pixel_size">16</property>
-                                        <property name="icon_name">format-indent-more-symbolic</property>
-                                      </object>
-                                    </child>
+                                    <property name="can_focus">False</property>
+                                    <property name="pixel_size">16</property>
+                                    <property name="icon_name">format-ordered-list-symbolic</property>
                                   </object>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">True</property>
-                                    <property name="position">0</property>
-                                  </packing>
                                 </child>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
+                            <style>
+                              <class name="linked"/>
+                            </style>
+                          </object>
+                        </child>
+                        <child>
+                          <object class="GtkBox" id="indentation_buttons">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <child>
+                              <object class="GtkButton" id="indent_button">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="focus_on_click">False</property>
+                                <property name="receives_default">False</property>
+                                <property name="tooltip_text" translatable="yes">Indent or quote 
text</property>
+                                <property name="action_name">edt.indent</property>
+                                <property name="always_show_image">True</property>
                                 <child>
-                                  <object class="GtkButton" id="outdent_button">
+                                  <object class="GtkImage" id="indent_image">
                                     <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="focus_on_click">False</property>
-                                    <property name="receives_default">False</property>
-                                    <property name="tooltip_text" translatable="yes">Un-indent or unquote 
text</property>
-                                    <property name="action_name">edt.outdent</property>
-                                    <property name="always_show_image">True</property>
-                                    <child>
-                                      <object class="GtkImage" id="outdent_image">
-                                        <property name="visible">True</property>
-                                        <property name="can_focus">False</property>
-                                        <property name="pixel_size">16</property>
-                                        <property name="icon_name">format-indent-less-symbolic</property>
-                                      </object>
-                                    </child>
+                                    <property name="can_focus">False</property>
+                                    <property name="pixel_size">16</property>
+                                    <property name="icon_name">format-indent-more-symbolic</property>
                                   </object>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">True</property>
-                                    <property name="position">1</property>
-                                  </packing>
                                 </child>
-                                <style>
-                                  <class name="linked"/>
-                                </style>
                               </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">0</property>
+                              </packing>
                             </child>
                             <child>
-                              <object class="GtkButton" id="remove_format_button">
+                              <object class="GtkButton" id="outdent_button">
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="focus_on_click">False</property>
                                 <property name="receives_default">False</property>
-                                <property name="tooltip_text" translatable="yes">Remove text 
formatting</property>
-                                <property name="action_name">edt.remove-format</property>
+                                <property name="tooltip_text" translatable="yes">Un-indent or unquote 
text</property>
+                                <property name="action_name">edt.outdent</property>
                                 <property name="always_show_image">True</property>
                                 <child>
-                                  <object class="GtkImage" id="remove_format_image">
+                                  <object class="GtkImage" id="outdent_image">
                                     <property name="visible">True</property>
                                     <property name="can_focus">False</property>
                                     <property name="pixel_size">16</property>
-                                    <property name="icon_name">format-text-remove-symbolic</property>
+                                    <property name="icon_name">format-indent-less-symbolic</property>
                                   </object>
                                 </child>
                               </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
+                            <style>
+                              <class name="linked"/>
+                            </style>
+                          </object>
+                        </child>
+                        <child>
+                          <object class="GtkButton" id="remove_format_button">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="focus_on_click">False</property>
+                            <property name="receives_default">False</property>
+                            <property name="tooltip_text" translatable="yes">Remove text 
formatting</property>
+                            <property name="action_name">edt.remove-format</property>
+                            <property name="always_show_image">True</property>
+                            <child>
+                              <object class="GtkImage" id="remove_format_image">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="pixel_size">16</property>
+                                <property name="icon_name">format-text-remove-symbolic</property>
+                              </object>
                             </child>
                           </object>
                         </child>
                         <child>
-                          <object class="GtkBox" id="bottom_buttons">
+                          <object class="GtkMenuButton" id="font_button">
                             <property name="visible">True</property>
-                            <property name="can_focus">False</property>
-                            <property name="spacing">6</property>
-                            <property name="halign">start</property>
+                            <property name="can_focus">True</property>
+                            <property name="menu_model">font_menu</property>
+                            <property name="tooltip_text" translatable="yes">Change font type</property>
+                            <property name="direction">up</property>
                             <child>
-                              <object class="GtkMenuButton" id="font_button">
+                              <object class="GtkBox">
                                 <property name="visible">True</property>
-                                <property name="can_focus">True</property>
-                                <property name="menu_model">font_menu</property>
-                                <property name="tooltip_text" translatable="yes">Change font type</property>
-                                <property name="direction">up</property>
+                                <property name="can_focus">False</property>
+                                <property name="orientation">horizontal</property>
                                 <child>
-                                  <object class="GtkBox">
+                                  <object class="GtkStack" id="font_button_stack">
                                     <property name="visible">True</property>
                                     <property name="can_focus">False</property>
-                                    <property name="orientation">horizontal</property>
                                     <child>
-                                      <object class="GtkStack" id="font_button_stack">
+                                      <object class="GtkLabel">
                                         <property name="visible">True</property>
                                         <property name="can_focus">False</property>
-                                        <child>
-                                          <object class="GtkLabel">
-                                            <property name="visible">True</property>
-                                            <property name="can_focus">False</property>
-                                            <property name="label" translatable="yes">Sans Serif</property>
-                                            <property name="halign">start</property>
-                                          </object>
-                                          <packing>
-                                            <property name="name">sans</property>
-                                          </packing>
-                                        </child>
-                                        <child>
-                                          <object class="GtkLabel">
-                                            <property name="visible">True</property>
-                                            <property name="can_focus">False</property>
-                                            <property name="label" translatable="yes">Serif</property>
-                                            <property name="halign">start</property>
-                                          </object>
-                                          <packing>
-                                            <property name="name">serif</property>
-                                          </packing>
-                                        </child>
-                                        <child>
-                                          <object class="GtkLabel">
-                                            <property name="visible">True</property>
-                                            <property name="can_focus">False</property>
-                                            <property name="label" translatable="yes">Fixed Width</property>
-                                            <property name="halign">start</property>
-                                          </object>
-                                          <packing>
-                                            <property name="name">monospace</property>
-                                          </packing>
-                                        </child>
+                                        <property name="label" translatable="yes">Sans Serif</property>
+                                        <property name="halign">start</property>
                                       </object>
+                                      <packing>
+                                        <property name="name">sans</property>
+                                      </packing>
                                     </child>
                                     <child>
-                                      <object class="GtkImage">
+                                      <object class="GtkLabel">
                                         <property name="visible">True</property>
                                         <property name="can_focus">False</property>
-                                        <property name="icon-name">pan-down</property>
+                                        <property name="label" translatable="yes">Serif</property>
+                                        <property name="halign">start</property>
                                       </object>
+                                      <packing>
+                                        <property name="name">serif</property>
+                                      </packing>
                                     </child>
+                                    <child>
+                                      <object class="GtkLabel">
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">False</property>
+                                        <property name="label" translatable="yes">Fixed Width</property>
+                                        <property name="halign">start</property>
+                                      </object>
+                                      <packing>
+                                        <property name="name">monospace</property>
+                                      </packing>
+                                    </child>
+                                  </object>
+                                </child>
+                                <child>
+                                  <object class="GtkImage">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="icon-name">pan-down</property>
                                   </object>
                                 </child>
                               </object>
                             </child>
+                          </object>
+                        </child>
+                        <child>
+                          <object class="GtkButton">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="action_name">edt.color</property>
+                            <property name="tooltip_text" translatable="yes">Change font color</property>
                             <child>
-                              <object class="GtkButton">
+                              <object class="GtkImage" id="font_color_icon">
                                 <property name="visible">True</property>
-                                <property name="can_focus">True</property>
-                                <property name="action_name">edt.color</property>
-                                <property name="tooltip_text" translatable="yes">Change font color</property>
+                                <property name="can_focus">False</property>
+                              </object>
+                            </child>
+                          </object>
+                        </child>
+                        <child>
+                          <object class="GtkMenuButton" id="font_size_button">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="menu_model">font_size_menu</property>
+                            <property name="tooltip_text" translatable="yes">Change font size</property>
+                            <property name="direction">up</property>
+                            <child>
+                              <object class="GtkBox">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="orientation">horizontal</property>
+                                <child>
+                                  <object class="GtkImage">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="icon-name">font-size-symbolic</property>
+                                  </object>
+                                </child>
                                 <child>
-                                  <object class="GtkImage" id="font_color_icon">
+                                  <object class="GtkImage">
                                     <property name="visible">True</property>
                                     <property name="can_focus">False</property>
+                                    <property name="icon-name">pan-down</property>
                                   </object>
                                 </child>
                               </object>
                             </child>
+                          </object>
+                        </child>
+                        <child>
+                          <object class="GtkBox" id="insert_buttons">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
                             <child>
-                              <object class="GtkMenuButton" id="font_size_button">
+                              <object class="GtkButton" id="insert_link_button">
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
-                                <property name="menu_model">font_size_menu</property>
-                                <property name="tooltip_text" translatable="yes">Change font size</property>
-                                <property name="direction">up</property>
+                                <property name="focus_on_click">False</property>
+                                <property name="receives_default">False</property>
+                                <property name="tooltip_text" translatable="yes">Insert or update text 
link</property>
+                                <property name="action_name">edt.insert-link</property>
+                                <property name="always_show_image">True</property>
                                 <child>
-                                  <object class="GtkBox">
+                                  <object class="GtkImage" id="insert_link_image">
                                     <property name="visible">True</property>
                                     <property name="can_focus">False</property>
-                                    <property name="orientation">horizontal</property>
-                                    <child>
-                                      <object class="GtkImage">
-                                        <property name="visible">True</property>
-                                        <property name="can_focus">False</property>
-                                        <property name="icon-name">font-size-symbolic</property>
-                                      </object>
-                                    </child>
-                                    <child>
-                                      <object class="GtkImage">
-                                        <property name="visible">True</property>
-                                        <property name="can_focus">False</property>
-                                        <property name="icon-name">pan-down</property>
-                                      </object>
-                                    </child>
+                                    <property name="pixel_size">16</property>
+                                    <property name="icon_name">insert-link-symbolic</property>
                                   </object>
                                 </child>
                               </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">0</property>
+                              </packing>
                             </child>
                             <child>
-                              <object class="GtkBox" id="insert_buttons">
+                              <object class="GtkButton" id="insert_image_button">
                                 <property name="visible">True</property>
-                                <property name="can_focus">False</property>
-                                <child>
-                                  <object class="GtkButton" id="insert_link_button">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="focus_on_click">False</property>
-                                    <property name="receives_default">False</property>
-                                    <property name="tooltip_text" translatable="yes">Insert or update text 
link</property>
-                                    <property name="action_name">edt.insert-link</property>
-                                    <property name="always_show_image">True</property>
-                                    <child>
-                                      <object class="GtkImage" id="insert_link_image">
-                                        <property name="visible">True</property>
-                                        <property name="can_focus">False</property>
-                                        <property name="pixel_size">16</property>
-                                        <property name="icon_name">insert-link-symbolic</property>
-                                      </object>
-                                    </child>
-                                  </object>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">True</property>
-                                    <property name="position">0</property>
-                                  </packing>
-                                </child>
+                                <property name="can_focus">True</property>
+                                <property name="focus_on_click">False</property>
+                                <property name="receives_default">False</property>
+                                <property name="tooltip_text" translatable="yes">Insert an image</property>
+                                <property name="action_name">edt.insert-image</property>
+                                <property name="always_show_image">True</property>
                                 <child>
-                                  <object class="GtkButton" id="insert_image_button">
+                                  <object class="GtkImage">
                                     <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="focus_on_click">False</property>
-                                    <property name="receives_default">False</property>
-                                    <property name="tooltip_text" translatable="yes">Insert an 
image</property>
-                                    <property name="action_name">edt.insert-image</property>
-                                    <property name="always_show_image">True</property>
-                                    <child>
-                                      <object class="GtkImage">
-                                        <property name="visible">True</property>
-                                        <property name="can_focus">False</property>
-                                        <property name="pixel_size">16</property>
-                                        <property name="icon_name">insert-image-symbolic</property>
-                                      </object>
-                                    </child>
+                                    <property name="can_focus">False</property>
+                                    <property name="pixel_size">16</property>
+                                    <property name="icon_name">insert-image-symbolic</property>
                                   </object>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">True</property>
-                                    <property name="position">1</property>
-                                  </packing>
                                 </child>
-                                <style>
-                                  <class name="linked"/>
-                                </style>
                               </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">1</property>
+                              </packing>
                             </child>
+                            <style>
+                              <class name="linked"/>
+                            </style>
                           </object>
                         </child>
                       </object>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]