Rd: Icons in menus: GtkAccelLabel woes




	This is an addendum to a previous message.  That prior message
was not sent to "gtk-devel-list", so I have included it below.  It may
make more sense to read that first.

	I am now moving this message to "gtk-devel-list" from "gtk-list"
because it appears that something in Gtk+ is broken, and that
GtkAccelLabel may need to be re-implemented.  After this message, I will
not send emails of this thread to "gtk-list".

	If you haven't already, now would be a good time to read the
previous message (attached below) :).

	...the addendum is that I have tried replacing the "hbox" widget
with a table consisting of 1 row and two columns.  My menuitems now look
like this:

GtkMenuItem---------------------------------------------------------
|  table---------------------------------------------------------- |
|  |  pixmap_widget (at 0,1,0,1)  |   GtkAccelLabel (at 1,2,0,1) | |
|  |-------------------------------------------------------------- |
-------------------------------------------------------------------|

	The coords are listed as (left,right,top,bottom) ala'
gtk_table_attach().

	The results are interesting, and perhaps shed some light on the
situation.

	The results of building it like the diagram above are just like
the hbox example of the first message--the "Open" appears, but the
accelerator combination does not.

	Similarly, if I set up the coords like this:

GtkMenuItem---------------------------------------------------------
|  table---------------------------------------------------------- |
|  |  GtkAccelLabel (at 0,1,0,1)   |  pixmap_widget (at 1,2,0,1) | |
|  |-------------------------------------------------------------- |
-------------------------------------------------------------------|

	Then "Open" appears on the left, "_XPM_" appears on the right, and
the generated accel keys are still not visible.

	However, if I set the coords of the "accel_label" to be 0,2,0,1
then the hotkeys *do* show up.  Unfortunately, at that point I have
overlapping table cells and the letters "_XPM_" appear superimposed over
the GtkAccelLabel.

	But at least I can see that the text "Ctrl-P" is being generated
by the GtkAccelLabel.  They are simply not being drawn correctly. I
suspect perhaps that one of the containers is not allocating any space for
the "Ctrl-P" text because it is not a direct child of "GtkMenuItem".
Unfortunately, I do not (yet) understand how the space allocation in Gtk+
works.

	Any suggestions would be greatly appreciated.  I'm currently
working my way through the libgnomeui source to see how they got it to
work, but there are a large number of extraneous macros and structs in
there that don't concern me...

--Derek


---------- Previous message ----------

	I am writing a Gtk+ application.  It will have a standard-looking
menu bar with File, Edit, etc.

	I want to have icons in my menus, so that they look cool like the
Gnome standard menuitems.  I.e., many of the GtkMenuItems will have a
small graphical icon to the left of the text label.

	I also want the hotkeys (Accelerator Key Combitions) to show up on
the right, right-aligned.  Again, this is how the Gnome menus look.  (I do
not want to require the Gnome libs for my application).

	So, my idea was this: I'll create menus manually (because the
GtkItemFactory only allows you to create menus with lables, not pixmaps),
and for each GtkMenuItem in my menus I'll have two things: on the left,
the XPM icon, and on the right, the GtkAccelLabel that you'd normally
expect in a menu.

	Here is a diagram of what I had in mind for my "File" menu:

--------
| File |
-----------------------------
XPM   New              Ctrl+N
XPM   Open...          Ctrl+O
XPM   Save             Ctrl+S
XPM   Exit
-----------------------------

	I was planning to have each GtkMenuItem layed out like this:

GtkMenuItem---------------------------------
|  hbox----------------------------------- |                  
|  |  pixmap_widget    |   GtkAccelLabel | |
|  |-------------------------------------- |
-------------------------------------------|

	...but it does not work.  The GtkAccelLabel will show the regular
text label (the first argument to the gtk_accel_label_new() function) but
it will NOT show any accelerators which have been attached to that
GtkMenuItem.

	So my questions are:

1) Am I doing things correctly, or is there a mistake in my code?

2) If I'm doing things correctly, why aren't the Accel keys showing up?

3) If this is not something that can be made to work, how else would you
handle it?  One idea I've had is writing in the hotkey combinations
manually in a 3-field hbox, using a regular "label", but I'd prefer to
have the accelerators created automatically.

4)  Below is my test program.  It has a "File" menu with "New" and "Open"
menuitems.  The "New" menuitem is created normally with
gtk_menu_item_new_with_label() and works fine, but the "Open" is a test
case for the problem I'm having.

	There is a strange side-effect I don't understand in my test
