Slider - same position/on top of each other

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Trej
Posts: 13
Joined: 10 Mar 2019, 19:25

Slider - same position/on top of each other

Post by Trej » 12 Mar 2019, 22:30

Hi all,

I have a question relating to sliders and having two aligned over each other. The idea is I am trying to make a scroll bar. As I understand it, scroll bars can only be used in Listview items.

I have modified a bit of code from @Pulover from an archived post in the link below.

What I can do, to have them work on the same line. Below is the screen capture of the issue that is affecting me. I have tried any number of changes with no luck.

https://autohotkey.com/board/topic/28850-using-progress-as-a-slider/

Image

Code: Select all

CoordMode, Mouse, Window
SetBatchLines -1
PBarSize := 600  ; Choose Progress Bar width in pixels.
Prop := PBarSize / 100 * 10

SetFormat, Float, 2.0  ; For the Tooltip only.
Gui, -dpiscale +Owner +LastFound +AlwaysOnTop +ToolWindow -Caption
Gui, Add, Progress, x+10 w%PBarSize% h20 cGreen vMyProgress +E0x00400000 R0-100, 75
Gui, Add, Progress, x-10 w%PBarSize% h20 cGreen vMyProgress2 R0-100, 25
Gui, Show,, vMyProgress2
OnMessage(0x201, "WM_LBUTTONDOWN")  ; Monitors Left Clicks on Gui.

return

WM_LBUTTONDOWN(wParam, lParam)
{
   MouseGetPos, mX,,, control
   If control <> msctls_progress321  ; If the click wasn't in the progress bar, do nothing.
      return
   SetTimer, WatchCursor, 0
}

WatchCursor:
If !GetKeyState("LButton", "P")
{
   Tooltip
   SetTimer, WatchCursor, off
   return
}
MouseGetPos, mX  ; Gets mouse position relative to the Window.
X := 100 - (mX * 10 / Prop)
Y := mX * 10 / Prop
Tooltip, % PBar(X)

GuiControl,, MyProgress, %X%  ; Sets progress bar to mouse position.
GuiControl,, MyProgress2, %Y%  ; Sets progress bar to mouse position.
return

GuiEscape:
ExitApp



PBar(X)
{
	If X < 0
		return 0
	If X > 100
		return 100
	Else
		return X
}
Attachments
Screen Capture.png
Screen Capture.png (1.14 KiB) Viewed 3651 times

just me
Posts: 9576
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Slider - same position/on top of each other

Post by just me » 13 Mar 2019, 04:26

Since progress bars have an opaque background it doesn't seem to be possibe to achieve what you want with two overlapping controls (at least without much additional work in the background). You might consider to use two controls of appropriate size side by side. But resizing the controls at a high frequency might cause annoying flickering (I didn't test it here).

teadrinker
Posts: 4412
Joined: 29 Mar 2015, 09:41
Contact:

Re: Slider - same position/on top of each other

Post by teadrinker » 13 Mar 2019, 07:30

I'd try another approach:

Code: Select all

size := 400
height := 15
thumbWidth := 50

WS_CLIPCHILDREN := 0x02000000, WS_EX_COMPOSITED := 0x02000000
Gui, Back: +ToolWindow -Caption +AlwaysOnTop +%WS_CLIPCHILDREN% +E%WS_EX_COMPOSITED%
Gui, Back: Color, Lime

Gui, Thumb: +ToolWindow -Caption +ParentBack +hwndhThumb
Gui, Thumb: Color, Fuchsia
Gui, Thumb: Show, NA x0 y0 w%thumbWidth% h%height%

Gui, Back: Show, w%size% h%height%
OnMessage( 0x201, Func("WM_LBUTTONDOWN").Bind(hThumb, thumbWidth, size, height) )
Return

Esc:: ExitApp

WM_LBUTTONDOWN(hThumb, thumbWidth, maxSize, height, wp, lp, msg, hwnd) {
   static pos := 0, maxPos, dpi := A_ScreenDPI/96
   ( maxPos =  "" && maxPos := (maxSize - thumbWidth)*dpi )
   
   if (hwnd = hThumb) {
      MouseGetPos, prevX
      while GetKeyState("LButton", "P") {
         MouseGetPos, X
         newPos := pos + X - prevX
         (newPos < 0 && newPos := 0), (newPos > maxPos && newPos := maxPos)
         try Gui, Thumb: Show, NA x%newPos% y0 w%thumbWidth% h%height%
         ToolTip % Round(newPos*100/maxPos)
         Sleep, 10
      }
      (newPos != "" && pos := newPos)
      ToolTip
   }
}

