Progress2 - class for an easy progress bar - 2020/08/07 - a121

Share the finished AutoHotkey v2 Scripts and libraries you made here. Please put the current version of AutoHotkey v2 you used in Square Brackets at the start of the topic title.
User avatar
TheArkive
Posts: 330
Joined: 05 Aug 2016, 08:06
GitHub: TheArkive

Progress2 - class for an easy progress bar - 2020/08/07 - a121

Post by TheArkive » 19 May 2020, 14:50

I noticed that AHK2 didn't have any kind of Progress command, so I tried to just make one. This class is pretty straight forward. Feel free to post feedback, bugs, etc.

Example is included at the top, just uncomment it.

I just put in the basics, but I plan to expand this a bit.

=====================================================================================
Updates
=====================================================================================

Code: Select all

; ahk v2
; ============================================================================================
; Progress bar window contains a MainText element (above the progress bar), a SubText element
; (below the progress bar), the progress bar itself, and an optional title bar.
;
; Here are the defaults:
;	Font                  = Verdana
;	Font Size (subText)   = 8
;	Font Size (mainText)  = subTextSize + 2
;   Main/SubText value    = blank unless specified
;	display coords        = primary monitor
;	default range         = 0-100
;
; ============================================================================================
; Create Progress Bar
;	obj := progress2.New(rangeStart := 0, rangeEnd := 100, sOptions := "")
;		> specify start and end range
;		> specify options to initialize certain values on creation (optional)
;
; Methods:
;	obj.Update(value := "", mainText := "", subText := "")
;		> value = numeric within the specified range
;		> mainText / subText: update the text above / below the progress bar
;		> if you want to clear the mainText or subText pass a space, ie. " "
;		> to leave mainText / SubText unchanged, pass a zero-length string, ie. ""
;
;	obj.Close()
;		> closes the progress bar
;
; ============================================================================================
; Options on create.  Comma separated string including zero or more of the below options.
; MainText / SubText are the text above / below the progress bar.
;
;	fontFace:font_str
;		> set the font for MainText / SubText
;
;	fontSize:###
;		> set font size for MainText / SubText (MainText is 2 pts larger than SubText)
;
;	mainText:text_str
;		> creates the Progress Bar with specified mainText (above the progress bar)
;
;	mainTextAlign:left/right/center
;		> specifies alignment of mainText element.
;
;	mainTextSize:#
;		> sets custom size for mainText element.
;
;	modal:Hwnd
;		> same as parent, but also disables the parent window while progressbar is active
;
;	parent:Hwnd
;		> defines the parent GUI window, and prevents a taskbar icon from appearing
;
;	start:#
;		> defines the starting numeric withing the specified range on creation
;
;	subText:text_str
;		> creates the Pogress Bar with specified subText (below the progress bar)
;
;	subTextAlign:left/right/center
;		> specifies alignment of subText element.
;
;	title:title_str
;		> Defines a title and ensures there is a title bar.  This allows normal moving of the
;		  progress bar by click-dragging the title bar.  No title hides the title bar and
;		  prevents the window from being moved by the mouse (by normal means).
;
;	w:###
;		> sets a specific pixel width for the progress bar
;
;	x:###  And  y:###  (specify both and separate by comma in options string)
;		> sets custom x/y coords to display the progress bar window.  Specify both or none.
;
; ============================================================================================
; Example
; ============================================================================================
; Global prog, g
; prog := ""

; g := Gui.New()
; g.OnEvent("close","close_gui")
; g.Add("Text","w600 h300","Test GUI")
; g.Add("Button",,"Test Progress - click 2 times slowly").OnEvent("click","click_btn")
; g.show("x200 y200")

; click_btn(p*) {
	; If (!IsObject(prog)) {
		; options := "mainText:Test Main Text pqg,subText:Test Sub Text pqg,title:test title,"
		; options .= "start:25,parent:" g.hwnd
		; prog := progress2.New(0,100,options)
	; } Else {
		; prog.Update(50," ","Test 3")
		; Sleep 2000
		; prog.Close()
	; }
; }

; close_gui(g) {
	; ExitApp
; }
; ============================================================================================
; End Example
; ============================================================================================

