Módulo C.P.2017 (I): Reloj Analógico.

Buen camino a todos:

Tras esa corta introducción que compartimos días atrás, en la Comunidad de Embarcadero, Módulo de control de presencia (2017): de la vcl a fmx, retomamos hoy la primera entrada de la serie.

En principio, mi idea es que exista, entre una entrada y otra, una periodicidad semanal, de forma que tengáis tiempo para curiosear y experimentar. Al final dependerá un poco de la carga de trabajo. Sabéis que el contenido de este blog por lo general, va dirigido a los compañeros que dan sus primeros pasos, a la gente que se inicia, cuidando especialmente que sea didáctico y que ayude a reflexionar, sin verdades absolutas y fomentando la curiosidad como vía para aprender día a día.

Consideración inicial…

version3

Si se me permite, empezaré argumentando que añadir un reloj analógico no era algo preciso ni necesario. De hecho, no aparecía en ese código asociado a la entrada Módulo de control de presencia y la visualización del reloj se hacia con un simple TLabel, mostrando el texto con el formato de la hora indicada. Por lo tanto, y pensando en mi mismo y economizar esa tarea de actualizar el código, me lo hubiera podido ahorrar. Es mas, en la vida real, en los contextos de producción tan distintos de estos experimentos, los usuarios no se paran a contemplar el reloj, ¡ni falta que les hace!. Pensemos que es un simple artilugio para anotar la hora de entrada y salida del recinto laboral (si fuera ese el caso) y como tal, forma parte de un proceso donde lo de menos es el reloj, en cuanto apariencia. Lo importante realmente es el apunte de la hora, ese marcaje del registro horario, que yo vine a llamar coloquialmente “movimiento” en aquella entrada. Y la mejor prueba de saber si funciona o no funciona, es colocar un centenar de empleados deseosos de abandonar la empresa tras la jornada laboral. 😀 Nadie espera un minuto a que se procese un trabajo interno o que se reinicie la aplicación porque ha generado un error catastrófico, o perdido la conexión de la red. No digo que se vaya a apalear al informático pero… ¡Lo dicho! Lo mejor es no tentar al diablo. Diseña algo sencillo, rápido y eficaz.

A lo largo de nuestra vida laboral los hemos conocido de muchos tipos, formatos y tamaños: desde aquellos artefactos metálicos o de madera, antiguos, en los que el trabajador introducía una ficha de cartón, donde iban que2005-11 stempeluhr.JPGdando anotadas esas entradas y salidas que luego alguien procesaba con papel y boli, pasando por dispositivos lectores de tarjetas de banda conectados a software para recolectar esos registros, hasta llegar a los actuales, que usan todo tipo de tecnologías de reconocimiento, táctil o facial o cualquiera otra opción que se nos ocurra para identificar al usuario. 
De Ziko-CTrabajo propio, CC BY-SA 3.0, Enlace

Siendo sinceros, el orden natural de la serie, era que hubiéramos empezado descargando el código fuente de la entrada del 2010, pero me parecía mas oportuno ahora, empezar la creación de este reloj analógico, que es un componente, aislado, que vamos a poder añadir al final a nuestro reloj para fichar, y dar así tiempo a quien siga la serie, para que pueda descargarse aquella entrada y curiosear en el código. He creado un correo temporal (*) para que puedas contactar conmigo si tienes alguna duda sobre lo que vamos a ir compartiendo. Siéntete libre de contactar:

  • reloj[arroba]delphibasico[punto]com.
  • (*) Una vez finalice la serie borraré este correo.

Estas primeras entradas se han compilado con la versión Starter de Delphi 10.1 Berlin (Update2), para que puedan llegar a mas compañeros, mas aun cuando desde Embarcadero se promocionó recientemente esta versión, ofreciendo temporalmente la suscripción a coste cero, tanto de Delphi como de C++ Builder y muchos compañeros se suscribieron. Es por ello que se han mantenido algunas características ligadas a la persistencia en el almacenamiento de los registros, para evitar introducir cualquier motor de datos tradicional, sea local o remoto, al menos en esta etapa.

Las primeras decisiones

Puestos ya en la tarea de construir el reloj analógico, en adelante lo referiremos simplemente como reloj, nos vemos obligados a tomar las primeras decisiones. Por ejemplo, podemos decidir crear nuestro propio “componente” que represente a ese reloj. A priori, puede ser una decisión inteligente, porque encapsular ese código del resto de código (concretamente del reloj de fichar) nos va permitir reutilizar el reloj en otros proyectos;  también nos permitirá depurar los posibles errores de una forma sencilla. Esas ventajas, son inherentes a ese concepto que referimos como “encapsular”: representado en la ocultación del estado interior de un objeto, accesible solo por ciertas propiedades y métodos que hace públicos para operar con él. Esa parte publica de la interfaz del componente, hace de alguna forma, que pongamos el énfasis en lo que hace y no en cómo lo hace. Así pues, plantearse el reloj como un componente, desde el punto de vista de la independencia de su código a priori puede ser una buena idea.