Trej
Posts: 13
Joined: 10 Mar 2019, 19:25

Re: Slider - same position/on top of each other

Post by Trej » 13 Mar 2019, 08:47

Hi Teadrinker, that is great!!! Exactly what I have been looking for!!

Follow up questions:

- How can I modify the position in response wheelup/down events?
- How am I able to rotate it 90 degress?

Trej
Posts: 13
Joined: 10 Mar 2019, 19:25

Re: Slider - same position/on top of each other

Post by Trej » 13 Mar 2019, 11:05

Got it going up/down.

Another question, how do I break it down so it moves in steps of 6 lines. With 6 being the bottom, and 1 at the top?

Code: Select all

size := 400
height := 400
thumbWidth := 50

WS_CLIPCHILDREN := 0x02000000, WS_EX_COMPOSITED := 0x02000000
Gui, Back: +ToolWindow -Caption +AlwaysOnTop +%WS_CLIPCHILDREN% +E%WS_EX_COMPOSITED%
Gui, Back: Color, Lime

Gui, Thumb: +ToolWindow -Caption +ParentBack +hwndhThumb
Gui, Thumb: Color, Fuchsia
Gui, Thumb: Show, NA x0 y0 w%height% h%thumbWidth%

Gui, Back: Show, w%size% h%height%
OnMessage( 0x201, Func("WM_LBUTTONDOWN").Bind(hThumb, thumbWidth, size, height) )
Return

Esc:: ExitApp

WM_LBUTTONDOWN(hThumb, thumbWidth, maxSize, height, wp, lp, msg, hwnd) {
   static pos := 0, maxPos, dpi := A_ScreenDPI/96
   ( maxPos =  "" && maxPos := (maxSize - thumbWidth)*dpi )
   
   if (hwnd = hThumb) {
      MouseGetPos, prevX
      while GetKeyState("LButton", "P") {
         MouseGetPos,, X
         newPos := pos + X - prevX
         (newPos < 0 && newPos := 0), (newPos > maxPos && newPos := maxPos)
         try Gui, Thumb: Show, NA x0 y%newPos% w%height% h%thumbWidth%
         ToolTip % Round(newPos*100/maxPos)
         Sleep, 10
      }
      (newPos != "" && pos := newPos)
      ToolTip
   }
}

teadrinker
Posts: 4412
Joined: 29 Mar 2015, 09:41
Contact:

Re: Slider - same position/on top of each other

Post by teadrinker » 13 Mar 2019, 12:06

Trej wrote: Got it going up/down.
For me it doesn't work. :)
I tried to write the class for sliders, it seems to work:

Code: Select all

slider1 := new MySlider("h", 400, 15, 50, "Lime", "Fuchsia", 10)
Gui, % slider1.hGui ":Show", x300 y300

slider2 := new MySlider("v", 300, 15, 50, "Silver", "Red", 50)
Gui, % slider2.hGui ":Show", x800 y150
Return

Esc::ExitApp

class MySlider
{
   __New(orientation, len, height, thumbWidth, backColor, thumbColor, startPosPercent := 0) {
      static WS_CLIPCHILDREN := 0x02000000, WS_EX_COMPOSITED := 0x02000000
      this.dpi := A_ScreenDPI/96
      this.vert := !!InStr(orientation, "v")
      this.height := height
      this.thumbWidth := thumbWidth
      this.len := len
      this.maxSize := (len - thumbWidth)*this.dpi
      
      Gui, New, +hwndhBack +ToolWindow -Caption +AlwaysOnTop +%WS_CLIPCHILDREN% +E%WS_EX_COMPOSITED%
      this.hGui := hBack
      Gui, Color, % backColor
      
      Gui, New, +hwndhThumb +ToolWindow -Caption +Parent%hBack%
      this.hThumb := hThumb
      Gui, Color, % thumbColor
      this.pos := Round( this.maxSize/100*startPosPercent )
      Gui, Show, % "NA " . this.BuildCoords(this.pos)
      
      coords := this.vert ? "w" . height . " h" . len : "w" . len . " h" . height
      Gui, %hBack%: Show, Hide %coords%
      OnMessage( 0x201, ObjBindMethod(this, "WM_LBUTTONDOWN") )
      OnMessage( 0x20A, ObjBindMethod(this, "WM_MOUSEWHEEL") )
   }
   
