summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2022-06-30 23:23:04 +0000
committerMatthias Clasen <mclasen@redhat.com>2022-06-30 23:23:04 +0000
commit091daf4cff6b6c1218da1747cc470973a9d661b2 (patch)
tree429097a61af0b369dca951f27dac9d98e2556c8e
parent21b9667f08eea27503bb4ec562d1b05f84eaa40a (diff)
parent64f3ac676014a0555f6684ebd824b228f6a7a2e3 (diff)
downloadgtk+-091daf4cff6b6c1218da1747cc470973a9d661b2.tar.gz
Merge branch 'matthiasc/for-main' into 'main'
Add gtk_builder_cscope_add_callback See merge request GNOME/gtk!4843
-rw-r--r--demos/gtk-demo/demo.gresource.xml2
-rw-r--r--demos/gtk-demo/font_features.c532
-rw-r--r--demos/gtk-demo/font_features.ui (renamed from demos/gtk-demo/font-features.ui)142
-rw-r--r--gtk/gtkbuilderscope.c13
-rw-r--r--gtk/gtkbuilderscope.h8
5 files changed, 399 insertions, 298 deletions
diff --git a/demos/gtk-demo/demo.gresource.xml b/demos/gtk-demo/demo.gresource.xml
index 849ef462dc..fd2d62a09a 100644
--- a/demos/gtk-demo/demo.gresource.xml
+++ b/demos/gtk-demo/demo.gresource.xml
@@ -376,7 +376,7 @@
<file>glarea-gles.vs.glsl</file>
</gresource>
<gresource prefix="/font_features">
- <file>font-features.ui</file>
+ <file>font_features.ui</file>
<file>fontplane.c</file>
</gresource>
<gresource prefix="/spinbutton">
diff --git a/demos/gtk-demo/font_features.c b/demos/gtk-demo/font_features.c
index 6fbaf2eec9..035039a724 100644
--- a/demos/gtk-demo/font_features.c
+++ b/demos/gtk-demo/font_features.c
@@ -24,24 +24,69 @@
#define MAKE_TAG(a,b,c,d) (unsigned int)(((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
-static GtkWidget *the_label;
-static GtkWidget *settings;
-static GtkWidget *description;
-static GtkWidget *font;
-static GtkWidget *script_lang;
-static GtkWidget *resetbutton;
-static GtkWidget *stack;
-static GtkWidget *the_entry;
-static GtkWidget *variations_heading;
-static GtkWidget *variations_grid;
-static GtkWidget *instance_combo;
-static GtkWidget *edit_toggle;
-static GtkAdjustment *size_adjustment;
-static GtkAdjustment *letterspacing_adjustment;
-static GtkAdjustment *line_height_adjustment;
-static GtkWidget *size_entry;
-static GtkWidget *letterspacing_entry;
-static GtkWidget *line_height_entry;
+typedef struct {
+ unsigned int tag;
+ const char *name;
+ GtkWidget *icon;
+ GtkWidget *dflt;
+ GtkWidget *feat;
+} FeatureItem;
+
+typedef struct {
+ unsigned int start;
+ unsigned int end;
+ PangoFontDescription *desc;
+ char *features;
+ PangoLanguage *language;
+} Range;
+
+typedef struct {
+ guint32 tag;
+ GtkAdjustment *adjustment;
+ double default_value;
+ guint tick_cb;
+ guint64 start_time;
+ gboolean increasing;
+} Axis;
+
+typedef struct {
+ GtkWidget *the_label;
+ GtkWidget *settings;
+ GtkWidget *description;
+ GtkWidget *font;
+ GtkWidget *script_lang;
+ GtkWidget *feature_list;
+ GtkWidget *variations_grid;
+ GtkWidget *instance_combo;
+ GtkWidget *stack;
+ GtkWidget *the_entry;
+ GtkWidget *edit_toggle;
+ GtkAdjustment *size_adjustment;
+ GtkAdjustment *letterspacing_adjustment;
+ GtkAdjustment *line_height_adjustment;
+ GtkWidget *size_entry;
+ GtkWidget *letterspacing_entry;
+ GtkWidget *line_height_entry;
+ GList *feature_items;
+ GList *ranges;
+ GHashTable *instances;
+ GHashTable *axes;
+} FontFeaturesDemo;
+
+static void
+demo_free (gpointer data)
+{
+ FontFeaturesDemo *demo = data;
+
+ g_list_free_full (demo->feature_items, g_free);
+ g_list_free_full (demo->ranges, g_free);
+ g_clear_pointer (&demo->instances, g_hash_table_unref);
+ g_clear_pointer (&demo->axes, g_hash_table_unref);
+
+ g_free (demo);
+}
+
+static FontFeaturesDemo *demo;
static void update_display (void);
@@ -94,25 +139,24 @@ basic_entry_activated (GtkEntry *entry,
gtk_adjustment_set_value (adjustment, value);
}
-typedef struct {
- unsigned int tag;
- const char *name;
- GtkWidget *icon;
- GtkWidget *dflt;
- GtkWidget *feat;
-} FeatureItem;
-
-static GList *feature_items;
+static void
+font_features_reset_basic (void)
+{
+ gtk_adjustment_set_value (demo->size_adjustment, 20);
+ gtk_adjustment_set_value (demo->letterspacing_adjustment, 0);
+ gtk_adjustment_set_value (demo->line_height_adjustment, 1);
+}
-typedef struct {
- unsigned int start;
- unsigned int end;
+static void
+update_basic (void)
+{
PangoFontDescription *desc;
- char *features;
- PangoLanguage *language;
-} Range;
-static GList *ranges;
+ desc = gtk_font_chooser_get_font_desc (GTK_FONT_CHOOSER (demo->font));
+
+ gtk_adjustment_set_value (demo->size_adjustment,
+ pango_font_description_get_size (desc) / (double) PANGO_SCALE);
+}
static void add_font_variations (GString *s);
@@ -155,7 +199,7 @@ ensure_range (unsigned int start,
GList *l;
Range *range;
- for (l = ranges; l; l = l->next)
+ for (l = demo->ranges; l; l = l->next)
{
Range *r = l->data;
@@ -170,7 +214,7 @@ ensure_range (unsigned int start,
range->start = start;
range->end = end;
- ranges = g_list_insert_sorted (ranges, range, compare_range);
+ demo->ranges = g_list_insert_sorted (demo->ranges, range, compare_range);
set:
if (range->desc)
@@ -299,7 +343,7 @@ add_check_group (GtkWidget *box,
item->dflt = NULL;
item->feat = feat;
- feature_items = g_list_prepend (feature_items, item);
+ demo->feature_items = g_list_prepend (demo->feature_items, item);
}
gtk_box_append (GTK_BOX (box), group);
@@ -357,7 +401,7 @@ add_radio_group (GtkWidget *box,
item->dflt = NULL;
item->feat = feat;
- feature_items = g_list_prepend (feature_items, item);
+ demo->feature_items = g_list_prepend (demo->feature_items, item);
}
gtk_box_append (GTK_BOX (box), group);
@@ -382,9 +426,9 @@ update_display (void)
char *features;
double value;
- text = gtk_editable_get_text (GTK_EDITABLE (the_entry));
+ text = gtk_editable_get_text (GTK_EDITABLE (demo->the_entry));
- if (gtk_label_get_selection_bounds (GTK_LABEL (the_label), &ins, &bound))
+ if (gtk_label_get_selection_bounds (GTK_LABEL (demo->the_label), &ins, &bound))
{
start = g_utf8_offset_to_pointer (text, ins) - text;
end = g_utf8_offset_to_pointer (text, bound) - text;
@@ -395,9 +439,9 @@ update_display (void)
end = PANGO_ATTR_INDEX_TO_TEXT_END;
}
- desc = gtk_font_chooser_get_font_desc (GTK_FONT_CHOOSER (font));
+ desc = gtk_font_chooser_get_font_desc (GTK_FONT_CHOOSER (demo->font));
- value = gtk_adjustment_get_value (size_adjustment);
+ value = gtk_adjustment_get_value (demo->size_adjustment);
pango_font_description_set_size (desc, value * PANGO_SCALE);
s = g_string_new ("");
@@ -413,7 +457,7 @@ update_display (void)
s = g_string_new ("");
has_feature = FALSE;
- for (l = feature_items; l; l = l->next)
+ for (l = demo->feature_items; l; l = l->next)
{
FeatureItem *item = l->data;
@@ -453,11 +497,11 @@ update_display (void)
features = g_string_free (s, FALSE);
- if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (script_lang), &iter))
+ if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (demo->script_lang), &iter))
{
hb_tag_t lang_tag;
- model = gtk_combo_box_get_model (GTK_COMBO_BOX (script_lang));
+ model = gtk_combo_box_get_model (GTK_COMBO_BOX (demo->script_lang));
gtk_tree_model_get (model, &iter,
3, &lang_tag,
-1);
@@ -471,23 +515,23 @@ update_display (void)
attrs = pango_attr_list_new ();
- if (gtk_adjustment_get_value (letterspacing_adjustment) != 0.)
+ if (gtk_adjustment_get_value (demo->letterspacing_adjustment) != 0.)
{
- attr = pango_attr_letter_spacing_new (gtk_adjustment_get_value (letterspacing_adjustment));
+ attr = pango_attr_letter_spacing_new (gtk_adjustment_get_value (demo->letterspacing_adjustment));
attr->start_index = start;
attr->end_index = end;
pango_attr_list_insert (attrs, attr);
}
- if (gtk_adjustment_get_value (line_height_adjustment) != 1.)
+ if (gtk_adjustment_get_value (demo->line_height_adjustment) != 1.)
{
- attr = pango_attr_line_height_new (gtk_adjustment_get_value (line_height_adjustment));
+ attr = pango_attr_line_height_new (gtk_adjustment_get_value (demo->line_height_adjustment));
attr->start_index = start;
attr->end_index = end;
pango_attr_list_insert (attrs, attr);
}
- for (l = ranges; l; l = l->next)
+ for (l = demo->ranges; l; l = l->next)
{
Range *range = l->data;
@@ -510,10 +554,10 @@ update_display (void)
}
}
- gtk_label_set_text (GTK_LABEL (description), font_desc);
- gtk_label_set_text (GTK_LABEL (settings), features);
- gtk_label_set_text (GTK_LABEL (the_label), text);
- gtk_label_set_attributes (GTK_LABEL (the_label), attrs);
+ gtk_label_set_text (GTK_LABEL (demo->description), font_desc);
+ gtk_label_set_text (GTK_LABEL (demo->settings), features);
+ gtk_label_set_text (GTK_LABEL (demo->the_label), text);
+ gtk_label_set_attributes (GTK_LABEL (demo->the_label), attrs);
g_free (font_desc);
pango_font_description_free (desc);
@@ -527,8 +571,8 @@ get_pango_font (void)
PangoFontDescription *desc;
PangoContext *context;
- desc = gtk_font_chooser_get_font_desc (GTK_FONT_CHOOSER (font));
- context = gtk_widget_get_pango_context (font);
+ desc = gtk_font_chooser_get_font_desc (GTK_FONT_CHOOSER (demo->font));
+ context = gtk_widget_get_pango_context (demo->font);
return pango_context_load_font (context, desc);
}
@@ -592,7 +636,7 @@ update_script_combo (void)
GtkTreeIter active_iter;
gboolean have_active = FALSE;
- lang = gtk_font_chooser_get_language (GTK_FONT_CHOOSER (font));
+ lang = gtk_font_chooser_get_language (GTK_FONT_CHOOSER (demo->font));
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
active = hb_ot_tag_from_language (hb_language_from_string (lang, -1));
@@ -693,11 +737,11 @@ update_script_combo (void)
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store),
GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
GTK_SORT_ASCENDING);
- gtk_combo_box_set_model (GTK_COMBO_BOX (script_lang), GTK_TREE_MODEL (store));
+ gtk_combo_box_set_model (GTK_COMBO_BOX (demo->script_lang), GTK_TREE_MODEL (store));
if (have_active)
- gtk_combo_box_set_active_iter (GTK_COMBO_BOX (script_lang), &active_iter);
+ gtk_combo_box_set_active_iter (GTK_COMBO_BOX (demo->script_lang), &active_iter);
else
- gtk_combo_box_set_active_iter (GTK_COMBO_BOX (script_lang), 0);
+ gtk_combo_box_set_active_iter (GTK_COMBO_BOX (demo->script_lang), 0);
}
static void
@@ -714,10 +758,10 @@ update_features (void)
/* set feature presence checks from the font features */
- if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (script_lang), &iter))
+ if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (demo->script_lang), &iter))
return;
- model = gtk_combo_box_get_model (GTK_COMBO_BOX (script_lang));
+ model = gtk_combo_box_get_model (GTK_COMBO_BOX (demo->script_lang));
gtk_tree_model_get (model, &iter,
1, &script_index,
2, &lang_index,
@@ -726,7 +770,7 @@ update_features (void)
if (lang_tag == 0) /* None is selected */
{
- for (l = feature_items; l; l = l->next)
+ for (l = demo->feature_items; l; l = l->next)
{
FeatureItem *item = l->data;
gtk_widget_show (item->feat);
@@ -738,7 +782,7 @@ update_features (void)
return;
}
- for (l = feature_items; l; l = l->next)
+ for (l = demo->feature_items; l; l = l->next)
{
FeatureItem *item = l->data;
gtk_widget_hide (item->feat);
@@ -779,7 +823,7 @@ update_features (void)
buf[4] = 0;
g_print ("%s present in %s\n", buf, i == 0 ? "GSUB" : "GPOS");
#endif
- for (l = feature_items; l; l = l->next)
+ for (l = demo->feature_items; l; l = l->next)
{
FeatureItem *item = l->data;
@@ -804,10 +848,10 @@ update_features (void)
}
}
- feat = gtk_font_chooser_get_font_features (GTK_FONT_CHOOSER (font));
+ feat = gtk_font_chooser_get_font_features (GTK_FONT_CHOOSER (demo->font));
if (feat)
{
- for (l = feature_items; l; l = l->next)
+ for (l = demo->feature_items; l; l = l->next)
{
FeatureItem *item = l->data;
char buf[5];
@@ -867,12 +911,18 @@ entry_activated (GtkEntry *entry,
static void unset_instance (GtkAdjustment *adjustment);
-typedef struct {
- guint32 tag;
- GtkAdjustment *adjustment;
-} Axis;
+static void
+font_features_reset_variations (void)
+{
+ GHashTableIter iter;
+ Axis *axis;
-static GHashTable *axes;
+ g_hash_table_iter_init (&iter, demo->axes);
+ while (g_hash_table_iter_next (&iter, (gpointer *)NULL, (gpointer *)&axis))
+ {
+ gtk_adjustment_set_value (axis->adjustment, axis->default_value);
+ }
+}
static void
add_font_variations (GString *s)
@@ -882,7 +932,7 @@ add_font_variations (GString *s)
char buf[G_ASCII_DTOSTR_BUF_SIZE];
const char *sep = "";
- g_hash_table_iter_init (&iter, axes);
+ g_hash_table_iter_init (&iter, demo->axes);
while (g_hash_table_iter_next (&iter, (gpointer *)NULL, (gpointer *)&axis))
{
char tag[5];
@@ -914,6 +964,73 @@ axes_equal (gconstpointer v1, gconstpointer v2)
return p1->tag == p2->tag;
}
+static double
+ease_out_cubic (double t)
+{
+ double p = t - 1;
+
+ return p * p * p + 1;
+}
+
+static gboolean
+animate_axis (GtkWidget *widget,
+ GdkFrameClock *frame_clock,
+ gpointer data)
+{
+ Axis *axis = data;
+ guint64 now;
+ double upper, lower, value;
+
+ now = g_get_monotonic_time ();
+
+ if (now >= axis->start_time + G_TIME_SPAN_SECOND)
+ {
+ axis->start_time += G_TIME_SPAN_SECOND;
+ axis->increasing = !axis->increasing;
+ }
+
+ value = (now - axis->start_time) / (double) G_TIME_SPAN_SECOND;
+
+ value = ease_out_cubic (value);
+
+ lower = gtk_adjustment_get_lower (axis->adjustment);
+ upper = gtk_adjustment_get_upper (axis->adjustment);
+
+ if (axis->increasing)
+ gtk_adjustment_set_value (axis->adjustment, lower + (upper - lower) * value);
+ else
+ gtk_adjustment_set_value (axis->adjustment, upper - (upper - lower) * value);
+
+ return G_SOURCE_CONTINUE;
+}
+
+static void
+start_axis_animation (GtkButton *button,
+ gpointer data)
+{
+ Axis *axis = data;
+
+ if (axis->tick_cb)
+ {
+ gtk_widget_remove_tick_callback (GTK_WIDGET (button), axis->tick_cb);
+ axis->tick_cb = 0;
+ gtk_button_set_icon_name (button, "media-playback-start");
+ }
+ else
+ {
+ double value, upper, lower;
+
+ gtk_button_set_icon_name (button, "media-playback-stop");
+ axis->tick_cb = gtk_widget_add_tick_callback (GTK_WIDGET (button), animate_axis, axis, NULL);
+ value = gtk_adjustment_get_value (axis->adjustment);
+ lower = gtk_adjustment_get_lower (axis->adjustment);
+ upper = gtk_adjustment_get_upper (axis->adjustment);
+ value = value / (upper - lower);
+ axis->start_time = g_get_monotonic_time () - value * G_TIME_SPAN_SECOND;
+ axis->increasing = TRUE;
+ }
+}
+
static void
add_axis (hb_face_t *hb_face,
hb_ot_var_axis_info_t *ax,
@@ -927,13 +1044,14 @@ add_axis (hb_face_t *hb_face,
Axis *axis;
char name[20];
unsigned int name_len = 20;
+ GtkWidget *button;
hb_ot_name_get_utf8 (hb_face, ax->name_id, HB_LANGUAGE_INVALID, &name_len, name);
axis_label = gtk_label_new (name);
gtk_widget_set_halign (axis_label, GTK_ALIGN_START);
gtk_widget_set_valign (axis_label, GTK_ALIGN_BASELINE);
- gtk_grid_attach (GTK_GRID (variations_grid), axis_label, 0, i, 1, 1);
+ gtk_grid_attach (GTK_GRID (demo->variations_grid), axis_label, 0, i, 1, 1);
adjustment = gtk_adjustment_new (value, ax->min_value, ax->max_value,
1.0, 10.0, 0.0);
axis_scale = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, adjustment);
@@ -941,18 +1059,25 @@ add_axis (hb_face_t *hb_face,
gtk_widget_set_valign (axis_scale, GTK_ALIGN_BASELINE);
gtk_widget_set_hexpand (axis_scale, TRUE);
gtk_widget_set_size_request (axis_scale, 100, -1);
- gtk_grid_attach (GTK_GRID (variations_grid), axis_scale, 1, i, 1, 1);
+ gtk_grid_attach (GTK_GRID (demo->variations_grid), axis_scale, 1, i, 1, 1);
axis_entry = gtk_entry_new ();
gtk_widget_set_valign (axis_entry, GTK_ALIGN_BASELINE);
gtk_editable_set_width_chars (GTK_EDITABLE (axis_entry), 4);
gtk_editable_set_max_width_chars (GTK_EDITABLE (axis_entry), 4);
gtk_widget_set_hexpand (axis_entry, FALSE);
- gtk_grid_attach (GTK_GRID (variations_grid), axis_entry, 2, i, 1, 1);
+ gtk_grid_attach (GTK_GRID (demo->variations_grid), axis_entry, 2, i, 1, 1);
axis = g_new (Axis, 1);
axis->tag = ax->tag;
axis->adjustment = adjustment;
- g_hash_table_add (axes, axis);
+ axis->default_value = ax->default_value;
+ g_hash_table_add (demo->axes, axis);
+
+ button = gtk_button_new_from_icon_name ("media-playback-start");
+ gtk_widget_add_css_class (GTK_WIDGET (button), "circular");
+ gtk_widget_set_valign (GTK_WIDGET (button), GTK_ALIGN_CENTER);
+ g_signal_connect (button, "clicked", G_CALLBACK (start_axis_animation), axis);
+ gtk_grid_attach (GTK_GRID (demo->variations_grid), button, 3, i, 1, 1);
adjustment_changed (adjustment, GTK_ENTRY (axis_entry));
@@ -992,8 +1117,6 @@ free_instance (gpointer data)
g_free (instance);
}
-static GHashTable *instances;
-
static void
add_instance (hb_face_t *face,
unsigned int index,
@@ -1013,15 +1136,15 @@ add_instance (hb_face_t *face,
instance->name = g_strdup (name);
instance->index = index;
- g_hash_table_add (instances, instance);
+ g_hash_table_add (demo->instances, instance);
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), instance->name);
}
static void
unset_instance (GtkAdjustment *adjustment)
{
- if (instance_combo)
- gtk_combo_box_set_active (GTK_COMBO_BOX (instance_combo), 0);
+ if (demo->instance_combo)
+ gtk_combo_box_set_active (GTK_COMBO_BOX (demo->instance_combo), 0);
}
static void
@@ -1044,7 +1167,7 @@ instance_changed (GtkComboBox *combo)
goto out;
ikey.name = text;
- instance = g_hash_table_lookup (instances, &ikey);
+ instance = g_hash_table_lookup (demo->instances, &ikey);
if (!instance)
{
g_print ("did not find instance %s\n", text);
@@ -1074,7 +1197,7 @@ instance_changed (GtkComboBox *combo)
value = coords[ai[i].axis_index];
akey.tag = ai[i].tag;
- axis = g_hash_table_lookup (axes, &akey);
+ axis = g_hash_table_lookup (demo->axes, &akey);
if (axis)
{
g_signal_handlers_block_by_func (axis->adjustment, unset_instance, NULL);
@@ -1125,9 +1248,9 @@ add_font_plane (int i)
Axis key;
key.tag = MAKE_TAG('w','g','h','t');
- weight_axis = g_hash_table_lookup (axes, &key);
+ weight_axis = g_hash_table_lookup (demo->axes, &key);
key.tag = MAKE_TAG('w','d','t','h');
- width_axis = g_hash_table_lookup (axes, &key);
+ width_axis = g_hash_table_lookup (demo->axes, &key);
if (weight_axis && width_axis)
{
@@ -1136,7 +1259,7 @@ add_font_plane (int i)
gtk_widget_set_size_request (plane, 300, 300);
gtk_widget_set_halign (plane, GTK_ALIGN_CENTER);
- gtk_grid_attach (GTK_GRID (variations_grid), plane, 0, i, 3, 1);
+ gtk_grid_attach (GTK_GRID (demo->variations_grid), plane, 0, i, 3, 1);
}
}
@@ -1166,13 +1289,13 @@ update_font_variations (void)
unsigned int length;
int i;
- while ((child = gtk_widget_get_first_child (variations_grid)))
- gtk_grid_remove (GTK_GRID (variations_grid), child);
+ while ((child = gtk_widget_get_first_child (demo->variations_grid)))
+ gtk_grid_remove (GTK_GRID (demo->variations_grid), child);
- instance_combo = NULL;
+ demo->instance_combo = NULL;
- g_hash_table_remove_all (axes);
- g_hash_table_remove_all (instances);
+ g_hash_table_remove_all (demo->axes);
+ g_hash_table_remove_all (demo->instances);
pango_font = get_pango_font ();
hb_font = pango_font_get_hb_font (pango_font);
@@ -1199,7 +1322,7 @@ update_font_variations (void)
gtk_label_set_xalign (GTK_LABEL (label), 0);
gtk_widget_set_halign (label, GTK_ALIGN_START);
gtk_widget_set_valign (label, GTK_ALIGN_BASELINE);
- gtk_grid_attach (GTK_GRID (variations_grid), label, 0, -1, 2, 1);
+ gtk_grid_attach (GTK_GRID (demo->variations_grid), label, 0, -1, 2, 1);
combo = gtk_combo_box_text_new ();
gtk_widget_set_valign (combo, GTK_ALIGN_BASELINE);
@@ -1218,9 +1341,9 @@ update_font_variations (void)
}
}
- gtk_grid_attach (GTK_GRID (variations_grid), combo, 1, -1, 2, 1);
+ gtk_grid_attach (GTK_GRID (demo->variations_grid), combo, 1, -1, 2, 1);
g_signal_connect (combo, "changed", G_CALLBACK (instance_changed), NULL);
- instance_combo = combo;
+ demo->instance_combo = combo;
}
for (i = 0; i < n_axes; i++)
@@ -1237,6 +1360,7 @@ done:
G_MODULE_EXPORT void
font_features_font_changed (void)
{
+ update_basic ();
update_script_combo ();
update_features ();
update_font_variations ();
@@ -1249,17 +1373,17 @@ font_features_script_changed (void)
update_display ();
}
-G_MODULE_EXPORT void
+static void
font_features_reset_features (void)
{
GList *l;
- gtk_label_select_region (GTK_LABEL (the_label), 0, 0);
+ gtk_label_select_region (GTK_LABEL (demo->the_label), 0, 0);
- g_list_free_full (ranges, free_range);
- ranges = NULL;
+ g_list_free_full (demo->ranges, free_range);
+ demo->ranges = NULL;
- for (l = feature_items; l; l = l->next)
+ for (l = demo->feature_items; l; l = l->next)
{
FeatureItem *item = l->data;
@@ -1281,9 +1405,9 @@ static char *text;
static void
switch_to_entry (void)
{
- text = g_strdup (gtk_editable_get_text (GTK_EDITABLE (the_entry)));
- gtk_stack_set_visible_child_name (GTK_STACK (stack), "entry");
- gtk_widget_grab_focus (the_entry);
+ text = g_strdup (gtk_editable_get_text (GTK_EDITABLE (demo->the_entry)));
+ gtk_stack_set_visible_child_name (GTK_STACK (demo->stack), "entry");
+ gtk_widget_grab_focus (demo->the_entry);
}
static void
@@ -1291,14 +1415,14 @@ switch_to_label (void)
{
g_free (text);
text = NULL;
- gtk_stack_set_visible_child_name (GTK_STACK (stack), "label");
+ gtk_stack_set_visible_child_name (GTK_STACK (demo->stack), "label");
update_display ();
}
G_MODULE_EXPORT void
font_features_toggle_edit (void)
{
- if (strcmp (gtk_stack_get_visible_child_name (GTK_STACK (stack)), "label") == 0)
+ if (strcmp (gtk_stack_get_visible_child_name (GTK_STACK (demo->stack)), "label") == 0)
switch_to_entry ();
else
switch_to_label ();
@@ -1307,7 +1431,7 @@ font_features_toggle_edit (void)
G_MODULE_EXPORT void
font_features_stop_edit (void)
{
- g_signal_emit_by_name (edit_toggle, "clicked");
+ g_signal_emit_by_name (demo->edit_toggle, "clicked");
}
static gboolean
@@ -1327,8 +1451,6 @@ entry_key_press (GtkEventController *controller,
return GDK_EVENT_PROPAGATE;
}
-#define gtk_builder_cscope_add_callback(scope, callback) \
- gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (scope), #callback, G_CALLBACK (callback))
GtkWidget *
do_font_features (GtkWidget *do_widget)
{
@@ -1338,7 +1460,6 @@ do_font_features (GtkWidget *do_widget)
{
GtkBuilder *builder;
GtkBuilderScope *scope;
- GtkWidget *feature_list;
GtkEventController *controller;
builder = gtk_builder_new ();
@@ -1346,134 +1467,89 @@ do_font_features (GtkWidget *do_widget)
scope = gtk_builder_cscope_new ();
gtk_builder_cscope_add_callback (scope, basic_value_changed);
gtk_builder_cscope_add_callback (scope, basic_entry_activated);
+ gtk_builder_cscope_add_callback (scope, font_features_reset_basic);
+ gtk_builder_cscope_add_callback (scope, font_features_reset_features);
+ gtk_builder_cscope_add_callback (scope, font_features_reset_variations);
gtk_builder_set_scope (builder, scope);
- gtk_builder_add_from_resource (builder, "/font_features/font-features.ui", NULL);
+ demo = g_new0 (FontFeaturesDemo, 1);
+
+ gtk_builder_add_from_resource (builder, "/font_features/font_features.ui", NULL);
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
- feature_list = GTK_WIDGET (gtk_builder_get_object (builder, "feature_list"));
- the_label = GTK_WIDGET (gtk_builder_get_object (builder, "label"));
- settings = GTK_WIDGET (gtk_builder_get_object (builder, "settings"));
- description = GTK_WIDGET (gtk_builder_get_object (builder, "description"));
- resetbutton = GTK_WIDGET (gtk_builder_get_object (builder, "reset"));
- font = GTK_WIDGET (gtk_builder_get_object (builder, "font"));
- script_lang = GTK_WIDGET (gtk_builder_get_object (builder, "script_lang"));
- stack = GTK_WIDGET (gtk_builder_get_object (builder, "stack"));
- the_entry = GTK_WIDGET (gtk_builder_get_object (builder, "entry"));
- edit_toggle = GTK_WIDGET (gtk_builder_get_object (builder, "edit_toggle"));
- size_entry = GTK_WIDGET (gtk_builder_get_object (builder, "size_entry"));
- size_adjustment = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "size_adjustment"));
- letterspacing_entry = GTK_WIDGET (gtk_builder_get_object (builder, "letterspacing_entry"));
- letterspacing_adjustment = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "letterspacing_adjustment"));
- line_height_entry = GTK_WIDGET (gtk_builder_get_object (builder, "line_height_entry"));
- line_height_adjustment = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "line_height_adjustment"));
-
- basic_value_changed (size_adjustment, size_entry);
- basic_value_changed (letterspacing_adjustment, letterspacing_entry);
- basic_value_changed (line_height_adjustment, line_height_entry);
+ g_object_set_data_full (G_OBJECT (window), "demo", demo, demo_free);
+
+ demo->the_label = GTK_WIDGET (gtk_builder_get_object (builder, "label"));
+ demo->settings = GTK_WIDGET (gtk_builder_get_object (builder, "settings"));
+ demo->description = GTK_WIDGET (gtk_builder_get_object (builder, "description"));
+ demo->font = GTK_WIDGET (gtk_builder_get_object (builder, "font"));
+ demo->script_lang = GTK_WIDGET (gtk_builder_get_object (builder, "script_lang"));
+ demo->feature_list = GTK_WIDGET (gtk_builder_get_object (builder, "feature_list"));
+ demo->stack = GTK_WIDGET (gtk_builder_get_object (builder, "stack"));
+ demo->the_entry = GTK_WIDGET (gtk_builder_get_object (builder, "entry"));
+ demo->edit_toggle = GTK_WIDGET (gtk_builder_get_object (builder, "edit_toggle"));
+ demo->size_entry = GTK_WIDGET (gtk_builder_get_object (builder, "size_entry"));
+ demo->size_adjustment = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "size_adjustment"));
+ demo->letterspacing_entry = GTK_WIDGET (gtk_builder_get_object (builder, "letterspacing_entry"));
+ demo->letterspacing_adjustment = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "letterspacing_adjustment"));
+ demo->line_height_entry = GTK_WIDGET (gtk_builder_get_object (builder, "line_height_entry"));
+ demo->line_height_adjustment = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "line_height_adjustment"));
+
+ basic_value_changed (demo->size_adjustment, demo->size_entry);
+ basic_value_changed (demo->letterspacing_adjustment, demo->letterspacing_entry);
+ basic_value_changed (demo->line_height_adjustment, demo->line_height_entry);
controller = gtk_event_controller_key_new ();
- g_object_set_data_full (G_OBJECT (the_entry), "controller", g_object_ref (controller), g_object_unref);
- g_signal_connect (controller, "key-pressed", G_CALLBACK (entry_key_press), the_entry);
- gtk_widget_add_controller (the_entry, controller);
-
- add_check_group (feature_list, _("Kerning"), (const char *[]){ "kern", NULL });
- add_check_group (feature_list, _("Ligatures"), (const char *[]){ "liga",
- "dlig",
- "hlig",
- "clig",
- "rlig", NULL });
- add_check_group (feature_list, _("Letter Case"), (const char *[]){ "smcp",
- "c2sc",
- "pcap",
- "c2pc",
- "unic",
- "cpsp",
- "case",NULL });
- add_radio_group (feature_list, _("Number Case"), (const char *[]){ "xxxx",
- "lnum",
- "onum", NULL });
- add_radio_group (feature_list, _("Number Spacing"), (const char *[]){ "xxxx",
- "pnum",
- "tnum", NULL });
- add_radio_group (feature_list, _("Fractions"), (const char *[]){ "xxxx",
- "frac",
- "afrc", NULL });
- add_check_group (feature_list, _("Numeric Extras"), (const char *[]){ "zero",
- "nalt",
- "sinf", NULL });
- add_check_group (feature_list, _("Character Alternatives"), (const char *[]){ "swsh",
- "cswh",
- "locl",
- "calt",
- "falt",
- "hist",
- "salt",
- "jalt",
- "titl",
- "rand",
- "subs",
- "sups",
- "ordn",
- "ltra",
- "ltrm",
- "rtla",
- "rtlm",
- "rclt", NULL });
- add_check_group (feature_list, _("Positional Alternatives"), (const char *[]){ "init",
- "medi",
- "med2",
- "fina",
- "fin2",
- "fin3",
- "isol", NULL });
- add_check_group (feature_list, _("Width Variants"), (const char *[]){ "fwid",
- "hwid",
- "halt",
- "pwid",
- "palt",
- "twid",
- "qwid", NULL });
- add_check_group (feature_list, _("Alternative Stylistic Sets"), (const char *[]){ "ss01",
- "ss02",
- "ss03",
- "ss04",
- "ss05",
- "ss06",
- "ss07",
- "ss08",
- "ss09",
- "ss10",
- "ss11",
- "ss12",
- "ss13",
- "ss14",
- "ss15",
- "ss16",
- "ss17",
- "ss18",
- "ss19",
- "ss20", NULL });
- add_check_group (feature_list, _("Mathematical"), (const char *[]){ "dtls",
- "flac",
- "mgrk",
- "ssty", NULL });
- add_check_group (feature_list, _("Optical Bounds"), (const char *[]){ "opbd",
- "lfbd",
- "rtbd", NULL });
- feature_items = g_list_reverse (feature_items);
-
- variations_heading = GTK_WIDGET (gtk_builder_get_object (builder, "variations_heading"));
- variations_grid = GTK_WIDGET (gtk_builder_get_object (builder, "variations_grid"));
- if (instances == NULL)
- instances = g_hash_table_new_full (instance_hash, instance_equal, NULL, free_instance);
+ g_object_set_data_full (G_OBJECT (demo->the_entry), "controller", g_object_ref (controller), g_object_unref);
+ g_signal_connect (controller, "key-pressed", G_CALLBACK (entry_key_press), demo->the_entry);
+ gtk_widget_add_controller (demo->the_entry, controller);
+
+ add_check_group (demo->feature_list, _("Kerning"),
+ (const char *[]){ "kern", NULL });
+ add_check_group (demo->feature_list, _("Ligatures"),
+ (const char *[]){ "liga", "dlig", "hlig", "clig", "rlig", NULL });
+ add_check_group (demo->feature_list, _("Letter Case"),
+ (const char *[]){ "smcp", "c2sc", "pcap", "c2pc", "unic", "cpsp",
+ "case",NULL });
+ add_radio_group (demo->feature_list, _("Number Case"),
+ (const char *[]){ "xxxx", "lnum", "onum", NULL });
+ add_radio_group (demo->feature_list, _("Number Spacing"),
+ (const char *[]){ "xxxx", "pnum", "tnum", NULL });
+ add_radio_group (demo->feature_list, _("Fractions"),
+ (const char *[]){ "xxxx", "frac", "afrc", NULL });
+ add_check_group (demo->feature_list, _("Numeric Extras"),
+ (const char *[]){ "zero", "nalt", "sinf", NULL });
+ add_check_group (demo->feature_list, _("Character Alternatives"),
+ (const char *[]){ "swsh", "cswh", "locl", "calt", "falt", "hist",
+ "salt", "jalt", "titl", "rand", "subs", "sups",
+ "ordn", "ltra", "ltrm", "rtla", "rtlm", "rclt", NULL });
+ add_check_group (demo->feature_list, _("Positional Alternatives"),
+ (const char *[]){ "init", "medi", "med2", "fina", "fin2", "fin3",
+ "isol", NULL });
+ add_check_group (demo->feature_list, _("Width Variants"),
+ (const char *[]){ "fwid", "hwid", "halt", "pwid", "palt", "twid",
+ "qwid", NULL });
+ add_check_group (demo->feature_list, _("Alternative Stylistic Sets"),
+ (const char *[]){ "ss01", "ss02", "ss03", "ss04", "ss05", "ss06",
+ "ss07", "ss08", "ss09", "ss10", "ss11", "ss12",
+ "ss13", "ss14", "ss15", "ss16", "ss17", "ss18",
+ "ss19", "ss20", NULL });
+ add_check_group (demo->feature_list, _("Mathematical"),
+ (const char *[]){ "dtls", "flac", "mgrk", "ssty", NULL });
+ add_check_group (demo->feature_list, _("Optical Bounds"),
+ (const char *[]){ "opbd", "lfbd", "rtbd", NULL });
+ demo->feature_items = g_list_reverse (demo->feature_items);
+
+ demo->variations_grid = GTK_WIDGET (gtk_builder_get_object (builder, "variations_grid"));
+ if (demo->instances == NULL)
+ demo->instances = g_hash_table_new_full (instance_hash, instance_equal, NULL, free_instance);
else
- g_hash_table_remove_all (instances);
+ g_hash_table_remove_all (demo->instances);
- if (axes == NULL)
- axes = g_hash_table_new_full (axes_hash, axes_equal, NULL, g_free);
+ if (demo->axes == NULL)
+ demo->axes = g_hash_table_new_full (axes_hash, axes_equal, NULL, g_free);
else
- g_hash_table_remove_all (axes);
+ g_hash_table_remove_all (demo->axes);
font_features_font_changed ();
diff --git a/demos/gtk-demo/font-features.ui b/demos/gtk-demo/font_features.ui
index 844638641c..4a707b532f 100644
--- a/demos/gtk-demo/font-features.ui
+++ b/demos/gtk-demo/font_features.ui
@@ -2,26 +2,26 @@
<interface>
<object class="GtkAdjustment" id="size_adjustment">
<property name="lower">7</property>
+ <property name="upper">100</property>
<property name="value">14</property>
<property name="step_increment">0.5</property>
<property name="page_increment">10</property>
- <property name="upper">100</property>
<signal name="value-changed" handler="basic_value_changed" object="size_entry" swapped="false"/>
</object>
<object class="GtkAdjustment" id="letterspacing_adjustment">
- <property name="lower">0</property>
+ <property name="lower">-1024</property>
+ <property name="upper">8192</property>
<property name="value">0</property>
<property name="step_increment">1</property>
<property name="page_increment">512</property>
- <property name="upper">10240</property>
<signal name="value-changed" handler="basic_value_changed" object="letterspacing_entry" swapped="false"/>
</object>
<object class="GtkAdjustment" id="line_height_adjustment">
- <property name="lower">1</property>
- <property name="value">1</property>
+ <property name="lower">0.75</property>
+ <property name="upper">2.5</property>
+ <property name="value">1.0</property>
<property name="step_increment">0.1</property>
<property name="page_increment">1</property>
- <property name="upper">3</property>
<signal name="value-changed" handler="basic_value_changed" object="line_height_entry" swapped="false"/>
</object>
<object class="GtkWindow" id="window">
@@ -35,7 +35,9 @@
<property name="receives-default">1</property>
<property name="tooltip-text">Reset</property>
<property name="icon-name">view-refresh-symbolic</property>
+ <signal name="clicked" handler="font_features_reset_basic" swapped="no"/>
<signal name="clicked" handler="font_features_reset_features" swapped="no"/>
+ <signal name="clicked" handler="font_features_reset_variations" swapped="no"/>
</object>
</child>
</object>
@@ -59,7 +61,7 @@
<object class="GtkFontButton" id="font">
<property name="receives-default">1</property>
<property name="font">Sans 12</property>
- <property name="level">family|style|size|variations|features</property>
+ <property name="level">family|style</property>
<signal name="font-set" handler="font_features_font_changed" swapped="no"/>
</object>
</child>
@@ -240,87 +242,93 @@
</object>
</child>
<child>
- <object class="GtkBox">
- <property name="orientation">vertical</property>
- <property name="hexpand">1</property>
- <property name="vexpand">1</property>
- <property name="margin-start">20</property>
- <property name="margin-end">20</property>
- <property name="margin-top">20</property>
- <property name="margin-bottom">20</property>
- <property name="spacing">20</property>
+ <object class="GtkScrolledWindow">
+ <property name="hscrollbar-policy">never</property>
+ <property name="vscrollbar-policy">automatic</property>
<child>
- <object class="GtkStack" id="stack">
+ <object class="GtkBox">
+ <property name="orientation">vertical</property>
+ <property name="hexpand">1</property>
+ <property name="vexpand">1</property>
+ <property name="margin-start">20</property>
+ <property name="margin-end">20</property>
+ <property name="margin-top">20</property>
+ <property name="margin-bottom">20</property>
+ <property name="spacing">20</property>
<child>
- <object class="GtkStackPage">
- <property name="name">label</property>
- <property name="child">
- <object class="GtkLabel" id="label">
- <property name="wrap">1</property>
- <property name="xalign">0</property>
- <property name="yalign">0</property>
- <property name="valign">start</property>
- <property name="selectable">1</property>
+ <object class="GtkStack" id="stack">
+ <child>
+ <object class="GtkStackPage">
+ <property name="name">label</property>
+ <property name="child">
+ <object class="GtkLabel" id="label">
+ <property name="wrap">1</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="valign">start</property>
+ <property name="selectable">1</property>
+ </object>
+ </property>
</object>
- </property>
- </object>
- </child>
- <child>
- <object class="GtkStackPage">
- <property name="name">entry</property>
- <property name="child">
- <object class="GtkEntry" id="entry">
- <property name="text">Grumpy wizards make toxic brew for the evil Queen and Jack. A quick movement of the enemy will jeopardize six gunboats. The job of waxing linoleum frequently peeves chintzy kids. My girl wove six dozen plaid jackets before she quit. Twelve ziggurats quickly jumped a finch box.
+ </child>
+ <child>
+ <object class="GtkStackPage">
+ <property name="name">entry</property>
+ <property name="child">
+ <object class="GtkEntry" id="entry">
+ <property name="text">Grumpy wizards make toxic brew for the evil Queen and Jack. A quick movement of the enemy will jeopardize six gunboats. The job of waxing linoleum frequently peeves chintzy kids. My girl wove six dozen plaid jackets before she quit. Twelve ziggurats quickly jumped a finch box.
-Разъяренный чтец эгоистично бьёт пятью жердями шустрого фехтовальщика. Наш банк вчера же выплатил Ф.Я. Эйхгольду комиссию за ценные вещи. Эх, чужак, общий съём цен шляп (юфть) – вдрызг! В чащах юга жил бы цитрус? Да, но фальшивый экземпляр!
+ Разъяренный чтец эгоистично бьёт пятью жердями шустрого фехтовальщика. Наш банк вчера же выплатил Ф.Я. Эйхгольду комиссию за ценные вещи. Эх, чужак, общий съём цен шляп (юфть) – вдрызг! В чащах юга жил бы цитрус? Да, но фальшивый экземпляр!
-Τάχιστη αλώπηξ βαφής ψημένη γη, δρασκελίζει υπέρ νωθρού κυνός</property>
- <signal name="activate" handler="font_features_stop_edit"/>
- <property name="valign">start</property>
- <property name="width-chars">50</property>
+ Τάχιστη αλώπηξ βαφής ψημένη γη, δρασκελίζει υπέρ νωθρού κυνός</property>
+ <signal name="activate" handler="font_features_stop_edit"/>
+ <property name="valign">start</property>
+ <property name="width-chars">50</property>
+ </object>
+ </property>
</object>
- </property>
+ </child>
</object>
</child>
- </object>
- </child>
- <child>
- <object class="GtkLabel" id="settings">
- <property name="wrap">1</property>
- <property name="xalign">0</property>
- <property name="valign">end</property>
- <property name="width-chars">50</property>
- <property name="max-width-chars">50</property>
- <property name="hexpand">1</property>
- <property name="vexpand">1</property>
- <style>
- <class name="monospace"/>
- </style>
- </object>
- </child>
- <child>
- <object class="GtkBox">
- <property name="spacing">10</property>
<child>
- <object class="GtkLabel" id="description">
+ <object class="GtkLabel" id="settings">
<property name="wrap">1</property>
- <property name="wrap-mode">char</property>
<property name="xalign">0</property>
<property name="valign">end</property>
<property name="width-chars">50</property>
<property name="max-width-chars">50</property>
<property name="hexpand">1</property>
+ <property name="vexpand">1</property>
<style>
<class name="monospace"/>
</style>
</object>
</child>
<child>
- <object class="GtkToggleButton" id="edit_toggle">
- <property name="icon-name">document-edit-symbolic</property>
- <property name="halign">end</property>
- <property name="valign">end</property>
- <signal name="toggled" handler="font_features_toggle_edit"/>
+ <object class="GtkBox">
+ <property name="spacing">10</property>
+ <child>
+ <object class="GtkLabel" id="description">
+ <property name="wrap">1</property>
+ <property name="wrap-mode">char</property>
+ <property name="xalign">0</property>
+ <property name="valign">end</property>
+ <property name="width-chars">50</property>
+ <property name="max-width-chars">50</property>
+ <property name="hexpand">1</property>
+ <style>
+ <class name="monospace"/>
+ </style>
+ </object>
+ </child>
+ <child>
+ <object class="GtkToggleButton" id="edit_toggle">
+ <property name="icon-name">document-edit-symbolic</property>
+ <property name="halign">end</property>
+ <property name="valign">end</property>
+ <signal name="toggled" handler="font_features_toggle_edit"/>
+ </object>
+ </child>
</object>
</child>
</object>
diff --git a/gtk/gtkbuilderscope.c b/gtk/gtkbuilderscope.c
index f5503c8b11..6d472dc6a8 100644
--- a/gtk/gtkbuilderscope.c
+++ b/gtk/gtkbuilderscope.c
@@ -429,6 +429,19 @@ gtk_builder_cscope_new (void)
}
/**
+ * gtk_builder_cscope_add_callback:
+ * @self: a `GtkBuilderCScope`
+ * @callback_symbols: (scope async): The callback pointer
+ *
+ * Adds the @callback_symbol to the scope of @builder under its
+ * own name.
+ *
+ * This is a convenience wrapper of [method@Gtk.BuilderCScope.add_callback_symbol].
+ *
+ * Since: 4.8
+ */
+
+/**
* gtk_builder_cscope_add_callback_symbol:
* @self: a `GtkBuilderCScope`
* @callback_name: The name of the callback, as expected in the XML
diff --git a/gtk/gtkbuilderscope.h b/gtk/gtkbuilderscope.h
index 7fc2ccbc0b..5ab602fc06 100644
--- a/gtk/gtkbuilderscope.h
+++ b/gtk/gtkbuilderscope.h
@@ -114,10 +114,14 @@ GDK_AVAILABLE_IN_ALL
void gtk_builder_cscope_add_callback_symbols (GtkBuilderCScope *self,
const char *first_callback_name,
GCallback first_callback_symbol,
- ...) G_GNUC_NULL_TERMINATED;
+ ...) G_GNUC_NULL_TERMINATED;
+
+#define gtk_builder_cscope_add_callback(scope, callback) \
+ gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (scope), #callback, G_CALLBACK (callback))
+
GDK_AVAILABLE_IN_ALL
GCallback gtk_builder_cscope_lookup_callback_symbol(GtkBuilderCScope *self,
- const char *callback_name);
+ const char *callback_name);
G_END_DECLS