No obstante, y dado que hablamos de la plataforma Firemonkey, me gustaría que le dierais un vistazo a este imagen de la docwiki de Embarcadero, que nos muestra la relación de jerarquía entre las clases mas representativas de la biblioteca.

firemonkeyhierarchy2

Enlace a la imagen: FireMonkey Component Library

Las dos familias, bajo la rama de la clase TControl: las que forman parte de las Primitivas (gráficas), descendientes de TShape, y las que pertenecen a los controles que definen estilos, descendientes de TStyledControl, han heredado unas características en su ascendencia común que van a facilitar las técnicas ligadas a la composición, y esto puede hacer replantearte puntualmente crear un componente o no hacerlo. TFrmxObject en la unidad FMX.Types, es la responsable de que todos los controles, visuales o no, actúen como contenedores, y que puedan generarse nueva funcionalidad en aras de esa composición. El ejemplo que se pone habitualmente porque resulta especialmente ilustrativo, es el de componer un botón con una imagen, algo que nuestra VCL solo permitiría sobrescribiendo el componente base. Ahora, Firemonkey nos permitirá colocar en un formulario un componente TButton, que a su vez, contenga un componente TImage, o cualquier otra combinación que imaginemos, y que trabajen juntos. Firemonkey cambia algunas reglas que ahora nos permiten otros enfoques. Y por ello, al valorar crear ese componente (volviendo la vista al párrafo anterior), en mi opinión tiene mas peso la independencia de ese código y su reutilización.

Os animo a enmarcar esta idea para no olvidarla: Para Firemonkey cualquier clase que descienda de TFmxObject se comporta como un contenedor, capaz de alojar otro componente.

Nuestro punto de partida para conocer y profundizar en la creación de componentes con FMX debería ser la documentación oficial que encontramos en el enlace de la docwiki de Embarcadero:  Guía de Componentes . Es un buen momento para ojear su contenido.guia_comp_fmx

Tomada esa primera decisión, quedan otros aspectos sobre los que tenemos que pronunciarnos. El primero de ellos y mas importante, será la clase base sobre la que construiremos nuestro reloj. De esa decisión dependerá gran parte del trabajo posterior puesto que nuestro componente va a heredar toda la funcionalidad que nos aporte ese ascendente. Así que este punto nos obliga a conocer muy bien esa jerarquía de clases para determinar cual es nuestro punto de partida. El segundo aspecto, será decidir si nuestro componente se integrará en el IDE, registrándose en alguna de las paletas de componentes. O si por el contrario, lo vamos a utilizar exclusivamente en tiempo de ejecución. ¿Necesitamos, o queremos, que el reloj esté disponible en tiempo de diseño y que podamos desde el inspector de objetos modificar algunas de sus propiedades? Cada cual haga su elección. Muchos argumentarán a favor de uno u otro, pero la realidad es que esta ultima decisión es un tanto arbitraria, porque no va a afectar a la funcionalidad que expone sino a la usabilidad que nos aporta. Integrarlo en el IDE nos permitirá añadir el componente rápidamente a cualquier proyecto. En contra, es posible que nos obligue a considerar aspectos que no tendríamos que tener en cuenta en tiempo de ejecución: la peculiaridad de que algunos métodos se ejecutan en tiempo de diseño y otros no, para poder permitirnos desde el IDE observar los cambios, en respuesta a la modificación de los valores de las propiedades publicadas. Tendríamos que tener en cuenta los estados internos de los componentes respecto al IDE: si se está creando, leyendo los valores por defecto o si se está destruyendo. Amen, de conocer otras peculiaridades propias del modo en el que se modifica una propiedad, que puede requerir editores especializados.

A efectos de nuestro reloj, seguiremos las indicaciones de la Guía de Componentes para crearlo e integrarlo en nuestro entorno de desarrollo.

Vamos a verlo.

Las primeras acciones: preparar el terreno.

Abrid el documento de la guía de Componentes. Vamos a crear la estructura del proyecto que nos permitirá que el código compilado se instale en la paleta de componentes. Delphi nos ayuda en esta tarea mediante asistentes que nos van a guiar paso a paso. Así que solo tenéis que seguir esos pasos.

Nuestro reloj va a descender de la clase TCircle, que pertenece a la familia de controles que heredan de TShape. He elegido ésta, porque quiero que mantenga las proporciones de la figura geométrica respecto a la esfera del reloj. De esa forma, si cambia el tamaño o la forma en la que se acopla a su contenedor, seguirá manteniendo el aspecto. En este caso, hemos optado por crear el componente a partir de la primera familia, cuya principal característica es que no responden a un diseño visual desde un archivo de estilo, como es el caso de la familia descendiente del TStyledControl sino que se dibujan a si mismos sobrescribiendo el método Paint que introduce TControl en la unidad FMX.Control. Notad que TStyledControl también desciende a TControl, por lo que no existe una restricción a que desde sus descendiente puedan combinarse ambas técnicas.

Abrimos el asistente para la creación de un nuevo componente.

Voy a acompañar estos pasos por si alguien necesita esa ayuda adicional. En caso contrario, saltad esta parte, que nos va a dejar al final de la entrada con la estructura de un grupo de proyectos y dos proyectos añadidos. Uno para empaquetar el componente y otro para ir probando que los cambios que hagamos son correctos.

