RE: how to position a gtk submenu on top of gtkmenu



Hi Shankar....
I have faced the same problem, while developing an application for mobile.
The am just suggesting you, based on whatever I did. This may not be the
intended solution.
For your Main Menu don't attach a sub menu. On click of the item pop up
another main menu. You can position this Main menu so as to look as a sub
menu.

Rgds,
Madhusudan E 
- 9980527224


 
-----Original Message-----
From: gtk-app-devel-list-bounces gnome org
[mailto:gtk-app-devel-list-bounces gnome org] On Behalf Of shankar rajan
Sent: Thursday, March 22, 2007 2:59 PM
To: gtk-app-devel-list gnome org
Subject: how to position a gtk submenu on top of gtkmenu

Hi ALl,
I have  a strange requirement. I am developing an application for mobile
where menubar is at the bottom.
I have menu popping up from menubar and I am also able to position it using
GtkMenuPositionFunc. However if the main menu has a sub menu for one of the
gtk item in it, the GtkMenuPositionFunc doesn't seem to have any affect for
positioning the sub menu. It always appears by the side of the main menu
item though I am positioning it some where else.( overlapping the main menu
because of mobile screen size.) How do I fix this issue. Kindly help.
I am pasting the entire code here for your sake.
Regards,
Shankvio



#include <stdio.h>

#include <gtk/gtk.h>

#include <gdk/gdkkeysyms.h>



static gboolean button_press (GtkWidget *, GdkEvent *);

static void menuitem_response (gchar *);

static gboolean submenuitem_response (GtkWidget  *menu_item, gpointer
user_data);

GtkWidget *menu_bar;

GtkWidget *vbox;



/* Print a string when a menu item is selected */



static void menuitem_response( gchar *string )

{


    printf ("%s\n", string);

//    gtk_main_quit();

}



void callback( GtkWidget *widget,

               gpointer   data )

{

        gtk_main_quit();

}





GtkWidget *menu_items;

GtkWidget *menu;

GtkWidget *menu_items_sub;

int main( int   argc,

          char *argv[] )

{



    GtkWidget *window;

//    GtkWidget *menu_bar;

    GtkWidget *root_menu;

    GtkWidget *button;

    GtkWidget *menu1;

    char buf[128];

    int i;



    gtk_init (&argc, &argv);



    /* create a new window */

    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

    gtk_widget_set_size_request (GTK_WIDGET (window), 400, 200);

    gtk_window_set_title (GTK_WINDOW (window), "GTK Menu Test");

    g_signal_connect (G_OBJECT (window), "delete_event",

                      G_CALLBACK (gtk_main_quit), NULL);



    /* Init the menu-widget, and remember -- never

     * gtk_show_widget() the menu widget!! 

     * This is the menu that holds the menu items, the one that

     * will pop up when you click on the "Root Menu" in the app */

    menu = gtk_menu_new ();

    menu1 = gtk_menu_new ();



    /* Next we make a little loop that makes three menu-entries for
"test-menu".

     * Notice the call to gtk_menu_shell_append.  Here we are adding a list
of

     * menu items to our menu.  Normally, we'd also catch the "clicked"

     * signal on each of the menu items and setup a callback for it,

     * but it's omitted here to save space. */



    for (i = 0; i < 5; i++)

        {

            /* Copy the names to the buf. */

            sprintf (buf, "Submenu - %d", i);



            /* Create a new menu-item with a name... */

            menu_items_sub = gtk_menu_item_new_with_label (buf);



            /* ...and add it to the menu. */

            gtk_menu_shell_append (GTK_MENU_SHELL (menu1), menu_items_sub);



            /* Do something interesting when the menuitem is selected */

            g_signal_connect_swapped (G_OBJECT (menu_items_sub), "activate",

                                      G_CALLBACK (menuitem_response), 

                                      (gpointer) g_strdup (buf));



            /* Show the widget */

            gtk_widget_show (menu_items_sub);

        }



    for (i = 0; i < 7; i++)

        {

            /* Copy the names to the buf. */

            sprintf (buf, "Test-Mainundermenu - %d", i);



            /* Create a new menu-item with a name... */

            menu_items = gtk_menu_item_new_with_label (buf);



            /* ...and add it to the menu. */

            gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_items);



            /* Do something interesting when the menuitem is selected */

            g_signal_connect_swapped (G_OBJECT (menu_items), "activate",

                                      G_CALLBACK (menuitem_response), 

                                      (gpointer) g_strdup (buf));



            /* Show the widget */

            gtk_widget_show (menu_items);

        }



        //gtk_menu_shell_append (GTK_MENU_SHELL (menu_items), menu1);

    /* This is the root menu, and will be the label

     * displayed on the menu bar.  There won't be a signal handler attached,

     * as it only pops up the rest of the menu when pressed. */

    root_menu = gtk_menu_item_new_with_label ("Root Menu");



    gtk_widget_show (root_menu);



    /* Now we specify that we want our newly created "menu" to be the menu

     * for the "root menu" */

    gtk_menu_item_set_submenu (GTK_MENU_ITEM (root_menu), menu);

    gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_items), menu1);



    //g_signal_connect(G_OBJECT (menu1), "event", G_CALLBACK
