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

Reply via email to