cómo hacer una galería de imágenes con FWH

Esta entrada se publicó originalmente en Harbour Magazine, mi publicación sobre el lenguaje de programación Harbour.

Desde hace mucho tiempo he querido incorporar una galería de imágenes a algunos de mis programas. Esto data de mis tiempos de fanboy de Apple, cuando quedé prendado de un programa llamado Delicious Library al que me referí en esta entrada.

El caso es que hace poco estaba dándole vueltas a la cabeza en la manera de hacerlo y pregunté en el foro de FWH. La primera intención fue crear una clase a medida dentro de una ventana, pero esa solución no me valía porqué el flujo del programa es muy complicado de controlar pues las ventanas quedan independientes. Hubo otra propuesta de clase basada en diálogo utilizando la clase TPanel de FWH, y buscando ejemplos de esta clase me topé con la clase TScrollPanel que no conocía y de la que apenas hay documentación. Utilizando esta clase y el código que Mr. Rao había realizado para la clase TAlbum fue muy sencillo implementar la galería de imágenes.

Esta galería de imágenes la puedo utilizar, por ejemplo, para crear una galería de portadas de libros.

Ejemplo de galería de portadas de libros

Lo bueno de esta galería es que muestra las portadas en el orden de la rejilla de libros y si hay algún filtro activo la galería muestra unicamente los libros que aparecen en el filtro.

El código que he utilizado para crear la galería es el siguiente:

1Function LiGaleria()
2   LOCAL cAlias  := "LI"
3   LOCAL nRecno  := ( cAlias )->( RecNo() )
4   LOCAL nOrder  := ( cAlias )->( ordNumber() )
5   local aImages := {}
6   local aLabels := {}
7   local aRecno  := {}
8   local oDlgAlbum, oAlbum
9 
10   LI->(DbGoTop())
11   WHILE ! LI->(EOF())
12      IF ! Empty(Rtrim(LI->LiImagen))
13         AAdd(aImages, Rtrim(LI->LiImagen))
14         AAdd(aLabels, Rtrim(LI->LiTitulo))
15         AAdd(aRecno, LI->(Recno()))
16      ENDIF
17      LI->(DbSkip())
18   ENDDO
19   LI->(DbGoTo(nRecno))
20 
21   DEFINE DIALOG oDlgAlbum SIZE oApp():oGrid:nWidth, oApp():oGrid:nHeight PIXEL TRUEPIXEL ;
22      TITLE "Galería de portadas de libros - dobleclik para editar un libro"
23   oDlgAlbum:SetFont(oApp():oFont)
24   //
25   oAlbum := TScrollPanel():New( 20, 20, oApp():oGrid:nHeight-50, oApp():oGrid:nWidth-20, oDlgAlbum, .f. )
26   oAlbum:SetColor(CLR_WHITE, CLR_WHITE)
27   oAlbum:SetFont( oDlgAlbum:oFont )
28 
29   @ oApp():oGrid:nHeight-40, oApp():oGrid:nWidth-96 BUTTON "Aceptar" ;
30      SIZE 76, 24 PIXEL OF oDlgAlbum ACTION oDlgAlbum:End()
31 
32   ACTIVATE DIALOG oDlgAlbum ;
33      ON INIT ( LiAlbum( oAlbum, aImages, aRecno, oDlgAlbum ), oDlgAlbum:Center( oApp():oWndMain ) )
34 
35   RETURN NIL 
36 
37function LiAlbum( oPanel, aPhotos, aRecno, oDlgAlbum )
38   local nImgPerRow  := 8
39   local nImgWidth   // := 180
40   local nImgHeight  // := Int( nImgWidth * 4 / 3 )
41   local nHGutter    := 10
42   local nVGutter    := 20
43   local nCols       := nImgPerRow
44   local nRows, nRow, nCol, x, y, nImage, xMax, nImages := Len( aPhotos )
45   local oImage, oSay
46 
47   // el ancho del scrollbar es 16
48   nImgWidth := INT((oPanel:nWidth-16-(nImgPerRow+1)*nHGutter)/nImgPerRow)
49   nImgHeight:= Int( nImgWidth * 4 / 3 )
50   nRows    := Ceiling( nImages / nCols )
51   xMax     := nCols * ( nImgWidth * nHGutter )
52   y        := nVGutter
53   nImage   := 1
54   do while nImage <= nImages
55      x     := nHGutter
56      nCol  := 1
57      do while nCol <= nCols .and. nImage <= nImages
58         // llamo a una funcion para conseguir detached locals
59         LiAlbumImage(y, x, nImgWidth, nImgHeight, oPanel, aPhotos, aRecno, nImage, nVGutter, oDlgAlbum)
60         nImage++
61         nCol++
62         x  += ( nImgWidth + nHGutter )
63      enddo
64      y  += ( nImgHeight + nVGutter )
65   enddo
66   //::nImgCols  := nCols
67   // ::nHeight   := y
68   oPanel:SetRange() // call this after defining all controls
69 
70return nil
71 
72Function LiAlbumImage(y, x, nImgWidth, nImgHeight, oPanel, aPhotos, aRecno, nImage, nVGutter, oDlgAlbum)
73   local oImage, oSay, nLiRecno
74   nLiRecno := aRecno[nImage]
75   @ y, x XIMAGE oImage SIZE nImgWidth, nImgHeight OF oPanel NOBORDER
76   oImage:SetSource( If( HB_ISARRAY( aPhotos[ nImage ] ), aPhotos[ nImage, 1 ], aPhotos[ nImage ] ) )
77   oImage:nUserControl := 0
78   oImage:lBmpTransparent := .f.
79   oImage:bLDblClick := { || ( LiForm( oApp():oGrid, "edt", , nLiRecno, oDlgAlbum )) }
80 
81   //@ y+nImgHeight+(nVGutter/2), x SAY oSay PROMPT nLiRecno FONT oApp():oFont ;
82   //   COLOR CLR_BLACK, CLR_WHITE ;
83   //   SIZE nImgWidth, 2*nVGutter CENTER PIXEL OF oPanel
84return NIL

En este código estoy utilizando tres funciones:

  • LaGaleria que recorre el fichero de libros para crear 3 arrays donde guardo las portadas, los títulos y los número de registro a que se refiere cada portada. Aquí creo el diálogo y el ScrollPanel.
  • LiAlbum donde recorro el array de imágenes para crear las imágenes dentro del ScrollPanel. Como luego quiero acceder a cada imagen para editar el libro haciendo doble click tengo que crear las imágenes en otra función utilizando la técnica de ‘detached locals’.
  • LiAlbumImage que es donde creo cada una de las imágenes, este código lo realizó Mr. Rao en el foro de FWH.

En una próxima actualización de Cuaderno de Bitácora incluiré galerías con las portadas de libros, discos y videos.

alanit
Resumen de privacidad

Esta web utiliza cookies para que podamos ofrecerte la mejor experiencia de usuario posible. La información de las cookies se almacena en tu navegador y realiza funciones tales como reconocerte cuando vuelves a nuestra web o ayudar a nuestro equipo a comprender qué secciones de la web encuentras más interesantes y útiles.