   WM_LBUTTONDOWN(wp, lp, msg, hwnd) {
      CoordMode, Mouse, Client
      MouseGetPos, prevX, prevY
      
      if (hwnd = this.hGui) {
         this.pos := (this.vert ? this.maxSize - prevY : prevX) + this.thumbWidth*this.dpi//2*(this.vert ? 1 : -1)
         (this.pos < 0 && this.pos := 0), (this.pos > this.maxSize && this.pos := this.maxSize)
         Gui, % this.hThumb ": Show", % "NA " . this.BuildCoords(this.pos)
      }
      if (hwnd = this.hThumb) {
         while GetKeyState("LButton", "P") {
            MouseGetPos, X, Y
            newPos := this.pos + (this.vert ? Y - prevY : X - prevX)*(this.vert ? -1 : 1)
            (newPos < 0 && newPos := 0), (newPos > this.maxSize && newPos := this.maxSize)
            try Gui, % this.hThumb ": Show", % "NA " . this.BuildCoords(newPos)
            ToolTip % Round(newPos*100/this.maxSize)
            Sleep, 10
         }
         (newPos != "" && this.pos := newPos)
         ToolTip
      }
   }
   
   WM_MOUSEWHEEL(wp) {
      if !WinActive("ahk_id" this.hGui)
         Return
      dir := (wp >> 16)//120
      this.pos += dir*this.thumbWidth*this.dpi//2
      (this.pos < 0 && this.pos := 0), (this.pos > this.maxSize && this.pos := this.maxSize)
      Gui, % this.hThumb ": Show", % "NA " . this.BuildCoords(this.pos)
   }
   
   BuildCoords(pos) {
      Return this.vert ? "x0 y" . (this.len*this.dpi - pos - this.thumbWidth*this.dpi) . " w" . this.height . " h" . this.thumbWidth
                       : "x" . pos . " y0 w" . this.thumbWidth . " h" . this.height
   }
}
Trej wrote: Another question, how do I break it down so it moves in steps of 6 lines. With 6 being the bottom, and 1 at the top?
Try playing with this.pos += dir*this.thumbWidth*this.dpi//2.

wolf_II
Posts: 2688
Joined: 08 Feb 2015, 20:55

Re: Slider - same position/on top of each other

Post by wolf_II » 13 Mar 2019, 12:45

Thanks, teadrinker, great approach, very elegant!

Here is my attempt, based on yours, I use hotkeys for wheel.

Code: Select all

    Size := 400
    number_of_steps := 6
    Height := Size / number_of_steps

    Gui, New, ToolWindow -Caption HWNDhBack AlwaysOnTop
    Gui, +0x02000000 ; WS_CLIPCHILDREN
    Gui, Color, Lime

    Gui, New, -Caption HWNDhThumb Parent%hBack%
    Gui, Color, Fuchsia
    Gui, Show, NA x0 y0 w15 h%Height%
    Gui, %hBack%: Show, w15 h%Size%

    fn := Func("WM_LBUTTONDOWN").Bind(hThumb)
    OnMessage(0x201, fn) ; WM_LBUTTONDOWN

return

Esc:: ExitApp
F5:: Reload



;-------------------------------------------------------------------------------
#If WinActive("ahk_id " hBack)
;-------------------------------------------------------------------------------
    WheelUp::   Wheel("Up")
    WheelDown:: Wheel("Dn")

#If ; end


;-------------------------------------------------------------------------------
WM_LBUTTONDOWN(hThumb, wp, lp, msg, hWnd) { ; event handler
;-------------------------------------------------------------------------------
    static pos := 0, maxPos, dpi := A_ScreenDPI / 96
    global Height, Size

    if (maxPos = "")
        maxPos := (Size-Height) * dpi

    if (hThumb = hWnd) {
        MouseGetPos,, prevY
        while GetKeyState("LButton", "P") {
            MouseGetPos,, Y
            newPos := pos + Y - prevY
            newPos := clamp(newPos, 0, maxPos)
            Gui, %hThumb%: Show, NA x0 w15 y%newPos% h%Height%
            ToolTip, % Round(newPos * 100 / maxPos)
            Sleep, 10
        }
    }

    if newPos
        pos := newPos

    ToolTip ; off
}



;-------------------------------------------------------------------------------
Wheel(Direction) { ; callled by hotkeys
;-------------------------------------------------------------------------------
    static pos := 0, dpi := A_ScreenDPI / 96
    global hThumb, Height, Size, number_of_steps

    pos += (Direction = "Up") ? -1 : 1
    pos := clamp(pos, 0, number_of_steps - 1)
    newY := pos * Size / number_of_steps

    Gui, %hThumb%: Show, NA x0 w15 y%newY% h%Height%
}



