Recent

Author Topic: Can we create a multicolumn menu in Lazarus?  (Read 8987 times)

vkhoa

  • New Member
  • *
  • Posts: 47
Can we create a multicolumn menu in Lazarus?
« on: October 08, 2015, 09:50:58 am »
for example like the choose color menu in Word
I want a grid menu which is used to choose a list of special characters
« Last Edit: October 08, 2015, 10:04:14 am by vkhoa »

zeljko

  • Hero Member
  • *****
  • Posts: 1596
    • http://wiki.lazarus.freepascal.org/User:Zeljan
Re: Can we create a multicolumn menu in Lazarus?
« Reply #1 on: October 08, 2015, 11:34:43 am »
I don't think it's possible, but you can create your own popup form and put whatever you want inside that form ...

rvk

  • Hero Member
  • *****
  • Posts: 6169
Re: Can we create a multicolumn menu in Lazarus?
« Reply #2 on: October 08, 2015, 11:48:22 am »
for example like the choose color menu in Word
I want a grid menu which is used to choose a list of special characters
What exactly are you after?
Something like the "Character map" (Lazarus > Edit > Insert from Character Map) ?

Graeme

  • Hero Member
  • *****
  • Posts: 1428
    • Graeme on the web
Re: Can we create a multicolumn menu in Lazarus?
« Reply #3 on: October 08, 2015, 01:13:59 pm »
for example like the choose color menu in Word
I want a grid menu which is used to choose a list of special characters
Not possible with LCL as far as I know, but is possible with custom drawn toolkits like fpGUI.

As a work-around, you could do what fpGUI does as standard (in any text input widgets) - add a popup menu with a "Insert from Character Map" menu entry.
--
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/

vkhoa

  • New Member
  • *
  • Posts: 47
Re: Can we create a multicolumn menu in Lazarus?
« Reply #4 on: October 09, 2015, 08:20:04 am »
Thanks all for the quick replies. :)
@zeljko, @Graeme
I see.
@rvk
Yes, it likes characters maps, but it is the menu of my application
« Last Edit: October 09, 2015, 08:23:18 am by vkhoa »

rvk

  • Hero Member
  • *****
  • Posts: 6169
Re: Can we create a multicolumn menu in Lazarus?
« Reply #5 on: October 09, 2015, 11:10:39 am »
Yes, it likes characters maps, but it is the menu of my application
Do you mean something like attached image?
(If not you might want to sketch something as how you want it and post it. Images/sketches are much clearer than words)

You could create a normal TMainMenu and on the MenuItems.OnClick you could open a separate form (with ShowModal) containing a StringGrid with all your options. That form can be created on the fly (in code) and if done right, it could act just like a submenu with columns. Unfortunately there is no component (that I know of) that does this already.

rvk

  • Hero Member
  • *****
  • Posts: 6169
Re: Can we create a multicolumn menu in Lazarus?
« Reply #6 on: October 09, 2015, 11:48:47 am »
Okay (I couldn't leave it alone :D).

I didn't find an option in Lazarus to set MF_MENUBREAK to make a TMenuItem go to a new column. In Delphi this is much easier (just set TMenuItem.Break to mbBreak).

But if you're on Windows you could do it (with some hackery :))

Use the following function (which I took from lcl\interfaces\win32win32wsmenus.pp):
Code: Pascal  [Select][+][-]
  1. uses Windows,
  2.  
  3. function myChangeMenuFlag(const AMenuItem: TMenuItem; Flag: Cardinal; Value: boolean): boolean;
  4. var
  5.   MenuInfo: MENUITEMINFO;     // TMenuItemInfoA and TMenuItemInfoW have same size and same structure type
  6. begin
  7.   FillChar(MenuInfo, SizeOf(MenuInfo), 0);
  8.   MenuInfo.cbSize := sizeof(TMenuItemInfo);
  9.   MenuInfo.fMask := MIIM_FTYPE;         // don't retrieve caption (MIIM_STRING not included)
  10.   GetMenuItemInfo(AMenuItem.Parent.Handle, AMenuItem.Command, False, @MenuInfo);
  11.   if Value then
  12.     MenuInfo.fType := MenuInfo.fType or Flag
  13.   else
  14.     MenuInfo.fType := MenuInfo.fType and (not Flag);
  15.   Result := SetMenuItemInfo(AMenuItem.Parent.Handle, AMenuItem.Command, False, @MenuInfo);
  16.   //TriggerFormUpdate(AMenuItem);
  17. end;

Now create a large menu with lots of MenuItems.
Determine where you want to go to a new column and use the following command in FormCreate() (for instance for MenuItem5):
Code: Pascal  [Select][+][-]
  1.   myChangeMenuFlag(MenuItem5, MF_MENUBREAK, true);

Now, when you run your program, you have a MainMenu with columns  8)

