Page 1 of 4
galería de imágenes
Posted: Mon Jan 04, 2021 8:14 am
by José Luis Sánchez
Hola,
En primer lugar quiero desearos a todos un feliz año 2021 y que vayamos retomando la vida anterior al pasado año.
Me gustaría saber si con FWH es posible hacer una galería de imágenes tipo Goodreads, como la imagen que acompaño. Quiero hacer algo similar para mi Cuaderno de Bitácora y no se por donde empezar.
Saludos,
José Luis
Re: galería de imágenes
Posted: Mon Jan 04, 2021 4:45 pm
by AngelSalom
Hola José Luis, feliz año igualmente.
Un buen inicio podría partir de xbrimag3.prg en el directorio samples de Fivewin.
Code: Select all
#include "fivewin.ch"
function Main()
local oWnd, oBrw, oFont, oBold
USE WWONDERS NEW
DEFINE FONT oFont NAME "TAHOMA" SIZE 0,-12
DEFINE FONT oBold NAME "VERDANA" SIZE 0,-13 BOLD
DEFINE WINDOW oWnd TITLE "Image and Text in same cell"
oWnd:SetFont( oFont )
@ 0,0 XBROWSE oBrw OF oWnd DATASOURCE "WWONDERS" ;
COLUMNS "NAME","DETAILS" COLSIZES 200, 250 ;
LINES NOBORDER
WITH OBJECT oBrw
:nRowHeight := 200
WITH OBJECT :aCols[ 1 ]
:bStrImage := { || FIELD->IMAGE }
:oDataFont := oBold
:nDataStrAlign := AL_CENTER + AL_BOTTOM
:nDataBmpAlign := AL_CENTER
:aImgRect := { nil, nil, -40, nil }
END
//
:CreateFromCode()
END
oWnd:oClient := oBrw
oWnd:nHeight := 700
ACTIVATE WINDOW oWnd CENTERED
RELEASE FONT oFont, oBold
return nil
Re: galería de imágenes
Posted: Mon Jan 04, 2021 5:26 pm
by José Luis Sánchez
Hola Angel,
gracias por contestar, lo que me propones es un principio pero esperaba que hubiera algún control más parecido a lo que busco.
Saludos,
José Luis
Re: galería de imágenes
Posted: Mon Jan 04, 2021 5:40 pm
by Antonio Linares
José Luis,
Estamos preparándote un ejemplo
Re: galería de imágenes
Posted: Tue Jan 05, 2021 10:46 am
by José Luis Sánchez
¡ Muchas gracias Antonio !
Saludos,
Re: galería de imágenes
Posted: Wed Jan 06, 2021 8:52 am
by nageswaragunupudi
Sample:
Code: Select all
#include "fivewin.ch"
//----------------------------------------------------------------------------//
function Main()
local aImages := nil
local cLog := cFileSetExt( ExeName(), "log" )
FERASE( cLog )
aImages := ImageArray()
TAlbum():New( aImages ):Activate()
if File( cLog )
WinExec( "notepad.exe " + cLog )
endif
return nil
//----------------------------------------------------------------------------//
static function ImageArray()
local aDir
aDir := DirectoryRecurse( "c:\fwh\bitmaps\*.*" )
ASort( aDir, nil, nil, { |x,y| x[ 2 ] > y[ 2 ] } )
ASize( aDir, 200 )
return aDir
//----------------------------------------------------------------------------//
CLASS TAlbum
DATA aPhotos
DATA oWnd
DATA nWndWidth INIT 800
DATA nWndHeight INIT 800
DATA nImgWidth INIT 210
DATA nGutter INIT 30
DATA nImgCols PROTECTED
DATA nOffset INIT 0 PROTECTED
DATA nHeight
ACCESS oVScroll INLINE ::oWnd:oVScroll
METHOD New( aPhotos ) CONSTRUCTOR
METHOD Activate()
PROTECTED:
METHOD CreateWindow()
METHOD CreateControls()
METHOD SetVScroll()
METHOD GoUp()
METHOD GoDown()
METHOD ThumbPos( nPos )
METHOD MouseWheel()
METHOD VSetPos() INLINE ::oWnd:oVScroll:SetPos( -::nOffSet )
METHOD GoTop()
METHOD GoBottom()
METHOD KeyDown( nKey )
METHOD ScrollWnd( nPixels )
METHOD Resize( nType, nWidth, nHeight )
ENDCLASS
//----------------------------------------------------------------------------//
METHOD New( aPhotos ) CLASS TAlbum
::aPhotos := aPhotos
return Self
//----------------------------------------------------------------------------//
METHOD Activate() CLASS TAlbum
::CreateWindow()
::CreateControls()
::SetVScroll()
::oWnd:bResized := { |t,w,h| ::Resize( t, w, h ) }
if ::oWnd:IsKindOf( "MDICHILD" )
ACTIVATE WINDOW ::oWnd
else
ACTIVATE WINDOW ::oWnd CENTERED
endif
return Self
//----------------------------------------------------------------------------//
METHOD CreateWindow() CLASS TAlbum
local oMain, x, y
if ( oMain := WndMain() ) != nil .and. oMain:IsKindOf( "TMDIFRAME" )
DEFINE WINDOW ::oWnd MDICHILD OF oMain VSCROLL
else
x := Int( ( ScreenWidth() - ::nWndWidth ) / 2 )
y := Int( ( ScreenHeight() - ::nWndHeight ) / 2 )
DEFINE WINDOW ::oWnd FROM y,x TO ::nWndHeight + y, ::nWndWidth + x PIXEL VSCROLL COLOR CLR_BLACK,0xe8e8e8
endif
return Self
//----------------------------------------------------------------------------//
METHOD CreateControls() CLASS TAlbum
local nImgWidth := ::nImgWidth
local nImgHeight := Int( nImgWidth * 4 / 3 )
local nGutter := ::nGutter
local nRows, nCols, nRow, nCol, x, y, nImage, xMax, nImages := Len( ::aPhotos )
local oImage
nCols := Int( ( ::oWnd:nWidth - nGutter ) / ( nImgWidth + nGutter ) )
nRows := Ceiling( nImages / nCols )
xMax := nCols * ( nImgWidth * nGutter )
y := nGutter
nImage := 1
do while nImage <= nImages
x := nGutter
nCol := 1
do while nCol <= nCols .and. nImage <= nImages
@ y, x XIMAGE oImage SIZE nImgWidth, nImgHeight OF ::oWnd NOBORDER
oImage:SetSource( If( HB_ISARRAY( ::aPhotos[ nImage ] ), ::aPhotos[ nImage, 1 ], ::aPhotos[ nImage ] ) )
oImage:nUserControl := 0
#if FW_VersionNo >= 21010
oImage:Shadow()
#else
oImage:bPainted := PaintBlock( oImage )
#endif
nImage++
nCol++
x += ( nImgWidth + nGutter )
enddo
y += ( nImgHeight + nGutter )
enddo
::nImgCols := nCols
::nHeight := y
return Self
//----------------------------------------------------------------------------//
METHOD Resize( nType, nWidth, nHeight ) CLASS TAlbum
local nImgHeight := Int( ::nImgWidth * 4 / 3 )
local nRows, nCols, nRow, nCol, x, y, nImage, nImages := Len( ::aPhotos )
if nWidth == nil
return nil
endif
nCols := Int( ( ::oWnd:nWidth - ::nGutter ) / ( ::nImgWidth + ::nGutter ) )
if nCols == ::nImgCols
return nil
endif
nRows := Ceiling( nImages / nCols )
y := ::nGutter
nImage := 1
do while nImage <= nImages
x := ::nGutter
nCol := 1
do while nCol <= nCols .and. nImage <= nImages
WITH OBJECT ::oWnd:aControls[ nImage ]
:nTop := y
:nLeft := x
END
nImage++
x += ( ::nImgWidth + ::nGutter )
nCol++
enddo
y += ( nImgHeight + ::nGutter )
enddo
::nImgCols := nCols
::nHeight := y
::oVScroll:SetRange( 0, ::nHeight - ::oWnd:nHeight )
::nOffSet := 0
::VSetPos()
return nil
//----------------------------------------------------------------------------//
METHOD SetVScroll() CLASS TAlbum
local oSelf := Self
WITH OBJECT ::oWnd:oVScroll
:SetRange( 0, ::nHeight - ::oWnd:nHeight )
:bGoUp := { || oSelf:GoUp() }
:bGoDown := { || oSelf:GoDown() }
:bPos := { |nPos| oSelf:ThumbPos( nPos ) }
:bGoTop := { || oSelf:GoTop() }
:bGoDown := { || oSelf:GoDown() }
END
::oWnd:bMouseWheel := ;
{ |k,nDelta| oSelf:MouseWheel( k, nDelta ) }
::oWnd:bKeyDown := { |k| oSelf:KeyDown( k ) }
return Self
//----------------------------------------------------------------------------//
METHOD ScrollWnd( nPixels ) CLASS TAlbum
ScrollWindow( ::oWnd:hWnd, 0, nPixels, 0, GetClientRect( ::oWnd:hWnd ) )
return Self
//----------------------------------------------------------------------------//
METHOD GoUp() CLASS TAlbum
local nPixels := Min( 20, ::oVScroll:nMin - ::nOffset )
::ScrollWnd( nPixels )
::nOffSet += nPixels
::VSetPos()
return Self
//----------------------------------------------------------------------------//
METHOD GoDown() CLASS TAlbum
local nPixels := Min( 20, ::oVScroll:nMax + ::nOffSet )
::ScrollWnd( -nPixels )
::nOffSet -= nPixels
::VSetPos()
return Self
//----------------------------------------------------------------------------//
METHOD ThumbPos( nPos ) CLASS TAlbum
AEval( ::oWnd:aControls, { |o| o:nTop -= ( nPos + ::nOffSet ) } )
::nOffSet := -nPos
::VSetPos()
return Self
//----------------------------------------------------------------------------//
METHOD MouseWheel( k, nDelta ) CLASS TAlbum
if nDelta > 0
::GoUp()
else
::GoDown()
endif
::VSetPos()
return Self
//----------------------------------------------------------------------------//
METHOD GoTop() CLASS TAlbum
AEval( ::oWnd:aControls, { |o| o:nTop -= ::nOffSet } )
::nOffSet := 0
::VSetPos()
return Self
//----------------------------------------------------------------------------//
METHOD GoBottom() CLASS TAlbum
AEval( ::oWnd:aControls, { |o| o:nTop -= ( ::oVScroll:nMax + ::nOffSet ) } )
::nOffSet := -::oVScroll:nMax
::VSetPos()
return Self
//----------------------------------------------------------------------------//
METHOD KeyDown( nKey ) CLASS TAlbum
SWITCH nKey
case VK_UP
if GetKeyState( VK_CONTROL )
::GoTop()
else
::GoUp()
endif
return 0
EXIT
case VK_DOWN
if GetKeyState( VK_CONTROL )
::GoBottom()
else
::GoDown()
endif
return 0
EXIT
case VK_HOME
::GoTop()
return 0
EXIT
case VK_END
::GoBottom()
return 0
EXIT
END
return nil
//----------------------------------------------------------------------------//
#if FW_VersionNo < 21010
//----------------------------------------------------------------------------//
static function PaintBlock( oImage )
return { || DrawShadow( oImage ) }
//----------------------------------------------------------------------------//
static function DrawShadow( oImage )
local aRect := { oImage:nTop, oImage:nLeft, oImage:nTop + oImage:nHeight, oImage:nLeft + oImage:nWidth }
local hDC := oImage:oWnd:GetDC()
local n, nColor, hPen, nIncClr, nSize := 10
n := Int( ( 0xf0 - 0x48 ) / ( nSize - 1 ) )
nIncClr := n + 256 * n + 256 * 256 * n
nColor := 0x484848
for n := 0 to nSize - 1
hPen := CreatePen( PS_SOLID, 1, nColor )
MoveTo( hDC, aRect[ 4 ] + n, aRect[ 1 ] + n )
LineTo( hDC, aRect[ 4 ] + n, aRect[ 3 ] + n, hPen )
MoveTo( hDC, aRect[ 2 ] + n, aRect[ 3 ] + n )
LineTo( hDC, aRect[ 4 ] + n + 1, aRect[ 3 ] + n, hPen )
DeleteObject( hPen )
nColor += nIncClr
next
oImage:oWnd:ReleaseDC()
return nil
#endif
//----------------------------------------------------------------------------//
The images are re-adjusted if the window is resized.
Window can be scrolled up and down by
1. Using the vertical scrollbar
2. MouseWheel
3. Keys UP,DOWN,HOME,END
We used the bitmaps and images available in fwh\bitmaps folder which are of different sizes. The appearance will look better if we use images of same size and use the same image dimensions in the program.
Re: galería de imágenes
Posted: Wed Jan 06, 2021 10:20 am
by elvira
Excellent work, great functionality.
Would it be possible to add an action by double-clicking on each image, for example to execute a function that opens an individualized URL with the book?
Thank you!
Re: galería de imágenes
Posted: Wed Jan 06, 2021 7:50 pm
by nageswaragunupudi
Sure.
Add code something similar to
Code: Select all
oImage:bLDblClick := { |r,c,f,oImage| HtmlView( oImage:uSource ) }
while creating the image control.
Re: galería de imágenes
Posted: Thu Jan 07, 2021 10:50 am
by juanjogascem
Uff. Estupendo.
Se podría añadir texto, tanto a la galería de imágenes, como en la imagen ampliada?.
Saludos
Juan Jose
Re: galería de imágenes
Posted: Fri Jan 08, 2021 12:32 pm
by José Luis Sánchez
Thanks a lot !!! It's an incredible Reyes Magos gift !!!
Kind regards,
José Luis
Re: galería de imágenes
Posted: Thu Jan 14, 2021 5:28 pm
by José Luis Sánchez
Really nice !!!
How can I add action when doubleclick an image ? I want to call the book edit function when double click the image of any cover.
Regards,
Re: galería de imágenes
Posted: Thu Jan 14, 2021 6:08 pm
by AngelSalom
nageswaragunupudi wrote:Sure.
Add code something similar to
Code: Select all
oImage:bLDblClick := { |r,c,f,oImage| HtmlView( oImage:uSource ) }
while creating the image control.
Re: galería de imágenes
Posted: Fri Jan 15, 2021 5:04 pm
by José Luis Sánchez
Thanks Angel, it works fine.
I have 2 new questions:
1.- I call the TAlbum window from another window but the focus returns to the parent window and the talbum window remains hiden. How can I stop the focus on the talbum window ?
2.- How can I center the talbum window over the parent window ? When I use dialogs I can do odlg:center(owndparent) but with another windows I don't know how tod do it.
I think these questions are FWH 101 but my programming skills are a bit rusty.
Regards,
José Luis
Re: galería de imágenes
Posted: Fri Jan 15, 2021 5:43 pm
by Antonio Linares
José Luis,
METHOD CreateWindow() CLASS TAlbum creates a non modal WINDOW.
Please change there DEFINE WINDOW into DEFINE DIALOG ...
also from METHOD Activate() CLASS TAlbum change ACTIVATE WINDOW into ACTIVATE DIALOG
Class TWindow implements Method Center( oWndParent ) so that message can be sent to any object whose class is or inherits from TWindow
Re: galería de imágenes
Posted: Fri Jan 15, 2021 6:06 pm
by José Luis Sánchez
Antonio,
If I change the Windows for the Dialog I will loss the VScroll feature that is very important for me.
RPreview is also a non modal window but it remains on top of the screen: How can I do this ?
Regards,