;-------------------------------------------------------------------------------
clamp(Variable, min, max) { ; limit variable range to [min..max]
;-------------------------------------------------------------------------------
	Return, (Variable < min) ? min
          : (Variable > max) ? max : Variable
}

teadrinker
Posts: 4412
Joined: 29 Mar 2015, 09:41
Contact:

Re: Slider - same position/on top of each other

Post by teadrinker » 13 Mar 2019, 13:32

wolf_II wrote: Thanks, teadrinker, great approach, very elegant!
Thanks, but it is just a try, it does not pretend to be something complete. :)
wolf_II wrote: I use hotkeys for wheel.
Works, but after wheel it springs when you try dragging.

teadrinker
Posts: 4412
Joined: 29 Mar 2015, 09:41
Contact:

Re: Slider - same position/on top of each other

Post by teadrinker » 13 Mar 2019, 18:41

Some improvements:

Code: Select all

#Warn
slider1 := new MySlider("h", 400, 15, 70, "Lime", "Fuchsia", 10)
Gui, % slider1.hWnd ":Show", x300 y350

slider2 := new MySlider("v", 400, 17, 70, "Silver", "Red", 50)
Gui, % slider2.hWnd ":Show", x800 y150
Return

Esc::ExitApp

class MySlider
{
   __New(orientation, len, height, thumb, backColor, thumbColor, startPosPercent := 0) {
      static styles := "+"  . (WS_CLIPCHILDREN  := 0x2000000)
                    . " +E" . (WS_EX_COMPOSITED := 0x2000000)
      this.dpi := A_ScreenDPI/96
      this.vert := !!InStr(orientation, "v")
      this.height := height
      this.thumb := thumb
      this.len := len
      this.maxSize := (len - thumb)*this.dpi
      
      Gui, New, +hwndhBack +ToolWindow -Caption +AlwaysOnTop %styles%
      this.hWnd := hBack
      Gui, Color, % backColor
      
      Gui, New, +hwndhThumb +ToolWindow -Caption +Parent%hBack%
      this.hThumb := hThumb
      Gui, Color, % thumbColor
      this.pos := Round( this.maxSize/100*startPosPercent )
      Gui, Show, % this.BuildCoords(this.pos)
      
      coords := this.vert ? "w" . height . " h" . len : "w" . len . " h" . height
      Gui, %hBack%: Show, Hide %coords%
      
      self := this.Clone(), self.self := true
      this.onClick := this.WM_LBUTTONDOWN.Bind(self)
      this.onWheel := this.WM_MOUSEWHEEL.Bind(self)
      OnMessage(0x201, this.onClick)
      OnMessage(0x20A, this.onWheel)
   }
   
   __Delete() {
      if this.self
         Return
      Gui, % this.hThumb ": Destroy"
      Gui, % this.hWnd   ": Destroy"
      OnMessage(0x201, this.onClick, 0)
      OnMessage(0x20A, this.onWheel, 0)
   }
   
   WM_LBUTTONDOWN() {
      static newPos
      if !GetKeyState("LButton", "P")
         Return
      prevCMM := A_CoordModeMouse
      CoordMode, Mouse, Screen
      MouseGetPos, X_Mouse, Y_Mouse, hwnd, hCtrl, 2
      WinGetPos, X_Gui, Y_Gui,,, % "ahk_id" this.hWnd
      
      prevX := X_Mouse - X_Gui
      prevY := Y_Mouse - Y_Gui
      
      if (hCtrl = "" && hwnd = this.hWnd) {
         if this.vert
            this.pos := this.maxSize - prevY + this.thumb//2 * this.dpi
         else
            this.pos := prevX - this.thumb//2 * this.dpi
         
         this.pos := this.InRange(this.pos)
         Gui, % this.hThumb ": Show", % this.BuildCoords(this.pos)
         hCtrl := this.hThumb
      }
      if (hCtrl = this.hThumb) {
         while GetKeyState("LButton", "P") {
            MouseGetPos, X_Mouse, Y_Mouse
            X := X_Mouse - X_Gui
            Y := Y_Mouse - Y_Gui
            if this.vert
               newPos := this.pos - Y + prevY
            else
               newPos := this.pos + X - prevX
            
            newPos := this.InRange(newPos)
            try Gui, % this.hThumb ": Show", % this.BuildCoords(newPos)
            ToolTip % Round(newPos*100/this.maxSize)
            Sleep, 10
         }
         this.pos := newPos
         ToolTip
      }
      CoordMode, Mouse, % prevCMM
   }
   
