Crea tu propio ImageWell con Canvas

La creación de controles gráficos personalizados ya se ha abordado en anteriores entradas. En este caso me centraré en mostrar lo sencillo que resulta emular el comportamiento del ImageWell suministrado de serie como parte del Framework de Xojo. ¿Qué ventajas nos puede aportar? Entre otras cosas, evitaremos así un bug que está presente y que impide mostrar como imagen asignada del ImageWell cualquiera de las asignadas y cuyo tamaño ajustemos proporcionalmente (esto es que se muestre completa en la superficie del control). También nos servirá para ver como podemos habilitar y detectar la capacidad de que el usuario arrastre y suelte sobre el control un archivo de imagen.

Detectar archivos soltados sobre el control

Como de costumbre, comenzaremos añadiendo una nueva clase al proyecto. Puedes utilizar el Panel Inspector para añadir un nombre descriptivo (en el ejemplo utilizaré MyCanvas), asignando como clase superior Canvas, de modo que podamos heredar todas las propiedades, eventos y métodos de dicha clase.

Para que cualquiera de las instancias basadas en la recién creada clase puedan detectar el soltado de archivos JPEG, de modo que podamos tratarlos posteriormente, añadiremos el Evento Open e incluiremos la siguiente línea:

Me.AcceptFileDrop("img/jpeg")

En el caso de que quisiéramos aceptar otras extensiones de archivos gráficos, de entre los soportados por Xojo, bastaría con editar un File Type Set y utilizarlo como asignación de la anterior línea.

Tratar archivos soltados

El siguiente paso consiste en implementar el evento DropObject (cuya signatura completa es DropObject(obj As DragItem, action As Integer). Este es el evento que se disparará cuando el usuario suelte un archivo en los límites del control. Eso sí, hemos de verificar que se trata de un archivo de imagen, algo fácil de hacer. En el caso de que así sea, cargaremos el contenido del archivo como Picture y lo asignaremos a una propiedad del mismo tipo. Por tanto, aprovecha y añade ahora una propiedad a la clase (en el ejemplo image As Picture).

El código a añadir en el evento, por tanto, será el siguiente:

If obj.FolderItemAvailable Then
  image = Picture.Open(obj.FolderItem)
  Invalidate  
End If

¿Por qué Invalidate? Bien, acabamos de recibir una nueva imagen… de modo que tendremos que actualizar el estado gráfico de la instancia. Esto es lo que conseguimos mediante esta instrucción que fuerza el redibujado del control cuando sea posible.

Propiedades adicionales: Color de borde, tamaño de línea, color…

Las instancias creadas a partir de la clase han de indicar de algún modo que están presentes en el diseño de la ventana donde se vayan a utilizar. En nuestro caso nos limitaremos a hacerlo rellenando el fondo con un color específico, así como dibujando el borde del control con el color y tamaño de línea que deseemos. Para ello, añadiremos otra serie de propiedades a la clase:

  • backGroundColor As Color = &cdddddd
  • borderColor As Color = &c000000
  • penSize as Integer = 2

Redibujar el control

El último paso consiste en redibujar el control. Aquí es donde crearemos el aspecto propiamente dicho, no sólo rellenando el color de fondo y el borde con los colores asignados, sino también encajando y redimensionando (de ser necesario) la imagen soltada del control para que se vea correctamente. Esto es lo que logramos con el siguiente código:

//Rellenamos el fondo con el color indicado
g.ForeColor = backgroundColor
g.FillRect(0,0,Me.Width,Me.Height)

//Si hay una imagen válida, la dibujamos
If image <> Nil Then 

  Dim Height, Width As Integer

  Dim sourcey, sourcex As Integer = 0 

  If image.Height > image.Width Then

    Height = Me.Height
    Width = (Me.Height * image.Width) / image.Height

    sourcey = (Me.Width - Width) / 2

  Else

    Width = Me.Width
    Height = (Me.Width * image.Height) / image.Width

    sourcex = (Me.Height - Height) /2

  End If

  g.DrawPicture(image,sourcey,sourcex,Width,Height,0,0,image.Width,image.Height)

End If

//dibujamos el borde del control
g.PenWidth = penSize
g.PenHeight = penSize

g.ForeColor = borderColor

g.DrawRect(0,0,Me.Width,Me.Height)

Como puedes ver el código se explica por sí solo. No es nada complicado.

Si quieres, puedes sacar provecho del Inspector Behavior de modo que las propiedades añadidas al control puedan asignarse utilizando el Panel Inspector. De este modo, cuando añadamos nuevas instancias al diseño de las ventanas en el Editor de Diseño, sólo tendremos que utilizar el Panel Inspector para indicar el color de fondo, color de borde y grosor de línea que deseemos. Puedes leer como utilizar el Inspector Behaviour en tus clases en esta entrada.

Ahora ya sólo queda que arrastres la recién creada clase a la ventana donde desees incorporar dicha capacidad, ¡y listo! Verás como cuando sueltes archivos de imágenes JPEG sobre el control este se encargará de mostrarlas centradas sobre la superficie disponible.

En la imagen de ejemplo puedes ver como queda la misma imagen cuando se arrastra sobre un ImageWell (arriba) y sobre una instancia de la clase que hemos creado en este tutorial.

4 comentarios en “Crea tu propio ImageWell con Canvas

  1. TANCO MAURICIO ANDRES

    Supongo ese ejemplo es para Desktop no? porque
    Me.AcceptFileDrop(“img/jpeg”) en WebCanvas (Web) no existe.
    Como “vuelco” una imagen en un control web (me sirve cualquiera que pueda soportarlo y luego grabarlo a mysql)

    1. Javier Rodriguez

      Hola Mauricio,

      Puedes ver un modo de incorporar imágenes en proyectos Web en el tutorial “Animaciones en la Web“.

      1. mauricio

        Hola Javier gracias por tu respuesta, pero lo que necesito más que nada es subir una imagen desde mi carpeta a la web (para luego grabarlo en mysql).
        Al estilo de las web que subes documentación, foto o un logo, eso es lo que quiero hacer. Le escribí a Greg O’Lone pero la solución que pone en el foro no es lo que necesito, quizás no me supe expresar.

      2. Javier Rodriguez

        Hola Mauricio,

        Sobre subir y descargar archivos en apps Xojo web, échale un vistazo a este articulo

        Y sobre como guardar y recuperar la imagen en base de datos, echa un vistazo a este artículo. Está basado en SQLite, pero fijo que lo puedes adaptar fácilmente para MySQL. En PostgreSQL, por ejemplo, se hace de otra forma.

        Si quieres, también podemos verlo en detalle en tu caso específico. ¡Recuerda que los bonos de formación no caducan en el tiempo, y es una forma fácil y rápida de darle un empujón a muchas cuestiones!

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *