-
Notifications
You must be signed in to change notification settings - Fork 1
/
my-caret.ahk
135 lines (116 loc) · 3.61 KB
/
my-caret.ahk
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
; Add extra mark to the text caret (aka blinking cursor) depending on input language and capslock state.
; Script is lookin into "./carets/" folder for files like "1-capslock.png", "2.png", etc.
#SingleInstance Force
#Requires AutoHotkey v2.0
#include lib/GetInputLocaleIndex.ahk
#include lib/ImagePut.ahk
#include lib/GetCaretRect.ahk
#include lib/GetCapslockState.ahk
;#include lib/Log.ahk
;#include lib/Jsons.ahk
global capslockSuffix := "-capslock"
global marginX := 1 ; mark's margin from the caret itself
global marginY := -1
global crt := Object() ; global storage of script state
crt.folder := A_ScriptDir . "\carets\"
crt.extensions := [".png", ".gif"]
crt.markWindow := -1 ; GUI's window to render caret's mark
crt.markPath := -1
crt.isShown := 0
crt.localeIndex := -1 ; init, later 1, 2, 3...
crt.prev := { x : -1, y : -1, markPath : crt.markPath }
RunCaret()
RunCaret() {
SetTimer CheckCaret, 50 ; main routine, to be executed every 50 milliseconds
}
; Checks if caret reflect current input locale or capslock state
CheckCaret() {
global
crt.markPath := GetImagePath()
if (crt.markPath == -1) {
HideMark()
return
}
top := -1
left := -1
bottom := -1
right := -1
GetCaretRect(&left?, &top?, &right?, &bottom?, &detectMethod)
caretWidth := right - left
if (detectMethod == "failure" or caretWidth < 1) {
HideMark()
return
}
PaintMark(right, top)
}
PaintMark(x := -1, y := -1) {
global
if (x == -1 or y == -1 or crt.markPath == -1) {
HideMark()
return
}
if (crt.markWindow != -1) {
if (crt.prev.x == x and crt.prev.y == y) {
if (crt.prev.markPath == crt.markPath) {
return ; same caret mark + at the same position = no repaint
}
}
}
w := ImageWidth(crt.markPath)
h := ImageHeight(crt.markPath)
halfMarkHeight := Floor(h/2)
if (crt.markWindow == -1 or crt.prev.markPath != crt.markPath) {
crt.prev.markPath := crt.markPath
InitMark()
}
showOptions := "X" x + marginX " Y" y - halfMarkHeight + marginY " AutoSize NA"
crt.markWindow.Show(showOptions)
crt.isShown := 1
crt.prev.x := x
crt.prev.y := y
; create or recreate transparent window for a caret mark's image
InitMark() {
if (crt.markWindow != -1)
crt.markWindow.Destroy()
backgroundColor := "FFFFFF"
minSize := " +MinSize" w "x" h
maxSize := " +MaxSize" w "x" h
; GUI to be transparent and not affected by DPI scaling
crt.markWindow := Gui("+LastFound -Caption +AlwaysOnTop +ToolWindow -Border -DPIScale -Resize" minSize maxSize)
crt.markWindow.MarginX := 0
crt.markWindow.MarginY := 0
crt.markWindow.Title := ""
crt.markWindow.BackColor := backgroundColor
WinSetTransColor(backgroundColor, crt.markWindow)
; create a dummy control to repurpose for ImagePut's functionality
display := crt.markWindow.Add("Text", "xm+0")
display.move(,,w,h) ; must resize the viewable area of the control
; use ImagePut to create a child window, and set the parent as the text control
image_hwnd := ImageShow(crt.markPath,, [0, 0], 0x40000000 | 0x10000000 | 0x8000000,, display.hwnd)
}
}
HideMark() {
global
if (crt.markWindow == -1 or crt.isShown == 0) {
return
}
crt.markWindow.Hide()
crt.isShown := 0
crt.markPath := -1
crt.prev.markPath := crt.markPath
}
GetImagePath() {
crt.localeIndex := GetInputLocaleIndex()
for Ext in crt.extensions {
if (GetCapslockState() == 1) {
path := crt.folder . crt.localeIndex . capslockSuffix . Ext ; e.g. "\carets\1-capslock.png"
if (FileExist(path))
return path ; capslock-suffixed file to be used
}
; fallback if no capslock-suffixed file found
path := crt.folder . crt.localeIndex . Ext ; e.g. "\carets\1.png"
if (FileExist(path))
return path
}
return -1
}