   WM_MOUSEWHEEL(wp, lp, msg, hwnd) {
      if !WinActive("ahk_id" this.hWnd) || hwnd != this.hWnd
         Return
      dir := (wp >> 16) & 0xFFFF = 120 ? 1 : -1
      this.pos += dir*this.thumb*this.dpi//2
      this.pos := this.InRange(this.pos)
      Gui, % this.hThumb ": Show", % this.BuildCoords(this.pos)
   }
   
   BuildCoords(pos) {
      Return "NA " . ( this.vert ? "x" . 0                                       . " "
                                 . "y" . (this.len -  this.thumb)*this.dpi - pos . " "
                                 . "w" . this.height                             . " "
                                 . "h" . this.thumb
                       
                                 : "x" . pos                                     . " "
                                 . "y" . 0                                       . " "
                                 . "w" . this.thumb                              . " "
                                 . "h" . this.height )
   }
   
   InRange(value) {
      Return value < 0 ? 0 : value > this.maxSize ? this.maxSize : value
   }
}
Last edited by teadrinker on 13 Mar 2019, 22:24, edited 1 time in total.

Trej
Posts: 13
Joined: 10 Mar 2019, 19:25

Re: Slider - same position/on top of each other

Post by Trej » 13 Mar 2019, 21:11

Hi teadrinker,

Thank you heaps for the help, can you tell me what is different between the 1st and 2nd approaches? I have very little programming experience, but have a solid understanding of technology. What I am trying to do is piece together bits of code and learn as I go.

To give you context on my project I am trying to increase my functionality of my Microsoft Surface Dial. Below is how I plan on doing this.

- On single press of the dial a gui will come up showing a list that of slider you can select using Up/down scroll events.
- Once you have landed on the slider you want, single press of the dial will select the line, close the gui and match a corresponding slider control within lightroom.

I have gotten a separate working which I can control a slider using the dial, the script here forms part of how I select the slider I want to control. There is a a bit of work still to do, but I need to slowly piece it all together.

Below is what I have done to date on the gui, I have tried to put your script as a subroutine but it is not working, will need to tinker more :D

Code: Select all


y := 31
Width := 500
Gui, +LastFound
WinSet, Transparent, 240
Gui, Color, cD0D0D0
Gui, Margin, 0, 0
Gui, Font, s11 808080 Bold
;Gosub Scrollbar
Gui, Add, Progress, % "x-0 y0 w" (Width+2) " h30 Background404040 Disabled hwndHPROG"
Gui, Add, Text, % "x0 y0 w" Width-400 " h30 BackgroundTrans Center 0x200 gGuiMove vCaption", Select Slider
Gui, Font, s8
Gui, Add, Text, % "x7 y+10 w" (Width-14) "r1 +0x4000 BackgroundTrans vTX1 gS1", Slider 1
Gui, Add, Text, % "x7 y+10 w" (Width-14) "r1 +0x4000 BackgroundTrans vTX2 gS2", Slider 2
Gui, Add, Text, % "x7 y+10 w" (Width-14) "r1 +0x4000 BackgroundTrans vTX3 gs3", Slider 3
Gui, Add, Text, % "x7 y+10 w" (Width-14) "r1 +0x4000 BackgroundTrans vTX4 gs4", Slider 4
Gui, Add, Text, % "x7 y+10 w" (Width-14) "r1 +0x4000 BackgroundTrans vTX5 gClose", Close
Gui, Add, Text, % "x7 y+10 w" (Width-14) "h5 vP"
GuiControlGet, P, Pos
H := PY + PH 
Gui, -Caption
WinSet, Region, 0-0 w%Width% h%H% r6-6
Gui, Show, % "w" Width " NA" " x" 500 " y200"
WinSet AlwaysOnTop
return

GuiMove:
   PostMessage, 0xA1, 2
return

S1:
MsgBox, You clicked Slider 1 (%A_GuiControl%).
return

S2:
MsgBox, You clicked Slider 2 (%A_GuiControl%).
return

S3:
MsgBox, You clicked Slider 3 (%A_GuiControl%).
return

S4:
MsgBox, You clicked Slider 4 (%A_GuiControl%).
return

Scrollbar:
    H := PY + PH 
    Size := H
    number_of_steps := 6
    Height := Size / number_of_steps

    Gui, New, ToolWindow -Caption HWNDhBack AlwaysOnTop
    Gui, +0x02000000 ; WS_CLIPCHILDREN
    Gui, Color, cD0D0D0

    Gui, New, -Caption HWNDhThumb Parent%hBack%
    Gui, Color, 404040
    Gui, Show, NA x0 y0 w500 h%Height%
    Gui, %hBack%: Show, w500 h%Size%

    fn := Func("WM_LBUTTONDOWN").Bind(hThumb)
    OnMessage(0x201, fn) ; WM_LBUTTONDOWN

