How can I change the font of a text field using non-deprecated way?

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

How can I change the font of a text field using non-deprecated way?

Gtk+ - Apps Dev mailing list
Hello.

I'm trying to make a small application in C using GTK+3 (the latest
stable). The application is going to have a text field implemented using
GtkTextView where a user can write text. I also font a user to be able to
change font, so I've added a font chooser using GtkFontChooserDialog.

The problem is that I don't know how to actually set the font of a text
field to the one that a user chose using font chooser. Well, at least not
using an up-to-date method. I know I can use gtk_widget_override_font(),
and though it works perfectly, I'd rather not use it since it's deprecated
function so it's not meant to be used anymore.

I've tried two other ways though, but both of them failed in one respect or
the other. I'll now describe those two ways:

 1. Using CSS
    I tried using CSS. The way I'd do this is I'd get a font that a user
chose using gtk_font_chooser_get_font(), then I'd format it in a CSS
syntax, such that, for example, Hack 11 Bold, becomes textview { bold 11pt
Hack }. This worked for the most fonts, but there were fonts like B&H
LucidaBright that had "strange" styles like Sans or Book, or Linux
Libertine Initials O Initials that had style called Initial. I managed to
format some of them too, but not all of them, leaving few fonts non-usable.

2. Using GtkTextTag
    I tried creating a tag for a buffer that with a font description of the
currently selected font. This worked perfectly for all fonts, but it
produced two other "errors": 1. It didn't actually change the context style
of the widget, through which I get currently active font for some other
purpose, and 2. using gtk_text_buffer_apply_tag() I was able to set the
font only to the text between the current begin and end, meaning that later
modifications to the text were in the starting font.

In a nutshell, the problem with first approach is that it doesn't work for
all fonts, while the problem with the second one is that it doesn't really
change the font of a widget but only the font of the current text in a
buffer.

Therefore, I'd like to know a non-deprecated way of achieving what a
deprecated function gtk_widget_override_font() achieves. Also, I see that
the first problem with the second approach can be fixed by holding the
user-selected font in a variable, and the second problem of the same
approach by setting the font on every insertion, but those are impractical
"patches" rather than proper methods. I guess that a proper way is using
CSS, but I just don't know how to do it properly (if it is possible, of
course).

If it is not possible to achieve the same effects of
gtk_widget_override_font() in an up-to-date way, then I guess I'd just have
to use gtk_widget_override_font() after all.

Thank you for reading this and I'll hope you'll help me to solve my problem.
_______________________________________________
gtk-app-devel-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Reply | Threaded
Open this post in threaded view
|

Re: How can I change the font of a text field using non-deprecated way?

Gtk+ - Apps Dev mailing list
 
Hi Radomir,

The function gtk_widget_override_font() is deprecated but as far as I know it still works fine in GTK3.

With the Pango font description and the textview you should be able to set everything up without getting any deprecated warnings. It doesn't set the textview widget itself to a particular font but you do have the Pango font description that you can use elsewhere if needed.

Eric

   
//gcc -Wall font_chooser1.c -o font_chooser1 `pkg-config --cflags --libs gtk+-3.0`

#include <gtk/gtk.h>

static void show_font_chooser(GtkWidget *button, gpointer **user_data)
  {
    static gint i=1;
    GtkWidget *chooser=gtk_font_chooser_dialog_new("Font Chooser", GTK_WINDOW(user_data[0]));
    gint result=gtk_dialog_run(GTK_DIALOG(chooser));

    if(result==GTK_RESPONSE_OK)
      {      
        PangoFontDescription *desc=gtk_font_chooser_get_font_desc(GTK_FONT_CHOOSER(chooser));
        GtkTextBuffer *buffer=gtk_text_view_get_buffer(GTK_TEXT_VIEW(user_data[1]));
        gchar *tag_name=g_strdup_printf("font-tag%i", i);
        GtkTextTag *font_tag=gtk_text_buffer_create_tag(buffer, tag_name, "font-desc", desc, NULL);
        g_ptr_array_add((GPtrArray*)user_data[2], (gpointer)font_tag);
        i++;
        g_free(tag_name);
        pango_font_description_free(desc);
      }
   
    gtk_widget_destroy(chooser);
  }
