Sígueme

lunes, 12 de noviembre de 2012

PB12.5: Lista lateral de botones estilo XP

Es uno de mis controles favoritos; la apariencia, fantástica, y aúna claridad, simpleza y organización. En esta entrada voy a explicar cómo implementar este tipo de menús de opciones en nuestras aplicaciones de escritorio PB. 

Es un control automático deslizante, que permite crear varios grupos de opciones, cada una con o sin imagen, que se pueden expandir o contraer. Además, permite añadir textos, con o sin retorno de carro. Al ser deslizante, si tenemos muchas opciones se va a desplazar automáticamente cuando el puntero del ratón se posicione arriba o abajo. Por supuesto, el color de fondo y los degradados se hacen con el tema de Windows XP predeterminado (tengo pendiente probarlo con otros S.O. de Microsoft). 

Para implementar una botonera de este tipo, podemos hacer lo siguiente: 


  • Como siempre, añadimos las librerías del ejemplo ADVGUI*.PBL y CANVAS.PBX a nuestro proyecto.
  • Creamos un nuevo objeto de usuario heredando de U_CST_XPLISTBAR (está en ADVGUICONTROLS.PBL). 

  • En el evento Open(uo_postopen, etc. de nuestra ventana, pestaña, etc. tenemos el siguiente script: 

//XPListBar
Long ll_parent

// GRUPO GENERAL
ll_parent = uo_1.of_AddGroup('General', 'Mail.ico', uo_1.SPECIAL) // Grupo 1: Opciones Generales, con imagen

uo_1.of_AddLink ('Añadir', '1.ico', ll_parent)
uo_1.of_AddLink ('Borrar', '2.ico', ll_parent)
uo_1.of_AddLink ('Editar', '3.ico', ll_parent)
uo_1.of_AddLink ('Ordenar', '4.ico', ll_parent)
uo_1.of_AddLink ('Filtrar', '5.ico', ll_parent)
uo_1.of_AddLine (ll_parent) // Separador
uo_1.of_AddLink ('Seleccionar Impresora', '', ll_parent) // Sin imagen
uo_1.of_AddLink ('Imprimir', '7.ico', ll_parent)
uo_1.of_AddLine (ll_parent) // Separador
uo_1.of_AddLink ('Grabar', '8.ico', ll_parent)
uo_1.of_AddLink ('Deshacer Cambios', '9.ico', ll_parent)

ll_parent = uo_1.of_AddGroup ('Style', '') // Grupo 2; opciones varias, sin icono

uo_1.of_AddLink ('XP', 'Average!', ll_parent)
uo_1.of_AddLink ('Vista Embossed', 'Custom005!', ll_parent)
uo_1.of_AddLink ('Vista Original', 'Custom006!', ll_parent)
uo_1.of_AddLink ('Vista Glass', 'Custom007!', ll_parent)
uo_1.of_AddLink ('Custom', 'Custom008!', ll_parent)

ll_parent = uo_1.of_AddGroup('Pattern', '') // Grupo 3: varias opciones
uo_1.of_AddLink('None', 'Custom018!', ll_parent)
uo_1.of_AddLink('Solid Circle', 'Custom019!', ll_parent)
uo_1.of_AddLink('Hollow Circle', 'Custom020!', ll_parent)
uo_1.of_AddLink('Solid Square', 'Custom021!', ll_parent)
uo_1.of_AddLink('Hollow Square', 'Custom022!', ll_parent)
uo_1.of_AddLink('Star', 'Custom023!', ll_parent)
uo_1.of_AddLink('Wave', 'Custom024!', ll_parent)
uo_1.of_AddLink('Bar', 'Custom025!', ll_parent)
uo_1.of_AddLink('Diamond', 'Custom026!', ll_parent)


// Grupo 4: label de texto, largo sin crlf y con crlf
ll_parent = uo_1.of_AddGroup('Ejemplos con textos largos (con CR+LF y sin CR+LF)', '', uo_1.NOARROW)

uo_1.of_AddLabel ('Ejemplo de texto que no lleva al final retorno de carro', '', ll_parent)
uo_1.of_AddLabel ('Ejemplo de texto que SÍ ~r~n lleva al final retorno de carro', '', ll_parent)

  • En el evento "ItemSelected" del userobject heredado, tenemos el script que vamos a lanzar al ejecutar cada opción: 
// Mostramos un mensage con el grupo y opción seleccionados
MessageBox ('Grupo seleccionado: ' + as_group, 'Opción seleccionada: ' + as_item)

El resultado es muy bueno, visualmente hablando: 






PB12.5: botonera horizontal tipo Outlook.

 Como he comentado en mis entradas anteriores (no voy a repetirlo, por tanto, en esta serie de entradas), para implementar una botonera horizontal tipo OutLook en PB12.5 podemos usar el objeto de usuario "u_cst_toolbarstrip" que está en "avdguicontrols.pbl". 

Se trata de una botonera horizontal con el tema por defecto del sistema,  y que nos permite mostrar/ocultar el texto de cada botón, añadir campos editables para teclear valores, o bien un DDLB para seleccionar algún valor, incluyendo los separadores que consideremos. Podemos activar/desactivar botones, y se pueden usar .ICO o bien los predefinidos de PB.

Para su implementación os comento cómo he montado mi ejemplo: 


  • Crear un objeto de usuario heredado de "u_cst_toolbarstrip" en nuestra ventana. 
  • Creamos un control de edición de texto y un control desplegable con algunos valores (ddlb). No es necesario ocultarlos porque luego se moverán automáticamente a su lugar dentro de la botonera.
  • En el evento Open/uo_postopen/... podemos pegar el siguiente script: 
// Toolbar Strip
uo_1.of_AddItem ('Open', '4.ico')
uo_1.of_AddItem ('Save', '8.ico')
uo_1.of_AddSeparator()
uo_1.of_AddItem ('Print', 'Print!')
uo_1.of_AddItem ('Preview', 'Preview!')
uo_1.of_AddSeparator()
uo_1.of_AddItem ('Cut','Cut!')
uo_1.of_AddItem ('Copy','Copy!')
uo_1.of_AddItem ('Paste','Paste!')
uo_1.of_AddSeparator()
uo_1.of_AddItem ('First Row', 'VCRFirst!')
uo_1.of_AddItem ('Prior Row', 'VCRPrior!')
uo_1.of_AddObject ('', em_1) // Petición de un valor alfabético
uo_1.of_AddItem ('Next Row', 'VCRNext!')
uo_1.of_AddItem ('Last Row', 'VCRLast!')
uo_1.of_AddObject ('', ddlb_1) // DDLB para seleccioanr un valor
 

  • En el userobject, en el evento de usuario "ue_buttonclicked" controlamos la pulsación de cada botón/control: 
st_1.TEXT = 'Opción pulsada: ' + Upper(as_button) // Control que muestra la opción pulsada
CHOOSE CASE Upper(as_button)
CASE 'SAVE'
//...
CASE 'OPEN'
//...
CASE 'PRINT'
//...
END CHOOSE 

  • Para activar/desactivar un botón: 
uo_1.of_SetEnabled('save',Checked)

  • Para mostrar/ocultar el texto de los botones (el espacio y posición de los botones se redistribuye automáticamente): 
uo_1.of_DisplayText (Checked)


Unas capturas mas del resultado: 






PB12.5: botonera vertical tipo OutLook

En la aplicación de ejemplos de PB12.5 ADVGUI tenemos un ejemplo fantástico de botonera tipo Outlook; a mí me gusta bastante, porque es un poco configurable por el usuario y tiene una apariencia muy buena. 

Se pueden añadir múltiples opciones, cada una de ellas con su icono (que puede ser un .ICO o bien uno predefinido de PB), y el usuario decide qué opciones se muestran desplegadas y cuales no.

¿Cómo implementarla? Es muy sencillo; basta con seguir los siguientes pasos:

  • Copiar de la aplicación de ejemplos ADVGUI "advgui*.pbl" y "canvas.pbx" a la carpeta de nuestro proyecto. 
  • En nuestra ventana o TAB, creamos un userobject, heredando de "u_cst_shortcutbar" (está en ADVGUICONTROLS.PBL).
  • Para este ejemplo voy a usar controles "statictext" ocultos, uno por cada opción de la botonera, y que se mostrarán automáticamente justo debajo de la barra de título del control (en el ejemplo original se utilizan DW). Yo voy a mostrar un texto cuando se pulse un botón. Por tanto, necesitamos tantos control de texto ocultos como botones tengamos.
  • En el evento Open/postopen, etc., he tecleado el siguiente script: 

//Outlook Shortcut Bar; AÑADO ELEMENTOS, incluyendo el objeto a mostrar (dw, static text, etc)
uo_1.of_AddItem (st_1, "Añadir", '1.ico')
uo_1.of_AddItem (st_2, "Borrar", '2.ico')
uo_1.of_AddItem (st_3, "Editar", '3.ico')
uo_1.of_AddItem (st_4, "Ordenar", '4.ico')
uo_1.of_AddItem (st_5, "Filtrar", '5.ico')
uo_1.of_AddItem (st_6, "Seleccionar Impresora", '6.ico')
uo_1.of_AddItem (st_7, "Imprimir", '7.ico')
uo_1.of_AddItem (st_8, "Grabar", '8.ico')
uo_1.of_AddItem (st_9, "Deshacer Cambios", '9.ico')

// Establecemos una opción por defecto (seleccionada)...
uo_1.of_SelectItem ("Editar")

// Ponemos como ocultas algunas opciones (oculta el botón, 
// pero muestra el acceso directo inferior...
uo_1.of_HideItem ("Seleccionar Impresora")
uo_1.of_HideItem ("Imprimir")
uo_1.of_HideItem ("Grabar")
uo_1.of_HideItem ("Deshacer cambios")


  • En el evento "ue_selectionchanged" del objeto de usuario, que es el que se va a lanzar cuando hagamos click en un botón de la botonera, podemos tener el siguiente script: 

st_general.text = 'SE LANZA UN SCRIPT AL EJECUTAR LA OPCIÓN: ' + upper (as_text)

El argumento "as_text" de este evento de usuario es el que nos indica qué opción es la que se ha pulsado. El texto debe coincidir con el texto con el que hemos añadido cada botón.

Sencillamente genial este objeto: