Sunteți pe pagina 1din 57

16 Mens

En este captulo se describen los diferentes tipos de mens que ofrece el kit de
herramientas Motif. Tambin presenta una serie de formas de crear mens en una
aplicacin y habla de los temas involucrados en el diseo de sistemas de men.
Mens proporcionan al usuario un conjunto de opciones en una aplicacin sin
complicar su aspecto visual normal. Estos convenientes mini-cajas de
herramientas son esenciales para el usuario que, al igual que un mecnico de
automviles que est ocupado trabajando por debajo del coche, necesita un
acceso rpido y conveniente a sus herramientas sin tener que mirar o alejarse de
su trabajo. La Gua motivo de estilo prev tres diferentes tipos de mens:
PulldownMenus, PopupMenus, y OptionMenus. A pesar de las diferencias entre
los tres tipos de mens, todos ellos proporcionan el acceso fcil y cmodo a la
funcionalidad de la aplicacin.

16.1 Tipos de men


PulldownMenus que se publican desde el men de los mens son ms comunes
en una aplicacin. la figura muestra un ejemplo de un PulldownMenu. El men
aparece cuando el usuario presiona el primer botn del ratn sobre un
CascadeButton. El botn que publica el men suele ser configurable por el
usuario, ya que los usuarios zurdos pueden querer revertir las asignaciones a
botones por defecto. Como se describe en el Captulo 4, La ventana principal ,
CascadeButtons puede visualizarse como ttulos en una barra de men o como
elementos de men en un PulldownMenu. Cuando el CascadeButton es un hijo
de una barra de men, el men se despliega debajo del botn cuando el usuario
hace clic en l. Cuando el CascadeButton es un elemento de un men existente,
el nuevo men aparece a la derecha del elemento; que se refiere a veces como un
men en cascada o un men pullright.

Un PulldownMenu

Bajo ciertas condiciones, puede ser un inconveniente para el usuario para detener
lo que est haciendo, mueva el ratn a la barra del men para desplegar un men,
y luego mover el ratn de nuevo a donde estaba trabajando. Tener que mover el
ratn de distancia, incluso a otra parte de la misma ventana, puede reducir la
productividad.
A PopupMenu es una solucin a este problema ya que puede proporcionar el
acceso inmediato a la funcionalidad de la aplicacin. PopupMenus se registr
utilizando el tercer botn del ratn y se puede visualizar en cualquier lugar de
una aplicacin. En lugar de tener que mover el ratn, el usuario puede
simplemente pulsar el tercer botn del ratn para hacer que aparezca una
PopupMenu en el acto. Este tipo de men no necesita estar asociado con un
elemento de interfaz de usuario visible. De hecho, PopupMenus por lo general se
aparecieron a partir de un rea de trabajo o de otra regin que no est afiliado con
un componente de interfaz de usuario como un pulsador o CascadeButton.El
nico inconveniente de este diseo es que no hay ninguna indicacin para el
usuario principiante que existe el men. La figura muestra una PopupMenu.

Un PopupMenu

El OptionMenu combina las ventajas de un PulldownMenu y un


PopupMenu. Como un PulldownMenu, se registr a partir de un CascadeButton,
pero como un PopupMenu, se puede colocar donde se necesita. El
CascadeButton se utiliza para mostrar la opcin por defecto para el
men. Cuando el usuario presiona el botn, las opciones alternativas se muestran
en un men, como se muestra en la figura. Al igual que un PulldownMenu, un
OptionMenu se invoca utilizando el primer botn del ratn, pero se muestra en la
parte superior de su CascadeButton asociado en lugar de debajo de ella.

un OptionMenu
El uso del tercer botn del ratn para activar PopupMenus est en agudo
contraste con PulldownMenus y OptionMenus, que siempre son invocados por el
primer botn del ratn. Puede parecer confuso para el usuario que algunos mens
son invocados por el primer botn, mientras que otros son invocados por el
tercero. Sin embargo, hay una cierta coherencia en el hecho de que
PulldownMenus y OptionMenus siempre estn asociadas a CascadeButtons, y los
botones siempre se activan por el primer botn del ratn. Al precisar que
PopupMenus utilizar el tercer botn del ratn, el primer botn del ratn es libre
de ser usado para otras actividades en un rea de trabajo de aplicacin, lo cual es
importante ya que PopupMenus puede estallar en cualquier parte de una
aplicacin.
Cuando el usuario publica un men, slo se muestra hasta que el usuario realiza
una seleccin, y luego se retira. En Motif 1.2, el men puede tener una funcin
adicional que permite que pueda ser arrancado, para que as permanezca ha
escrito en su propia ventana. La funcionalidad de corte se activa mediante un
botn especial de corte en el men. El botn muestra una lnea discontinua para
indicar que se puede arrancar el men, como se rompiese un cupn de un
peridico. Cuando el usuario pulsa el botn de corte, el men se coloca en una
ventana separada, y el usuario puede hacer tantas selecciones como le
gustara. La figura muestra una PulldownMenu que proporciona la capacidad de
corte.

Un men desplegable con la funcionalidad de corte

Para hacer mens an ms cmodo de usar, elementos de men pueden


tener mnemotcnicos y aceleradores asociados con ellos. Estos dispositivos son
equivalentes en el teclado que permiten al usuario activar los elementos de men
utilizando el teclado en lugar del ratn. Por ejemplo, en la figura, la letra
subrayada en cada elemento del men es su mnemnico. Mientras que el men es
enviado, el usuario puede escribir el carcter especificado para activar ese
elemento de men. Los aceleradores son combinaciones de teclas que invocan un
elemento de men, incluso cuando no se visualiza el men.Aceleradores suelen
utilizar la tecla CTRL o ALT para distinguirlas de las pulsaciones de teclas
ordinarias que se envan a la aplicacin. Por ejemplo, de nuevo en la figura,
el Ctrl + C acelerador permite al usuario salir de la aplicacin sin acceder al
men.
Antes de sumergirnos en los detalles de la creacin de mens, una palabra de
advertencia a los programadores experimentados X Toolkit est en orden. Motif
no utiliza mtodos normales de Xt para la creacin y gestin de mens. De
hecho, usted no puede usar los mtodos estndar Xt para la creacin o la gestin
de mens sin prcticamente reimplementar el diseo del men del adorno. Si
tiene que trasladar una aplicacin basada en la mirada abierta sobre Motif o
Athena, es probable que tenga que volver a implementar el diseo de su
men. En Xt, lo ms habitual es crear una OverrideShell que contiene un widget
gestor genrico, seguido de un conjunto de pulsadores. Para visualizar el men,
que le abrir la cscara utilizando XtPopup () . El kit de herramientas Motif
abstrae el proceso de creacin y gestin de men con rutinas que hacen que la
cscara opaca para el programador.

16.2 Creacin de mens sencillos


En el Captulo 4, La ventana principal , que utiliza las simples rutinas de
creacin de men para construir la barra de mens y su PulldownMenus
asociado. Estas rutinas estn diseadas para ser plug-and-play rutinas de
conveniencia; sus nicos requisitos son cadenas de compuestos para las etiquetas
de men y una nica funcin de devolucin de llamada que se invoca cuando el
usuario activa cualquiera de los elementos del men.
crea una barra de men, mientras
que XmVaCreateSimplePulldownMenu () genera un PulldownMenu y sus elementos
asociados. Estas funciones toman una lista de argumentos de longitud variable de
parmetros que especifican ni los CascadeButtons para el BarraDeMens o los
elementos del men del PulldownMenu. Tambin se puede pasar pares de
recursos / valor RowColumn especficos para configurar el widget RowColumn
que gestiona los elementos en el men. Las funciones son extremos delanteros de
las rutinas ms primitivas que realmente crean los widgets de subyacentes, lo que
son convenientes para muchas necesidades de creacin de men sencillo. Debe
revisar el captulo 4, La ventana principal, para obtener ms informacin sobre
cmo utilizar estas funciones.
XmVaCreateSimpleMenuBar ()

Motif tambin proporciona rutinas de creacin de simples para crear


PopupMenus y OptionMenus. Tanto XmVaCreateSimplePopupMenu
() y XmVaCreateSimpleOptionMenu () son muy similares a las rutinas para la
creacin de PulldownMenus, por lo que gran parte de la informacin del captulo
4 tambin se aplica a estas funciones.
16.2.1 mens emergentes
La nica diferencia entre XmVaCreateSimplePulldownMenu
() y XmVaCreateSimplePopupMenu () es que esta ltima rutina no tiene un botn
de parmetro para especificar el CascadeButton utiliza para mostrar el
men. Desde PopupMenus no estn asociados con CascadeButtons, este
parmetro no es necesario. el cdigo fuente muestra la creacin de una simple
PopupMenu. funcin XtSetLanguageProc () slo est disponible en X11R5; no
hay una funcin correspondiente en X11R4. XmStringCreateLocalized () slo
est disponible en Motif 1.2; XmStringCreateSimple () es la funcin
correspondiente en Motif 1.1.
/ * Simple_popup.c - demostrar cmo utilizar un simple men emergente.
* Crear una ventana principal que contiene un widget de Dibujo, que
* Muestra un men emergente cuando el usuario presiona el tercer
botn del ratn.

* /
# include <Xm / RowColumn.h>
# include <Xm / MainW.h>
# include <Xm / DrawingA.h>
principal (argc, argv)
int argc;
char * argv [];
{
XmString lnea, cuadrado, crculo, salida, exit_acc;
Widget de nivel superior, main_w, drawing_a, popup_menu;
popup_cb void (), entrada ();
XtAppContext aplicacin;
Funcin XtSetLanguageProc (NULL, NULL, NULL);
toplevel = XtVaAppInitialize (y de aplicaciones, "Demos", NULL, 0,
Y argc, argv, NULL, NULL);
/ * Crear un widget MainWindow que contiene un DrawingArea en
* Su ventana de trabajo.
* /
main_w = XtVaCreateManagedWidget ( "main_w",
xmMainWindowWidgetClass, de nivel superior,
XmNscrollingPolicy, XmAUTOMATIC,
NULO);
/ * Crear un rea de Dibujo - dibujo real no se llevar a cabo.
* /

drawing_a = XtVaCreateManagedWidget ( "drawing_a",


xmDrawingAreaWidgetClass, main_w,
XmNwidth, 500,
XmNheight, 500,
NULO);

line = XmStringCreateLocalized ( "Lnea");


cuadrado = XmStringCreateLocalized ( "cuadrado");
crculo = XmStringCreateLocalized ( "Crculo");
salida = XmStringCreateLocalized ( "Salir");
exit_acc = XmStringCreateLocalized ( "Ctrl + C");
popup_menu = XmVaCreateSimplePopupMenu (drawing_a, "popup",
popup_cb,
XmVaPUSHBUTTON, lnea, 'L', NULL, NULL,
XmVaPUSHBUTTON, cuadrado, 'S', NULL, NULL,
XmVaPUSHBUTTON, crculo, 'C', NULL, NULL,
XmVaSEPARATOR,
XmVaPUSHBUTTON, salida, "x", "Ctrl <Key> c", exit_acc,
NULO);
XmStringFree (lnea);
XmStringFree (cuadrado);
XmStringFree (crculo);
XmStringFree (salida);
XmStringFree (exit_acc);
/ * Despus de crear el men emergente, aadir devolucin de
llamada para todos los eventos de entrada * /
XtAddCallback (drawing_a, XmNinputCallback, de entrada,
popup_menu);

XtRealizeWidget (nivel superior);


XtAppMainLoop (app);
}
/ * Entrada () - llamado en las respuestas a los acontecimientos en el
rea de Dibujo;
* Botn-3 aparece el men.
* /
vaco
entrada (widgets, client_data, call_data)
smbolo grfico;
client_data XtPointer;
call_data XtPointer;
{
Widget emergente = (Widget) client_data;
XmDrawingAreaCallbackStruct * = cbs
(XmDrawingAreaCallbackStruct *) call_data;
si (cbs-> event-> xany.type! = ButtonPress ||
cbs-> event-> xbutton.button! = 3)
regreso;
/ * Coloque el men en el que se produjo el suceso * /
XmMenuPosition (emergente, (XButtonPressedEvent *) (cbs->
evento));
XtManageChild (popup);
}
/ * Popup_cb () - invoca cuando el usuario selecciona un elemento en
el men emergente * /
vaco
popup_cb (menu_item, client_data, call_data)
menu_item Widget;
client_data XtPointer;
call_data XtPointer;
{
int item_no = (int) client_data;
si (item_no == 3) / * se selecciona la salida - salida * /
exit (0);
puts (XtName (menu_item)); / * De lo contrario, slo imprimir la
seleccin * /
}

Este programa crea un widget MainWindow estndar que contiene un widget de


Dibujo. El programa no hace ningn dibujo; es slo un esqueleto que muestra
cmo conectar un PopupMenu. El PopupMenu se ha creado
usando XmVaCreateSimplePopupMenu () con el control DrawingArea como su
padre. El men est elevado cuando el usuario pulsa el botn del ratn en el
tercer DrawingArea, como se muestra en la figura.