(submenuitem_response), NULL);

    g_signal_connect(G_OBJECT (menu_items), "activate", G_CALLBACK
(submenuitem_response), (gpointer) menu1);



    /* A vbox to put a menu and a button in: */

    vbox = gtk_vbox_new (FALSE, 0);

    gtk_container_add (GTK_CONTAINER (window), vbox);

    gtk_widget_show (vbox);



    /* Create a menu-bar to hold the menus and add it to our main window */

    menu_bar = gtk_menu_bar_new ();

    gtk_box_pack_end (GTK_BOX (vbox), menu_bar, FALSE, FALSE, 2);

    gtk_widget_show (menu_bar);



    /* Create a button to which to attach menu as a popup */

    button = gtk_button_new_with_label ("press me");

    g_signal_connect_swapped (G_OBJECT (button), "event", G_CALLBACK
(button_press), G_OBJECT (menu));

    //g_signal_connect_swapped (G_OBJECT (button), "event", G_CALLBACK
(button_press), G_OBJECT (menu));



    gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC
(callback), G_OBJECT( menu) );



    gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 2);

    gtk_widget_show (button);



    /* And finally we append the menu-item to the menu-bar -- this is the

     * "root" menu-item I have been raving about =) */

    gtk_menu_shell_append (GTK_MENU_SHELL (menu_bar), root_menu);

    //gtk_widget_set_uposition(menu, 0, 0);



    /* always display the window as the last step so it all splashes on

     * the screen at once. */

    gtk_widget_show (window);



    gtk_main ();



    return 0;

}



/* Respond to a button-press by posting a menu passed in as widget.

 *

 * Note that the "widget" argument is the menu being posted, NOT

 * the button that was pressed. ---------- bcoz of swapping.
 */

static void

submenu_position_func (GtkMenu  *menu,

                             gint     *x,

                             gint     *y,

                             gboolean *push_in,

                             gpointer  user_data)

{

  GtkWidget *widget = GTK_WIDGET (user_data);

  GtkRequisition req;



  gdk_window_get_origin (widget->window, x, y);



  gtk_widget_size_request (GTK_WIDGET (menu), &req);

  *y -= req.height;

  



  *push_in = FALSE;

}



static void

menu_position_func (GtkMenu  *menu,

                             gint     *x,

                             gint     *y,

                             gboolean *push_in,

                             gpointer  user_data)

{

  GtkWidget *widget = GTK_WIDGET (user_data);

  GtkRequisition req;

  GtkRequisition req1;



  gdk_window_get_origin (widget->window, x, y);



  gtk_widget_size_request (GTK_WIDGET (menu), &req);

  gtk_widget_size_request (GTK_WIDGET (widget), &req1);

  *y -= req.height;



  *push_in = FALSE;

}



int flag = 0;

static gboolean button_press( GtkWidget *widget,

                              GdkEvent *event )

{

    gint x, y;

    if (event->key.keyval == GDK_F5)// || event->type == GDK_KEY_PRESS) 

    {

        GdkEventButton *bevent = (GdkEventButton *) event; 

        GtkWidget *menu = gtk_menu_item_get_submenu
(GTK_MENU_ITEM(menu_items));

        gtk_menu_popup (GTK_MENU (widget), NULL, NULL, menu_position_func ,
menu_bar, bevent->button, bevent->time);

        

        return TRUE;

    }



    /* Tell calling code that we have not handled this event; pass it on. */

    return FALSE;

}



static gboolean submenuitem_response (GtkWidget *menu_item, gpointer
user_data)

{

   GdkEvent *event = gtk_get_current_event();

    GtkWidget *submenu = gtk_menu_item_get_submenu
(GTK_MENU_ITEM(menu_item));

    gtk_menu_popup   ( GTK_MENU(submenu), NULL, NULL, submenu_position_func
, menu_bar, 0, gtk_get_current_event_time ());

    

    return TRUE;

}

_______________________________________________
gtk-app-devel-list mailing list
gtk-app-devel-list gnome org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]