static void insert_text(GtkTextBuffer *textbuffer, GtkTextIter *location, gchar *text, gint len, GPtrArray *tags)
  {
    GtkTextIter *start=gtk_text_iter_copy(location);
    gtk_text_iter_backward_chars(start, len);
    //Get the last tag added to the tag array.
    GtkTextTag *font_tag=GTK_TEXT_TAG(g_ptr_array_index(tags, ((tags->len)-1)));
    gtk_text_buffer_apply_tag(textbuffer, font_tag, start, location);
    gtk_text_iter_free(start);
  }
int main(int argc, char *argv[])
  {
    gtk_init(&argc, &argv);

    GtkWidget *window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "Font Chooser");
    gtk_window_set_default_size(GTK_WINDOW(window), 300, 300);
    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
    gtk_container_set_border_width(GTK_CONTAINER(window), 20);
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

    GtkWidget *textview=gtk_text_view_new();
    gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textview), GTK_WRAP_CHAR);
    gtk_widget_set_hexpand(textview, TRUE);
    gtk_widget_set_vexpand(textview, TRUE);

    PangoContext *context=gtk_widget_get_pango_context(textview);
    PangoFontDescription *desc=pango_context_get_font_description(context);

    //For saving the tag pointers.
    GPtrArray *tags=g_ptr_array_new();

    GtkTextBuffer *buffer=gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
    GtkTextTag *font_tag=gtk_text_buffer_create_tag(buffer, "font-tag", "font-desc", desc, NULL);
    g_ptr_array_add(tags, (gpointer)font_tag);
    g_signal_connect_after(buffer, "insert-text", G_CALLBACK(insert_text), tags);

    GtkWidget *button=gtk_button_new_with_label("FontChooser");
    gtk_widget_set_hexpand(button, TRUE);
    gpointer user_data[]={window, textview, tags};
    g_signal_connect(button, "clicked", G_CALLBACK(show_font_chooser), user_data);

    GtkWidget *grid=gtk_grid_new();
    gtk_grid_attach(GTK_GRID(grid), textview, 0, 0, 1, 1);
    gtk_grid_attach(GTK_GRID(grid), button, 0, 1, 1, 1);

    gtk_container_add(GTK_CONTAINER(window), grid);

    gtk_widget_show_all(window);
   
    gtk_main();

    return 0;
  }

 
_______________________________________________
gtk-app-devel-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Reply | Threaded
Open this post in threaded view
|

Re: How can I change the font of a text field using non-deprecated way?

Gtk+ - Apps Dev mailing list
In reply to this post by Gtk+ - Apps Dev mailing list
On Sat, Sep 22, 2018 at 3:11 PM Радомир Хаџић via gtk-app-devel-list
<[hidden email]> wrote:

> I'm trying to make a small application in C using GTK+3 (the latest
> stable). The application is going to have a text field implemented using
> GtkTextView where a user can write text. I also font a user to be able to
> change font, so I've added a font chooser using GtkFontChooserDialog.
>
> The problem is that I don't know how to actually set the font of a text
> field to the one that a user chose using font chooser. Well, at least not
> using an up-to-date method. I know I can use gtk_widget_override_font(),
> and though it works perfectly, I'd rather not use it since it's deprecated
> function so it's not meant to be used anymore.

The functionality you are describing is present in pretty much every
GTK+3-based text editor, so look at the source of any one of them.

Gedit (as of 3.18.3 as packaged in Ubuntu 16.04) uses
gtk_widget_override_font, and so does Mousepad (as of 0.4.0), and
what’s good for the stock text editors of GNOME and Xfce, is probably
good for you, too.
_______________________________________________
gtk-app-devel-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list