La produccin de simple_popup.c
El kit de herramientas Motif no se ocupa de la publicacin de un PopupMenu de
forma automtica, como lo hace con PulldownMenus y OptionMenus, por lo que
debemos vigilar los eventos apropiados nosotros mismos. Usamos
el XmNinputCallback recursos del control DrawingArea para seguir los
acontecimientos, ya que la rutina es llamada cuando una accin de teclado o el
ratn pasa en el widget. En una aplicacin real, usaramos esta rutina para
manejar dibujo tambin. Sin embargo, en este caso, la entrada () rutina slo
busca ButtonPress eventos para el tercer botn del ratn. El men se pasa como
los datos de los clientes a la entrada () .
Si de entrada () ve un evento apropiado, utiliza el XmMenuPosition () rutina
para situar el men en las coordenadas especificadas en el caso de la estructura
de datos. El men se extrae a continuacin utilizando XtManageChild () . En lo
que se refiere a Xt, este mtodo para hacer estallar un men es tcnicamente
incorrecta. Se apoya en el kit de herramientas Motif para simplificar la interfaz
PopupMenu.Para obtener ms informacin, consulte la discusin sobre
apareciendo cuadros de dilogo en el captulo 5, Introduccin a los cuadros de
dilogo . El men contiene cuatro artculos, el ltimo de los cuales tiene el
acelerador Ctrl <clave> C . Cada vez que el usuario presiona CTRL-C en la
aplicacin, la rutina de devolucin de llamada asociado con el men se llama
como si el men se haba aparecido y lasalida tema haba sido
seleccionada. El popup_cb () de rutina o bien imprime el nombre del elemento de
men o sale, segn el elemento que ha seleccionado el usuario. Tenga en cuenta
que el nombre del elemento de men no se corresponde con su etiqueta. Como se
describe en el Captulo 4, La ventana principal , elementos de men se le asigna

automticamente nombres de la forma Button_ n , donde n es asignado en el


orden de la creacin del men, comenzando en 0 (cero).
16.2.2 Mens en cascada
Un men en cascada, o un men pullright, se implementa como un
PulldownMenu muestran a partir de un elemento de men en otro PulldownMenu
o PopupMenu que ya se encuentra presente. El elemento de men que publica el
men en cascada debe ser un CascadeButton. el cdigo fuente se muestra cmo
agregar un men en cascada utilizando las rutinas simples del men. El programa
aade un ancho lneaelemento de men al PopupMenu a partir del cdigo fuente
de este elemento de men es un CascadeButton que los puestos de un
PulldownMenu crea con XmVaCreateSimplePulldownMenu () . Funcin
XtSetLanguageProc () slo est disponible en X11R5; no hay una funcin
correspondiente en X11R4. XmStringCreateLocalized () slo est disponible en
Motif 1.2; XmStringCreateSimple () es la funcin correspondiente en Motif 1.1.
/ * Simple_pullright.c - demostrar cmo hacer un men pullright
* Usando simples rutinas de creacin de men. Crear una ventana
principal que
* Contiene un widget de Dibujo que muestra un men emergente cuando
el
* Usuario pulsa el tercer botn del ratn.
* /
# include <Xm / RowColumn.h>
# include <Xm / MainW.h>
# include <Xm / DrawingA.h>
principal (argc, argv)
int argc;
char * argv [];
{
XmString lnea, cuadrado, crculo, el peso, la salida, exit_acc;
XmString w_one, w_two, w_four, w_eight;
Widget de nivel superior, main_w, drawing_a, cascada, popup_menu,
pullright;
popup_cb void (), set_width (), entrada ();
XtAppContext aplicacin;
Funcin XtSetLanguageProc (NULL, NULL, NULL);
toplevel = XtVaAppInitialize (y de aplicaciones, "Demos", NULL, 0,
Y argc, argv, NULL, NULL);
/ * Crear un widget MainWindow que contiene un DrawingArea en
* Su ventana de trabajo.
* /
main_w = XtVaCreateManagedWidget ( "main_w",
xmMainWindowWidgetClass, de nivel superior,
XmNscrollingPolicy, XmAUTOMATIC,
NULO);

/ * Crear un rea de Dibujo - dibujo real no se llevar a cabo.


* /

drawing_a = XtVaCreateManagedWidget ( "drawing_a",


xmDrawingAreaWidgetClass, main_w,
XmNwidth, 500,
XmNheight, 500,
NULO);

line = XmStringCreateLocalized ( "Lnea");


cuadrado = XmStringCreateLocalized ( "cuadrado");
crculo = XmStringCreateLocalized ( "Crculo");
peso = XmStringCreateLocalized ( "Ancho de lnea");
salida = XmStringCreateLocalized ( "Salir");
exit_acc = XmStringCreateLocalized ( "Ctrl + C");
popup_menu = XmVaCreateSimplePopupMenu (drawing_a, "popup",
popup_cb,
XmVaPUSHBUTTON, lnea, 'L', NULL, NULL,
XmVaPUSHBUTTON, cuadrado, 'S', NULL, NULL,
XmVaPUSHBUTTON, crculo, 'C', NULL, NULL,
XmVaCASCADEBUTTON, peso, 'W',
XmVaSEPARATOR,
XmVaPUSHBUTTON, salida, "x", "Ctrl <Key> c", exit_acc,
NULO);
XmStringFree (lnea);
XmStringFree (cuadrado);
XmStringFree (crculo);
XmStringFree (peso);
XmStringFree (salida);
/ * Crear pullright para el botn de "Ancho de lnea" - este es el
cuarto elemento! * /
w_one = XmStringCreateLocalized ( "1");
w_two = XmStringCreateLocalized ( "2");
w_four = XmStringCreateLocalized ( "4");
w_eight = XmStringCreateLocalized ( "8");
pullright = XmVaCreateSimplePulldownMenu (popup_menu,
"Pullright", * Artculo 3 / men de desplazamiento * /,
set_width,
XmVaPUSHBUTTON, w_one, '1', NULL, NULL,
XmVaPUSHBUTTON, w_two, '2', NULL, NULL,
XmVaPUSHBUTTON, w_four, '4', NULL, NULL,
XmVaPUSHBUTTON, w_eight, '8', NULL, NULL,
NULO);
XmStringFree (w_one);
XmStringFree (w_two);
XmStringFree (w_four);
XmStringFree (w_eight);
/ * Despus de crear el men emergente, aadir devolucin de
llamada para todos los eventos de entrada * /
XtAddCallback (drawing_a, XmNinputCallback, de entrada,
popup_menu);
XtRealizeWidget (nivel superior);
XtAppMainLoop (app);
}

/ * Entrada () - llamado en las respuestas a los acontecimientos en el


