/* * Fichero: Switch.prg * Clase TSwitch * * Copyright 2020 Ignacio Ortiz de Zúñiga * Copyright 2020 https://Xailer.com * All rights reserved */ #include "Xailer.ch" CLASS XSwitch FROM TStdControl PUBLISHED: PROPERTY nWidth INIT 137 PROPERTY nHeight INIT 30 PROPERTY lChecked INIT .F. READ METHOD GetChecked WRITE METHOD SetChecked PROPERTY nClrText INIT clWindowText EDITOR PE_Color WRITE INLINE ( ::FnClrText := Value, ::Refresh() ) PROPERTY nClrPane INIT clWindow EDITOR PE_Color WRITE INLINE ( ::FnClrPane := Value, ::Refresh() ) PROPERTY nClrColorization INIT 0 EDITOR PE_Color WRITE INLINE ( ::FnClrColorization := Value, ::Refresh() ) PROPERTY cTextChecked INIT "" WRITE INLINE ( ::FcTextChecked := Value, ::Refresh() ) PROPERTY cTextUnChecked INIT "" WRITE INLINE ( ::FcTextUnChecked := Value, ::Refresh() ) PROPERTY lTabStop INIT .T. PROPERTY lTransparent INIT .T. PROPERTY nOpacity INIT 0 EVENT OnChange( oSender, lNewValue ) // --> Nil | lContinue EVENT OnClick( oSender ) // --> Nil PROTECTED: PROPERTY cText PROPERTY lBorder PROPERTY l3D DATA nCtlStyle INIT nOr( WS_CHILD, WS_CLIPCHILDREN, WS_CLIPSIBLINGS, WS_TABSTOP ) DATA aClickPos INIT {0,0} DATA nDotPos, nDotMid INIT 0 DATA lIsHot INIT .F. DATA lIsCaptured INIT .F. DATA lIsSmooth INIT .F. PUBLIC: METHOD Create( oParent ) CONSTRUCTOR METHOD Toggle() INLINE ::SetChecked( ! ::GetChecked(), .T. ) // --> Nil METHOD Click() INLINE ::Toggle(), ::OnClick(), 0 RESERVED: METHOD GetChecked() METHOD SetChecked( lValue, lSmooth ) METHOD WMEraseBkgnd() INLINE 1 METHOD WMKeyDown( nFlags, nLParam, hWnd ) METHOD WMMouseMove( nWParam, nLParam, hWnd ) METHOD WMMouseLeave() INLINE IIf( ::lIsHot, ( ::lIsHot := .F., ::Refresh( .F. ) ), ) METHOD WMLButtonDown( nWParam, nLParam, hWnd ) METHOD WMLButtonUp( nWParam, nLParam, hWnd ) METHOD WMKillFocus( hCtl ) INLINE ( ::Super:WMKillFocus( hCtl ), ::Refresh( .F. ) ) METHOD WMSetFocus( hCtl ) INLINE ( ::Super:WMSetFocus( hCtl ), ::Refresh( .F. ) ) METHOD WMPaint() METHOD XAClick() VIRTUAL ENDCLASS //------------------------------------------------------------------------------ METHOD Create( oParent ) CLASS XSwitch ::Super:Create( oParent ) ::SetChecked( ::FlChecked ) RETURN Self //------------------------------------------------------------------------------ METHOD GetChecked() CLASS XSwitch RETURN ::FlChecked //------------------------------------------------------------------------------ METHOD SetChecked( lValue, lSmooth ) CLASS XSwitch LOCAL lOk IF Valtype( lValue ) == "N" lValue := ( lValue != 0 ) ENDIF IF ::FlChecked != lValue lOk := ::OnChange( @lValue ) IF lOk == NIL .OR. lOk ::FlChecked := lValue IF lSmooth != NIL ::lIsSmooth := lSmooth ::nDotPos := 0 ENDIF IF ! Empty( ::Handle ) InvalidateRect( ::Handle ) ENDIF ENDIF ENDIF RETURN ::FlChecked //------------------------------------------------------------------------------ METHOD WMLButtonDown( nWParam, nLParam, hWnd ) CLASS XSwitch IF ::lEnabled ::lIsCaptured := .T. ::SetFocus() ::aClickPos := { LoInt( nLParam ), HiInt( nLParam ) } ::nDotPos := ::aClickPos[ 1 ] SetCapture( ::Handle ) ENDIF RETURN ::Super:WMLButtonDown( nWParam, nLParam, hWnd ) //------------------------------------------------------------------------------ METHOD WMLButtonUp( nWParam, nLParam, hWnd ) CLASS XSwitch LOCAL aPos, xDrag, yDrag IF ::lIsCaptured ::lIsCaptured := .F. ReleaseCapture( ::Handle ) xDrag := GetSystemMetrics( SM_CXDRAG ) yDrag := GetSystemMetrics( SM_CYDRAG ) aPos := { LoInt( nLParam ), HiInt( nLParam ) } IF PtInRect ( { ::aClickPos[ 1 ] - xDrag, ::aClickPos[ 2 ] - yDrag, ::aClickPos[ 1 ] + xDrag, ::aClickPos[ 2 ] + yDrag }, aPos ) ::Click() ELSE ::lChecked := ( ::nDotPos >= ::nDotMid ) ENDIF ::nDotPos := 0 ::Refresh( .F. ) ENDIF RETURN ::Super:WMLButtonUp( nWParam, nLParam, hWnd ) //------------------------------------------------------------------------------ METHOD WMKeyDown( nFlags, nLParam, hWnd ) CLASS XSwitch DO CASE CASE nFlags == VK_DOWN .OR. nFlags == VK_LEFT IF ::FlChecked ::SetChecked( .F., .T. ) ENDIF RETURN 0 CASE nFlags == VK_UP .or. nFlags == VK_RIGHT IF !::FlChecked ::SetChecked( .T., .T. ) ENDIF RETURN 0 CASE nFlags == VK_SPACE ::Toggle() RETURN 0 ENDCASE RETURN ::Super:WMKeyDown( nFlags, nLParam, hWnd ) //------------------------------------------------------------------------------ METHOD WMMouseMove( nWParam, nLParam, hWnd ) CLASS XSwitch IF !::lIsHot ::lIsHot := .T. ::Refresh( .F. ) TrackMouseEvent( ::Handle, TME_LEAVE ) ELSEIF ::lIsCaptured ::Refresh( .F. ) ENDIF RETURN ::Super:WMMouseMove( nWParam, nLParam, hWnd ) //------------------------------------------------------------------------------