Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

RADIAL MENU scripts - migrated to new forum


  • Please log in to reply
1310 replies to this topic
randomguy
  • Members
  • 94 posts
  • Last active: Oct 20 2017 11:11 PM
  • Joined: 30 Oct 2011
Hello everyone,

I'm trying to make a "Totally Portable" Radial User Menu that can be used everywhere (with all links using relative paths. If I have to leave my computer, I only need to copy RM folder as well as other Softwares' folder in the same drive (which RM has a link to) to a portable HDD, USB... and then I can use the menu anywhere.


Because of my organizing habit, I don't want to put everything/linked softwares inside RM folder.Therefore I cannot use the existing A_ScriptDir variable

Basically Rmenu and these softwares only share the same Drive Letter, which I want to take as a relative path variable.

I Use Splitpath to set the A_ScriptDir's Drive as the "A_PortDrv" Variable

SplitPath, A_ScriptDir,,,,, A_PortDrv
(in Radial menu.ahk)


But then I have to go open the "Menu definitions" textfiles, find and replace every existing and new link with the new variable, for example to change:

D:\photoshop portable\pts.exe

into
%A_PortDrv%\photoshop portable\pts.exe

The changed links work find, however, strangely enough, the %A_PortDrv% variable does not show up in Radial Menu Designer.

When I open the text file directly, It looks like:
Text=	Task Killer 230
Icon=	ksokoban.png
Action=	%A_PortDrv%\TRAVELLERstartup\Task Killer 230\TaskKiller.exe

But in the Designer it only shows:
Text=	Task Killer 230
Icon=	ksokoban.png
Action=	\TRAVELLERstartup\Task Killer 230\TaskKiller.exe

Is there something wrong?


gemisigo
  • Members
  • 94 posts
  • Last active: Apr 02 2015 02:36 PM
  • Joined: 10 Sep 2010
I don't how that mechanism works internally it might happen that:
1. the variable you create (A_PortDrv) is not global in which case its scope is the function where it was created.
2. it is global but the place where it is used is a function and it is not in assume-global mode, meaning that A_PortDrv is blank there.
3. it is passed as a variable and when it tries to resolve it, the expression %A_PortDrv% is considered the name of variable name and it (namely "D:" here) is a blank variable.

Also, (as far as I know) the Designer itself runs in a separate context and a result if this it might have absolutely no knowledge of what A_PortDrv is (since it is not a built-in variable). By the way, "RM" is not used as a variable (%RM%) but "RM\" is stringreplaced to the contents of A_ScriptDir (I guess).

Learning one
  • Members
  • 1483 posts
  • Last active: Jan 02 2016 02:30 PM
  • Joined: 04 Apr 2009
@serenityjazz & gemisigo: Thanks for giving user to user support.

@bennomoehlman
: serenityjazz & gemisigo gave you correct answer. Here's one more way how to do it. In My functions.ahk, located in RM\My codes folder, make a Send function that accepts one parameter;
Send(What) {
	Send, %What%
}
and in item action, specify Action = fun Send|^+a. Using this method, you can have just one Send function and use it to send anything. Examples:
Action = fun Send|^a
Action = fun Send|I love AutoHotkey
Action = fun Send|^w

etc..

@gemisigo:
Yes, it's possible to modify menu on-the-fly on 2 ways. Here's the way I recommend;
Open RM\Internal\Codes\RMApp lib.ahk Go to line 1222 . There you'll find: RM2_Off(). Just comment this line like this;
;RM2_Off()
Now RM2module and GDI+ will stay turned on, and all bitmaps that are used to draw menu elements will stay in memory. That allows you to update menus on the fly.

