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
dynamic menu new row - screen height - no manual barBreak
-
- Posts: 1259
- Joined: 16 Apr 2015, 09:41
Re: dynamic menu new row - screen height - no manual barBreak
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.
Personally, I just go the easy route and arbitrarily decide on a number of rows (I typically do 20) before forcing the break.
Re: dynamic menu new row - screen height - no manual barBreak
Thanks for the help Shadowpheonix.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.
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
}
}
}
cheers
-
- Posts: 1259
- Joined: 16 Apr 2015, 09:41
Re: dynamic menu new row - screen height - no manual barBreak
The method you used is virtually identical to what I use.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.
Re: dynamic menu new row - screen height - no manual barBreak
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%
}
}
Re: dynamic menu new row - screen height - no manual barBreak
With hard coding the amount of menu items, you might want to make your window not resize be or give it a minimum size.
Re: dynamic menu new row - screen height - no manual barBreak
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.
% (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.
Re: dynamic menu new row - screen height - no manual barBreak
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 ))
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 ))
Re: dynamic menu new row - screen height - no manual barBreak
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
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
Re: dynamic menu new row - screen height - no manual barBreak
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.
Re: dynamic menu new row - screen height - no manual barBreak
Try this:
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.
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%
}
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.
Re: dynamic menu new row - screen height - no manual barBreak
@MrHue
I had to put #Persistent at the beginning of your script for it to stay running in the system tray.
I had to put #Persistent at the beginning of your script for it to stay running in the system tray.
Re: dynamic menu new row - screen height - no manual barBreak
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?
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%
}