return

Esc:: ExitApp
F5:: Reload



;-------------------------------------------------------------------------------
#If WinActive("ahk_id " hBack)
;-------------------------------------------------------------------------------
    WheelUp::   Wheel("Up")
    WheelDown:: Wheel("Dn")

#If ; end


;-------------------------------------------------------------------------------
WM_LBUTTONDOWN(hThumb, wp, lp, msg, hWnd) { ; event handler
;-------------------------------------------------------------------------------
    static pos := 0, maxPos, dpi := A_ScreenDPI / 96
    global Height, Size

    if (maxPos = "")
        maxPos := (Size-Height) * dpi

    if (hThumb = hWnd) {
        MouseGetPos,, prevY
        while GetKeyState("LButton", "P") {
            MouseGetPos,, Y
            newPos := pos + Y - prevY
            newPos := clamp(newPos, 0, maxPos)
            Gui, %hThumb%: Show, NA x0 w500 y%newPos% h%H%
            ToolTip, % Round(newPos * 100 / maxPos)
            Sleep, 10
        }
    }

    if newPos
        pos := newPos

    ToolTip ; off
}



;-------------------------------------------------------------------------------
Wheel(Direction) { ; callled by hotkeys
;-------------------------------------------------------------------------------
    static pos := 0, dpi := A_ScreenDPI / 96
    global hThumb, Height, Size, number_of_steps

    pos += (Direction = "Up") ? -1 : 1
    pos := clamp(pos, 0, number_of_steps - 1)
    newY := pos * Size / number_of_steps

    Gui, %hThumb%: Show, NA x0 w500 y%newY% h%Height%
}



;-------------------------------------------------------------------------------
clamp(Variable, min, max) { ; limit variable range to [min..max]
;-------------------------------------------------------------------------------
	Return, (Variable < min) ? min
          : (Variable > max) ? max : Variable
}

Return

Escape::
ExitApp
return

Close:
ExitApp

wolf_II
Posts: 2688
Joined: 08 Feb 2015, 20:55

Re: Slider - same position/on top of each other

Post by wolf_II » 13 Mar 2019, 21:30

teadrinker wrote:
13 Mar 2019, 18:41
Some improvements:

Code: Select all

 ... class MySlider ...
For me: there is no action when I scroll the mouse-wheel. on Win 10 x64, AHK v1.30.01 (x64). I am not sure, why.
Tested on virtual XP x32, AHK v1.1.28.00 (x32 ANSI): => WheelUp: works sometime, WheelDown: not working.

What are your settings?

teadrinker
Posts: 4412
Joined: 29 Mar 2015, 09:41
Contact:

Re: Slider - same position/on top of each other

Post by teadrinker » 13 Mar 2019, 22:36

wolf_II, I fixed the bug, just tested on Windows 10, it works now.
Trej wrote: I am trying to increase my functionality of my Microsoft Surface Dial
This is interesting, I hope, you'll manadge to get it working. :)
Trej wrote: can you tell me what is different between the 1st and 2nd approaches?
I think, the second one is simplier to implement in another script, try it.

Trej
Posts: 13
Joined: 10 Mar 2019, 19:25

Re: Slider - same position/on top of each other

Post by Trej » 13 Mar 2019, 22:58

Hi Teadrinker,

Thanks, I will pursue the second option. I am having issues with what I think is the speed which my mouse is sending messages through to the gui. Scrolling down doesn't seem to be an issue, however scrolling back up I need to be very slow with the wheel action. If I go to fast it started scrolling down again.

teadrinker
Posts: 4412
Joined: 29 Mar 2015, 09:41
Contact:

Re: Slider - same position/on top of each other

Post by teadrinker » 13 Mar 2019, 23:20

Trej wrote: I am having issues with what I think is the speed which my mouse is sending messages through to the gui.
If you want to slow down the scrolling of the slider with the mouse wheel you could change the number 2 in this line this.pos += dir*this.thumb*this.dpi//2 with 4, 6 or 8.

Trej
Posts: 13
Joined: 10 Mar 2019, 19:25

Re: Slider - same position/on top of each other

Post by Trej » 13 Mar 2019, 23:26

teadrinker wrote:
13 Mar 2019, 23:20
Trej wrote: I am having issues with what I think is the speed which my mouse is sending messages through to the gui.
If you want to slow down the scrolling of the slider with the mouse wheel you could change the number 2 in this line this.pos += dir*this.thumb*this.dpi//2 with 4, 6 or 8.
That is good to know and something I will need in the future, the issue is more when I scroll my wheel quickly up or even 'normal' speed the position goes down and kinda jumps around the place...