Than open RM\Radial menu.ahk and put RM2_Off() in the RMApp_OnExit subroutine, like this:
RMApp_OnExit:	; on exit subroutine
[color=#ff0000]RM2_Off()[/color]
RMApp_OnExit()
; you can put or include your OnExit code here 
ExitApp
Now RM will now that it has to dispose of bitmaps used to draw menu elements and turn off GDI+ on RM exit.

Open My hotkeys.ahk and put this code inside.
MButton::RMApp_MyRMHandler2(70)

F5::
MenuDefinition =	; of course, you can load it directly from file. Example: RMApp_LoadMenu(56, "C:\Radial menu 1.txt")
(`
[Item1]
Icon=		Calculator.png
Action=		%A_WinDir%\system32\calc.exe
)
RMApp_LoadMenu(70, MenuDefinition) ; loads radial menu from variable (string), uses Gui number 70.
return

F6::
MenuDefinition =	; of course, you can load it directly from file. Example: RMApp_LoadMenu(56, "C:\Radial menu 2.txt")
(`
[Item3]
Icon=		Paint.png
Action=		%A_WinDir%\system32\mspaint.exe
)
RMApp_LoadMenu(70, MenuDefinition) ; loads radial menu from variable (string), uses Gui number 70.
return

F7::
MenuDefinition =	; of course, you can load it directly from file. Example: RMApp_LoadMenu(56, "C:\Radial menu 3.txt")
(`
[Item5]
Icon=	Notepad.png
Action=	%A_WinDir%\notepad.exe
)
RMApp_LoadMenu(70, MenuDefinition) ; loads radial menu from variable (string), uses Gui number 70.
return
Imagine that every press on F5, F6, F7 hotkey is "menu update event" in your code that reads specific file (or string, like in this example), and than updates the same menu (Gui number 70 in this example) on the fly. You could call those "menu update events" via SetTimer, or something else - that's up to you. This example can do 3 update types, but you can do as many updates you want - hundreds, thousands or more... The RM2module and GDI+ are turned on so you can update and redraw the same menu very fast and without problems. The only negative side is that now RM will consume a little bit more RAM, because all those bitmaps used to draw menu elements are in held memory. So resources will be freed on RM exit, not on RM auto-execute end (which it does by default).

In this example we modified 1 line of internal codes, but in upcoming updates, I think I'll give users an option to leave RM2module and GDI+ turned on after RM auto-execute end, without need to modify internal codes.


@randomguy:
Your request can be realized on a few ways. Here's the way I recommend;

Open My functions.ahk in RM\My codes folder, and put this function inside;
Portable(PathWithoutDrive) {
	static Drive
	if (Drive = "")
	SplitPath, A_ScriptDir,,,,,Drive
	Run, % Drive "" PathWithoutDrive
}
Let's say your portable USB or HDD is organised like this:

D:\photoshop portable\pts.exe
D:\App2\App2.exe
D:\Some documents\Document.doc
D:\Radial menu

Now, if you want to run D:\photoshop portable\pts.exe, in item action specify Action = fun Portable|photoshop portable\pts.exe
for D:\App2\App2.exe, specify Action = fun Portable|App2\App2.exe
and for D:\Some documents\Document.doc, specify Action = fun Portable|Some documents\Document.doc
etc.

That's it. RM will auto detect letter of your portable drive. For example, on one computer it may be D:\ on another F:\ etc. but by using technique described above, you won't have problems with that.

gemisigo
  • Members
  • 94 posts
  • Last active: Apr 02 2015 02:36 PM
  • Joined: 10 Sep 2010
Thanks for the reply, Learning one, a lot of useful info in your last post. I'll try them tomorrow morning.

EDIT:
Loading menu on-the-fly works perfectly. I call a function from a menu item that calls IniSettingsEditor (made by Rajat and toralf), recreates the cs menu file in "Menu definitions\Context-sensitive" after the ini editor GUI is closed and reloads it immediately . This way I have the menu at my disposal right after starting RM (if it was existing) and no need for hotkey to refresh it.

I added a few lines to Send() so that I can decide about the method in menu item:
Send(what, how = "")
{
	if (how = "")
		Send, %what%
	if (how = "r")
		SendRaw, %what%
	if (how = "i")
		SendInput, %what%
	if (how = "p")
		SendPlay, %what%
	if (how = "e")
		SendEvent, %what%
}

It's a pity we don't have something like:
MyWillBeDone(command, parameters)
{
	%command%, %parameters%
}
I can imagine doing some magic with it :)

I also added Portable() to my function collection, it might come in handy one day. Thanks again ;)

randomguy
  • Members
  • 94 posts
  • Last active: Oct 20 2017 11:11 PM
  • Joined: 30 Oct 2011

@randomguy:
Your request can be realized on a few ways. Here's the way I recommend;

Open My functions.ahk in RM\My codes folder, and put this function inside;

Portable(PathWithoutDrive) {
	static Drive
	if (Drive = "")
	SplitPath, A_ScriptDir,,,,,Drive
	Run, % Drive "" PathWithoutDrive
}
Let's say your portable USB or HDD is organised like this:

D:\photoshop portable\pts.exe
D:\App2\App2.exe
D:\Some documents\Document.doc
D:\Radial menu

Now, if you want to run D:\photoshop portable\pts.exe, in item action specify Action = fun Portable|photoshop portable\pts.exe
for D:\App2\App2.exe, specify Action = fun Portable|App2\App2.exe
and for D:\Some documents\Document.doc, specify Action = fun Portable|Some documents\Document.doc
etc.

That's it. RM will auto detect letter of your portable drive. For example, on one computer it may be D:\ on another F:\ etc. but by using technique described above, you won't have problems with that.

So in essence I would have to manually change every current link into "fun Portable|", and every future links as well?

I really like the idea that you just have to drag your files into Designer, then the script does the rest: if the program detects that the dragged file is in the same drive as the script, but it is not in the same folder as the script, it does automatically the "find and replace" job to make it portable.

I think this feature is already implemented, however it only applies to files inside "your" RM folder: everything changes to RM\link instead of full absolute path.

I also noticed that it does apply also to certain folders as well, such as Program Files,... it automatically changes to the Relative %A_ProgramFiles% variable

After some research inside the script,

I tried to mess around with RMD Classes.ahk to see if it is the trigger to the "Auto replace" function.

I add my link into the end of string of function TranslateBuiltInVars:

TranslateBuiltInVars(ByRef String, ToWho){	
			static List := "A_ScriptDir|A_AhkPath|A_Temp|A_WinDir|A_ProgramFiles|A_AppData|A_Desktop|A_StartMenu|A_Programs|A_Startup|A_AppDataCommon|A_DesktopCommon|A_StartMenuCommon|A_ProgramsCommon|A_StartupCommon|A_MyDocuments|A_UserName|A_PortDrv"


However it seems that now it has replaced all my prefixes with BLANK! (the links still work though, without the absolute path
For example:

Action=	\Program Files (x86)\Evernote\Evernote\Evernote.exe

still works fine, but it is so strange

me lance
  • Members
  • 15 posts
  • Last active: Mar 17 2015 05:00 PM
  • Joined: 03 May 2011
When I try to launch the Radial Menu Editor I get the following error message:

Error in #include file "C:\Program Files\Radial Menu\Radial Menu v4\Internal\Codes\RMD Classes.ahk":
Invalid option.

Specifically: .00000 y492.000000 w66 h66

Line#
2034: {
2035: this.Width := Width := (o.Width="") ? 64: o.Width
2036: this.Height := Height := (o.Height="") ? 64: o.Height
>Skipping lines here
2041: Gui,%GuiNum%:Show,Hide x%x% y%y% w%Width% h%Height%
Thanks,
Lance

User546456
  • Guests
  • Last active:
  • Joined: --
Nice update! :D
Thank you Learning one!!

tsenlaw
  • Members
  • 33 posts
  • Last active: Jan 06 2014 11:59 PM
  • Joined: 26 Aug 2011
wonderful updates! THX, Learning one!

BTW,
1. how can I set the context sensitive RM so that submenus can be used?

2. is it possible to make the MGA_gestures context sensitive? For example, MGA_U is valid in some applications , and gestures such as MG_U, MG_UD, etc. are valid in other applications.

3. how can set both Rbutton and Mbutton as RMShowHotkey?

Thank you very much!

Learning one
  • Members
  • 1483 posts
  • Last active: Jan 02 2016 02:30 PM
  • Joined: 04 Apr 2009
I'm currently very busy, so I probably won't reply in this thread for a while. User to user support is always more than welcome.

Here are some quick replies:
@gemisigo: Nice. ;) One suggestion - use else if like this;
Send(what, how = "")
{
   if (how = "")
      Send, %what%
   else if (how = "r")
      SendRaw, %what%
   else if (how = "i")
      SendInput, %what%
   else if (how = "p")
      SendPlay, %what%
   else if (how = "e")
      SendEvent, %what%
}
@randomguy: A_PortDrv is not AHK's Built-in variable, so that's the reason while your prefixes are replaced with blank. If you don't like "fun Portable" method I described above, you could open RM\Internal\Codes\RMD.ahk, and add your custom variable(s) in MenuVariables associative array when creating RMD application object via new c_App(). Unfortunately, I don't have time to give you step by step explanation.

@me lance: Radial Menu Editor works fine without errors. I guess you skipped one (or more) updates, and therefore, RMD Classes.ahk in your RM wasn't updated. For example, if you are on v4.29 and you want to update to v4.31, you must run: 1) update to v4.30 and than 2) update to v4.31. So you have to do step by step update. Here's a quick link to all updates since v4.00
RM4 Update steps:
- RM v4.00 --> v4.01 changes
- RM v4.01 --> v4.20 changes
- RM v4.20 --> v4.25 changes
- RM v4.25 --> v4.26 changes
- RM v4.26 --> v4.27 changes
- RM v4.27 --> v4.29 changes
- RM v4.29 --> v4.30 changes
- RM v4.30 --> v4.31 changes
- RM v4.31 --> v4.32 changes

@tsenlaw:

1. how can I set the context sensitive RM so that submenus can be used?

Only RM's main menu has ability to have submenus. All additional radial menus, which include context sensitive menus, can't have submenus (unless you modify internal codes or make a little bit "advanced" function and use it as item action)

2. is it possible to make the MGA_gestures context sensitive?

Of course. Just write your if/else statements inside your MGA_ function.

3. how can set both Rbutton and Mbutton as RMShowHotkey?

Hotkey combinations as RMShowHotkey are not allowed (unless you modify internal codes). But if you mean that both Rbutton and Mbutton separately, not as combination, can call RM, that's possible. Unfortunately, I don't have time to give you step by step explanation.

tsenlaw
  • Members
  • 33 posts
  • Last active: Jan 06 2014 11:59 PM
  • Joined: 26 Aug 2011
For 2, I mean make MGA_ function context sensitive, that is, MGA_ function is only valid in a few programs, but in other programs MG_gestures will be valid and not blocked by the MGA_ function.

for 3, I mean that both Rbutton and Mbutton separately

waiting for your comeback!

gemisigo
  • Members
  • 94 posts
  • Last active: Apr 02 2015 02:36 PM
  • Joined: 10 Sep 2010
We're going to miss you, Learning one, I hope you will come back soon.

Meanwhile, a question to more experienced users:
How does this ItemLayoutPerRing thing work? Is it possible to have a context sensitive menu that uses "8_14_20" layout while others and the main menu are still "6_12_18_24"? If not, is it possible to have different one-ringers? How do I set the layout at all? Is there a function for doing it and if there is where/how do call it?

tsenlaw
  • Members
  • 33 posts
  • Last active: Jan 06 2014 11:59 PM
  • Joined: 26 Aug 2011

We're going to miss you, Learning one, I hope you will come back soon.

Meanwhile, a question to more experienced users:
How does this ItemLayoutPerRing thing work? Is it possible to have a context sensitive menu that uses "8_14_20" layout while others and the main menu are still "6_12_18_24"? If not, is it possible to have different one-ringers? How do I set the layout at all? Is there a function for doing it and if there is where/how do call it?


I have had a similar question before, here is the reply from Learning One:

There is only one Item-Layout-Per-Ring per script possible. So, in one script, you can't have for example 8.14.20.26 layout for few menus, and 6.12.18.24 for all other menus. That is not going to change probably until RM3module (if I'll ever make it). All of above applies only on multi-ring menus and you probably know that in one script, you can have both multi-ring and one-ring menus, no problem. Layout in one-ring menus mainly depends on number of items in menu. For details, see documentation in RM2module.ahk's comments.


gemisigo
  • Members
  • 94 posts
  • Last active: Apr 02 2015 02:36 PM
  • Joined: 10 Sep 2010
I see. Having one-ringers is useful but setting it up with constraining its radius requires playing with the values quite a bit. The layout of a one-ringer menu without a fixed radius depends on the number of items it contains and they are scattered on the ring unevenly when the maximum number of the items on the given ring is not divisible with the actual number of items.
e.g. 4 items can be placed evenly on a 8-item ring (top, right, bottom, left) but they look kinda silly on a 6-item ring.

Are there any predefined values for different layouts?

It would also be nice be able to see in RMD what it would look like.

me lance
  • Members
  • 15 posts
  • Last active: Mar 17 2015 05:00 PM
  • Joined: 03 May 2011
@learningOne Thanks, I reinstalled and Designer works now. I was wondering how, in the Designer, you go about adding a new menu item. Currently I open text mode and edit it there but I was wondering if there is a way to do it in the gui.

Thanks

gemisigo
  • Members
  • 94 posts
  • Last active: Apr 02 2015 02:36 PM
  • Joined: 10 Sep 2010

@learningOne Thanks, I reinstalled and Designer works now. I was wondering how, in the Designer, you go about adding a new menu item. Currently I open text mode and edit it there but I was wondering if there is a way to do it in the gui.

Thanks


Yes, there is a way. Click and hold the middle of the menu. You will see a new item appear. Drag & drop it wherever you like.