GTK+ Forums Forum Index GTK+ Forums
Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

GtkTextView pop-up menu

 
Post new topic   Reply to topic    GTK+ Forums Forum Index -> GTK+ Programming
Author Message
Wolfgang
GTK+ Geek


Joined: 05 Feb 2008
Posts: 53

PostPosted: Fri Aug 29, 2008 7:52 am    Post subject: GtkTextView pop-up menu Reply with quote

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

PostPosted: Fri Aug 29, 2008 1:51 pm    Post subject: Reply with quote

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

PostPosted: Mon Sep 01, 2008 5:47 am    Post subject: Reply with quote

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

PostPosted: Mon Sep 01, 2008 6:11 am    Post subject: Reply with quote

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

PostPosted: Mon Sep 01, 2008 11:37 pm    Post subject: Reply with quote

@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

PostPosted: Mon Sep 01, 2008 11:52 pm    Post subject: Reply with quote

@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

PostPosted: Tue Sep 02, 2008 4:53 am    Post subject: Reply with quote

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

PostPosted: Tue Sep 23, 2008 1:16 pm    Post subject: Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    GTK+ Forums Forum Index -> GTK+ Programming All times are GMT
Page 1 of 1

 


Powered by phpBB © 2001, 2005 phpBB Group
CodeBB 1.0 Beta 2
Protected by Anti-Spam ACP