class progress2 {
	__New(rangeStart := 0, rangeEnd := 100, sOptions := "") {
		; ====================================================
		; default options
		; ====================================================
		this.rangeStart := rangeStart, this.rangeEnd := rangeEnd
		
		this.fontFace := "Verdana", this.fontSize := 8
		this.mainTextSize := this.fontSize + 2
		this.mainTextAlign := "left", this.subTextAlign := "left"
		
		this.mainText := " ", this.subText := " ", this.title := ""
		
		this.start := 0
		this.modal := false, this.hParent := 0
		
		this.width := 300
		this.x := "", this.y := ""
		
		this.mainTextHwnd := 0, this.subTextHwnd := 0
		
		; ====================================================
		; read user defined options
		; ====================================================
		optArr := StrSplit(sOptions,Chr(44))
		Loop optArr.Length {
			valArr := StrSplit(optArr[A_Index],":")
			curOpt := valArr.Has(1) ? valArr[1] : ""
            curVal := valArr.Has(2) ? valArr[2] : ""
			If (!curOpt)
                Continue
            
			If (curOpt = "fontFace")
				this.fontFace := curVal ? curVal : this.fontFace
			Else If (curOpt = "fontSize")
				this.fontSize := curVal ? curVal : this.fontSize
			Else If (curOpt = "mainText")
				this.mainText := curVal
			Else If (curOpt = "subText")
				this.subText := curVal
			Else If (curOpt = "start")
				this.start := curVal ? curVal : this.start
			Else if (curOpt = "title")
				this.title := curVal
			Else If (curOpt = "parent")
				this.hParent := curVal ? curVal : 0
			Else If (curOpt = "modal")
				this.hParent := curVal ? curVal : 0, this.modal := curVal ? true : false
			Else if (curOpt = "w")
				this.width := curVal ? curVal : 300
			Else If (curOpt = "mainTextSize")
				this.mainTextSize := curVal ? curVal : this.mainTextSize
			Else If (curOpt = "mainTextAlign")
				this.mainTextAlign := curVal ? curVal : this.mainTextAlign
			Else if (curOpt = "subTextAlign")
				this.subTextAlign := curVal ? curVal : this.subTextAlign
			Else If (curOpt = "x")
				this.x := curVal ? curVal : ""
			Else If (curOpt = "y")
				this.y := curVal ? curVal : ""
		}
		
		this.ShowProgress()
	}
	ShowProgress() {
        x := "", y := ""
		showTitle := this.title ? "" : " -Caption +0x40000" ; 0x40000 = thick border
		range := this.rangeStart "-" this.rangeEnd
		progress2_gui := Gui.New("AlwaysOnTop -DPIScale -SysMenu" showTitle,this.title)
		
		progress2_gui.SetFont("s" this.mainTextSize,this.fontFace)
		align := this.mainTextAlign
		mT := progress2_gui.AddText("vMainText " align " w" this.width,this.mainText)
		this.mainTextHwnd := mT.hwnd
		
        progress2_gui.SetFont("s" this.fontSize)
		prog := progress2_gui.AddProgress("vProgBar y+m xp w" this.width " Range" range,this.start)
		this.progHwnd := prog.hwnd
		
		align := this.subTextAlign
		sT := progress2_gui.AddText("vSubText " align " w" this.width,this.subText)
		this.subTextHwnd := sT.hwnd
		
		If (this.hParent) {
			WinGetPos pX, pY, pW, pH, "ahk_id " this.hParent
			Cx := pX + (pW/2), Cy := pY + (pH/2)
			
			borderW := SysGet(32)
			captionH := SysGet(4)
			captionH := this.title ? captionH : 0
			borderH := SysGet(7)
			
			prog.GetPos(,,progW:=0,h:=0)
			mT.GetPos(,,mTh:=0)
			sT.GetPos(,,sTh:=0)
			progress2_gui.GetPos(,,gH:=0)
			w := progW + (progress2_gui.MarginX * 2) + (borderW * 2)
			h := gH + captionH + (borderH * 2) + mTh + sTh + (progress2_gui.MarginY * 4)
			x := Cx - (w/2), y := Cy - (h/2)
			progress2_gui.Opt("+Owner" this.hParent)
			
			If (this.modal)
				WinSetEnabled 0, "ahk_id " this.hParent
		}
		If (this.x != "" And this.y != "")
			x := this.x, y := this.y
		
		coords := ""
		If (x And y)
			coords := "x" x " y" y
		
		progress2_gui.Show(coords " NA NoActivate")
		this.guiHwnd := progress2_gui.hwnd
		this.gui := progress2_gui
	}
	Update(value := "", mainText := "", subText := "") {
		If (value != "")
			this.gui["ProgBar"].Value := value
		If (this.mainTextHwnd And mainText)
			this.gui["MainText"].Text := mainText
		If (this.subTextHwnd And subText)
			this.gui["SubText"].Text := subText
	}
	Close() {
		If (IsObject(this.gui))
			this.gui.Destroy()
		
		If (this.modal)
			WinSetEnabled 0, "ahk_id " this.hParent
		If (this.hParent)
			WinActivate "ahk_id " this.hParent
		
		this.__Delete()
	}
	__Delete() {
		this.gui := ""
		this := ""
	}
}

Return to “AutoHotkey v2 Scripts and Functions”