aboutsummaryrefslogtreecommitdiff
path: root/!tt.scrollbar.ahk
diff options
context:
space:
mode:
authorJohn Ankarström <john@ankarstrom.se>2020-10-23 01:44:02 +0200
committerJohn Ankarström <john@ankarstrom.se>2020-10-23 01:44:02 +0200
commit1f460f7ebc10c2f8bb66ae684498f49187eab9bc (patch)
tree776f7a92b0d24e27cd682e4ff76bde477a02ff98 /!tt.scrollbar.ahk
downloadahk-1f460f7ebc10c2f8bb66ae684498f49187eab9bc.tar.gz
first commit
Diffstat (limited to '!tt.scrollbar.ahk')
-rw-r--r--!tt.scrollbar.ahk220
1 files changed, 220 insertions, 0 deletions
diff --git a/!tt.scrollbar.ahk b/!tt.scrollbar.ahk
new file mode 100644
index 0000000..c88f451
--- /dev/null
+++ b/!tt.scrollbar.ahk
@@ -0,0 +1,220 @@
+;; Plan 9-like scrollbar for Windows XP ---------------------------------------
+
+;; The following rules apply:
+
+;; * Press/hold left mouse button to scroll down.
+;; * Press/hold right mouse button to scroll up.
+;; * The closer to the top of the scrollbar, the slower the speed.
+;; * The closer to the bottom of the scrollbar, the faster the speed.
+
+;; The scrolling is achieved by simulating the mouse wheel.
+;; Windows without mousewheel support do not work.
+
+;; To use the scrollbar normally, hold any modifier key while clicking the
+;; mouse. Ctrl works well, as Ctrl-clicking a scrollbar does nothing special.
+
+;; -> init
+
+GroupAdd, ScrollbarExceptions, ahk_class Shell_TrayWnd
+GroupAdd, ScrollbarExceptions, ahk_class #32768
+
+;; -> body
+
+#If (ScrollbarClip or WinActive("ahk_class MozillaWindowClass")) and (ScrollbarCurrent := CurrentScrollbar())
+
+LButton::
+MouseGetPos,, my
+s := ScrollbarCurrent
+r := ceil((my - s.a) / (s.b - s.a) * 10)
+ScrollbarAmount := r
+if (WinActive("ahk_class PuTTY"))
+ ScrollbarDown = ^{PgDn}
+else
+ ScrollbarDown = {WheelDown}
+ScrollbarNew := true
+if (not ScrollbarScrolling)
+ SetTimer, ScrollbarScroll, 0
+return
+
+RButton::
+MouseGetPos,, my
+s := ScrollbarCurrent
+r := ceil((my - s.a) / (s.b - s.a) * 10)
+ScrollbarAmount := -r
+if (WinActive("ahk_class PuTTY"))
+ ScrollbarUp = ^{PgUp}
+else
+ ScrollbarUp = {WheelUp}
+ScrollbarNew := true
+if (not ScrollbarScrolling)
+ SetTimer, ScrollbarScroll, 0
+return
+
+#If
+
+<^>!§::SendInput, {Text}§
+
+§::
+global ScrollbarClip
+DllCall("ClipCursor", "Ptr", &0)
+WinGetPos, x,, w,, A
+MouseGetPos, mx, my
+s := CurrentScrollbar(w - 12, my)
+ScrollbarClip := !ScrollbarClip
+if (not ScrollbarClip or not s)
+ return
+WinGetPos, x, y
+VarSetCapacity(r, 12, 0)
+NumPut(x + s.aa + 6, &r + 0)
+NumPut(y + s.a + 1, &r + 4)
+NumPut(x + s.bb + 6, &r + 8)
+NumPut(y + s.b, &r + 12)
+DllCall("ClipCursor", "UInt", &R)
+r = ""
+return
+
+;; -> library
+
+ScrollbarScroll:
+SetTimer, ScrollbarScroll, Off
+ScrollbarScrolling := true
+ScrollbarNew := false
+i := 0
+j := abs(ScrollbarAmount)
+while (i < j or GetKeyState(ScrollbarAmount > 0 ? "LButton" : "RButton", "P"))
+{
+ i += 1
+ if (ScrollbarNew)
+ {
+ i := 0
+ j := abs(ScrollbarAmount)
+ ScrollbarNew := false
+ }
+ MouseGetPos,, my
+ s := ScrollbarCurrent
+ if (my < s.a)
+ r := 1
+ else
+ r := ceil((my - s.a) / (s.b - s.a) * 10)
+ ScrollbarAmount := ScrollbarAmount > 0 ? r : -r
+ if (ScrollbarAmount > 0)
+ SendInput, %ScrollbarDown%
+ else
+ SendInput, %ScrollbarUp%
+ Sleep, % 100 / abs(ScrollbarAmount)
+ if (not (i < j or GetKeyState(ScrollbarAmount > 0 ? "LButton" : "RButton", "P")))
+ break
+ if (i = j)
+ Sleep, 150
+}
+ScrollbarScrolling := false
+return
+
+CurrentScrollbar(mx = "", my = "")
+{
+ static size := 17
+ static GA_ROOT := 2
+
+ old := A_BatchLines
+ SetBatchLines, -1
+ goto begin
+end:
+ SetBatchLines, % A_BatchLines
+ return false
+begin:
+
+ ;; Because this function is run whenever the left mouse button is pressed, it
+ ;; is important to return false as early as possible.
+
+ CoordMode, Mouse, Window
+ if (mx = "" and my = "")
+ MouseGetPos, mx, my, hwnd
+ if (mx = "" and my != "")
+ MouseGetPos,, my, hwnd
+ if (mx != "" and my = "")
+ MouseGetPos, mx,, hwnd
+ if (mx != "" and my != "")
+ MouseGetPos,,, hwnd
+ WinGet, id, id, ahk_id %hwnd% ahk_group ScrollbarExceptions
+ if (hwnd = id)
+ goto end
+ if (not ScrollbarScrolling and hwnd != WinActive("A"))
+ goto end
+
+ tmp := A_CoordModePixel
+ CoordMode, Pixel, Window
+
+ ImageSearch,, wy, % mx - size, % my - size, % mx + size, % my + size, whitesection.bmp
+ ImageSearch,, by, % mx - size, % my - size, % mx + size, % my + size, *50 bluesection.bmp
+ if (wy = "" and by = "")
+ goto end
+
+ WinGetPos,,,, h, A
+ quit := false
+
+ if (my > h / 2)
+ {
+ gosub ScrollbarFindDownBelow
+ if (quit)
+ goto end
+ gosub ScrollbarFindUpAbove
+ if (quit)
+ goto end
+ } else {
+ gosub ScrollbarFindUpAbove
+ if (quit)
+ goto end
+ gosub ScrollbarFindDownBelow
+ if (quit)
+ goto end
+ }
+ goto ScrollbarFindRest
+
+ScrollbarFindUpAbove:
+ y := 20
+ Loop
+ {
+ ImageSearch, uax, uay, % mx - size, % my - y, % mx + size, % my, arrowup.bmp
+ y += 20
+ } until (uay != "" or my - y <= 0)
+
+ if (uay = "")
+ {
+ CoordMode, Pixel, % tmp
+ quit := true
+ }
+ return
+
+ScrollbarFindDownBelow:
+ ImageSearch, dbx, dby, % mx - size, % my, % mx + size, % h, arrowdown.bmp
+
+ if (dby = "")
+ {
+ CoordMode, Pixel, % tmp
+ quit := true
+ }
+ return
+
+ScrollbarFindRest:
+ y := 20
+ ; Find down arrow above
+ Loop
+ {
+ ImageSearch, dax, day, % mx - size, 0, % mx + size, % h, arrowdown.bmp ; above
+ y += 20
+ } until (day != "" or my - y <= 0)
+
+ ; Find up arrow below
+ ImageSearch, ubx, uby, % mx - size, % my, % mx + size, % h, arrowup.bmp
+
+ ; In the middle of two scrollbars
+ if (day != "" and uby != "" and day > uay and uby < dby)
+ {
+ CoordMode, Pixel, % tmp
+ goto end
+ }
+
+ CoordMode, Pixel, % tmp
+ SetBatchLines, % A_BatchLines
+ return { a: uay + size + 1, b: dby - 1, aa: uax, bb: dbx }
+}