Multiple Font PopupMenus in Same Window

Hi. I’ve noticed a delay in the opening of a window if it has multiple popupmenus with the avialble fonts loaded into them all on WIndow.Open.

What is the most efficient way to handle this so there is no delay and essentially it only has to create the font array once and just duplicate instances of the same popup font menu? A class? Container Control?

Also, where would be the best place to set the index of each one, in Window.Open or the control/class open event? Does WIndow.Open occur after all the controls have opened and filled with menu items?

Thanks.

Depending on how you’ve set this up you might just use a loop over all fonts ONCE and set however many instances to the same values instead of loading each one individually

you can use a popup menu subclass
example

I currently have multiple controls, not using a class…so I do ONE loop iteration but have to load items into each menu in that loop and it’s still slow.

look at the example, drag the fontpopup to the place where you need it

Thanks. Yes I’m not on my dev computer at the moment but will defintiely look at that as soon as I am. I’m assuming the class loads the fonts on the control’s open event. Do you know if this will speed things up or will it essentially be the same speed as manually doing it for each control? And would the winodw’s open event occur after the control’s open event so I can set the index value in that?

It would be the same speed, however you could speed things up by loading it just once and caching the result in a shared property. Downside is of course that if the font folder changes then the font menu is inaccurate.

Make a FontPopup class as a subclass of PopupMenu

Add a shared property Private Shared mySharedMenu() As string to the FontPopup class

Add an Event Definition Open() to the class so the event is available in the instances

Add this to the Open event of the PopupMenu class:

[code] // first one? Build the font menu

if mySharedMenu.Ubound < 0 then

dim i, n as integer
n = fontCount - 1
for i = 0 to n
  mySharedMenu.Append (font(i))
next

end if

// set the font menu

for i as integer = 0 to mySharedMenu.Ubound
me.AddRow mySharedMenu( i )
next

call Open()
[/code]

Yes I suspected as much. It seems to me that the thing slowing it down is the actuall AddRow function to each PopupMenu whether it be adding rows to individual menu controls or to subclass instances of menu controls.

Either way it has to add a new row for every font for every menu.

So the question is…is there a way to overcome this?

I’ve never used a container control before – could that help in some way?

[quote=234396:@Markus Winter]

[code]
// set the font menu

for i as integer = 0 to mySharedMenu.Ubound
me.AddRow mySharedMenu( i )
next
[/code][/quote]

Me.AddRows(mySharedMenu)

:slight_smile:

[quote=234482:@Marco Hof]Me.AddRows(mySharedMenu)

:)[/quote]
Nice.

No.

What makes you say that?

Disk access is about 10,000 times slower than memory access, and addRow should be negligible compared to loading the info from disk.

I assumed that because although I am not currently using a subclass I am already loading the fonts only once into an array and looping through that array once using AddRow for each popupmenu control. I need to test this new subclass proposed solution out with Me.AddRow(fontarray) and see if there is a speed difference. I suspect iterating for the shared font array loop for each subclassed control will be slower than AddRow in a single loop but perhaps AddRow(fontarray) might be quicker.

Why? It’s exactly the same but uses less memory … unless I’m missing something you are doing.

AddRows

With an s

Noted! Thanks!

I really doubt there is a noticeable delay with filling a bunch of popupmenus. A tiny for Next Loop like that is so extremely fast, you won’t notice the difference if it’s 1 or 10.

I would debug things a bit more or run Analyze to see where your actual delay is coming from.

Ok. I’ll delve deeper in case that isn’t the issue.

Okay, so I’ve finally managed to debug and test this and here are my results:

  1. It is 100% the populating process of each popup menu that is slowing down the appearance of the parent window.
  2. AddRows(fontarray) is marginly quicker than looping through once and using AddRow(fontname) for each font.
  3. Using a subclass of the popupmenu doesn’t speed things up.

If I just add a single “font name” row to each popupmenu the window instantly appears…demonstrating the cause of the delay.

So while I understand a few more things unfortunately I still have no satisfactory solution to this.

  • Make your first PopupMenu a Control Set
  • Make it invisible
  • load the font names,
  • Make it visible,
  • clone it with New to produce the second one.

It should be way faster than loading the font names into each.

See http://documentation.xojo.com/index.php/New

Do you mean ContainerControl? Never worked with this before or a “Control Set”.

I understand the logic of creating a new instance of an exisiting object but not sure how to get started with this or how to refer to each new instance (to set or get its index value) and position it on the window as I would for an actual popupmenu control placed on the window in the IDE.

Can you please clarify and perhaps point me to an example of how to achieve this?

Thanks.