dynamic menu new row - screen height - no manual barBreak

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
bish01
Posts: 96
Joined: 22 Feb 2016, 03:57

dynamic menu new row - screen height - no manual barBreak

09 Aug 2016, 18:08

Hi, sorry about keywords in the title...

Let just say menu is dynamic and has 1000 items (from a directory loop or similar) ... any way to make menu start a new row once it hits the bottom of screen?

I have came across barBreak and I know if you have let say 10 items you can state on 5th one +barBreak so menu will start a new row but how do I tell it to break once it hit certain amount of entries or it hits the bottom of screen?
Is that possible and how would I do it?

cheers
Shadowpheonix
Posts: 1259
Joined: 16 Apr 2015, 09:41

Re: dynamic menu new row - screen height - no manual barBreak

10 Aug 2016, 10:35

To the best of my knowledge, there is no easy way to do this. You will need to calculate the height of a single line of text (see here, here, and here for some possible ways to do so), then determine how many of those can fit on the screen (allowing for margin between rows), then use that to determine which menu entry needs the +BarBreak.

Personally, I just go the easy route and arbitrarily decide on a number of rows (I typically do 20) before forcing the break.
bish01
Posts: 96
Joined: 22 Feb 2016, 03:57

Re: dynamic menu new row - screen height - no manual barBreak

14 Aug 2016, 20:56

Shadowpheonix wrote: Personally, I just go the easy route and arbitrarily decide on a number of rows (I typically do 20) before forcing the break.
Thanks for the help Shadowpheonix.
So i tried that using loop counting and inserting +barBreak after 20 items.
Works fine just curious if i am doing it correctly or is there more proper way of doing it.

Code: Select all

SetKeyDelay, -1

folderPath = C:\windows
buildMenu(folderPath)

^1::
MouseGetPos, x, y
Menu, myMenu, show, %x%, %y%
return

runthis:
itemNum := A_ThisMenuItemPos 
MsgBox, % file%itemNum%
return

buildMenu(folder)
	{
		global
		menuitemcount=0
		Loop, %folder%\*
			{
				menuitemcount++
				if menuitemcount < 20
				{
					Menu, myMenu, add , %A_LoopFileName% ,runthis
					file%A_Index% = %A_LoopFileFullPath%
				}
				else if menuitemcount = 20
				{
					Menu, myMenu, add , %A_LoopFileName% ,runthis, +BarBreak
					file%A_Index% = %A_LoopFileFullPath%
					menuitemcount = 0
				}
			}
	}
Later i will see if i can figure out how to measure menu and split it based on screenheight...
cheers
Shadowpheonix
Posts: 1259
Joined: 16 Apr 2015, 09:41

Re: dynamic menu new row - screen height - no manual barBreak

15 Aug 2016, 09:40

bish01 wrote:So i tried that using loop counting and inserting +barBreak after 20 items.
Works fine just curious if i am doing it correctly or is there more proper way of doing it.
The method you used is virtually identical to what I use. :)
User avatar
kczx3
Posts: 1649
Joined: 06 Oct 2015, 21:39

Re: dynamic menu new row - screen height - no manual barBreak

15 Aug 2016, 10:21

Code: Select all

SetKeyDelay, -1
 
folderPath = C:\windows
buildMenu(folderPath)
 
^1::
MouseGetPos, x, y
Menu, myMenu, show, %x%, %y%
return
 
runthis:
itemNum := A_ThisMenuItemPos 
MsgBox, % file%itemNum%
return
 
buildMenu(folder)
	{
		global
		Loop, %folder%\*
			{
				Menu, myMenu, add, %A_LoopFileName%, runthis, % (mod((A_Index = 1 ? A_Index : A_Index - 1), 20) = 0 ? "+BarBreak" : "")
				file%A_Index% = %A_LoopFileFullPath%
			}
	}
punchin
Posts: 439
Joined: 17 Jan 2014, 17:54

Re: dynamic menu new row - screen height - no manual barBreak

15 Aug 2016, 18:56

With hard coding the amount of menu items, you might want to make your window not resize be or give it a minimum size.
bish01
Posts: 96
Joined: 22 Feb 2016, 03:57

Re: dynamic menu new row - screen height - no manual barBreak

17 Aug 2016, 22:11

Thanks "kczx3", only if you have extra time could you help me understand/learn this bellow?
% (mod((A_Index = 1 ? A_Index : A_Index - 1), 20) = 0 ? "+BarBreak" : "")
I understand it does similar if-else thing just cant wrap my head around it yet. I do not quite get mod() thing yet.
No worries otherwise. Thank you.
punchin
Posts: 439
Joined: 17 Jan 2014, 17:54

