// IconGroup control by Ramón Avendaño
// 15-08-98
#include "FiveWin.ch"
#include "Constant.ch"
#define GWL_STYLE -16
#define COLOR_ACTIVECAPTION 2
#define COLOR_WINDOW 5
#define COLOR_WINDOWTEXT 8
#define COLOR_CAPTIONTEXT 9
#define SOURCE_VCOORS 5
#define SOURCE_HCOORS 35
#define STEP_VCOORS 85
#define STEP_HCOORS 75
#define LAPSTEP_HCOORS STEP_HCOORS - 32
#define STEP_VSCROLL 16
#define STEP_HSCROLL 16
#define MK_MBUTTON 0x0010
#ifdef __XPP__
#define Super ::TControl
#define New _New
#endif
STATIC nFirst:= 0 // Victor Daniel Cuatecatl León 01/Sep/2013
STATIC nLast := 0 // Victor Daniel Cuatecatl León 01/Sep/2013
STATIC nScrPos:= 0 // Victor Daniel Cuatecatl León 02/Sep/2013
STATIC nDown:= 0 // Victor Daniel Cuatecatl León 03/Sep/2013
STATIC nView:= 0 // Victor Daniel Cuatecatl León 03/Sep/2013
STATIC nPage:= 0 // Victor Daniel Cuatecatl León 05/Sep/2013
//----------------------------------------------------------------------------//
CLASS TIconGroup FROM TControl
CLASSDATA lRegistered AS LOGICAL
DATA aIcons, aPrompts, aActions
DATA aCoors, aOrder
DATA nVScroll AS NUMERIC INIT 0
DATA nHScroll AS NUMERIC INIT 0
DATA nIcoCol AS NUMERIC INIT 0 // Victor Daniel Cuatecatl León 01/Sep/2013
DATA nIcoRow AS NUMERIC INIT 0 // Victor Daniel Cuatecatl León 01/Sep/2013
DATA nFocused
DATA lStatic
DATA lEdit, lAutoEdit
DATA oGet
METHOD New( nRow, nCol, aIcons, aPrompts, aActions, ;
oWnd, nHelpId, lNoBorder, bChange, nWidth, nHeight, cMsg, ;
lPixel, lVScroll, lHScroll, nClrFore, nClrBack, ;
oFont, oCursor, lDesign, LUPDATE ) CONSTRUCTOR
METHOD REDEFINE( nId, aIcons, aPrompts, aActions, oWnd, nHelpId, bChange, cMsg, ;
nClrFore, nClrBack, oFont, oCursor, LUPDATE ) CONSTRUCTOR
METHOD Initiate( hDlg ) INLINE Super:Initiate( hDlg ), ::DEFAULT()
METHOD DISPLAY() INLINE ::BeginPaint(), ::PAINT(), ::EndPaint()
METHOD SetVScroll()
METHOD SetHScroll()
METHOD SetScrollRange()
METHOD DEFAULT()
METHOD GetDlgCode( nLastKey )
METHOD CoorsUpdate()
METHOD PAINT()
METHOD END() INLINE AEVAL( ::aIcons, {| hIcon | IF( hIcon != 0, ;
DestroyIcon( hIcon ), Nil ) } ),Super:END()
METHOD _VScroll( nMove )
METHOD _HScroll( nMove )
METHOD ShowFocus( lFocused )
METHOD ChangeFocus( nFocused )
METHOD GotFocus( hCtlLost ) INLINE ::ShowFocus( .t. ), Super:GotFocus( hCtlLost )
METHOD LostFocus( hWndGetFocus ) INLINE ::ShowFocus( .f. ), Super:LostFocus( hWndGetFocus )
METHOD ReSize( nType, nWidth, nHeight ) INLINE Super:ReSize( nType, nWidth, nHeight ), ;
::SetScrollRange()
METHOD nGetDown( nRow, nCol )
METHOD LButtonDown( nRow, nCol, nFlags )
METHOD LButtonUp( nRow, nCol, nFlags )
METHOD MouseMove( nRow, nCol, nKeyFlags )
METHOD LDblClick( nRow, nCol, nKeyFlags )
METHOD EditPrompt( nAt, uVar, bValid, nClrFore, nClrBack )
METHOD aGetAway()
METHOD nGetTail()
METHOD DrawIcon( nAt )
METHOD Add( hIcon, cPrompt, bAction )
METHOD Modify( hIcon, cPrompt, bAction, nAt )
METHOD Del( nAt )
METHOD Arrange() INLINE ::Adjust(), ::Refresh(), ;
::nVScroll := 0, ::nHScroll := 0, ::SetScrollRange()
METHOD Invert( nRow, nCol, nRowInit, nColInit )
METHOD Adjust()
METHOD KeyDown( nKey, nFlags ) // Victor Daniel Cuatecatl León 12/Ago/2013
METHOD MouseWheel( nKeys, nDelta ) // Victor Daniel Cuatecatl León 12/Ago/2013
METHOD Reset() INLINE nPage:= 0,nView:= 0,::nIcoCol:= 0,::nIcoRow:= 0 // Victor Daniel Cuatecatl León 12/Ago/2013
ENDCLASS
//----------------------------------------------------------------------------//
METHOD New( nRow, nCol, aIcons, aPrompts, aActions, ;
oWnd, nHelpId, lNoBorder, bChange, nWidth, nHeight, cMsg, ;
lPixel, lVScroll, lHScroll, nClrFore, nClrBack, ;
oFont, oCursor, lDesign, LUPDATE ) CLASS TIconGroup
#ifdef __XPP__
#undef New
#endif
DEFAULT aIcons := {}, aPrompts := {}, aActions := {}
DEFAULT nHelpId:= 0
DEFAULT nRow := 0, nCol := 0, oWnd := GetWndDefault()
DEFAULT lNoBorder := .f., lVScroll := .f., lHScroll := .f.
DEFAULT nClrFore := GetSysColor( COLOR_WINDOWTEXT ),;
nClrBack := GetSysColor( COLOR_WINDOW )
DEFAULT nWidth := 100, nHeight := 100,;
LUPDATE := .f., lDesign := .f.
::aIcons = aIcons
::aPrompts = aPrompts
::aActions = aActions
::nTop = IF( lPixel, nRow, nRow * WIN_CHARPIX_H ) //16
::nLeft = IF( lPixel, nCol, nCol * WIN_CHARPIX_W ) //8
::nBottom = ::nTop + nHeight
::nRight = ::nLeft + nWidth
::bChange = bChange
::oWnd = oWnd
::nStyle = nOR( IF( lNoBorder, 0, WS_BORDER ), ;
IF( lVScroll, WS_VSCROLL, 0 ),;
IF( lHScroll, WS_HSCROLL, 0 ),;
WS_CHILD, WS_VISIBLE, WS_GROUP, WS_TABSTOP,;
IF( lDesign, WS_CLIPSIBLINGS, 0 ) )
::nId = ::GetNewId()
::lStatic = .f.
::lDrag = lDesign
::lCaptured = .f.
::lEdit = .f.
::oFont = oFont
::oCursor = oCursor
::cMsg = cMsg
::LUPDATE = LUPDATE
::lAutoEdit := .f.
#ifdef __XPP__
::nVScroll = 0
::nHScroll = 0
#endif
::SETCOLOR( nClrFore, nClrBack )
::Register( nOR( CS_VREDRAW, CS_HREDRAW ) )
IF ! EMPTY( oWnd:hWnd )
::CREATE()
::DEFAULT()
oWnd:AddControl( Self )
ELSE
oWnd:DefControl( Self )
ENDIF
IF lDesign
::CheckDots()
ENDIF
RETURN Self
//----------------------------------------------------------------------------//
METHOD REDEFINE( nId, aIcons, aPrompts, aActions, oWnd, nHelpId, bChange, cMsg, ;
nClrFore, nClrBack, oFont, oCursor, LUPDATE ) CLASS TIconGroup
DEFAULT aIcons := {}, aPrompts := {}, aActions := {}
DEFAULT nClrFore := GetSysColor( COLOR_WINDOWTEXT ),;
nClrBack := GetSysColor( COLOR_WINDOW )
DEFAULT LUPDATE := .f., oWnd := GetWndDefault()
DEFAULT nHelpId := 0
::aIcons = aIcons
::aPrompts = aPrompts
::aActions = aActions
::nId = nId
::bChange = bChange
::oWnd = oWnd
::lStatic = .f.
::lDrag = .f.
::lCaptured = .f.
::lEdit = .f.
::oFont = oFont
::oCursor = oCursor
::cMsg = cMsg
::LUPDATE = LUPDATE
::lAutoEdit := .f.
#ifdef __XPP__
::nVScroll = 0
::nHScroll = 0
#endif
::SETCOLOR( nClrFore, nClrBack )
::Register( nOR( CS_VREDRAW, CS_HREDRAW ) )
IF oWnd != Nil
oWnd:DefControl( Self )
ENDIF
RETURN Self
//----------------------------------------------------------------------------//
METHOD SetVScroll() CLASS TIconGroup
DEFINE SCROLLBAR ::oVScroll OF Self ;
VERTICAL ;
RANGE 0, 1 ;
PAGESTEP 1 ;
ON UP ::_VScroll( -STEP_VSCROLL ) ;
ON DOWN ::_VScroll( STEP_VSCROLL ) /*;
ON PAGEUP ::_VScroll( 1 * -STEP_VSCROLL) ;
ON PAGEDOWN ::_VScroll( 1 * STEP_VSCROLL )*/
::oVSCroll:bPos := {| nPos | ::_VScroll( ( nPos - ::oVScroll:GetPos() ) * STEP_VSCROLL ), ;
::oVScroll:SETPOS(nPos) }
::oVSCroll:bTrack := ::oVSCroll:bPos
RETURN Nil
//----------------------------------------------------------------------------//
METHOD SetHScroll() CLASS TIconGroup
DEFINE SCROLLBAR ::oHScroll OF Self ;
HORIZONTAL ;
RANGE 0, 0 ;
PAGESTEP 1 ;
ON UP ::_HScroll( -STEP_HSCROLL ) ;
ON DOWN ::_HScroll( STEP_HSCROLL ) ;
ON PAGEUP ::_HScroll( 1 * -STEP_HSCROLL) ;
ON PAGEDOWN ::_HScroll( 1 * STEP_HSCROLL )
::oHSCroll:bPos := {| nPos | ::_HSCroll( ( nPos - ::oHSCroll:GetPos() ) * STEP_HSCROLL ), ;
::oHSCroll:SETPOS(nPos) }
::oHSCroll:bTrack := ::oHSCroll:bPos
RETURN Nil
//----------------------------------------------------------------------------//
METHOD SetScrollRange() CLASS TIconGroup
LOCAL nVMax, nHMax
LOCAL aAway := ::aGetAway()
LOCAL nAlto := ::nBottom - ::nTop
IF LEN( ::aIcons ) = 0
nVMax := 0
nHMax := 0
ELSE
nVMax := aAway[ 1 ]
nHMax := aAway[ 2 ]
IF nVMax <> nFirst .AND. nFirst > 0 // Victor Daniel Cuatecatl León 01/Sep/2013
::nIcoRow:= ::nIcoRow + 1
ENDIF
IF nHMax <> nLast // Victor Daniel Cuatecatl León 01/Sep/2013
::nIcoCol:= ::nIcoCol + 1
ENDIF
nFirst:= nVMax // Victor Daniel Cuatecatl León 01/Sep/2013
nLast:= nHMax // Victor Daniel Cuatecatl León 01/Sep/2013
IF LEN(::aIcons) > (::nIcoRow * ::nIcoCol) // Victor Daniel Cuatecatl León 01/Sep/2013
::nIcoRow:= ::nIcoRow + 1
ENDIF
nVMax := IF( nVMax < nAlto .AND. ::nVScroll = 0, ; // Victor Daniel Cuatecatl León 02/Sep/2013
(0), (nView:= nView + 1,(((nVMax - nAlto) + STEP_VCOORS) / STEP_VSCROLL)))
nHMax := IF( nHMax < ( (::nRight - ::nLeft) - STEP_HCOORS ) .AND. ::nHScroll = 0, ;
(0), ( nHMax - SOURCE_HCOORS ) / STEP_HSCROLL )
ENDIF
IF ::oVScroll != Nil
::oVScroll:SetRange( 0, nVMax)
::oVScroll:SETPOS( ::nVScroll )
ENDIF
IF ::oHScroll != Nil
::oHScroll:SetRange( 0, nHMax )
::oHScroll:SETPOS( ::nHScroll )
ENDIF
nScrPos:= (nVMax / ::nIcoRow)
nDown:= nScrPos
RETURN Nil
//----------------------------------------------------------------------------//
METHOD DEFAULT() CLASS TIconGroup
LOCAL nLen
LOCAL aRect := GetCoors( ::hWnd )
LOCAL nIcons := LEN( ::aIcons )
LOCAL nPrompts := LEN( ::aPrompts )
LOCAL nActions := LEN( ::aActions )
IF ::oFont != Nil
::SetFont( ::oFont )
ELSE
::SetFont( ::oWnd:oFont )
ENDIF
IF lAnd( GetWindowLong( ::hWnd, GWL_STYLE ), WS_VSCROLL )
::SetVScroll()
ENDIF
IF lAnd( GetWindowLong( ::hWnd, GWL_STYLE ), WS_HSCROLL )
::SetHScroll()
ENDIF
::nTop = aRect[1]
::nLeft = aRect[2]
::nBottom = aRect[3]
::nRight = aRect[4]
nLen = MAX( nIcons, nPrompts )
IF nLen == 0
::aIcons := {}
::aPrompts := {}
::aActions := {}
::aCoors := {}
::aOrder := {}
::nFocused = 0
ELSE
ASIZE( ::aIcons, nLen ); AFILL( ::aIcons, "", nIcons + 1 )
AEVAL( ::aIcons, {| cIcon, nAt | ::aIcons[ nAt ] := IF( FILE( cIcon ), ;
ExtractIcon( cIcon ), LoadIcon( GetResources(), cIcon ) ) } )
// AEval( ::aPrompts, {| cPrompt, nPrompt | ::aPrompts[ nPrompt ] += Chr(0) } )
ASIZE( ::aPrompts, nLen ); AFILL( ::aPrompts, "", nPrompts + 1 )
ASIZE( ::aActions, nLen ); AFILL( ::aActions, {|| Nil }, nActions + 1 )
::aCoors = ARRAY( nLen, 8 )
::aOrder = ARRAY( nLen )
::nFocused = 1
ENDIF
::Adjust(); ::DISPLAY(); ::SetScrollRange()
RETURN Nil
//----------------------------------------------------------------------------//
METHOD GetDlgCode( nLastKey ) CLASS TIconGroup
IF .not. ::oWnd:lValidating
IF nLastKey == VK_RETURN .OR. nLastKey == VK_TAB
::oWnd:nLastKey = nLastKey
ENDIF
ENDIF
RETURN DLGC_WANTALLKEYS
//----------------------------------------------------------------------------//
METHOD PAINT() CLASS TIconGroup
LOCAL n, nAt
LOCAL hDC, hFont
hDC := GetDC( ::hWnd )
hFont := IF( ::oFont != Nil, ::oFont:hFont, 0 )
FOR n := 1 TO LEN( ::aOrder )
nAt := ::aOrder[ n ]
::aCoors[ nAt ] = ExtDrawIcon( hDC, ::aCoors[ nAt, 1 ], ::aCoors[ nAt, 2 ], ;
::aIcons[ nAt ], ::aPrompts[ nAt ], hFont, ;
::nClrText, ::nClrPane, .f., .f., ::lEdit )
NEXT
ReleaseDC( ::hWnd, hDC )
::ShowFocus( ::lFocused )
RETURN Super:PAINT()
//----------------------------------------------------------------------------//
METHOD _VScroll( nMove ) CLASS TIconGroup
LOCAL aRect := GetClientRect( ::hWnd )
IF ( ::nVScroll + nMove ) < 0
nMove := -::nVScroll
ENDIF
IF ( ::nVScroll + nMove ) > ( ::oVScroll:nMax * STEP_VSCROLL )
nMove := ( ::oVScroll:nMax * STEP_VSCROLL ) - ::nVScroll
ENDIF
AEVAL( ::aCoors, {| aCoor | aCoor[ 1 ] -= nMove } )
ScrollWindow( ::hWnd, 0, -nMove, aRect, aRect )
::nVScroll += nMove
RETURN Nil
//----------------------------------------------------------------------------//
METHOD _HScroll( nMove ) CLASS TIconGroup
LOCAL aRect := GetClientRect( ::hWnd )
IF ( ::nHScroll + nMove ) < 0
nMove := -::nHScroll
ENDIF
IF ( ::nHScroll + nMove ) > ( ::oHScroll:nMax * STEP_HSCROLL )
nMove := ( ::oHScroll:nMax * STEP_HSCROLL ) - ::nHScroll
ENDIF
AEVAL( ::aCoors, {| aCoor | aCoor[ 2 ] -= nMove } )
ScrollWindow( ::hWnd, -nMove, 0, aRect, aRect )
::nHScroll += nMove
RETURN Nil
//----------------------------------------------------------------------------//
METHOD ShowFocus( lFocused ) CLASS TIconGroup
LOCAL nAt := ::nFocused
LOCAL hDC, hFont
IF nAt == 0
RETURN Nil
ENDIF
hDC := GetDC( ::hWnd )
hFont := IF( ::oFont != Nil, ::oFont:hFont, 0 )
::aCoors[ nAt ] = ExtDrawIcon( hDC, ::aCoors[ nAt, 1 ], ::aCoors[ nAt, 2 ], ;
::aIcons[ nAt ], ::aPrompts[ nAt ], hFont, ;
::nClrText, ::nClrPane, lFocused, .t., ::lEdit )
ReleaseDC( ::hWnd, hDC )
RETURN Nil
//----------------------------------------------------------------------------//
METHOD ChangeFocus( nFocused ) CLASS TIconGroup
LOCAL nAt := ::nFocused
LOCAL hDC, hFont
IF nAt == 0 .OR. nAt == nFocused
RETURN Nil
ENDIF
hDC := GetDC( ::hWnd )
hFont := IF( ::oFont != Nil, ::oFont:hFont, 0 )
ExtDrawIcon( hDC, ::aCoors[ nAt, 1 ], ::aCoors[ nAt, 2 ], ;
::aIcons[ nAt ], ::aPrompts[ nAt ], hFont, ;
::nClrText, ::nClrPane, .f., .f., .f. )
ExtDrawIcon( hDC, ::aCoors[ nFocused, 1 ], ::aCoors[ nFocused, 2 ], ;
::aIcons[ nFocused ], ::aPrompts[ nFocused ], hFont,;
::nClrText, ::nClrPane, ::lFocused, .t., .f. )
ReleaseDC( ::hWnd, hDC )
::nFocused = nFocused
ADEL( ::aOrder, ASCAN( ::aOrder, ::nFocused ) )
::aOrder[ LEN( ::aIcons ) ] := ::nFocused
::lEdit := .f.
IF ::bChange != Nil
EVAL( ::bChange )
ENDIF
RETURN Nil
//----------------------------------------------------------------------------//
METHOD nGetDown( nRow, nCol ) CLASS TIconGroup
LOCAL n, nAt, nDown := 0
FOR n := LEN( ::aOrder ) TO 1 step -1
nAt := ::aOrder[ n ]
IF nRow >= ::aCoors[ nAt, 1 ] .AND. nRow <= ::aCoors[ nAt, 3 ] .AND. ;
nCol >= ::aCoors[ nAt, 2 ] .AND. nCol <= ::aCoors[ nAt, 4 ]
nDown := nAt
EXIT
ENDIF
IF nRow >= ::aCoors[ nAt, 5 ] .AND. nRow <= ::aCoors[ nAt, 7 ] .AND. ;
nCol >= ::aCoors[ nAt, 6 ] .AND. nCol <= ::aCoors[ nAt, 8 ]
::lEdit := .t.
nDown := nAt
EXIT
ENDIF
NEXT
RETURN nDown
//----------------------------------------------------------------------------//
METHOD LButtonDown( nRow, nCol, nFlags ) CLASS TIconGroup
LOCAL nAt := ::nGetDown( nRow, nCol )
IF !::lFocused
::SetFocus()
ENDIF
IF nAt = 0
::lEdit := .f.
ELSE
::ChangeFocus( nAt )
ENDIF
IF nAt = 0 .OR. ::lStatic .OR. ::lDrag
RETURN Super:LButtonDown( nRow, nCol, nFlags )
ENDIF
IF ! ::lCaptured
::lCaptured = .t.
::Capture()
::Invert( , , nRow, nCol )
ENDIF
Super:LButtonDown( nRow, nCol, nFlags )
RETURN Nil
//----------------------------------------------------------------------------//
METHOD LButtonUp( nRow, nCol, nFlags ) CLASS TIconGroup
LOCAL nAt
IF ( ::lStatic .AND. !::lEdit ) .OR. ::lDrag
RETURN Super:LButtonUp( nRow, nCol, nFlags )
ENDIF
IF ::lCaptured
::lCaptured = .f.
ReleaseCapture()
::Invert()
::PAINT(); ::SetScrollRange()
ENDIF
IF ::lEdit
IF ::lAutoEdit
nAt := ::nFocused
::EditPrompt( nAt, ::aPrompts[ nAt ],;
{|uVar| IF( uVar != Nil, ::aPrompts[ nAt ] := uVar, ), ::DrawIcon( nAt ) },;
GetSysColor( COLOR_WINDOWTEXT ), GetSysColor( COLOR_CAPTIONTEXT ) ) // ::nClrText, ::nClrPane
ELSE
::lEdit := .f.
::PAINT(); ::SetScrollRange()
ENDIF
ELSE
::lEdit := .f.
ENDIF
Super:LButtonUp( nRow, nCol, nFlags )
RETURN Nil
//----------------------------------------------------------------------------//
METHOD MouseMove( nRow, nCol, nKeyFlags ) CLASS TIconGroup
IF ::lStatic .OR. ::lDrag
RETURN Super:MouseMove( nRow, nCol, nKeyFlags )
ENDIF
IF ::lCaptured
::Invert( nRow, nCol )
::lEdit := .f.
RETURN 0
ELSE
::oWnd:SetMsg( ::cMsg )
ENDIF
IF ::oCursor != Nil
SETCURSOR( ::oCursor:hCursor )
ELSE
CursorArrow()
ENDIF
RETURN 0
//----------------------------------------------------------------------------//
METHOD LDblClick( nRow, nCol, nKeyFlags ) CLASS TIconGroup
LOCAL nAt := ::nGetDown( nRow, nCol )
IF nAt == 0
RETURN Super:LDblClick( nRow, nCol, nKeyFlags )
ENDIF
::lEdit:= .f.
EVAL( ::aActions[ nAt ], Self )
RETURN Nil
//----------------------------------------------------------------------------//
METHOD EditPrompt( nAt, uVar, bValid, nClrFore, nClrBack ) CLASS TIconGroup
LOCAL oFont
LOCAL nWidth, nHeight
LOCAL aDim, aPos
uVar := STRTRAN( uVar, CHR(10), CRLF )
aDim := ::aCoors[ nAt ]
aPos := { aDim[5] - 1, aDim[6] - 1 }
nWidth := MAX( aDim[8] - aDim[6] + 1, 26 )
nHeight := aDim[7] - aDim[5] + 2
// ScreenToClient( Self:hWnd, aPos )
DEFAULT nClrFore := ::nClrText ,;
nClrBack := ::nClrPane ,;
bValid := {|| Nil }
IF ::oGet != Nil .AND. ! EMPTY( ::oGet:hWnd )
::oGet:END()
ENDIF
IF ::oFont != Nil
oFont = TFont():New( ::oFont:cFaceName, ::oFont:nWidth,;
::oFont:nHeight, .f., ::oFont:lBold )
ENDIF
::oGet:=TIconGet():New( aPos[ 1 ], aPos[ 2 ], bSETGET( uVar ), Self,;
nWidth, nHeight, oFont,;
nClrFore, nClrBack )
::nLastKey := 0
// ::oGet:Set3dLook()
::oGet:SetFocus()
::oGet:SelectAll()
::oGet:bLostFocus := {|| uVar := STRTRAN( ::oGet:cText(), CRLF, " " ),;
IF( Self:nLastKey != VK_ESCAPE,;
EVAL( bValid, uVar, Self:nLastKey ),;
EVAL( bValid, Nil, Self:nLastKey ) ),;
::oGet:END(), ::lEdit:= .f. }
::oGet:bKeyDown := { | nKey | IF( nKey == VK_RETURN .OR. ;
nKey == VK_ESCAPE, ;
(Self:nLastKey := nKey, ::oGet:END(), ::lEdit := .f. ),) }
RETURN .f.
//----------------------------------------------------------------------------//
METHOD aGetAway() CLASS TIconGroup
LOCAL nRow := 0, nCol := 0
IF !EMPTY( ::aCoors )
AEVAL( ::aCoors, { | aCoor | nRow := MAX( nRow, aCoor[ 1 ] ), ;
nCol := MAX( nCol, aCoor[ 2 ] ) } )
ENDIF
RETURN({ nRow + ::nVScroll, nCol + ::nHScroll })
//----------------------------------------------------------------------------//
METHOD nGetTail() CLASS TIconGroup
LOCAL nRow, nCol
LOCAL nTail := LEN( ::aIcons )
IF nTail > 0
nRow := ::aCoors[ nTail, 1 ]
AEVAL( ::aCoors, { | aCoor, nCoor | IF( aCoor[ 1 ] > nRow, ;
( nRow := aCoor[ 1 ], nTail := nCoor ), Nil ) } )
nCol := ::aCoors[ nTail, 1 ]
AEVAL( ::aCoors, { | aCoor, nCoor | IF( aCoor[ 1 ] = nRow .AND. aCoor[ 2 ] > nCol, ;
( nCol := aCoor[ 2 ], nTail := nCoor ), Nil ) } )
ENDIF
RETURN( nTail )
//----------------------------------------------------------------------------//
METHOD DrawIcon( nAt ) CLASS TIconGroup
LOCAL hDC, hFont
hDC := GetDC( ::hWnd )
hFont := IF( ::oFont != Nil, ::oFont:hFont, 0 )
::aCoors[ nAt ] = ExtDrawIcon( hDC, ::aCoors[ nAt, 1 ], ::aCoors[ nAt, 2 ], ;
::aIcons[ nAt ], ::aPrompts[ nAt ], hFont, ;
::nClrText, ::nClrPane, .f., .f., ::lEdit )
ReleaseDC( ::hWnd, hDC )
RETURN Nil
//----------------------------------------------------------------------------//
METHOD Add( hIcon, cPrompt, bAction ) CLASS TIconGroup
LOCAL nAt := LEN( ::aIcons ) + 1
LOCAL nTail := ::nGetTail()
LOCAL nX := SOURCE_HCOORS, nY := SOURCE_VCOORS
LOCAL aRect := GetClientRect( ::hWnd )
DEFAULT hIcon := 0, cPrompt := "", bAction := {|| Nil }
IF hIcon == 0 .AND. cPrompt == ""
RETURN Nil
ENDIF
IF nAt > 1
nY := ::aCoors[ nTail, 1 ]
nX := ::aCoors[ nTail, 2 ]
nX += STEP_HCOORS
IF nX + LAPSTEP_HCOORS > aRect[4]
nX := SOURCE_HCOORS
nY += STEP_VCOORS
END
ELSE
::nFocused := 1
ENDIF
AADD( ::aIcons, hIcon )
AADD( ::aPrompts, cPrompt )
AADD( ::aActions, bAction )
AADD( ::aCoors, { nY, nX, 0, 0, 0, 0, 0, 0 } )
AADD( ::aOrder, nAt )
::DrawIcon( nAt ); ::SetScrollRange()
::Refresh( .f. )
RETURN Nil
//----------------------------------------------------------------------------//
METHOD Modify( hIcon, cPrompt, bAction, nAt ) CLASS TIconGroup
DEFAULT hIcon := 0, cPrompt := "", bAction := {|| Nil }
IF ( hIcon == 0 .AND. cPrompt == "" ) .OR. ;
nAt > LEN( ::aIcons)
RETURN Nil
ENDIF
IF ::aIcons[ nAt ] != 0
DestroyIcon( ::aIcons[ nAt ] )
ENDIF
::aIcons[ nAt ] := hIcon
::aPrompts[ nAt ] := cPrompt
::aActions[ nAt ] := bAction
::DrawIcon( nAt ); ::SetScrollRange()
::Refresh( .t. )
RETURN Nil
//----------------------------------------------------------------------------//
METHOD Del( nAt ) CLASS TIconGroup
LOCAL nLen := LEN( ::aIcons ) - 1
IF nAt > nLen + 1 .OR. nAt = 0 .OR. nLen < 0
RETURN Nil
ENDIF
ADEL( ::aIcons, nAt ); ASIZE( ::aIcons, nLen )
ADEL( ::aPrompts, nAt ); ASIZE( ::aPrompts, nLen )
ADEL( ::aActions, nAt ); ASIZE( ::aActions, nLen )
ADEL( ::aCoors, nAt ); ASIZE( ::aCoors, nLen )
ADEL( ::aOrder, ASCAN( ::aOrder, nAt ) ); ASIZE( ::aOrder, nLen )
AEVAL( ::aOrder, {|u,n| IF( u > nAt, ::aOrder[ n ] := u - 1, ) } )
IF nAt < ::nFocused
::nFocused--
ELSEIF nAt == ::nFocused
::nFocused := IF( nLen == 0, 0, 1 )
ENDIF
::SetScrollRange()
::Refresh()
IF nLen == 0
::Reset() // Victor Daniel Cuatecatl León 01/Sep/2013
ENDIF
RETURN Nil
//----------------------------------------------------------------------------//
METHOD KeyDown( nKey, nFlags ) CLASS TIconGroup // Victor Daniel Cuatecatl León 12/Ago/2013
LOCAL cPrompt, nNewPos
LOCAL nAt:= ::nFocused
LOCAL nSteep:= ::nIcoCol
LOCAL nLen:= LEN(::aIcons)
LOCAL nVisibl:= nLen - nView
LOCAL XPos:= STEP_VCOORS * (nVisibl / ::nIcoCol)
LOCAL nRango:= (::oVScroll:GetRange()[2] / ::nIcoRow) * (nVisibl / ::nIcoCol)
DO CASE
CASE nKey == VK_UP
IF nAT <= nLen .AND. nAt - nSteep >= 1
nDown:= nDown - nScrPos
nAt:= nAt - nSteep
ENDIF
::oVScroll:SETPOS(nDown)
::_VScroll((-STEP_VSCROLL * 4.5))
::ChangeFocus(nAt)
RETURN 0
CASE nKey == VK_DOWN
IF nAT >= 1 .AND. nAt + nSteep <= nLen
nDown:= nDown + nScrPos
nAt:= nAt + nSteep
ELSEIF nAT > nLen
nAt:= nLen
ENDIF
::oVScroll:SETPOS(nDown)
::_VScroll((STEP_VSCROLL * 4.5))
::ChangeFocus(nAt)
RETURN 0
CASE nKey == VK_LEFT
IF nAT > 1
nAt:= nAt - 1
ENDIF
::ChangeFocus( nAt )
::oVScroll:SETPOS(nAt)
RETURN 0
CASE nKey == VK_RIGHT
IF nAT < nLen
nAt:= nAt + 1
ENDIF
::ChangeFocus(nAt)
::oVScroll:SETPOS(nAt)
RETURN 0
CASE nKey == VK_HOME
::oVScroll:SETPOS(1)
::_VScroll((-STEP_VSCROLL * (nLen+::nIcoRow)))
::ChangeFocus(1)
RETURN 0
CASE nKey == VK_END
::oVScroll:SETPOS(nLen)
::_VScroll((STEP_VSCROLL * (nLen +::nIcoRow)))
::ChangeFocus(nLen)
::Refresh()
RETURN 0
CASE nKey == VK_PRIOR
nAt:= nAt - nVisibl
IF nAt < 1
::ChangeFocus(1)
ELSE
::ChangeFocus(nAt)
nPage:= nPage - nRango
ENDIF
nNewPos:= ::oVScroll:GetPos()
IF nNewPos >= 0
::_VScroll(-XPos)
::oVScroll:SETPOS(nPage)
ENDIF
RETURN 0
CASE nKey == VK_NEXT
nAt:= nAt + nVisibl
IF nAt > nLen
::ChangeFocus(nLen)
//nPage:= nPage + nRango
ELSE
::ChangeFocus(nAt)
nPage:= nPage + nRango
ENDIF
nNewPos:= ::oVScroll:GetPos()
IF nNewPos < ::oVScroll:GetRange()[2]
::_VScroll(XPos)
::oVScroll:SETPOS(nPage)
ENDIF
RETURN 0
CASE nKey == VK_F2
IF ::lAutoEdit
::lEdit := .t.
MSGInfo(cPrompt)
cPrompt := ::aPrompts[nAt]
::EditPrompt( nAt, cPrompt,;
{|uVar| IF( uVar != Nil, ::aPrompts[ nAt ] := uVar, ), ::DrawIcon( nAt ) },;
GetSysColor( COLOR_WINDOWTEXT ), GetSysColor( COLOR_CAPTIONTEXT ) ) // ::nClrText, ::nClrPane
RETURN 0
ENDIF
ENDCASE
RETURN Super:KeyDown( nKey, nFlags )
//----------------------------------------------------------------------------//
METHOD Invert( nRow, nCol, nRowInit, nColInit ) CLASS TIconGroup
STATIC nInitRow, nInitCol, nOldRow, nOldCol
LOCAL nAt := ::nFocused
LOCAL lErase := .f.
::GetDC()
IF nRow = Nil .AND. nCol = Nil
IF nRowInit = Nil .AND. nColInit = Nil
lErase = .t.
::aCoors[ nAt ] = { ::aCoors[ nAt, 1 ] + nOldRow, ::aCoors[ nAt, 2 ] + nOldCol, ;
::aCoors[ nAt, 3 ] + nOldRow, ::aCoors[ nAt, 4 ] + nOldCol, ;
::aCoors[ nAt, 5 ] + nOldRow, ::aCoors[ nAt, 6 ] + nOldCol, ;
::aCoors[ nAt, 7 ] + nOldRow, ::aCoors[ nAt, 8 ] + nOldCol }
ELSE
nInitRow = nRowInit
nInitCol = nColInit
ENDIF
nRow = 0
nCol = 0
ELSE
IF nRow < 0 .OR. ( nRow + ::nTop > ::nBottom ) .OR. ;
nCol < 0 .OR. ( nCol + ::nLeft > ::nRight )
::ReleaseDC()
RETURN Nil
ENDIF
nRow = nRow - nInitRow
nCol = nCol - nInitCol
DrawFocusRect( ::hDC, ::aCoors[ nAt, 1 ] + nOldRow, ::aCoors[ nAt, 2 ] + nOldCol, ;
::aCoors[ nAt, 3 ] + nOldRow, ::aCoors[ nAt, 4 ] + nOldCol )
DrawFocusRect( ::hDC, ::aCoors[ nAt, 5 ] + nOldRow, ::aCoors[ nAt, 6 ] + nOldCol, ;
::aCoors[ nAt, 7 ] + nOldRow, ::aCoors[ nAt, 8 ] + nOldCol )
ENDIF
DrawFocusRect( ::hDC, ::aCoors[ nAt, 1 ] + nRow, ::aCoors[ nAt, 2 ] + nCol, ;
::aCoors[ nAt, 3 ] + nRow, ::aCoors[ nAt, 4 ] + nCol )
DrawFocusRect( ::hDC, ::aCoors[ nAt, 5 ] + nRow, ::aCoors[ nAt, 6 ] + nCol, ;
::aCoors[ nAt, 7 ] + nRow, ::aCoors[ nAt, 8 ] + nCol )
IF lErase
FillRect( ::hDC, { ::aCoors[ nAt, 1 ] - nOldRow, ::aCoors[ nAt, 2 ] - nOldCol, ;
::aCoors[ nAt, 3 ] - nOldRow, ::aCoors[ nAt, 4 ] - nOldCol }, ::oBrush:hBrush )
FillRect( ::hDC, { ::aCoors[ nAt, 5 ] - nOldRow, ::aCoors[ nAt, 6 ] - nOldCol, ;
::aCoors[ nAt, 7 ] - nOldRow, ::aCoors[ nAt, 8 ] - nOldCol }, ::oBrush:hBrush )
ENDIF
nOldRow = nRow
nOldCol = nCol
::ReleaseDC()
RETURN Nil
//----------------------------------------------------------------------------//
METHOD Adjust() CLASS TIconGroup
LOCAL nAt
LOCAL nX := SOURCE_HCOORS, nY := SOURCE_VCOORS
LOCAL aRect := GetClientRect( ::hWnd )
FOR nAt:= 1 TO LEN( ::aIcons )
::aCoors[ nAt, 1 ] := nY
::aCoors[ nAt, 2 ] := nX
::aOrder[ nAt ] := nAt
nX += STEP_HCOORS
IF nX + LAPSTEP_HCOORS > aRect[4]
nX := SOURCE_HCOORS
nY += STEP_VCOORS
END
NEXT
RETURN Nil
//----------------------------------------------------------------------------//
METHOD CoorsUpdate() CLASS TIconGroup
LOCAL aRect := GetCoors( ::hWnd )
::nTop = aRect[ 1 ]
::nLeft = aRect[ 2 ]
::nBottom = aRect[ 3 ]
::nRight = aRect[ 4 ]
RETURN Nil
//----------------------------------------------------------------------------//
// R.Avendaño. 1998
//----------------------------------------------------------------------------//
METHOD MouseWheel( nKeys, nDelta ) CLASS TIconGroup // Victor Daniel Cuatecatl León 12/Ago/2013
LOCAL nAt := ::nFocused
LOCAL nLen := LEN( ::aIcons )
IF lAnd( nKeys, MK_MBUTTON )
IF nDelta > 0
IF ++nAT > nLen
nAt = 1
ENDIF
ELSE
IF --nAT < 1
nAt = nLen
ENDIF
ENDIF
::ChangeFocus( nAt )
::oVScroll:SETPOS(nAt)
ELSE
IF nDelta > 0
::_VScroll( -STEP_VSCROLL)
::oVScroll:PageUp()
ELSE
::_VScroll( STEP_VSCROLL)
::oVScroll:PageDown()
ENDIF
ENDIF
RETURN Nil