Thursday, September 17, 2009

Rediseño del TwinPanel

Pues parece que vamos a hacer cierto rediseño del núcleo de TP dado que hay algunos problemas importantes que debemos resolver. Estos son algunos  de los más urgentes:

  • No hay ninguna forma mínimamente cómoda de hacer baterías de pruebas.  Hay que pensar una forma lo menos invasiva posible de poder comprobar entradas y salidas. Yo estoy trabajando en un proyecto para hacer pruebas automáticas de GUIs, pero sería bueno poder probar el modelo sin GUI, o con una capa de presentación alternativa basada en linea de comandos o algún medio de comunicación programático.
    • Los «stores» (ListStore y TreeStore) provocan mucha contención y no están convenientemente probados. Probablemente son la causa más importante de los cuelgues actuales de TP debido a la tácita enemistad entre GTK y los hilos.
      • El diseño basado en método y dominio no escala. Quedan muchos casos que ese modelo no cubre y complica el uso de la factoría. Necesitamos una forma de abstraer el acceso (http, ftp, ice, etc) del modelo (multimedia, repositorio, sensor, etc).
        • Muchas de las interacciones entre plugins y core no están definidas por interfaces. Necesitamos documentar e imponer interfaces concretas de modo que TP se niegue a cargar plugins que no cumplan la interfaz. zope-interface parece una buena solución pero la hemos aplicado a muy pocas interfaces hasta el momento.
          • Necesitamos un sistema de instalación y activación/desactivación de plugins, de modo que los que den problemas se "desactiven" automáticamente evitando la ristra de errores que aparecen al arrancar la aplicación.
          Lo bueno es que todos estos cambios afectan (o deberían afectar) muy poco a los plugins que es dónde está la mayor parte del trabajo hecho hasta la fecha.

          David me dijo que Carlos está trabajando ya en algunos de estos problemas, principalmente en cuestiones de captura de requisitos y diseño pero no he sabido nada más. Empieza a ser urgente ponernos con esto porque la bola de nieve sigue creciendo y empieza a ser preocupante. Personalmente ha llegado un punto en el que me da miedo añadir o modificar nada en TP porque es imposible saber las consecuencias que tiene en el resto de la aplicación.

          Thursday, April 9, 2009

          Galería de imágenes

          He decidido añadir algunas imágenes de cómo se va viendo la aplicación.




          Aquí podemos observar los paneles gemelos. A la izquierda está la lista de plugins (que es jerarquizable y, por tanto, se puede navegar) y a la derecha la lista de directorios. Se pueden ver también los tabs de distintas rutas.





          En esta otra imagen está un netstat tal cual se ve :-D






          Y aquí está la vista del ping.

          Pensaba poner también la lista de créditos, pero como sólo se iba a ver a uno de los creadores, creo que iba a ser algo muy feo y no la he añadido :-D

          Saturday, October 4, 2008

          MItem

          Bueno, pues después de oir las duras críticas de Óscar, Magmax y las mías propias le he hecho algunos cambios al ModelCol. No supone un cambio muy importante, de hecho internamente no hay ningún cambio, solo en el API.

          Lo primero es que ha cambiado de nombre, ahora se llama MItem, que viene a ser algo así como "elemento del modelo". Si el modelo es una tabla, el MItem puede describir una columna, que es el caso habitual, pero también se podría ver como una fila si se requiere.

          No está ligado a TreeModel o TreeView, ni siquiera a GTK. A pesar de ello, lo voy a describir como el modelo de ListStore para que la explicación no quede tan abstracta. El MItem tiene los siguientes campos (todos opcionales):

          • title (str): Es el título de la cabecera de la columna.

          • render (str): Identifica al encargado de representar el dato en ese columna (en el caso de TreeView, será un CellRenderer). Si no se indica, el render por defecto es "text". El significado real del render depende del encargado de representar el modelo, por ejemplo, el skin_list.

          • id (int). Es una prioridad para esa columna. Lo usamos para crear los índices de ordenación. El "id" más alto es la columna de ordenación por defecto. Si una columna no tiene "id", no se puede ordenar por ella.

          • var (bool). Indica (si es True) que para una misma fila, los valores de esa columna pueden cambiar con el tiempo. Por ejemplo, en un inspector que muestra la lista de unidades de disco, la columna de "espacio libre" sería "var". Si no se indica, es "False" por defecto.

          Los parámetros de MItem se indican como un diccionarios (kargs que se dice en Python). A parte de los anteriores, se pueden indicar como clave cualquier palabra que pueda ser utilizada para identificar una propiedad de la columna que describe, en nuestro caso, hasta ahora solo los hemos utilizado para indicar propiedades de los CellRendereres de los TreeViewColumn.

          El valor de esas propiedades se puede indicar de dos modos:
          • Por instancia (o fila). En este caso, el identificador va precedido de un guión bajo (_nombre) y el valor es el nombre de un atributo de un objeto del modelo. Cada fila tiene un valor propio para esa propiedad. Suena complicado, pero en los ejemplos vais a ver que es muy sencillo.

          • Fijo (por columna). En este caso, el identificador debe ir precedido de un doble guión bajo (__nombre). El valor indicado se interpreta como un literal y se aplica a toda la columna.

          Limitaciones

          • Los nombres de las propiedades no pueden empezar por guión bajo.
          • Los nombres de las propiedades tienen que ser identificadores Python válidos. En el caso de propiedades gobject, como "stock-id" el consumidor del metamodelo deberá hacer las transformaciones oportunas.

          Ejemplos:

          Voy a poner la versión MItem de los mismos ejemplo que para ModelCol. Si los comparáis veréis que el interfaz es más genérico y para el mismo caso es más corto casi siempre.

          MItem(title='Name')
          - Etiqueta de la columna: 'Name'
          - Renderer: 'text'
          - Asignar a la propiedad 'text' del renderer, el valor del atributo 'Name'

          MItem(title='Name', _text='filename')
          - Asignar a la propiedad 'text' el valor del atributo 'filename'

          MItem(title='Name', id=10)
          - Ordenar por esta columna, prioridad: 10

          MItem(title='Value', _text='val', __xalign=1)
          - Asignar a la propiedad 'text' el valor del atributo 'val'
          - Justificar el texto de esta columna a la derecha

          MItem(title="Level", _markup="level", id=10)
          - Asignar a la propiedad 'markup' el valor del atributo 'level'
          - Ordenar por esta columna, prioridad: 10

          MItem(title='Variable', _text='key',
          __background='gray', __background-set=True)
          - Asignar a la propiedad 'text' el valor del atributo 'key'
          - Fijar color de fondo de esta columna a 'gray'

          MItem(render='pixbuf', __stock-id='gtk-file')
          - Columna sin título
          - Renderer: 'pixbuf'
          - Fijar la propiedad 'stock-id' a 'gtk-file' para cualquier fila

          MItem(title='Identity', _text='key', _markup='format')
          - Asignar a la propiedad 'text' el valor del atributo 'key'
          - Asignar a la propiedad 'markup' el valor del atributo 'format'

          MItem(render='pixbuf', _stock-id='icon')
          - Columna sin título
          - Renderer: 'pixbuf'
          - Asignar a la propiedad 'stock-id' el valor del atributo 'icon'

          MItem(title="Installed", render="toggle", _active='installed',
          __activatable=True)
          - Renderer: 'toggle'
          - Asignar a la propiedad 'active' el valor del atributo 'installed'
          - Fijar la propiedad 'activatable' a True para todas las filas

          Thursday, September 18, 2008

          Chrome tabs?

          En los primeros prototipos de twinpanel, teníamos la "barra de direcciones" dentro de la página del notebook pero la barra de herramientas fuera. Pensamos que por "usabilidad" era mejor dejar las dos cosas fuera del notebook como hacen (hacían) todos los navegadores.

          El problema es que eso complica un poco la construcción del interfaz, porque al cambiar de solapa hay que configurar tanto la uri como la barra de botones de acuerdo al panel activo. Luego salió Google Chrome con su diseño "innovador" y me lo estoy volviendo a plantear: solapas arriba o solapas abajo? Tened en cuenta que de hacer el cambio, TwinPanel tendría una barra de herramientas y otra de URI en cada "side", lo que obviamente nos hace desperdiciar algo de espacio en la interfaz (no mucho).


          by Google Chrome