rea de Dibujo;
* Botn-3 aparece el men.
* /
vaco
entrada (widgets, client_data, call_data)
smbolo grfico;
client_data XtPointer;
call_data XtPointer;
{
Widget emergente = (Widget) client_data;
XmDrawingAreaCallbackStruct * = cbs
(XmDrawingAreaCallbackStruct *) call_data;
si (cbs-> event-> xany.type! = ButtonPress ||
cbs-> event-> xbutton.button! = 3)
regreso;
/ * Coloque el men en el que se produjo el suceso * /
XmMenuPosition (emergente, (XButtonPressedEvent *) (cbs->
evento));
XtManageChild (popup);
}
/ * Popup_cb () - invoca cuando el usuario selecciona un elemento en
el men emergente * /
vaco
popup_cb (menu_item, client_data, call_data)
menu_item Widget;
client_data XtPointer;
call_data XtPointer;
{
int item_no = (int) client_data;
si (item_no == 4) / * se selecciona la salida - salida * /
exit (0);
puts (XtName (menu_item)); / * De lo contrario, slo imprimir la
seleccin * /
}
/ * Set_width () - que se llama cuando los elementos de la espesura de
la lnea de men pullright
* Son seleccionados.
* /
vaco
set_width (menu_item, client_data, call_data)
menu_item Widget;
client_data XtPointer;
call_data XtPointer;
{
int item_no = (int) client_data;
printf ( "El grosor de lnea =% D0, 1 << item_no);
}

En la llamada a XmVaCreateSimplePulldownMenu () , el PopupMenu se especifica


como el padre del men en cascada. El botn de parmetro se establece en 3 para

indicar que el cuarto punto en el PopupMenu publica el men en cascada. la


figura muestra la salida del programa.

La produccin de simple_pullright.c

16.2.3 Opcin Mens


Un OptionMenu es similar a un PulldownMenu en que ambos estn asociados
con CascadeButtons. Sin embargo, tambin hay varias diferencias importantes
entre los dos tipos de mens. En una OptionMenu, la CascadeButton no es parte
de una barra de men. En su lugar, se crea como el hijo de un widget
RowColumn que tambin contiene una etiqueta.
Otra diferencia es que el men aparece en la parte superior de la CascadeButton,
en lugar de caer por debajo de ella. La etiqueta de la CascadeButton es uno de los
elementos en el men; la CascadeButton muestra la seleccin de men actual. El
kit de herramientas Motif se encarga de la gestin de la PulldownMenu para la
OptionMenu, por lo que su mango no est disponible para usted, ni necesita
ser. Debido al diseo de la OptionMenu, no puede tener mens en cascada.
el cdigo fuente demuestra el uso de XmVaCreateSimpleOptionMenu () . El
programa utiliza un DrawingArea de nuevo, pero ahora el usuario selecciona el
estilo de dibujo de un OptionMenu que se muestra por encima de la de Dibujo.
/ * Simple_option.c - demostrar cmo utilizar un simple men de
opciones.

* Mostrar un
dibujo de
* El men de
* /
# include <Xm
# include <Xm
# include <Xm
# include <Xm
# include <Xm

rea de dibujo. El usuario selecciona el estilo de


opciones.
/
/
/
/
/

RowColumn.h>
MainW.h>
ScrolledW.h>
DrawingA.h>
PushB.h>

principal (argc, argv)


int argc;
char * argv [];
{
XmString draw_shape, lnea, cuadrado, crculo;
Widget de nivel superior, main_w, rc, sw, drawing_a, option_menu,

PB;

option_cb void (), exit ();


XtAppContext aplicacin;
Funcin XtSetLanguageProc (NULL, NULL, NULL);
toplevel = XtVaAppInitialize (y de aplicaciones, "Demos", NULL, 0,
Y argc, argv, NULL, NULL);
/ * Crear un widget MainWindow que contiene un RowColumn
* Reproductor como su ventana de trabajo.
* /
main_w = XtVaCreateManagedWidget ( "main_w",
xmMainWindowWidgetClass, de nivel superior, NULL);
rc = XtVaCreateWidget ( "Fila Col", xmRowColumnWidgetClass,
main_w, NULL);
y la

/ * Dentro RowColumn es el pulsador de salida, el men de opciones

* Ventana que contiene el rea de dibujo desplazado.


* /
pb = XtVaCreateManagedWidget ( "Salir", xmPushButtonWidgetClass,
rc, NULL);
XtAddCallback (pb, XmNactivateCallback, salida, NULL);
draw_shape = XmStringCreateLocalized ( "Draw modo:");
line = XmStringCreateLocalized ( "Lnea");
cuadrado = XmStringCreateLocalized ( "cuadrado");
crculo = XmStringCreateLocalized ( "Crculo");
option_menu = XmVaCreateSimpleOptionMenu (rc, "option_menu",
draw_shape, 'D', 0 / * seleccin del men inicial * /,
option_cb,
XmVaPUSHBUTTON, lnea, 'L', NULL, NULL,
XmVaPUSHBUTTON, cuadrado, 'S', NULL, NULL,
XmVaPUSHBUTTON, crculo, 'C', NULL, NULL,
NULO);
XmStringFree (lnea);
XmStringFree (cuadrado);
XmStringFree (crculo);
XmStringFree (draw_shape);

XtManageChild (option_menu);
/ * Crear un DrawingArea dentro de un ScrolledWindow * /
sw = XtVaCreateManagedWidget ( "SW",
xmScrolledWindowWidgetClass, rc,
XmNscrollingPolicy, XmAUTOMATIC,
NULO);
drawing_a = XtVaCreateManagedWidget ( "drawing_area",
xmDrawingAreaWidgetClass, sw,
XmNwidth, 500,
XmNheight, 500,
NULO);
XtManageChild (RC);
XtRealizeWidget (nivel superior);
XtAppMainLoop (app);
}
la

/ * Option_cb () - invoca cuando el usuario selecciona un elemento de


* Men de opciones
* /
vaco
option_cb (menu_item, client_data, call_data)
menu_item Widget;
client_data XtPointer;
call_data XtPointer;
{
int item_no = (int) client_data;
}

puts (XtName (menu_item));

El diseo de la aplicacin es diferente de la de los ejemplos previos porque se


utiliza un ScrolledWindow separado para el DrawingArea. El widget
RowColumn que contiene la salida botn, el OptionMenu, y el ScrolledWindow
es el rea de trabajo para el MainWindow. la figura muestra la salida del
programa, tanto antes como despus se visualiza el OptionMenu. Observe cmo
la etiqueta de la CascadeButton cambia a medida que selecciona valores
alternativos en el men.

La produccin de simple_option.c

16.3 Diseo de Sistemas de men


Las ventajas de las simples rutinas de creacin de mens son claros. Es fcil para
crear mens con ellos, el cdigo es muy fcil de leer, y el trabajo se hace sin
mucho margen de error. Una vez que el cdigo est escrito, es fcil de modificar
una llamada de funcin, etiquetas, mnemotcnicos, y los aceleradores utilizados
por un men.
Tambin hay algunas desventajas en el uso de las simples funciones de creacin
de men. Uno de los problemas es que requieren una gran cantidad de mayor
para crear un nico men. Si una aplicacin necesita para crear un gran nmero
de mens, tiene que utilizar una gran cantidad de cdigo redundante porque las
simples rutinas de creacin hacen que sea difcil para construir una estructura
iterativa o una funcin para automatizar el proceso. Puesto que las rutinas de
creacin de nombres de los widgets con nombres no nicos, es difcil especificar
etiquetas, mnemotcnicos, y aceleradores en un archivo de recursos. Si estos
valores se establecen utilizando una rutina de creacin, este punto es irrelevante
porque las rutinas codifique los valores. Las sencillas rutinas de creacin tambin
hacen que sea imposible especificar diferentes funciones de devolucin de los
elementos del men.

Para conseguir alrededor de las deficiencias de las simples rutinas de creacin,


vamos a construir un nuevo sistema que es tan fcil de usar, pero ms dinmico y
fcil de modificar. Antes de que podamos construir nuestro nuevo sistema, es
necesario examinar las rutinas avanzadas de creacin de men de Motif y discutir
el diseo general de un sistema de mens. Vamos a empezar con la barra de
mens y PulldownMenus porque casi cada aplicacin utiliza estos
componentes. Por otra parte, todo lo que hay que saber acerca de los mens se
pueden adaptar a partir del diseo de un sistema de mens que utiliza estos
mens.
Vamos a comenzar por examinar los pasos que debes seguir para crear una barra
de men y su PulldownMenus asociada:
Crear un widget RowColumn para su uso como una barra de men
con XmCreateMenuBar () .
Crear cada PulldownMenu usando XmCreatePulldownMenu

()

Crear las opciones de men (pulsadores, ToggleButtons, separadores, etc.)


para cada PulldownMenu.
Crear un CascadeButton para cada men en la barra de mens y adjuntar
el PulldownMenu asociada a la misma.
Gestionar el Men con XtManageChild

()

El programa en el cdigo fuente demuestra estos pasos mediante la creacin de


una barra de men que contiene un nico archivo PulldownMenu. Funcin
XtSetLanguageProc () slo est disponible en X11R5; no hay una funcin
correspondiente en X11R4. XmStringCreateLocalized () slo est disponible en
Motif 1.2; XmStringCreateSimple () es la funcin correspondiente en Motif 1.1.
/ * File_menu.c - demostrar cmo crear una barra de men desplegable y
* Men usando las rutinas de creacin de Motif.
* /
# include <Xm / RowColumn.h>
# include <Xm / MainW.h>
# include <Xm / CascadeB.h>
# include <Xm / SeparatoG.h>
# include <Xm / PushBG.h>
principal (argc, argv)
int argc;
char * argv [];
{

Widget de nivel superior, MainWindow, barra de men, FilePullDown;


XmString LABEL_STR;
XtAppContext aplicacin;
Funcin XtSetLanguageProc (NULL, NULL, NULL);
toplevel = XtVaAppInitialize (y de aplicaciones, "Demos", NULL, 0,
Y argc, argv, NULL, NULL);
MainWindow = XtVaCreateManagedWidget ( "main_w",
xmMainWindowWidgetClass, de nivel superior,
XmNscrollingPolicy, XmAUTOMATIC,
NULO);
BarraDeMens = XmCreateMenuBar (MainWindow, "BarraDeMens", NULL,
0);
/ * Crear el men "Archivo" * /
FilePullDown = XmCreatePulldownMenu (barra de men,
"FilePullDown", NULL, 0);
/ * Crear el botn "Archivo" (adjuntar men mediante los
XmNsubMenuId) * /
LABEL_STR = XmStringCreateLocalized ( "File");
XtVaCreateManagedWidget ( "File",
xmCascadeButtonWidgetClass, barra de men,
XmNlabelString, LABEL_STR,
XmNmnemonic, "F",
XmNsubMenuId, FilePullDown,
NULO);
XmStringFree (LABEL_STR);
/ * Ahora agregue los elementos del men * /
XtVaCreateManagedWidget ( "abierto",
xmPushButtonGadgetClass, FilePullDown, NULL);
XtVaCreateManagedWidget ( "Guardar",
xmPushButtonGadgetClass, FilePullDown, NULL);
XtVaCreateManagedWidget ( "separador",
xmSeparatorGadgetClass, FilePullDown, NULL);
XtVaCreateManagedWidget ( "Salir",
xmPushButtonGadgetClass, FilePullDown, NULL);
XtManageChild (MenuBar);
XtRealizeWidget (nivel superior);
XtAppMainLoop (app);
}

El cdigo sigue los pasos que acabamos de exponer. La barra de men se crea
como un hijo de la MainWindow, y el PulldownMenu se crea como un hijo de la
barra de men. El CascadeButton acta como elArchivo elemento ttulo en la
barra de men, por lo que tambin se crea como el nio de la barra de
men. Tanto el ttulo del men y la PulldownMenu son hijos de la barra de

men. El CascadeButton establece su XmNsubMenuId recurso a la PulldownMenu


de modo que cuando se selecciona el botn, se sabe, que PulldownMenu que se
vea. Cuando se crea un PulldownMenu mediante la rutina de creacin de men
simple, se establece este recurso detrs de las escenas.
Tambin establecemos la etiqueta de la CascadeButton utilizando
el XmNlabelString recursos. Este valor es una cadena de compuesto, al igual que
en la funcin de creacin simple. Si no hubiramos fijado directamente a la
etiqueta, el nombre del widget en s aparecera como la etiqueta, y que se poda
anularlo con una especificacin en un archivo de recursos. Puesto que no estamos
utilizando la rutina de creacin sencilla, podemos elegir si desea o no que difcil
que el cdigo de la etiqueta para el CascadeButton. Despus creamos los
elementos en el men, administramos el BarraDeMens usando XtManageChild
() . La salida del cdigo fuente, tanto antes como despus de la PulldownMenu
se publica, se muestra en la figura.

La produccin de file_menu.c

16.3.1 ttulos de los mens


Los ttulos en una barra de men son en realidad las etiquetas de los
CascadeButtons. Las etiquetas pueden ser especificados usando

las XmNlabelString de recursos, ya sea en el cdigo de la aplicacin o en un


archivo de recursos. Cada CascadeButton debe tener un submen asociado a l a
travs de la XmNsubMenuId de recursos. Cuando el usuario selecciona el
CascadeButton, se muestra el PulldownMenu asociado. Nunca se debe adjuntar
una funcin de devolucin de llamada directamente a un CascadeButton En el
men lateral, ya que podra confundir al usuario. Funciones de devolucin de
llamada slo deben estar unidos a elementos de men en PulldownMenus que se
publican desde la barra de men.
El PulldownMenu que est asociado con un CascadeButton se crea
utilizando XmCreatePulldownMenu () . Esta rutina devuelve el widget RowColumn
que gestiona los elementos de men. La rutina crea la RowColumn como hijo de
un widget MenuShell. Desde la rutina vuelve del widget RowColumn, la lista de
recursos proporcionada a la funcin slo establece recursos para el widget
RowColumn, no para el MenuShell que lo contiene.
Ttulos de los mens no deben ser creadas o destruidas de forma dinmica. Una
aplicacin no debe hacer que el BarraDeMens desaparecer o aadir nuevos
ttulos a la BarraDeMens mientras se ejecuta la aplicacin. Todos los ttulos de
la BarraDeMens debe estar disponible para el usuario cuando el MainWindow
es visible. Puede, sin embargo, desactivar un men completo, cambiando
el XmNsensitive de recursos en el widget CascadeButton que acta como su
ttulo, como se discute en la Seccin #smenusens.
16.3.2 Elementos de men
Los elementos de un men son en realidad las etiquetas de los botones que
componen el men. A diferencia del Archivo elemento ttulo en la barra de
men, optamos por no utilizar valores no modificables para las cadenas de
elementos de men, por lo que las cadenas se pueden establecer en un archivo de
recursos. Si bien nuestro men slo contiene aparatos de botn, un
PulldownMenu tambin puede contener ToggleButtons, separadores y
CascadeButtons.
Puede instalar una rutina de devolucin de llamada para cada uno de los
elementos de un men, o puede instalar un XmNentryCallback para el widget
RowColumn para actuar en nombre de todos los elementos de men. Este recurso
especifica una funcin de devolucin de llamada que anula
el XmNactivateCallback utilizado por pulsadores y
la XmNvalueChangedCallback utilizado por ToggleButtons. El uso de este recurso
genera un diseo que es similar a las rutinas de men simples descritos

anteriormente. Consulte el Captulo 8, Reproductores Administrador , para


obtener ms informacin sobre este recurso RowColumn genrico.
Al igual que con los artculos del ttulo, elementos de men no deben ser creadas
o destruidas, ya que puede confundir al usuario de forma dinmica. Sin embargo,
hay una excepcin a esta directriz. Si un men contiene elementos que realizan el
seguimiento de una lista dinmica de objetos, tales como los archivos abiertos en
un editor de texto, los elementos de men deben cambiar para reflejar el estado
actual de la aplicacin.
16.3.3 mnemnicos
Mnemotcnicos ayudan a los usuarios atraviesan el sistema de mens y
seleccionar opciones de men reales sin tener que usar el ratn. En el cdigo
fuente se utiliz el XmNmnemonic recurso para fijar el nemotcnico "F" para
el archivo de men, que permite al usuario utilizar la secuencia de teclas ALT-F
para abrir o cerrar el men sin utilizar el ratn. El XmNmnemonic recurso se define
por la clase de etiqueta, pero slo es utilizado por pulsadores, ToggleButtons y
CascadeButtons cuando estos objetos se utilizan en un sistema de men.
Una tecla de acceso est representado visualmente por el subrayado del carcter
mnemnico en la cadena de etiqueta. En este caso, la "F" en la palabra "Archivo"
est subrayada. Si la etiqueta no contiene el carcter mnemotcnico, no hay
retroalimentacin visual para el mnemnico, pero todava funciona. Cuando se
especifica una regla mnemotcnica, el personaje puede estar en mayscula o
minscula, pero la distincin slo afecta a qu letra est subrayada. Para fines
operativos, mnemotcnicos son sensibles a maysculas.
Nuestro ejemplo slo proporcion una tecla de acceso para todo el men, pero
mnemotcnicos se puede establecer en los elementos del men tambin. Cuando
se muestra un PulldownMenu, el usuario puede activar un elemento de men con
slo escribir la letra representada por su mnemnico. (La tecla ALT no se utiliza
una vez que se visualiza el men.) Si el usuario activa un elemento del men
utilizando una tecla de acceso, la funcin de devolucin de llamada para el men
se llama igual que si el usuario ha seleccionado con el ratn.
Mnemotcnicos se establecen en ttulos barra de mens y opciones de men en la
misma forma. Para ilustrar esto, vamos a aadir una tecla de acceso a
la salida artculo en nuestro archivo de men. Podemos configurar la tecla de
acceso directo en la declaracin del tema, de la siguiente manera:
XtVaCreateManagedWidget ( "Salir",
xmPushButtonGadgetClass, FilePullDown,

XmNmnemonic, 'X',
NULO);

Si bien este mtodo lleva a cabo la tarea, un problema con esto es que la tecla de
acceso est codificada en el widget, mientras que la etiqueta no lo es. Considere
la siguiente especificacin de recursos en un archivo de recursos:
* Exit.labelString: Quit

Este recurso define la etiqueta para el botn de elemento en "Salir", pero desde el
mnemnico para el botn no es modificable a "x", hay una retroalimentacin
visual, y la tecla de acceso en s es contrario a la intuicin.
La mejor manera de manejar esta situacin es especificar tanto la cadena de la
etiqueta y la tecla de acceso en el mismo lugar: un archivo de recursos o cdigo
de la aplicacin. Por ejemplo:
* Exit.labelString: Salir
* Exit.mnemonic: x

Ajuste de los dos de estos recursos de la misma manera ayuda a garantizar que
una aplicacin tiene una interfaz consistente.
16.3.4 Aceleradores
El propsito de los aceleradores de men es proporcionar al usuario la capacidad
de activar elementos de men en un PulldownMenu sin tener que visualizar el
men en absoluto. En la Figura 15-1, la Quitelemento de men muestra el
acelerador Ctrl + C para indicar que el usuario puede pulsar la secuencia de
teclas CTRL-C para activar ese elemento de men y salir de la aplicacin.
Para instalar un acelerador en un elemento de men, utilice el XmNaccelerator de
recursos para especificar la traduccin del acelerador y XmNacceleratorText para
proporcionar informacin visual al usuario.Un efecto secundario de la aplicacin
de aceleradores motivo es que no se puede instalar sus propios aceleradores
utilizando los mtodos estndar proporcionados por el kit de herramientas
intrnseco X (comoXtInstallAccelerators () o XtInstallAllAccelerators
() ). Estas funciones no funcionarn, y que pueden interferir con el mecanismo
del acelerador del adorno al tratar de usarlos. Estos recursos son definidos por la
clase de etiqueta, pero slo funcionan para los pulsadores y ToggleButtons en
mens. La sintaxis para el acelerador es exactamente el mismo que el de una
tabla de traduccin, excepto que no se especifica una funcin de accin con la
secuencia de eventos. El acelerador para la Quit botn en la figura 15-1 se
especifica como "Ctrl <clave> C" . (Para obtener informacin sobre cmo

especificar las tablas de traduccin, consulte el Volumen Cuatro, X Intrinsics del


Kit Manual de programacin .
Sin embargo, la cadena que se muestra para el acelerador no es la misma que la
traduccin del acelerador, ya que sera confuso para la mayora de usuarios. En
su lugar, usted debe mostrar algo as como "^ C" , "Ctrl-C" , o "Ctrl + C" , ya
que estos hacen que sea razonablemente claro lo que se espera que el usuario
escriba. (Esta ltima es la convencin recomendada por la Gua motivo de estilo ,
aunque se utilizan con frecuencia las tres formas.) Desde este recurso especifica
el texto visualizable, no se puede utilizar una cadena de C comn; el texto debe
darse como una cadena compuesta.
Por ejemplo, el cdigo siguiente muestra cmo instalar un acelerador para
la salida botn en el cdigo fuente
char * aceleracin = "Ctrl <clave> C";
XmString accel_text = XmStringCreateLocalized ( "Ctrl + C");
XtVaCreateManagedWidget ( "Salir",
xmPushButtonGadgetClass, FilePullDown,
XmNaccelerator, aceleracin,
XmNacceleratorText, accel_text,
NULO);
XmStringFree (accel_text);

Al igual que con mnemotcnicos, los recursos para el acelerador de s mismo y el


texto se utiliza para mostrar el acelerador o bien se pueden configurar
directamente en el cdigo de aplicacin o especifican en un archivo de
recursos. Tanto de los recursos, deberan especificarse de la misma manera, por
lo que siempre son consistentes.
16.3.5 El men Ayuda
Motif especifica diferentes formas, para que el usuario consiga ayuda. Ella puede
usar las teclas de Ayuda o F1 en el teclado, la Ayuda botn en un cuadro de
dilogo o la Ayuda ttulo en la barra de men.Este ttulo ofrece el ms alto nivel
de ayuda para su aplicacin, por lo que no debe proporcionar demasiados detalles
acerca de las funciones de nivel inferior en el programa. Cuando se crea un
PulldownMenu para este ttulo, se debe proporcionar los elementos que le dan al
usuario el acceso al sistema de ayuda. La figura muestra un comn Ayuda men.

Un men de ayuda desde el men


Las opciones que se muestran en la figura son recomendados por la Gua motivo
de estilo ; si se aplican a su solicitud, usted debe usarlos. Por lo general hay un
elemento en la Ayuda men que le da al usuario una breve descripcin de cmo
utilizar el sistema de ayuda. Debe consultar la Gua motivo de estilo para obtener
detalles sobre qu tipo de ayuda cada una de las selecciones anteriores deberan
proporcionar. Por lo general, es una buena idea tener un elemento que muestra un
ndice del tipo de ayuda que est disponible en una aplicacin. Un ejemplo de
dilogo ndice de la ayuda se muestra en la figura. Vase el Captulo
21, avanzada Dialog , para una discusin de dilogos de ayuda.

Un dilogo ndice de la ayuda

Creacin de una Ayuda men es igual que la creacin de cualquier otro men,
excepto que una vez que se haya creado el CascadeButton, se debe configurar
el XmNmenuHelpWidget recurso para la barra de men. Este recurso especifica qu
CascadeButton se coloca en el extremo derecho de la barra de men, que es
donde el Libro de estilo establece que la Ayuda de men tiene que ser
colocado. el cdigo fuente contiene una rutina que muestra cmo crear
un Ayuda men y adjuntarlo a la barra de men. En este ejemplo, se presenta un
enfoque alternativo para la creacin de ttulos barra de mens y su
PulldownMenus asociado.
vaco
BuildHelpMenu (MenuBar)
BarraDeMens Widget;
{
Widget HelpPullDown, flash;
int i;
char * h_items estticas [] = {
"En Contexto", NULL, "En Ayuda", "En Ventana", "en claves",
"ndice", "Tutorial", "En la versin"
};
/ * * Men de Ayuda /

HelpPullDown = XmCreatePulldownMenu (barra de men,


"HelpPullDown", NULL, 0);
Reproductor = XtVaCreateManagedWidget ( "Ayuda",
xmCascadeButtonWidgetClass, barra de men,
XmNsubMenuId, HelpPullDown,
NULO);
/ * Decir la BarraDeMens que este es el widget ayuda * /
XtVaSetValues (barra de men, XmNmenuHelpWidget, flash, NULL);
/ * Ahora agregue los elementos de men para el men desplegable *

for (i = 0; i <XtNumber (h_items); i ++) {


(si h_items [i]! = NULL) {
Reproductor = XtVaCreateManagedWidget (h_items [i],
xmPushButtonGadgetClass, HelpPullDown, NULL);
XtAddCallback (widgets, XmNactivateCallback,
do_help, h_items [i]);
}
ms
Reproductor = XtVaCreateManagedWidget ( "sep",
xmSeparatorGadgetClass, HelpPullDown, NULL);
}

Gran parte del trabajo necesario para crear un PulldownMenu est involucrado en
la creacin de los elementos del men. Podemos optimizar el cdigo mediante el
uso de un bucle que crea los elementos individuales en base a los nombres
indicados en una matriz esttica. Si desea aadir un nuevo elemento de ayuda a la
lista, slo tiene que aadir su nombre a la h_items lista. Un NULL entrada hace que
un aparato separador que se aade al men. En el cdigo fuente se especifica la
misma funcin de devolucin de llamada para cada elemento en el
men; la client_data es el mismo que el nombre del elemento de men. En la
seccin #smenucreate, ampliamos en este enfoque para construir mens
arbitrarios para la barra de men.
16.3.6 Sensibilidad
Como hemos mencionado anteriormente, ttulos barra de mens y elementos de
men no deben ser creadas o destruidas de forma dinmica. Pueden, sin embargo,
pueden activar o desactivar el uso de XtSetSensitive () . Cuando un
CascadeButton o un elemento de men es insensible , que est en gris, y el
usuario no es capaz de mostrar el men asociado o activar el elemento de men.
Para CascadeButtons, la insensibilidad tiene el efecto adicional de prevenir que el
usuario pueda acceder a cualquiera de los elementos en el men asociado,
incluido el acceso a travs de la mnemotcnica y aceleradores, ya que el men no
se puede visualizar. El men y todos sus artculos son completamente disponible
hasta que la sensibilidad de la CascadeButton se pone a cero. Un mtodo

alternativo para deshabilitar un men completo es fijar el panel PulldownMenu


insensibles. Este enfoque tiene la ventaja de que todava permite al usuario
visualizar el men y ver todos los artculos, al tiempo que los elementos no
disponibles.
Por ejemplo, tener un programa de tratamiento. Si el usuario no est editando un
archivo, no tiene sentido tener el Guardar elemento en el archivo de men sea
seleccionable. Una vez que el usuario inicia la edicin de un archivo,
el Guardar botn est sensibilizado por lo que el usuario puede
seleccionarlo. Dado que el usuario no puede seleccionar el elemento hasta que su
sensibilidad se pone a cero, es importante que la aplicacin lo hace en el
momento apropiado. Otro ejemplo menos realista, pero que podemos demostrar,
implica un elemento de men que aparece un cuadro de dilogo. Mientras que el
dilogo se ha terminado, el usuario no puede volver a seleccionar el elemento del
men. Para los propsitos de esta demostracin, digamos que el Abierto
de elemento aparece un FileSelectionDialog y desensibiliza en s. Cuando se
descarta el cuadro de dilogo, la opcin de men se resensitized. Este
comportamiento no es un gran diseo. El dilogo realmente debe almacenar en
cach, y el elemento de men debe seguir siendo sensible. Si se vuelve a
seleccionar el tema, el dilogo debe volver a asignar o subir a la parte superior de
la pila de ventanas, si es necesario.
Para implementar este comportamiento, especificamos una rutina de devolucin
de llamada para el Abierto de elemento de men que crea un
FileSelectionDialog y establece el elemento insensible. Tambin especificamos
una rutina de devolucin de llamada para el cuadro de dilogo que restablece la
sensibilidad del elemento de men. El fragmento de cdigo en el cdigo fuente
muestra estas rutinas de devolucin de llamada.
/ * Reset_sensitive () - rutina generalizada que restablece el
* Sensibilidad en el widget pasa como el parmetro client_data
* En una llamada a XtAddCallback ().
* /
vaco
reset_sensitive (w, client_data, call_data)
Widget w;
client_data XtPointer;
call_data XtPointer;
{
reset_widget Widget = (Widget) client_data;
XtSetSensitive (reset_widget, true);
}
/ * Open_callback () - la rutina de devolucin de llamada para cuando
el "abierto"

* Opcin de men se selecciona de entre el ttulo "Archivo" en la


barra de men.
* /
vaco
open_callback (menu_item, client_data, call_data)
menu_item Widget;
client_data XtPointer;
call_data XtPointer;
{
Widget de dilogo, padre = menu_item;
/ * Obtener el widget cscara gestor de ventanas asociado con el
elemento * /
while (! XtIsWMShell (padre))
parent = XtParent (padre);
/ * Apagar la sensibilidad para el botn Abrir ... * /
XtSetSensitive (menu_item, false);
de dilogo = XmCreateFileSelectionDialog (padre, "archivos", NULL,
0);
/ * Aadir rutinas de devolucin de llamada para responder a la
seleccin botn OK aqu. * /
/ * Asegrese de que si el dilogo se aspersor cerrado o
destruido, el
* La sensibilidad de menu_item se pone a cero.
* /
XtAddCallback (XtParent (de dilogo), / * El dilogo _parent_ * /
XmNpopdownCallback, reset_sensitive, menu_item);
XtAddCallback (dilogo, XmNdestroyCallback, reset_sensitive,
menu_item);
XtManageChild (de dilogo);
XtPopup (XtParent (de dilogo), XtGrabNone);
}

El open_callback () funcin es llamada cuando el usuario activa


el Abrir elemento de men en el archivo de men. Lo primero
que open_callback () hace es encontrar el widget WMShell cercano asociado
con el elemento de men. No queremos que la MenuShell aqu, ya que
necesitamos un widget no transitorio para actuar como el padre de la
FileSelectionDialog. Si el elemento de men se utiliza como matriz para el
dilogo, cuando el men se extrae hacia abajo, el dilogo tambin se aspersor
cerrado porque es una ventana secundaria.
Hemos establecido la sensibilidad del elemento de men a Falso , lo que impide
que el usuario seleccione el elemento de nuevo. Con el fin de ser notificado
cuando el FileSelectionDialog es despedido, aadimos las rutinas de devolucin
de llamada para XmNpopdownCallback y XmNdestroyCallback . En ambos casos,
el abierto debe ser reiniciado para que el usuario pueda seleccionar de nuevo

elemento de men. La nica cosa en open_callback () es una funcin de


devolucin de llamada que se abre el archivo seleccionado cuando el usuario
selecciona el Aceptar botn. Esta funcionalidad est ms all del alcance de este
captulo; vase el captulo 6, Seleccin de cuadros de dilogo , para ms
detalles.
16.3.7 Corte manual Mens
Motif 1.2 proporciona una nueva caracterstica que permite a los mens para ser
arrancadas y colocadas en ventanas separadas. Desde la perspectiva del usuario,
los mens desprendibles hacen que sea fcil de hacer selecciones de men
repetidas. Normalmente, cuando el usuario publica un men, slo se visualiza
hasta que se hace una seleccin, y luego se retira. Si el men ha sido arrancada,
sin embargo, se muestra en una ventana separada, y el usuario puede hacer tantas
selecciones como quiera sin tener que volver a publicar cada vez.
comportamiento Tear-off se proporciona para todos los tipos de men de Motif,
pero el comportamiento est desactivado por defecto. Cuando la funcionalidad de
corte est habilitado en un men, el primer elemento en el men es un botn de
corte. El botn muestra una lnea discontinua para indicar que el usuario puede
arrancar el men, tanto como hubiera podido abrirse un cupn de un peridico. Si
el usuario selecciona el botn de corte, el men se coloca en una ventana
separada con limitados decoraciones del gestor de ventanas. La ventana se puede
mover, por lo que el usuario puede posicionar en un lugar conveniente. El men
permanece arrancada hasta que el usuario cancela el men pulsando la tecla
ESCAPE dentro de la ventana.
Funcionalidad Tear-off es controlado por el XmNtearOffModel recursos del widget
RowColumn. Este recurso slo es vlido cuando el RowColumn est siendo
utilizado como un PulldownMenu o una PopupMenu. El recurso puede tener uno
de los siguientes valores: XmTEAR_OFF_ENABLED o XmTEAR_OFF_DISABLED . De
manera predeterminada, el recurso se establece en XmTEAR_OFF_DISABLED , por lo
que si se desea proporcionar funcionalidad de corte en los mens de la
aplicacin, se debe establecer el recurso para todos los paneles de men. La
figura muestra una PulldownMenu tanto antes como despus de haber sido
arrancado.

A PulldownMenu antes y despus de haber sido arrancada

Motif no se instala un convertidor de recursos para el XmNtearOffModel de


recursos, pero proporciona una que se puede instalar si desea especificar el
recurso en un archivo de recursos. ElXmRepTypeInstallTearOffModelConverter
() rutina instala el convertidor de recursos para XmNtearOffModel . Esta rutina no
tiene ningn argumento, pero s ganar el premio a nombre de la funcin ms
larga en el kit de herramientas Motif. Una vez instalado el convertidor, puede
utilizar la siguiente especificacin de recursos para habilitar la funcionalidad de
corte para todos los mens:
* TearOffModel: TEAR_OFF_ENABLED

El convertidor no se instala por defecto por razones de compatibilidad hacia


atrs.
Algunas aplicaciones utilizan mens de tal manera que ellos necesitan para
mantener un registro de cuando el men est elevado y el aspersor cerrado. Por
ejemplo, una aplicacin podra utilizar algunos ToggleButtons en un
PulldownMenu para permitir al usuario establecer variables de estado para el
programa. Si la aplicacin tambin ofrece otra interfaz para cambiar las variables,
como una lnea de comandos, la aplicacin necesita saber cuando el men est
elevado para que pueda asegurarse de que los ToggleButtons se establecen de
manera apropiada.

Ahora vamos a decir que esta aplicacin se vuelve a compilar con Motif 1.2. Si el
convertidor de recurso para XmNtearOffModel se han instalado, el usuario puede
habilitar la funcionalidad de corte, y que podra causar que la aplicacin no
funcione correctamente. Si una aplicacin necesita para realizar un seguimiento
de las idas y venidas de los mens, lo que tiene que hacer trabajo extra para los
mens de corte. Puesto que el convertidor no est instalado de forma
predeterminada, el programador puede decidir si desea o no admite la
funcionalidad de corte en este caso. Si la aplicacin se modifica para apoyar a los
mens de corte, entonces se puede instalar el convertidor y permitir al usuario
configurar el recurso en un archivo de recursos. Si su aplicacin no requiere
ningn tratamiento especial de mens, no hay ninguna razn para no permitir la
funcionalidad de corte para todos los mens, ya que realmente es una comodidad
para el usuario.
El widget RowColumn ofrece dos nuevos recursos de devolucin de llamada que
permiten una aplicacin para realizar un seguimiento de los mens de
corte. El XmNtearOffMenuActivateCallback rutina es llamada cuando un men est
arrancada; XmNtearOffMenuDeactivateCallback se llama cuando se desestim el
men arrancada. Estas devoluciones de llamada proporcionan una forma para
llevar a cabo ningn proceso especial que es necesaria para el manejo de mens
de corte.
Motif tambin proporciona acceso al botn de corte con el XmGetTearOffControl
() de rutina. Esta rutina toma un panel de men y devuelve el identificador de
artefacto que el botn de corte en el men, si es que existe. De lo contrario, la
rutina retorna NULL . El botn de corte tiene un aspecto similar al
separador; puede especificar su fondo, el frente y la parte superior e inferior de la
sombra colores utilizando los recursos estndar, as como
la XmNseparatorType recursos. Tambin puede configurar estos recursos en un
archivo de recursos utilizando el nombre del botn, que es TearOffControl .

16.4 tcnicas de creacin del men general


Ahora hemos abordado cada uno de los elementos fundamentales de la barra de
mens y los recursos utilizados para proporcionar al usuario la retroalimentacin
apropiada. Con esta informacin, podemos generalizar la forma en que
construimos MenuBars, que nos permite crear arbitrariamente grandes MenuBars
y PulldownMenus utilizando una cantidad sustancialmente menor de cdigo.
En los ejemplos que siguen, utilizamos muchos de los elementos recomendados
para un estndar de Motif barra de men. Puede ajustar los algoritmos y
estructuras de datos para adaptarse a las necesidades de su propia

aplicacin. Aunque utilizamos los valores codificados de forma rgida por los
recursos de widgets, esta tcnica es de ninguna manera un requisito, ni debe ser
interpretado como uso recomendado.Si se elige especificar los recursos en un
archivo de recursos, debe escribir un archivo por defecto de la aplicacin que
contiene los valores de los recursos apropiados.
16.4.1 Construccin desplegable mens
Vamos a comenzar por la identificacin de cada uno de los atributos de un
elemento de men:
Etiqueta
Mnemotcnico
acelerador
acelerador de texto
rutina de devolucin de llamada
los datos de devolucin de llamada
Con esta informacin, podemos construir una estructura de datos que describe
todos los aspectos importantes de un elemento de men. Definimos
el MenuItem estructura como sigue:
_menu_item typedef struct {
char * etiqueta; / * La etiqueta del elemento * /
clase WidgetClass *; / * Pulsador, etiqueta, separador, ... * /
charlas mnemotcnica; / * Mnemotcnica; NULL si ninguno * /
char * acelerador; / * Acelerador; NULL si ninguno * /
char * accel_text; / * Se convierte en el compuesto cadena * /
void (* devolucin de llamada) (); / * Para llamar a la rutina;
NULL si ninguno * /
callback_data XtPointer; / * Client_data de devolucin de llamada
() * /
} Opcin del men;

Para crear un PulldownMenu, todo lo que tenemos que hacer es inicializar una
matriz de MenuItem estructuras y pasarlo a una rutina que itera a travs de la
matriz y crea los elementos usando la informacin apropiada. Por ejemplo, la
siguiente declaracin describe los elementos de un archivo de men:
Menultem file_items [] = {
{ "Nuevo", y xmPushButtonGadgetClass, 'N',
NULL, NULL, do_open, NEW},

{ "Abrir ...", y xmPushButtonGadgetClass, 'O',


NULL, NULL, do_open, OPEN},
{ "Guardar", y xmPushButtonGadgetClass, 'S',
NULL, NULL, do_save, GUARDA},
{ "Guardar como ...", y xmPushButtonGadgetClass, "A",
NULL, NULL, do_save, salvar_como},
{ "Imprimir ...", y xmPushButtonGadgetClass, 'P',
NULL, NULL, do_print, NULL},
{ "", Y xmSeparatorGadgetClass, NULL,
NULL, NULL, NULL, NULL},
{ "Salir", y xmPushButtonGadgetClass, 'x',
"Ctrl <clave> C", "Ctrl + C", do_quit, NULL},
NULO,
};

Cada elemento de la Menultem estructura de datos est llena de valores por


defecto para cada elemento del men. Si un valor de recurso no es significativa, o
no va a estar codificadas, inicializamos el campo para NULL . Si usted no necesita
una funcin de devolucin de llamada o los datos del cliente para un artculo, el
campo se puede establecer en NULL . El nico campo que no puede ser NULL es la
clase de widgets. La terminacin definitiva NULL en la etiqueta del campo indica
el final de la lista.
No hemos especificado ninguna aceleradores a excepcin de la salida artculo. El
aparato separador es completamente indeterminada, puesto que ninguno de los
recursos, incluso se aplica a los separadores.Este diseo hace modificacin y
mantenimiento muy simple. Si desea agregar un acelerador para
el Guardar punto, todo lo que tiene que hacer es cambiar los campos
correspondientes en la estructura de datos, en lugar de tener que buscar en el
cdigo fuente en busca de donde se crea dicho elemento.
Un punto de inters particular es la forma en que el WidgetClass se inicializa
campo. Se declara como un puntero a una clase Widget en lugar de slo una clase
de widget, por lo que inicializar el campo con la direccin de la variable de clase
widget que se declara en el archivo de cabecera del widget. El uso de y
xmPushButtonGadgetClass es un ejemplo de ello. La estructura debe ser
inicializado de esta manera porque el compilador requiere un valor especfico con
el fin de inicializar una estructura de datos
esttica. El xmPushButtonWidgetClass puntero no tiene un valor hasta que el
programa se est ejecutando en realidad, pero la direccin de la variable tiene un
valor. Una vez que el programa se est ejecutando, el puntero se puede acceder
eliminan las referencias a la clase widget de bienes pulsador.
Ahora podemos escribir una rutina que utiliza el Menultem estructura de datos
para crear un PulldownMenu. El BuildPulldownMenu () funcin se muestra en el
cdigo fuente de los bucles de rutina a travs de cada elemento de un conjunto de

pre-inicializado MenuItem estructuras y crea elementos de men en base a la


informacin. XmStringCreateLocalized () slo est disponible en Motif
1.2;XmStringCreateSimple () es el la funcin correspondiente de Motif
1.1. El XmNtearOffModel recurso slo est disponible en Motif 1.2; no debe ser
especificado en Motif 1.1.
Widget
BuildPulldownMenu (padre, menu_title, menu_mnemonic, tear_off,
artculos)
Widget padre;
char * menu_title, menu_mnemonic;
tear_off booleana;
* Menultem artculos;
{
Widget descolgante, cascada, flash;
int i;
XmString str;
Descolgante = XmCreatePulldownMenu (padre, "_pulldown", NULL, 0);
si (tear_off)
XtVaSetValues (pulldown, XmNtearOffModel, XmTEAR_OFF_ENABLED,
NULL);

str = XmStringCreateLocalized (menu_title);


cascada = XtVaCreateManagedWidget (menu_title,
xmCascadeButtonWidgetClass, padre,
XmNsubMenuId, desplegable,
XmNlabelString, str,
XmNmnemonic, menu_mnemonic,
NULO);
XmStringFree (str);

/ * Ahora agregue los elementos del men * /


for (i = 0; artculos [I] .label = NULL;! i ++) {
widgets = XtVaCreateManagedWidget (artculos [i], .label
* Los artculos [i] .class, desplegable,
NULO);
if (artculos [i] .mnemonic)
XtVaSetValues (Widget, XmNmnemonic, artculos [i]
.mnemonic, NULL);
si (artculos [i]) {.accelerator
str = XmStringCreateLocalized (artculos [i] .accel_text);
XtVaSetValues (flash,
XmNaccelerator, artculos [i] .accelerator,
XmNacceleratorText, str,
NULO);
XmStringFree (str);
}
si (artculos [i] .callback)
XtAddCallback (widgets, XmNactivateCallback,
Artculos [i] .callback, artculos [i]
.callback_data);
}
cascada de retorno;
}

La funcin toma cinco parmetros. Progenitor es un identificador para un widget


BarraDeMens que debe haber sido ya creada, menu_title indica el ttulo del
men, menu_mnemonic especifica el mnemnico,tear_off indica si o no el men
puede ser arrancada y artculos es una gama de MenuItem estructuras.
Lo primero que la rutina hace es crear un PulldownMenu. Dado que el nombre de
este widget no es tan importante, usamos un nombre predefinido, con el prefijo
con un guin, para indicar que el nombre no est destinado a ser referencia en un
archivo de recursos. Este uso del subrayado es nuestro propio convenio, por
cierto, no es uno aprobado por la X Toolkit intrnseco. Se nos ocurri esta "regla
no escrita" porque Xt no tiene esas convenciones de nomenclatura para los
widgets que no deseen que sus recursos especificados externamente.
Despus de crear el PulldownMenu, la rutina crea la CascadeButton que acta
como el ttulo para el men de la barra de men. El nombre del widget se toma
del segundo parmetro, menu_title . La rutina tambin establece el mnemnico y
de la XmNtearOffModel recurso en este punto. Todos los ttulos deben tener
MenuBar mnemnicos asociados con ellos.
Ahora la funcin de bucle a travs de la matriz de MenuItem estructuras que crean
los elementos del men hasta que encuentra una entrada con un NULL nombre de
la etiqueta. Utilizamos este valor como un indicador de fin de men en nuestra
inicializacin. Cuando se crea cada widget, el acelerador, y la funcin
mnemotcnica, devolucin de llamada se aadan slo si se especifican en
el Menultem estructura.
debe llamarse desde otra funcin que pasa a las estructuras
de datos adecuadas y otros parmetros. En nuestro diseo, esto sera la rutina que
crea la propia barra de men. el cdigo fuente muestra el cdigo de
la CreateMenuBar () de rutina. Esta funcin simple crea un widget de barra de
men, llama BuildPulldownMenu () para cada men, gestiona la barra de men, y
lo devuelve a la funcin de llamada.
BuildPulldownMenu ()

Widget
CreateMenuBar (MainWindow)
MainWindow Widget;
{
Widget BarraDeMens, flash, BuildPulldownMenu ();
BarraDeMens = XmCreateMenuBar (MainWindow, "BarraDeMens", NULL,
0);
(void) BuildPulldownMenu (barra de men, "File", "F", es cierto,
file_items);

(Void) BuildPulldownMenu (barra


edit_items);
(void) BuildPulldownMenu (barra
view_items);
(void) BuildPulldownMenu (barra
cierto, options_items);
Reproductor = BuildPulldownMenu
cierto, help_items);

de men, "Editar", "E", es cierto,


de men, "Ver", "V", es cierto,
de men, "Opciones", "O", es
(barra de men, "ayuda", "H", es

XtVaSetValues (barra de men, XmNmenuHelpWidget, flash, NULL);


XtManageChild (MenuBar);
volver BarraDeMens;
}

Cada llamada a BuildPulldownMenu () pasa un vector de preinicializado MenuItem estructuras. La Ayuda men es un caso especial, por lo que
establece la XmNmenuHelpWidget de recursos para que el BarraDeMens s a qu
elemento se trata. Al establecer el recurso a la CascadeButton devuelto por la
funcin, la BarraDeMens sabe que este botn se debe colocar en el extremo
derecho. El nico parmetro a la CreateMenuBar () la funcin es el control
MainWindow que es el padre de la BarraDeMens que se devuelve.
16.4.2 Construccin Mens en cascada
Podemos aadir mens pullright a nuestra metodologa de creacin de mens con
bastante facilidad mediante la adicin a la MenuItem estructura de datos y hacer
una ligera modificacin a laCreatePulldownMenu () funcin. Como hemos
aprendido de las simples rutinas de creacin de men, un men en cascada es
realmente un PulldownMenu que se asocia con un CascadeButton. Tambin
sabemos que podemos adjuntar un men a una CascadeButton estableciendo
el XmNsubMenuId recurso a la manija de la PulldownMenu. Comenzamos por la
modificacin del Menultem estructura de la siguiente manera:
_menu_item typedef struct {
char * etiqueta; / * La etiqueta del elemento * /
clase WidgetClass *; / * Pulsador, etiqueta, separador ... * /
charlas mnemotcnica; / * Mnemotcnica; NULL si ninguno * /
char * acelerador; / * Acelerador; NULL si ninguno * /
char * accel_text; / * Se convierte en el compuesto cadena * /
void (* devolucin de llamada) (); / * Para llamar a la rutina;
NULL si ninguno * /
callback_data XtPointer; / * Client_data de devolucin de llamada
() * /
_menu_item struct * subpuntos; / * Elementos de men pullright, si
no es NULL * /
} Opcin del men;

El nuevo campo en el extremo de la estructura es un puntero a otra matriz


de MenuItem estructuras. Si este puntero no es NULL , el elemento de men tiene un

submen en cascada que se describe por los subpuntos . el cdigo fuente se


muestra un ejemplo de cmo crear un men en cascada. Este programa utiliza
una versin modificada del BuildPulldownMenu () que llama a s mismo para
crear mens en cascada. Funcin XtSetLanguageProc () slo est disponible en
X11R5; no hay una funcin correspondiente en X11R4. XmStringCreateLocalized
() slo est disponible en Motif 1.2; XmStringCreateSimple () es la funcin
correspondiente en Motif 1.1. El XmNtearOffModel recurso slo est disponible en
Motif 1.2; no debe ser especificado en Motif 1.1.
/ * Build_menu.c - Demostrar la rutina BuildPulldownMenu () y
* La forma en que se puede utilizar para crear mens desplegables
pullright -y-.
* Los mens estn definidos por la que se declara una matriz de
estructuras MenuItem.
* /
# include <Xm / RowColumn.h>
# include <Xm / MainW.h>
# include <Xm / DrawingA.h>
# include <Xm / CascadeBG.h>
# include <Xm / PushB.h>
# include <Xm / PushBG.h>
# include <Xm / ToggleB.h>
# include <Xm / ToggleBG.h>
_menu_item typedef struct {
char * etiqueta; / * La etiqueta del elemento * /
clase WidgetClass *; / * Pulsador, etiqueta, separador ... * /
charlas mnemotcnica; / * Mnemotcnica; NULL si ninguno * /
char * acelerador; / * Acelerador; NULL si ninguno * /
char * accel_text; / * Se convierte en el compuesto cadena * /
void (* devolucin de llamada) (); / * Para llamar a la rutina;
NULL si ninguno * /
callback_data XtPointer; / * Client_data de devolucin de llamada
() * /
_menu_item struct * subpuntos; / * Elementos de men pullright, si
no es NULL * /
} Opcin del men;
/ * Mens desplegables estn construidos a partir de los botones en
cascada, por lo que esta funcin
* Tambin incluye mens pullright. Crear el men, el botn de cascada
* Que posee el men, y luego los elementos del submen.
* /
Widget
BuildPulldownMenu (padre, menu_title, menu_mnemonic, tear_off,
artculos)
Widget padre;
char * menu_title, menu_mnemonic;
tear_off booleana;
* Menultem artculos;
{
Widget descolgante, cascada, flash;
int i;
XmString str;

NULL);

Descolgante = XmCreatePulldownMenu (padre, "_pulldown", NULL, 0);


si (tear_off)
XtVaSetValues (pulldown, XmNtearOffModel, XmTEAR_OFF_ENABLED,
str = XmStringCreateLocalized (menu_title);
cascada = XtVaCreateManagedWidget (menu_title,
xmCascadeButtonGadgetClass, padre,
XmNsubMenuId, desplegable,
XmNlabelString, str,
XmNmnemonic, menu_mnemonic,
NULO);
XmStringFree (str);

/ * Ahora agregue los elementos del men * /


for (i = 0; artculos [I] .label = NULL;! i ++) {
/ * Si existen elementos secundarios, crear el men
desplegable de la derecha llamando a este
* La funcin recursiva. Dado que la funcin devuelve una
cascada
* Botn, el widget devuelto se utiliza ..
* /
si (artculos [i] .subitems)
Reproductor = BuildPulldownMenu (descolgante, artculos
[i] .label,
Artculos [i] .mnemonic, tear_off, artculos [i]
.subitems);
ms
widgets = XtVaCreateManagedWidget (artculos [i], .label
* Los artculos [i] .class, desplegable,
NULO);
/ * Si el artculo es un artculo real o un botn con una
cascada
* Men, todava puede tener una tecla de acceso.
* /
if (artculos [i] .mnemonic)
XtVaSetValues (Widget, XmNmnemonic, artculos [i]
.mnemonic, NULL);
/ * Cualquier elemento puede tener un acelerador, excepto
mens en cascada. Pero,
* Que no se preocupe por eso; sabemos mejor en nuestras
declaraciones.
* /
si (artculos [i]) {.accelerator
str = XmStringCreateLocalized (artculos [i] .accel_text);
XtVaSetValues (flash,
XmNaccelerator, artculos [i] .accelerator,
XmNacceleratorText, str,
NULO);
XmStringFree (str);
}
si (artculos [i] .callback)
XtAddCallback (flash,
(Artculos [i] == .class y xmToggleButtonWidgetClass
||
artculos [i] == .class y xmToggleButtonGadgetClass)?

XmNvalueChangedCallback: / * * clase
ToggleButton /

XmNactivateCallback, / * Clase PushButton * /


Artculos [i] .callback, artculos [i]

.callback_data);
}
cascada de retorno;
}

/ * Funciones de devolucin de llamada para los elementos de men


declarado ms tarde ... * /
vaco
set_weight (widgets, client_data, call_data)
smbolo grfico;
client_data XtPointer;
call_data XtPointer;
{
peso = int (int) client_data;
}

printf ( "grosor de lnea ajuste de D0%, en peso);

set_color (widgets, client_data, call_data)


smbolo grfico;
client_data XtPointer;
call_data XtPointer;
{
char * color = (char *) client_data;
}

printf ( "Ajuste de color a S0%, color);

vaco
set_dot_dash (widgets, client_data, call_data)
smbolo grfico;
client_data XtPointer;
call_data XtPointer;
{
int dot_or_dash = (int) client_data;
printf ( "Ajuste de estilo de lnea de% S0, dot_or_dash?" punto
":" guin ");
}
Menultem weight_menu [] = {
{ "1", y xmPushButtonGadgetClass, '1', NULL, NULL,
set_weight, (XtPointer) 1, (Menultem *) NULL},
{ "2", y xmPushButtonGadgetClass, '2', NULL, NULL,
set_weight, (XtPointer) 2, (Menultem *) NULL},
{ "3", y xmPushButtonGadgetClass, '3', NULL, NULL,
set_weight, (XtPointer) 3, (Menultem *) NULL},
{ "4", y xmPushButtonGadgetClass, '4', NULL, NULL,
set_weight, (XtPointer) 4, (Menultem *) NULL},
NULO,
};
Menultem color_menu [] = {

{ "Cyan", y xmPushButtonGadgetClass, "C", "Alt <clave> C", "Alt +


C",

set_color, (XtPointer) "cian", (Menultem *) NULL},


{ "Amarillo", y xmPushButtonGadgetClass, "Y", "Alt <clave> Y",
"Alt + Y",
set_color, (XtPointer) "amarilla", (Menultem *) NULL},
{ "Magenta", y xmPushButtonGadgetClass, "M", "Alt <clave> M", "Alt
+ M",
set_color, (XtPointer) "magenta", (Menultem *) NULL},
{ "Negro", y xmPushButtonGadgetClass, "B", "Alt <clave> B", "Alt +
B",
set_color, (XtPointer) "negro", (Menultem *) NULL},
NULO,
};
Menultem style_menu [] = {
{ "Dash", y xmPushButtonGadgetClass, 'D', NULL, NULL,
set_dot_dash, (XtPointer) 0, (Menultem *) NULL},
{ "Dot", y xmPushButtonGadgetClass, 'O', NULL, NULL,
set_dot_dash, (XtPointer) 1, (Menultem *) NULL},
NULO,
};
Menultem drawing_menus [] = {
{ "Grosor de lnea", y xmCascadeButtonGadgetClass, 'W', NULL,
NULL,
0, 0, weight_menu},
{ "Color de lnea", y xmCascadeButtonGadgetClass, 'C', NULL, NULL,
0, 0, color_menu},
{ "Estilo de lnea", y xmCascadeButtonGadgetClass, 'S', NULL,
NULL,
0, 0, style_menu},
NULO,
};
principal (argc, argv)
int argc;
char * argv [];
{
Widget de nivel superior, main_w, barra de men, drawing_a;
XtAppContext aplicacin;
Funcin XtSetLanguageProc (NULL, NULL, NULL);
toplevel = XtVaAppInitialize (y de aplicaciones, "Demos", NULL, 0,
Y argc, argv, NULL, NULL);
/ * Crear un widget MainWindow que contiene un DrawingArea en
* Su ventana de trabajo.
* /
main_w = XtVaCreateManagedWidget ( "main_w",
xmMainWindowWidgetClass, de nivel superior,
XmNscrollingPolicy, XmAUTOMATIC,
NULO);
barra de men = XmCreateMenuBar (main_w, "menubar", NULL, 0);

BuildPulldownMenu (barra de men, "Lneas", "L", True,


drawing_menus);
XtManageChild (barra de men);
/ * Crear un rea de Dibujo - dibujo real no se llevar a cabo.
* /

drawing_a = XtVaCreateManagedWidget ( "drawing_a",


xmDrawingAreaWidgetClass, main_w,
XmNwidth, 500,
XmNheight, 500,
NULO);

XtRealizeWidget (nivel superior);


XtAppMainLoop (app);

La mayor parte de este programa se compone de la nueva versin


de BuildPulldownMenu () y las declaraciones de los mens y submens. Todos los
mens y sus elementos se declaran en orden inverso, porque debe existir la
declaracin men en cascada antes de que realmente se hace referencia en el
men. La salida del programa se muestra en la figura.

La produccin de build_menu.c
Todo lo que tenemos que hacer para conseguir BuildPulldownMenu () para crear
un men en cascada es aadir cdigo que comprueba si el men actual tiene un
submen. Si lo hace, la rutina llama a s misma para crear el submen. Debido a
que la funcin crea y devuelve un CascadeButton, el valor de retorno se puede
utilizar como el elemento de men en el men que se est construyendo
actualmente. Tenemos que crear el men en cascada en primer lugar porque tiene
que existir antes de que se pueda asociar a un CascadeButton. La recursividad se
ocupa de este problema para nosotros mediante la creacin de los submens ms
profundo en primer lugar, lo que asegura que todos los submens necesarios
estn construidos antes de que sus CascadeButtons ellos requieren.

Tambin hemos aadido soporte para ToggleButtons a esta versin


de BuildPulldownMenu () , a pesar de que nuestros mens no contienen ningn
ToggleButtons. El nico cambio que tenemos que hacer aqu implica la funcin
de devolucin de llamada. Desde ToggleButtons tienen
un XmNvalueChangedCallback , mientras PushButton tienen
un XmNactivateCallback , que compruebe que se aade la clase del tema y
especifique el recurso de devolucin de llamada apropiado en nuestra llamada
a XtAddCallback () .
16.4.3 Construccin mens emergentes
Para demostrar an ms la flexibilidad de nuestro diseo y explotar las
similitudes entre PulldownMenus, PopupMenus y mens en cascada, se puede
modificar fcilmente la BuildPulldownMenu () rutina para apoyar cualquiera de
estos tipos de men. Tan slo hay que especificar un nuevo parmetro que indica
cul de los dos tipos de men para su uso. Desde Motif ya define los
valores XmMENU_PULLDOWN yXmMENU_POPUP en < Xm / Xm.h >, usamos esos
valores. Tambin hemos dado la funcin de un nombre ms genrico, BuildMenu
() , como se muestra en el cdigo fuente XmStringCreateLocalized () slo est
disponible en Motif 1.2; XmStringCreateSimple () es la funcin correspondiente
en Motif 1.1. El XmNtearOffModel recurso slo est disponible en Motif 1.2; no
debe ser especificado en Motif 1.1.
Widget
BuildMenu (padre, menu_type, menu_title, menu_mnemonic, tear_off,
artculos)
Widget padre;
int menu_type;
char * menu_title, menu_mnemonic;
tear_off booleana;
* Menultem artculos;
{
men flash, cascada, flash;
int i;
XmString str;

NULL);

si (== menu_type XmMENU_PULLDOWN)


menu = XmCreatePulldownMenu (padre, "_pulldown", NULL, 0);
ms
menu = XmCreatePopupMenu (padre, "_popup", NULL, 0);
si (tear_off)
XtVaSetValues (men, XmNtearOffModel, XmTEAR_OFF_ENABLED,
si (== menu_type XmMENU_PULLDOWN) {
str = XmStringCreateLocalized (menu_title);
cascada = XtVaCreateManagedWidget (menu_title,
xmCascadeButtonGadgetClass, padre,
XmNsubMenuId, men,

XmNlabelString, str,
XmNmnemonic, menu_mnemonic,
NULO);
XmStringFree (str);

/ * Ahora agregue los elementos del men * /


for (i = 0; artculos [I] .label = NULL;! i ++) {
/ * Si existen elementos secundarios, crear el men
desplegable de la derecha llamando a este
* La funcin recursiva. Dado que la funcin devuelve una
cascada
* Botn, el widget devuelto se utiliza ..
* /
si (artculos [i] .subitems)
Reproductor = BuildMenu (men, XmMENU_PULLDOWN, artculos
[i] .label,
Artculos [i] .mnemonic, tear_off, artculos [i]
.subitems);
ms
widgets = XtVaCreateManagedWidget (artculos [i], .label
* Los artculos [i] .class, men,
NULO);
/ * Si el artculo es un artculo real o un botn con una
cascada
* Men, todava puede tener una tecla de acceso.
* /
if (artculos [i] .mnemonic)
XtVaSetValues (Widget, XmNmnemonic, artculos [i]
.mnemonic, NULL);
/ * Cualquier elemento puede tener un acelerador, excepto
mens en cascada. Pero,
* Que no se preocupe por eso; sabemos mejor en nuestras
declaraciones.
* /
si (artculos [i]) {.accelerator
str = XmStringCreateLocalized (artculos [i] .accel_text);
XtVaSetValues (flash,
XmNaccelerator, artculos [i] .accelerator,
XmNacceleratorText, str,
NULO);
XmStringFree (str);
}
/ * De nuevo, cualquier persona puede tener una devolucin de
llamada - sin embargo, esta es una
* Activar-devolucin de llamada. Esto puede no ser adecuado
para todos los elementos.
* /
si (artculos [i] .callback)
XtAddCallback (flash,
(Artculos [i] == .class y xmToggleButtonWidgetClass ||
artculos [i] == .class y xmToggleButtonGadgetClass)?
XmNvalueChangedCallback: / * * clase
ToggleButton /
XmNactivateCallback, / * Clase PushButton * /
Artculos [i] .callback, artculos [i]
.callback_data);

}
volver menu_type == XmMENU_POPUP? Men: cascada;

Toda la funcionalidad original se mantiene; slo aadimos un par de lneas para


apoyar mens emergentes. Es decir, cuando XmMENU_POPUP se pasa como
el menu_type parmetro, la funcin XmCreatePopupMenu () se llama, y se devuelve
el propio men. De lo contrario la rutina devuelve un CascadeButton. Si
cualquiera de los elementos del men tienen mens en cascada, que continuar lo
que hacamos antes para los submens.
Para utilizar esta rutina en una aplicacin, tendramos que crear el PopupMenu
como el hijo de otro widget y establecer una rutina de devolucin de llamada
para publicar el men, tal como lo hicimos con la simple rutina de creacin de
men. Desde mnemotcnicos no se utilizan normalmente para PopupMenus, los
campos mnemotcnicos en la estructura de datos deben ser especificados
como NULL .
Ahora podemos construir PopupMenus, pero lo que realmente necesitamos
hablar es cuando se debe utilizar en una aplicacin PopupMenus. La Gua motivo
de estilo tiene muy poco que decir acerca de cundo y cmo se deben utilizar los
mens emergentes. Una de las directrices es que PopupMenus slo debe
utilizarse como un medio redundantes de activacin de funciones de la
aplicacin, ya que no se hacen evidentes para el usuario. El nico requisito es que
PopupMenus utilizar el botn del ratn en tercer lugar, lo que lleva a la pregunta:
cmo obtener los eventos necesarios en un widget de arbitraria por lo que se
puede hacer aparecer un men?
En nuestros ejemplos anteriores PopUpMenu, hemos utilizado el control
DrawingArea debido a su capacidad para realizar un seguimiento de este tipo de
eventos de entrada a travs de una rutina de devolucin de llamada. Sin embargo,
para todos los otros controles, la solucin no es tan sencilla. Por desgracia, el
diseo de PopupMenus en el kit de herramientas Motif requiere que cavar en los
mecanismos Xt de gestin de eventos de nivel inferior con el fin de publicar un
PopupMenu. Podemos continuar la construccin de mens de la misma
manera; es slo que tenemos que hacer un poco de trabajo para hacer estallar
para arriba.
el cdigo fuente se muestra cmo mostrar un PopupMenu para un widget de
arbitraria. Aqu, nosotros usamos eventos en un widget pulsador para mostrar un
PopupMenu, pero el men podra ser activado desde cualquier tipo de
widget. Este programa utiliza el BuildMenu () de rutina a partir del cdigo fuente,

as que no lo muestran en este ejemplo. Funcin XtSetLanguageProc () slo est


disponible en X11R5; no hay una funcin correspondiente en X11R4.
/ * Popups.c - demostrar el uso de unos mens emergentes de forma
arbitraria
* Widget. Mostrar dos pulsadores. El segundo tiene una ventana
emergente
* Men unido a l que se activa con el tercer
* Botn del ratn.
* /
# include <Xm / LabelG.h>
# include <Xm / PushBG.h>
# include <Xm / PushB.h>
# include <Xm / ToggleBG.h>
# include <Xm / ToggleB.h>
# include <Xm / SeparatoG.h>
# include <Xm / RowColumn.h>
# include <Xm / FileSB.h>
# include <Xm / CascadeBG.h>
Widget de nivel superior;
extern void exit ();
open_dialog_box void ();
/ * Devolucin de llamada para la activacin del botn * /
vaco
put_string (w, client_data, call_data)
Widget w;
client_data XtPointer;
call_data XtPointer;
{
String str = (String) client_data;
puts (str);
}
_menu_item typedef struct {
char * etiqueta;
clase WidgetClass *;
charlas mnemotcnica;
char * acelerador;
char * accel_text;
void (* devolucin de llamada) ();
callback_data XtPointer;
_menu_item struct * subpuntos;
} Opcin del men;
Menultem file_items [] = {
{ "Artculos de archivos", y xmLabelGadgetClass, null, null, null,
null, null, null},
{ "_sep1", Y xmSeparatorGadgetClass, NULL, NULL, NULL, NULL, NULL,
NULL},
{ "Nuevo", y xmPushButtonGadgetClass, 'N', NULL, NULL,
put_string, "Nuevo", NULL},
{ "Abrir ...", y xmPushButtonGadgetClass, 'O', NULL, NULL,

open_dialog_box, (XtPointer) XmCreateFileSelectionDialog,


NULL},

NULL},

{ "Guardar", y xmPushButtonGadgetClass, 'S', NULL, NULL,


put_string, "Guardar", NULL},
{ "Guardar como ...", y xmPushButtonGadgetClass, 'A', NULL, NULL,
open_dialog_box, (XtPointer) XmCreateFileSelectionDialog,
{ "Salir", y xmPushButtonGadgetClass, "x", "Ctrl <clave> C", "Ctrl

+ C",

salida, NULL, NULL},


NULO,
};
principal (argc, argv)
int argc;
char * argv [];
{
Widget BuildMenu (), botn, Fila Col, emergente;
XtAppContext aplicacin;
extern postit void ();
Funcin XtSetLanguageProc (NULL, NULL, NULL);
toplevel = XtVaAppInitialize (y de aplicaciones, "Demos", NULL, 0,
Y argc, argv, NULL, NULL);
/ * Construir un RowColumn para contener dos pulsadores * /
Fila Col = XtVaCreateManagedWidget ( "Fila Col",
xmRowColumnWidgetClass, de nivel superior,
NULO);
/ * El primer PushButton es un -gadget-, por lo que no puede popup

un men

* de aqu!
* /
= botn XtVaCreateManagedWidget ( "Botn 1",
xmPushButtonGadgetClass, Fila Col, NULL);
XtAddCallback (botn, XmNactivateCallback, put_string, "Botn 1");
por lo

/ * Esta tecla es un widget, por lo que tiene su propia ventana,

* Podemos hacer aparecer un men de aqu mediante la adicin de


un controlador de eventos
* Especficamente para el 3er botn del ratn (cumplimiento con
motivos).
* /
= botn XtVaCreateManagedWidget ( "Botn 2",
xmPushButtonWidgetClass, Fila Col,
NULO);
/ * Todava puede tener su devolucin de llamada! * /
XtAddCallback (botn, XmNactivateCallback, put_string, "Botn 2");
/ * Crear el men ... * /
popup = BuildMenu (botn, XmMENU_POPUP, "cosas", NULL,
Es cierto que los file_items);
/ * Aadir el controlador de eventos (PostIt ()) y pasar el men
de nueva creacin

* Como el client_data. Esto se hace para evitar el uso de


variables globales innecesarios.
* /
XtAddEventHandler (botn, ButtonPressMask, Falso, postit, popup);
XtRealizeWidget (nivel superior);
XtAppMainLoop (app);
}
/ * Postit () - controlador de eventos para el botn del ratn en el
tercero
* Ventana del widget de botn pulsador.
* /
vaco
Postit (pb, client_data, evento)
Widget pb;
client_data XtPointer;
* XEvent evento;
{
Widget emergente = (Widget) client_data;
XButtonPressedEvent * Bevent = (XButtonPressedEvent *) evento;
si (bevent-> botn! = 3)
regreso;
/ * Posicionar el men en la ubicacin del botn de prensa. Si
quisiramos
* Para colocarlo en otro lugar, podramos cambiar los campos X, Y
del
* Estructura de eventos.
* /
XmMenuPosition (popup, Bevent);
XtManageChild (popup);
}
/ * Open_dialog_box () - devolucin de llamada para algunos de los
elementos del men declarados
* En la estructura Menultem. Los datos de cliente es la funcin de
creacin
* Para el dilogo. Asociar el dilogo con el men
* Artculo va XmNuserData por lo que no tiene que llevar un mundial
y
* No tiene que crear varias ocasiones uno.
* /
vaco
open_dialog_box (w, client_data, call_data)
Widget w;
client_data XtPointer;
call_data XtPointer;
{
Widget (* func) (); = client_data;
Widget de dilogo = NULL;
/ * Primero ver si de dilogo de este elemento de men se ha
creado todava * /
XtVaGetValues (w, XmNuserData, y de dilogo, NULL);
si (dilogo) {

/ * Elemento de men no ha sido elegido todava - crear el


dilogo.
que la

* Utilice el nivel superior como el padre, porque no queremos


* Padre de un dilogo que sea un elemento del men.

* /

de dilogo = (* func) (nivel superior, "dilogo", NULL, 0);

XtVaSetValues (XtParent (de dilogo), XmNtitle, XtName (w),


NULL);
XtVaSetValues (dilogo, XmNautoUnmanage, True, NULL);
/ * Almacenar el dilogo recin creado en el XmNuserData para
el men

* Artculo para la recuperacin fcil la prxima vez. (Vase


obtener valores ms arriba).
* /
XtVaSetValues (w, XmNuserData, de dilogo, NULL);
}
XtManageChild (de dilogo);
XtPopup (XtParent (de dilogo), XtGrabNone);
/ * Si el dilogo ya estaba abierta, XtPopup no hace nada. En
* Este caso, al menos asegrese de que la ventana se eleva a la
parte superior
* Del rbol de la ventana (o tan alto como se puede conseguir).
* /
XRaiseWindow (XtDisplay (de dilogo), XtWindow (XtParent
(dilogo)));
}

La salida del programa se muestra en la figura.

La produccin de popups.c
El programa muestra dos pulsadores, uno de los cuales es un gadget y el otro un
widget. Obtenemos el ButtonPress caso preguntando especficamente para l
usando XtAddEventHandler () . Esta rutina requiere un widget porque necesita
una ventana. Para agregar un controlador de eventos para un dispositivo, que
tendra que instalarlo en el padre del dispositivo, el cual es un widget
gerente. Cada vez que unButtonPress evento se produce en el administrador, el
controlador de eventos se llama, por lo que el controlador de eventos tendra que
comprobar las coordenadas del evento y ver si ocurri dentro de los lmites del
gadget. Esta tcnica funciona, pero est ms all del alcance de esta simple
demostracin.
XtAddEventHandler ()

toma la siguiente forma:

XtAddEventHandler anular ( w , event_mask , nonmaskable ,


proc , client_data )
Widget w ;
EventMask event_mask ;
Boolean nonmaskable ;
XtEventHandler proc ;
XtPointer client_data ;

El widget de parmetro especifica el widget en el que el controlador de eventos


se va a instalar, mientras que event_mask identifica los eventos que estn siendo
manipulados. Especificamos ButtonPressMaskpara indicar que estamos
interesados en ButtonPress eventos. El nonmaskable argumento indica si el
controlador de eventos debe ser llamado en los acontecimientos no
enmascarable. Especificamos falso ya que no estamos interesados en los
acontecimientos. Los ltimos argumentos especifican la rutina de control de
eventos y los datos del cliente que se pasa a la misma. En nuestro caso,
especificamos el postit () de rutina y pasarle el PopupMenu como los datos del
cliente. Vase el cuarto volumen, X Intrinsics del Kit Manual de programacin ,
para obtener una lista completa de las mscaras de eventos e informacin ms
detallada sobre XtAddEventHandler () .
Una rutina de controlador de eventos tiene la forma siguiente:
vaco
event_handler ( Reproductor , client_data , evento )
Widget
widget de ;
XtPointer
client_data ;
* XEvent evento ;

En el postit () controlador de eventos, comprobamos qu botn produjo


el ButtonPress evento. Si no fuera el tercer botn, simplemente retornamos. Para

que aparezca el men, hay que posicionar el men y luego administrar el panel de
men. Para colocarlo, utilizamos XmMenuPosition () , que toma la forma
siguiente:
vaco
XmMenuPosition ( Reproductor , evento )
Widget widget de ;
* XButtonPressedEvent evento ;

Dado que el evento de parmetro de esta funcin se define como de


tipo XButtonPressedEvent , es posible que encuentre problemas si intenta utilizar
otro tipo de evento. Los x_root y y_root campos en la estructura de eventos se
utilizan para colocar el men apropiada, ya que estos campos indican la posicin
en la que se ha pulsado el botn del ratn. Usted puede modificar estos campos
para posicionar el men en otro lugar, pero se recomienda moderacin.
Con el fin de hacer estallar en realidad el men, que llamamos XtManageChild
() en la PopupMenu. Motif trata PopupMenus al igual que los widgets de dilogo
con respecto a sus padres de concha. A pesar de lo visible PopupMenu es un
widget RowColumn, tiene un padre MenuShell invisible. Al igual que con los
cuadros de dilogo, cuando se llama a XtManageChild () , el RowColumn
comprueba suXmNrowColumnType recurso para ver si es un PopupMenu. Si es as,
los controles de widget para ver si su padre es un MenuShell y si es as, se llama
automticamente XtPopup () en la MenuShell.
El widget RowColumn tiene un recurso que se puede establecer en PopupMenus
llamada XmNmenuPost , que le permite especificar un botn alternativo para
colocar el men. A partir de Motif 1.2, si se especifica este recurso y luego
simplemente colocar y gestionar el men en un controlador de eventos, el kit de
herramientas se encarga de comprobar el evento para asegurarse de que coincide
con la descripcin de un evento para el XmNmenuPost recursos. En las versiones
anteriores de Motif, el establecimiento de este recurso podra hacer que el
servidor se bloquea, por lo que no recomendamos que se use menos que est
utilizando Motif 1.2.
Usted puede haber notado que la PopupMenu se muestra en la figura tiene
aceleradores asociados a ella. Estos aceleradores slo tienen efecto si el foco de
entrada est en el widget que contiene el men.
La nica vez que debe nunca agregar un controlador de eventos para que
aparezca un men es cuando se utiliza un PopupMenu. No se debe adjuntar
PulldownMenus o OptionMenus a los widgets Motif arbitrarias. Tambin es

inadecuado utilizar un PopupMenu en un CascadeButton, puesto que ya tiene un


men asociado a l.
16.4.4 mens de opciones de construccin
En esta seccin final sobre mtodos de creacin de men generalizadas,
examinamos cmo crear OptionMenus utilizando el BuildMenu () funcin. En
este caso, la funcin subyacente es XmCreateOptionMenu () , que es otra rutina de
comodidad proporcionado por el kit de herramientas Motif. La rutina crea un
widget RowColumn que gestiona la etiqueta y los widgets CascadeButton que
definen el OptionMenu, pero hay que crear el real PulldownMenu nosotros
mismos. La versin final de la BuildMenu () funcin se muestra en el cdigo
fuente
/ * Build_option.c - La versin final de BuildMenu () se utiliza para
* Acumulacin emergente, una opcin desplegable -y- pullright mens.
Los mens estn
* Definido por la que se declara una matriz de estructuras MenuItem
como de costumbre.
* /
# include <Xm / MainW.h>
# include <Xm / ScrolledW.h>
# include <Xm / PanedW.h>
# include <Xm / RowColumn.h>
# include <Xm / DrawingA.h>
# include <Xm / CascadeBG.h>
# include <Xm / ToggleB.h>
# include <Xm / ToggleBG.h>
# include <Xm / PushB.h>
# include <Xm / PushBG.h>
_menu_item typedef struct {
char * etiqueta; / * La etiqueta del elemento * /
clase WidgetClass *; / * Pulsador, etiqueta, separador ... * /
charlas mnemotcnica; / * Mnemotcnica; NULL si ninguno * /
char * acelerador; / * Acelerador; NULL si ninguno * /
char * accel_text; / * Se convierte en el compuesto cadena * /
void (* devolucin de llamada) (); / * Para llamar a la rutina;
NULL si ninguno * /
callback_data XtPointer; / * Client_data de devolucin de llamada
() * /
_menu_item struct * subpuntos; / * Elementos de men pullright, si
no es NULL * /
} Opcin del men;
/ * Construir emergente, y la opcin de mens desplegables,
dependiendo de la menu_type.
* Puede ser XmMENU_PULLDOWN, XmMENU_OPTION o XmMENU_POPUP. pulldowns
* Devolver el CascadeButton que aparece en el men. Popups retornan
al men.

* Los mens de opciones estn creadas, pero la RowColumn que acta


como la opcin
* "Zona" se devuelve no administrado. (El usuario debe manejarlo.)
* mens desplegables estn construidos a partir de los botones en
cascada, por lo que esta funcin
* Tambin construye mens pullright. La funcin tambin se suma la
derecha
* Devolucin de llamada para el teclado o en el men ToggleButton
artculos.
* /
Widget
BuildMenu (padre, menu_type, menu_title, menu_mnemonic, tear_off,
artculos)
Widget padre;
int menu_type;
char * menu_title, menu_mnemonic;
tear_off booleana;
* Menultem artculos;
{
men flash, cascada, flash;
int i;
XmString str;
si (menu_type == == XmMENU_PULLDOWN || menu_type XmMENU_OPTION)
menu = XmCreatePulldownMenu (padre, "_pulldown", NULL, 0);
else if (menu_type == XmMENU_POPUP)
menu = XmCreatePopupMenu (padre, "_popup", NULL, 0);
else {
XtWarning ( "tipo de men vlido pas a BuildMenu ()");
NULL regresar;
}
si (tear_off)
XtVaSetValues (men, XmNtearOffModel, XmTEAR_OFF_ENABLED,
NULL);
/

/ * Mens desplegables requieren un botn en cascada que hacerse *

si (== menu_type XmMENU_PULLDOWN) {


str = XmStringCreateLocalized (menu_title);
cascada = XtVaCreateManagedWidget (menu_title,
xmCascadeButtonGadgetClass, padre,
XmNsubMenuId, men,
XmNlabelString, str,
XmNmnemonic, menu_mnemonic,
NULO);
XmStringFree (str);
}
else if (menu_type == XmMENU_OPTION) {
/ * Los mens de opciones son un caso especial, pero no es
difcil de manejar * /
args Arg [5];
int n = 0;
str = XmStringCreateLocalized (menu_title);
XtSetArg (args [n], XmNsubMenuId, men); n ++;
XtSetArg (args [n], XmNlabelString, str); n ++;
/ * Esto realmente no es una cascada, pero este es el widget
de mango

* Vamos a volver al final de la funcin.


* /
cascada = XmCreateOptionMenu (padre, menu_title, args, n);
XmStringFree (str);

/ * Ahora agregue los elementos del men * /


for (i = 0; artculos [I] .label = NULL;! i ++) {
/ * Si existen elementos secundarios, crear el men
desplegable de la derecha llamando a este
* La funcin recursiva. Dado que la funcin devuelve una
cascada
* Botn, el widget devuelto se utiliza ..
* /
si (artculos [i] .subitems)
si (== menu_type XmMENU_OPTION) {
XtWarning ( "No se puede tener submens de los
elementos del men de opciones.");
continuar;
}
ms
Reproductor = BuildMenu (men, XmMENU_PULLDOWN,
artculos [i] .label,
Artculos [i] .mnemonic, tear_off, artculos
[i] .subitems);
ms
widgets = XtVaCreateManagedWidget (artculos [i], .label
* Los artculos [i] .class, men,
NULO);
/ * Si el artculo es un artculo real o un botn con una
cascada

* Men, todava puede tener una tecla de acceso.


* /
if (artculos [i] .mnemonic)
XtVaSetValues (Widget, XmNmnemonic, artculos [i]
.mnemonic, NULL);
/ * Cualquier elemento puede tener un acelerador, excepto
mens en cascada. Pero,
* Que no se preocupe por eso; sabemos mejor en nuestras
declaraciones.
* /
si (artculos [i]) {.accelerator
str = XmStringCreateLocalized (artculos [i] .accel_text);
XtVaSetValues (flash,
XmNaccelerator, artculos [i] .accelerator,
XmNacceleratorText, str,
NULO);
XmStringFree (str);
}
si (artculos [i] .callback)
XtAddCallback (flash,
(Artculos [i] == .class y xmToggleButtonWidgetClass
||

artculos [i] == .class y xmToggleButtonGadgetClass)?

XmNvalueChangedCallback: / * * clase
ToggleButton /
.callback_data);
}

XmNactivateCallback, / * Clase PushButton * /


Artculos [i] .callback, artculos [i]

/ * Para los mens emergentes, simplemente volver al men; mens


desplegables, el retorno
* El botn de cascada; mens de opciones, devolver la cosa
devuelta
* Desde XmCreateOptionMenu (). Esto no es un men o un botn de
cascada!
* /
volver menu_type == XmMENU_POPUP? Men: cascada;
}
Menultem drawing_shapes [] = {
{ "Lneas", y xmPushButtonGadgetClass, 'L', NULL, NULL, 0, 0,
NULL},
{ "Crculos", y xmPushButtonGadgetClass, 'C', NULL, NULL, 0, 0,
NULL},
{ "Cuadrados", y xmPushButtonGadgetClass, 'S', NULL, NULL, 0, 0,
NULL},
NULO,
};
principal (argc, argv)
int argc;
char * argv [];
{
Widget de nivel superior, main_w, panel, sw, drawing_a, men,
option_menu;
anular la entrada ();
XtAppContext aplicacin;
geom XtWidgetGeometry;
Funcin XtSetLanguageProc (NULL, NULL, NULL);
toplevel = XtVaAppInitialize (y de aplicaciones, "Demos", NULL, 0,
Y argc, argv, NULL, NULL);
main_w = XtVaCreateManagedWidget ( "main_w",
xmMainWindowWidgetClass, de nivel superior, NULL);
/ * Utilice un widget PanedWindow como el rea de trabajo de la
ventana principal * /
panel = XtVaCreateWidget ( "panel", xmPanedWindowWidgetClass,
main_w, NULL);
/ * Crear el men de opciones - no se olvide de su gestin. * /
option_menu = BuildMenu (panel, XmMENU_OPTION, "Formas",
'S', es cierto, drawing_shapes);
XtManageChild (option_menu);
/ * Establecer el OptionMenu de modo que no puede cambiar el
tamao * /

geom.request_mode = CWHeight;
XtQueryGeometry (option_menu, NULL, y geom);
XtVaSetValues (option_menu,
XmNpaneMinimum, geom.height,
XmNpaneMaximum, geom.height,
NULO);
/ * La ventana de desplazamiento (que contiene el rea de
es un nio
* De la PanedWindow; su hermano, el men de opciones, no
cambiar el tamao,
* Por lo que si el usuario cambia el tamao de la concha
superior, esta * * ventana cambiar de tamao.
* /
sw = XtVaCreateManagedWidget ( "SW",
xmScrolledWindowWidgetClass, panel,
XmNscrollingPolicy, XmAUTOMATIC,
NULO);
/ * Crear un rea de Dibujo - dibujo real no se llevar a
* /
drawing_a = XtVaCreateManagedWidget ( "drawing_a",
xmDrawingAreaWidgetClass, sw,
XmNwidth, 500,
XmNheight, 500,
NULO);

dibujo)
se puede
de nivel

cabo.

XtManageChild (panel);
XtRealizeWidget (nivel superior);
XtAppMainLoop (app);
}

Hay dos caractersticas particularmente interesantes de este programa. En primer


lugar, por supuesto, es la modificacin de la BuildMenu () funcin. A medida que
los comentarios en el cdigo indican, la funcin ahora totalmente compatible con
todos los tipos de men de Motif. Utilizamos XmCreatePulldownMenu () para
crear el panel de men que se publica desde el CascadeButton del
OptionMenu. Este panel de men est unido a la OptionMenu estableciendo
la XmNsubMenuId como de costumbre. A medida que recorrer los elementos de
men que se van a colocar en el men, que impida la creacin de un men en una
pullright OptionMenu, como mens en cascada no estn permitidos en
OptionMenus.
Cuando BuildMenu () se utiliza para crear una OptionMenu, la funcin devuelve
el widget RowColumn que es devuelto por XmCreateOptionMenu () , a pesar de
que no es realmente un CascadeButton como el nombre de la variable podra
indicar. La funcin que llama necesita el widget RowColumn para que pueda
gestionar el OptionMenu llamando XtManageChild () . (La llamada
a XtManageChild () podra ser otra parte automatizada de BuildMenu () si desea
modificarlo.)

La otra caracterstica interesante del programa es el diseo de la MainWindow. El


widget MainWindow tiene un nico widget de PanedWindow como su hijo
porque deseamos mantener la relacin de apilamiento vertical entre el
OptionMenu y el rea de Dibujo. Otra ventaja de utilizar el PanedWindow es
que podemos establecer la altura mxima y mnima de cada panel. El usuario
puede cambiar el tamao de la ventana entera usando el gestor de ventanas, pero
no desea que el OptionMenu para cambiar el tamao, por lo que permitir que el
ScrolledWindow para absorber las fluctuaciones de tamao.

16.5 Resumen
Los mens son bsicamente objetos simples que proporcionan al usuario el
acceso a la funcionalidad de la aplicacin. Mientras que las simples rutinas de
creacin de men son muy tiles para la creacin de un prototipo bsico y otras
construcciones de aplicaciones simples, su utilidad es limitada una vez que
comience a desarrollar aplicaciones a gran escala.
Hemos descrito el diseo de una rutina de creacin de men general, por lo que
debe quedar claro que slo se necesitan dos cosas para crear un nmero arbitrario
de mens: arrays predefinidos de MenuItemestructuras y la BuildMenu
() funcin. Ya que la inicializacin de una matriz MenuItem objetos es muy
sencillo, nuestro mtodo es conveniente y tambin ms potente que las simples
rutinas de creacin de men. Hemos definido nuestro propio tipo de datos y
generalizada la rutina para crear mens para que pueda utilizar y modificar estas
funciones como usted quiera, para ajustarse a las necesidades de su aplicacin.

16.6 Ejercicios
En este captulo se podra seguir para siempre discutiendo ms y ms cosas que
puede hacer con los mens. Sin embargo, el objetivo era presentar con los
conceptos fundamentales y las consideraciones de diseo detrs de los mens. A
partir de esta informacin, usted debe ser capaz de aprender por su cuenta nuevas
tcnicas que no hemos abordado al. En ese espritu, debe ser capaz de hacer los
siguientes ejercicios basado en el material tratado en este captulo.
Crear un widget MainWindow que tiene una barra de men que contenga
al menos el Archivo , Editar y Ayuda mens, un OptionMenu, y un
PopupMenu que aparece a partir de un control DrawingArea. En primer
lugar poner en prctica los mens usando las simples rutinas de creacin
de men y, a continuacin, ponerlas en prctica mediante el BuildMenu
() funcin.

Inicializar un Menultem estructura cuyos campos se ajustan a NULL , excepto


para los nombres de los elementos del men ', rutinas de devolucin de
llamada, y clases de widget, y luego escribir un archivo de recursos que
genera un men utilizable.
Modificar el Menultem estructura y la BuildMenu rutina para que pueda
especificar la sensibilidad inicial para los elementos de men.
Modificar BuildMenu () para reconocer cuando el men est a punto de
construir una radiobox. Usted puede optar por implementar este
comportamiento pasando un nuevo parmetro a la funcin o mediante el
examen de los nios en el Menultem lista para ver si son
ToggleButtons. Tendr que modificar el Menultem estructura mediante la
adicin de otro booleano campo para permitir que cada elemento que
indique si se trata de un botn de opcin o una llanura
ToggleButton. Vase el Captulo 4, La ventana principal , para una
discusin de radioboxes en los mens.

S-ar putea să vă placă și