Someone updated my library.

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
x32
Posts: 177
Joined: 25 Nov 2016, 16:44

Someone updated my library.

Post by x32 » 03 Feb 2023, 09:01

I have a lib file I use to make rotary knobs in guis, it can be found here. This morning I was Googling to see if there was a way to change the knob's color and I ran across this GitHub page by Ixiko with my library but it has been updated and is now called class_Rotary_Knob.ahk. I'm excited to see it has been updated, and most likely improved on, but I have no idea how to use it now that it's a class instead of a normal library function. Is this an AHK2 thing? or where can I learn how it works? Thanks
Image

Updated lib:

Code: Select all

; Link:   	https://www.autohotkey.com/boards/viewtopic.php?f=6&t=77311
; Author:
; Date:
; for:     	AHK_L

; Original concept by ahklerner
; https://autohotkey.com/board/topic/64700-rotary-knob-for-a-gui/#entry408451
; Edited to be used as a library function by x32
; https://www.autohotkey.com/boards/viewtopic.php?f=6&t=77311

class RotaryKnob {

	__New(hControl,size,angle) {
		this.size := size
		this.angle := angle
		this.knobSize := size * 1.05
		this.indicatorSize := size / 9
		this.radius := this.knobSize / 3
		this.hdc := DllCall("GetDC", "uint", hControl)
		this.x := 0
		this.y := 0
		this.Draw(this.angle)
	}

	Draw(angle) {
		this.angle := (angle > 360 ? 360 : angle < 0 ? 0 : angle)
		this.UpdatePosition()

		DllCall("Ellipse", "uint", this.hDc, "int", 1, "int", 1, "int", this.knobsize, "int", this.knobsize)
		DllCall("Ellipse", "uint", this.hDc, "int", 3, "int", 3, "int", this.knobsize-2, "int", this.knobsize-2)
		DllCall("Ellipse", "uint", this.hDc, "int", this.x, "int", this.y, "int", this.x + this.indicatorsize, "int", this.y + this.indicatorsize)
	}

	UpdatePosition() {
		this.x := ((this.knobsize/2)-3) - sin(this.angle*4*ATan(1)/180)*this.radius
		this.y := ((this.knobsize/2)-3) + cos(this.angle*4*ATan(1)/180)*this.radius
	}

	UpdateSize(size) {
		this.knobSize := size * 1.05
		this.indicatorSize := size / 9
	}
}

User avatar
boiler
Posts: 16768
Joined: 21 Dec 2014, 02:44

Re: Someone updated my library.

Post by boiler » 03 Feb 2023, 09:24

x32 wrote: …I have no idea how to use it now that it's a class instead of a normal library function. Is this an AHK2 thing? or where can I learn how it works?
Classes have been part of AHK v1.1 since its beginning, and that class is written in/for v1.1. Note where it says it’s for AHK_L, which is the original name and current nickname for v1.1 since it was created by Lexikos.

See the documentation page on Classes to see how to instantiate a class and call its methods. It’s really pretty straightforward:

Code: Select all

MyKnob := new RotaryKnob(hMyControl, 50, 45)
MyKnob.Draw(90)

x32
Posts: 177
Joined: 25 Nov 2016, 16:44

Re: Someone updated my library.

Post by x32 » 03 Feb 2023, 10:43

Thanks boiler I did look in the docs but only on the Content tab, didn't think to search the index. I did find the page but it is still above my head.

I've updated a working example using the class and I am able to draw the control but not able to spin it, or animate it, or whatever the terminology would be for making the indicator dot move around the edge.

Also, how do you use a class object. Can it be called like a library function or does it need to be included in the script.

Here is my example script. If you use the library functions and comment out the class functions (are they called functions?) it works fine.

Code: Select all

size = 75
PotNow = 1

Gui, add, Text, x2 y5 h%size% w%size% hwndhText1 gt1, 
Gui, Add, Progress, x5 y+5 w%size% cRed Range0-360 vp1, 
Gui, Show,  , Potentiometers

;RotaryKnob(hText1,size,PotNow,1)
MyKnob := new RotaryKnob(hText1, size, 10)
MyKnob.Draw(90)

return

t1:
MouseGetPos, , OutY
StartPoint := OutY
Loop, 
	{
	KeyIsDown := GetKeyState("LButton")
	If KeyIsDown = 1
		{
		MouseGetPos, , OutY
		PotSet := StartPoint-OutY+PotNow
		
		If PotSet < 0
			PotSet = 0
		If PotSet > 360
			PotSet = 360
		;RotaryKnob(hText1,size,PotSet,1)
		pos := MyKnob.UpdatePosition()
		MyKnob.Draw(pos)
		GuiControl, , p1, %PotSet%
		Sleep, 50
		}
	If KeyIsDown = 0
		{
		PotNow := PotSet
		IniWrite, %PotSet%, knobs.ini, vals, pot1
		Break
		}
	}
Return

Exit:
GuiEscape:
GuiClose:
Gui, Destroy
ExitApp
Return

class RotaryKnob {

	__New(hControl,size,angle) {
		this.size := size
		this.angle := angle
		this.knobSize := size * 1.05
		this.indicatorSize := size / 9
		this.radius := this.knobSize / 3
		this.hdc := DllCall("GetDC", "uint", hControl)
		this.x := 0
		this.y := 0
		this.Draw(this.angle)
	}

