 |
GTK+ Forums Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
|
|
|
| Author |
Message |
|
|
Wolfgang GTK+ Geek
Joined: 05 Feb 2008 Posts: 53
|
Posted: Fri Aug 29, 2008 7:52 am Post subject: GtkTextView pop-up menu |
|
|
Hello, everybody!
Is there any way to modify default pop-up menu of GtkTextView? In particular - to add own menu item |
|
| Back to top |
|
 |
dreblen Never Seen the Sunlight
Joined: 14 Jun 2007 Posts: 526 Location: Falun, WI USA
|
Posted: Fri Aug 29, 2008 1:51 pm Post subject: |
|
|
you can use the "populate-popup" signal
http://library.gnome.org/devel/gtk/stable/GtkTextView.html#GtkTextView-populate-popup
you can then use GTK's menu related functions of the GtkMenu argument
http://library.gnome.org/devel/gtk/stable/GtkMenu.html
http://library.gnome.org/devel/gtk/stable/GtkMenuItem.html
http://library.gnome.org/devel/gtk/stable/GtkMenuShell.html
here's an example:
| Code: (C) | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| #include <gtk/gtk.h>
void populate_popup(GtkTextView *view, GtkMenu *menu, gpointer user_data)
{
GtkWidget *m;
GtkWidget *i;
gint x;
const gchar *labels[] = {
"Some menu item number 1",
"This is a menu item too",
"this is too",
NULL,
};
i = gtk_separator_menu_item_new();
gtk_menu_shell_append(GTK_MENU_SHELL(menu), i);
gtk_widget_show(i);
i = gtk_menu_item_new_with_label("Some item");
gtk_menu_shell_append(GTK_MENU_SHELL(menu), i);
gtk_widget_show(i);
m = gtk_menu_new();
i = gtk_menu_item_new_with_label("Some menu");
gtk_menu_shell_append(GTK_MENU_SHELL(menu), i);
gtk_menu_item_set_submenu(GTK_MENU_ITEM(i), m);
gtk_widget_show(i);
for(x = 0; labels[x] != NULL; x++)
{
i = gtk_menu_item_new_with_label(labels[x]);
gtk_menu_shell_append(GTK_MENU_SHELL(m), i);
gtk_widget_show(i);
}
}
int main(int argc, char **argv)
{
GtkWidget *win;
GtkWidget *swin;
GtkWidget *view;
gtk_init(&argc, &argv);
win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(G_OBJECT(win), "delete-event", G_CALLBACK(gtk_main_quit), NULL);
swin = gtk_scrolled_window_new(NULL, NULL);
gtk_container_add(GTK_CONTAINER(win), swin);
gtk_widget_show(swin);
view = gtk_text_view_new();
g_signal_connect(G_OBJECT(view), "populate-popup", G_CALLBACK(populate_popup), NULL);
gtk_container_add(GTK_CONTAINER(swin), view);
gtk_widget_show(view);
gtk_widget_show(win);
gtk_main();
return 0;
} | |
|
| Back to top |
|
 |
Wolfgang GTK+ Geek
Joined: 05 Feb 2008 Posts: 53
|
Posted: Mon Sep 01, 2008 5:47 am Post subject: |
|
|
Thank you very much!
And how can I detect click coordinates to know over which text menu appears? |
|
| Back to top |
|
 |
