is it possible to have a font menu without subclassing menuitem ?

Hi everyone,

I want to install a font menu for a control (with a menu in the menubar)
and for simplicity of this control handling, I want to have all code in the control, so no extra class beside the control.

I can make a font menu (when the control gets the focus I create the menu in the menubar)
but how do I know which font has been choosen in the menu ?
I can make a menuhandler for the font, but when the menuhandler gets fired, I have no more reference to the choosen menuitem.

is this even possible ?
thanks.

I don’t think so.
So I make a subclass each time.

Personally I went the route of creating a popup menu subclass as my font selector.

Technically it’s more than possible to share the menu between the menubar and the popup menu (as this can be done in Cocoa), but I don’t know how it would work in your application.

Create the menu items for the fonts as array elements, then the menu handler will have an index argument.

Add a menu “FontMenu” with one child “FontItem” to the menu bar:

[code]FontMenu
Index = (empty)
Text = Fonts

FontItem
Index = 0
Text = -    (<- this is now a Separator menu item, which will be suppressed as it is the first one)

[/code]
Create a control subclass:

[code]Class TextAreaSubclass Inherits TextArea

// Events:
Sub EnableMenuItems()
For i As Integer = FontMenu.Count - 1 DownTo 1
Dim item As MenuItem = FontMenu.Item(i)
item.Close()
Next
For i As Integer = 0 To FontCount - 1
Dim item As New FontItem()
item.Text = Font(i)
Next
End Sub

// Menu Handlers:
Function FontItem(index as Integer) As Boolean // index as Integer doesn’t show in the IDE
Dim fontName As String = FontItem(index).Text
Me.SelTextFont = fontName
Return True
End Function

End Class[/code]

how do you make this menuhandler ?
I cannot add a parameter to a menuhandler, you only have a boolean return value …

I tried to display the index value inside the menuhandler : it exists !
but I’ve got value that makes it look like a handle to something, but what ?
anyway it’s not the selected menuitem index…

The above code works. Put that in the menu handler to see it:

Function FontItem(index as Integer) As Boolean Dim fontName As String = FontItem(index).Text Me.Text = fontName Me.SelStart = 0 Me.SelLength = Me.Text.Len Me.SelTextFont = fontName Return True End Function
You can also add anything you want to the Tag property of the menu item in EnableMenuItems, and then in the menu handler you query the tag.

this is my menuhandler :

[code]Function MyTextFont() As Boolean
MsgBox MyTextFont(Index).text
Return True

End Function
[/code]

it does not compile : “this item (mytextfont) does not exist”
what did I miss ?
I did not create the menu in the menubar, but dynamically.

if I create a “mytextfont” menu in the menubar, it does not compile too with
“too many arguments got 1 expected 0” at the msgbox line

Try my code as above before saying “it does not compile”.

how do you install the “index” parameter into the menuhandler ?
when I create a menuhandler, I have no parameter except the returned value as boolean
and you cannot add any parameter to it ?

Eli:

I have no doubts that I missed something: in 2015r1 and in 2016r3, I was not able to get the FontItem MenuHandler (in the right PopupMenu List). I checked and re-checked with my new glasses: no MenuHandler with that name.

I will re start from the beginning, creating a brand new project later today.

I do not need that, I only was (am) curious. I had some questions on the old Forumaboutdynamically created Menus and I consistently get “add a MenuItem Subclass…”.

Edit:
When I removed “-” (without the quotes) from the TextItem.Text, it appears in the list of availables MenuHandlers.

Now I have errors in:

Sub EnableMenuItems() For i As Integer = FontMenu.Count - 1 DownTo 1 Dim item As MenuItem = FontMenu.Item(i)

Static reference … on FontMenu (.Count and .Item).

Edit:
If I comment the first For Next in the EnaleMenuItems, the project compile and I saw the Font Menu with tons of entries and I am able to set one to the selected text.

It works with some commented out code and I do not understand.

Eli ?

Emile,
you are not forced to choose a menuhandler, you can type the name you want.
you can do that way when you make dynamic menuitems, they don’t appear in the menuhandler popup menu

[quote=295766:@Jean-Yves Pochez]I tried to display the index value inside the menuhandler : it exists !
but I’ve got value that makes it look like a handle to something, but what ?
anyway it’s not the selected menuitem index…[/quote]
in fact it seems the “index” we get here is the textarea.index, so nothing to do with the menuitem we want ?

We cannot see the index in the parameter list, but if I copy the MenuHandler (and paste it in TextEdit for example), the Index parameter appears.

Now that works fine.

I wrote explicitely that the index parameter of a menu handler is not shown in the IDE.

I really wish menu handlers returned the menuItem analogous to a to contextual menu actions are handled. It would eliminate the need for menuItem subclasses for list type menus and not break any existing code.

The real advantage comes from the fact that multiple menu items can have the same name, so that they all call the same menu handler. If the menuItem was passed into the handler, you could either use the Text or a value you save in the tag to perform the menu Action without the need for a subclass or even knowing the name of of the “parent” menu.

That would help encapsulate the logic better IMO for lists. Things like Font menus, List of fonts sizes, or colors or any related groups where where action only varies by the value of a single parameter

That is about as unintuitive as possible…
As far as I can see, to get it to work you have to :

  1. Create the parent menuitem in the IDE
  2. Create the first Item on that menu
  3. set it’s index to 0

THEN you can add the other child items dynamically and assign then teh same name as the first one…

Besides being unintuitive it’s hard to pick that up from teh documentation as well (I don’t think it is in the section on dynamic menus). I wonder how many people realize that can be done that way!

If Xojo implemented what I suggest above, everything becomes MUCH more intutive, explicit, encapsulated , and able to be done totally dynamically ( able to be done 100% in code)

  • karen

[quote=295819:@Karen Atkocius]If Xojo implemented what I suggest above, everything becomes MUCH more intutive, explicit, encapsulated , and able to be done totally dynamically ( able to be done 100% in code)
[/quote]

There is a feedback from 2013 requesting what i suggest but it was closed :
<https://xojo.com/issue/24232>

There is another one from 2012 that is still open and says almost exactly what I said above.
<https://xojo.com/issue/23013>

I really don’t understand why Xojo would not want to make menu handlers more consistent with menuItem.Popup and contextual menus. It would be more discoverable. more consistent and much more obvious.

  • karen