	Draw(angle) {
		this.angle := (angle > 360 ? 360 : angle < 0 ? 0 : angle)
		this.UpdatePosition()

		DllCall("Ellipse", "uint", this.hDc, "int", 1, "int", 1, "int", this.knobsize, "int", this.knobsize)
		DllCall("Ellipse", "uint", this.hDc, "int", 3, "int", 3, "int", this.knobsize-2, "int", this.knobsize-2)
		DllCall("Ellipse", "uint", this.hDc, "int", this.x, "int", this.y, "int", this.x + this.indicatorsize, "int", this.y + this.indicatorsize)
	}

	UpdatePosition() {
		this.x := ((this.knobsize/2)-3) - sin(this.angle*4*ATan(1)/180)*this.radius
		this.y := ((this.knobsize/2)-3) + cos(this.angle*4*ATan(1)/180)*this.radius
	}

	UpdateSize(size) {
		this.knobSize := size * 1.05
		this.indicatorSize := size / 9
	}
}

User avatar
boiler
Posts: 16768
Joined: 21 Dec 2014, 02:44

Re: Someone updated my library.

Post by boiler » 03 Feb 2023, 14:27

x32 wrote: I've updated a working example using the class and I am able to draw the control but not able to spin it, or animate it, or whatever the terminology would be for making the indicator dot move around the edge.
To spin it, you just keep calling the Draw() method with different values:

Code: Select all

#Include RotaryKnob.ahk
size = 75
Gui, add, Text, x2 y5 h%size% w%size% hwndhText1
Gui, Show,  , Potentiometers

MyKnob := new RotaryKnob(hText1, size, 10)
loop, 360 {
	MyKnob.Draw(A_Index)
	Sleep, 10
}
return

Exit:
GuiEscape:
GuiClose:
ExitApp
I'll leave how you do that with the mouse position to you, but you can see how the above spins it based on the value passed to the method. You seem to be trying to call UpdatePosition() directly. There isn't a reason to do that; the Draw() method calls it. Just call Draw() with the value you want.

x32 wrote: Also, how do you use a class object. Can it be called like a library function or does it need to be included in the script.
I don't know of a way to auto-include a class, but you can always use #Include instead of adding a copy into the parent script itself.

x32 wrote: ...the class functions (are they called functions?)
They are called methods.

gmoises
Posts: 74
Joined: 18 Nov 2017, 16:43

Re: Someone updated my library.

Post by gmoises » 03 Feb 2023, 19:34

I did a little updating to your example
it works now

Code: Select all

#Requires AutoHotkey v1.1.36+
size = 75
PotNow = 1

Gui, add, Text, x2 y5 h%size% w%size% hwndhText1 gt1, 
Gui, Add, Progress, x5 y+5 w%size% cRed Range0-360 vp1, 
Gui, Show,  , Potentiometers

;RotaryKnob(hText1,size,PotNow,1)
MyKnob := new RotaryKnob(hText1, size, 10)
MyKnob.Draw(90)

return

t1:
MouseGetPos, , OutY
StartPoint := OutY
Loop, 
{
	If (KeyIsDown := GetKeyState("LButton"))
	{
		MouseGetPos, , OutY
		PotSet := StartPoint-OutY+PotNow
		
		If PotSet < 0
			PotSet = 0
		If PotSet > 360
			PotSet = 360
		;RotaryKnob(hText1,size,PotSet,1)
		pos := MyKnob.UpdatePosition()
		MyKnob.Draw(PotSet)
		GuiControl, , p1, %PotSet%
		Sleep, 50
	}
	If KeyIsDown = 0
	{
		PotNow := PotSet
		IniWrite, %PotSet%, knobs.ini, vals, pot1
		Break
	}
}
Return

Exit:
GuiEscape:
GuiClose:
Gui, Destroy
	ExitApp


class RotaryKnob {

	__New(hControl,size,angle) {
		this.size := size
		this.angle := angle
		this.knobSize := size * 1.05
		this.indicatorSize := size / 9
		this.radius := this.knobSize / 3
		this.hdc := DllCall("GetDC", "uint", hControl)
		this.x := 0
		this.y := 0
		this.Draw(this.angle)
	}

	Draw(angle) {
		this.angle := (angle > 360 ? 360 : angle < 0 ? 0 : angle)
		this.UpdatePosition()

		DllCall("Ellipse", "uint", this.hDc, "int", 1, "int", 1, "int", this.knobsize, "int", this.knobsize)
		DllCall("Ellipse", "uint", this.hDc, "int", 3, "int", 3, "int", this.knobsize-2, "int", this.knobsize-2)
		DllCall("Ellipse", "uint", this.hDc, "int", this.x, "int", this.y, "int", this.x + this.indicatorsize, "int", this.y + this.indicatorsize)
	}

	UpdatePosition() {
		this.x := ((this.knobsize/2)-3) - sin(this.angle*4*ATan(1)/180)*this.radius
		this.y := ((this.knobsize/2)-3) + cos(this.angle*4*ATan(1)/180)*this.radius
	}

	UpdateSize(size) {
		this.knobSize := size * 1.05
		this.indicatorSize := size / 9
	}
}

User avatar
Chunjee
Posts: 1400
Joined: 18 Apr 2014, 19:05
Contact:

Re: Someone updated my library.

Post by Chunjee » 04 Feb 2023, 12:01

I prefer classes as they are better at self containing the relevant code.

Code: Select all

PotSet = 0
may be worthwhile updating to assignment operator :=

Post Reply

Return to “Ask for Help (v1)”