diff options
author | Matthias Clasen <mclasen@redhat.com> | 2022-06-30 23:52:37 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2022-06-30 23:52:37 -0400 |
commit | 88bbb933a1185b72f569e3dbe297fb541a1c0295 (patch) | |
tree | 18699ccb1349e673e5a70895a54e7f94fc2f1f36 | |
parent | 4070e794d26dd63336d544bdbfbe020e87296c6b (diff) | |
download | gtk+-88bbb933a1185b72f569e3dbe297fb541a1c0295.tar.gz |
gtk4-demo: Add a waterfall to font features
-rw-r--r-- | demos/gtk-demo/font_features.c | 186 | ||||
-rw-r--r-- | demos/gtk-demo/font_features.ui | 90 |
2 files changed, 191 insertions, 85 deletions
diff --git a/demos/gtk-demo/font_features.c b/demos/gtk-demo/font_features.c index a4267ecdce..f907989700 100644 --- a/demos/gtk-demo/font_features.c +++ b/demos/gtk-demo/font_features.c @@ -47,6 +47,7 @@ typedef struct { guint tick_cb; guint64 start_time; gboolean increasing; + GtkWidget *button; } Axis; typedef struct { @@ -60,10 +61,13 @@ typedef struct { GtkWidget *instance_combo; GtkWidget *stack; GtkWidget *the_entry; + GtkWidget *plain_toggle; + GtkWidget *waterfall_toggle; GtkWidget *edit_toggle; GtkAdjustment *size_adjustment; GtkAdjustment *letterspacing_adjustment; GtkAdjustment *line_height_adjustment; + GtkWidget *size_scale; GtkWidget *size_entry; GtkWidget *letterspacing_entry; GtkWidget *line_height_entry; @@ -71,6 +75,8 @@ typedef struct { GList *ranges; GHashTable *instances; GHashTable *axes; + char *text; + GtkWidget *swin; } FontFeaturesDemo; static void @@ -82,6 +88,7 @@ demo_free (gpointer data) 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_clear_pointer (&demo->text, g_free); g_free (demo); } @@ -90,6 +97,27 @@ static FontFeaturesDemo *demo; static void update_display (void); +static void +font_features_toggle_plain (void) +{ + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (demo->plain_toggle)) || + gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (demo->waterfall_toggle))) + { + gtk_stack_set_visible_child_name (GTK_STACK (demo->stack), "label"); + update_display (); + } +} + +static void +font_features_notify_waterfall (void) +{ + gboolean can_change_size; + + can_change_size = !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (demo->waterfall_toggle)); + gtk_widget_set_sensitive (demo->size_scale, can_change_size); + gtk_widget_set_sensitive (demo->size_entry, can_change_size); +} + typedef struct { GtkAdjustment *adjustment; GtkEntry *entry; @@ -425,10 +453,23 @@ update_display (void) char *font_desc; char *features; double value; + int text_len; + gboolean do_waterfall; + GString *waterfall; text = gtk_editable_get_text (GTK_EDITABLE (demo->the_entry)); + text_len = strlen (text); + + do_waterfall = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (demo->waterfall_toggle)); - if (gtk_label_get_selection_bounds (GTK_LABEL (demo->the_label), &ins, &bound)) + gtk_label_set_wrap (GTK_LABEL (demo->the_label), !do_waterfall); + + if (do_waterfall) + { + start = PANGO_ATTR_INDEX_FROM_TEXT_BEGINNING; + end = PANGO_ATTR_INDEX_TO_TEXT_END; + } + else 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; @@ -502,17 +543,13 @@ update_display (void) hb_tag_t lang_tag; model = gtk_combo_box_get_model (GTK_COMBO_BOX (demo->script_lang)); - gtk_tree_model_get (model, &iter, - 3, &lang_tag, - -1); + gtk_tree_model_get (model, &iter, 3, &lang_tag, -1); lang = pango_language_from_string (hb_language_to_string (hb_ot_tag_to_language (lang_tag))); } else lang = NULL; - ensure_range (start, end, desc, features, lang); - attrs = pango_attr_list_new (); if (gtk_adjustment_get_value (demo->letterspacing_adjustment) != 0.) @@ -531,32 +568,69 @@ update_display (void) pango_attr_list_insert (attrs, attr); } - for (l = demo->ranges; l; l = l->next) + if (do_waterfall) { - Range *range = l->data; - - attr = pango_attr_font_desc_new (range->desc); - attr->start_index = range->start; - attr->end_index = range->end; + attr = pango_attr_font_desc_new (desc); pango_attr_list_insert (attrs, attr); - - attr = pango_attr_font_features_new (range->features); - attr->start_index = range->start; - attr->end_index = range->end; + attr = pango_attr_font_features_new (features); + pango_attr_list_insert (attrs, attr); + attr = pango_attr_language_new (lang); pango_attr_list_insert (attrs, attr); + } + else + { + ensure_range (start, end, desc, features, lang); - if (range->language) + for (l = demo->ranges; l; l = l->next) { - attr = pango_attr_language_new (range->language); + Range *range = l->data; + + attr = pango_attr_font_desc_new (range->desc); + attr->start_index = range->start; + attr->end_index = range->end; + pango_attr_list_insert (attrs, attr); + + attr = pango_attr_font_features_new (range->features); attr->start_index = range->start; attr->end_index = range->end; pango_attr_list_insert (attrs, attr); + + if (range->language) + { + attr = pango_attr_language_new (range->language); + attr->start_index = range->start; + attr->end_index = range->end; + pango_attr_list_insert (attrs, attr); + } } } 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); + + if (do_waterfall) + { + waterfall = g_string_new (""); + int sizes[] = { 7, 8, 9, 10, 12, 14, 16, 20, 24, 30, 40, 50, 60, 70, 90 }; + start = 0; + for (int i = 0; i < G_N_ELEMENTS (sizes); i++) + { + g_string_append (waterfall, text); + g_string_append_c (waterfall, '\n'); + + attr = pango_attr_size_new (sizes[i] * PANGO_SCALE); + attr->start_index = start; + attr->end_index = start + text_len; + pango_attr_list_insert (attrs, attr); + + start += text_len + 1; + } + gtk_label_set_text (GTK_LABEL (demo->the_label), waterfall->str); + g_string_free (waterfall, TRUE); + } + else + gtk_label_set_text (GTK_LABEL (demo->the_label), text); + gtk_label_set_attributes (GTK_LABEL (demo->the_label), attrs); g_free (font_desc); @@ -911,6 +985,9 @@ entry_activated (GtkEntry *entry, static void unset_instance (GtkAdjustment *adjustment); +static void start_or_stop_axis_animation (GtkButton *button, + gpointer data); + static void font_features_reset_variations (void) { @@ -920,6 +997,8 @@ font_features_reset_variations (void) g_hash_table_iter_init (&iter, demo->axes); while (g_hash_table_iter_next (&iter, (gpointer *)NULL, (gpointer *)&axis)) { + if (axis->tick_cb) + start_or_stop_axis_animation (GTK_BUTTON (axis->button), axis); gtk_adjustment_set_value (axis->adjustment, axis->default_value); } } @@ -1005,8 +1084,8 @@ animate_axis (GtkWidget *widget, } static void -start_axis_animation (GtkButton *button, - gpointer data) +start_or_stop_axis_animation (GtkButton *button, + gpointer data) { Axis *axis = data; @@ -1044,7 +1123,6 @@ 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); @@ -1073,11 +1151,11 @@ add_axis (hb_face_t *hb_face, 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); + axis->button = gtk_button_new_from_icon_name ("media-playback-start"); + gtk_widget_add_css_class (GTK_WIDGET (axis->button), "circular"); + gtk_widget_set_valign (GTK_WIDGET (axis->button), GTK_ALIGN_CENTER); + g_signal_connect (axis->button, "clicked", G_CALLBACK (start_or_stop_axis_animation), axis); + gtk_grid_attach (GTK_GRID (demo->variations_grid), axis->button, 3, i, 1, 1); adjustment_changed (adjustment, GTK_ENTRY (axis_entry)); @@ -1357,7 +1435,7 @@ done: g_free (design_coords); } -G_MODULE_EXPORT void +static void font_features_font_changed (void) { update_basic (); @@ -1366,7 +1444,7 @@ font_features_font_changed (void) update_font_variations (); } -G_MODULE_EXPORT void +static void font_features_script_changed (void) { update_features (); @@ -1400,35 +1478,26 @@ font_features_reset_features (void) } } -static char *text; - -static void -switch_to_entry (void) -{ - 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 -switch_to_label (void) -{ - g_free (text); - text = NULL; - 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 (demo->stack)), "label") == 0) - switch_to_entry (); + if (strcmp (gtk_stack_get_visible_child_name (GTK_STACK (demo->stack)), "entry") != 0) + { + g_free (demo->text); + demo->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); + gtk_adjustment_set_value (gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (demo->swin)), 0); + } else - switch_to_label (); + { + g_clear_pointer (&demo->text, g_free); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (demo->plain_toggle), TRUE); + update_display (); + } } -G_MODULE_EXPORT void +static void font_features_stop_edit (void) { g_signal_emit_by_name (demo->edit_toggle, "clicked"); @@ -1443,8 +1512,7 @@ entry_key_press (GtkEventController *controller, { if (keyval == GDK_KEY_Escape) { - gtk_editable_set_text (GTK_EDITABLE (entry), text); - font_features_stop_edit (); + gtk_editable_set_text (GTK_EDITABLE (entry), demo->text); return GDK_EVENT_STOP; } @@ -1470,6 +1538,12 @@ do_font_features (GtkWidget *do_widget) 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_cscope_add_callback (scope, font_features_toggle_plain); + gtk_builder_cscope_add_callback (scope, font_features_toggle_edit); + gtk_builder_cscope_add_callback (scope, font_features_stop_edit); + gtk_builder_cscope_add_callback (scope, font_features_font_changed); + gtk_builder_cscope_add_callback (scope, font_features_script_changed); + gtk_builder_cscope_add_callback (scope, font_features_notify_waterfall); gtk_builder_set_scope (builder, scope); demo = g_new0 (FontFeaturesDemo, 1); @@ -1487,13 +1561,17 @@ do_font_features (GtkWidget *do_widget) 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->plain_toggle = GTK_WIDGET (gtk_builder_get_object (builder, "plain_toggle")); + demo->waterfall_toggle = GTK_WIDGET (gtk_builder_get_object (builder, "waterfall_toggle")); demo->edit_toggle = GTK_WIDGET (gtk_builder_get_object (builder, "edit_toggle")); + demo->size_scale = GTK_WIDGET (gtk_builder_get_object (builder, "size_scale")); 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")); + demo->swin = GTK_WIDGET (gtk_builder_get_object (builder, "swin")); basic_value_changed (demo->size_adjustment, demo->size_entry); basic_value_changed (demo->letterspacing_adjustment, demo->letterspacing_entry); diff --git a/demos/gtk-demo/font_features.ui b/demos/gtk-demo/font_features.ui index 4a707b532f..77d47120ad 100644 --- a/demos/gtk-demo/font_features.ui +++ b/demos/gtk-demo/font_features.ui @@ -81,7 +81,7 @@ </object> </child> <child> - <object class="GtkScale"> + <object class="GtkScale" id="size_scale"> <property name="hexpand">1</property> <property name="width-request">100</property> <property name="valign">baseline</property> @@ -242,19 +242,21 @@ </object> </child> <child> - <object class="GtkScrolledWindow"> - <property name="hscrollbar-policy">never</property> - <property name="vscrollbar-policy">automatic</property> + <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="GtkBox"> - <property name="orientation">vertical</property> - <property name="hexpand">1</property> + <object class="GtkScrolledWindow" id="swin"> + <property name="hscrollbar-policy">automatic</property> + <property name="vscrollbar-policy">automatic</property> + <property name="propagate-natural-height">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="GtkStack" id="stack"> <child> @@ -290,15 +292,34 @@ </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="settings"> + <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> - <property name="vexpand">1</property> <style> <class name="monospace"/> </style> @@ -306,31 +327,38 @@ </child> <child> <object class="GtkBox"> - <property name="spacing">10</property> + <style> + <class name="linked"/> + </style> + <property name="valign">end</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 class="GtkToggleButton" id="plain_toggle"> + <property name="label" translatable="yes">Plain</property> + <property name="active">1</property> + <property name="valign">baseline</property> + <signal name="toggled" handler="font_features_toggle_plain"/> </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="GtkToggleButton" id="waterfall_toggle"> + <property name="label" translatable="yes">Waterfall</property> + <property name="valign">baseline</property> + <property name="group">plain_toggle</property> + <signal name="toggled" handler="font_features_toggle_plain"/> + <signal name="notify::active" handler="font_features_notify_waterfall"/> </object> </child> </object> </child> + <child> + <object class="GtkToggleButton" id="edit_toggle"> + <property name="group">waterfall_toggle</property> + <property name="icon-name">document-edit-symbolic</property> + <property name="halign">end</property> + <property name="valign">end</property> + <signal name="clicked" handler="font_features_toggle_edit"/> + </object> + </child> </object> </child> </object> |