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;

}




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