sábado, 31 de octubre de 2009

Trazalogic: Software para trazabilidad de alimentos

Trazalogic es un proyecto actualmente en desarrollo para dar cobertura a la trazabilidad de alimentos para empresas de elaboración y manipulación de alimentos. Las principales características de Trazalogic con respecto a otros productos similares son las siguientes:

  • Costes mínimos:


    • Desarrollado bajo estándares de software libre:


      • Servidor de aplicaciones Apache Tomcat

      • Procesos de negocio servidos mediante Java

      • Base de datos PostgreSQL

      • Front-end basado en Adobe AIR/Flash

      • Mínimo mantenimiento


    • Libertad de licencias:


      • Sin restricciones en cuanto a equipos instalados

      • Sin restricciones en cuanto a tiempo

      • El soporte es opcional, y sólo se paga por el plan deseado acorde al uso del mismo



  • Sencillez y productividad optimizadas:


    • Interfaces de usuario ricas

    • Sistema de inteligencia que anticipa los procesos

    • Menos operaciones manuales y más procesos automatizados

    • Entorno muy intuitivo que apenas requiere aprendizaje

    • Pensado también para pantallas táctiles


  • Arquitectura web:


    • Instale un único servidor, acceda desde múltiples puestos en cualquier lugar

    • Versatilidad en configuraciones de acceso

    • Acceso restringido a usuarios previamente configurados

    • Sistema abierto para acceso mediante servicios web, de cara a que otras aplicaciones se puedan integrar con Trazalogic (con requerimiento de firma)


  • Múltiples idiomas: Inicialmente en castellano y en inglés, pero sería fácil agregar cualquier otro idioma con sistema de caracteres latinos

  • Múltiples plataformas: Puede ser utilizado en Windows y en Linux



Las principales características funcionales de Trazalogic son las siguientes:

  • Sistema de administración:


    • Gestión de usuarios

    • Gestión de clientes

    • Gestión de proveedores

    • Gestión de inventario

    • Gestión de puntos de control y almacenes

    • Gestión de recetas o preparación de alimentos

    • Trazabilidad de actividad del sistema

    • Trazabilidad de los alimentos

    • Estadísticas y cuadros de mando

    • Informes


  • Sistema de operación:


    • Gestión de lotes (entrada y salida)

    • Gestión de productos

    • Recepción de alimentos primarios

    • Gestión de almacenamiento de alimentos (entrada y salida)

    • Elaboración de alimentos

    • Gestión del envasado

    • Gestión de salida de productos elaborados




A continuación algunas pantallas de Trazalogic en acción:



















Puede solicitar información sin compromiso sobre Trazalogic, a través del correo electrónico: info@tecnillusions.com

Tecnillusions: http://www.tecnillusions.com

domingo, 25 de octubre de 2009

Firma de libros en la Conferencia de SPI en Pontevedra

El pasado viernes, 23 de Octubre de 2009, se celebró en Pontevedra una conferencia sobre SPI, a la que fui invitado por la presidenta de la AESPI, Esperanza López Maquieira. El acto fue presidido, además de por la presidenta de la AESPI, por la vicepresidenta Teresa Pinto, la tesorera Mª Jesús Catalán, el doctor Diego García-Borreguero y el vicepresidente de la diputación de Pontevedra D. José Juan Durán.

En el acto se presentó mi libro "SPI: el demonio que me despierta mientras duermo", que se entregó al final de la conferencia entre los asistentes, y a los que, gustosamente, firmé.

A los interesados, podéis conseguir información sobre el SPI y descargaros mi libro, desde la página de la AESPI: http://www.aespi.net

Existe un foro donde podrás encontrar información de todo tipo (asociaciones, médicos, consultas, tratamientos, noticias, etc.): http://groups.google.com/group/sindrome-de-piernas-inquietas





martes, 20 de octubre de 2009

Flex/AIR: Error de conversión a ArrayCollection de ObjectProxy en llamadas HTTPService

Me he encontrado con un problema habitual, y ocurre cuando uno hace una llamada a un HTTPService, y en la función que gestiona (handle) la llamada, al asignar el resultado del XML a un ArrayCollection, se encuentra con que no puede asignarse un objeto ObjectProxy al ArrayCollection. Este tipo de operaciones son habituales cuando hay que cargar una lista o un ComboBox. Este problema ocurre cuando solamente se tiene un elemento en la lista, mientras que si hay más de uno, este problema no ocurre. Asimismo, si no hay resultado, también puede dar un error de null. Creo que se trata de un bug de Flex, ya que en estos casos, automáticamente debería dar un ArrayCollection de todas maneras, con cero, uno o más de un item.

Antes de continuar, indicar que este post no contiene un ejemplo completo para poder probar, si no que explica detalladamente como resolver esta situación.

Tras dar vueltas y vueltas al problema, he realizado una pequeña "ñapa" o "parche" para que la carga del ArrayCollection se realice sin problemas.

En primer lugar voy a presentar el XML que devuelve el HTTPService:




<?xml version="1.0" encoding="ISO-8859-1" ?>

<products_providers_in_use>
  <product_provider_in_use>
    <data>6</data>
    <label>Bill Gates</label>
    <id_product>21</id_product>
    <name_product>Escalope de ternera</name_product>
    <total>0</total>
  </product_provider_in_use>
  ...
<products_providers_in_use>




La definición del HTTPService permite definir en qué funciones delegar la ejecución en caso de error (fault) o de éxito (result), así como la URL al HTTPService (url).



<!-- Call to srvGetProductsProvidersInUse service -->
<mx:HTTPService 
  result="handleProductsProvidersInUse(event);"
  fault="handleFault(event);" 
  id="nombre_del_servicio" resultFormat="object"
  url="url_al_httpservice"
  useProxy="false">
</mx:HTTPService>



Es necesario definir el ArrayCollection como una variable de ámbito local, que pueda ser accedida por todas funciones del módulo, componente, etc.



[Bindable]
import mx.collections.ArrayCollection;

private var acInUse:ArrayCollection;



La llamada al HTTPService se realiza mediante el objeto HTTPService (referenciando el nombre indicado en la propiedad id) y al método "send" en el momento que sea necesario (en el creationComplete, al pulsar un botón, etc.):



nombre_del_servicio.send();



Una vez se ejecuta el HTTPService, éste accederá a dicho servicio para obtener un XML. En el caso de que no se haya producido ningún problema en la comunicación, se delegará la ejecución en la función definida en "result". El código para leer correctamente este XML en todos los casos (ya corregido el bug) es el siguiente:



private function handleProductsProvidersInUse(event:ResultEvent):void {
  try {
    acInUse = 
      event.result.products_providers_in_use.product_provider_in_use
        as ArrayCollection;
  }
  catch (err:Error) {
    acInUse=new ArrayCollection();
  }
  if (acInUse==null) {
    var o:Object;
    o=event.result.products_providers_in_use.product_provider_in_use;
    acInUse = new ArrayCollection(
      [{data:o.data,label:o.label,id_product:o.id_product,
      name_product:o.name_product,total:o.total}]);
  }
}



Para controlar las excepciones se abre un bloque try...catch para intentar acceder al XML recogido. Lo normal es asignar al ArrayCollection la colección de datos del XML que se repite. El XML está contenido dentro del parámetro de evento, y en la propiedad "result". El primer elemento del XML ("products_providers_in_use") no se repite, y marca el principio y fin del grupo de datos. Por ello hay que llegar hasta el siguiente nivel del XML: "product_provider_in_use". En teoría, este nivel retornaría un ArrayCollection. En el caso de que tenga más de un elemento no hay problema, pero si hay un sólo elemento, no produce ninguna excepción, pero, inexplicablemente, nos retorna un null. Por ello, tras el catch se hace una comprobación de si es nulo, en cuyo caso se crea un ArrayCollection nuevo, se recoge el único elemento del resultado en un objeto genérico, y se crea un elemento con la información recogida en el XML. En el caso de que el XML estuviera vacío o tuviera algún problema, saltaría una excepción, la cual es recogida por el bloque "catch" y crea un ArrayCollection nuevo, pero vacío, pero no null.

Espero que este ejemplo corte definitivamente el tiempo que os haya hecho perder esta singular situación.

Safe Creative #1001195348495

Flex/AIR: Listas personalizadas con ItemRenderer

Una de las mayores virtudes de Flex es que es posible personalizar la vista de una lista o de un Datagrid, pudiendo añadir elementos que no son estándares (la típica etiqueta o texto), sino que se pueden añadir también elementos gráficos o incluso elementos de interfaz de usuario.

Para ver una muestra de ello, la siguiente imagen muestra una lista con un icono a la izquierda, dependiendo del estado del item:

Como puede apreciarse, aunque sea un ejemplo sencillo, da alas a multitud de posibilidades, tanto de visualización como de edición.

El poder de ItemRenderer es poder incrustar en lugar de un item un componente. Esto es, en lugar de una fila en una lista, o de una columna en un DataGrid.


Planteamiento
El planteamiento de este componente o, mejor dicho, su utilidad, es poder realizar una lista que nos permita seleccionar un elemento, pero que, dependiendo de su estado, se pueda interactuar de una manera u otra.

Por ejemplo, imaginemos una lista de frutas asociadas a un pedido. Puede haber frutas que han sido ya entregadas (estado false o no disponibles) y otras que aún no han sido entregadas (estado true o disponibles). De esa lista, es posible quitar frutas para que no sean servidas. Obviamente, aquellas que ya han sido entregadas no podrán quitarse del pedido, y sí aquellas aún no han sido entregadas. Además del dato de estado, una ayuda visual se agradece, indicando con un pequeño icono o algún estilo de texto cuáles están disponibles y cuáles no.


Componente de contenido

El componente de contenido será aquel que será renderizado en el item. En nuestro caso será un simple HBox, que contendrá una imagen de 20x20 (en formato png, por las transparencias), y una etiqueta con el texto a visualizar.

El código de este componente es el siguiente:


Es importante señalar que en una lista la interacción de los datos ha de coordinarse, pues al hacer clic sobre el item, éste también debe retornar la información. Si no fuera así, sólamente sería un elemento decorativo y no se podría seleccionar. Es por ello que se haya sobreescrito (override) los método set data y get data. Cuando la lista comienza a dibujar (render) cada item, utiliza este componente que hemos utilizado, y le pasa (set) los datos. Internamente, cuando recibe los datos, llama al método refresh para pintarlos adecuadamente. Por otro lado, cuando el usuario hace clic sobre el item, éste debe devolverle (get) a la lista los datos para que pueda seleccionarse e interactuar con el código.

Otra cosa importante a señalar es el uso de la función loadImage:


// This function loads the image
private function loadImage(imgURL:String):void {
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,
function (e:Event):void {
itImage.source=e.currentTarget.content; });

loader.load(new URLRequest(encodeURI(imgURL)));
}


Se le llama con la ruta donde se alojan las imágenes (puede ser en disco duro, o una URL externa, o una referencia desde el directorio raíz). En el ejemplo, se ha creado un directorio "resources" dentro del raíz del código Flex, y por ello se indica en la ruta como "resources/imagen". Esta función es más recomendable que usar simplemente la propiedad source de la imagen, pues además permite recoger la información correspondiente a la imagen si queremos hacer uso de ella.

LISTA

En el ejemplo, se visualizará la lista correspondiente a partir de unos datos almacenados en un ArrayCollection. Estos datos están incrustados en el código, pero podrían ser leídos de un HTTPService o de un servicio Web.

Los campos de información son los siguientes:
- label: etiqueta o texto a visualizar en la lista
- data: código numérico del producto (no se visualiza)
- state: true/false. Indica la disponibilidad del item

El código es el siguiente:

El punto de inflexión está en la propiedad itemRenderer de la lista, en donde se indica qué componente va a dibujarse en el item de la lista.

El resultado será, además del visual, el que cuando un usuario seleccione un item de la lista, se mostrará una alerta con los datos del item seleccionado, tal y como muestra la siguiente imagen:


Safe Creative #1001195347856

domingo, 18 de octubre de 2009

Flex/AIR: Teclado virtual avanzado para pantallas táctiles

Ya está disponible una nueva versión del teclado virtual para pantallas táctiles, con las siguientes mejoras y cambios:

- Posibilidad de elegir entre un texto simple (una línea) o un texto multilínea.
- Se ha evitado los estados para hacer más sencilla la recepción del texto, con tan sólo cerrar la ventana.
- La tecla "Aceptar" se ha sustituito por el "Intro" o retorno de carro.
- Se ha agregado el botón "Anular", con el que se anula por completo el texto actual.
- Se puede interactuar con el teclado tradicional, haciendo editable el display. De esta manera, cuando el texto sea más grande que el display, se hará scrolling, accediendo a la zona de edición (en la versión anterior se cortaba, pues sólo se veía el principio).
- Es posible editar texto para su sustitución por un carácter pulsado en el teclado, o por la tecla borrar.
- Es posible especificar el tamaño máximo del texto (número de caracteres).
- Se ha incluido un status en el que se visualiza cuántos caracteres hay escritos y cuántos caracteres se pueden escribir (tamaño máximo del texto).



En la segunda demo, se ha incluído un fondo para ver cómo el teclado utiliza las transparencias con el fondo. Hay una caja de texto simple y una TextArea. La edición de ambas cajas de texto se realiza, simplemente, haciendo click sobre cada una de ellas.

Cajas de texto simple y multilínea


Teclado virtual avanzado editando multilínea


El código de la demo es el siguiente:


La explicación del código es muy similar a la del ejemplo anterior (mirar http://rafinguer.blogspot.com/2009/10/flexair-teclado-virtual-para-pantallas.html para el detalle). Tan sólo añadir que se pasa al componente, a través de la función "setTextType()", el tipo de texto a visualizar: TYPE_SINGLE (opcional) o TYPE_MULTILINE (en caso de querer un texto multilínea). Asimismo, también se especifica el tamaño máximo a editar para el texto, mediante la función "setMaxChars()".

Otro detalle a considerar es que ahora, al no tener estados o acciones (sólo el cierre de la ventana del teclado), el evento a gestionar es de tipo "Event.CLOSE", cuya función delegada simplemente ha de obtener el texto (función "getText()") sin necesidad de evaluar estados.

Para ver la demo en directo: http://www.tecnillusions.com/demos/DemoKeyboard2/DemoKeyboard2.html

Para descargarse el código fuente y el ejecutable: http://www.tecnillusions.com/demos/DemoKeyboard2/DemoKeyboard2.zip

sábado, 17 de octubre de 2009

Flex/AIR: Teclado virtual para pantallas táctiles

En esta ocasión no voy a explicar algún detalle sobre alguna técnica concreta, si no que voy a publicar, íntegramente un componente que muestra un teclado virtual que puede ser utilizado en lugar del teclado físico, ya sea con el ratón o bien en una pantalla táctil.

El teclado es de tipo QWERTY, y tiene tres modos: normal (minúsculas), mayúsculas y símbolos. Incluye también los números.

Otro detalle importante es que posee transparencia con el fondo y posee efectos especiales al utilizar los botones. ¿Qué más se puede pedir?

El aspecto que presenta es el siguiente:

Modo normal


Modo Mayúsculas


Modo Símbolo


El modo de utilizarlo es muy sencillo. El código para el ejemplo es el siguiente:



El ejemplo parte de que el componente está en la misma carpeta que la aplicación. Si no fuese así, habría que hacer el "import" correspondiente.

El ejemplo es muy sencillo: en una caja de texto escribiremos parte de un texto. Cuando se pulse el botón "Teclado" aparecerá el el teclado virtual con el texto escrito. En ese momento se modificará el texto con este teclado. Al darle al botón "Aceptar", el nuevo texto aparecerá en la caja de texto. Si se cerrase la ventana con el botón de cierre, mostrará un texto indicando que el texto no fue aceptado, y no habrá cambio alguno.

El componente KeyboardWindow es un "TitleWindow" o PopUp. Hay que importar la clase PopUpManager y declarar una variable de este tipo KeyboardWindow:


import mx.managers.PopUpManager;
import mx.controls.Alert;

private var wKeyboard:KeyboardWindow;



Cuando el usuario haga click sobre el botón "Aceptar" se ejecutará la función "showKeyboard()":


private function showKeyboard():void {
  wKeyboard = KeyboardWindow(PopUpManager.createPopUp(
    this, KeyboardWindow, true));

  wKeyboard.addEventListener(Event.REMOVED, checkText);
  PopUpManager.centerPopUp(wKeyboard);
  wKeyboard.setText(myText.text);
}


La primera sentencia crea la ventana emergente (PopUp), indicando cual es el contenedor padre (this o la propia aplicación), así como de qué tipo es la ventana hija (KeyboardWindow).

La segunda sentencia agrega el evento Event.REMOVED que permite escuchar cuándo la ventana emergente se cierra, enviando la ejecución del código a la función checkText.

La tercer sentencia se encarga de centrar la ventana emergente dentro del contenedor (en nuestro caso, la aplicación).

La cuarta sentencia le pasa al teclado virtual el texto que tenemos en la caja de texto, para su gestión.

Por último, queda la función checkText(), cuyo código es el siguiente:


private function checkText(e:Event):void {
  if (wKeyboard.action==wKeyboard.ACTION_OK)
    myText.text = wKeyboard.getText();
  else if (wKeyboard.action==wKeyboard.ACTION_CANCEL)
    Alert.show("Texto no aceptado");
}


El componente KeyboardWindow tiene una variable que contiene el estado o acción realizada antes de cerrar la ventana. Si se hizo click sobre el botón "Aceptar", el estado será ACTION_OK. Si se hizo click sobre el botón de cierre de la ventana, la acción o estado será ACTION_CANCEL. En el primer caso, se recogerá el texto gestionado por el teclado virtual mediante el método getText(), y se colocará en la caja de texto principal. En el segundo caso, se mostrará una alerta indicando que el texto no fue aceptado.

El aspecto final de este ejemplo es el siguiente:



Para ejecutar el ejemplo en directo:
http://www.tecnillusions.com/demos/DemoKeyboard/DemoKeyboard.html

Para descargar el componente y el código fuente:
http://www.tecnillusions.com/demos/DemoKeyboard/DemoKeyboard.zip

¿Razones para apostar por la tecnología OLED?

Sólo una:

viernes, 16 de octubre de 2009

Software por la patilla

OFICINA


MindRaider: Excelente gestor de ideas, a modo de mapa conceptual. Disponible para Windows y Linux.


PDF Creator: Permite convertir cualquier documento en formato PDF. Para ello, imprimir el documento seleccionando PDFCreator como impresora. Para Windows.


MULTIMEDIA


Gom Player: Fantástico reproductor multimedia para Windows, que incluye la mayor parte de codecs para vídeos y música.

Irfanview: Excelente visor de imágenes y reproductor de vídeos, que tiene en su haber el contar con el mayor catálogo de formatos. Para Windows.



PROGRAMACION


Aptana Studio: Increíble entorno (IDE) de desarrollo basado en eClipse, y que permite desarrollar en Java, Ruby on Rails, AIR (Adobe), HTML, CSS, Python, PHP, Ajax y Javascript. Disponible en Windows, Linux y Mac.



UTILIDADES


Defraggler: Una utilidad imprescindible. Permite organizar y ordenar (defragmentar) los datos en el disco duro. A medida que se usa el ordenador, la información se va degradando y haciéndose más lento. Defragmentar el disco permite acceder más rápidamente a la información y realizar menos accesos. Para Windows.


Nexus: Nexus añade un dock al escritorio de Windows. Esto es una herramienta muy útil que permite, entre otras cosas, tener a mano los iconos más utilizados y les permite añadir efectos especiales, o cambiar el aspecto completo del escritorio y de los elementos de ventana (hay varios temas).


FBackup: Potente y sencilla herramienta para realizar copias de seguridad de cualquier unidad de almacenamiento, permitiendo comprimir la copia y protegerla con contraseña. Para Windows.


MBR Wizard: Utilidad para recuperar el Master Boot Record (o gestor de arranque) del disco duro, en el caso de que esté corrupto, permitiendo definir la partición activa.


SEGURIDAD


Avast Antivirus Protection: Completa solución contra virus, rookits, troyanos y P2P. La versión gratuita está disponible para Windows y Linux.


INTERNET


Opera: Para mí, el navegador más innovador de todos, además del más rápido y eficaz, capaz de cargar páginas hechas específicamente para Explorer y para Firefox. Para Windows, Linux, Mac y Mobile.

Digsby: Cliente de mensajería que permite conectar con todas los protocolos y redes existentes, incluyendo correo electrónico y redes sociales. Todo en uno. Para Windows.

miércoles, 14 de octubre de 2009

TI Facturas v2009 ha sido liberado como Freeware


TI Facturas ahora es completamente funcional, sin limitaciones Y GRATIS. Puede descargarse la versión completa con total libertad, y poder utilizarla en entornos de producción y sin limitaciones de tiempo, máquinas o usuarios. Únicamente, no incluye soporte ni garantía, que puede ser contratado de manera opcional.

TI Facturas es el software imprescindible e ideal para que cualquier PYME o cualquier trabajador autónomo pueda gestionar de forma sencilla y económica sus presupuestos y facturas. Se ha optimizado al máximo la sencillez del programa, para que empezar a trabajar con él no sea un reto, y que el día a día sea algo natural y no consuma mucho tiempo, el cual se requeriría o se aprovecharía para otras actividades más importantes.

Para más información y descarga:

http://www.tecnillusions.com/TIFacturas/principal.html

martes, 13 de octubre de 2009

Flex/AIR: Reemplazar datos en tiempo de visualización

Hay ocasiones en las que ha de tratarse los datos que se van a visualizar. Por ejemplo, imaginemos una tabla en la que se visualiza los datos recogidos de una consulta, pero el valor de cierto campo posee datos que puedan ser ambiguos, tales como un número (códigos, por ejemplo) o valores true/false. Los datos son almacenados así en el origen de datos, pero mostrarlos al usuario puede ocasionarle confusión. En estos casos sería de gran utilidad poder definir qué valores se van a visualizar (como el texto correspondiente a cada código o un texto en lugar de true o false).

Aunque este post vaya dirigido al DataGrid y el AdvancedDataGrid, sirve también para otros componentes que muestren la información basada en un ArrayCollection, tales como una lista, un combo o un Tree.

Flex/AIR nos permite controlar el modo en que se van visualizando los datos a partir de la colección de datos. Esto se puede controlar gracias a la propiedad labelFunction, que estos componentes.

El funcionamiento es muy sencillo. Se indica en esta propiedad el nombre de una función o método que se ejecutará cada vez que trate el dato (en cada fila y columna en el caso de los DataGrid). En la definición del correspondiente DataGridColumn o de AdvancedDataGridColumn (el que contenga la revisión de la información a tratar). Ejemplo:


<mx:AdvancedDataGridColumn
  dataField="product_raw"
  labelFunction="replaceValuesColumn"/>


La función se definiría así:


private function replaceValuesColumn(
  item:Object, column:AdvancedDataGridColumn):String
{
  // Código que tratará cada dato
}


Los parámetros dependerán de cada tipo de componente. En el caso de un DataGrid, el parámetro 'column' será de tipo DataGridColumn. Las listas no tienen este parámetro.

Esta función se lanzará cada vez que el DataGrid (en este caso) vaya a rellenar esa columna en la fila actual. Aquí se evaluará los valores y, en consecuencia, decidir qué dato visualizar, el cual será indicado en el return de la función en formato String. En nuestro caso, el campo' product_raw' contiene los datos true o false, que indican si el producto es un ingediente o un producto elaborado.

El código a utilizar dentro en la función 'replaceValuesColumn' (se puede dar el nombre que uno quiera) sería el siguiente:


private function replaceValuesColumn(
  item:Object, column:AdvancedDataGridColumn):String
{
  var result:String="";
  if (item.product_raw==true)
    result="Ingrediente";
  else if (item.product_raw==false)
    result="Elaborado";
  
  return result;
}


Resumiendo: los componentes, a la hora de rellenar cada dato en el componente, permiten utilizar una función para el tratamiento específico de dicho dato. Dicha función evalúa el dato y devuelve el valor que se ha de utilizar para visualizarlo.

En el caso de un AdvancedDataGrid, si hace uso de un agrupamiento, el tratamiento del item se complica, pues la estructura interna a la hora de agrupar varía.

Como ejemplo vamos ver el siguiente AdvancedDataGrid:



En este caso tenemos un agrupamiento por el campo "name_product_type" (tipo de producto), y además un campo resumen (Total). Al depurar la función, veremos que cuando se trata del agrupamiento, se crea un nivel de colección children con los datos del item en su interior, mientras que si trata directamente las filas de datos (ya agrupadas), este nivel no existe. Para tratar este caso, el código a utilizar sería el siguiente:


private function replaceValuesColumn(
  item:Object, column:AdvancedDataGridColumn):String
{
  var result:String="";
  
  try {
    if (item.product_raw==true)
      result="Ingrediente";
    else if (item.product_raw==false)
      result="Elaborado";
  }
  catch (e:Error) {
    if (item.children[0].product_raw==true)
      result="Ingrediente";
    else if (item.children[0].product_raw==false)
      result="Elaborado";
  }
  
  return result;
}


Safe Creative #1001195348518

lunes, 12 de octubre de 2009

Flex/AIR: Estilos personalizados para Alert

Los diálogos Alert de Flex/AIR no son componentes propiamente dichos, si no un objeto previamente definido por defecto en la interfaz de usuario, que se muestran como un PopUp. Este tipo de diálogo hereda los mismos atributos de visualización que el contenedor padre que lo invoca.

Es posible modificar sus atributos mediante CSS, de la siguiente manera:


<mx:Style>
  .alertTitle{
    color:#aaaaff;
    fontWeight:bold;
  }
  Alert {
    backgroundColor:#AAAAAA;
    backgroundAlpha: 0.8;
    color: #aaaaff;
    borderColor: #000000;
    borderAlpha: 0.8;
    headerHeight:25;
    themeColor: #666666;
    titleStyleName:alertTitle;
    dropShadowEnabled:true;
    shadowDirection:right;
    cornerRadius:10;
  }
</mx:Style>

Pero para que funcione, estos estilos no se deben definir desde un componente, si no desde la aplicación principal (Application en el caso de Flex, y WindowedApplication en el caso de AIR). Los estilos definidos aquí para Alert serán válidos para todos los Alert de la aplicación, en cualquier componente contenido.

Para más información sobre estilos que se pueden aplicar:
http://www.cristalab.com/tips/personalizar-diseno-del-componente-alert-de-flex-con-css-c47959l/

domingo, 11 de octubre de 2009

Molinux Zero: una pequeña maravilla


Tengo mi viejo portátil Pentium III con unos 500 Mhz de velocidad, y con apenas 128 MB RAM. Si bien mi inglés es bueno y mis conocimientos sobre Linux son un poco avanzados, he decidido delegar este equipo a mi hija, con 8 años, para que comience a aprender a utilizar el ordenador y usarlo para sus deberes del colegio.

Ya Windows 95 (el sistema original de este equipo) era un poco pesado, y, sobre todo inextable. Windows XP es mejor ni pensarlo, si no quieres morir con sobredosis de cafeína tomando un café entre clic de botón y que empiece a funcionar algo.

La solución es Linux, con un entorno gráfico y con herramientas de Office y de escritorio con lo que poder empezar a adentrarse en este mundillo. Eso sí: en castellano.

Encontrar una distribución Linux muy, muy ligera, sencilla y por ende en castellano, se convierte en una tarea un tanto difícil. Las opciones son aquellas que tengan un escritorio ligero, tales como FluxBox, XFCE o LXDE. La lista se reduce considerablemente. Xubuntu es una distro que funciona muy bien, y, desde luego, la recomiendo.

Pero probé Molinux Zero, por curiosidad, y me ha encantado por su velocidad y por la cantidad de recursos con los que cuenta, con apenas 100 MB de ISO, y que es un "Puplet" o derivado de la distribución "Puppy". Podéis encontrar esta distro en la siguiente URL:


La distro es un live-CD, que solicitará en su inicio algunos parámetros de configuración, como el idioma, el teclado, la resolución de pantalla, el ratón... Una vez cargado en memoria, impresiona la velocidad a la que se ejecuta, incluso funcionando con un docklet en la parte superior (similar a la del MacOS X), y con unos widgets en la parte derecha, similar a la del Windows Vista.

Tiene multitud de opciones de configuración, así como aplicaciones de escritorio, de red, de seguridad, diseño gráfico, internet, multimedia, etc.

Os recomiendo bajaros y probar on live esta distribución. Merece la pena darle una segunda oportunidad a ese viejo ordenador.

lunes, 5 de octubre de 2009

Jugar al Spectrum online sin emulador

Los nostálgicos estamos de enhorabuena. Por fin podemos jugar a los juegos del Spectrum sin necesidad de instalarnos ningún software emulador, gracias a una pequeña maravilla. En la siguiente URL:

http://www.zxspectrum.net

Podemos encontrar un emulador online realizado en Java, en el que podremos cargar cientos de juegos (a la izquierda) del mítico Spectrum. Además, podemos escribir nuestros programillas en Basic o en ensamblador, pues la consola está disponible. ¿A qué esperas para echarte una pachanga?





sábado, 3 de octubre de 2009

Flex/AIR: Imágenes en DataGrid

El ejemplo que hoy nos ocupa es muy sencillo y no pretende ambiciosos objetivos. Básicamente, permitirá a un DataGrid visualizar una imagen en una determinada celda que va vinculado al valor que lo contiene. Aunque esta entrada esté dedicada a un DataGrid, lo mismo puede aplicarse a las listas.

Para ilustrar el ejemplo, vamos a ver una captura del resultado final:


Como puede observarse, la columna Type (tipo) visualiza el tipo de lote (batch) mediante un simple gráfico: entrada (verde) o salida (rojo).

No voy a exponer cómo cargar los datos en el DataGrid, pues aquí, lo que nos ocupa es precisamente cómo cargar esas imágenes dependiendo del valor de la columna.

En este caso, sólo hay dos valores posibles, por lo que en la tabla de la base de datos sólo almacena en el campo "input_batch" los valores true o false, y para los mismos valores se han creado dos imágenes de 20x20, llamadas "true.png" y "false.png".

Por defecto, los DataGrids y las listas muestran la información en formato texto. Pero Flex/AIR puede permitir representar la información en formato gráfico. Para ellos existen lo que se denominan renderers (presentadores). Existen varios tipos de renderers, como cellRenderer o itemRenderer. Para nuestro ejemplo vamos a utilizar un itemRenderer de forma muy sencilla:

<mx:DataGrid id="dgBatches"
  dataProvider="{batchesList}"
  left="18" right="18" top="50" bottom="18">

  <mx:columns>
    <mx:DataGridColumn dataField="date" headerText="Date" width="80"/<
    <mx:DataGridColumn dataField="id_batch" headerText="Batches"/>
    <mx:DataGridColumn dataField="input_batch" headerText="Type" width="50">
      <mx:itemRenderer>
        <mx:Component>
          <mx:HBox width="100%" horizontalAlign="center">
            <mx:Image source="/resources/batches/{data.input_batch}.png" />
          </mx:HBox>
        /mx:Component>
      </mx:itemRenderer>
    </mx:DataGridColumn>
  </mx:columns>
</mx:DataGrid>

El punto clave está en la columna "input_batch", la cual recoge el tipo de lote (entrada (true) o salida (false). Esta columna contiene un elemento de tipo "itemRenderer", que es el encargado de presentar el valor de dicha celda. En su interior se crea un componente simple, compuesto únicamente por un HBox como contenedor, y como contenido tendrá una imagen que apuntará a la imagen a cargar. En este caso se encuetra en el directorio "/resources/batches/" y el nombre del archivo es el propio valor del campo (data.input_batch" con la extensión ".png".

Este mismo ejemplo podría servir para cargar imágenes ya predefinidas, en lugar de dos valores únicos de tipo true/false. También podrían residir en una URL concreta en lugar de en el disco duro.

Los renderers son muy flexibles y potentes, y permiten también introducir elementos de interfaz de usuario, como listas desplegables, campos numéricos, de texto, checkboxes, etc.