SetBatchLines, -1 ; just temporary, to do all Auto-execute as fast as possible ;===Description========================================================================= /* RADIAL MENU v2.1 beta (50x50 buttons) by Learning one AHK forum location: http://www.autohotkey.com/forum/viewtopic.php?p=308352#308352 Draws radial menu when you press & hold RButton. Touch items with mouse to select them. Release RButton to hide menu. After each selection, mouse will bounce back to center. You can easily select multiple items at once, just with one mouse click! When I was writing this script, my goals were (sorted by priority): 1. minimize mouse clicks 2. minimize mouse movements 3. minimize eye movements 4. support longer item names than in RADIAL MENU v1 5. not too big, practical, and nice looking menu 6. preserve normal RButton click function 7. write script in tidy, neat style to ease studying and modifying job for all members of AHK community 8. add some special effects HOW DOES IT WORK? It simply draws 8 carefully positioned & shaped GUIs. See comments in script. IMPORTANT: Menu items are identified by GUI's title, not by item's text. As GUI's titles are Item1, Item2 etc., we can say that items are identified by position. I was using high GUI numbers, so you can easily implant Radial menu in your script. SOME THOUGHTS: Don't think that 8 items are the limit of this menu! One item can be submenu that will open new radial menu! Or, selecting one "special" item may also have effect like pressing modyfiers on you keyboard (Ctrl, Alt, etc.)! There are almost no limits! Such "special" items may have different color or may be slightly transparent. Also try to create context sensitive radial menu (menu items are different for different active windows). That's what I did (my private version). Add icons instead of item's text. Change item's background picture (try to use 70x70 images). Add some sounds. Create different menu build effect. There are plenty of "make-up" and functional possibilities. LICENCE: Free for non-commercial use. For commercial use, e-mail me please. If you will use Radial menu in your free software, mention author's name and contact. Author: Boris Mudrinic (Learning one on AHK forum) Contact: boris-mudrinic@net.hr HOTKEYS: RButton ; Press & hold to show menu. Touch items with mouse to select them. Release RButton to hide menu. Escape ; ExitApp Pause ; Pauses the script's current thread and suspends RButton Hotkey, but not Escape Hotkey! ITEM NAMES AND ACTIONS Item actions are Run command parameters! If you want to execute something more complicated than just Run..., you can: 1. leave Item _Action blank and edit "complicated" action deeper in GetSelectedItem subroutine OR 2. just run (by touching menu button of course) another script that does something more complicated CODE STRUCTURE: Settings Auto-execute Hotkey Subroutines GetSelectedItem RadialMenuClose MutualActions My standard ExitApp and Suspend+Pause hotkeys */ ;===Basic settings==================================================================== TotalButtons = 8 ; Total number of buttons in menu (8 max!) ButtonBack = Button2 50x50v2.png ; Button's background (in %A_scriptdir%) ; Item names and actions ; Item actions are Run command parameters! For item names use `n if you need. Item1_Name = Explorer Item1_Action = %A_WinDir%\explorer.exe Item2_Name = NotePad Item2_Action = notepad Item3_Name = Calc Item3_Action = %A_WinDir%\system32\calc.exe Item4_Name = About Item4_Action = Item5_Name = Item5_Action = Item6_Name = Item6_Action = Item7_Name = Item7_Action = Item8_Name = Item8_Action = ;You can change button's action in GetSelectedItem subroutine ;===Advanced settings================================================================= ;Button's icons (in %A_scriptdir%) ; Use .png format! Icon1 = Icon2 = Icon3 = Icon4 = Icon5 = monitor.png Icon6 = Icon7 = Icon8 = TextSize = 7 ; Item's text size Once when you get used to your radial menu, you will remember item's positions, and text size won't be so important to you. So you will select items by position in your mind, not by reading item's text. TextColor = Navy ; Item's text color Font = Arial ; Item's font BuildDelay = 190 ; menu will start to show itself after %BuildDelay% miliseconds. To show it instantly, set 0. This delay gives you opportunity to send normal RButton click without annoying menu showing. THE BEST THING TO DO is to change hotkey to XButton1 or XButton1 (if you have them - I don't) and use BuildDelay = 0. MButton is also good idea. BuildEffect = 30 ; menu items will show themself, one by one, in interval of %BuildEffect% ms. To show them all instantly, set 0. ItemBounce = 1 ; 1 means: items will bounce when you select them. 0 means: items will not bounce. SoundOnSelect = 1 ; 1 means: play sound when item is selected. 0 means: don't play sound. Of course, you can change sound... ; SoundOnShow ; Play with effects: you can easily add this by slightly modifying script... ; SoundOnDestroy Color = Black ; this is alternative background color, if script can't load picture (button picture). ;===Auto-execute====================================================================== IfNotExist, %A_scriptdir%\%ButtonBack% { URLDownloadToFile, http://www.autohotkey.net/~Learning one/Radial Menu/%ButtonBack%, %A_scriptdir%\%ButtonBack% Sleep, 500 } IfNotExist, %A_scriptdir%\monitor.png { URLDownloadToFile, http://www.autohotkey.net/~Learning one/Radial Menu/monitor.png, %A_scriptdir%\monitor.png Sleep, 500 } StringTrimRight, Sname, A_ScriptName, 4 Menu, Tray, Tip, %Sname% if TotalButtons = Auto Loop, 9 { if Item%A_Index%_Name = { TotalButtons := A_Index - 1 Break } } ;===Set button's background, altenative background and font=== Loop, %TotalButtons% { Gui 9%A_Index%:Add, Picture, x-1 y-2 w52 h52 , %A_scriptdir%\%ButtonBack% Gui 9%A_Index%:Font, s%TextSize%, %Font% Gui 9%A_Index%: Color, %Color% } ;======Set icons====== Loop, %TotalButtons% { CurrentIcon := Icon%A_Index% if (CurrentIcon = "") Continue Gui 9%A_Index%:Add, Picture, x3 y3 w44 h44 BackgroundTrans, %A_scriptdir%\%CurrentIcon% } ;======Set item names====== ; text has precedence over icons! ; Play with effects: Remove BackgroundTrans in GuiTextOptions and set Color = 757500 (GUI's color) GuiTextOptions = x6 y6 w39 h38 c%TextColor% BackgroundTrans ; principle Loop, %TotalButtons% { ;if A_index = 7 ; exception ;Gui 97:Add, Text, x7 y14 w56 h50 c%TextColor% center BackgroundTrans , %Item7% ;else ; principle CurrentItem := Item%A_Index%_Name Gui 9%A_Index%:Add, Text, %GuiTextOptions% , %CurrentItem% ; Build items } SetBatchLines, 10ms ; default ;===Hotkey============================================================================== RButton:: ; Press & hold to show menu. Touch items with mouse to select them. Release RButton to hide menu. THE BEST THING TO DO is to change hotkey to XButton1 or XButton1 if you have them ( I don't :( ) PressedTime = 0 CoordMode, mouse, Screen MouseGetPos, mx1, my1 SetTimer, RadialMenuClose, 35 Loop, %TotalButtons% ; Draw items (GUIs) at exact positions --> 50x50 buttons { if A_index = 1 { RMx := mx1-25 RMy := my1-95 if BuildDelay { Sleep , %BuildDelay% ; menu will start to show itself after %BuildDelay% ms if not (GetKeyState("RButton","p")) Return } } Else if A_index = 2 { RMx := mx1+25 RMy := my1-75 } Else if A_index = 3 { RMx := mx1+45 RMy := my1-25 } Else if A_index = 4 { RMx := mx1+25 RMy := my1+25 } Else if A_index = 5 { RMx := mx1-25 RMy := my1+45 } Else if A_index = 6 { RMx := mx1-75 RMy := my1+25 } Else if A_index = 7 { RMx := mx1-95 RMy := my1-25 } Else if A_index = 8 { RMx := mx1-75 RMy := my1-75 } Gui 9%A_Index%: +AlwaysOnTop +ToolWindow -caption +LastFound WinSet, Region, 1-0 W50 H50 R12-12 Gui 9%A_Index%: Show, x%RMx% y%RMy% h50 w50, Item%A_Index% WinSet, TransColor, silver 255, Item%A_Index% Sleep, %BuildEffect% if not (GetKeyState("RButton","p")) Return } SetTimer, GetSelectedItem, 15 Return ;===Subroutines========================================================================= ;===Change button's action here=== GetSelectedItem: ; menu items are identified by GUI's title! MouseGetPos, , , WinID WinGetTitle, WinTitle, ahk_id %WinID% if WinTitle contains Item ; This is just example. Build your own menu! { CoordMode, mouse, Screen MouseMove, %mx1%, %my1% if WinTitle = Item1 { if not (Item1_Action = "") Run, %Item1_Action% Else { Sleep, 0 ; leave Item _Action blank and edit "complicated" action here } Gosub, MutualActions Return } Else if WinTitle = Item2 { if not (Item2_Action = "") Run, %Item2_Action% Else { Sleep, 0 ; leave Item _Action blank and edit "complicated" action here } Gosub, MutualActions Return } Else if WinTitle = Item3 { if not (Item3_Action = "") Run, %Item3_Action% Else { Sleep, 0 ; leave Item _Action blank and edit "complicated" action here } Gosub, MutualActions Return } Else if WinTitle = Item4 { if not (Item4_Action = "") Run, %Item4_Action% Else ; "complicated" action example { SoundOnSelect = 0 ; avoids double beep Gosub, MutualActions MsgBox, 64, About, Title:%A_Tab%Radial menu v2`nAuthor:%A_Tab%Boris Mudrinic (Learning one on AHK forum)`nContact:%A_Tab%boris-mudrinic@net.hr`n`nLicence:`nFree for non-commercial use.`nFor commercial use, e-mail me please.`n`nIf you will use Radial menu in your free software,`nmention author's name and contact. SoundOnSelect = 1 } Return } Else if WinTitle = Item5 { if not (Item5_Action = "") Run, %Item5_Action% Else { Sleep, 0 ; leave Item _Action blank and edit "complicated" action here } Gosub, MutualActions Return } Else if WinTitle = Item6 { if not (Item6_Action = "") Run, %Item6_Action% Else { Sleep, 0 ; leave Item _Action blank and edit "complicated" action here } Gosub, MutualActions Return } Else if WinTitle = Item7 { if not (Item7_Action = "") Run, %Item7_Action% Else { Sleep, 0 ; leave Item _Action blank and edit "complicated" action here } Gosub, MutualActions Return } Else if WinTitle = Item8 { if not (Item8_Action = "") Run, %Item8_Action% Else { Sleep, 0 ; leave Item _Action blank and edit "complicated" action here } Gosub, MutualActions Return } } Return RadialMenuClose: PressedTime++ if not (GetKeyState("RButton","p")) { if (PressedTime < 7) ; if user holded RButton for less than 210ms ... SendInput, {RButton} ; ... script will send normal RButton click SetTimer, GetSelectedItem, off SetTimer, RadialMenuClose, off ; Fade out effect InitialTrans = 255 Loop, 17 { Loop, 8 WinSet, Transparent, %InitialTrans%, Item%A_Index% InitialTrans -= 15 Sleep, 25 ; change fade out speed if you wish } Loop, %TotalButtons% Gui 9%A_index%: Hide Return } Return MutualActions: Critical if SoundOnSelect = 1 SoundPlay, *-1 if not (ItemBounce = 1) Return ;===Bounce effect=== WinGetPos, XBounce, YBounce,,, %WinTitle% SetTimer, RadialMenuClose, off SetTimer, GetSelectedItem, off SetWinDelay, 5 ; bounce speed if WinTitle = Item1 { Loop, 8 { if A_Index <= 4 YBounce -= 4 ; bounce lenght Else YBounce += 4 WinMove, %WinTitle%, , %XBounce%, %YBounce% } } else if WinTitle = Item2 { Loop, 8 { if A_Index <= 4 { XBounce += 4 YBounce -= 4 } Else { XBounce -= 4 YBounce += 4 } WinMove, %WinTitle%, , %XBounce%, %YBounce% } } else if WinTitle = Item3 { Loop, 8 { if A_Index <= 4 XBounce += 4 Else XBounce -= 4 WinMove, %WinTitle%, , %XBounce%, %YBounce% } } else if WinTitle = Item4 { Loop, 8 { if A_Index <= 4 { XBounce += 4 YBounce += 4 } Else { XBounce -= 4 YBounce -= 4 } WinMove, %WinTitle%, , %XBounce%, %YBounce% } } else if WinTitle = Item5 { Loop, 8 { if A_Index <= 4 YBounce += 4 Else YBounce -= 4 WinMove, %WinTitle%, , %XBounce%, %YBounce% } } else if WinTitle = Item6 { Loop, 8 { if A_Index <= 4 { XBounce -= 4 YBounce += 4 } Else { XBounce += 4 YBounce -= 4 } WinMove, %WinTitle%, , %XBounce%, %YBounce% } } else if WinTitle = Item7 { Loop, 8 { if A_Index <= 4 XBounce -= 4 Else XBounce += 4 WinMove, %WinTitle%, , %XBounce%, %YBounce% } } else if WinTitle = Item8 { Loop, 8 { if A_Index <= 4 { XBounce -= 4 YBounce -= 4 } Else { XBounce += 4 YBounce += 4 } WinMove, %WinTitle%, , %XBounce%, %YBounce% } } SetWinDelay, 100 ; default SetTimer, GetSelectedItem, on SetTimer, RadialMenuClose, on Return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ExitApp Pause:: Suspend Pause,,1 return Escape:: Suspend ExitApp Return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;