PageRenderTime 65ms CodeModel.GetById 54ms app.highlight 6ms RepoModel.GetById 1ms app.codeStats 0ms

/res/ahk/macro_recorder.ahk

http://github.com/Skiouros/Macro
AutoHotKey | 439 lines | 352 code | 78 blank | 9 comment | 40 complexity | 79324fc5c4c66217d0e2c531269f9d49 MD5 | raw file
  1Class MacroRecorder Extends CGUI
  2{
  3
  4	__New(mainGui, owner = "")
  5    {
  6		this.btnAdd := this.AddControl("Button", "btnAdd", "x20 y380 w90 h23", "New")
  7        this.btnCancel := this.AddControl("Button", "btnCancel", "x462 y400 w90 h23", "Cancel")
  8        this.btnDelete := this.AddControl("Button", "btnDelete", "x110 y380 w90 h23", "Delete")
  9        this.btnOK := this.AddControl("Button", "btnOK", "x362 y400 w90 h23", "OK")
 10        this.btnHelp := this.AddControl("Button", "btnHelp", "x562 y400 w90 h23", "Help")
 11
 12        this.btnStartRecord := this.AddControl("Button", "btnStartRecord", "x525 y50 w90 h23", "Start Recording")
 13        this.btnStopRecord := this.AddControl("Button", "btnStopRecord", "x525 y25 w90 h23", "Stop Recording")
 14
 15        this.chkDelay := this.AddControl("Checkbox", "chkDelay", "x485 y80 w165 h30", "Record delays between events")
 16
 17        this.AddControl("Groupbox", "groupbox1", "x485 y110 w155 h80", "")
 18        this.chkMouse := this.AddControl("Checkbox", "chkMouse", "x510 y107 w120 h20", "Include mouse clicks")
 19        this.chkCoords := this.AddControl("Checkbox", "chkCoords", "x490 y130 w100 h20", "Record location")
 20
 21		this.AddControl("GroupBox", "e", "x222 y10 w430 h380", "Details")
 22
 23        this.macroList := this.AddControl("ListView", "macroList", "x12 y10 w190 h360 NoSortHdr -Multi -ReadOnly", "Macro")
 24        this.currentMacro := this.AddControl("ListView", "currentMacro", "x232 y40 w250 h330 NoSortHdr -Multi count100", "Keys")
 25
 26        this.btnStopRecord.Disable()
 27        this.btnStartRecord.Disable()
 28
 29
 30        Menu, MacroName, Add, Edit, EditName
 31        Menu, MacroName, Add, Delete, DeleteName
 32
 33        Menu, LButton, Add, Down, MouseEvent
 34        Menu, LButton, Add, Up, MouseEvent
 35        Menu, LButton, Add, Click, MouseEvent
 36
 37        Menu, RButton, Add, Down, MouseEvent
 38        Menu, RButton, Add, Up, MouseEvent
 39        Menu, RButton, Add, Click, MouseEvent
 40
 41        Menu, MButton, Add, Down, MouseEvent
 42        Menu, MButton, Add, Up, MouseEvent
 43        Menu, MButton, Add, Click, MouseEvent
 44
 45        Menu, Wheel, Add, Backward, MouseEvent
 46        Menu, Wheel, Add, Forward, MouseEvent
 47
 48        Menu, MouseEvents, Add, Left Button, :LButton
 49        Menu, MouseEvents, Add, Right Button, :RButton
 50        Menu, MouseEvents, Add, Middle Button, :MButton
 51        Menu, MouseEvents, Add, Wheel, :Wheel
 52
 53        Menu, Macro, Add, Insert Mouse Event, :MouseEvents, P100
 54
 55        Menu, Macro, Add, Edit, Edit
 56        Menu, Macro, Add, Insert Delay, InsertDelay
 57        Menu, Macro, Add, Delete, Delete ; Menu for adding delays and mouse events
 58
 59        this.gui := mainGui
 60        this.Owner := owner, this.OwnerAutoClose := 1, this.MinimizeBox := 0
 61
 62        this.Toolwindow := 1
 63		this.Title := "Macro Recorder"
 64	}
 65
 66    chkMouse_CheckedChanged()
 67    {
 68        enabled := this.chkMouse.Checked
 69        this.chkCoords.Enabled := enabled
 70    }
 71
 72    btnOK_Click()
 73    {
 74        debug ? debug("Saving macros")
 75        this.UpdateMacro()
 76        xml.Save(A_ScriptDir . "\res\Profiles\" . xml.Get("name") . ".xml") ; Save xml file.
 77        this.ClearCurrentMacro()
 78
 79        ; Update current hotkey with new macro name.
 80        if (this.selectedRow)
 81            if (macroName := this.MacroName(this.selectedRow))
 82                this.gui.UpdateKey(MacroName)
 83
 84        this.oldMacroName := "", this.selectedRow := 0
 85        this.gui.Enabled := true
 86        this.Hide()
 87        this.gui.UpdateMacros()
 88    }
 89
 90    btnHelp_Click()
 91    {
 92        MsgBox,
 93        ( LTrim
 94            Right click "Keys" listview for context menu.
 95
 96            Any thing selected from context menu will be added to bottom of seleced item.
 97        )
 98    }
 99
100    btnStartRecord_Click()
101	{
102        global PID
103        this.StopRecording := 0
104        this.ClearCurrentMacro()
105
106        debug ? debug("Start recording macro")
107
108        ; Disable controls while recording keys.
109        this.SetControls(0)
110        this.btnStopRecord.Enabled  := 1
111        this.btnStartRecord.Enabled := 0
112
113        Delay := this.chkDelay.Checked
114        Click := this.chkMouse.Checked
115        location := this.chkCoords.Checked
116
117        ; load the script to monitor key strokes.
118        AhkRecorder.ahkDll(A_ScriptDir . "\res\ahk\recorder.ahk")
119        AhkRecorder.ahkAssign("delay", (Delay ? "1" : "0"))
120        AhkRecorder.ahkAssign("mouseClicks", (Click ? "1" : "0"))
121        AhkRecorder.ahkAssign("location", (location ? "1" : "0"))
122        AhkRecorder.ahkAssign("PID", PID)
123
124        While (!AhkRecorder.ahkReady()) ;wait for the script to be ready
125            Sleep 10
126
127	}
128
129
130    btnStopRecord_Click()
131    {
132        AhkRecorder.ahkTerminate()
133        initial := 0
134
135        debug ? debug("Stop recording macro")
136        this.StopRecording := 1
137        ; Enable controls
138        this.SetControls(1)
139        this.btnStopRecord.Enabled  := 0
140        this.btnStartRecord.Enabled := 1
141        this.UpdateMacro()
142    }
143
144    SetControls(Enabled)
145    {
146        this.currentMacro.Enabled   := Enabled
147        this.macroList.Enabled      := Enabled
148        this.btnOK.Enabled          := Enabled
149        this.btnAdd.Enabled         := Enabled
150        this.btnDelete.Enabled      := Enabled
151        this.chkDelay.Enabled       := Enabled
152        this.chkMouse.Enabled       := Enabled
153        this.chkCoords.Enabled      := Enabled
154    }
155
156    btnCancel_Click()
157    {
158        debug ? debug("Canceled macro manager")
159        this.PreClose()
160        this.Hide()
161    }
162
163	btnAdd_Click(saveRow = 0)
164	{
165        debug ? debug("Added macro")
166        Loop ; Create a macro with a unique name.
167        {
168            macroName := "Macro" . A_Index
169            if (!xml.Exist("macro", macroName))
170                break
171        }
172		this.macroList.Items.Add("Select", macroName)
173        this.macroList.Items.Modify(this.macroList.Items.Count, "vis")
174        xml.AddMacro(macroName, "")
175
176        ; Make the name editable right away.
177        ControlFocus, SysListView321, A
178        ControlSend, SysListView321, {End}, A
179        ControlSend, SysListView321, {F2}, A
180
181        ; Save current macro for possible use.
182        if (saveRow)
183            this.selectedRow := this.macroList.FocusedIndex
184	}
185
186    btnDelete_Click()
187    {
188        selectedRow := this.macroList.FocusedIndex
189        if (!text := this.macroList.Items[selectedRow][1])
190            return
191        MsgBox, 52, , % "Are you sure you want to delete:`n" . text
192        IfMsgBox, No
193            return
194        debug ? debug("Deleted macro: " . text)
195        this.macroList.Items.Delete(selectedRow)
196        this.ClearCurrentMacro()
197        xml.Delete("macros", text)
198    }
199
200    currentMacro_ContextMenu()
201    {
202        if (this.macroList.FocusedIndex && this.currentMacro.Enabled) ;Also works if other controls like the button were focused before.
203        {
204            selectedRow := this.currentMacro.FocusedIndex
205            ControlGet, pressedKeys, List, , % this.currentMacro.ClassNN, A ; Get all the keys from the listbox
206            StringSplit, text,pressedKeys, `n
207
208            if (InStr(text%selectedRow%, "Sleep"))
209            {
210                Menu, Macro, Enable, Edit
211                GuiControl, -ReadOnly, % this.currentMacro.ClassNN
212            }
213            else
214                Menu, Macro, Disable, Edit
215            Menu, Macro, Show
216        }
217    }
218
219    macroList_ContextMenu()
220    {
221        if (this.macroList.FocusedIndex && this.macroList.Enabled)
222            Menu, MacroName, Show
223    }
224
225    MacroName(Index)
226    {
227        ControlGet, macros, List, , % this.macroList.ClassNN, A ; Get all the keys from the listbox
228        StringSplit, macroName, macros, `n
229        return macroName%Index%
230    }
231
232    macroList_ItemFocused(RowIndex)
233    {
234        macroName := this.MacroName(RowIndex)
235
236        if (macroName = this.oldMacroName)
237            return
238        else if macroName is number
239            return
240
241        this.oldMacroName := macroName
242        this.LoadMacro(macroName) ; Update ListView to show keys in macro
243        debug ? debug("Loaded macro: " . macroName)
244    }
245
246
247    macroList_EditingStart(RowIndex)
248    {
249        this.savedText := this.macroList.Items[RowIndex][1]
250    }
251
252    macroList_EditingEnd(RowIndex)
253    {
254        text := this.macroList.Items[RowIndex][1]
255        firstChar := SubStr(text, 1, 1)
256
257        ; Make sure name is fine
258        if text is not alnum
259        {
260            MsgBox, 48, , Only letters and numbers allowed.
261            this.macroList.Items[RowIndex][1] := this.savedText
262        }
263        else if (!text) ; Make sure text isn't blank
264            this.macroList.Items[RowIndex][1] := this.savedText
265        else if firstChar is not Alpha
266        {
267            MsgBox, 48, , Macro names must start with a letter.
268            this.macroList.Items[RowIndex][1] := this.savedText
269        }
270        else if (text = this.savedText)
271            return
272        else if (xml.Exist("macro", text)) ; Check to make sure we don't have duplicate macros.
273        {
274            MsgBox, 48, ,Duplicate names are not allowed.
275            this.macroList.Items[RowIndex][1] := this.savedText
276        }
277        else
278        {
279            xml.Rename("macro", this.savedText, text)
280            debug ? debug("Renamed macro: " . this.savedText . " to " . text)
281            ; xml.Save(A_ScriptDir, xml.Get("name")) ; Save xml file.
282        }
283    }
284
285    currentMacro_EditingStart(RowIndex)
286    {
287        selectedRow := this.currentMacro.FocusedIndex
288        ControlGet, pressedKeys, List, , % this.currentMacro.ClassNN, A ; Get all the keys from the listbox
289        StringSplit, text,pressedKeys, `n
290        text := text%selectedRow%
291
292        if (!InStr(text, "Sleep"))
293        {
294            GuiControl, +ReadOnly, % this.currentMacro.ClassNN
295            return
296        }
297        this.savedDelay := text
298        Send % Trim(RegExReplace(text, "Sleep??,[\s]*?")) . "^+{Left}"
299    }
300
301    currentMacro_EditingEnd(RowIndex)
302    {
303        ControlGet, pressedKeys, List, , % this.currentMacro.ClassNN, A ; Get all the keys from the listbox
304        StringSplit, text, pressedKeys, `n
305        text := text%RowIndex%
306
307        if (!text)
308            this.currentMacro.Items.Modify(RowIndex, "", this.savedDelay)
309        else if text is not number
310            this.currentMacro.Items.Modify(RowIndex, "", this.savedDelay)
311        else
312            this.currentMacro.Items.Modify(RowIndex, "", "Sleep, " . text)
313
314    }
315
316    ClearCurrentMacro()
317    {
318        Loop % this.currentMacro.Items.Count
319            this.currentMacro.Items.Delete(1)
320    }
321
322    LoadMacro(macroName)
323    {
324
325        if (!macroName)
326            return
327        debug ? debug("Loading " . macroName . " in macro manager")
328        this.ClearCurrentMacro()
329        value := xml.Get("macro", macroName, "value")
330
331        StringReplace, value, value, ``n, `n, all
332        Loop, Parse, value, `n
333            this.currentMacro.Items.Add("", A_LoopField) ; add contents of macro to listview.
334
335        this.btnStartRecord.Enable()
336
337    }
338
339    Load(name = "", new = 0)
340    {
341        Loop % this.macroList.Items.Count
342            this.macroList.Items.Delete(1)
343        debug ? debug("Loading macro manager")
344        macros := xml.List("macros", "|")
345        Loop, Parse, macros, |
346            if (Trim(A_LoopField, "`n`r "))
347                this.macroList.Items.Add("", A_LoopField) ; Add each macro to the listview.
348
349        this.Show()
350
351        if (name)
352        {
353            ControlGet, macros, List, , % this.macroList.ClassNN, A ; Get all the keys from the listbox
354            StringSplit, macroName, macros, `n
355            Loop % macroName0
356                if (name = macroName%A_Index%)
357                    index := A_Index
358
359            ControlFocus, % this.macroList.ClassNN, A
360            this.macroList.Items.Modify(index, "Focus")
361            this.macroList.Items.Modify(index, "Select")
362        }
363        if (new)
364            this.btnAdd_Click(1)
365    }
366
367    UpdateMacro()
368    {
369        if (!this.macroList.FocusedIndex)
370            return
371        ControlGet, pressedKeys, List, , SysListView322, A ; Get all the keys from the listbox
372        StringReplace, pressedKeys, pressedKeys, `n, ``n, All ; Changes newlines to `n so it can be stored in xml
373        selectedRow := this.macroList.FocusedIndex
374        macroName := this.macroList.Items[selectedRow][1]
375        debug ? debug("Updated macro: " . macroName)
376        xml.AddMacro(macroName, pressedKeys) ; Add the macro to xml.
377    }
378
379    ;Called when the window was destroyed (e.g. closed here)
380	PreClose()
381	{
382        this.btnStopRecord_Click()
383        this.ClearCurrentMacro()
384
385        xml := new Xml(currentXml)
386        this.oldMacroName := "", this.selectedRow := 0
387        this.gui.Enabled := true
388	}
389}
390
391EditName:
392    Send, {F2}
393return
394
395DeleteName:
396    gui.Macro.btnDelete_Click()
397return
398
399Edit:
400    Send, {F2}
401return
402
403Delete:
404    selectedRow := gui.Macro.currentMacro.FocusedIndex
405    gui.Macro.currentMacro.Items.Delete(selectedRow)
406return
407
408InsertDelay:
409    selectedRow := gui.Macro.currentMacro.FocusedIndex + 1
410    if (!selectedRow)
411        selectedRow := 1
412    gui.Macro.currentMacro.Items.Insert(selectedRow, "", "Sleep, 100")
413return
414
415MouseEvent:
416    selectedRow := gui.Macro.currentMacro.FocusedIndex + 1
417
418    if (A_ThisMenu = "Wheel")
419    {
420        if (A_ThisMenuItem = "Forward")
421            event := "{" . A_ThisMenu . "Up}"
422        else if (A_ThisMenuItem = "backwards")
423            event := "{" . A_ThisMenu . "Down}"
424    }
425    else if (A_ThisMenuItem = "click")
426    {
427        event := "{" . A_ThisMenu . " Down}"
428        gui.Macro.currentMacro.Items.Insert(selectedRow, "", event)
429
430        event := "{" . A_ThisMenu . " Up}"
431        gui.Macro.currentMacro.Items.Insert(selectedRow + 1, "", event)
432        return
433    }
434    else
435        event := "{" . A_ThisMenu . " " . A_ThisMenuItem . "}"
436
437    gui.Macro.currentMacro.Items.Insert(selectedRow, "", event)
438    gui.UpdateMacro()
439return