Multi colored ProgressBarGadget

Just starting out? Need help? Post your questions and find answers here.
longwave
New User
New User
Posts: 8
Joined: Thu Nov 28, 2013 9:36 pm

Multi colored ProgressBarGadget

Post 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 ?
User avatar
Bisonte
Addict
Addict
Posts: 1313
Joined: Tue Oct 09, 2007 2:15 am

Re: Multi colored ProgressBarGadget

Post 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...
PureBasic 6.21 (Windows x64) | Windows 11 Pro | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
English is not my native language... (I often use DeepL.)
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Multi colored ProgressBarGadget

Post 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
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: Multi colored ProgressBarGadget

Post 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.
BERESHEIT
User avatar
flaith
Enthusiast
Enthusiast
Posts: 704
Joined: Mon Apr 25, 2005 9:28 pm
Location: $300:20 58 FC 60 - Rennes
Contact:

Re: Multi colored ProgressBarGadget

Post 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
“Fear is a reaction. Courage is a decision.” - WC
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: Multi colored ProgressBarGadget

Post 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()
BERESHEIT
User avatar
BasicallyPure
Enthusiast
Enthusiast
Posts: 539
Joined: Thu Mar 24, 2011 12:40 am
Location: Iowa, USA

Re: Multi colored ProgressBarGadget

Post 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! :)
Last edited by BasicallyPure on Fri Nov 29, 2013 3:38 am, edited 1 time in total.
BasicallyPure
Until you know everything you know nothing, all you have is what you believe.
User avatar
flaith
Enthusiast
Enthusiast
Posts: 704
Joined: Mon Apr 25, 2005 9:28 pm
Location: $300:20 58 FC 60 - Rennes
Contact:

Re: Multi colored ProgressBarGadget

Post by flaith »

Codes added to my CanvasGadget directory, thanks guys :D
“Fear is a reaction. Courage is a decision.” - WC
davido
Addict
Addict
Posts: 1890
Joined: Fri Nov 09, 2012 11:04 pm
Location: Uttoxeter, UK

Re: Multi colored ProgressBarGadget

Post by davido »

@BasicallyPure,

Another nice little demo.
Thank you for sharing. :D
DE AA EB
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Multi colored ProgressBarGadget

Post by IdeasVacuum »

I think we can say the cat was kicked, but no feedback from longwave?
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
doctorized
Addict
Addict
Posts: 882
Joined: Fri Mar 27, 2009 9:41 am
Location: Athens, Greece

Re: Multi colored ProgressBarGadget

Post 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
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Multi colored ProgressBarGadget

Post by IdeasVacuum »

8) Very nice
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
dibor
Enthusiast
Enthusiast
Posts: 160
Joined: Wed May 20, 2020 5:19 pm
Location: The 3rd planet in the Solar System
Contact:

Re: Multi colored ProgressBarGadget

Post by dibor »

Gradient bar looks GOOD.
Any example with vertical progress bar please.
Mac Studio M1Max, PB 6.12 Arm64 and x64.
Macbook Air M2, PB 6.12 Arm64 and x64.
Windows 10, PB 6.12 x64 and x86.
normeus
Enthusiast
Enthusiast
Posts: 472
Joined: Fri Apr 20, 2012 8:09 pm
Contact:

Re: Multi colored ProgressBarGadget

Post 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.
Last edited by normeus on Sat May 04, 2024 10:00 pm, edited 1 time in total.
google Translate;Makes my jokes fall flat- Fait mes blagues tombent à plat- Machte meine Witze verpuffen- Eh cumpari ci vo sunari
dibor
Enthusiast
Enthusiast
Posts: 160
Joined: Wed May 20, 2020 5:19 pm
Location: The 3rd planet in the Solar System
Contact:

Re: Multi colored ProgressBarGadget

Post 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
Mac Studio M1Max, PB 6.12 Arm64 and x64.
Macbook Air M2, PB 6.12 Arm64 and x64.
Windows 10, PB 6.12 x64 and x86.
Post Reply