En el menu superior, accedemos al area de Componente, Nuevo Componente:

nuevocomponente-1
El asistente nos permite seleccionar la plataforma (seleccionamos Firemonkey)nuevocomponente-2
El siguiente paso, es localizar su ancestro, la clase base sobre la que vamos a partir para construirlo. Hemos comentado anteriormente que seleccionamos TCircle. 

La casilla de búsqueda superior os ayudará a localizarlo.nuevocomponente-3

A continuación, determinamos el nombre de la clase del nuevo componente.

Indicaremos la paleta en la que se va a ubicar y la ruta de la unidad. Opcionalmente se puede indicar la ruta de búsqueda.

La selección de la unidad, junto con el nombre de la clase y la paleta de registro, permitirá a Delphi crear fisicamente el archivo con el módulo de código y la estructura de la clase vacía de información, preparada para que nosotros podamos iniciar el diseño del componente.
nuevocomponente-4-0

Estamos finalizando… Por regla general, dado que estamos haciendo pruebas lo ideal es que selecciones la ultima opción. Crearemos un nuevo Package.
nuevocomponente-5
Y te falta indicar la ubicación de ese fichero dpk, que representa el paquete, con la unidad o unidades enlazadas al proyecto. El fichero junto con de proyecto, son mantenidos por el sistema y contienen información de la compilación, de las unidades externas requeridas y de las unidades que contiene.nuevocomponente-6
Tras finalizar, Delphi creará para nosotros la unidad “.pas”, con el interface y la implementación de la clase. Tras confirmar el nombre de la unidad, el entorno compilará e instalará el nuevo componente, mostrando la información en esa ventana de dialogo.
nuevocomponente-8
Falta un último aviso, que da por finalizada la tarea: el entorno detecta que nuestro componente contiene referencias al framework de Firemonkey y nos avisa que es necesario que se asigne al proyecto para evitar referencias ambiguas. Contestamos afirmativamente, como nos muestra la figura inferior.
nuevocomponente-10

Una vez creado el grupo de proyecto conteniendo el proyecto del componente, vamos a añadir un proyecto vacío que nos permitirá posteriormente hacer pruebas y comprobar que los cambios que efectuamos en el componente funcionan adecuadamente.

Evito reproducir esos pasos en imágenes para no alargar innecesariamente la entrada:nuevocomponente-11

Sobre el grupo de proyectos del “Project Manager”, añadimos un nuevo proyecto. Seleccionamos “Blank Application”, para que se añada un proyecto vacío y finalmente, guardaremos tanto el modulo “.pas” como el “.dpr”.

El resultado final:

nuevocomponente-14

Comprobamos que todo es correcto.Añadimos el componente, ubicado en la pestaña Samples de la paleta de componentes y vemos en tiempo de diseño, sobre el formulario, un circulo con las propiedades por defecto.

Nuestro componente todavia no se parece a un reloj pero estamos mas cerca.

nuevocomponente-15

Finalizando…

Cerramos aquí esta primera entrada que contiene aspectos triviales de la creación del componente pero necesarios, y abrimos un grupo en la Comunidad de Embarcadero, para seguir el taller: Taller de Delphi Basico 2017

La próxima entrada nos llevará a empezar el diseño del reloj analógico. Necesitamos unas manecillas y determinar el modo en el que se van a mover. Y pintaremos sobre ese lienzo o Canvas, otras partes del reloj, como los diales de la hora o los minutos, lo cual nos permite introducir las ventajas y la potencia de los gráficos basados en vectores, propio de la naturaleza de esta plataforma y representado en este caso, como veremos, en el componente TPath.

Hasta ahora.

3 comentarios sobre “Módulo C.P.2017 (I): Reloj Analógico.

Agrega el tuyo

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

Blog de WordPress.com.

Subir ↑

Recetas y consejos nutricionales

Indicadas para personas con diabetes, recomendadas para todos.

¡Buen camino!

ANÉCDOTAS Y REFLEXIONES SOBRE UN VIAJE A SANTIAGO…

http://lfgonzalez.visiblogs.com/

Algunas reflexiones y comentarios sobre Delphi

It's All About Code!

A blog about Delphi and related technologies

The Podcast at Delphi.org

The Podcast about the Delphi programming language, tools, news and community.

Blog de Carlos G

Algunas reflexiones y comentarios sobre Delphi

The Road to Delphi

Delphi - Free Pascal - Oxygene

La web de Seoane

Algunas reflexiones y comentarios sobre Delphi

El blog de cadetill

Cosas de programación....... y de la vida

Delphi-losophy

A Lover of Delphi Wisdom

Delphi en Movimiento

Algunas reflexiones y comentarios sobre Delphi

marcocantu.blog

Algunas reflexiones y comentarios sobre Delphi

/*Prog*/ Delphi-Neftalí /*finProg*/

Blog sobre programación de Neftalí -Germán Estévez-

Press F9

Algunas reflexiones y comentarios sobre Delphi

El blog de jachguate

Un blog sobre tecnología y la vida en general

A %d blogueros les gusta esto: