Eigenes ProgressBarGadget

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
dussel
Beiträge: 49
Registriert: 15.09.2004 12:52
Wohnort: Bei Frankfurt/Main

Eigenes ProgressBarGadget

Beitrag von dussel »

Hallo zusammen,

angeregt durch einen Thread im englischen Forum ()http://www.purebasic.fr/english/viewtop ... highlight=) habe ich mir ein eigenes ProgressBarGadget programmiert.

Features:
- Skinnable (die Grafiken lassen sich anpassen)
- Threadsafe
- EnableExplicit
- Funktionsnamen an PB ProgressBarGadget angelehnt
- Geschwindigkeitsoptimiert (lässt sich sicherlich noch verbessern)
- Keine OS spezifischen Funktionen
- Einbinden per simplen XincludeFile

Anmerkungen:
- Linux sollte gehen; jedoch nicht getestet
- Geschwindigkeit unter Windows akzeptabel; bei mir etwa 10x langsamer als Windows XP Skinned ProgressBarGadget


Bild



If you like it -> use it ;-)


Download: http://scuttle.absolut-marc.de/progressbar.zip

Code: Alles auswählen

;
;
;   Progressbar
;

EnableExplicit

Enumeration
  #mod_progressbar_enum_prgbr_done_left
  #mod_progressbar_enum_prgbr_done_element
  #mod_progressbar_enum_prgbr_done_current
  #mod_progressbar_enum_prgbr_open_element
  #mod_progressbar_enum_prgbr_open_right
EndEnumeration

Structure progressbar
  	Image.l         ; Image
		ImageID.l       ; ImageID
		Gadgetid.l      ; GadgetID
		Width.l
		Height.l
		min.l 
		max.l
		value.l
EndStructure

Structure prgbr_ressources
    type.l
    image.l
    imageid.l
    width.l
EndStructure    

NewList mod_progressbar.progressbar()
NewList mod_prgbr_ressources.prgbr_ressources()

CompilerIf #PB_Compiler_Thread = 1
  ; Support for thread safe
  Define mod_progressbar_mutex.l
  Define mod_prgbr_ressources_mutex.l
  mod_progressbar_mutex       = CreateMutex()
  mod_prgbr_ressources_mutex  = CreateMutex()
CompilerEndIf

Define mod_progressbar_minsize.l                          ; Min possible calculated Size for Progressbar

Define mod_progressbar_image4speed_zeropercent_image.l    ; Optimized4Speed: A   0% Progressbar w = Screenwidth
Define mod_progressbar_image4speed_hundredpercent_image.l ; Optimized4Speed: A 100% Progressbar w = Screenwidth

CompilerIf #PB_Compiler_Thread = 1
  ; Support for thread safe
  Define mod_progressbar_image4speed_mutex.l
  mod_progressbar_image4speed_mutex = CreateMutex()
CompilerEndIf  