teadrinker
Posts: 4412
Joined: 29 Mar 2015, 09:41
Contact:

Re: Slider - same position/on top of each other

Post by teadrinker » 13 Mar 2019, 23:45

Have you tried the corrected last script?

Trej
Posts: 13
Joined: 10 Mar 2019, 19:25

Re: Slider - same position/on top of each other

Post by Trej » 13 Mar 2019, 23:51

Yep, i had the same issue that Wolf had, it worked with the updated script, but buggy when scrolling up.

wolf_II
Posts: 2688
Joined: 08 Feb 2015, 20:55

Re: Slider - same position/on top of each other

Post by wolf_II » 14 Mar 2019, 01:05

teadrinker wrote:
13 Mar 2019, 22:36
wolf_II, I fixed the bug, just tested on Windows 10, it works now.
I still see no movement of thumb-Gui when I scroll the wheel. :( (tested only on Win 10)

meanwhile, I worked on a Thumb class. It is at present capable to produce the exact buggy behaviour as my prev buggy script.
But with this approach I hope to find a solution.

progress: MAYBE jumps less erratically ?!

Code: Select all

; https://www.autohotkey.com/boards/viewtopic.php?p=267675#p267675

#NoEnv

    Size := 400
    number_of_steps := 6
    Height := Size / number_of_steps

    ; GUI for backdrop
    Gui, New, ToolWindow -Caption HWNDhBack AlwaysOnTop
    Gui, +0x02000000 ; WS_CLIPCHILDREN
    Gui, Color, Lime

    ; GUI for thumb
    Gui, New, -Caption HWNDhThumb Parent%hBack%
    Gui, Color, Fuchsia
    Gui, Show, NA x0 y0 w15 h%Height%
    Gui, %hBack%: Show, w15 h%Size%
    new Thumb(Size, number_of_steps)

    ; event handlers
    fn := Func("WM_LBUTTONDOWN").Bind(hThumb)
    OnMessage(0x201, fn) ; WM_LBUTTONDOWN
    Wheel := ObjBindMethod(Thumb, "onChange", hThumb)

return ; end of auto-execute section

Esc:: ExitApp
F5::  Reload



;-------------------------------------------------------------------------------
#If WinActive("ahk_id " hBack) or WinActive("ahk_id " hThumb)
;-------------------------------------------------------------------------------
    WheelUp::   %Wheel%("Up")
    WheelDown:: %Wheel%("Dn")

#If ; end



;===============================================================================
class Thumb { ; keep track of thumb's position on the backdrop
;===============================================================================

    ; CONSTANTS
    static DPI := A_ScreenDPI / 96
    static Size
    static number_of_steps
    static Height
    static maxPos

    ; variable
    static pos

    __New(Size, number_of_steps) { ; constructor
        Thumb.Size := Size
        Thumb.number_of_steps := number_of_steps
        Thumb.Height := Size / number_of_steps
        Thumb.maxPos := (Size-Thumb.Height) * Thumb.DPI
        Thumb.pos := 0
    }

    onChange(hThumb, Direction) { ; wheel events
        this.pos += (Direction = "Up") ? -1 : 1
        this.pos := clamp(this.pos, 0, this.number_of_steps - 1)
        newY := this.pos * this.Size / this.number_of_steps
        THeight := Thumb.Height
        Gui, %hThumb%: Show, NA x0 w15 y%newY% h%THeight%
    }

} ; end of class



;-------------------------------------------------------------------------------
WM_LBUTTONDOWN(hThumb, wp, lp, msg, hWnd) { ; event handler
;-------------------------------------------------------------------------------
    static pos := 0, maxPos := "", newPos := 0
    global Height, Size

    if (maxPos = "")
        maxPos := (Size-Height) * Thumb.DPI

    if (hThumb = hWnd) {
        MouseGetPos,, prevY
        while GetKeyState("LButton", "P") {
            MouseGetPos,, Y
            newPos := pos + Y - prevY
            newPos := clamp(newPos, 0, maxPos)

            Gui, %hThumb%: Show, NA x0 w15 y%newPos% h%Height%
            ToolTip, % Round(newPos * 100 / maxPos)
            Thumb.Pos := Round(newPos * (Thumb.number_of_steps - 1) / maxPos)
            Sleep, 10
        }
    }

    if newPos
        pos := newPos

    ToolTip ; off
}



;-------------------------------------------------------------------------------
clamp(Variable, min, max) { ; limit variable range to [min..max]
;-------------------------------------------------------------------------------
	Return, (Variable < min) ? min
          : (Variable > max) ? max : Variable
}

just me
Posts: 9576
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Slider - same position/on top of each other

Post by just me » 14 Mar 2019, 02:39

Hi wolf_II,

mouse wheel scrolling is working with the current version of teadrinker's script on Win 10. You need to activate the 'scrollbar' window and place the mouse cursor upon the window.

wolf_II
Posts: 2688
Joined: 08 Feb 2015, 20:55

Re: Slider - same position/on top of each other

Post by wolf_II » 14 Mar 2019, 03:49

@just me: Thx, I'll check it out.

Thie is my next attempt: no more thumbs jumping here:
My class is working as expected, but the script needs more cleaning.
Variables are a mess right now, and I do this dividsion twice Size / number_of_steps (most prominent example)

Code: Select all

; https://www.autohotkey.com/boards/viewtopic.php?p=267689#p267689

#NoEnv

    Size := 400
    number_of_steps := 6
    Height := Size / number_of_steps

    ; GUI for backdrop
    Gui, New, ToolWindow -Caption HWNDhBackdrop AlwaysOnTop
    Gui, +0x02000000 ; WS_CLIPCHILDREN
    Gui, Color, Lime

    ; GUI for thumb
    Gui, New, -Caption HWNDhThumb Parent%hBackdrop%
    Gui, Color, Fuchsia
    Gui, Show, NA x0 y0 w15 h%Height%
    Gui, %hBackdrop%: Show, w15 h%Size%
    new Thumb(Size, number_of_steps)

    ; event handlers
    fn := Func("WM_LBUTTONDOWN")
    OnMessage(0x201, fn) ; WM_LBUTTONDOWN
    Wheel := ObjBindMethod(Thumb, "onChange", hThumb)

return ; end of auto-execute section

Esc:: ExitApp
F5::  Reload



;-------------------------------------------------------------------------------
#If WinActive("ahk_id " hBackdrop)
;-------------------------------------------------------------------------------
    WheelUp::   %Wheel%("Up")
    WheelDown:: %Wheel%("Dn")

#If ; end



;===============================================================================
class Thumb { ; keep track of thumb's position on the backdrop
;===============================================================================

    ; CONSTANTS
    static DPI := A_ScreenDPI / 96
    static Size
    static number_of_steps
    static Height
    static maxPos

    ; variable
    pos := 0

    __New(Size, number_of_steps) { ; constructor
        Thumb.Size := Size
        Thumb.number_of_steps := number_of_steps
        Thumb.Height := Size / number_of_steps
        Thumb.maxPos := (Size-Thumb.Height) * Thumb.DPI
        this.pos := 0
    }

    onChange(hThumb, Direction) { ; wheel events
        this.pos += (Direction = "Up") ? -1 : 1
        this.pos := clamp(this.pos, 0, this.number_of_steps - 1)
        newY := this.pos * this.Size / this.number_of_steps
        THeight := Thumb.Height
        Gui, %hThumb%: Show, NA x0 w15 y%newY% h%THeight%
    }

} ; end of class



;-------------------------------------------------------------------------------
WM_LBUTTONDOWN(wp, lp, msg, hWnd) { ; event handler
;-------------------------------------------------------------------------------
    global hBackdrop, hThumb

    WinGetPos,, BackdropY,,, ahk_id %hBackdrop%
    WinGetPos,, ThumbY,,, ahk_id %hThumb%
    THeight := Thumb.Height

    if (hWnd = hThumb) {
        MouseGetPos,, prevY
        while GetKeyState("LButton", "P") {
            MouseGetPos,, currY
            newY := (ThumbY - BackdropY) + (currY - prevY) ; Y_offset + dY
            newY := clamp(newY, 0, Thumb.maxPos)
            Gui, %hThumb%: Show, NA x0 w15 y%newY% h%THeight%
            percent := newY * 100 / Thumb.maxPos
            ToolTip, % Round(percent), 20, 25 + newY
            Sleep, 10

            Thumb.Pos := Round(newY * (Thumb.number_of_steps - 1) / Thumb.maxPos)
        }
        ToolTip ; off
    }
}



;-------------------------------------------------------------------------------
clamp(Variable, min, max) { ; limit variable range to [min..max]
;-------------------------------------------------------------------------------
	Return, (Variable < min) ? min
          : (Variable > max) ? max : Variable
}
Edit: I managed to see the wheel working, Thx again, just me

Post Reply

Return to “Ask for Help (v1)”