Improving the default FM2 Popup Menu style under OS X

This post describes changes you can make to improve the appearance of popup menus in your Delphi XE3 FireMonkey applications that target OS X.

Modifying OS X styles at design time

To modify OS X styles at design time you must change the target platform for the application to OS X. Otherwise you will always be modifying a windows based style at design time.

If you want to RUN your application with an OS X style on a Windows machine (can be handy for debugging) you need to find and comment out the following lines of the FMX.Styles.pas unit. Copy the unit to your application before modifying it.

Locate the “class function TStyleManager.LoadFromStream(const AStream: TStream): TFmxObject;” method implementation. Towards the end there is a section of code that checks the description and shows a message dialog if the style being used doesn’t match the current target. You can comment out that entire block of code.

What is interesting about this dialog, is that if it does show in your application, due to invalid style being used for the target platform – your application will crash terribly after the dialog is shown. Probably not something you would want to happen.

The Default Popup Menu Style

Here is a screen capture of what the default FM2 popup menu style looks like under Mountain Lion.
Default FM2 style under Mountain Lion

Here is a screen capture of what the native menu looks like under Mountain Lion.
Default Mountain Lion menu

As you can see, there are some obvious differences between the default style that FM2 expects you to use and what should be expected.

  1. FM2 menu has square corners
  2. Font is totally wrong
  3. Disabled item state isn’t very clear
  4. Separator too close to previous item
  5. Selected item doesn’t span the width of the menu
  6. First (and last) items are not padded from the top (or bottom) of the menu

Background on menu styles

There are three different styles contained in the default style.

  1. menuviewstyle – the style that makes up the background of the popup menu
  2. menuitemstyle – the style that makes up the item in the menu
  3. menuseparatorstyle – the style used for a separator in the menu

If you extract the default styles from the IDE, why these aren’t included as raw style files is an unbelievable oversight by Embarcadero you can look at these styles and expand, modify or redo them.

Chris Rolliston has a great post on how to extract the default styles for a given platform here: http://delphihaven.wordpress.com/2012/09/11/inspecting-the-default-platform-fmx-styles-in-xe3/

menuviewstyle changes

The changes made to the menuviewstyle are significant. Gone is the “pixel perfect” usage of TSubImage since it kills the rounded appearance of the popup menu it’s been replaced with a TRectangle shape, shadow effect and some very selective use of the padding properties (to have the shadow appear correctly).

The content layout now contains padding values to have the items span the width of the popup menu, as well as provide extra space at the top and bottom of the menu.

menuitemstyle changes

There were two changes to this style.

  1. Changed the font family and size to the “text” and “shortcut” TText objects
  2. Added TColorAnimation components to the “text” and “shortcut” objects that trigger when the Enabled property is changed

menuseparator style

The following changes were made to this style:

  1. Made the separator span the entire width of the item
  2. Made the separator height 1 pixel
  3. Modified the top and bottom padding of the sub image object to center the line better within the item

NOTE: The source lookup for the TSubImage component included in the style reference “OSX Lionstyle.png”. You need to change this value when adding these styles into your retina style book. I have not tested on a retina system, but if you want to send me a retina enabled laptop for testing, please email me (jeremy.north@gmail.com) for the ship to address!

Style only changes

With some changes to the menu, menu item and menu separator styles, I’ve managed to make the FM2 menu style a little more plausible.

Here is the result:

Modified style with no code changes

Style and three source code changes

Throw in a couple of modifications to the FMX.Menus.pas unit, the results are improved once again.

  1. Item height reduction
  2. Disabled text actually looks disabled

This is the final result for the modified popup menu.

Modified style with code changesAnother menu with modified style and code changes

Not perfect and could be tweaked further but I think its a vast improvement on the default!

 

How to put these changes in your application

Modified style download

To get these changes working in your applications, download the attached popupmenustyle.style file and Add that to your OS X style book(s) for your application. Use the Add… feature in the Style Designer.

Code changes

Copy the FMX.Menus.pas unit to your application folder.

In the TMenuItem.ApplyStyle method add the two lines of code to the end of the method:

ApplyTriggerEffect(Self, ‘Enabled’);
StartTriggerAnimation(Self, ‘Enabled’);

In the TMenuItem.SetEnabled method add the same two lines inside the “if Value <> Enabled then” statement.

These two changes causes the Enabled property to trigger the animation which turns the Text color to Gray.

If you inspect the styles included in the style file, both the text and shortcut style items for the ‘menuitemstyle’ have color animation components added to them with triggers. Some screen captures of the style changes are below.
Structure of the style Animation Properties

Instead of applying a color animation, this could have been achieved by directly updating the text and shortcut style items. However this solution allows for further customizations down the track if required. Such as making the disabled color RED!

The final code change addresses the issue of the menu items default height. Currently it is 23, however the native height is 19 (on my installation anyway). To address this issue (which isn’t an ideal solution) I did the following change:

In the TMenuItem.CalcSize method change the following line:

Result := PointF(0, 23);

To something like this:

{$IFDEF JEDOSX}
Result := PointF(0, 19);
{$ELSE}
Result := PointF(0, 23);
{$ENDIF}

NOTE: A define is used here because you don’t want to affect other target platform item sizes. For my applications that target OS X, I always define JEDOSX. This is why I used this define – you should define your own value here!

What I should have done here is added a TStyleTag to the style and set its stylename to ItemHeight and read the value from the style, instead of hardcoding it. This is left as an exercise for the reader – I’ve already spent way too long on this as it is.

 

Conclusion

Hopefully this post has helped improve the default look of a popup menu in your applications that target OS X. Any queries, post a comment and I’ll try and respond.

NOTE: I’m not done with popup menus and there use in FM2, however that will have to wait for another post.

 

 

8 Comments

  1. That is a great improvement. It really looks native now. I can only hope Embarcadero adopt these changes and incorporate hem into the original sources/style.

  2. My first thoughts were that the FM2 menus look better. They are more crisp! But, it is important to be able to look like the native menus.

  3. Petar says:

    Some of the pics are broken? 🙂

  4. Chee Meng says:

    Hi. The separator in OSX actually does not span the full width of the menu 🙂

    There is a 1 px padding on either ends of the separator.

    Thanks for the post!