ramesh GTK+ Guru
Joined: 16 Nov 2006 Posts: 173 Location: INDIA
|
Posted: Mon Sep 01, 2008 6:11 am Post subject: |
|
|
| dreblen wrote: | you can use the "populate-popup" signal
http://library.gnome.org/devel/gtk/stable/GtkTextView.html#GtkTextView-populate-popup
you can then use GTK's menu related functions of the GtkMenu argument
http://library.gnome.org/devel/gtk/stable/GtkMenu.html
http://library.gnome.org/devel/gtk/stable/GtkMenuItem.html
http://library.gnome.org/devel/gtk/stable/GtkMenuShell.html
here's an example:
| Code: (C) | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| #include <gtk/gtk.h>
void populate_popup(GtkTextView *view, GtkMenu *menu, gpointer user_data)
{
GtkWidget *m;
GtkWidget *i;
gint x;
const gchar *labels[] = {
"Some menu item number 1",
"This is a menu item too",
"this is too",
NULL,
};
i = gtk_separator_menu_item_new();
gtk_menu_shell_append(GTK_MENU_SHELL(menu), i);
gtk_widget_show(i);
i = gtk_menu_item_new_with_label("Some item");
gtk_menu_shell_append(GTK_MENU_SHELL(menu), i);
gtk_widget_show(i);
m = gtk_menu_new();
i = gtk_menu_item_new_with_label("Some menu");
gtk_menu_shell_append(GTK_MENU_SHELL(menu), i);
gtk_menu_item_set_submenu(GTK_MENU_ITEM(i), m);
gtk_widget_show(i);
for(x = 0; labels[x] != NULL; x++)
{
i = gtk_menu_item_new_with_label(labels[x]);
gtk_menu_shell_append(GTK_MENU_SHELL(m), i);
gtk_widget_show(i);
}
}
int main(int argc, char **argv)
{
GtkWidget *win;
GtkWidget *swin;
GtkWidget *view;
gtk_init(&argc, &argv);
win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(G_OBJECT(win), "delete-event", G_CALLBACK(gtk_main_quit), NULL);
swin = gtk_scrolled_window_new(NULL, NULL);
gtk_container_add(GTK_CONTAINER(win), swin);
gtk_widget_show(swin);
view = gtk_text_view_new();
g_signal_connect(G_OBJECT(view), "populate-popup", G_CALLBACK(populate_popup), NULL);
gtk_container_add(GTK_CONTAINER(swin), view);
gtk_widget_show(view);
gtk_widget_show(win);
gtk_main();
return 0;
} | |
awesome code
for first time click the mouse button opens a popup menu.
again we have to click mouse button to close this popup menu
and again we have to click the mouse button to open popup for second time.
so, here we are clicking 3 times to open popup twise.
is there any way to avoid this 3 times mouse click.
i need to click only to 2 times to open popup twise. |
|
| Back to top |
|
 |
dreblen Never Seen the Sunlight
Joined: 14 Jun 2007 Posts: 526 Location: Falun, WI USA
|
Posted: Mon Sep 01, 2008 11:37 pm Post subject: |
|
|
@Wolfgang - You can use gtk_text_view_get_iter_at_location and the "button-press-event" to get an iter under the cursor.
http://library.gnome.org/devel/gtk/stable/GtkTextView.html#gtk-text-view-get-iter-at-location
Here's an example:
| Code: (C) | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
| #include <gtk/gtk.h>
gboolean button_press_cb(GtkTextView *view, GdkEventButton *ev, gchar **text)
{
GtkTextIter iter, start, end;
gint x, y;
gunichar ch;
/* only do something with RMB */
if(ev->button != 3)
return FALSE;
/* convert the event coords to buffer coords */
gtk_text_view_window_to_buffer_coords(view, GTK_TEXT_WINDOW_WIDGET, ev->x, ev->y, &x, &y);
/* get our starting iter at the new buffer coords */
gtk_text_view_get_iter_at_location(view, &iter, x, y);
/* get the character at the current location */
ch = gtk_text_iter_get_char(&iter);
/* if it's whitespace, then nothing is active */
if(ch == ' ' || ch == '\t' || ch == '\n')
{
*text = NULL;
return FALSE;
}
do
{
/* if we're at the beginning of the buffer, stop */
if(gtk_text_iter_backward_char(&iter) == FALSE)
break;
ch = gtk_text_iter_get_char(&iter);
} while(ch != ' ' && ch != '\t' && ch != '\n');
/* make sure that we have a non-whitespace char */
if(ch == ' ' || ch == '\t' || ch == '\n')
gtk_text_iter_forward_char(&iter);
/* set our start iter */
start = iter;
do
{
/* if we're at the end of the buffer, stop */
if(gtk_text_iter_forward_char(&iter) == FALSE)
break;
ch = gtk_text_iter_get_char(&iter);
} while(ch != ' ' && ch != '\t' && ch != '\n');
end = iter;
/* set *text to the text between start and end */
*text = gtk_text_buffer_get_text(gtk_text_view_get_buffer(view), &start, &end, FALSE);
return FALSE;
}
void populate_popup_cb(GtkTextView *view, GtkMenu *menu, gchar **text)
{
GtkWidget *i;
gchar *s;
/* put a separator in front of our item */
i = gtk_separator_menu_item_new();
gtk_menu_shell_append(GTK_MENU_SHELL(menu), i);
gtk_widget_show(i);
/* this will turn out to be:
* if *text == NULL - "Do something with: <No active text>"
* else - "Do something with: '$*text'"
*/
s = g_strdup_printf("Do something with: %s", (*text == NULL ? "<No active text>" : g_strdup_printf("'%s'", *text)));
i = gtk_menu_item_new_with_label(s);
gtk_menu_shell_append(GTK_MENU_SHELL(menu), i);
gtk_widget_show(i);
}
int main(int argc, char **argv)
{
GtkWidget *win;
GtkWidget *swin;
GtkWidget *view;
gchar *text = NULL;
gtk_init(&argc, &argv);
win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(G_OBJECT(win), "delete-event", G_CALLBACK(gtk_main_quit), NULL);
gtk_container_set_border_width(GTK_CONTAINER(win), 10);
swin = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_container_add(GTK_CONTAINER(win), swin);
gtk_widget_show(swin);
view = gtk_text_view_new();
g_signal_connect(G_OBJECT(view), "button-press-event", G_CALLBACK(button_press_cb), (gpointer)&text);
g_signal_connect(G_OBJECT(view), "populate-popup", G_CALLBACK(populate_popup_cb), (gpointer)&text);
gtk_container_add(GTK_CONTAINER(swin), view);
gtk_widget_show(view);
gtk_widget_show(win);
gtk_main();
return 0;
} | |
|
| Back to top |
|
 |