program. If I place the mouse pointer of the "New" menuitem in my test
program, pressing CTRL+<any letter> changes what the hotkey combination
reads in the "New" GtkAccelLabel.  Why is that?

	As a possible hint of what's going wrong with "Open", I think the
same thing is happening to the "Open" menuitem.  Although I cannot see any
"Ctrl-X" types of string changing, I *can* see the the menu flicker and
expand slightly as I hit Ctrl-C followed by Ctrl-Z (indicating that there 
is a label there that is changing, as is the case with the "New"
menuitem).

	Below is the source code to my test program, called test.c.  It
can be compiled with the command 

cc -o test test.c `gtk-config --cflags --libs`

	...and it shows what I'm talking about.  It is also attached as a
MIME attachment.

	Please take a look (the code is VERY simple) and let me know what
you think.

Thank You,
Derek Simkowiak
dereks@kd-dev.com

-------------- Begin test.c --------------

#include <gtk/gtk.h>

gint Delete (GtkWindow *widget, gpointer data) {
	gtk_main_quit();
	return FALSE;
}


int main(int argc, char *argv[]) {

	GtkWidget *window;	/* Top-level window */
	GtkWidget *menubar;	/* To hold our sample "File" menu */
	GtkWidget *menuitem;	/* Used for the "File","New","Open" MenuItems */
	GtkWidget *submenu;	/* The actual "menu" holding "New", "Open" */

	GtkWidget *hbox;	/* hbox to hold multiple widgets in menuitem */
	GtkWidget *label;	/* text item to put into hbox  */
	GtkAccelGroup *accel;	/* Our accel group */
	GtkWidget *accel_label; /* Our GtkAccelLabel (appears broken?!)*/

	gtk_init(&argc, &argv);

	/* Create top-level window */
	window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	gtk_signal_connect(GTK_OBJECT(window), "delete_event",
		 GTK_SIGNAL_FUNC(Delete), NULL);

	/* Create our accel group, attach it to our top-level window */
	accel = gtk_accel_group_new();
	gtk_accel_group_attach(accel, GTK_OBJECT(window));
	/* The accels are added down below... */

	/* create the menu bar as the only widget in our "window" */
	menubar = gtk_menu_bar_new();
	gtk_container_add(GTK_CONTAINER(window), menubar);
	gtk_widget_show(menubar);

	/* Create the "File" GtkMenuItem */
	menuitem = gtk_menu_item_new_with_label("File");
	gtk_menu_bar_append(GTK_MENU_BAR(menubar), menuitem);
	gtk_widget_show(menuitem);

	/* Create the actual drop-down menu (called "submenu") */
	submenu = gtk_menu_new();
	/* set it to be the submenu of "File" */
	gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);

	/* Create "New" entry in our submenu: */
	menuitem = gtk_menu_item_new_with_label("New");
	gtk_menu_append(GTK_MENU(submenu), menuitem);

	/* Finally, add an accelerator for "New" of CTRL-N */
	gtk_widget_add_accelerator(menuitem, 
	"activate", accel, 'N', GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);

	/* Wrap up the "New" GtkMenuItem by showing it: */
	gtk_widget_show(menuitem);


	/* Create a second GtkMenuItem ("Open") that contains an hbox */
	/* The plan is to have a pixmap AND a GtkAccelLabel, to look like 
	   the Gnome built-in menus... */
	menuitem = gtk_menu_item_new();

	/* Create the hbox, fill it with two things, put it into the menuitem */
	hbox = gtk_hbox_new(FALSE, 0);

	/* Our first (leftmost) hbox item: */
	/* In a real app, this label would be replaced with an icon */
	label = gtk_label_new("_XPM_");
	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 0);
	gtk_widget_show(label);

	/* Our second hbox item, an accel_label which does not show 
	   accelerators!  The "Open" is visible, but "Ctrl-P" is not.

	Why doesn't this show the accelerators? */

	accel_label = gtk_accel_label_new("Open");

	/* We attach it to 'menuitem', which is the GtkMenuItem holding
	   the hbox which is holding the accel_label */

	/* I've tried to make these next 4 lines of code look just like
	   the function gtk_menu_item_new_with_label() in gtkmenuitem.c */

	gtk_misc_set_alignment(GTK_MISC(accel_label), 0.0, 0.5);
	gtk_box_pack_start(GTK_BOX(hbox), accel_label, FALSE, TRUE, 0);
	gtk_accel_label_set_accel_widget(GTK_ACCEL_LABEL(accel_label), menuitem);
	gtk_widget_show(accel_label);
		
	gtk_container_add(GTK_CONTAINER(menuitem), hbox);
	gtk_widget_show(hbox);

	/* All done--add this menuitem to the submenu and show it... */
	gtk_menu_append(GTK_MENU(submenu), menuitem);	
	gtk_widget_show(menuitem);

	/* Now, add an accelerator to the hbox-holding menuitem */
	gtk_widget_add_accelerator(menuitem, 
	"activate", accel, 'P', GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);


	gtk_widget_show(window);

	gtk_main();

	return 0;
}
#include <gtk/gtk.h>