Procedure mod_progressbar_internal_prepare4speed()

    ; Prepare for optimization

    Shared mod_progressbar_image4speed_zeropercent_image
    Shared mod_progressbar_image4speed_hundredpercent_image

    Shared mod_prgbr_ressources.prgbr_ressources()
    
    CompilerIf #PB_Compiler_Thread = 1
      Shared mod_prgbr_ressources_mutex.l
      Shared mod_progressbar_image4speed_mutex.l
    CompilerEndIf
    
    Define i_width.l
    Define i_width2.l
    Define i_counter.l
  
    CompilerIf #PB_Compiler_Thread = 1  
      ; Lock Mutex within thread safe environment
      LockMutex(mod_prgbr_ressources_mutex)
      LockMutex(mod_progressbar_image4speed_mutex)
    CompilerEndIf
    
    ExamineDesktops()
    i_width = DesktopWidth(0)
    
    SelectElement(mod_prgbr_ressources(),#mod_progressbar_enum_prgbr_done_left)
    mod_progressbar_image4speed_zeropercent_image     = CreateImage(#PB_Any,i_width,ImageHeight(mod_prgbr_ressources()\image))
    mod_progressbar_image4speed_hundredpercent_image  = CreateImage(#PB_Any,i_width,ImageHeight(mod_prgbr_ressources()\image))  
    
    ; Create 100% Image
    StartDrawing(ImageOutput(mod_progressbar_image4speed_hundredpercent_image))
      ; Done Left
      SelectElement(mod_prgbr_ressources(),#mod_progressbar_enum_prgbr_done_left)
      DrawImage(mod_prgbr_ressources()\imageid,0,0)
      ; Done Element
      i_counter = ImageWidth(mod_prgbr_ressources()\image)
      SelectElement(mod_prgbr_ressources(),#mod_progressbar_enum_prgbr_done_element)
      i_width2  = ImageWidth(mod_prgbr_ressources()\image)
      While i_counter < i_width-1
        DrawImage(mod_prgbr_ressources()\imageid,i_counter,0)
        i_counter + i_width2
      Wend
      ; Open Right
      SelectElement(mod_prgbr_ressources(),#mod_progressbar_enum_prgbr_open_right)
      i_width2 = ImageWidth(mod_prgbr_ressources()\image)
      DrawImage(mod_prgbr_ressources()\imageid,i_width - i_width2,0)
    StopDrawing()
    
    ; Create 0% Image
    StartDrawing(ImageOutput(mod_progressbar_image4speed_zeropercent_image))
      ; Done Left
      SelectElement(mod_prgbr_ressources(),#mod_progressbar_enum_prgbr_done_left)
      DrawImage(mod_prgbr_ressources()\imageid,0,0)
      ; Done Element
      i_counter = 1
      SelectElement(mod_prgbr_ressources(),#mod_progressbar_enum_prgbr_open_element)
      i_width2  = ImageWidth(mod_prgbr_ressources()\image)
      While i_counter < i_width-1
        DrawImage(mod_prgbr_ressources()\imageid,i_counter,0)
        i_counter + i_width2
      Wend
      ; Open Right
      SelectElement(mod_prgbr_ressources(),#mod_progressbar_enum_prgbr_open_right)
      i_width2 = ImageWidth(mod_prgbr_ressources()\image)
      DrawImage(mod_prgbr_ressources()\imageid,i_width - i_width2,0)
    StopDrawing()   
    

    CompilerIf #PB_Compiler_Thread = 1  
      ; Lock Mutex within thread safe environment
      UnlockMutex(mod_progressbar_image4speed_mutex)
      UnlockMutex(mod_prgbr_ressources_mutex)
    CompilerEndIf

EndProcedure

Procedure mod_progressbar_FreeGadget(gadgetid.l)

  Shared mod_progressbar.progressbar()
  
  CompilerIf #PB_Compiler_Thread = 1
    Shared mod_progressbar_mutex.l
  CompilerEndIf
  
  CompilerIf #PB_Compiler_Thread = 1  
    ; Lock Mutex within thread safe environment
    LockMutex(mod_progressbar_mutex)
  CompilerEndIf
  
    ResetList(mod_progressbar())
    ForEach mod_progressbar()
      If mod_progressbar()\gadgetid = gadgetid
          FreeImage(mod_progressbar()\Image)
          FreeGadget(mod_progressbar()\GadgetID)
          DeleteElement(mod_progressbar())
        Break
      EndIf
    Next

  CompilerIf #PB_Compiler_Thread = 1  
    ; Lock Mutex within thread safe environment
    UnlockMutex(mod_progressbar_mutex)
  CompilerEndIf
  
EndProcedure

Procedure mod_progressbar_init()

  ; INIT (or use your own init)

  Shared mod_prgbr_ressources.prgbr_ressources()
  Shared mod_progressbar_minsize.l
    
  CompilerIf #PB_Compiler_Thread = 1
    Shared mod_prgbr_ressources_mutex.l
  CompilerEndIf

  UseJPEGImageDecoder()

  CompilerIf #PB_Compiler_Thread = 1  
    ; Lock Mutex within thread safe environment
    LockMutex(mod_prgbr_ressources_mutex)
  CompilerEndIf
  
    AddElement(mod_prgbr_ressources())
      mod_prgbr_ressources()\type   = #mod_progressbar_enum_prgbr_done_left
      mod_prgbr_ressources()\image  = LoadImage(#PB_Any,"images\prgrb_done_left.jpg")
      mod_prgbr_ressources()\imageid= ImageID(mod_prgbr_ressources()\image)
      mod_prgbr_ressources()\width  = ImageWidth(mod_prgbr_ressources()\image)
      mod_progressbar_minsize + mod_prgbr_ressources()\width

    AddElement(mod_prgbr_ressources())
      mod_prgbr_ressources()\type   = #mod_progressbar_enum_prgbr_done_element
      mod_prgbr_ressources()\image  = LoadImage(#PB_Any,"images\prgrb_done_element.jpg")
      mod_prgbr_ressources()\imageid= ImageID(mod_prgbr_ressources()\image)
      mod_prgbr_ressources()\width  = ImageWidth(mod_prgbr_ressources()\image)
      mod_progressbar_minsize + mod_prgbr_ressources()\width

    AddElement(mod_prgbr_ressources())
      mod_prgbr_ressources()\type   = #mod_progressbar_enum_prgbr_done_current
      mod_prgbr_ressources()\image  = LoadImage(#PB_Any,"images\prgrb_done_current.jpg")
      mod_prgbr_ressources()\imageid= ImageID(mod_prgbr_ressources()\image)
      mod_prgbr_ressources()\width  = ImageWidth(mod_prgbr_ressources()\image)
      mod_progressbar_minsize + mod_prgbr_ressources()\width

    AddElement(mod_prgbr_ressources())
      mod_prgbr_ressources()\type   = #mod_progressbar_enum_prgbr_open_element
      mod_prgbr_ressources()\image  = LoadImage(#PB_Any,"images\prgrb_open_element.jpg")
      mod_prgbr_ressources()\imageid= ImageID(mod_prgbr_ressources()\image)
      mod_prgbr_ressources()\width  = ImageWidth(mod_prgbr_ressources()\image)
      mod_progressbar_minsize + mod_prgbr_ressources()\width

    AddElement(mod_prgbr_ressources())
      mod_prgbr_ressources()\type   = #mod_progressbar_enum_prgbr_open_right
      mod_prgbr_ressources()\image  = LoadImage(#PB_Any,"images\prgrb_open_right.jpg")
      mod_prgbr_ressources()\imageid= ImageID(mod_prgbr_ressources()\image)
      mod_prgbr_ressources()\width  = ImageWidth(mod_prgbr_ressources()\image)
      mod_progressbar_minsize + mod_prgbr_ressources()\width

  CompilerIf #PB_Compiler_Thread = 1  
    ; Lock Mutex within thread safe environment
    UnlockMutex(mod_prgbr_ressources_mutex)
  CompilerEndIf
  
  ; AFTER INIT YOU HAVE TO CALL mod_progressbar_internal_prepare4speed() !
  mod_progressbar_internal_prepare4speed()
  
EndProcedure

Procedure mod_progressbar_GetGadgetState(gadgetid.l)

  Shared mod_progressbar.progressbar()
  
  CompilerIf #PB_Compiler_Thread = 1
    Shared mod_progressbar_mutex.l
  CompilerEndIf
  
  Define retval.l
  
  CompilerIf #PB_Compiler_Thread = 1  
    ; Lock Mutex within thread safe environment
    LockMutex(mod_progressbar_mutex)
  CompilerEndIf
  
    ResetList(mod_progressbar())
    ForEach mod_progressbar()
      If mod_progressbar()\gadgetid = gadgetid
        retval = mod_progressbar()\value
        Break
      EndIf
    Next

  CompilerIf #PB_Compiler_Thread = 1  
    ; Lock Mutex within thread safe environment
    UnlockMutex(mod_progressbar_mutex)
  CompilerEndIf
  
  ProcedureReturn retval
  
EndProcedure

Procedure mod_progressbar_SetGadgetState(gadgetid.l,value.l)
  ;
  ;
  ;
  Shared mod_progressbar.progressbar()
  Shared mod_prgbr_ressources.prgbr_ressources()
  
  Shared mod_progressbar_image4speed_hundredpercent_image
  Shared mod_progressbar_image4speed_zeropercent_image
  
  CompilerIf #PB_Compiler_Thread = 1
    Shared mod_progressbar_mutex.l
    Shared mod_prgbr_ressources_mutex.l
    Shared mod_progressbar_image4speed_mutex.l
  CompilerEndIf
  
  Define i_tmp_image.l          ; procedure internal image
  Define i_tmp_image_x.l        ;
  Define i_tmp_image_w.l
  Define i_tmp_image_h.l
  Define i_pixel.f
  

  CompilerIf #PB_Compiler_Thread = 1  
    ; Lock Mutex within thread safe environment
    LockMutex(mod_progressbar_mutex)
    LockMutex(mod_prgbr_ressources_mutex)
    LockMutex(mod_progressbar_image4speed_mutex)
  CompilerEndIf
  
    ResetList(mod_progressbar())
    ForEach mod_progressbar()
      If mod_progressbar()\gadgetid = gadgetid
        Break
      EndIf
    Next
    
    ; Calc
    
    If value < 0
      value = 0
    EndIf
    
    i_pixel = (mod_progressbar()\width-2)/(mod_progressbar()\max - mod_progressbar()\min) * (value - mod_progressbar()\min) +1
    If i_pixel > mod_progressbar()\width
      i_pixel = mod_progressbar()\width
    EndIf
    
    ; Draw
    
    StartDrawing(ImageOutput(mod_progressbar()\image))
      
      ; Draw DONE Part
      ;SelectElement(mod_prgbr_ressources(),#mod_progressbar_enum_prgbr_done_left)

      i_tmp_image_x = 0
      i_tmp_image_w = i_pixel
      i_tmp_image_h = ImageHeight(mod_progressbar()\image)
      i_tmp_image = GrabImage(mod_progressbar_image4speed_hundredpercent_image,#PB_Any,0,0,i_tmp_image_w,i_tmp_image_h)
      
      DrawImage(ImageID(i_tmp_image),0,0)
      FreeImage(i_tmp_image)
      
      ; Draw OPEN Part

      i_tmp_image_x = ImageWidth(mod_progressbar_image4speed_zeropercent_image)-(mod_progressbar()\width - i_pixel)
      i_tmp_image_w = mod_progressbar()\width - i_pixel
      If i_tmp_image_w > 0
        i_tmp_image = GrabImage(mod_progressbar_image4speed_zeropercent_image,#PB_Any,i_tmp_image_x,0,i_tmp_image_w,i_tmp_image_h)
        DrawImage(ImageID(i_tmp_image),i_pixel,0)
        FreeImage(i_tmp_image)
      EndIf

    StopDrawing()
    
    mod_progressbar()\value = value
    
    SetGadgetState(mod_progressbar()\gadgetid,mod_progressbar()\imageid)
  
  CompilerIf #PB_Compiler_Thread = 1  
    ; UnLock Mutex within thread safe environment
    UnlockMutex(mod_progressbar_image4speed_mutex)
    UnlockMutex(mod_prgbr_ressources_mutex)
    UnlockMutex(mod_progressbar_mutex)
  CompilerEndIf


EndProcedure

Procedure.l mod_progressbar_ProgressbarGadget(gadgetid.l, x.l, y.l, width.l, height.l, min.l, max.l) 
  ;
  ; 
  ;
  
  Shared mod_progressbar.progressbar()
  Shared mod_progressbar_minsize.l
  
  CompilerIf #PB_Compiler_Thread = 1
    Shared mod_progressbar_mutex.l
  CompilerEndIf
  
  Define image.l
  Define gadgetretvalue.l
  
  ; Value Check
  If width < mod_progressbar_minsize
    CompilerIf #PB_Compiler_Debugger = 1
      Debug "Warning: Invalid value for ProgressbarGadget. width < mod_progressbar_minsize !"
    CompilerElse
    width = mod_progressbar_minsize
    CompilerEndIf
  EndIf
  
  If min > max
    CompilerIf #PB_Compiler_Debugger = 1
      Debug "Warning: Invalid value for ProgressbarGadget. min > max !"
    CompilerElse
      min = max
    CompilerEndIf
  EndIf
  
  ; Create Gadget
  gadgetretvalue = ImageGadget(gadgetid,x,y,width,height,0)
  If gadgetretvalue = 0
    ProcedureReturn 0
  EndIf
  If gadgetid = #PB_Any
    gadgetid = gadgetretvalue
  EndIf
  
  ; Create Image
  image = CreateImage(#PB_Any,width,height)
  
  CompilerIf #PB_Compiler_Thread = 1  
    ; Lock Mutex within thread safe environment
    LockMutex(mod_progressbar_mutex)
  CompilerEndIf
  
      AddElement(mod_progressbar())
        mod_progressbar()\Image   = image
        mod_progressbar()\ImageID = ImageID(image)
        mod_progressbar()\Gadgetid= gadgetid
        mod_progressbar()\Width   = width
        mod_progressbar()\Height  = height
        mod_progressbar()\min     = min
        mod_progressbar()\max     = max
    
  CompilerIf #PB_Compiler_Thread = 1  
    ; Unlock Mutex within thread safe environment
    UnlockMutex(mod_progressbar_mutex)
  CompilerEndIf
  
  ; Paint Gadget
  mod_progressbar_SetGadgetState(gadgetid.l,min)
  
  ProcedureReturn gadgetid
  
EndProcedure
Zuletzt geändert von dussel am 07.03.2008 13:44, insgesamt 1-mal geändert.
Bild|Bild
Bild|Bild|Bild
Benutzeravatar
Kiffi
Beiträge: 10711
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: Eigenes ProgressBarGadget

Beitrag von Kiffi »

dussel hat geschrieben:angeregt durch einen Thread im englischen Forum [...] habe ich mir ein
eigenes ProgressBarGadget programmiert.
schick! :allright:

darf ich Dich weiter anregen? ;-)

http://www.codeproject.com/KB/vb/sql200 ... gress.aspx

http://www.codeproject.com/KB/cpp/mrg_l ... ircle.aspx

http://www.codeproject.com/KB/cpp/XpProgressBar.aspx

Grüße ... Kiffi
a²+b²=mc²
Antworten