Recent

Author Topic: Customize PopupMenu?  (Read 11249 times)

Josh

  • Hero Member
  • *****
  • Posts: 1274
Customize PopupMenu?
« on: April 21, 2015, 12:44:51 pm »
Hi

Is it possible to customize popupmenu so that you can specify the font, background color and enable the showing of the bitmaps etc.

I have tried to hide the bitmap by setting glyphshowmode, but this leaves a bank space for it, i would like the popup items to cascade smoothly and be pleasing in appearance to the color scheme of my application,

I was hoping to use the ownerdraw method, but tpopupmenu does not appear to have this.

If it is not easily possible, does anyone know of a different popupmenu component that is more customizable than the default one.

Hope someone can help or advise

Thanks in advance.
The best way to get accurate information on the forum is to post something wrong and wait for corrections.

Signal

  • New Member
  • *
  • Posts: 41
Re: Customize PopupMenu?
« Reply #1 on: April 21, 2015, 01:00:01 pm »
I'm interested in the responses you get. I have similar issues with TPopupMenu.

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Customize PopupMenu?
« Reply #2 on: April 21, 2015, 03:16:43 pm »
The LCL uses the underlying OS widget to display popup menus (and main menus).
Consequently customisation is limited to whatever menu customisation your OS theme provides.

This is why there are no Font or Color etc. properties for TMenu descendants - they would be quite useless since they would be totally ignored by the theming engine of the OS.

One purpose of themes is to provide a uniform look and feel across all apps running on that OS. They have market value because they add to the 'brand' image, so (bog standard, non-custom-drawn) Android, Mac and Windows apps are immediately recognisable and distinctive. Themes are not designed to extend individual customisations.

I don't know of an Object Pascal custom-drawn popupmenu component that works within an LCL environment (though there may well be one, if there is hopefully someone here will tell you). It would be tricky to write, since to use popups a TForm expects a TPopupMenu... and that type name is already taken in the LCL. So a replacement would have to be written as a TPopupMenu descendant (unless you were happy with dreadful hacks), which would mean the component developer would be constantly fighting against the current design of TPopupMenu in order to provide for the desired customisation features.

rvk

  • Hero Member
  • *****
  • Posts: 6169
Re: Customize PopupMenu?
« Reply #3 on: April 21, 2015, 04:04:30 pm »
The LCL uses the underlying OS widget to display popup menus (and main menus).
Are you sure this is true (for win32 at least)? There is some heavy drawing done in \lcl\interfaces\win32\win32wsmenus.pp. That doesn't seem like handing off all drawing to the OS. It does use calls to the Themedraw-interface though but the rest is all done in code. Delphi also uses custom drawing of menus like that but at least there you have the possibility to override it with OwnerDraw/OnDrawItem. For LCL there also could have been an OnDrawItem somewhere in the win32wsmenus.pp so the programmer can override the menu-drawing. (I'm only speaking for win32 in this case. Not sure about the other OS'es)

Of course you're right in saying that in that case you're overriding the OS-theme and creating a different visible experience. And it's always difficult to emulate theme-drawing in your own custom-draw when you only want one small change.

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Customize PopupMenu?
« Reply #4 on: April 21, 2015, 06:36:01 pm »
Rvk is quite right. Having looked at the interfaces file he identified, the LCL actually does a lot of custom size calculations and drawing, to emulate Win95, Vista etc., using ThemeServices (on Windows at least). And as he points out, unlike Delphi, the LCL provides no customisation hook through an OnDrawItem event or similar.

Josh

  • Hero Member
  • *****
  • Posts: 1274
Re: Customize PopupMenu?
« Reply #5 on: April 22, 2015, 02:36:55 pm »
Hi
Thanks for your responses.

In my case I do not use themes and do not wish to; as my user Interfaces are carefully crafted for particular use, and the only annoying thing I have is the Popupmenu coloring etc destroys the UI coloring scheme.
Delphi can do it with owner draw, and many applications have a customized popup that suits the applications coloring scheme.

I am pondering creating my own HACK of a popup menu, I suspect it will take a fair amount of effort, creating forms as needed, but then these can be custom shape, and I could use TBCButtons as the Item Lists.