Graeme

  • Hero Member
  • *****
  • Posts: 1428
    • Graeme on the web
Re: Can we create a multicolumn menu in Lazarus?
« Reply #7 on: October 09, 2015, 12:09:21 pm »
Unfortunately there is no component (that I know of) that does this already.
Sadly, this was supported natively by OS/2 2.11 already back in 1990. Attached is a scanned image from a book I have Real-World Programming for OS/2 2.11. From quickly scanning through the Menus chapter, it looks like multi-column popup menus under OS/2 is achieved by defining your menus with the MIS_STATIC, MIA_FRAMED and MIS_BREAKSEPARATOR menu attributes. The latter is what causes a multi-column menu to appear.

Windows was heavily influenced by OS/2, so Windows might still have similar menu attributes. Obviously that would only work for LCL-Win32 with direct Win32 API calls, and not for any other OS targets.
« Last Edit: October 09, 2015, 12:11:41 pm by Graeme »
--
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/

rvk

  • Hero Member
  • *****
  • Posts: 6169
Re: Can we create a multicolumn menu in Lazarus?
« Reply #8 on: October 09, 2015, 12:12:38 pm »
Unfortunately there is no component (that I know of) that does this already.
Sadly, this was supported natively by OS/2 2.11 already back in 1990. Attached is a scanned image from a book I have Real-World Programming for OS/2 2.11. From quickly scanning through the Menus chapter, it looks like multi-column popup menus under OS/2 is achieved by defining your munes with the MIS_STATIC, MIA_FRAMED and MIS_BREAKSEPARATOR menu attributes. Windows was heavily influenced by OS/2, so Windows might still have similar menu attributes. Obviously that would only work for LCL-Win32, and not for any other OS targets.
I already posted a function to achieve similar under Windows.
It's done by setting the MF_MENUBREAK flag on a TMenuItem.

Code: Pascal  [Select][+][-]
  1.   myChangeMenuFlag(MenuItem5, MF_MENUBREAK, true);
  2.   myChangeMenuFlag(MenuItem8, MF_MENUBREAK, true);
« Last Edit: October 09, 2015, 12:16:37 pm by rvk »

vkhoa

  • New Member
  • *
  • Posts: 47
Re: Can we create a multicolumn menu in Lazarus?
« Reply #9 on: October 10, 2015, 08:24:49 am »
Thanks! I'll try it later :D
I have posted the screenshot which is what I wanted, but instead of the color square, I will draw a symbol or an image at each square. Is it posible? I also want to change the square size.


rvk

  • Hero Member
  • *****
  • Posts: 6169
Re: Can we create a multicolumn menu in Lazarus?
« Reply #10 on: October 10, 2015, 10:59:05 am »
I have posted the screenshot which is what I wanted, but instead of the color square, I will draw a symbol or an image at each square. Is it posible? I also want to change the square size.
You could draw images in a menu but you don't have much control over the rest of the appearance. So if you want to do what you described, it's best to go with a separate form which you can popup.

Do the squares need to be of different size of are they all the same size? If they all are the same size you could create a form with TDrawGrid and you can draw the images on that. If the squares are of different sizes you could just but several TSpeedButtons or TBitBtns on the form. That's why a real sketch of your interface is important, so you know where you're working towards. Also the functionality needs to be described. Do you need to select an options with your keyboard or is clicking an image enough?

wp

  • Hero Member
  • *****
  • Posts: 11923
