9Buttons & 27possible actions (3 per button) left, right & middle click on core radial menu.
More actions can be added to buttons by means of adding submenu's to the corresponding buttons as shown in the included button submenu examples, where middle clicking on Center and Bottom most buttons will spawn a button submenu. clicking on a button with out a handler function will result in a function for that button being created and copied to clipboard for ease of use IF DEBUGMODE is set to true.
All Core Radial Menu Actions correlate to running a dynamic function with this naming scheme, <MouseButton>_<ButtonName>(), Clicking on a button that has no corresponding action attached will copy a function to the clipboard that corresponds to that Button & Corresponding Left/Right/MiddleMouse button press that was registered. SubMenu Buttons are slightly different, buttons execute dynamic functions that share the same name as the button text,see examples...
HOLD & RELEASE Ctrl to spawn main radial menu.
Code: Select all
;LRM_RadialMenu Template.ahk
;9Buttons & 27possible actions (3 per button) left, right & middle click.
;More action can be added to buttons by means of adding submenu's to the corresponding buttons as shown in the included button submenu examples,
; where middle clicking on Center and Bottom most buttons will spawn a button submenu.
;clicking on a button with out a handler function will result in a function for that button being created and copied to clipboard for ease of use.
/*
;List of button names
ButtonTop
ButtonLU
ButtonL
ButtonLD
ButtonCenter
ButtonRU
ButtonR
ButtonRD
ButtonBottom
-->Any button that has no handlerFunction will generate a function for a mouse button press on a corresponding button,i.e left click on a center button &
a function to the one below will be copied to clipboard for ease of use... so just click on a button, paste the created function for the gui button & the mouse button pressed.
L_ButtonCenter(){
;action
}
--------------
Create function with Prefix with L_,M_,R_ followed by any of the above button names to have a function that handles the corresponding Gui Button & mouse button.
examples:
--------------
R_ButtonBottom(){
MsgBox, 0x40040, %A_ScriptName%, Right Button Bottom function handler example
}
L_ButtonBottom(){
MsgBox, 0x40040, %A_ScriptName%, Left Button Bottom function handler example
}
M_ButtonBottom(){
MsgBox, 0x40040, %A_ScriptName%, Middle Button Bottom function handler example
}
--------------
The button submenu, by default limited to activation on Middle Mouse Button press on Central Radial Menu button is handled by functions that have the same name as the assigned button name.
The button submenu is created by GuiCreateDynamicButtonStack() which creates a button stack dynamically using specified button names as defined as parameters.
--------------
a(){
MsgBox, 0x40040, %A_ScriptName%, submenu function handler example
}
*/
debugMode := True ;if enabled automatic function generation & tooltips on buttons with no handler functions will be enabled.
~Ctrl::
If ( IsHotkeyPressedHeld() = "HELD" ){
LRRadialMenuGuiCreate() ;destroying & recreating gui every time as hiding & restoring it seems to be inconsistent
SetTimer, CheckCursorPos, 100
Return
}Else, Gosub, GuiClose
Return
LRRadialMenuGuiCreate(ButtonTopText := "TL / TM / TR", ButtonLUText := "LUL / LUM / LUR", ButtonLText := "LL / LM / LR", ButtonLDText := "LDL / LDM / LDR", ButtonCenterText := "LCL / LCM / RCR", ButtonRUText := "RUL / RUM / RUR", ButtonRText := "RL / RM / RR", ButtonRDText := "RDL / RDM / RDR", ButtonBottomText := "BL / BM / BR"){ ;params are button texts
Global
Gosub, GuiClose
CoordMode, Mouse, Screen
MouseGetPos, guiX, guiY
Gui +HwndLRRadialMenuGuiHWND
;-------------------------------------------------------------------
Gui, Color, Green ;'green screen' for transparency
Gui, +ToolWindow -Caption +AlwaysOnTop +LastFound
Gui, Font, s15 cBlue, Terminal
;-------------------------------------------------------------------
;-theme removes the border around the edges of buttons to make them look flat
;-------------------------------------------------------------------
Gui, Add, Button,-theme vButtonTop gLeftClick x300 y0 w200 h50, %ButtonTopText%
;-------------------------------------------------------------------
Gui, Add, Button,-theme vButtonLU gLeftClick x0 y10 w250 h50, %ButtonLUText%
Gui, Add, Button,-theme vButtonL gLeftClick x0 y75 w225 h50, %ButtonLText%
Gui, Add, Button,-theme vButtonLD gLeftClick x0 y140 w250 h50, %ButtonLDText%
;-------------------------------------------------------------------
Gui, Add, Button,-theme vButtonCenter gLeftClick x250 y60 w300 h80, %ButtonCenterText%
;-------------------------------------------------------------------
Gui, Add, Button,-theme vButtonRU gLeftClick x550 y10 w250 h50, %ButtonRUText%
Gui, Add, Button,-theme vButtonR gLeftClick x575 y75 w225 h50, %ButtonRText%
Gui, Add, Button,-theme vButtonRD gLeftClick x550 y140 w250 h50, %ButtonRDText%
;-------------------------------------------------------------------
Gui, Add, Button,-theme vButtonBottom gLeftClick x300 y150 w200 h50, %ButtonBottomText%
;-------------------------------------------------------------------
guiX -= 400 , guiY -= 100
;create gui offscreen to hide flash
yOffscreen := 100000 ;way off screen
Gui, Show, x%guiX% y%yOffscreen% w800 h200 NA, LRRadialMenuGui ;create gui offscreen
;WinSet, TransColor, 000000, LRRadialMenuGui
WinSet, TransColor, Green, LRRadialMenuGui
Gui, Show, x%guiX% y%guiY% w800 h200, LRRadialMenuGui ;redraw transparency enabled gui onscreen
;-------------------------------------------------------------------
}
;==================================================================================================================================
;======================= Left/Right/Middle mouse buttton press handlers & ButtonSubmenu button press handlers =====================
;==================================================================================================================================
LeftClick:
GuiControlGet, var,, % A_GuiControl
If IsFunc("L_" . A_GuiControl)
L_%A_GuiControl%()
;generate function handler to perform actions on button press, and copy to clipboard.
Else If debugMode{
ToolTip, Left button clicked! `n %var% `n %A_GuiControl%
Clipboard = L_%A_GuiControl%(){`n;actions here`n}
}
return
;==================================================================================================================================
GuiContextMenu: ;detects any right clicks anywhere in gui
GuiControlGet, var,, % A_GuiControl
If IsFunc("R_" . A_GuiControl)
R_%A_GuiControl%()
;generate function handler to perform actions on button press, and copy to clipboard.
Else If debugMode{
ToolTip, Right button clicked! `n %var% `n %A_GuiControl%
Clipboard = L_%A_GuiControl%(){`n;actions here`n}
}
Return
;==================================================================================================================================
;Middle Mouse button
#IfWinActive, LRRadialMenuGui
MButton::
MouseGetPos, OutputVarX, OutputVarY, OutputVarWin, OutputVarControl
IfNotInString, OutputVarControl, Button ;if not a button control ignore middle mouse button
return
ControlGetText, OutputVar, %OutputVarControl%
activeButtonVar := GetValuePair(OutputVarControl, "Button1|ButtonTop", "Button2|ButtonLU", "Button3|ButtonL", "Button4|ButtonLD", "Button5|ButtonCenter", "Button6|ButtonRU", "Button7|ButtonR", "Button8|ButtonRD", "Button9|ButtonBottom")
;middle mouse button on center button only
IfEqual, activeButtonVar, ButtonCenter
GuiCreateDynamicButtonStack("a", "b", "c", "Hello", "World")
Else IfEqual, activeButtonVar, ButtonBottom
GuiCreateDynamicButtonStack("1", "2", "3", "last button...")
Else
Gui, 2:Destroy
;------------------------------------------------
If IsFunc("M_" . activeButtonVar)
M_%activeButtonVar%()
Else If debugMode{
ToolTip, MMButton clicked! `n %OutputVar% `n %OutputVarControl% `n %activeButtonVar%, % OutputVarX + 400
Clipboard = M_%activeButtonVar%(){`n;actions here`n}
}
;------------------------------------------------
Return
#IfWinActive
;==================================================================================================================================
;runs when button submenu is run
OnButtonSubmenu(pressedButton){
Global
MouseGetPos, guiX, guiY
If IsFunc(pressedButton)
%pressedButton%()
Else If debugMode{
ToolTip, MMButton clicked! `n %OutputVar% `n %OutputVarControl% `n %activeButtonVar% `n %pressedButton%, % guiX + 400
Clipboard = %pressedButton%(){`n;actions here`n}
}
}
;==================================================================================================================================
CheckCursorPos:
If debugMode
tooltip % "IsMouseOverClientArea: " IsMouseOverClientArea(LRRadialMenuGuiHWND) " ButtonArea:" IsMouseOverClientArea(ButtonStackGuiHWND),0,0,2
If (!IsMouseOverClientArea(LRRadialMenuGuiHWND) AND !IsMouseOverClientArea(ButtonStackGuiHWND)) ;so that when mouse leaves radial menu area, it automatically closes
Gosub, GuiClose
If (WinExist("ahk_id " ButtonStackGuiHWND) AND !IsMouseOverClientArea(ButtonStackGuiHWND)) ;so that when mouse leaves button menu area, it automatically closes
Gosub, GuiClose2
Return
;==================================================================================================================================
GuiEscape:
GuiClose:
SetTimer, CheckCursorPos, off
Gui, Destroy
Gui, 2:Destroy
ToolTip
Return
GuiClose2:
Gui, 2:Destroy
ToolTip
Return
IsHotkeyPressedHeld(timeoutInSec := 0.5){
thisHotkey := InStr(A_ThisHotkey,"~") ? LTrim(A_ThisHotkey,"~") : A_ThisHotkey
KeyWait, % thisHotkey
IfGreater, A_TimeSinceThisHotkey, % timeoutInSec * 1000 ;was pressed for extended period
Return % "HELD"
Else
Return % "PRESSED"
}
;x := 3
;MsgBox % GetValuePair(x, "3|three", "4|four", "three|3")
;given a, b & c where b & c are a pair delimited with | as in "b|c", if a = b then a = c,
;this function simply condenses what would other wise require a rather extensive ternary for a large number of value pair's.
GetValuePair(var, params*) {
for index,param in params{
paramArray := StrSplit(param, "|")
match := ( var = paramArray[1] ? paramArray[2] : match )
}
Return match
}
;sub menu
GuiCreateDynamicButtonStack(params*){
Static
Global ButtonStackGuiHWND
IfWinExist, ButtonStackGui
Gui, 2:Destroy
CoordMode, Mouse, Screen
Gui 2:+HwndButtonStackGuiHWND
Gui, 2:Color, Green
Gui, 2:+ToolWindow -Caption +AlwaysOnTop +LastFound
Gui , 2:font, s8 bold, Terminal
;-theme removes the border around the edges of buttons to make them look flat
for index,param in params
Gui, 2:Add, Button, w150 h25 vButton%index% gSubmit, %param% ;& prefix to underline string
Gui, 2:-caption
;create gui offscreen to hide flash
yOffscreen := 100000 ;way off screen
Gui, 2:Show ,AutoSize x0 y%yOffscreen% NA, ButtonStackGui ;create gui offscreen
WinSet, TransColor, Green, ButtonStackGui
MouseGetPos, guiX, guiY
guiX -= 60, guiY -= 20
Gui, 2:Show ,AutoSize x%guiX% y%guiY% NA, ButtonStackGui ;redraw transparency enabled gui onscreen
Return
Submit:
Count++
GuiControlGet, var,, % A_GuiControl
GuiControl,, %A_GuiControl%, %var% ;change button text
If debugMode
ToolTip, %A_GuiControl% - %var%
OnButtonSubmenu(var)
Gui, 2:Destroy
Return
}
IsMouseOverClientArea(hWnd, nOption=0) {
;[Descriptions]
; Checks whether the current mouse cursor is within the client area of a specified window.
; It can check even if the window is inactive or overlapped by other windows.
;[Parameters]
; hWnd: the window handle of the subject window.
; nOption:
; 0: the normal mode.
; 1: if the window is not active, the function returns an empty value.
;[Return Value]
; If the window does not exist, it returns an empty value.
; Returns 1 if the mouse cursor is over the client area of the specified window; otherwise, it returns 0.
; AutoHotkey Basic users should uncomment this line.
;ptr := ptr ? "ptr" : "uint"
; Check if the window exists.
if !WinExist("ahk_id " hWnd)
Return
; if the option is set to 1, check if the window is active.
if (nOption = 1) && !WinActive("ahk_id " hWnd)
Return
; Retrieve the window position and convert it to the client top-left position in screen coordinate.
VarSetCapacity(pt, 16), NumPut(0, pt, 0), NumPut(0, pt, 4)
DllCall("ClientToScreen", ptr, hwnd, ptr, &pt)
nClientX := NumGet(pt, 0, "int") , nClientY := NumGet(pt, 4, "int")
; Retrieve the size of client area of the window.
VarSetCapacity(rc, 16), DllCall("GetClientRect", ptr, hwnd, ptr, &rc)
nClientW := NumGet(rc, 8, "int") , nClientH := NumGet(rc, 12, "int")
; Retrieve the mouse cursor position in screen coordinates.
; Use the GetCursorPos API function in order not to affect the coord mode of the script.
VarSetCapacity(pos, 8), DllCall("GetCursorPos", ptr, &pos)
nCursorX := NumGet(pos, 0, "int") , nCursorY := NumGet(pos, 4, "int")
; Return True if the cursor is in the client are of the window.
nCursorX := nCursorX - nClientX, nCursorY := nCursorY - nClientY ; Convert it to be client relative
if (nCursorX >= 0) && (nCursorY >= 0) && (nCursorX <= nClientW) && (nCursorY <= nClientH)
Return True
else
Return False
; by A_Samurai 2012/2/16 licence: Public Domain
}
R_ButtonBottom(){
MsgBox, 0x40040, %A_ScriptName%, Right Button Bottom function handler example
}
L_ButtonBottom(){
MsgBox, 0x40040, %A_ScriptName%, Left Button Bottom function handler example
}
M_ButtonBottom(){
; MsgBox, 0x40040, %A_ScriptName%, Middle Button Bottom function handler example
SoundBeep
}
a(){
MsgBox, 0x40040, %A_ScriptName%, submenu function handler example
}
Below are two demo's for the functionality that spawns button submenu's...
Code: Select all
SetTimer, CheckCursorPos, 100
SoundGet, vol
GuiCreateDynamicButtonStack("VOLUME_60", "VOLUME_40", "VOLUME_20", "VOLUME_80", "VOLUME_100","======" . Round(vol) . "======")
Esc::ExitApp
;==================================================================================================================================
CheckCursorPos:
If (WinExist("ahk_id " ButtonStackGuiHWND) AND !IsMouseOverClientArea(ButtonStackGuiHWND)) ;so that when mouse leaves button menu area, it automatically closes
Gosub, GuiClose
Return
;==================================================================================================================================
GuiClose:
SetTimer, CheckCursorPos, off
ExitApp
Return
GuiCreateDynamicButtonStack(params*){
Static
Global ButtonStackGuiHWND
CoordMode, Mouse, Screen
Gui, Color, Green
Gui +HwndButtonStackGuiHWND
Gui, +ToolWindow -Caption +AlwaysOnTop
Gui , font, s10, Terminal
;-theme removes the border around the edges of buttons to make them look flat
for index,param in params
Gui, Add, Button, w150 h25 -theme vButton%index% gSubmit, %param% ;& prefix to underline string
Gui, -caption
;create gui offscreen to hide flash
yOffscreen := 100000 ;way off screen
Gui, Show ,AutoSize x0 y%yOffscreen% NA, ButtonStackGui ;create gui offscreen
WinSet, TransColor, Green, ButtonStackGui
MouseGetPos, guiX, guiY
guiX -= 60, guiY -= 50
Gui, Show ,AutoSize x%guiX% y%guiY% NA, ButtonStackGui ;redraw transparency enabled gui onscreen
Return
Submit:
Count++
GuiControlGet, var,, % A_GuiControl
;GuiControl,, %A_GuiControl%, %var% ;change button text
;ToolTip, %A_GuiControl% - %var%
If IsFunc(var)
%var%() ;call function with button name if it exists
Return
}
IsMouseOverClientArea(hWnd, nOption=0) {
;[Descriptions]
; Checks whether the current mouse cursor is within the client area of a specified window.
; It can check even if the window is inactive or overlapped by other windows.
;[Parameters]
; hWnd: the window handle of the subject window.
; nOption:
; 0: the normal mode.
; 1: if the window is not active, the function returns an empty value.
;[Return Value]
; If the window does not exist, it returns an empty value.
; Returns 1 if the mouse cursor is over the client area of the specified window; otherwise, it returns 0.
; AutoHotkey Basic users should uncomment this line.
;ptr := ptr ? "ptr" : "uint"
; Check if the window exists.
if !WinExist("ahk_id " hWnd)
Return
; if the option is set to 1, check if the window is active.
if (nOption = 1) && !WinActive("ahk_id " hWnd)
Return
; Retrieve the window position and convert it to the client top-left position in screen coordinate.
VarSetCapacity(pt, 16), NumPut(0, pt, 0), NumPut(0, pt, 4)
DllCall("ClientToScreen", ptr, hwnd, ptr, &pt)
nClientX := NumGet(pt, 0, "int") , nClientY := NumGet(pt, 4, "int")
; Retrieve the size of client area of the window.
VarSetCapacity(rc, 16), DllCall("GetClientRect", ptr, hwnd, ptr, &rc)
nClientW := NumGet(rc, 8, "int") , nClientH := NumGet(rc, 12, "int")
; Retrieve the mouse cursor position in screen coordinates.
; Use the GetCursorPos API function in order not to affect the coord mode of the script.
VarSetCapacity(pos, 8), DllCall("GetCursorPos", ptr, &pos)
nCursorX := NumGet(pos, 0, "int") , nCursorY := NumGet(pos, 4, "int")
; Return True if the cursor is in the client are of the window.
nCursorX := nCursorX - nClientX, nCursorY := nCursorY - nClientY ; Convert it to be client relative
if (nCursorX >= 0) && (nCursorY >= 0) && (nCursorX <= nClientW) && (nCursorY <= nClientH)
Return True
else
Return False
; by A_Samurai 2012/2/16 licence: Public Domain
}
VOLUME_100(){
SoundSet, 100
ExitApp
}
VOLUME_80(){
SoundSet, 80
ExitApp
}
VOLUME_60(){
SoundSet, 60
ExitApp
}
VOLUME_40(){
SoundSet, 40
ExitApp
}
VOLUME_20(){
SoundSet, 20
ExitApp
}
Code: Select all
debugMode :=True
SetTimer, CheckCursorPos, 100
GuiCreateDynamicButtonStack("a", "b", "c")
Return
b(){
MsgBox
}
OnButtonSubmenu(pressedButton){
Global
MouseGetPos, guiX, guiY
If IsFunc(pressedButton)
%pressedButton%()
Else If debugMode{
ToolTip, %pressedButton%, % guiX + 400
Clipboard = %pressedButton%(){`n;actions here`n}
}
}
;==================================================================================================================================
CheckCursorPos:
tooltip % "IsMouseOverClientArea: ButtonArea:" IsMouseOverClientArea(ButtonStackGuiHWND),0,0,2
If (WinExist("ahk_id " ButtonStackGuiHWND) AND !IsMouseOverClientArea(ButtonStackGuiHWND)) ;so that when mouse leaves button menu area, it automatically closes
Gosub, GuiClose
Return
;==================================================================================================================================
GuiClose:
SetTimer, CheckCursorPos, off
Gui, 2:Destroy
If debugMode
ExitApp
Return
;sub menu
GuiCreateDynamicButtonStack(params*){
Static
Global ButtonStackGuiHWND
IfWinExist, ButtonStackGui
Gui, 2:Destroy
CoordMode, Mouse, Screen
Gui 2:+HwndButtonStackGuiHWND
Gui, 2:Color, Green
Gui, 2:+ToolWindow -Caption +AlwaysOnTop +LastFound
Gui , 2:font, s8 bold, Terminal
;-theme removes the border around the edges of buttons to make them look flat
for index,param in params
Gui, 2:Add, Button, w150 h25 vButton%index% gSubmit, %param% ;& prefix to underline string
Gui, 2:-caption
;create gui offscreen to hide flash
yOffscreen := 100000 ;way off screen
Gui, 2:Show ,AutoSize x0 y%yOffscreen% NA, ButtonStackGui ;create gui offscreen
WinSet, TransColor, Green, ButtonStackGui
MouseGetPos, guiX, guiY
guiX -= 80, guiY -= 50
Gui, 2:Show ,AutoSize x%guiX% y%guiY% NA, ButtonStackGui ;redraw transparency enabled gui onscreen
Return
Submit:
Count++
GuiControlGet, var,, % A_GuiControl
GuiControl,, %A_GuiControl%, %var% ;change button text
If debugMode
ToolTip, %A_GuiControl% - %var%
OnButtonSubmenu(var)
Gui, 2:Destroy
Return
}
IsMouseOverClientArea(hWnd, nOption=0) {
;[Descriptions]
; Checks whether the current mouse cursor is within the client area of a specified window.
; It can check even if the window is inactive or overlapped by other windows.
;[Parameters]
; hWnd: the window handle of the subject window.
; nOption:
; 0: the normal mode.
; 1: if the window is not active, the function returns an empty value.
;[Return Value]
; If the window does not exist, it returns an empty value.
; Returns 1 if the mouse cursor is over the client area of the specified window; otherwise, it returns 0.
; AutoHotkey Basic users should uncomment this line.
;ptr := ptr ? "ptr" : "uint"
; Check if the window exists.
if !WinExist("ahk_id " hWnd)
Return
; if the option is set to 1, check if the window is active.
if (nOption = 1) && !WinActive("ahk_id " hWnd)
Return
; Retrieve the window position and convert it to the client top-left position in screen coordinate.
VarSetCapacity(pt, 16), NumPut(0, pt, 0), NumPut(0, pt, 4)
DllCall("ClientToScreen", ptr, hwnd, ptr, &pt)
nClientX := NumGet(pt, 0, "int") , nClientY := NumGet(pt, 4, "int")
; Retrieve the size of client area of the window.
VarSetCapacity(rc, 16), DllCall("GetClientRect", ptr, hwnd, ptr, &rc)
nClientW := NumGet(rc, 8, "int") , nClientH := NumGet(rc, 12, "int")
; Retrieve the mouse cursor position in screen coordinates.
; Use the GetCursorPos API function in order not to affect the coord mode of the script.
VarSetCapacity(pos, 8), DllCall("GetCursorPos", ptr, &pos)
nCursorX := NumGet(pos, 0, "int") , nCursorY := NumGet(pos, 4, "int")
; Return True if the cursor is in the client are of the window.
nCursorX := nCursorX - nClientX, nCursorY := nCursorY - nClientY ; Convert it to be client relative
if (nCursorX >= 0) && (nCursorY >= 0) && (nCursorX <= nClientW) && (nCursorY <= nClientH)
Return True
else
Return False
; by A_Samurai 2012/2/16 licence: Public Domain
}