RADIAL MENU scripts - migrated to new forum
Whats the possibility of having a "Sub-Radial Menus" feature?
So you open up your radial, and one of the icons says something like "Program Files"
Then when you hover over it, another Radial is created with the items that fall under that category.
Awesome idea Doyle! I wondered about that myself.
Learning one: Good luck with your new project, I hope you can get back to RM soon. It's an incredible tool!
Has anyone tried using RM to activate hotkeys rather than launch applications?
I'm tinkering with it myself but not having much luck, other than using RM to activate a standalone script that sends the hotkey... seems like a lot of extra work tho.
Computers make it easier to do a lot of
things, but most of the things they make
it easier to do don't need to be done.
--Andy Rooney
--------------------------------------------------
I think your method of launching standalone scripts is probably the only way to do so at the moment, but maybe someone can mod it in, or Learning One may take a look at it when he returns to this project.
Maybe a Labels.ahk #Include(d) with the script would work.
You'd have to define what type of code the button would execute though I guess.
You don't like to launch standalone scripts by selecting RMItem?
You want that selecting RMItem has effect like pressing a hotkey, (when you select it, RM executes specified subroutine)?
Around line 500, in the item selection portion of the script:
if WinTitle contains RMItem ; RMShowHotkey released on item { MouseMove, %mx1%, %my1% ; back to original position Gosub, MutualActions Loop, %TotalButtons% ; determine what to run { if (WinTitle = "RMItem" . A_Index) { CurAction := I%A_Index%Action if (CurAction = "Error" or CurAction = "") Break Else { [color=red]If IsLabel(CurAction) GoSub, %CurAction% Else {[/color] Transform, CurAction, Deref, %CurAction% ; suggestion by Maxmax14 (Thanks!) Run, %CurAction% [color=red]}[/color] Break } } } Gosub, RadialMenuClose ;WinActivate, %OrigWinTitle% }
At the very end of the code:
#Include *i %A_ScriptDir%\UserCommands.txt
UserCommands.txt should be a file in the same directory as RM, and should be formatted as a standard AHK script:
TestLabel: MsgBox, This is a test label from an included file. Return
Just add an item to the menu with the action TestLabel and it will launch on selection.
On another note:
I have several new projects that I am having to see to completion before I can continue my work on the settings front-end (a couple websites to build, and some stuff for work). I do hope to continue work on this soon, but if I find that I cannot return to it before long, I will release what I do have, so that hopefully someone else may complete it and further improve upon Radial Menu!
I'm already using it for about 1 week, and it works perfectly.
There are also some other improvements/changes in RM v3.15.
Although I'm still very busy, I'll try to find some time to prepare RM v3.15 for public release.
Changes log:
- new layout - 6 items in 1. ring, all other rings have slightly reduced radius. After using RM for a longer time, I concluded that this is the best good look/functionality compromise. Number of items in menu is limited to 66 max (4 full rings).
- 2 new .ini keys in [General] section; MenuBackgroundWidth and MenuBackgroundHeight. Determines menu's background Width/Height. If blank or above MenuBackground's (image) resolution, MenuBackground's image resolution applies as Width/Height.
- added new: MenuBackground, ButtonBackground (minor change; just smaller shadow), SoundOnHover(shorter)
- added "Edit MySubroutines" in tray menu
- possibility to execute custom Item's subroutine instead of launching stand-alone script (Hotkey-like behavior). To do this:
1. specify Mysub in item's action
2. create your custom subroutine in \Utilities\MySubroutines.ahk. If you are creating subroutine for Item1, subroutine's label must be Item1. For Item2, Item2 and so on...
- some new small scripts in utilities dir, and other minor changes...
Download: Radial menu v3.15 (16.12.2009.)
"I would like to have submenus, can you do that?"
Yes I can. That's very old idea; see description in my first RM script; Radial menu v1
I know how to do it, I want to do it, but I'm currently still very busy. So, you have to wait...
For now, you can take a look at my Submenus concept
fixed now.
1: Can execute Comands (like our ver. 3.15)
2: Button 1 - 6 are the actually open windows. Like Alt + Tab.
The function ( like alt + tab) looks at the icon path for icons with the program name. So, you have to have icons for every programm that you want put in there.
For the Script function you have to add a field Script at the ITEM(x) - RM setinngs.
---------------------------------------------------------------------------------------------------- ITEMS ---------------------------------------------------------------------------------------------------- [Item1] Name= Action= Script= Icon=lime3.png IconShrink=1 Tooltip= SpecialButtonBack=no background ID= [Item2] Name= Action= Script= Icon=lime3.png IconShrink = 1 Tooltip = SpecialButtonBack =no background ID= [Item3] Name= Action= Script= Icon=lime3.png IconShrink = 1 Tooltip = SpecialButtonBack =no background ID= [Item4] Name= Action= Script= Icon=lime3.png IconShrink = 1 Tooltip = SpecialButtonBack =no background ID= [Item5] Name= Action= Script= Icon=lime3.png IconShrink = 1 Tooltip = SpecialButtonBack =no background ID= [Item6] Name= Action= Script= Icon=lime3.png IconShrink = 1 Tooltip = SpecialButtonBack =no background ID= [Item7] Name=-------Search Action= Script=GoogleSearch Icon=google.png IconShrink = 1 Tooltip =Google Search SpecialButtonBack =no background ID= [Item8] Name=-------Image Action= Script=GoogleImage Icon=google.png IconShrink =1 Tooltip = SpecialButtonBack =no background ID= [Item9] Name= Action= Script=LEGENDAS.TV Icon=Legendas.tv1.png IconShrink = 1 Tooltip =Legendas.TV SpecialButtonBack = no background ID= [Item10] Name= Action= Script=OpenSubtitles Icon=OpenSubtitles.png IconShrink = 1 Tooltip =Fullscreem SpecialButtonBack =no background ID= [Item11] Name= Action= Script=Wikipedia Icon=Wikipedia.png IconShrink = 1 Tooltip = SpecialButtonBack = no background [Item12] Name= Action= Script=IMDB Icon=imdb4.png IconShrink = 1 Tooltip = SpecialButtonBack = no background [Item13] Name= Action= Script=Wikipedia Icon=Wikipedia.png IconShrink = 1 Tooltip = SpecialButtonBack = no background [Item14] Name= Action= Script=IMDB Icon=imdb4.png IconShrink = 1 Tooltip = SpecialButtonBack = no background [Item15] Name= Action= Script= Icon=sub_black_next.png IconShrink = 1 Tooltip = SpecialButtonBack = no background [Item16] Name=Series Action= Script=Series Icon=search_file.png IconShrink = 1 Tooltip = SpecialButtonBack = no background [Item17] Name=Filmes Action= Script=Filmes Icon=search_file.png IconShrink = 1 Tooltip = SpecialButtonBack =no background ID= [Item18] Name=Filmes Action= Script=Filmes Icon=search_file.png IconShrink = 1 Tooltip = SpecialButtonBack =no background ID= [Item19] Name= Action= Script=Desktop Icon=Desktop.png IconShrink =1 Tooltip =Desktop SpecialButtonBack =no background [Item20] Name= Action= Script= Icon= lime3.png IconShrink = 2 Tooltip = SpecialButtonBack = no background [Item21] Name= Action= Script= Icon= lime3.png IconShrink = 2 Tooltip = SpecialButtonBack = no background [Item22] Name= Action= Script= Icon= lime3.png IconShrink = 2 Tooltip = SpecialButtonBack = no background [Item23] Name= Action= Script= Icon= lime3.png IconShrink = 2 Tooltip = SpecialButtonBack = no background [Item24] Name= Action= Script= Icon= lime3.png IconShrink = 2 Tooltip = SpecialButtonBack = no background [Item25] Name= Action= Script= Icon= lime3.png IconShrink = 2 Tooltip = SpecialButtonBack = no background [Item26] Name= Action= Script= Icon= lime3.png IconShrink = 2 Tooltip = SpecialButtonBack = no background [Item27] Name= Action= Script= Icon= lime3.png IconShrink = 2 Tooltip = SpecialButtonBack = no background [Item28] Name= Action= Script=WindowMonitorSwitch Icon=sub_black_next.png IconShrink = 1 Tooltip = SpecialButtonBack = no background [Item29] Name= Action= Script=WinMove_Full_NoTitle Icon=sub_black_add.png IconShrink = 1 Tooltip =Fullscreem SpecialButtonBack =no background ID= [Item30] Name= Action= Script=WindowMonitorSwitch Icon=sub_black_prev.png IconShrink =1 Tooltip = SpecialButtonBack = no background [Item31] Name= Action= %A_WinDir%\system32\calc.exe Script= Icon= Calculator1.png IconShrink = 2 Tooltip = SpecialButtonBack = no background -------------- And so on, up to Item48 (3 full rings)... Continue if you wish... -------------- ---------------------------------------------------------------------------------------------------- GENERAL ---------------------------------------------------------------------------------------------------- [General] RMShowHotkey = XButton1 ShowDelay = 150 MenuBackground = RMbackground.png MenuBackgroundTrans = 390 ButtonBackground = blue3.png ShadowHeight = 0 GenIconShrink = 11 Sounds = 1 SoundOnShow = SoundOnHover = hover.wav SoundOnSelect = SoundOnHide = SelectEffect = shake DestroyDelay = 0 RMCloseDirection = CCW Font = arial TextSize = 12 TextColor = FFFFFF TextAntialias = 1 TextTrans = DD Shadow = 1 ShadowColor = 222222 ShadowOffset = 1 ButtonSize = 60 MinWheelRadius = 50 LicenceAgreement =1
;===Description========================================================================= /* RADIAL MENU v3.15 by Learning one AHK forum location: http://www.autohotkey.com/forum/viewtopic.php?p=308352#308352 Thanks: Tic, TomXIII Script uses Tic's GDI+ functions library. Draws radial menu when you press & hold defined mouse hotkey (RButton by default). Release mouse above item to select it, or anywhere else to hide menu. After each selection, mouse will bounce back to center. To learn more about variables loaded in "settings" heading, see descriptions and comments in my earlier versions; 1 and 2. One of the most important is ShowDelay --> menu will show after %ShowDelay% miliseconds. This delay gives you opportunity to send normal mouse click without annoying menu showing. To show it instantly, set 0. I'll try to make Radial menu creator - edit your RM visually, and a Help file. Due to some special circumstances, this script is released before I planed, so it is not totally finished... LICENCE: Free for non-commercial, personal use. For commercial use, e-mail me please. Do not (re)distribute without my permission! Author: Boris Mudrinic (Learning one on AHK forum) Contact: [email protected] No matter how much you improve this Radial menu, my share in authorship will always be minimum 81%. If you make your own program, based on one of mine Radial menu scripts; 1) my share in authorship in your program will always be minimum 51%, 2) you have to mention my name and contact in it, 3) you have to inform me about your program. This are conditions under which I'm releasing all my Radial menu scripts. If you don't agree with this, exit and delete this program from your computer immediately! Note that script uses: - Tic's GDI+ functions library. (Thank you!) - a few lines developed by TomXIII. (Thank you!) - some modified sounds by patchen and SpeedY (Thank you!) - some icons by Iconka http://iconka.com (Thank you!) - some images from other authors - see: Image sources.txt HOW DOES IT WORK? It simply draws carefully positioned & shaped GUIs and threats them as menu items. Menu items are identified by GUI's title, not by item's text. GUI's titles are RMItem1, RMItem2 etc. IMPROVING PERFORMANCE On my computer (just Intel Celeron 1.47 GHz and 896 MB RAM), script works rocket fast! If this is not the case on your machine, do something like this: - lower the resolution fo images - use #NoEnv - disable (or set to 0) all open/select/close effects and delays - disable sounds or lower their duration, or quality - reduce number of items in menu - set Process priority of the script to AboveNormal or High I decided to limit number of items to 66 max (4 rings). If you want more items, it is much better to use classic drop down menus! DEFAULT HOTKEY: RButton ; Press & hold to show menu after %ShowDelay% miliseconds. CODE STRUCTURE: - Description - Auto-execute start - Functions - Load settings - Prepare menu - RMshow Hotkey - Subroutines */ ;===Auto-execute start================================================================== SetBatchLines, -1 #SingleInstance force CoordMode, mouse, Screen OnExit, Exit SetTitleMatchMode, 3 ; exact match Menu, Tray, Icon, %A_ScriptDir%\RMdata\RMTrayIcon.ico Menu, Tray, Tip, Radial menu v3.15 AboutRadialMenu = ( Title:%A_Tab%Radial menu v3.15 Author:%A_Tab%Boris Mudrinic (Learning one on AHK forum) Contact:%A_Tab%[email protected] Thanks:%A_Tab%Tic, TomXIII Licence: Free for non-commercial, personal use. For commercial use, e-mail me please. Do not (re)distribute without my permission! No matter how much you improve this Radial menu, my share in authorship will always be minimum 81`%. If you make your own program, based on one of mine Radial menu scripts; 1) my share in authorship in your program will always be minimum 51`%, 2) you have to mention my name and contact in it, 3) you have to inform me about your program. This are conditions under which I'm releasing all my Radial menu scripts. If you don't agree with this, exit and delete this program from your computer immediately! Note that script uses: - Tic's GDI+ functions library. (Thank you!) - a few lines developed by TomXIII. (Thank you!) - some modified sounds by patchen and SpeedY (Thank you!) - some icons by Iconka http://iconka.com (Thank you!) - some images from other authors - see: Image sources.txt ) ;===LicenceAgreement=== IniRead, LicenceAgreement, %A_ScriptDir%\RM settings.ini, General, LicenceAgreement if not (LicenceAgreement = 1) { MsgBox,324, Welcome to Radial menu v3.15, %AboutRadialMenu%`n`n`nDo you agree on licence and authorship terms?`n(If you agree, this message will never show again.) ; default button is no just because I want you to read MsgBox, not just automatically press enter or space... IfMsgBox, Yes IniWrite, 1, %A_ScriptDir%\RM settings.ini, General, LicenceAgreement Else ExitApp } Progress, m2 b fs13 zh0 WMn700, `nPlease wait...`n ;===Functions=========================================================================== #Include %A_ScriptDir%\RMdata\Gdip.ahk CalcPos() { global deg := deg ? deg+(360/TotalButtons): (360/TotalButtons)+90 rad := deg*(pi/180) xOffset := WheelRadius*(-1*Cos(rad))-picRadius yOffset := WheelRadius*(-1*Sin(rad))-picRadius itemX := mx1 + xOffset itemY := my1 + yOffset } ;===Count items=== Loop, 67 { IniRead, I%A_Index%Name, %A_ScriptDir%\RM settings.ini, Item%A_Index%, Name if I%A_Index%Name = ERROR ; item Section and Key does not exist at all { TotalButtons := A_Index - 1 Break } Else if (I%A_Index%Name = "" ) ; Blank name { IniRead, I%A_Index%Icon, %A_ScriptDir%\RM settings.ini, Item%A_Index%, Icon if I%A_Index%Icon = ; Blank Icon { TotalButtons := A_Index - 1 ; Auto set TotalButtons Break } } } if TotalButtons = TotalButtons = 66 ;===Load settings======================================================================= ;===Items=== Loop, %TotalButtons% { IniRead, I%A_Index%Icon, %A_ScriptDir%\RM settings.ini, Item%A_Index%, Icon IniRead, I%A_Index%Action, %A_ScriptDir%\RM settings.ini, Item%A_Index%, Action IniRead, I%A_Index%Script, %A_ScriptDir%\RM settings.ini, Item%A_Index%, Script IniRead, I%A_Index%ID, %A_ScriptDir%\RM settings.ini, Item%A_Index%, ID IniRead, I%A_Index%IconShrink, %A_ScriptDir%\RM settings.ini, Item%A_Index%, IconShrink IniRead, I%A_Index%Tooltip, %A_ScriptDir%\RM settings.ini, Item%A_Index%, Tooltip ; Tooltips are TomXIII's idea (Thanks!) IniRead, I%A_Index%SpecialButtonBack , %A_ScriptDir%\RM settings.ini, Item%A_Index%, SpecialButtonBack } ;===General=== IniRead, RMShowHotkey, %A_ScriptDir%\RM settings.ini, General, RMShowHotkey IniRead, ShowDelay, %A_ScriptDir%\RM settings.ini, General, ShowDelay IniRead, MenuBackground, %A_ScriptDir%\RM settings.ini, General, MenuBackground IniRead, MenuBackgroundTrans, %A_ScriptDir%\RM settings.ini, General, MenuBackgroundTrans IniRead, MenuBackgroundWidth, %A_ScriptDir%\RM settings.ini, General, MenuBackgroundWidth IniRead, MenuBackgroundHeight, %A_ScriptDir%\RM settings.ini, General, MenuBackgroundHeight IniRead, ButtonBackground, %A_ScriptDir%\RM settings.ini, General, ButtonBackground IniRead, ShadowHeight, %A_ScriptDir%\RM settings.ini, General, ShadowHeight IniRead, GenIconShrink, %A_ScriptDir%\RM settings.ini, General, GenIconShrink IniRead, Sounds , %A_ScriptDir%\RM settings.ini, General, Sounds IniRead, SoundOnShow, %A_ScriptDir%\RM settings.ini, General, SoundOnShow IniRead, SoundOnHover, %A_ScriptDir%\RM settings.ini, General, SoundOnHover IniRead, SoundOnSelect, %A_ScriptDir%\RM settings.ini, General, SoundOnSelect IniRead, SoundOnHide, %A_ScriptDir%\RM settings.ini, General, SoundOnHide IniRead, SelectEffect , %A_ScriptDir%\RM settings.ini, General, SelectEffect IniRead, DestroyDelay, %A_ScriptDir%\RM settings.ini, General, DestroyDelay IniRead, RMCloseDirection, %A_ScriptDir%\RM settings.ini, General, RMCloseDirection IniRead, Font, %A_ScriptDir%\RM settings.ini, General, Font IniRead, TextSize, %A_ScriptDir%\RM settings.ini, General, TextSize IniRead, TextColor, %A_ScriptDir%\RM settings.ini, General, TextColor IniRead, TextAntialias, %A_ScriptDir%\RM settings.ini, General, TextAntialias IniRead, TextTrans, %A_ScriptDir%\RM settings.ini, General, TextTrans IniRead, Shadow, %A_ScriptDir%\RM settings.ini, General, Shadow IniRead, ShadowColor, %A_ScriptDir%\RM settings.ini, General, ShadowColor IniRead, ShadowOffset, %A_ScriptDir%\RM settings.ini, General, ShadowOffset IniRead, ButtonSize, %A_ScriptDir%\RM settings.ini, General, ButtonSize IniRead, MinWheelRadius, %A_ScriptDir%\RM settings.ini, General, MinWheelRadius ;===Other stuff=== if (ShadowOffset > 3) ; limit ShadowOffset = 3 if (ButtonSize > 130) ; limit ButtonSize = 130 Loop, %TotalButtons% ; set separators { IniRead, I%A_Index%Name, %A_ScriptDir%\RM settings.ini, Item%A_Index%, Name if I%A_Index%Name = separator { I%A_Index%Name = I%A_Index%Icon = I%A_Index%SpecialButtonBack = separator } } pi :=4*Atan(1) WheelRadius := ButtonSize/(2*Sin(pi/TotalButtons)) ; Auto WheelRadius formula by TomXIII (Thanks!) if (TotalButtons > 6) ; 6 items in first ring WheelRadius := ButtonSize/(2*Sin(pi/6)) if (WheelRadius < MinWheelRadius) WheelRadius := MinWheelRadius picRadius := ButtonSize/2 if TextAntialias = 1 TextRen = 4 if TextAntialias = 0 TextRen = 1 if DestroyDelay = 0 RMCloseDirection = CW ; performs better if Sounds = 0 ; sounds off { SoundOnShow = SoundOnHover = SoundOnSelect = SoundOnHide = } Menu, tray, add Menu, tray, add, About, AboutRM Menu, tray, add, Open RM folder, OpenRMF Menu, tray, add, Edit MySubroutines, EditMySubroutines Menu, tray, add, Settings, RMSettings Menu, tray, add, Reload, ReloadRM Menu, tray, add, Exit, ExitRM Menu, tray, default, Settings ;===Set item's tooltip if not specified=== Loop, %TotalButtons% { if I%A_Index%Tooltip = ; custom tooltip (if specified) has precedence over auto tooltip (item's name or icon's file name without extension) { if I%A_Index%Name = { I%A_Index%Tooltip := I%A_Index%icon StringTrimRight, I%A_Index%Tooltip, I%A_Index%Tooltip, 4 ; remove extension } Else I%A_Index%Tooltip := I%A_Index%Name } } ;===Set IconShrink if not specified=== Loop, %TotalButtons% { if (I%A_Index%IconShrink = "" or I%A_Index%IconShrink = "ERROR") I%A_Index%IconShrink = %GenIconShrink% } ;===Prepare menu======================================================================= Gdip_Startup() ;===Prepare menu background=== ; Gui, 99 is Radial menu's background Gui, 99: -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs Gui, 99: Show, hide hwnd1 := WinExist() CurMenuBackground = %A_ScriptDir%\Images\Menu backgrounds\%MenuBackground% pBitmap := Gdip_CreateBitmapFromFile(CurMenuBackground) RMBWidth := Gdip_GetImageWidth(pBitmap), RMBHeight := Gdip_GetImageHeight(pBitmap) hbm := CreateDIBSection(RMBWidth, RMBHeight) hdc := CreateCompatibleDC() obm := SelectObject(hdc, hbm) G := Gdip_GraphicsFromHDC(hdc) Gdip_SetInterpolationMode(G, 7) if (MenuBackgroundWidth = "" or MenuBackgroundWidth > RMBWidth) ; automatic & limit MenuBackgroundWidth := RMBWidth if (MenuBackgroundHeight = "" or MenuBackgroundHeight > RMBHeight) ; automatic & limit MenuBackgroundHeight := RMBHeight Gdip_DrawImage(G, pBitmap, 0, 0, MenuBackgroundWidth, MenuBackgroundHeight, 0, 0, RMBWidth, RMBHeight) UpdateLayeredWindow(hwnd1, hdc, 0, 0, RMBWidth, RMBHeight, MenuBackgroundTrans) SelectObject(hdc, obm) DeleteObject(hbm) DeleteDC(hdc) Gdip_DeleteGraphics(G) Gdip_DisposeImage(pBitmap) ;===Prepare MouseOnItem=== ; Gui, 98 is MouseOnItem glow Gui, 98: -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs Gui, 98: Show, hide, MouseOnItem hwnd1 := WinExist() MouseOnItemImage = %A_ScriptDir%\RMdata\MouseOnItem.png pBitmap := Gdip_CreateBitmapFromFile(MouseOnItemImage) Width := Gdip_GetImageWidth(pBitmap), Height := Gdip_GetImageHeight(pBitmap) hbm := CreateDIBSection(Width, Height) hdc := CreateCompatibleDC() obm := SelectObject(hdc, hbm) G := Gdip_GraphicsFromHDC(hdc) Gdip_SetInterpolationMode(G, 7) Gdip_DrawImage(G, pBitmap, 0, 0, ButtonSize, ButtonSize, 0, 0, Width, Width) UpdateLayeredWindow(hwnd1, hdc, 0, 0, ButtonSize, ButtonSize) SelectObject(hdc, obm) DeleteObject(hbm) DeleteDC(hdc) Gdip_DeleteGraphics(G) Gdip_DisposeImage(pBitmap) ;===Prepare buttons=== Loop, %TotalButtons% { Gui, %A_Index%: -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs Gui, %A_Index%: Show, hide x%A_Index% y%A_Index% w%ButtonSize% h%ButtonSize%, RMItem%A_Index% ;===Gdi+ prepare=== hwnd1 := WinExist() hbm := CreateDIBSection(ButtonSize, ButtonSize) hdc := CreateCompatibleDC() obm := SelectObject(hdc, hbm) G := Gdip_GraphicsFromHDC(hdc) Gdip_SetInterpolationMode(G, 7) ;===CreateBitmapFromFile=== ;=Background= if (I%A_Index%SpecialButtonBack = "" or I%A_Index%SpecialButtonBack = "ERROR") ; blank or error CurItemBackground = %A_ScriptDir%\Images\Item backgrounds\%ButtonBackground% Else if (I%A_Index%SpecialButtonBack = "no background") ; no background CurItemBackground := A_ScriptDir "\RMdata\no background.png" Else if (I%A_Index%SpecialButtonBack = "separator") ; separator CurItemBackground := A_ScriptDir "\RMdata\separator.png" Else ; else CurItemBackground := A_ScriptDir "\Images\Item backgrounds\" I%A_Index%SpecialButtonBack pBitmapBackground := Gdip_CreateBitmapFromFile(CurItemBackground) ;=Icon= CurIcon := A_ScriptDir "\Images\Icons\" I%A_Index%Icon pBitmapIcon := Gdip_CreateBitmapFromFile(CurIcon) ;===Prepare item background and icon=== BackgroundWidth := Gdip_GetImageWidth(pBitmapBackground), BackgroundHeight := Gdip_GetImageHeight(pBitmapBackground) Gdip_DrawImage(G, pBitmapBackground, 0, 0, ButtonSize, ButtonSize, 0, 0, BackgroundWidth, BackgroundHeight) ; Background tempShadowHeight := ShadowHeight/2 if (I%A_Index%SpecialButtonBack = "no background") tempShadowHeight := 0 CurISX := I%A_Index%IconShrink CurISY := I%A_Index%IconShrink - tempShadowHeight IconWidth := Gdip_GetImageWidth(pBitmapIcon), IconHeight := Gdip_GetImageHeight(pBitmapIcon) Gdip_DrawImage(G, pBitmapIcon, CurISX, CurISY, ButtonSize-CurISX*2, ButtonSize-CurISX*2, 0, 0, IconWidth, IconHeight) ; Icon ;===Set item Text name and position=== CurIName := I%A_Index%Name ;===Prepare item text's Shadow=== if not (Shadow = 0) { Gdip_FontFamilyCreate(Font) Options = Center Vcenter cFE%ShadowColor% r%TextRen% s%TextSize% Gdip_TextToGraphics(G, CurIName, Options, Font, ButtonSize+ShadowOffset*2 , ButtonSize+ShadowOffset*2-ShadowHeight ) } ;===Prepare item Text=== ; 2 times! I think that this gives better antialias results when TextAntialias = 1 Gdip_FontFamilyCreate(Font) Options = Center Vcenter c%TextTrans%%TextColor% r%TextRen% s%TextSize% Gdip_TextToGraphics(G, CurIName, Options, Font, ButtonSize, ButtonSize-ShadowHeight ) Gdip_TextToGraphics(G, CurIName, Options, Font, ButtonSize, ButtonSize-ShadowHeight ) ;===Update button-window=== UpdateLayeredWindow(hwnd1, hdc, 0, 0, ButtonSize, ButtonSize) ;===Select and delete=== SelectObject(hdc, obm) DeleteObject(hbm) DeleteDC(hdc) Gdip_DeleteGraphics(G) Gdip_DisposeImage(pBitmapBackground) Gdip_DisposeImage(pBitmapIcon) } Hotkey, %RMShowHotkey%, RMShowHotkey Progress, off Return ;===Auto-execute ends here=== ;===RMshow Hotkey======================================================================== RMShowHotkey: QuitRMShow = 0 deg = 0 MouseGetPos, mx1, my1, OrigWinID WinGetTitle, OrigWinTitle, ahk_id %OrigWinID% SetTimer, QuitRMShow, 20 ;=========get windows list============ Winget, ids, list, , , Program Manager Index = 1 Loop, 6 { id:=ids%Index% Wingettitle, title, ahk_id %id% WinGet, Exe_Name, ProcessName, ahk_id %id% Exe_Name:= RegExReplace(Exe_Name, "i)" ".exe", ".png") Name:= RegExReplace(Exe_Name, "i)" ".png", "") I%A_Index%Icon=missing-image.png I%A_Index%Tooltip= if (Name="explorer" or Name="msnmsgr" or title="" or Name="KMPlayer" or title not contains dock) { Index += 1 id:=ids%Index% Wingettitle, title, ahk_id %id% WinGet, Exe_Name, ProcessName, ahk_id %id% Exe_Name:= RegExReplace(Exe_Name, "i)" ".exe", ".png") Name:= RegExReplace(Exe_Name, "i)" ".png", "") if (Name="explorer" or Name="msnmsgr" or title="" or Name="KMPlayer" or title not contains dock) { Index += 1 id:=ids%Index% Wingettitle, title, ahk_id %id% WinGet, Exe_Name, ProcessName, ahk_id %id% Exe_Name:= RegExReplace(Exe_Name, "i)" ".exe", ".png") Name:= RegExReplace(Exe_Name, "i)" ".png", "") } } if (Name="") { Exe_Name=missing-image.png Name= } I%A_Index%Icon=%Exe_Name% I%A_Index%ID=%id% I%A_Index%Tooltip=%Name% Index += 1 } ;===Set item's tooltip if not specified=== Loop, 6 { if I%A_Index%Tooltip = ; custom tooltip (if specified) has precedence over auto tooltip (item's name or icon's file name without extension) { if I%A_Index%Name = { I%A_Index%Tooltip := I%A_Index%icon StringTrimRight, I%A_Index%Tooltip, I%A_Index%Tooltip, 4 ; remove extension } Else I%A_Index%Tooltip := I%A_Index%Name } } ;===Prepare buttons=== ;Loop, %TotalButtons% Loop, 6 { Gui, %A_Index%: -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs Gui, %A_Index%: Show, hide x%A_Index% y%A_Index% w%ButtonSize% h%ButtonSize%, RMItem%A_Index% ;===Gdi+ prepare=== hwnd1 := WinExist() hbm := CreateDIBSection(ButtonSize, ButtonSize) hdc := CreateCompatibleDC() obm := SelectObject(hdc, hbm) G := Gdip_GraphicsFromHDC(hdc) Gdip_SetInterpolationMode(G, 7) ;===CreateBitmapFromFile=== ;=Background= if (I%A_Index%SpecialButtonBack = "" or I%A_Index%SpecialButtonBack = "ERROR") ; blank or error CurItemBackground = %A_ScriptDir%\Images\Item backgrounds\%ButtonBackground% Else if (I%A_Index%SpecialButtonBack = "no background") ; no background CurItemBackground := A_ScriptDir "\RMdata\no background.png" Else if (I%A_Index%SpecialButtonBack = "separator") ; separator CurItemBackground := A_ScriptDir "\RMdata\separator.png" Else ; else CurItemBackground := A_ScriptDir "\Images\Item backgrounds\" I%A_Index%SpecialButtonBack pBitmapBackground := Gdip_CreateBitmapFromFile(CurItemBackground) ;=Icon= CurIcon := A_ScriptDir "\Images\Icons\" I%A_Index%Icon pBitmapIcon := Gdip_CreateBitmapFromFile(CurIcon) ;===Prepare item background and icon=== BackgroundWidth := Gdip_GetImageWidth(pBitmapBackground), BackgroundHeight := Gdip_GetImageHeight(pBitmapBackground) Gdip_DrawImage(G, pBitmapBackground, 0, 0, ButtonSize, ButtonSize, 0, 0, BackgroundWidth, BackgroundHeight) ; Background tempShadowHeight := ShadowHeight/2 if (I%A_Index%SpecialButtonBack = "no background") tempShadowHeight := 0 CurISX := I%A_Index%IconShrink CurISY := I%A_Index%IconShrink - tempShadowHeight IconWidth := Gdip_GetImageWidth(pBitmapIcon), IconHeight := Gdip_GetImageHeight(pBitmapIcon) Gdip_DrawImage(G, pBitmapIcon, CurISX, CurISY, ButtonSize-CurISX*2, ButtonSize-CurISX*2, 0, 0, IconWidth, IconHeight) ; Icon ;===Set item Text name and position=== CurIName := I%A_Index%Name ;===Prepare item text's Shadow=== if not (Shadow = 0) { Gdip_FontFamilyCreate(Font) Options = Center Vcenter cFE%ShadowColor% r%TextRen% s%TextSize% Gdip_TextToGraphics(G, CurIName, Options, Font, ButtonSize+ShadowOffset*2 , ButtonSize+ShadowOffset*2-ShadowHeight ) } ;===Prepare item Text=== ; 2 times! I think that this gives better antialias results when TextAntialias = 1 Gdip_FontFamilyCreate(Font) Options = Center Vcenter c%TextTrans%%TextColor% r%TextRen% s%TextSize% Gdip_TextToGraphics(G, CurIName, Options, Font, ButtonSize, ButtonSize-ShadowHeight ) Gdip_TextToGraphics(G, CurIName, Options, Font, ButtonSize, ButtonSize-ShadowHeight ) ;===Update button-window=== UpdateLayeredWindow(hwnd1, hdc, 0, 0, ButtonSize, ButtonSize) ;===Select and delete=== SelectObject(hdc, obm) DeleteObject(hbm) DeleteDC(hdc) Gdip_DeleteGraphics(G) Gdip_DisposeImage(pBitmapBackground) Gdip_DisposeImage(pBitmapIcon) } ;===Prepare background postiton=== RMBX := mx1-MenuBackgroundWidth/2, RMBY := my1-MenuBackgroundHeight/2 Gui, 99: Show, hide x%RMBX% y%RMBY%, RMBackground ; RMBackground ;===Prepare buttons postitons=== Loop, %TotalButtons% { ;===Calculate positions=== OrigTotalButtons := TotalButtons ; save real TotalButtons OrigwheelRadius := WheelRadius ; save real WheelRadius If (TotalButtons < 7) ; up to 6 buttons regime { CalcPos() TotalButtons := OrigTotalButtons } Else ; 9 and more buttons regime { if A_Index between 1 and 6 ; 1. ring { TotalButtons = 6 CalcPos() TotalButtons := OrigTotalButtons ; restore real TotalButtons } if A_Index between 7 and 19 ; 2. ring { TotalButtons = 13 ;10 WheelRadius := ButtonSize/(2*Sin(pi/TotalButtons)) CalcPos() TotalButtons := OrigTotalButtons ; restore real TotalButtons WheelRadius := OrigwheelRadius ; restore real WheelRadius } if A_Index between 20 and 39 ; 3. ring { TotalButtons = 20 WheelRadius := ButtonSize/(2*Sin(pi/TotalButtons)) CalcPos() TotalButtons := OrigTotalButtons ; restore real TotalButtons WheelRadius := OrigwheelRadius ; restore real WheelRadius } if A_Index between 40 and 66 ; 4. ring { TotalButtons = 27 WheelRadius := ButtonSize/(2*Sin(pi/TotalButtons)) CalcPos() TotalButtons := OrigTotalButtons ; restore real TotalButtons WheelRadius := OrigwheelRadius ; restore real WheelRadius } } Gui, %A_Index%: -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs Gui, %A_Index%: Show, hide x%itemX% y%itemY% w%ButtonSize% h%ButtonSize%, RMItem%A_Index% if QuitRMShow = 1 Return } While (A_TimeSinceThisHotkey < ShowDelay) ; ShowDelay sleep... Sleep, 10 SetTimer, QuitRMShow, off if QuitRMShow = 1 Return ;===If RMShowHotkey is still down - show prepared menu=== if SoundOnShow SoundPlay, %A_ScriptDir%\Sounds\%SoundOnShow% Gui, 99: Show, x%RMBX% y%RMBY%,RMBackground ; RMBackground Loop, %TotalButtons% ; RMItem (s) Gui, %A_Index%: Show SetTimer, ItemTooltip, 20 if SoundOnHover SetTimer, SoundOnHover, 20 KeyWait, %RMShowHotkey%, u ; waits RMShowHotkey to be released ;===When user releases RMShowHotkey=== SetTimer, ItemTooltip, off Gui, 98: Hide ; MouseOnItem SetTimer, SoundOnHover, off ToolTip ; if problems with run occur (if Gui, 50 is still not hidden), put a short sleep here MouseGetPos, , , WinID WinGetTitle, WinTitle, ahk_id %WinID% if WinTitle contains RMItem ; RMShowHotkey released on item { MouseMove, %mx1%, %my1% ; back to original position Gosub, MutualActions Gosub, RadialMenuClose Loop, %TotalButtons% ; determine what to run { if (WinTitle = "RMItem" . A_Index) { CurAction := I%A_Index%Action CurActionScript := I%A_Index%Script if (CurAction = "Error" or CurAction = "") { if (CurActionScript = "Error" or CurActionScript = "") Break Else { WinActivate, %OrigWinTitle% Sleep, 10 ;Sendinput, %CurActionScript% Gosub, %CurActionScript% Break } } Else { Transform, CurAction, Deref, %CurAction% ; suggestion by Maxmax14 (Thanks!) Run, %CurAction% Break } } } Loop, 6 ; determine what to run { if (WinTitle = "RMItem" . A_Index) { CurActionID := I%A_Index%ID if (CurActionID = "Error" or CurActionID = "") Break Else { winactivate,ahk_id %CurActionID% Break } } } ;WinActivate, %OrigWinTitle% } else ; RMShowHotkey not released on item - just close menu { if SoundOnHide SoundPlay, %A_ScriptDir%\Sounds\%SoundOnHide% Gosub, RadialMenuClose } Return ;===Subroutines========================================================================= QuitRMShow: if not (GetKeyState(RMShowHotkey,"p")) { SetTimer, QuitRMShow, off QuitRMShow = 1 SendInput, {%RMShowHotkey%} } Return ItemTooltip: ; + MouseOnItem glow Critical MouseGetPos, , , WinID WinGetTitle, WinTitle, ahk_id %WinID% if WinTitle = MouseOnItem { PlaySOHSound = 0 ToolTip, %CurToolTip% Return } Else if WinTitle contains RMItem ; if mouse over RMItem { PlaySOHSound = 1 Gui, 98: Hide ToolTip Loop, %TotalButtons% { if (WinTitle = "RMItem" . A_Index) { LastRMItemNum := A_Index CurToolTip := I%A_Index%ToolTip ToolTip, %CurToolTip% Break } } WinGetPos, ActiveItemX, ActiveItemY, , ,%WinTitle% Gui, 98: Show, x%ActiveItemX% y%ActiveItemY% NA, MouseOnItem ; MouseOnItem } Else { PlaySOHSound = 0 Gui, 98: Hide ToolTip } Return SoundOnHover: if PlaySOHSound = 1 SoundPlay, %A_ScriptDir%\Sounds\%SoundOnHover%, wait Return Exit: Gdip_Shutdown(pToken) ExitApp Return RadialMenuClose: Gui, 98: Hide if RMCloseDirection = CW ; clockwise { Loop, %TotalButtons% { Gui %A_index%: Hide Sleep, %DestroyDelay% } } Else if RMCloseDirection = CCW ; counter-clockwise { TempTB := TotalButtons Loop, %TotalButtons% { Gui %TempTB%: Hide TempTB -- Sleep, %DestroyDelay% } } Gui, 99: Hide Return MutualActions: Critical if SoundOnSelect SoundPlay, %A_ScriptDir%\Sounds\%SoundOnSelect% if SelectEffect = ; Select Effects disabled Return ;===SelectEffects=== ; if you want fastes performance, just disable Select Effects by setting blank SelectEffect variable in .ini file --> SelectEffect = WinGetPos, XEff, YEff,,, %WinTitle% ;==Fade out effect== ; in development (in fact, I don't need this...) ; Note; WinSet , Transparent won't work for layered windows, so use UpdateLayeredWindow() for fade out effect - last parameter represents transparency ;==Shake effect== if SelectEffect = Shake { SetWinDelay, 35 ; Shake speed Loop, 5 { ; Set Shake intensity. X axis shake looks better than Y axis shake if A_index = 1 ; 2 pixels XEff -= 2 if A_index = 2 ; 2 pixels XEff += 4 if A_index = 3 ; 1 pixel XEff -= 3 if A_index = 4 ; 1 pixel XEff += 2 if A_index = 5 ; back to initial position XEff -= 1 WinMove, %WinTitle%,, %XEff%, %YEff% } } SetWinDelay, 100 ; default Return OpenRMF: Run, explore %A_ScriptDir% Return ReloadRM: Reload Return RMSettings: Run, %A_ScriptDir%\RM settings.ini Return AboutRM: MsgBox, 64, About Radial menu, %AboutRadialMenu% Return ExitRM: ExitApp Return EditMySubroutines: Run, edit %A_ScriptDir%\Utilities\MySubroutines.ahk Return #Include %A_ScriptDir%\Utilities\MySubroutines.ahk #include %A_ScriptDir%\Scripts\Dic.ahk ;Escape::ExitApp
I would also prefer sub menus instead of 50+ items..
On my machine, it is unusable over a video window (vmr9), cause of strong flickering...
The configuration is a little complicated, if one has to have the icons extracted in the Icons folder - why not take it from the exe or system?
You are right! Hm... I think I can't fix this. I think this is GDI+ problem...On my machine, it is unusable over a video window (vmr9), cause of strong flickering...
Submenus and auto-extracting icons are on to do list.
I have to study HotKeyIt's ToolTip()
There are also some functions (like the ones in ToolTip() ) that can find associated icon automatically, would be great as well
On the left side, you can see improved Radial menu "mg".image not found
- (reminder: It uses different system than Radial menu v3; only 1 Gui - LayeredWindow, items are identified by mouse gestures...)
- new skin
- now supports multiple item rings
- I wrote a small function library and item identification is now very simple; just call GetSelectedItem()
- main problem with RM "mg" is that writing a code that will automatically create such nice looking interface, and allow user to modify it as he wish is very hard. For now I can manually create custom RM "mg" graphical user interfaces on demand.
- code for this one is still not released on AHK forum, Edit: but it's "core" is - see post below.
On the right side, you can see Radial menu v3.16
- new skin
- testing submenus!!! - lower right picture
- I'll release the code when 100% stable version is finished
I hope you like previews. :wink:
.
Radial menu "mg" method
This script is the core of Radial menu mg. It's sort of "How does Radial menu mg work" tutorial.
If you are working on radial menus, study it - it's short and isn't hard to understand. "Mg" means mouse gesture.
This method has greater potential than method used in Radial menu v3.
Download Radial menu mg method. Read description in script. Default hotkey is MButton.