Re: Can we create a multicolumn menu in Lazarus?
« Reply #11 on: October 12, 2015, 12:09:03 am »
vkhoa, the attached demo maybe gets close to what you want. It creates a form as suggested by rvk onto which a series of speedbuttons are placed, each one with its assigned color. This form can be opend from a toolbutton.

A question to the experts: This pseudo popup-menu inherits from a form, and therefore it looks differently from the regular PopupMenus. Is there a way to "hijack" the window opened by a TPopupMenu component and place the buttons into it?

A second question: In the Office applications the color selection toolbuttons are usually split: a dropdown button to show the popup menu, and a regular toolbutton the apply the previously selected color. Is there a way to distinguish that a mouse click occured on the arrow or button part of a TToolbutton with style tbsDropdown?

rvk

  • Hero Member
  • *****
  • Posts: 6169
Re: Can we create a multicolumn menu in Lazarus?
« Reply #12 on: October 12, 2015, 12:57:26 pm »
vkhoa, the attached demo maybe gets close to what you want. It creates a form as suggested by rvk onto which a series of speedbuttons are placed, each one with its assigned color. This form can be opend from a toolbutton.
Nice little demo  8-)

(This would make a nice alternative ColorPicker. The TColorDialog is always a separate dialog but this is much nicer)

A question to the experts: This pseudo popup-menu inherits from a form, and therefore it looks differently from the regular PopupMenus. Is there a way to "hijack" the window opened by a TPopupMenu component and place the buttons into it?
As TPopupMenu inherits from TMenu and that in turn uses the Windows-api to draw the menus I don't think it's possible to "hijack" that window. But what do you see different from the regular PopupMenus about this? I think it really looks good. I don't think Word uses TMenu for this either. The only thing might be that Word could be using a TPanel instead of a TForm to show this but I'm not sure.

A second question: In the Office applications the color selection toolbuttons are usually split: a dropdown button to show the popup menu, and a regular toolbutton the apply the previously selected color. Is there a way to distinguish that a mouse click occured on the arrow or button part of a TToolbutton with style tbsDropdown?
Yeah, that's a problem. The only way to use it with tbsDropdown is to actually assign a DropDownMenu to the button. Maybe TColorPopup should be inherited from TPopupMenu and instead of popping up a menu you popup the form. But all the normal events should be handled like it is a TPopupMenu to be able to assign this to the DropDownMenu of a TToolButton. Another option would be to assign a "dummy" TPopupMenu to the DropDownMenu and show the form in the OnPopup of that dummy TPopupMenu.

« Last Edit: October 12, 2015, 12:59:06 pm by rvk »

rvk

  • Hero Member
  • *****
  • Posts: 6169
Re: Can we create a multicolumn menu in Lazarus?
« Reply #13 on: October 12, 2015, 01:02:32 pm »
A question to the experts: This pseudo popup-menu inherits from a form, and therefore it looks differently from the regular PopupMenus. Is there a way to "hijack" the window opened by a TPopupMenu component and place the buttons into it?
I had a quick look at the TJvOfficeColorButton which is included in Jedi/JVCL.
It uses a panel to do this.

Code: Pascal  [Select][+][-]
  1.   TJvCustomOfficeColorButton = class(TJvCustomPanel, IJvHotTrack)
  2.   private
  3.     FMainButton: TJvColorSpeedButton;
  4.     FArrowButton: TJvSpeedButton;

wp

  • Hero Member
  • *****
  • Posts: 11923
Re: Can we create a multicolumn menu in Lazarus?
« Reply #14 on: October 12, 2015, 01:30:48 pm »
The TJvCustomOfficeColorButton represents the button with the arrow key, it corresponds to the TToolbutton used by myself. Of course the jvcl button is better because it distinguishes between the button and arrow areas. But it won't integrate into a toolbar as nicely as a TToolbutton child.

The office color panel shown in your screen shot, in the end, inherits from a plain old form, with many additions though, but should appear similar to the form of my demo. I'd expect to miss the shadow of a true popup menu as well. (I did not install the huge jcl library in Delphi any more, so I can't tell for sure).

My idea was: the popup windows opened from a toolbutton or a menu item, is nothing else than a "window" (in Windows terms). Therefore, it should be possible to insert another control (my color panel) into it.

 

TinyPortal © 2005-2018