habe heute mal ein anderes Problem.
Kenne mich mit Klassen und Methoden noch nicht so aus. Habe in den Xbase++ News eine Progressbar gefunden die mir sehr gut gefällt.
In der Original Version wurde die Prozentanzeige zentriert dargestellt. Habe das geändert das diese immer links
erscheint. Möchte das jetzt aber wahlweise haben, wenn ich einen Text übergebe (cTitle) sollte das von links
in etwa so sein
10% von Muster.pdf erstellt.
wenn ich keinen Text übergebe sollte die Prozentzahl zentriert dargestellt werden.
Wo ich das machen muss ist mir klar, Zeile 69 bzw. 70, aber wie übergebe ich den Parameter ?
habe mir das so gedacht:
if empty(cTitle)
::Percentage:Options := XBPSTATIC_TEXT_CENTER+XBPSTATIC_TEXT_VCENTER
else
::Percentage:Options := XBPSTATIC_TEXT_LEFT+XBPSTATIC_TEXT_VCENTER
endif
und in Zeile 333
IF !EMPTY(::Percent)
if empty(cTitle)
::Percent:SetCaption(STR(INT(100*::_current/(::maximum-::minimum)),3)+"%")
else
::Percent:SetCaption(STR(INT(100*::_current/(::maximum-::minimum)),3)+"%"+" von "+cTitle+ " erstellt)
endif
ENDIF
Hier der Source Code
Code: Alles auswählen
#xtrans CenterPos( <aProgSize>, <aRefSize> ) => ;
{ Int( (<aRefSize>\[1] - <aProgSize>\[1]) / 2 ) ;
, Int( (<aRefSize>\[2] - <aProgSize>\[2]) / 2 ) }
Private oProgDlg , ;
aProgSize := {600,100} // horizontal
PROCEDURE statusanzeige (nMode, nMin, nMax, fromcol, fromrow, n_width, n_height, cTitle)
Local nColor := 2 // Blau
default cTitle to " "
default fromcol to 0
default fromrow to 0
default n_width to 400
default n_height to 24
default nMax to 100
do case
case nMode = 0
oProgDlg := StartProgress(Appdesktop(),aProgSize,nMin,nMax,nColor,cTitle)
case nMode = 1
IncProgress(oProgDlg)
case nMode = 2
oProgDlg:Destroy()
oProgDlg:= NIL
sleep(5)
endcase
RETURN
FUNCTION StartProgress(oParent,aProgSize,nMin,nMax,nColor,cTitle)
LOCAL oDlg
IF EMPTY(aProgSize)
aProgSize := {300,55}
ENDIF
oDlg := ProgressDlg():NEW(oParent,,CenterPos(aProgSize,oParent:CurrentSize()),aProgSize)
oDlg:ProgressBar:minimum := nMin
oDlg:ProgressBar:maximum := nMax
IF nColor != NIL
oDlg:ProgressBar:Color := nColor
ENDIF
oDlg:create()
RETURN oDlg
PROCEDURE IncProgress(oProgDlg)
oProgDlg:ProgressBar:increment()
RETURN
CLASS ProgressDlg FROM XbpDialog
EXPORTED:
VAR ProgressBar,Percentage
INLINE METHOD INIT(oParent, oOwner, aPos, aProgSize, aPP, lVisible )
::XbpDialog:Init(oParent, oOwner, aPos, aProgSize, aPP, lVisible )
::TitleBar := .F.
IF aProgSize[1]>aProgSize[2] // wide use horizontal
::ProgressBar:= ProgressBar():New(::XbpDialog,,{10,aProgSize[2]/2-INT(0.3*aProgSize[2])},{aProgSize[1]-20,INT(0.3*aProgSize[2])})
IF aProgSize[2] >= 50
::Percentage := XbpStatic():New(::XbpDialog,,{10,aProgSize[2]-INT(0.5*aProgSize[2])},{aProgSize[1]-20,INT(0.3*aProgSize[2])})
::Percentage:Type := XBPSTATIC_TYPE_TEXT
// ::Percentage:Options := XBPSTATIC_TEXT_CENTER+XBPSTATIC_TEXT_VCENTER
::Percentage:Options := XBPSTATIC_TEXT_LEFT+XBPSTATIC_TEXT_VCENTER
::ProgressBar:Percent := ::Percentage
ENDIF
ELSE
::ProgressBar:= ProgressBar():New(::XbpDialog,,{aProgSize[1]/2+INT(0.3*aProgSize[1])/4,10},{INT(0.3*aProgSize[1]),aProgSize[2]-20})
IF aProgSize[1] >= 50
::Percentage := XbpStatic():New(::XbpDialog,,{0,10},{INT(0.5*aProgSize[1]),aProgSize[2]-20})
::Percentage:Type := XBPSTATIC_TYPE_TEXT
// ::Percentage:Options := XBPSTATIC_TEXT_CENTER+XBPSTATIC_TEXT_VCENTER
::Percentage:Options := XBPSTATIC_TEXT_CENTER+XBPSTATIC_TEXT_LEFT
::ProgressBar:Percent := ::Percentage
ENDIF
ENDIF
RETURN Self
INLINE METHOD Create(oParent, oOwner, aPos, aProgSize, aPP, lVisible )
::XbpDialog:Create(oParent, oOwner, aPos, aProgSize, aPP, lVisible )
::ProgressBar:Create()
IF !EMPTY(::Percentage)
::Percentage:Create()
ENDIF
RETURN Self
INLINE METHOD Destroy()
::ProgressBar:Destroy()
::ProgressBar := NIL
::XbpDialog:Destroy()
RETURN Self
ENDCLASS
CLASS ProgressBar FROM XbpStatic
PROTECTED:
VAR squares, every, _current
METHOD displayHoriz, displayVert
EXPORTED:
VAR maxWait, color,Thread,sig
VAR minimum, current, maximum
VAR Percent
ASSIGN METHOD minimum, current, maximum
METHOD init , create , destroy , setSize
METHOD display, execute, increment
ENDCLASS
/*
* Initialize the object and set Thread:interval() to zero. This way,
* method :execute() is automatically repeated.
*/
METHOD ProgressBar:init( oParent, oOwner, aPos, aProgSize, aPP, lVisible )
::Thread := Thread():New() // don't inherhit
// ::Thread:init()
::Thread:setInterval( 1 ) // maybe the problem is with interval(0)-nope
::Thread:atStart := {|| ::xbpStatic:show() }
::Sig := Signal():New() // don't inherhit
// ::Signal:init()
::xbpStatic:init( oParent, oOwner, aPos, aProgSize, aPP, lVisible )
::xbpStatic:type := XBPSTATIC_TYPE_RAISEDBOX
::xbpStatic:paint := {|| ::display() }
::color := GRA_CLR_BLUE
::squares := 1
::current := 0
::every := 1
::maxWait := 100
::minimum := 0
::maximum := 100
RETURN
/*
* Request system resources; calculate the number or squares which
* fit into the progress bar and start the thread.
*/
METHOD ProgressBar:create( oParent, oOwner, aPos, aProgSize, aPP, lVisible )
::xbpStatic:create( oParent, oOwner, aPos, aProgSize, aPP, lVisible )
aProgSize := ::currentSize()
::squares := Int( aProgSize[1] / (aProgSize[2]+1) )
::Thread:start({||::execute()})
RETURN
/*
* Stop the thread of ProgressBar and release system resources
*/
METHOD ProgressBar:destroy
/*
* Turn off automatic repetition of :execute().
*/
::thread:setInterVal( NIL )
IF ::thread:active
/*
* Thread is still active.
* Signal thread to leave its :wait() state
*/
::Sig:signal()
ENDIF
IF ThreadObject() <> ::thread
/*
* The current thread is not the thread of ProgressBar (self).
* Therefore, the current thread must wait for the end of self:thread
*/
::thread:synchronize(0)
ENDIF
/*
* System resources are released when self:thread has terminated
*/
::thread := NIL // bingo this does release the thread!!!!
::xbpStatic:destroy()
RETURN self
/*
* Change the size of ProgressBar. Before the size is changed,
* everything is overpainted with the background color.
*/
METHOD ProgressBar:setSize( aProgSize )
LOCAL oPS, aAttr[ GRA_AA_COUNT ], _aProgSize
oPS := ::lockPS()
_aProgSize := ::currentSize()
_aProgSize[1] -= 2
_aProgSize[2] -= 2
aAttr [ GRA_AA_COLOR ] := GRA_CLR_BACKGROUND
GraSetAttrArea( oPS, aAttr )
GraBox( oPS, {1,1}, _aProgSize, GRA_FILL )
::unlockPS( oPS )
::xbpStatic:setSize( aProgSize )
RETURN self
/*
* ASSIGN method for :minimum
*/
METHOD ProgressBar:minimum( nMinimum )
IF ::maximum <> NIL .AND. nMinimum > ::maximum
::minimum := ::maximum
::maximum := nMinimum
ELSE
::minimum := nMinimum
ENDIF
::current := ::minimum
RETURN self
/*
* ASSIGN method for :current
*/
METHOD ProgressBar:current( nCurrent )
IF Valtype( nCurrent ) == "N"
::current := nCurrent
IF Valtype( ::maximum ) + Valtype( ::minimum ) == "NN"
::every := Int( ( ::maximum - ::minimum ) / ::squares )
::_current := ::current
ENDIF
ENDIF
RETURN ::current
/*
* ASSIGN method for :maximum
*/
METHOD ProgressBar:maximum( nMaximum )
IF ::minimum <> NIL .AND. nMaximum < ::minimum
::maximum := ::minimum
::minimum := nMaximum
ELSE
::maximum := nMaximum
ENDIF
::current := ::minimum
RETURN self
/*
* Increment the current value and refresh display if necessary
*/
METHOD ProgressBar:increment( nIncrement )
IF Valtype( nIncrement ) <> "N"
nIncrement := 1
ENDIF
/*
* While a progress is displayed, PROTECTED VAR :_current is incremented
* to avoid the overhead of the ASSIGN method :current()
*/
::_current += nIncrement
IF Int( ::_current % ::every ) == 0
/*
* This interrupts the ::wait( ::maxWait ) method in :execute().
* The progress bar is then refreshed immediately in its own thread.
* Since the display occurs in a separate thread, it does not
* slow down the actual process whose progress is visualized.
* Index creation, for example, does not update the display,
* but only signals self:thread
*/
::Sig:signal()
ENDIF
RETURN
/*
* Refresh progress bar automatically every ::maxWait / 100 seconds
* This method runs in self:thread and is automatically restarted
* due to :setInterval(0)
*/
METHOD ProgressBar:execute
::Sig:wait( ::maxWait )
::display()
RETURN self
/*
* Visualize the current state of a process
*/
METHOD ProgressBar:display
LOCAL oPS := ::lockPS()
LOCAL aProgSize := ::currentSize()
LOCAL aAttr [ GRA_AA_COUNT ]
aProgSize[1] -= 2
aProgSize[2] -= 2
IF aProgSize[1] > aProgSize[2]
::displayHoriz( oPS, aProgSize, aAttr )
ELSE
::displayVert ( oPS, aProgSize, aAttr )
ENDIF
IF !EMPTY(::Percent)
::Percent:SetCaption(STR(INT(100*::_current/(::maximum-::minimum)),3)+"%")
ENDIF
::unlockPS( oPS )
RETURN self
/*
* Display squares from left to right (horizontal display)
*/
METHOD ProgressBar:displayHoriz( oPS, aProgSize, aAttr )
LOCAL nX, aPos1, aPos2, nCenter
/*
* Max. x coordinate for squares
*/
nX := aProgSize[1] * ::_current / ( ::maximum - ::minimum )
nX := Min( nX, aProgSize[1] )
/*
* Fill the area to the right of the squares with background color
*/
aAttr [ GRA_AA_COLOR ] := GRA_CLR_BACKGROUND
GraSetAttrArea( oPS, aAttr )
GraBox( oPS, {1+nX,1}, {aProgSize[1],aProgSize[2]}, GRA_FILL )
/*
* Define fill color for squares
*/
aAttr [ GRA_AA_COLOR ] := ::color
GraSetAttrArea( oPS, aAttr )
/*
* Calculate position for leftmost square (starting position)
*/
aPos1 := { 2, 2 }
::squares := Int( aProgSize[1] / (aProgSize[2]+1) )
nCenter := 2 + ( aProgSize[1] - (::squares * (aProgSize[2]+1)) ) / 2
aPos1[1] := Max( 2, nCenter )
aPos2 := { aPos1[1]+aProgSize[2]-2 , aProgSize[2]-1 }
/*
* Draw the squares
*/
DO WHILE aPos2[1] < nX
GraBox( oPS, aPos1, aPos2, GRA_FILL )
aPos1[1] += aProgSize[2]+1
aPos2[1] += aProgSize[2]+1
ENDDO
IF aPos2[1] < aProgSize[1]
GraBox( oPS, aPos1, aPos2, GRA_FILL )
ENDIF
RETURN self
/*
* Display squares from bottom to top (vertical display)
*/
METHOD ProgressBar:displayVert( oPS, aProgSize, aAttr )
LOCAL nY, aPos1, aPos2, nCenter
/*
* Max. y coordinate for squares
*/
nY := aProgSize[2] * ::_current / ( ::maximum - ::minimum )
nY := Min( nY, aProgSize[2] )
/*
* Fill the area above the squares with background color
*/
aAttr [ GRA_AA_COLOR ] := GRA_CLR_BACKGROUND
GraSetAttrArea( oPS, aAttr )
GraBox( oPS, {1,nY}, {aProgSize[1],aProgSize[2]}, GRA_FILL )
/*
* Define fill color for squares
*/
aAttr [ GRA_AA_COLOR ] := ::color
GraSetAttrArea( oPS, aAttr )
/*
* Calculate position for lowest square (starting position)
*/
aPos1 := { 2, 2 }
::squares := Int( aProgSize[2] / (aProgSize[1]+1) )
nCenter := 2 + (aProgSize[2] - (::squares * (aProgSize[1]+1)) ) / 2
aPos1[2] := Max( 2, nCenter )
aPos2 := { aProgSize[1]-1, aPos1[2]+aProgSize[1]-2 }
/*
* Draw the squares
*/
DO WHILE aPos2[2] < nY
GraBox( oPS, aPos1, aPos2, GRA_FILL )
aPos1[2] += aProgSize[1]+1
aPos2[2] += aProgSize[1]+1
ENDDO
IF aPos2[2] < aProgSize[2]
GraBox( oPS, aPos1, aPos2, GRA_FILL )
ENDIF
RETURN self