font chooser: Add a tweak page

Add a button the dialog's header bar that lets us
switch to a second page where we can customize
the selected font.

Make the font chooser widget export an action that the
dialog can use for the button. This has some advantages:
- we can export not just the toggle state, but also enabled
- we can reuse the same enabled state to make the select
  button insensitive when no font is selected

To determine whether a font is selected, listen to changes
of the list selection. And ensure that the font chooser is
in an initial state when mapped, even if we close the dialog
from the tweak page.
This commit is contained in:
Matthias Clasen 2018-01-02 22:52:05 -05:00
parent 70bae02612
commit 15f8b2d0ae
5 changed files with 466 additions and 164 deletions

View File

@ -36,6 +36,9 @@
#include "gtkwidget.h"
#include "gtksettings.h"
#include "gtkdialogprivate.h"
#include "gtktogglebutton.h"
#include "gtkheaderbar.h"
#include "gtkactionable.h"
struct _GtkFontChooserDialogPrivate
{
@ -43,6 +46,7 @@ struct _GtkFontChooserDialogPrivate
GtkWidget *select_button;
GtkWidget *cancel_button;
GtkWidget *tweak_button;
};
/**
@ -136,6 +140,49 @@ gtk_font_chooser_dialog_key_press_event (GtkWidget *dialog,
return handled;
}
static void
setup_tweak_button (GtkFontChooserDialog *dialog)
{
gboolean use_header;
if (dialog->priv->tweak_button)
return;
g_object_get (dialog, "use-header-bar", &use_header, NULL);
if (use_header)
{
GtkWidget *button;
GtkWidget *header;
GActionGroup *actions;
actions = G_ACTION_GROUP (g_simple_action_group_new ());
g_action_map_add_action (G_ACTION_MAP (actions), gtk_font_chooser_widget_get_tweak_action (dialog->priv->fontchooser));
gtk_widget_insert_action_group (GTK_WIDGET (dialog), "font", actions);
g_object_unref (actions);
button = gtk_toggle_button_new ();
gtk_actionable_set_action_name (GTK_ACTIONABLE (button), "font.tweak");
gtk_widget_set_focus_on_click (button, FALSE);
gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
gtk_button_set_icon_name (GTK_BUTTON (button), "emblem-system-symbolic");
header = gtk_dialog_get_header_bar (GTK_DIALOG (dialog));
gtk_header_bar_pack_end (GTK_HEADER_BAR (header), button);
dialog->priv->tweak_button = button;
}
}
static void
gtk_font_chooser_dialog_map (GtkWidget *widget)
{
GtkFontChooserDialog *dialog = GTK_FONT_CHOOSER_DIALOG (widget);
setup_tweak_button (dialog);
GTK_WIDGET_CLASS (gtk_font_chooser_dialog_parent_class)->map (widget);
}
static void
gtk_font_chooser_dialog_class_init (GtkFontChooserDialogClass *klass)
{
@ -146,6 +193,7 @@ gtk_font_chooser_dialog_class_init (GtkFontChooserDialogClass *klass)
gobject_class->set_property = gtk_font_chooser_dialog_set_property;
widget_class->key_press_event = gtk_font_chooser_dialog_key_press_event;
widget_class->map = gtk_font_chooser_dialog_map;
_gtk_font_chooser_install_properties (gobject_class);
@ -155,6 +203,8 @@ gtk_font_chooser_dialog_class_init (GtkFontChooserDialogClass *klass)
"/org/gtk/libgtk/ui/gtkfontchooserdialog.ui");
gtk_widget_class_bind_template_child_private (widget_class, GtkFontChooserDialog, fontchooser);
gtk_widget_class_bind_template_child_private (widget_class, GtkFontChooserDialog, select_button);
gtk_widget_class_bind_template_child_private (widget_class, GtkFontChooserDialog, cancel_button);
gtk_widget_class_bind_template_callback (widget_class, font_activated_cb);
}
@ -169,11 +219,14 @@ gtk_font_chooser_dialog_init (GtkFontChooserDialog *fontchooserdiag)
gtk_widget_init_template (GTK_WIDGET (fontchooserdiag));
gtk_dialog_set_use_header_bar_from_setting (GTK_DIALOG (fontchooserdiag));
priv->select_button = gtk_dialog_get_widget_for_response (GTK_DIALOG (fontchooserdiag), GTK_RESPONSE_OK);
priv->cancel_button = gtk_dialog_get_widget_for_response (GTK_DIALOG (fontchooserdiag), GTK_RESPONSE_CANCEL);
_gtk_font_chooser_set_delegate (GTK_FONT_CHOOSER (fontchooserdiag),
GTK_FONT_CHOOSER (priv->fontchooser));
g_object_bind_property (gtk_font_chooser_widget_get_tweak_action (priv->fontchooser),
"enabled",
priv->select_button,
"sensitive",
G_BINDING_SYNC_CREATE);
}
/**

View File

@ -81,6 +81,7 @@
struct _GtkFontChooserWidgetPrivate
{
GtkWidget *stack;
GtkWidget *grid;
GtkWidget *search_entry;
GtkWidget *family_face_list;
@ -92,12 +93,15 @@ struct _GtkFontChooserWidgetPrivate
GtkTreeModel *filter_model;
GtkWidget *preview;
GtkWidget *preview2;
GtkWidget *font_name_label;
gchar *preview_text;
gboolean show_preview_entry;
GtkWidget *size_label;
GtkWidget *size_spin;
GtkWidget *size_slider;
GtkWidget *size_slider2;
PangoFontMap *font_map;
@ -111,6 +115,8 @@ struct _GtkFontChooserWidgetPrivate
guint last_fontconfig_timestamp;
GtkFontChooserLevel level;
GAction *tweak_action;
};
/* Keep in line with GtkTreeStore defined in gtkfontchooserwidget.ui */
@ -173,6 +179,8 @@ static void gtk_font_chooser_widget_cell_data_func (GtkTreeViewColum
static void gtk_font_chooser_widget_set_level (GtkFontChooserWidget *fontchooser,
GtkFontChooserLevel level);
static GtkFontChooserLevel gtk_font_chooser_widget_get_level (GtkFontChooserWidget *fontchooser);
static void selection_changed (GtkTreeSelection *selection,
GtkFontChooserWidget *fontchooser);
static void gtk_font_chooser_widget_iface_init (GtkFontChooserIface *iface);
@ -418,6 +426,7 @@ gtk_font_chooser_widget_update_marks (GtkFontChooserWidget *fontchooser)
}
gtk_scale_clear_marks (GTK_SCALE (priv->size_slider));
gtk_scale_clear_marks (GTK_SCALE (priv->size_slider2));
adj = gtk_range_get_adjustment (GTK_RANGE (priv->size_slider));
spin_adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (priv->size_spin));
@ -446,6 +455,9 @@ gtk_font_chooser_widget_update_marks (GtkFontChooserWidget *fontchooser)
gtk_scale_add_mark (GTK_SCALE (priv->size_slider),
sizes[i],
GTK_POS_BOTTOM, NULL);
gtk_scale_add_mark (GTK_SCALE (priv->size_slider2),
sizes[i],
GTK_POS_BOTTOM, NULL);
}
g_free (font_sizes);
@ -555,6 +567,7 @@ gtk_font_chooser_widget_update_preview_attributes (GtkFontChooserWidget *fontcho
pango_attr_list_insert (attrs, pango_attr_font_desc_new (priv->font_desc));
gtk_entry_set_attributes (GTK_ENTRY (priv->preview), attrs);
pango_attr_list_unref (attrs);
}
@ -562,11 +575,28 @@ static void
rows_changed_cb (GtkFontChooserWidget *fontchooser)
{
GtkFontChooserWidgetPrivate *priv = fontchooser->priv;
const char *page;
if (gtk_tree_model_iter_n_children (priv->filter_model, NULL) == 0)
gtk_stack_set_visible_child_name (GTK_STACK (priv->list_stack), "empty");
page = "empty";
else
gtk_stack_set_visible_child_name (GTK_STACK (priv->list_stack), "list");
page = "list";
if (strcmp (gtk_stack_get_visible_child_name (GTK_STACK (priv->list_stack)), page) != 0)
gtk_stack_set_visible_child_name (GTK_STACK (priv->list_stack), page);
}
static void
gtk_font_chooser_widget_map (GtkWidget *widget)
{
GtkFontChooserWidget *fontchooser = GTK_FONT_CHOOSER_WIDGET (widget);
GtkFontChooserWidgetPrivate *priv = fontchooser->priv;
gtk_entry_set_text (GTK_ENTRY (priv->search_entry), "");
gtk_stack_set_visible_child_name (GTK_STACK (priv->stack), "list");
g_simple_action_set_state (G_SIMPLE_ACTION (priv->tweak_action), g_variant_new_boolean (FALSE));
GTK_WIDGET_CLASS (gtk_font_chooser_widget_parent_class)->map (widget);
}
static void
@ -581,7 +611,7 @@ gtk_font_chooser_widget_measure (GtkWidget *widget,
GtkFontChooserWidget *self = GTK_FONT_CHOOSER_WIDGET (widget);
GtkFontChooserWidgetPrivate *priv = gtk_font_chooser_widget_get_instance_private (self);
gtk_widget_measure (priv->grid, orientation, for_size,
gtk_widget_measure (priv->stack, orientation, for_size,
minimum, natural,
minimum_baseline, natural_baseline);
}
@ -593,7 +623,7 @@ gtk_font_chooser_widget_snapshot (GtkWidget *widget,
GtkFontChooserWidget *self = GTK_FONT_CHOOSER_WIDGET (widget);
GtkFontChooserWidgetPrivate *priv = gtk_font_chooser_widget_get_instance_private (self);
gtk_widget_snapshot_child (widget, priv->grid, snapshot);
gtk_widget_snapshot_child (widget, priv->stack, snapshot);
}
static void
@ -607,7 +637,7 @@ gtk_font_chooser_widget_size_allocate (GtkWidget *widget,
GTK_WIDGET_CLASS (gtk_font_chooser_widget_parent_class)->size_allocate (widget, allocation, -1, out_clip);
gtk_widget_size_allocate (priv->grid, allocation, -1, out_clip);
gtk_widget_size_allocate (priv->stack, allocation, -1, out_clip);
}
static void
@ -616,10 +646,10 @@ gtk_font_chooser_widget_dispose (GObject *object)
GtkFontChooserWidget *self = GTK_FONT_CHOOSER_WIDGET (object);
GtkFontChooserWidgetPrivate *priv = gtk_font_chooser_widget_get_instance_private (self);
if (priv->grid)
if (priv->stack)
{
gtk_widget_unparent (priv->grid);
priv->grid = NULL;
gtk_widget_unparent (priv->stack);
priv->stack = NULL;
}
G_OBJECT_CLASS (gtk_font_chooser_widget_parent_class)->dispose (object);
@ -638,6 +668,7 @@ gtk_font_chooser_widget_class_init (GtkFontChooserWidgetClass *klass)
widget_class->measure = gtk_font_chooser_widget_measure;
widget_class->size_allocate = gtk_font_chooser_widget_size_allocate;
widget_class->snapshot = gtk_font_chooser_widget_snapshot;
widget_class->map = gtk_font_chooser_widget_map;
gobject_class->finalize = gtk_font_chooser_widget_finalize;
gobject_class->dispose = gtk_font_chooser_widget_dispose;
@ -659,10 +690,14 @@ gtk_font_chooser_widget_class_init (GtkFontChooserWidgetClass *klass)
gtk_widget_class_bind_template_child_private (widget_class, GtkFontChooserWidget, model);
gtk_widget_class_bind_template_child_private (widget_class, GtkFontChooserWidget, filter_model);
gtk_widget_class_bind_template_child_private (widget_class, GtkFontChooserWidget, preview);
gtk_widget_class_bind_template_child_private (widget_class, GtkFontChooserWidget, preview2);
gtk_widget_class_bind_template_child_private (widget_class, GtkFontChooserWidget, size_label);
gtk_widget_class_bind_template_child_private (widget_class, GtkFontChooserWidget, size_spin);
gtk_widget_class_bind_template_child_private (widget_class, GtkFontChooserWidget, size_slider);
gtk_widget_class_bind_template_child_private (widget_class, GtkFontChooserWidget, size_slider2);
gtk_widget_class_bind_template_child_private (widget_class, GtkFontChooserWidget, stack);
gtk_widget_class_bind_template_child_private (widget_class, GtkFontChooserWidget, grid);
gtk_widget_class_bind_template_child_private (widget_class, GtkFontChooserWidget, font_name_label);
gtk_widget_class_bind_template_callback (widget_class, text_changed_cb);
gtk_widget_class_bind_template_callback (widget_class, stop_search_cb);
@ -673,10 +708,33 @@ gtk_font_chooser_widget_class_init (GtkFontChooserWidgetClass *klass)
gtk_widget_class_bind_template_callback (widget_class, rows_changed_cb);
gtk_widget_class_bind_template_callback (widget_class, size_change_cb);
gtk_widget_class_bind_template_callback (widget_class, output_cb);
gtk_widget_class_bind_template_callback (widget_class, selection_changed);
gtk_widget_class_set_css_name (widget_class, I_("fontchooser"));
}
static void
change_tweak (GSimpleAction *action,
GVariant *state,
gpointer data)
{
GtkFontChooserWidget *fontchooser = data;
gboolean tweak = g_variant_get_boolean (state);
if (tweak)
{
gtk_entry_grab_focus_without_selecting (GTK_ENTRY (fontchooser->priv->preview2));
gtk_stack_set_visible_child_name (GTK_STACK (fontchooser->priv->stack), "tweaks");
}
else
{
gtk_entry_grab_focus_without_selecting (GTK_ENTRY (fontchooser->priv->search_entry));
gtk_stack_set_visible_child_name (GTK_STACK (fontchooser->priv->stack), "list");
}
g_simple_action_set_state (action, state);
}
static void
gtk_font_chooser_widget_init (GtkFontChooserWidget *fontchooser)
{
@ -715,6 +773,9 @@ gtk_font_chooser_widget_init (GtkFontChooserWidget *fontchooser)
fontchooser,
NULL);
priv->tweak_action = G_ACTION (g_simple_action_new_stateful ("tweak", NULL, g_variant_new_boolean (FALSE)));
g_signal_connect (priv->tweak_action, "change-state", G_CALLBACK (change_tweak), fontchooser);
/* Load data and set initial style-dependent parameters */
gtk_font_chooser_widget_load_fonts (fontchooser, TRUE);
gtk_font_chooser_widget_set_cell_size (fontchooser);
@ -1022,6 +1083,8 @@ gtk_font_chooser_widget_finalize (GObject *object)
g_clear_object (&priv->font_map);
g_object_unref (priv->tweak_action);
G_OBJECT_CLASS (gtk_font_chooser_widget_parent_class)->finalize (object);
}
@ -1080,7 +1143,7 @@ gtk_font_chooser_widget_find_font (GtkFontChooserWidget *fontchooser,
pango_font_description_free (merged);
g_object_unref (family);
}
return valid;
}
@ -1158,20 +1221,36 @@ static gint
gtk_font_chooser_widget_get_size (GtkFontChooser *chooser)
{
GtkFontChooserWidget *fontchooser = GTK_FONT_CHOOSER_WIDGET (chooser);
PangoFontDescription *desc = gtk_font_chooser_widget_get_font_desc (fontchooser);
return pango_font_description_get_size (fontchooser->priv->font_desc);
if (desc)
return pango_font_description_get_size (desc);
return -1;
}
static gchar *
gtk_font_chooser_widget_get_font (GtkFontChooserWidget *fontchooser)
{
return pango_font_description_to_string (fontchooser->priv->font_desc);
PangoFontDescription *desc = gtk_font_chooser_widget_get_font_desc (fontchooser);
if (desc)
return pango_font_description_to_string (desc);
return NULL;
}
static PangoFontDescription *
gtk_font_chooser_widget_get_font_desc (GtkFontChooserWidget *fontchooser)
{
return fontchooser->priv->font_desc;
GtkFontChooserWidgetPrivate *priv = fontchooser->priv;
GtkTreeSelection *selection;
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->family_face_list));
if (gtk_tree_selection_count_selected_rows (selection) > 0)
return fontchooser->priv->font_desc;
return NULL;
}
static void
@ -1184,13 +1263,77 @@ gtk_font_chooser_widget_set_font (GtkFontChooserWidget *fontchooser,
gtk_font_chooser_widget_take_font_desc (fontchooser, font_desc);
}
static void
gtk_font_chooser_widget_update_font_name (GtkFontChooserWidget *fontchooser,
GtkTreeSelection *selection)
{
GtkFontChooserWidgetPrivate *priv = fontchooser->priv;
GtkTreeModel *model;
GtkTreeIter iter;
PangoFontFamily *family;
PangoFontFace *face;
GtkDelayedFontDescription *desc;
const PangoFontDescription *font_desc;
PangoAttrList *attrs;
const char *fam_name;
const char *face_name;
char *title;
gtk_tree_selection_get_selected (selection, &model, &iter);
gtk_tree_model_get (model, &iter,
FAMILY_COLUMN, &family,
FACE_COLUMN, &face,
FONT_DESC_COLUMN, &desc,
-1);
fam_name = pango_font_family_get_name (family);
face_name = pango_font_face_get_face_name (face);
font_desc = gtk_delayed_font_description_get (desc);
g_object_unref (family);
g_object_unref (face);
if (priv->level == GTK_FONT_CHOOSER_LEVEL_FAMILY)
title = g_strdup (fam_name);
else
title = g_strconcat (fam_name, " ", face_name, NULL);
attrs = gtk_font_chooser_widget_get_preview_attributes (fontchooser, font_desc);
gtk_label_set_attributes (GTK_LABEL (priv->font_name_label), attrs);
pango_attr_list_unref (attrs);
gtk_label_set_label (GTK_LABEL (priv->font_name_label), title);
g_free (title);
}
static void
selection_changed (GtkTreeSelection *selection,
GtkFontChooserWidget *fontchooser)
{
GtkFontChooserWidgetPrivate *priv = fontchooser->priv;
g_object_notify (G_OBJECT (fontchooser), "font");
g_object_notify (G_OBJECT (fontchooser), "font-desc");
if (gtk_tree_selection_count_selected_rows (selection) > 0)
{
gtk_font_chooser_widget_update_font_name (fontchooser, selection);
g_simple_action_set_enabled (G_SIMPLE_ACTION (priv->tweak_action), TRUE);
}
else
{
g_simple_action_set_state (G_SIMPLE_ACTION (priv->tweak_action), g_variant_new_boolean (FALSE));
g_simple_action_set_enabled (G_SIMPLE_ACTION (priv->tweak_action), FALSE);
}
}
static void
gtk_font_chooser_widget_ensure_selection (GtkFontChooserWidget *fontchooser)
{
GtkFontChooserWidgetPrivate *priv = fontchooser->priv;
GtkTreeSelection *selection;
GtkTreeIter filter_iter;
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->family_face_list));
if (gtk_list_store_iter_is_valid (GTK_LIST_STORE (priv->model), &priv->font_iter) &&
@ -1450,3 +1593,10 @@ gtk_font_chooser_widget_handle_event (GtkWidget *widget,
return gtk_search_entry_handle_event (GTK_SEARCH_ENTRY (priv->search_entry), event);
}
GAction *
gtk_font_chooser_widget_get_tweak_action (GtkWidget *widget)
{
return GTK_FONT_CHOOSER_WIDGET (widget)->priv->tweak_action;
}

View File

@ -25,6 +25,8 @@ G_BEGIN_DECLS
gboolean gtk_font_chooser_widget_handle_event (GtkWidget *widget,
GdkEventKey *event);
GAction *gtk_font_chooser_widget_get_tweak_action (GtkWidget *fontchooser);
G_END_DECLS
#endif /* __GTK_FONT_CHOOSER_WIDGET_PRIVATE_H__ */

View File

@ -27,7 +27,7 @@
</object>
</child>
<child type="action">
<object class="GtkButton" id="ok_button">
<object class="GtkButton" id="select_button">
<property name="label" translatable="yes">_Select</property>
<property name="use-underline">1</property>
<property name="can-default">1</property>
@ -35,7 +35,7 @@
</child>
<action-widgets>
<action-widget response="cancel">cancel_button</action-widget>
<action-widget response="ok" default="true">ok_button</action-widget>
<action-widget response="ok" default="true">select_button</action-widget>
</action-widgets>
</template>
</interface>

View File

@ -32,176 +32,273 @@
</object>
<template class="GtkFontChooserWidget" parent="GtkWidget">
<child>
<object class="GtkGrid" id="grid">
<property name="row-spacing">6</property>
<property name="column-spacing">6</property>
<object class="GtkStack" id="stack">
<child>
<object class="GtkSearchEntry" id="search_entry">
<property name="can-focus">1</property>
<property name="hexpand">1</property>
<property name="activates-default">1</property>
<property name="primary-icon-name">edit-find-symbolic</property>
<property name="primary-icon-activatable">0</property>
<property name="secondary-icon-activatable">0</property>
<property name="primary-icon-sensitive">0</property>
<property name="secondary-icon-sensitive">0</property>
<property name="placeholder-text" translatable="yes">Search font name</property>
<signal name="search-changed" handler="text_changed_cb" swapped="no"/>
<signal name="stop-search" handler="stop_search_cb" swapped="no"/>
<object class="GtkGrid" id="grid">
<property name="row-spacing">6</property>
<property name="column-spacing">6</property>
<child>
<object class="GtkSearchEntry" id="search_entry">
<property name="can-focus">1</property>
<property name="hexpand">1</property>
<property name="activates-default">1</property>
<property name="primary-icon-name">edit-find-symbolic</property>
<property name="primary-icon-activatable">0</property>
<property name="secondary-icon-activatable">0</property>
<property name="primary-icon-sensitive">0</property>
<property name="secondary-icon-sensitive">0</property>
<property name="placeholder-text" translatable="yes">Search font name</property>
<signal name="search-changed" handler="text_changed_cb" swapped="no"/>
<signal name="stop-search" handler="stop_search_cb" swapped="no"/>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkStack" id="list_stack">
<child>
<object class="GtkGrid" id="font_grid">
<property name="row-spacing">6</property>
<property name="column-spacing">6</property>
<child>
<object class="GtkScrolledWindow" id="list_scrolled_window">
<property name="width-request">400</property>
<property name="height-request">300</property>
<property name="can-focus">1</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="hscrollbar-policy">never</property>
<property name="shadow-type">etched-in</property>
<child>
<object class="GtkTreeView" id="family_face_list">
<property name="can-focus">1</property>
<property name="model">filter_model</property>
<property name="headers-visible">0</property>
<property name="enable-search">0</property>
<property name="fixed-height-mode">1</property>
<signal name="cursor-changed" handler="cursor_changed_cb" swapped="no"/>
<signal name="row-activated" handler="row_activated_cb" swapped="no"/>
<signal name="style-updated" handler="gtk_font_chooser_widget_set_cell_size" object="GtkFontChooserWidget" after="yes" swapped="yes"/>
<child internal-child="selection">
<object class="GtkTreeSelection" id="treeview-selection1">
<property name="mode">browse</property>
<signal name="changed" handler="selection_changed"/>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="family_face_column">
<property name="sizing">fixed</property>
<property name="title" translatable="yes">Font Family</property>
<child>
<object class="GtkCellRendererText" id="family_face_cell">
<property name="ellipsize">end</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
<property name="width">3</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="preview">
<property name="can-focus">1</property>
<property name="placeholder-text" translatable="yes">Preview text</property>
<signal name="scroll-event" handler="resize_by_scroll_cb" swapped="no"/>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">2</property>
<property name="width">3</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="size_label">
<property name="label" translatable="yes">Size</property>
<property name="xalign">0</property>
<property name="valign">baseline</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">3</property>
</packing>
</child>
<child>
<object class="GtkScale" id="size_slider">
<property name="can-focus">1</property>
<property name="hexpand">1</property>
<property name="adjustment">slider_adjustment</property>
<property name="draw-value">0</property>
<property name="round-digits">0</property>
<signal name="scroll-event" handler="resize_by_scroll_cb" swapped="no"/>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">3</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="size_spin">
<property name="can-focus">1</property>
<property name="adjustment">spin_adjustment</property>
<signal name="output" handler="output_cb"/>
</object>
<packing>
<property name="left-attach">2</property>
<property name="top-attach">3</property>
</packing>
</child>
</object>
<packing>
<property name="name">list</property>
</packing>
</child>
<child>
<object class="GtkGrid">
<property name="row-spacing">12</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<style>
<class name="dim-label"/>
</style>
<child>
<object class="GtkImage">
<property name="gicon">fonticon</property>
<property name="pixel-size">64</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">No Fonts Found</property>
<attributes>
<attribute name="weight" value="bold"/>
<attribute name="scale" value="1.2"/>
</attributes>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</packing>
</child>
</object>
<packing>
<property name="name">empty</property>
</packing>
</child>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</packing>
</child>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
<property name="width">2</property>
<property name="name">list</property>
</packing>
</child>
<child>
<object class="GtkStack" id="list_stack">
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkGrid">
<property name="row-spacing">6</property>
<property name="column-spacing">6</property>
<object class="GtkLabel" id="font_name_label">
<property name="margin-top">6</property>
<property name="margin-bottom">6</property>
<property name="margin-start">12</property>
<property name="margin-end">12</property>
<property name="ellipsize">end</property>
<property name="xalign">0</property>
</object>
</child>
<child>
<object class="GtkEntry" id="preview2">
<property name="can-focus">1</property>
<property name="placeholder-text" translatable="yes">Preview text</property>
<property name="text" bind-source="preview" bind-property="text" bind-flags="bidirectional"/>
<property name="attributes" bind-source="preview" bind-property="attributes" bind-flags="bidirectional"/>
<signal name="scroll-event" handler="resize_by_scroll_cb" swapped="no"/>
</object>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="hscrollbar-policy">never</property>
<property name="shadow-type">in</property>
<property name="vexpand">1</property>
<style>
<class name="view"/>
</style>
<child>
<object class="GtkScrolledWindow" id="list_scrolled_window">
<property name="width-request">400</property>
<property name="height-request">300</property>
<property name="can-focus">1</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="hscrollbar-policy">never</property>
<property name="shadow-type">etched-in</property>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="spacing">12</property>
<property name="margin">12</property>
<child>
<object class="GtkTreeView" id="family_face_list">
<property name="can-focus">1</property>
<property name="model">filter_model</property>
<property name="headers-visible">0</property>
<property name="enable-search">0</property>
<property name="fixed-height-mode">1</property>
<signal name="cursor-changed" handler="cursor_changed_cb" swapped="no"/>
<signal name="row-activated" handler="row_activated_cb" swapped="no"/>
<signal name="style-updated" handler="gtk_font_chooser_widget_set_cell_size" object="GtkFontChooserWidget" after="yes" swapped="yes"/>
<child internal-child="selection">
<object class="GtkTreeSelection" id="treeview-selection1">
<property name="mode">browse</property>
<object class="GtkBox">
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="size_label2">
<property name="label" translatable="yes">Size</property>
<property name="xalign">0</property>
<property name="valign">baseline</property>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="family_face_column">
<property name="sizing">fixed</property>
<property name="title" translatable="yes">Font Family</property>
<object class="GtkScale" id="size_slider2">
<property name="can-focus">1</property>
<property name="hexpand">1</property>
<property name="adjustment">slider_adjustment</property>
<property name="draw-value">0</property>
<property name="round-digits">0</property>
<signal name="scroll-event" handler="resize_by_scroll_cb" swapped="no"/>
</object>
</child>
<child>
<object class="GtkSpinButton" id="size_spin2">
<property name="can-focus">1</property>
<property name="adjustment">spin_adjustment</property>
<signal name="output" handler="output_cb"/>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox" id="feature_box">
<property name="orientation">vertical</property>
<property name="spacing">12</property>
<child>
<object class="GtkComboBox" id="feature_language_combo">
<property name="halign">start</property>
<property name="margin-top">10</property>
<child>
<object class="GtkCellRendererText" id="family_face_cell">
<property name="ellipsize">end</property>
</object>
<object class="GtkCellRendererText"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
<property name="width">3</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="preview">
<property name="can-focus">1</property>
<property name="placeholder-text" translatable="yes">Preview text</property>
<signal name="scroll-event" handler="resize_by_scroll_cb" swapped="no"/>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">2</property>
<property name="width">3</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="size_label">
<property name="visible">1</property>
<property name="label" translatable="yes">Size</property>
<property name="xalign">0</property>
<property name="valign">baseline</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">3</property>
</packing>
</child>
<child>
<object class="GtkScale" id="size_slider">
<property name="can-focus">1</property>
<property name="hexpand">1</property>
<property name="adjustment">slider_adjustment</property>
<property name="draw-value">0</property>
<property name="round-digits">0</property>
<signal name="scroll-event" handler="resize_by_scroll_cb" swapped="no"/>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">3</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="size_spin">
<property name="can-focus">1</property>
<property name="adjustment">spin_adjustment</property>
<signal name="output" handler="output_cb"/>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">3</property>
</packing>
</child>
</object>
<packing>
<property name="name">list</property>
</packing>
</child>
<child>
<object class="GtkGrid">
<property name="row-spacing">12</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<style>
<class name="dim-label"/>
</style>
<child>
<object class="GtkImage">
<property name="gicon">fonticon</property>
<property name="pixel-size">64</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">No Fonts Found</property>
<attributes>
<attribute name="weight" value="bold"/>
<attribute name="scale" value="1.2"/>
</attributes>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</packing>
</child>
</object>
<packing>
<property name="name">empty</property>
</packing>
</child>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
<property name="width">2</property>
<property name="name">tweaks</property>
</packing>
</child>
</object>