Page 1 of 2

Multi colored ProgressBarGadget

Posted: Thu Nov 28, 2013 11:41 pm
by longwave
I am using a ProgressBarGadget to display the value of a variable. I want the color of the ProgressBar to be multi colored to identify three different states; good (green), caution (yellow) and danger (red). I know the SetGadgetColor() can be used but that changes the color of the whole Bar. For example say the Min. and Max. range of the ProgressBarGadget is 0 and 100 respectively. I will want the levels 0 to 70 to show as green, the section of the ProgressBar between >70 and <90 to show as yellow and values > 90 to show as red. How can this effect be achieved ?

Re: Multi colored ProgressBarGadget

Posted: Fri Nov 29, 2013 12:09 am
by Bisonte
Not with the normal Progressbar(). The look of it is OS-specific.

You have to make your own progressbar with a CanvasGadget() or ImageGadget()
to draw your own colors that way...

Re: Multi colored ProgressBarGadget

Posted: Fri Nov 29, 2013 1:53 am
by IdeasVacuum
Very Simple with a Canvas Gadget, you just draw filled boxes on it.

Code: Select all

Enumeration
#Win
#Progress
EndEnumeration

Procedure Progress(i.i)
;----------------------

        If StartDrawing(CanvasOutput(#Progress))

               DrawingMode(#PB_2DDrawing_Default)

                       If(i > 90)
                       
                             Box(i,0,2,50, RGB(255,000,000))

                       ElseIf(i > 70) And (i < 91)
                       
                             Box(i,0,2,50, RGB(255,255,000))
                       Else
                             Box(i,0,2,50, RGB(000,255,000))
                       EndIf
                       
               StopDrawing()
        EndIf

EndProcedure

Procedure Win()
;--------------

   If OpenWindow(#Win, 0, 0, 200, 200, "Progress", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)

          SetWindowColor(#Win, RGB(096,096,096))
                                    ;X  Y   W    H
            CanvasGadget(#Progress, 50, 75, 100, 50)
   EndIf

EndProcedure

;Run----------------------

Win()

Define iProgressCnt.i = 0

Repeat

       Progress(iProgressCnt)
       iProgressCnt + 2
       Delay(30) ;So we can see the bar updating

Until WaitWindowEvent(1) = #PB_Event_CloseWindow

End

Re: Multi colored ProgressBarGadget

Posted: Fri Nov 29, 2013 2:27 am
by netmaestro
Looks like fun, so here's my kick at the cat:

Code: Select all

Structure progressdata
  width.l
  height.l
  image.i
EndStructure

Procedure ProgressBar(gadgetnumber, x, y, width, height, flags=0)
  
  If gadgetnumber = #PB_Any
    result = ImageGadget(#PB_Any, x, y, width, height, 0, flags)
  Else
    ImageGadget(gadgetnumber, x, y, width, height, 0, flags)
    result = gadgetnumber
  EndIf
  
  *this.progressdata = AllocateMemory(SizeOf(progressdata))
  With *this
    \width  = width
    \height = height
    \image  = CreateImage(#PB_Any, width,height)
  EndWith
  
  green.f =  width*0.7
  yellow.f = width*0.2
  red.f    = width*0.1
  
  StartDrawing(ImageOutput(*this\image))
    Box(0,0, Int(green), height, #Green)
    Box(Int(green), 0, Int(yellow), height, #Yellow)
    Box(Int(green)+Int(yellow), 0, Int(red), height, #Red)
  StopDrawing()
  
  SetGadgetData(result, *this)
  DisableGadget(result, 1)
  
  ProcedureReturn result
  
EndProcedure

Procedure SetProgressState(gadget, state)
  *this.progressdata = GetGadgetData(gadget)
  thisstate.f = *this\width/100 * state
  thisimage = GrabImage(*this\image, #PB_Any, 0, 0, Int(thisstate), *this\height)
  If IsImage(thatimage):FreeImage(thatimage):EndIf
  thatimage = CreateImage(#PB_Any, *this\width, *this\height, 24, GetSysColor_(#COLOR_BTNFACE))
  If IsImage(thisimage)
    StartDrawing(ImageOutput(thatimage))
      DrawImage(ImageID(thisimage),0,0)
    StopDrawing()
    FreeImage(thisimage)
  EndIf
 
  SetGadgetState(gadget, ImageID(thatimage))
  
EndProcedure

Procedure FreeProgress(gadget)
  *this.progressdata = GetGadgetData(gadget)
  FreeImage(*this\image)
  FreeGadget(gadget)
EndProcedure

OpenWindow(0,0,0,640,480,"",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)

result = progressbar(0, 50,50,300,20, #PB_Image_Border)
SetProgressState(0, 0)

TrackBarGadget(1,50,100,300,20,0,100)

Repeat
  ev=WaitWindowEvent()
  If ev=#PB_Event_Gadget
    If EventGadget() = 1
      SetProgressState(0, GetGadgetState(1))
    EndIf
  EndIf
Until ev=#PB_Event_CloseWindow

FreeProgress(0)
I didn't address resizing the gadget, but you can probably manage that.

Re: Multi colored ProgressBarGadget

Posted: Fri Nov 29, 2013 2:48 am
by flaith
netmaestro wrote:Looks like fun, so here's my kick at the cat:
I didn't address resizing the gadget, but you can probably manage that.
Clever the way you handle the width Image

Re: Multi colored ProgressBarGadget

Posted: Fri Nov 29, 2013 3:16 am
by netmaestro
Thanks! This way of drawing the image might look better:

Code: Select all

  StartDrawing(ImageOutput(*this\image))
    DrawingMode(#PB_2DDrawing_Gradient)
    GradientColor(0.0, #Green)
    GradientColor(0.7, #Yellow)
    GradientColor(1.0, #Red)
    LinearGradient(0, 0, *this\width, *this\height)
    Box(0,0,*this\width, *this\height)
  StopDrawing()

Re: Multi colored ProgressBarGadget

Posted: Fri Nov 29, 2013 3:17 am
by BasicallyPure
Using a gradient.

Code: Select all

#Bar_W = 400
#Bar_H = 30
#Canvas = 1

Procedure DRAW_BAR()
   Static scale.f = #Bar_W / 100
   Static bias.i = 7
   Static amp.f = 50
   
   amp + Random(16) - bias
   
   If amp < 50
      amp = 50 : bias = 7
   ElseIf amp > 100
      amp = 100 : bias = 9
   EndIf
   
   StartDrawing(CanvasOutput(#Canvas))
      DrawingMode(#PB_2DDrawing_Gradient)
      BackColor($00FF00)
      GradientColor(0.66, $00FF80)
      GradientColor(0.95, $00FFFF)
      FrontColor($0000FF)
      
      LinearGradient(0, 0, #Bar_W, 0)
      Box(0, 0 ,amp * scale, #Bar_H)
      DrawingMode(#PB_2DDrawing_Default)
      Box(amp * scale, 0, #Bar_W, #Bar_H, 0)
   StopDrawing()
EndProcedure

If OpenWindow(0,0,0,#Bar_W+20,#Bar_H+20,"",#PB_Window_ScreenCentered | #PB_Window_SystemMenu)
   AddWindowTimer(0,0,100)
   CanvasGadget(#Canvas, 10, 10, #Bar_W + 4, #Bar_H + 4, #PB_Canvas_Border)
   
   Repeat
      Select WaitWindowEvent()
         Case #PB_Event_CloseWindow : Break
         Case #PB_Event_Timer : DRAW_BAR()
      EndSelect
   ForEver
EndIf
BP

edit: missed by 1 second! :)

Re: Multi colored ProgressBarGadget

Posted: Fri Nov 29, 2013 3:22 am
by flaith
Codes added to my CanvasGadget directory, thanks guys :D

Re: Multi colored ProgressBarGadget

Posted: Fri Nov 29, 2013 8:04 am
by davido
@BasicallyPure,

Another nice little demo.
Thank you for sharing. :D

Re: Multi colored ProgressBarGadget

Posted: Fri Nov 29, 2013 1:57 pm
by IdeasVacuum
I think we can say the cat was kicked, but no feedback from longwave?

Re: Multi colored ProgressBarGadget

Posted: Fri Nov 29, 2013 4:50 pm
by doctorized
In IdeasVacuum's code I would do the following change for better colors, a little....

Code: Select all

Procedure Progress(i.i)
;----------------------

        If StartDrawing(CanvasOutput(#Progress))

        		DrawingMode(#PB_2DDrawing_Default)
        		a.l=(i-70)*20
        		If a<0:a=0:EndIf
        		If a>255:a=255:EndIf
        		b.l=(i-90)*30
        		If b<0:b=0:EndIf
        		If b>255:b=255:EndIf
				  Box(i,0,2,50, RGB(000+a,255-b,000))
                       
        		StopDrawing()
        EndIf

EndProcedure

Re: Multi colored ProgressBarGadget

Posted: Fri Nov 29, 2013 4:53 pm
by IdeasVacuum
8) Very nice

Re: Multi colored ProgressBarGadget

Posted: Fri May 03, 2024 11:44 pm
by dibor
Gradient bar looks GOOD.
Any example with vertical progress bar please.

Re: Multi colored ProgressBarGadget

Posted: Sat May 04, 2024 1:37 am
by normeus
Talk about a dead cat bounce, just switch around the x,y for the boxes.
IdeasVacuum's code , doctorized by doctorized :lol: :

Code: Select all

Enumeration
#Win
#Progress
EndEnumeration

Procedure Progress(i.i)
;----------------------

        If StartDrawing(CanvasOutput(#Progress))

        		DrawingMode(#PB_2DDrawing_Default)
        		a.l=(i-70)*20
        		If a<0:a=0:EndIf
        		If a>255:a=255:EndIf
        		b.l=(i-90)*30
        		If b<0:b=0:EndIf
        		If b>255:b=255:EndIf
				  Box(0,100-i,50,2, RGB(000+a,255-b,000)) ;<----- switch
                       
        		StopDrawing()
        EndIf

EndProcedure

Procedure Win()
;--------------

   If OpenWindow(#Win, 0, 0, 200, 200, "Progress", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)

          SetWindowColor(#Win, RGB(096,096,096))
                                    ;X  Y   W    H
            CanvasGadget(#Progress, 50, 75, 50, 100) ;<----- switch
   EndIf

EndProcedure

;Run----------------------

Win()

Define iProgressCnt.i = 0

Repeat

       Progress(iProgressCnt)
       iProgressCnt + 2
       Delay(30) ;So we can see the bar updating

Until WaitWindowEvent(1) = #PB_Event_CloseWindow

End

[EDIT] @Dilbor's idea of going from bottom to top looks good

Norm.

Re: Multi colored ProgressBarGadget

Posted: Sat May 04, 2024 6:42 pm
by dibor
@Norm
This trick I did, but bar fill from top to bottom, I interested in other direction, from bottom to top.
Example with Gradient, by BasicallyPure, is much better looks for me.
Anybody can adopt it for vertical ProgressBar?

Thank U