Re: turn on italics in TextView
Hi Doug, You can try using the "insert-text" callback to set your italics on the inserted text. This is what I came up with to test. The signal is connected after so that the update occurs first. Careful about not changing the location iter also since there is a warning in the documentation about doing so. Might not need to worry about it here but something to be aware of. https://developer.gnome.org/gtk3/stable/GtkTextBuffer.html#GtkTextBuffer-insert-text Eric /* gcc -Wall textview2.c -o textview2 `pkg-config --cflags --libs gtk+-3.0` Tested on GTK3.18 and Ubuntu16.04 */ #include static gboolean italic=FALSE; static void toggle_italic(GtkToggleButton *toggle1, gpointer data) { GtkWidget *label=gtk_bin_get_child(GTK_BIN(toggle1)); if(gtk_toggle_button_get_active(toggle1)) { gtk_label_set_markup(GTK_LABEL(label), "Italics"); italic=TRUE; } else { gtk_label_set_text(GTK_LABEL(label), "Italics"); italic=FALSE; } gtk_widget_grab_focus(GTK_WIDGET(data)); } static void new_text(GtkTextBuffer *textbuffer, GtkTextIter *location, gchar *text, gint len, gpointer user_data) { if(italic) { GtkTextIter *start=gtk_text_iter_copy(location); GtkTextIter *end=gtk_text_iter_copy(location); gtk_text_iter_backward_chars(start, len); gtk_text_buffer_apply_tag_by_name(textbuffer, "tag1", start, end); gtk_text_iter_free(start); gtk_text_iter_free(end); } } 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), "Textview"); gtk_window_set_default_size(GTK_WINDOW(window), 300, 200); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); GtkWidget *text_view1=gtk_text_view_new(); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text_view1), GTK_WRAP_CHAR); gtk_widget_set_vexpand(text_view1, TRUE); gtk_widget_set_hexpand(text_view1, TRUE); GtkTextBuffer *buffer=gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_view1)); gtk_text_buffer_create_tag(buffer, "tag1", "style", PANGO_STYLE_ITALIC, NULL); g_signal_connect_after(buffer, "insert-text", G_CALLBACK(new_text), NULL); GtkWidget *toggle1=gtk_toggle_button_new_with_label("Italics"); g_signal_connect(toggle1, "toggled", G_CALLBACK(toggle_italic), text_view1); GtkWidget *grid=gtk_grid_new(); gtk_container_set_border_width(GTK_CONTAINER(grid), 8); gtk_grid_set_row_spacing(GTK_GRID(grid), 12); gtk_grid_attach(GTK_GRID(grid), text_view1, 0, 0, 1, 1); gtk_grid_attach(GTK_GRID(grid), toggle1, 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 gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: turn on italics in TextView
Here are a few things that might improve the above code a little. Use gtk_button_set_focus_on_click(GTK_BUTTON(toggle1), FALSE); instead of a grab. Also the global gboolean can be eliminated if you pass the toggle button pointer to the "insert-text" callback. Then you can just use if(gtk_toggle_button_get_active(user_data)) For the sequence of events it is my understanding that the text changes will be made during the event cycle before the window gets re-painted. https://developer.gnome.org/gtk3/stable/chap-drawing-model.html Eric -Original Message- From: Doug McCasland To: cecashon Sent: Tue, Jun 13, 2017 4:09 pm Subject: Re: turn on italics in TextView cecashon, thanks so much for your great reply! I had tried all those calls, but I hadn't put them together as you did, nor did I apply the tag in the way your code does. And I didn't think of having one signal/function for the button-down and another for the apply_tag_by_name. Cool! So your code gets a signal after the character(s) is entered. Then the style is applied to that char, without moving the insert point. Do you know if the un-tagged char is visibly displayed first, and then altered? Or is all the processing somehow finished before the display changes, and then only the tagged char is put on the screen. ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: turn on italics in TextView
Thanks again. That works, but the state is lost when the cursor is moved. Here is some code to discover multiple styles after the cursor is moved. The pointers to the style tags are saved in globals, then in the callback for the cursor move, we look for those pointers in the linked-list returned by gtk_text_iter_get_tag(). I tried to use some of the other link-list functions/macros, such as g_slist_position, but could only get gtk_text_iter_get_tag() to work. Maybe there's a more efficient way to do this. // globals GSList *gtk_text_iter_get_tags (const GtkTextIter *iter); GtkTextTag *italp, *boldp, *ulinep; // call back after cursor is moved void get_style(GtkTextView *tv, GtkMovementStep step, gint count, gboolean extend, gpointer *user_data) { GSList *tlist; GtkTextIter start; GtkTextMark *mark; GtkTextBuffer *buf; buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(tv)); mark = gtk_text_buffer_get_insert(buf); gtk_text_buffer_get_iter_at_mark (buf, &start, mark); tlist = gtk_text_iter_get_tags(&start); // look for each style -- could used to set bits in a bitfield if (g_slist_find(tlist, italp)) g_printerr("got match for ital\n"); if (g_slist_find(tlist, boldp)) g_printerr("got match for bold\n"); if (g_slist_find(tlist, ulinep)) g_printerr("got match for uline\n"); } . . . main(...) . . . italp = gtk_text_buffer_create_tag(buffer, "ital", "style", PANGO_STYLE_ITALIC, NULL); boldp =gtk_text_buffer_create_tag(buffer, "bold", "weight", PANGO_WEIGHT_BOLD, NULL); ulinep = gtk_text_buffer_create_tag(buffer, "uline", "underline", PANGO_UNDERLINE_SINGLE, NULL); g_signal_connect_after(text_view, "move-cursor", G_CALLBACK(get_style), NULL); . . . On Wed, Jun 14, 2017 at 10:48 AM, wrote: > > Here are a few things that might improve the above code a little. Use > > gtk_button_set_focus_on_click(GTK_BUTTON(toggle1), FALSE); > > instead of a grab. Also the global gboolean can be eliminated if you pass > the toggle button pointer to the "insert-text" callback. Then you can just > use > > if(gtk_toggle_button_get_active(user_data)) > > For the sequence of events it is my understanding that the text changes > will be made during the event cycle before the window gets re-painted. > > https://developer.gnome.org/gtk3/stable/chap-drawing-model.html > > Eric > > > > -Original Message- > From: Doug McCasland > To: cecashon > Sent: Tue, Jun 13, 2017 4:09 pm > Subject: Re: turn on italics in TextView > > cecashon, thanks so much for your great reply! > > I had tried all those calls, but I hadn't put them together as you did, > nor did I apply the tag in the way your code does. And I didn't think of > having one signal/function for the button-down and another for the > apply_tag_by_name. Cool! > > So your code gets a signal after the character(s) is entered. Then the > style is applied to that char, without moving the insert point. Do you > know if the un-tagged char is visibly displayed first, and then altered? > Or is all the processing somehow finished before the display changes, and > then only the tagged char is put on the screen. > > > > -- Doug McCasland ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: turn on italics in TextView
Another option is to look at the properties of the tags to get the information that you need. This might work better than saving globals and matching pointers. Eric ... GSList *tlist=NULL; GSList *next=NULL; tlist=gtk_text_iter_get_tags(&start); if(tlist!=NULL) { do { next=tlist->next; gchar *string=NULL; g_object_get(G_OBJECT(tlist->data), "name", &string, NULL); g_print("%s\n", string); g_free(string); tlist=g_slist_next(tlist); }while(next!=NULL); } else g_print("No Tags\n"); if(tlist!=NULL) g_slist_free(tlist); ... ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: turn on italics in TextView
On that last post, I think that I have some bad pointer arithmetic. Moving a pointer past the end and freeing a moved pointer. Not so good. Eric ... GSList *tlist=NULL; GSList *p=NULL; GSList *next=NULL; tlist=gtk_text_iter_get_tags(&start); p=tlist; if(tlist!=NULL) { do { next=p->next; gchar *string=NULL; g_object_get(G_OBJECT(p->data), "name", &string, NULL); g_print("%s\n", string); g_free(string); if(next!=NULL)p=g_slist_next(p); }while(next!=NULL); } else g_print("No Tag\n"); if(tlist!=NULL) g_slist_free(tlist); ... -Original Message- From: Eric Cashon via gtk-app-devel-list To: dougm Cc: gtk-app-devel-list Sent: Tue, Jun 20, 2017 4:48 pm Subject: Re: turn on italics in TextView Another option is to look at the properties of the tags to get the information that you need. This might work better than saving globals and matching pointers. Eric ... GSList *tlist=NULL; GSList *next=NULL; tlist=gtk_text_iter_get_tags(&start); if(tlist!=NULL) { do { next=tlist->next; gchar *string=NULL; g_object_get(G_OBJECT(tlist->data), "name", &string, NULL); g_print("%s\n", string); g_free(string); tlist=g_slist_next(tlist); }while(next!=NULL); } else g_print("No Tags\n"); if(tlist!=NULL) g_slist_free(tlist); ... ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: turn on italics in TextView
Eric, thanks again. I ended up using g_signal_connect() on "key-press-event" (instead of "insert-text"). This makes it easier IMO to handle specific cases, since the callback fn can return TRUE if it did anything or FALSE to get GTK default behavior, unlike void insert-text fn. Plus if you paste 2 chars, the insert-text callback will process every one of them, whereas key-press-event will get none of them. I think I tried to do my own version of the move-cursor and change italic/bold state buttons, but abandoned it, don't remember why. But I took the advice to "store" the italic/bold states in the toolbar button states. It's a little quirky since the text cursor can move away from an italic/bold region and still the i/b tutton, if already pressed, stays that way and so typing at the new cursor location is i/b. Anyway, with Italic button pressed, for example, I get the char via key-press-event. (If style tool button not pressed, then return FALSE). The characters are just keycodes at this point, so need to kick back most of them to default: switch (event->keyval) { case GDK_KEY_Return: case GDK_KEY_Delete: case GDK_KEY_Shift_L: case GDK_KEY_Shift_R: case GDK_KEY_Alt_L: case GDK_KEY_Alt_R: case GDK_KEY_Control_L: case GDK_KEY_Up: case GDK_KEY_Down: case GDK_KEY_Left: case GDK_KEY_Right: case GDK_KEY_End: case GDK_KEY_Home: // case GDK_KEY_BackSpace: return FALSE; } or you get the first letter after "GDK_KEY_". Still haven't fixed up the backspace case. Then call text = gdk_keyval_name(event->keyval); If strlen(text) > 1, then go through this exercise: switch (event->keyval) { case GDK_KEY_exclam: text = "!"; break; case GDK_KEY_quotedbl: text = "\""; break; case GDK_KEY_numbersign: text = "#"; break; case GDK_KEY_dollar: text = "$"; break; case GDK_KEY_percent: text = "%"; break; case GDK_KEY_ampersand: text = "&"; break; case GDK_KEY_apostrophe: text = "'"; break; case GDK_KEY_parenleft: text = "("; break; case GDK_KEY_parenright: text = ")"; break; case GDK_KEY_asterisk: text = "*"; break; case GDK_KEY_plus: text = "+"; break; case GDK_KEY_colon: text = ":"; break; case GDK_KEY_less: text = "<"; break; case GDK_KEY_greater: text = ">"; break; case GDK_KEY_question: text = "?"; break; case GDK_KEY_at: text = "@"; break; case GDK_KEY_underscore: text = "_"; break; case GDK_KEY_braceleft: text = "{"; break; case GDK_KEY_bar: text = "|"; break; case GDK_KEY_braceright: text = "}"; break; case GDK_KEY_asciitilde: text = "~"; break; } Then after all that malarkey, simply insert the char, get the iters around it, and apply the style to it. Then return TRUE. So this works pretty good (good enough :-) ). Even though I didn't use your suggested code GSList *tlist=NULL; GSList *next=NULL; tlist=gtk_text_iter_get_tags(&start); if(tlist!=NULL) { do { next=tlist->next; gchar *string=NULL; g_object_get(G_OBJECT(tlist->data), "name", &string, NULL); g_print("%s\n", string); g_free(string); tlist=g_slist_next(tlist); }while(next!=NULL); } else g_print("No Tags\n"); if(tlist!=NULL) g_slist_free(tlist); after cursor motion, I did deploy that elsewhere to find format tags (for example in exporting to HTML, for which I have a crude version). Once again thanks for that do-while tlist loop -- I *never* would've figured out how to write that! --Doug On Tue, Jun 20, 2017 at 10:47 PM, wrote: > > On that last post, I think that I have some bad pointer arithmetic. Moving > a pointer past the end and freeing a moved pointer. Not so good. > > Eric > > ... > GSList *tlist=NULL; > GSList *p=NULL; > GSList *next=NULL; > tlist=gtk_text_iter_get_tags(&start); > p=tlist; > if(tlist!=NULL) > { > do > { > next=p->next; > gchar *string=NULL; > g_object_get(G_OBJECT(p->data), "name", &string, NULL); > g_print("%s\n", string); > g_free(string); >
Re: turn on italics in TextView
Hi Doug, I made a bit of a pointer mess there. Not the best of answers or way to go about iterating through a list. Looking at some GTK code, this is better done with a for loop. As usual, you don't want to move the pointer you get from gtk_text_iter_get_tags() and then free it. This will cause you grief later on along with buggy code that may not be so easy to debug. Very glad you got things working well even with a less than good answer. Need to be careful of the pointers myself. Eric GSList *tlist=NULL; GSList *p=NULL; tlist=gtk_text_iter_get_tags(&start); g_print("List %p p %p\n", tlist, p); for(p=tlist;p;p=p->next) { gchar *string=NULL; g_object_get(G_OBJECT(p->data), "name", &string, NULL); g_print("p %p %s\n", p, string); g_free(string); } g_print("List %p\n", tlist); if(tlist!=NULL) g_slist_free(tlist); ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: turn on italics in TextView
Heh-heh, yes that for loop does look better :-) I'll use that. Textview is awesome and will save me thousands of lines of code, but not being able to apply a tag to an iter -- that has been a big drawback for me. You can discover a tag at an iter, but only apply/remove it to a range. It would be great to be able to apply a style tag at an iter (including in a blank line) and then have text inserted their use that tag. One more suggestion for GTK Textview -- this is about the margin and indent tags. I found that you can apply those tags anywhere in a line and even multiple times. So in a 100-char line, you can have chars 33-45 with an indent of 100px, and chars 63-88 with an indent of -50px, etc. And in addition various left-margins. When you move the cursor through such a line, the cursor bounces around like crazy and the line is reformatted back and forth. I cannot imagine why anyone would want this. Such tags should only apply to whole lines, and only one indent or left-margin tag per line. As it is, the applied indent and margin tags are hard to manage and cause too much trouble. On Tue, Aug 15, 2017 at 11:34 AM, wrote: > > > Hi Doug, > > I made a bit of a pointer mess there. Not the best of answers or way to go > about iterating through a list. Looking at some GTK code, this is better > done with a for loop. As usual, you don't want to move the pointer you get > from gtk_text_iter_get_tags() and then free it. This will cause you grief > later on along with buggy code that may not be so easy to debug. > > Very glad you got things working well even with a less than good answer. > Need to be careful of the pointers myself. > > Eric > > > GSList *tlist=NULL; > GSList *p=NULL; > tlist=gtk_text_iter_get_tags(&start); > g_print("List %p p %p\n", tlist, p); > for(p=tlist;p;p=p->next) > { > gchar *string=NULL; > g_object_get(G_OBJECT(p->data), "name", &string, NULL); > g_print("p %p %s\n", p, string); > g_free(string); > } > > g_print("List %p\n", tlist); > if(tlist!=NULL) g_slist_free(tlist); > -- Doug McCasland ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: turn on italics in TextView
Have you tried gtk_text_buffer_insert_with_tags_by_name() to insert text with a tag at an iter? What tag combo do you use to get the cursor to bounce around? If I test having two indent tags on the same line, the first one applied wins out. This is what I tested with. Eric /* gcc -Wall move_cursor1.c -o move_cursor1 `pkg-config --cflags --libs gtk+-3.0` Tested on GTK3.18 and Ubuntu16.04 */ #include static void get_style(GtkTextView *tv, GtkMovementStep step, gint count, gboolean extend, gpointer *user_data) { static int i=1; GtkTextIter start; GtkTextMark *mark; GtkTextBuffer *buf; buf=gtk_text_view_get_buffer(GTK_TEXT_VIEW(tv)); mark=gtk_text_buffer_get_insert(buf); gtk_text_buffer_get_iter_at_mark (buf, &start, mark); g_print("Iter %i\n", gtk_text_iter_get_offset(&start)); GSList *tlist=NULL; GSList *p=NULL; tlist=gtk_text_iter_get_tags(&start); g_print("%i. List %p p %p\n", i, tlist, p); i++; for(p=tlist;p;p=p->next) { gchar *string=NULL; g_object_get(G_OBJECT(p->data), "name", &string, NULL); g_print("p %p %s\n", p, string); g_free(string); } g_print("List %p\n", tlist); if(tlist!=NULL) g_slist_free(tlist); } 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), "Move Cursor"); gtk_window_set_default_size(GTK_WINDOW(window), 300, 200); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); GtkWidget *textview=gtk_text_view_new(); gtk_widget_set_vexpand(textview, TRUE); gtk_widget_set_hexpand(textview, TRUE); g_signal_connect(textview, "move-cursor", G_CALLBACK(get_style), NULL); GtkTextBuffer *buffer=gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)); gtk_text_buffer_create_tag(buffer, "ital", "style", PANGO_STYLE_ITALIC, NULL); gtk_text_buffer_create_tag(buffer, "bold", "weight", PANGO_WEIGHT_BOLD, NULL); gtk_text_buffer_create_tag(buffer, "uline", "underline", PANGO_UNDERLINE_SINGLE, NULL); gtk_text_buffer_create_tag(buffer, "indent", "indent", 20, NULL); gtk_text_buffer_create_tag(buffer, "indent2", "indent", 40, NULL); gtk_text_buffer_create_tag(buffer, "left-margin", "left-margin", 20, NULL); gtk_text_buffer_create_tag(buffer, "left-margin2", "left-margin", 40, NULL); GtkTextIter iter; gtk_text_buffer_get_start_iter(buffer, &iter); gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "ital ", -1, "ital", NULL); gtk_text_buffer_get_end_iter(buffer, &iter); gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "bold ", -1, "bold", NULL); gtk_text_buffer_get_end_iter(buffer, &iter); //Check a newline for a tag. gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "uline \n", -1, "uline", NULL); gtk_text_buffer_get_end_iter(buffer, &iter); gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "all\n", -1, "ital", "bold", "uline", NULL); //Check indents in the same line. gtk_text_buffer_get_end_iter(buffer, &iter); gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "indent ", -1, "indent", NULL); gtk_text_buffer_get_end_iter(buffer, &iter); gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "indent2\n", -1, "indent2", NULL); gtk_text_buffer_get_end_iter(buffer, &iter); gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "indent2\n", -1, "indent2", NULL); //Check left-margin in the same line. gtk_text_buffer_get_end_iter(buffer, &iter); gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "left-margin ", -1, "left-margin", NULL); gtk_text_buffer_get_end_iter(buffer, &iter); gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "left-margin2\n", -1, "left-margin2", NULL); gtk_text_buffer_get_end_iter(buffer, &iter); gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "left-margin2", -1, "left-margin2", NULL); GtkWidget *grid=gtk_grid_new(); gtk_container_set_border_width(GTK_CONTAINER(grid), 8); gtk_grid_attach(GTK_GRID(grid), textview, 0, 0, 1, 1); gtk_container_add(GTK_CONTAINER(window), grid); gtk_widget_show_all(window); gtk_main(); return 0; } ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: turn on italics in TextView
Indeed, gtk_text_buffer_insert_with_tags_by_name() does what it says. What I was talking about was (in some future Textview) applying the tag to an iter, then whenever the insert point was on that iter, it would inherit the tag properties set there. So typing at that point gets the formatting. I don't have my code in front of me, but as I recall the jumpy-cursor thing happened with this: 1. Insert some text in a line. 2. Apply indent 50px to whole line. The line will be indented on the screen. 3. Start typing at the beginning of line, which will not inherit the indent tag. The indent will disappear on the screen. 4. Move the cursor to the region with the applied indent -- the indent comes back. On Tue, Aug 15, 2017 at 2:27 PM, wrote: > > Have you tried gtk_text_buffer_insert_with_tags_by_name() to insert text > with a tag at an iter? > > What tag combo do you use to get the cursor to bounce around? If I test > having two indent tags on the same line, the first one applied wins out. > This is what I tested with. > > Eric > > > /* > gcc -Wall move_cursor1.c -o move_cursor1 `pkg-config --cflags --libs > gtk+-3.0` > Tested on GTK3.18 and Ubuntu16.04 > */ > > #include > > static void get_style(GtkTextView *tv, GtkMovementStep step, gint count, > gboolean extend, gpointer *user_data) > { > static int i=1; > GtkTextIter start; > GtkTextMark *mark; > GtkTextBuffer *buf; > > buf=gtk_text_view_get_buffer(GTK_TEXT_VIEW(tv)); > > mark=gtk_text_buffer_get_insert(buf); > gtk_text_buffer_get_iter_at_mark (buf, &start, mark); > g_print("Iter %i\n", gtk_text_iter_get_offset(&start)); > > GSList *tlist=NULL; > GSList *p=NULL; > tlist=gtk_text_iter_get_tags(&start); > g_print("%i. List %p p %p\n", i, tlist, p); > i++; > for(p=tlist;p;p=p->next) > { > gchar *string=NULL; > g_object_get(G_OBJECT(p->data), "name", &string, NULL); > g_print("p %p %s\n", p, string); > g_free(string); > } > > g_print("List %p\n", tlist); > if(tlist!=NULL) g_slist_free(tlist); > } > 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), "Move Cursor"); > gtk_window_set_default_size(GTK_WINDOW(window), 300, 200); > gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); > g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); > > GtkWidget *textview=gtk_text_view_new(); > gtk_widget_set_vexpand(textview, TRUE); > gtk_widget_set_hexpand(textview, TRUE); > g_signal_connect(textview, "move-cursor", G_CALLBACK(get_style), NULL); > > GtkTextBuffer *buffer=gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview) > ); > gtk_text_buffer_create_tag(buffer, "ital", "style", > PANGO_STYLE_ITALIC, NULL); > gtk_text_buffer_create_tag(buffer, "bold", "weight", > PANGO_WEIGHT_BOLD, NULL); > gtk_text_buffer_create_tag(buffer, "uline", "underline", > PANGO_UNDERLINE_SINGLE, NULL); > gtk_text_buffer_create_tag(buffer, "indent", "indent", 20, NULL); > gtk_text_buffer_create_tag(buffer, "indent2", "indent", 40, NULL); > gtk_text_buffer_create_tag(buffer, "left-margin", "left-margin", 20, > NULL); > gtk_text_buffer_create_tag(buffer, "left-margin2", "left-margin", 40, > NULL); > > GtkTextIter iter; > gtk_text_buffer_get_start_iter(buffer, &iter); > gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "ital ", -1, > "ital", NULL); > gtk_text_buffer_get_end_iter(buffer, &iter); > gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "bold ", -1, > "bold", NULL); > gtk_text_buffer_get_end_iter(buffer, &iter); > //Check a newline for a tag. > gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "uline \n", > -1, "uline", NULL); > gtk_text_buffer_get_end_iter(buffer, &iter); > gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "all\n", -1, > "ital", "bold", "uline", NULL); > //Check indents in the same line. > gtk_text_buffer_get_end_iter(buffer, &iter); > gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "indent ", > -1, "indent", NULL); > gtk_text_buffer_get_end_iter(buffer, &iter); > gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "indent2\n", > -1, "indent2", NULL); > gtk_text_buffer_get_end_iter(buffer, &iter); > gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "indent2\n", > -1, "indent2", NULL); > //Check left-margin in the same line. > gtk_text_buffer_get_end_iter(buffer, &iter); > gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "left-margin > ", -1, "left-margin", NULL); > gtk_text_buffer_get_end_iter(buffer, &iter); > gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, > "left-margin2\n", -1, "left-margin2", NULL); > gtk_text_buffer_get_end_iter(buffer, &iter); > gtk_text_buffer_inse
Re: turn on italics in TextView
Indeed I tried your code from Aug 15 and if you insert a character at the beginning of the 3rd or 5th line, the indent/margin disappears. Then if you backspace over that inserted character, the indent/margin re-appears. I tried this in <3.20 and 3.22. Would you consider this a bug? I've never reported a bug to GTK. What is the basic procedure? On Tue, Aug 15, 2017 at 2:38 PM, Doug McCasland wrote: > Indeed, gtk_text_buffer_insert_with_tags_by_name() does what it says. > What I was talking about was (in some future Textview) applying the tag to > an iter, then whenever the insert point was on that iter, it would inherit > the tag properties set there. So typing at that point gets the > formatting. > > I don't have my code in front of me, but as I recall the jumpy-cursor > thing happened with this: > >1. Insert some text in a line. >2. Apply indent 50px to whole line. The line will be indented on the >screen. >3. Start typing at the beginning of line, which will not inherit the >indent tag. The indent will disappear on the screen. >4. Move the cursor to the region with the applied indent -- the indent >comes back. > > > > On Tue, Aug 15, 2017 at 2:27 PM, wrote: > >> >> Have you tried gtk_text_buffer_insert_with_tags_by_name() to insert text >> with a tag at an iter? >> >> What tag combo do you use to get the cursor to bounce around? If I test >> having two indent tags on the same line, the first one applied wins out. >> This is what I tested with. >> >> Eric >> >> >> /* >> gcc -Wall move_cursor1.c -o move_cursor1 `pkg-config --cflags --libs >> gtk+-3.0` >> Tested on GTK3.18 and Ubuntu16.04 >> */ >> >> #include >> >> static void get_style(GtkTextView *tv, GtkMovementStep step, gint count, >> gboolean extend, gpointer *user_data) >> { >> static int i=1; >> GtkTextIter start; >> GtkTextMark *mark; >> GtkTextBuffer *buf; >> >> buf=gtk_text_view_get_buffer(GTK_TEXT_VIEW(tv)); >> >> mark=gtk_text_buffer_get_insert(buf); >> gtk_text_buffer_get_iter_at_mark (buf, &start, mark); >> g_print("Iter %i\n", gtk_text_iter_get_offset(&start)); >> >> GSList *tlist=NULL; >> GSList *p=NULL; >> tlist=gtk_text_iter_get_tags(&start); >> g_print("%i. List %p p %p\n", i, tlist, p); >> i++; >> for(p=tlist;p;p=p->next) >> { >> gchar *string=NULL; >> g_object_get(G_OBJECT(p->data), "name", &string, NULL); >> g_print("p %p %s\n", p, string); >> g_free(string); >> } >> >> g_print("List %p\n", tlist); >> if(tlist!=NULL) g_slist_free(tlist); >> } >> 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), "Move Cursor"); >> gtk_window_set_default_size(GTK_WINDOW(window), 300, 200); >> gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); >> g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); >> >> GtkWidget *textview=gtk_text_view_new(); >> gtk_widget_set_vexpand(textview, TRUE); >> gtk_widget_set_hexpand(textview, TRUE); >> g_signal_connect(textview, "move-cursor", G_CALLBACK(get_style), >> NULL); >> >> GtkTextBuffer *buffer=gtk_text_view_get_buff >> er(GTK_TEXT_VIEW(textview)); >> gtk_text_buffer_create_tag(buffer, "ital", "style", >> PANGO_STYLE_ITALIC, NULL); >> gtk_text_buffer_create_tag(buffer, "bold", "weight", >> PANGO_WEIGHT_BOLD, NULL); >> gtk_text_buffer_create_tag(buffer, "uline", "underline", >> PANGO_UNDERLINE_SINGLE, NULL); >> gtk_text_buffer_create_tag(buffer, "indent", "indent", 20, NULL); >> gtk_text_buffer_create_tag(buffer, "indent2", "indent", 40, NULL); >> gtk_text_buffer_create_tag(buffer, "left-margin", "left-margin", 20, >> NULL); >> gtk_text_buffer_create_tag(buffer, "left-margin2", "left-margin", >> 40, NULL); >> >> GtkTextIter iter; >> gtk_text_buffer_get_start_iter(buffer, &iter); >> gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "ital ", -1, >> "ital", NULL); >> gtk_text_buffer_get_end_iter(buffer, &iter); >> gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "bold ", -1, >> "bold", NULL); >> gtk_text_buffer_get_end_iter(buffer, &iter); >> //Check a newline for a tag. >> gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "uline \n", >> -1, "uline", NULL); >> gtk_text_buffer_get_end_iter(buffer, &iter); >> gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "all\n", -1, >> "ital", "bold", "uline", NULL); >> //Check indents in the same line. >> gtk_text_buffer_get_end_iter(buffer, &iter); >> gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "indent ", >> -1, "indent", NULL); >> gtk_text_buffer_get_end_iter(buffer, &iter); >> gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "indent2\n", >> -1, "indent2", NULL); >> gtk_text_buffer_get_end_iter(buffer
Re: turn on italics in TextView
Hi Doug, I would consider it a usability bug but not necessarily a textview widget bug. If you add text, that doesn't have an indent tag, to the start of the line then it doesn't get indented. I suppose you could check the whole line for an indent tag but that would go against performance. This one might be up to the application developer to deal with. You could use spaces instead of tags depending on what is needed. To tag the inserted text at the start of the line you could check if there is an indent tag, and if there is, apply an indent tag to the newly inserted text. You can check bugzilla to see if there are any bugs reported that are similar. There is a link here. https://www.gtk.org/development.php Eric ... g_signal_connect_after(buffer, "insert-text", G_CALLBACK(insert_text), NULL); ... static void insert_text(GtkTextBuffer *buffer, GtkTextIter *location, gchar *text, gint len, gpointer data) { g_print("Text %s len %i offset %i\n", text, len, gtk_text_iter_get_offset(location)); GtkTextTagTable *table=gtk_text_buffer_get_tag_table(buffer); GtkTextTag *indent_tag=gtk_text_tag_table_lookup(table, "indent"); GtkTextIter *start=gtk_text_iter_copy(location); gtk_text_iter_backward_chars(start, len); if(gtk_text_iter_has_tag(location, indent_tag)) { g_print("Indent Tag\n"); gtk_text_buffer_apply_tag(buffer, indent_tag, start, location); } gtk_text_iter_free(start); } ... ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list