Feb
28

Con el fin de poner en práctica y adquirir experiencia sobre las cosas que fui aprendiendo en mi entrenamiento, me sugirieron que reescriba mi aplicación AjGenesisStudio usando Smart Client Software Factory, lo cual me pareció una buena idea y una oportunidad para lanzar una nueva versión con algo más de futuro, con esto me refiero a que la aplicación será más fácil de mantener y de añadir nuevas funcionalidades, cualquier persona que tenga algún conocimiento de SCSF podrá escribir nuevos módulos fácilmente.

AjGenesisStudio es un IDE que escribí hace unos meses que sirve para trabajar con el generador de código de Angel Lopez: “AjGenesis“, se podría pensar como algo similar al generador “MyGeneration” pero con las ventajas que ofrece el generador AjGenesis (y sin IntelliSense por ahora).

Requerimientos

AjGenesisStudio es un IDE inspirado en Visual Studio por lo cual su apariencia y funciones serán muy similares.

  • Poder abrir y editar cualquier tipo de archivo de texto,
  • Debe permitir realizar todas las funciones de edición de texto conocidas (copiar, pegar, buscar, reemplazar, etc.),
  • Resaltado de sintaxis para la mayor cantidad posible de archivos (XML, VB, CS, HTML. etc.),
  • Ofrecer resaltado de sintaxis en las plantillas de AjGenesis tanto para el código AjBasic como para el texto de salida (similar a ASP.net).
  • Poder abrir carpetas de proyectos de generación y mostrar los archivos en un Explorador de Proyecto en forma de árbol (similar al Explorador de Soluciones de Visual Studio).
  • Ejecutar archivos .build de NAnt con un botón (Run).
  • Administración de herramientas externas (similar al de Visual Studio).
  • Poder crear nuevos archivos y proyectos a partir de plantillas (igual que VS).

Para el resaltado de sintaxis y la interfaz tipo “docking” se emplea el excelente componente open source “DotNetFireball“.

Diseño de la Shell

En esta etapa ya tengo diseñado y codificado la shell y los demás elementos y servicios de infraestructura.

El layout principal tiene un menú principal (MainMenu) el cuál debe ser extendido usando el UIExtensionSite “MenuExtension” (los nuevos menús se insertarán entre el menú View y Tools), la barra del menú principal ya posee ítems que son genéricos y que todos los módulos pueden extender (ver imagen). Luego posee una barra de herramientas (MainToolbar) y una barra de estado (MainStatus).

ajgsshell

El shell tiene únicamente un Workspace: MainWorkspace, el cual es una implementación de IComposableWorkspace basado en el componente DockContainer de DotNetFireball. Este workspace usa un SmartPartInfo (DockableWindowSmartPartInfo) cuyo propósito es configurar el estado de la ventana (anclado, flotante, auto-ocultable, abajo, arriba, izquierda, derecha, etc). Este workspace se encuentra en el assembly Infrastructure.UI y deberá ser referenciado por los módulos de negocio que deseen mostrar vistas.

El menú archivo (FileMenu) puede ser extendido en 4 lugares:filemenu

  • FileNewMenu: ítems para crear un nuevo elemento (ej. módulo Documento: “Nuevo Archivo”, módulo Proyecto: “Nuevo Proyecto”).
  • FileOpenMenu: ítems para abrir elementos (ej. Abrir Archivo, Abrir Proyecto).
  • FileAddMenu: ítems que se pueden añadir a un proyecto (ej. Nuevo Xml, Nuevo Template).
  • FileMenuExtension: los módulos deben añadir ítems al menu archivo a travez de este UIExtensionSite (en la imagen se ven ítems añadidos por el módulo Documento).
¿Por qué MenuExtension y FileMenuExtension?

¿Por qué para extender el menú principal y el menú File hay que extender los elementos MenuExtension y FileMenuExtension respectivamente en lugar de extender directamente MainMenu o FileMenu? Esto ocurre porque se desea que los nuevos elementos se agreguen no al final si no en una posición determinada (entre el menú View y Tools para MainMenu y antes del Exit para FileMenu) y para lograr esto hay que usar un pequeño truco que consiste en insertar al final (luego de agregar los ítems básicos) un elemento no visible al menú en la posición deseada para que luego, los siguientes elementos sean agregados en la misma posición, pero hay que prestar atención al orden en que se agregan los nuevos elementos ya que serán añadidos por encima de los anteriores (al revés de lo normal). Pueden encontrar más información en el blog donde encontré la solución original: Workaround for Injecting menu items into CAB Shell MenuStrip.

Funciones de edición

Las opciones para edición se deben tratar de una forma particular para cumplir los siguientes dos requerimientos: cada botón (del MainToolbar) o ítem del menú (EditMenu) debe ser habilitado o deshabilitado según se pueda o no realizar la operación (ej. Paste sólo cuando hay algo en el clipboard), y cada función debe poder ser implementada por varios módulos (ej. el módulo Document para la edición del texto y el módulo Proyecto para la edición de los archivos y carpetas). Esto se puede resolver empleando comandos para cada función de edición asociados a los ítems y que estos comandos invoquen un evento individual para cada uno, de esta manera los módulos subscriben a los eventos y son responsables de ejecutar la operación de edición siempre que el usuario haya puesto el foco sobre la vista del módulo en cuestión. Los módulos también son responsables de actualizar el estado de activación de cada comando cada vez que alguna vista recibe el enfoque.

Los eventos a los que deben suscribirse los módulos que necesitan realizar operaciones de edición son los siguientes: EditCopy, EditCut, EditPaste, EditSelectAll, EditDelete, EditUndo, EditRedo, ShowFind, ShowReplace, ShowGoTo. Los comandos, que deben ser utilizados sólo para la activación de los items, tienen el mismo nombre (las constantes, el valor no es el mismo).

Servicios de infraestructura

Por ahora tengo pensados 2 servicios de infraestructura, el primero, “ExtensionService“, tiene funciones para facilitar la extensión de los menú y las barras de herramienta. El otro, “LoggingService“, permite mostrar al usuario información de la ejecución de las operaciones, este servicio publica un evento al que deberá suscribirse el módulo que se encargue de mostrar resultados.

En los siguientes posts seguiré con el desarrollo de los módulos que compondrán la aplicación.

Post a Comment
Name:
Email:
Website:
Comments: