/* * ProgressCircle.prg * Control circulo de progreso * * Copyright 2020 Ignacio Ortiz de Zúñiga * All rights reserved * */ #include "Xailer.ch" /* Note about lMarquee functionality: By default this functionality is done using a internal timer, but this has two limitations: 1) You must call the ProcessMessages() funtion on your working loop 2) You may experience stops on the progress circle due the working task In order to avoid those problems you should use a TFuture, but this forces to use the Multi-thread library (mtvm.lib). For example: METHOD MyHeavyTask() CLASS TForm1 LOCAL oFuture, bTask, bComplete bTask := {|| MyHeavyTask() } bComplete := { || ::oProgresBar:lMarquee := .F. } oFuture := TFuture():CreateFrom( bTask, bComplete ) ::oProgresCircle:lMarquee := .T. */ //-------------------------------------------------------------------------- CLASS XProgressCircle FROM TStdControl PUBLISHED: PROPERTY nWidth INIT 120 PROPERTY nHeight INIT 120 PROPERTY nClrPane INIT clBtnFace ; WRITE INLINE ( ::FnClrPane := Value, ::Refresh() ) ; EDITOR PE_Color PROPERTY nClrCircle INIT clSystem; WRITE INLINE ( ::FnClrCircle := Value, ::Refresh() ) ; EDITOR PE_Color PROPERTY nCircleGap INIT 20; WRITE INLINE ( ::FnCircleGap := Value, ::Refresh() ) PROPERTY nCircleSize INIT 20; WRITE INLINE ( ::FnCircleSize := Value, ::Refresh() ) PROPERTY lShowPercent INIT .F. ; WRITE INLINE ( ::FlShowPercent := Value, ::Refresh() ) PROPERTY lTransparent INIT .T. PROPERTY nBorderStyle INIT bvNONE PROPERTY nValue INIT 0 WRITE SetPos PROPERTY nMin INIT 0 WRITE INLINE ::SetRange( Value, ::nMax ) PROPERTY nMax INIT 100 WRITE INLINE ::SetRange( ::nMin, Value ) PROPERTY nBackOpacity INIT 63 WRITE INLINE ( ::FnBackOpacity := Value, ::Refresh() ) PROPERTY lMarquee INIT .F. WRITE SetMarquee PROPERTY nMarqueeSpeed INIT 100 WRITE INLINE ::FnMarqueeSpeed := Value, ::SetMarquee() EVENT OnChange( oSender, nPos ) // --> Nil METHOD Create( oParent ) CONSTRUCTOR METHOD Destroy( lFree ) INLINE iif( ::oTimer != NIL, ::oTimer:End(), ), ::Super:Destroy( lFree ) PROTECTED: PROPERTY cText PROPERTY lBorder INIT .F. PROPERTY l3D PROPERTY lTabStop INIT .F. DATA nCtlStyle INIT nOr( WS_CHILD, WS_CLIPCHILDREN, WS_CLIPSIBLINGS ) DATA oTimer DATA nMarquee INIT 0 RESERVED: METHOD SetPos( nPos, lEvents ) METHOD SetMarquee( lValue ) METHOD SetRange( nMin, nMax ) INLINE ::FnMin := nMin, ::FnMax := nMax, ; ::Refresh() METHOD WMPaint() METHOD WMEraseBkgnd() INLINE 1 METHOD WMPrintClient() EXTERN XProgressCircle_WMPaint() ENDCLASS //-------------------------------------------------------------------------- METHOD Create( oParent ) CLASS XProgressCircle ::Super:Create( oParent ) ::SetMarquee() RETURN Self //-------------------------------------------------------------------------- METHOD SetPos( nPos, lEvents ) CLASS XProgressCircle DEFAULT lEvents TO .T. ::FnValue := nPos IF lEvents .AND. !::lMarquee ::OnChange( nPos ) ENDIF ::Refresh() RETURN nPos //-------------------------------------------------------------------------- METHOD SetMarquee( lValue ) CLASS XProgressCircle DEFAULT lValue TO ::FlMarquee IF ::oTimer != NIL ::oTimer:End() ::oTimer := NIL ENDIF IF lValue .AND. ::lCreated ::oTimer := TTimer():Create( Self ) ::oTimer:nInterval := ::nMarqueeSpeed ::oTimer:OnTimer := {|| ::Refresh() } ::oTimer:lEnabled := .t. ENDIF ::flMarquee := lValue RETURN lValue //--------------------------------------------------------------------------