gint Delete (GtkWindow *widget, gpointer data) {
	gtk_main_quit();
	return FALSE;
}


int main(int argc, char *argv[]) {

	GtkWidget *window;	/* Top-level window */
	GtkWidget *menubar;	/* To hold our sample "File" menu */
	GtkWidget *menuitem;	/* Used for the "File","New","Open" MenuItems */
	GtkWidget *submenu;	/* The actual "menu" holding "New", "Open" */

	GtkWidget *hbox;	/* hbox to hold multiple widgets in menuitem */
	GtkWidget *label;	/* text item to put into hbox  */
	GtkAccelGroup *accel;	/* Our accel group */
	GtkWidget *accel_label; /* Our GtkAccelLabel (appears broken?!)*/

	gtk_init(&argc, &argv);

	/* Create top-level window */
	window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	gtk_signal_connect(GTK_OBJECT(window), "delete_event",
		 GTK_SIGNAL_FUNC(Delete), NULL);

	/* Create our accel group, attach it to our top-level window */
	accel = gtk_accel_group_new();
	gtk_accel_group_attach(accel, GTK_OBJECT(window));
	/* The accels are added down below... */

	/* create the menu bar as the only widget in our "window" */
	menubar = gtk_menu_bar_new();
	gtk_container_add(GTK_CONTAINER(window), menubar);
	gtk_widget_show(menubar);

	/* Create the "File" GtkMenuItem */
	menuitem = gtk_menu_item_new_with_label("File");
	gtk_menu_bar_append(GTK_MENU_BAR(menubar), menuitem);
	gtk_widget_show(menuitem);

	/* Create the actual drop-down menu (called "submenu") */
	submenu = gtk_menu_new();
	/* set it to be the submenu of "File" */
	gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);

	/* Create "New" entry in our submenu: */
	menuitem = gtk_menu_item_new_with_label("New");
	gtk_menu_append(GTK_MENU(submenu), menuitem);

	/* Finally, add an accelerator for "New" of CTRL-N */
	gtk_widget_add_accelerator(menuitem, 
	"activate", accel, 'N', GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);

	/* Wrap up the "New" GtkMenuItem by showing it: */
	gtk_widget_show(menuitem);


	/* Create a second GtkMenuItem ("Open") that contains an hbox */
	/* The plan is to have a pixmap AND a GtkAccelLabel, to look like 
	   the Gnome built-in menus... */
	menuitem = gtk_menu_item_new();

	/* Create the hbox, fill it with two things, put it into the menuitem */
	hbox = gtk_hbox_new(FALSE, 0);

	/* Our first (leftmost) hbox item: */
	/* In a real app, this label would be replaced with an icon */
	label = gtk_label_new("_XPM_");
	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 0);
	gtk_widget_show(label);

	/* Our second hbox item, an accel_label which does not show 
	   accelerators!  The "Open" is visible, but "Ctrl-P" is not.

	Why doesn't this show the accelerators? */

	accel_label = gtk_accel_label_new("Open");

	/* We attach it to 'menuitem', which is the GtkMenuItem holding
	   the hbox which is holding the accel_label */

	/* I've tried to make these next 4 lines of code look just like
	   the function gtk_menu_item_new_with_label() in gtkmenuitem.c */

	gtk_misc_set_alignment(GTK_MISC(accel_label), 0.0, 0.5);
	gtk_box_pack_start(GTK_BOX(hbox), accel_label, FALSE, TRUE, 0);
	gtk_accel_label_set_accel_widget(GTK_ACCEL_LABEL(accel_label), menuitem);
	gtk_widget_show(accel_label);
		
	gtk_container_add(GTK_CONTAINER(menuitem), hbox);
	gtk_widget_show(hbox);

	/* All done--add this menuitem to the submenu and show it... */
	gtk_menu_append(GTK_MENU(submenu), menuitem);	
	gtk_widget_show(menuitem);

	/* Now, add an accelerator to the hbox-holding menuitem */
	gtk_widget_add_accelerator(menuitem, 
	"activate", accel, 'P', GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);


	gtk_widget_show(window);

	gtk_main();

	return 0;
}


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