dreblen Never Seen the Sunlight
Joined: 14 Jun 2007 Posts: 526 Location: Falun, WI USA
|
Posted: Mon Sep 01, 2008 11:52 pm Post subject: |
|
|
@ramesh - You might be able to get creative with the "button-release-event",
http://library.gnome.org/devel/gtk/stable/GtkWidget.html#GtkWidget-button-release-event
I did a quick mockup of using the button-release-event, it's not perfect (e.g. if you release the mouse over an insensitive item
it won't popdown like it's supposed to), but you might be able to expand it
| Code: (C) | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| #include <gtk/gtk.h>
void populate_popup_cb(GtkWidget *wi, GtkMenu *menu, gpointer user_data)
{
g_signal_connect_after(G_OBJECT(menu), "button-release-event", G_CALLBACK(gtk_menu_popdown), NULL);
}
int main(int argc, char **argv)
{
GtkWidget *win;
GtkWidget *swin;
GtkWidget *view;
gtk_init(&argc, &argv);
win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(G_OBJECT(win), "delete-event", G_CALLBACK(gtk_main_quit), NULL);
gtk_container_set_border_width(GTK_CONTAINER(win), 10);
swin = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_container_add(GTK_CONTAINER(win), swin);
gtk_widget_show(swin);
view = gtk_text_view_new();
g_signal_connect(G_OBJECT(view), "populate-popup", G_CALLBACK(populate_popup_cb), NULL);
gtk_container_add(GTK_CONTAINER(swin), view);
gtk_widget_show(view);
gtk_widget_show(win);
gtk_main();
return 0;
} | |
|
| Back to top |
|
 |
ramesh GTK+ Guru
Joined: 16 Nov 2006 Posts: 173 Location: INDIA
|
Posted: Tue Sep 02, 2008 4:53 am Post subject: |
|
|
| dreblen wrote: | @ramesh - You might be able to get creative with the "button-release-event",
http://library.gnome.org/devel/gtk/stable/GtkWidget.html#GtkWidget-button-release-event
I did a quick mockup of using the button-release-event, it's not perfect (e.g. if you release the mouse over an insensitive item
it won't popdown like it's supposed to), but you might be able to expand it
| Code: (C) | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| #include <gtk/gtk.h>
void populate_popup_cb(GtkWidget *wi, GtkMenu *menu, gpointer user_data)
{
g_signal_connect_after(G_OBJECT(menu), "button-release-event", G_CALLBACK(gtk_menu_popdown), NULL);
}
int main(int argc, char **argv)
{
GtkWidget *win;
GtkWidget *swin;
GtkWidget *view;
gtk_init(&argc, &argv);
win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(G_OBJECT(win), "delete-event", G_CALLBACK(gtk_main_quit), NULL);
gtk_container_set_border_width(GTK_CONTAINER(win), 10);
swin = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_container_add(GTK_CONTAINER(win), swin);
gtk_widget_show(swin);
view = gtk_text_view_new();
g_signal_connect(G_OBJECT(view), "populate-popup", G_CALLBACK(populate_popup_cb), NULL);
gtk_container_add(GTK_CONTAINER(swin), view);
gtk_widget_show(view);
gtk_widget_show(win);
gtk_main();
return 0;
} | |
same problem again.
ex:
first am clicking mouse button at a position, then popup opens.
and am clicking mouse button second time in some other area of text view.
popup should have to open at this time also.
but present am getting no popup for second click.(it just closing the first opened popup instead od of opening the new popup) |
|
| Back to top |
|
 |
Wolfgang GTK+ Geek
Joined: 05 Feb 2008 Posts: 53
|
Posted: Tue Sep 23, 2008 1:16 pm Post subject: |
|
|
| Ok, I can handle button-press-event to know over which text menu appears, but what can I do in case with context-menu button on keyboard? And how can I detect reason of context menu appearance (keyboard/mouse)? |
|
| Back to top |
|
 |
|
Powered by phpBB © 2001, 2005 phpBB Group CodeBB 1.0 Beta 2
|