Has any one else attempting their own Popup Menu system.

I have not checked yet how easy it is to stop the inbuilt popup from activating and instead activate my own.

Any advice in this approach would be gratefully received
The best way to get accurate information on the forum is to post something wrong and wait for corrections.

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Customize PopupMenu?
« Reply #6 on: April 22, 2015, 08:26:41 pm »
One approach to rolling your own popup menu would be to write a new TMenuItem component (called perhaps TPopMenuItem) as a building block for a customisable popup.

The time needed to implement it would depend greatly on what properties of existing TMenuItems you needed it to implement. Presumably:

Action
Caption
Enabled
ShortCut
Visible
OnClick
Count
Handle
Items[]
MenuIndex
Menu
Parent
Command

would be essential - or are you happy with a more cut-down list?

What about:

Checked
Default
Bitmap
GroupIndex
GlyphShowMode
HelpContext
Hint
ImageIndex
RadioItem
RightJustify
ShortCutKey2
ShowAlwaysCheckable
SubMenuImages
 

For customisation you want additional properties, not currently offered, say:
Font
Color

Anything else?
Or have you now found an existing Object Pascal non-Lazarus popup component that does what you want?
As with any task, the specification determines the complexity. I would be willing to get you started with a basic working outline if you don't need anything too involved. I don't have time or resources to produce and test a truly robust component that would run well on all Lazarus-supported platforms, but I enjoy a (limited) challenge.

rvk

  • Hero Member
  • *****
  • Posts: 6169
Re: Customize PopupMenu?
« Reply #7 on: April 22, 2015, 11:19:53 pm »
Ok, say we are speaking of Windows...

How about starting with simply catching WM_DRAWITEM and WM_MEASUREITEM and drawing everything manually? That's also how it's done in win32callback.inc (where the real drawing of menus begins).

It seems Delphi 3 also didn't have the OwnerDraw yet and I found an example here where these message are caught and the menu drawn manually. In this example the TMainMenu is used but I imagine it's the same for TPopupMenu.

I changed it a little to work with Lazarus and the test-project is attached together with a screenshot of a menu containing 14 points Comic Sans MS font.
« Last Edit: April 22, 2015, 11:21:27 pm by rvk »

Josh

  • Hero Member
  • *****
  • Posts: 1274
Re: Customize PopupMenu?
« Reply #8 on: April 25, 2015, 02:17:02 pm »
Hi rvk,

Apologies for late reply, been busy with other stuff.

I will have a look see if anything that can be implemented.

It would need to be X-Platform though.

howardpc
For my needs it is pretty basic, use just control over the coloring and font is essential,  I would not be using any glyphs icons images etc. Just a basic text based concise popupmenu.
I have been having a look at some of my old popups with delphi and noticed that lazarus is lacking a bit; or I can't find easily find the answer.
In delphi I can split long popUp menu's into columns of more manageable ones, the break command is not implemented in lazarus, so I end up with a very long list of option, rather than categorizing into smaller manageable per-selection categories.

I will make a point of monitoring the topic more closely, totally my fault.

Again thank for suggestions; just trying to work out best scenario. I have been pondering creating a hack, where the popup is all generated, then on the OnPopUp event to make it non visible, and call separate routine that creates the custom menu in stackable forms/subforms.
« Last Edit: April 25, 2015, 11:08:06 pm by josh »
The best way to get accurate information on the forum is to post something wrong and wait for corrections.

loopbreaker

  • New Member
  • *
  • Posts: 32
Re: Customize PopupMenu?
« Reply #9 on: April 26, 2015, 09:13:26 am »
+1 for usefulness of menuitem.break and tmenu.ownerdraw,
at least for Windows so that Delphi projects could be ported to Lazarus.

A simple usecase is a colorpickergrid.
Since this is generally useful (like combobox ownerDraw),
event support in win32wsmenus.pp would be reasonable.

There is already a related report:
http://bugs.freepascal.org/view.php?id=26969
but no developer found

 

TinyPortal © 2005-2018