Re: dynamic menu new row - screen height - no manual barBreak

18 Aug 2016, 11:53

Mod stands for modulo. Basically the remainder in a division equation.

The whole bot of code your having an issue with is a ternary operation. Yours however has multiple ones nested.

To simplify: (If statement ? True result : False result)

If you need to nest them, you insert a complete ternary operation into the desired result section.

(If statement ? True : (2nd if statement ? True : false ))
bish01
Posts: 96
Joined: 22 Feb 2016, 03:57

Re: dynamic menu new row - screen height - no manual barBreak

30 Aug 2016, 14:47

Thank you punchin for explaining this.
I looked up some tutorials and blogs explaining this further so the way I understand there is no real performance difference between using nested or ternary ones, right?
No need to answer.

As for the barBreak, I still need to look into figuring out how to measure menu height vs screen height and split it.
If I ever figure it out I will post it.

cheers
punchin
Posts: 439
Joined: 17 Jan 2014, 17:54

Re: dynamic menu new row - screen height - no manual barBreak

31 Aug 2016, 02:49

Yeah. That is going to be tricky as the same font can display differently from computer to computer. What you could do is add a single item to the menu and do a pixel search to find out where the bottom of the menu is and do the math from there based on GUI/screen height. Once the calculations are done, go back through and add the other items.
MrHue
Posts: 17
Joined: 01 Oct 2015, 02:51

Re: dynamic menu new row - screen height - no manual barBreak

16 Sep 2016, 00:52

Try this:

Code: Select all

SysGet, MenuBarHeight, 15
MaxMenuItemCount := A_ScreenHeight // MenuBarHeight - 4
buildMenu("C:\Windows", MaxMenuItemCount, "mymenu")
return

RunThis:
	MsgBox, %A_ThisMenu% : %A_ThisMenuItem%
return

buildmenu(folder, MaxMenuItemCount, myMenu)
{
	Loop, %folder%\*
		If Mod(A_Index+1,MaxMenuItemCount)
			Menu,%myMenu%,Add,%A_LoopFileName%,RunThis
		Else	Menu,%myMenu%,Add,%A_LoopFileName%,RunThis, BarBreak
	Menu,Tray,Add,%Folder%,:%myMenu%
}
Mod(A_Index+1,MaxMenuItemCount) will be TRUE if the (menuitem number+1) divided by the maxmenuitemcount has a positive remainder.
The +1 will cause the Bar to break at MaxMenuItemCount-1 instead of at MaxMenuItemCount.
You need to reduce the row count by one because Windows starts to insert up and down arrows into the menu when you approach MaxMenuItemCount.
User avatar
kczx3
Posts: 1649
Joined: 06 Oct 2015, 21:39

Re: dynamic menu new row - screen height - no manual barBreak

16 Sep 2016, 09:35

@MrHue

I had to put #Persistent at the beginning of your script for it to stay running in the system tray.
bish01
Posts: 96
Joined: 22 Feb 2016, 03:57

Re: dynamic menu new row - screen height - no manual barBreak

16 Sep 2016, 18:01

Thank you mrHue.
Just one question about sysGet...
I looked at it earlier just did not get around working out how to use it (dividing screenheight and all that you posted)

Why 15 and not 55 ?
Just as a test putting 55 instead and removing -4 menu items (on second line of your code) creates menu top to bottom (not that I really need that) and windows did not insert up and down arrows into the menu.
With 15 it never goes all the way top to bottom.
What is the difference. ( read in the help file but not grasping it yet)

(from help)
15 SM_CYMENU: Height of a single-line menu bar, in pixels.
54, 55 SM_CXMENUSIZE, SM_CYMENUSIZE: Dimensions of menu bar buttons, such as the child window close button used in the multiple document interface, in pixels.

If I am to use larger icons in menu (as an example) would I use 55?

Code: Select all

#Persistent

SysGet, MenuBarHeight, 55		;15
MaxMenuItemCount := A_ScreenHeight // MenuBarHeight 	;- 4
buildMenu("C:\Windows", MaxMenuItemCount, "mymenu")
return

RunThis:
	MsgBox, %A_ThisMenu% : %A_ThisMenuItem%
return

buildmenu(folder, MaxMenuItemCount, myMenu)
{
	Loop, %folder%\*
		If Mod(A_Index+1,MaxMenuItemCount)
			Menu,%myMenu%,Add,%A_LoopFileName%,RunThis
		Else	Menu,%myMenu%,Add,%A_LoopFileName%,RunThis, BarBreak
	Menu,Tray,Add,%Folder%,:%myMenu%
}

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: peter_ahk and 334 guests