Lazarus

Free Pascal => Beginners => Topic started by: heebiejeebies on April 20, 2021, 01:39:40 pm

Title: [Solved!!!] Getting basic state-dependent properties for a component
Post by: heebiejeebies on April 20, 2021, 01:39:40 pm
Hi everyone!  :)

I have asked this question before, buried in the depths of another question, but I didn't really get any useful answers - so I'll ask it again as the main question.

In my current scenario, I need to get the currently selected value of a PopupMenu.  To me, it would be logical that this would be something like "if PopupMenu1.SelectedItem = 'My item' then;...

But I have tried everything I can think of in place of 'SelectedItem' and I still can't find what the correct property name is.  The wiki always seems to give a million things that I'll never use, and of course it gives all the properties that you can easily see and change in the object inspector.  But it never seems to give the basic state-dependent properties like what item is selected from the PopupMenu.  Someone suggested I type the component name and a dot, then wait for a menu to appear offering all options.  Yes, the menu appeared - but I still can't see any option that gives me the currently selected item in the PopupMenu!

So my question is: surely there's a simple property name that represents the currently selected menu item in a popup menu, but more importantly so I don't have to annoy you guys every single time....

Surely there's a way I can figure these out for myself without having to ask??  And just in case you didn't read the whole post, that's evidently not the wiki!   :D

Thank you very much!  :)
Title: Re: Getting basic state-dependent properties for a component
Post by: Zvoni on April 20, 2021, 02:12:16 pm
IIRC, a popup-menu (as well as a regular menu)-item, has three ways to "act" (I'm not talking about menu-items which contain a submenu):
1) The regular way: Fire an Event
2) The Checkbox-Way: Turn option on or off
3) The Option-Button way: Out of a group only one is on, the others are off

example: On Windows, right-click on your desktop
a context-menu (also called a popup-menu) shows up.
The second to last entry should be something like "Display Options" (sorry, german Windows here "Anzeigeeinstellungen")
That would be an example for 1) --> It fires an event launching Display Options from control panel

Further, in that context-menu the first item should be "View" (german "Ansicht"), which has a "sub-menu", showing examples
for 2) --> "Show Desktop-Symbols"
for 3) --> "Big/Medium/Small Symbols"

For which one of those "ways" are you looking for a property?
Title: Re: Getting basic state-dependent properties for a component
Post by: Handoko on April 20, 2021, 02:18:47 pm
Maybe a video tutorial can help:
https://www.youtube.com/watch?v=dcZd5HaiwyA
Title: Re: Getting basic state-dependent properties for a component
Post by: Gustavo 'Gus' Carreno on April 20, 2021, 11:26:46 pm
Hey heebiejeebies,

The question you ask: "In my current scenario, I need to get the currently selected value of a PopupMenu" doesn't make sense to me, so I'll need a bit more clarification.

A component that as the concept of a selected item is usually something with the name List on it, like a ListBox.
On a ListBox there is a property called ItemIndex that if it's value is different than -1, an Item of the List is selected.
It makes sense to maintain this selected state since selecting an item on a list is the first of any number of following actions.

To select a menu is a single action concept that does not need to maintain state for any other action.

This concept does not translate into menus, because when you select a menu item, it immediately fires the OnClick event and that's it, there's no maintained state.
If you want to know what menu item was selected, then you have two way:

So, it really begs the question: Why do you think that there should be a concept of a selected state after the action/event has been triggered?

Cheers,
Gus
Title: Re: Getting basic state-dependent properties for a component
Post by: heebiejeebies on April 21, 2021, 01:10:21 am
Thanks again everyone!  I realise now that I misinterpreted the purpose of the PopupMenu - I thought it was just a menu that popped up anywhere on the form and allowed you to select between various options.  Like the audio input selectors in Audacity, for example.  I was wondering why it wasn't appearing and thought that was another rabbit hole I'd have to go down! I managed to mock it up so that it pops up with a left-click on a TButton, and then whatever option you choose changes the caption of the TButton to that option.  Is that really the only way to do it though?  It looks a bit ugly and non-standard. I thought the other way was a reasonably standard UI item?  %)
Title: Re: Getting basic state-dependent properties for a component
Post by: jamie on April 21, 2021, 01:38:06 am
most controls have a PopupMenu property.. you Assign what ever popup you design to that property...

When you RIGHT click on that control the menu will popup..

There is a OnPopUp event  you can use which carries the sender, that reports what control popped it.

Each MenuItem has a onClick..
Title: Re: Getting basic state-dependent properties for a component
Post by: heebiejeebies on April 21, 2021, 03:55:44 am
Thanks Jamie.

So just to confirm, there's no way to do a simple, always-there popup menu like these in Lazarus?:

https://i.postimg.cc/4xym0k7f/audacity.png

Thanks guys
Title: Re: Getting basic state-dependent properties for a component
Post by: speter on April 21, 2021, 05:25:08 am
I am not sure, but you may be referring to a toolbar.

As others have explained a popup menu is generally something that appears in response to a right mouse button click, and displays a menu allowing the user to select a menu-item.

cheers
S.
Title: Re: Getting basic state-dependent properties for a component
Post by: heebiejeebies on April 21, 2021, 07:53:56 am
Not a toolbar or a coolbar.  I'm only talking about the pop-up menus in the middle of the Audacity toolbar that I linked.

Anyway, looks like there's no way to do it. Quite strange! But I'll work around it. Thanks everyone
Title: Re: Getting basic state-dependent properties for a component
Post by: Handoko on April 21, 2021, 08:12:40 am
I saw no popup menu in the screenshot you provided. Maybe what you meant is TComboBox.
Title: Re: Getting basic state-dependent properties for a component
Post by: heebiejeebies on April 21, 2021, 09:12:10 am
I saw no popup menu in the screenshot you provided. Maybe what you meant is TComboBox.

Right in the middle where it says "ALSA", "HDA Intel..." "2 (Stereo)" and "default".  These are pop up menus that are always visible, and accessible with the left mouse button.  I would have demonstrated them but Ubuntu won't take a screenshot while a menu is popped up.

You're so close with the combo box.  That's very nearly it, except that you can edit the options.  Mine needs to be just a read-only list, and unfortunately the ReadOnly property refuses to enable.  According to the wiki, that property is deprecated.
Title: Re: Getting basic state-dependent properties for a component
Post by: Handoko on April 21, 2021, 10:07:18 am
I'm not sure what you want but maybe you can try my custom popup:
https://forum.lazarus.freepascal.org/index.php/topic,37369.msg250939.html#msg250939 (https://forum.lazarus.freepascal.org/index.php/topic,37369.msg250939.html#msg250939)
Title: Re: Getting basic state-dependent properties for a component
Post by: Zvoni on April 21, 2021, 10:18:17 am
I think what he's looking for is ToolButton, which appears to be a member of a ToolBar

https://lazarus-ccr.sourceforge.io/docs/lcl/comctrls/ttoolbutton.html
Title: Re: Getting basic state-dependent properties for a component
Post by: lucamar on April 21, 2021, 10:45:18 am
You're so close with the combo box.  That's very nearly it, except that you can edit the options.  Mine needs to be just a read-only list, and unfortunately the ReadOnly property refuses to enable.  According to the wiki, that property is deprecated.

What you want is indeed a TComboBox with Style set to csDropDownList which shouldn't allow editing.

However it will neither look or behave like the Audacity one because Audacity uses wxWidget which is not available (AFAIK) for Lazarus/FPC; moreover, after some testing (Linux x86_64) I've discovered that whatever style you use you can always type something in the "edit" section, so the behaviour seems to be either widgetset-dependant or "buggy".

You can approximate what you want with a TToolButton associated to a TPopupMenu but then you'll have to keep track of the "selected item" through each item's OnClick. That's not as hard as it sounds: you can just use  a single OnClick handler for all menu items and assign inside it some property/variable depending on which item was actually clicked. If it's a property, its writer could then update the caption of the button and do whatever else you want it to do.

Of course, it's not easy as (almost) all that being done automagically but it's doable and not much code needs be added.

HTH!
Title: Re: Getting basic state-dependent properties for a component
Post by: Zvoni on April 21, 2021, 11:09:37 am
To finish this off:
are you looking for something like this?: https://blog.dummzeuch.de/2014/08/31/showing-a-dropdown-menu-when-clicking-a-button/
Title: Re: Getting basic state-dependent properties for a component
Post by: kupferstecher on April 21, 2021, 12:08:56 pm
moreover, after some testing (Linux x86_64) I've discovered that whatever style you use you can always type something in the "edit" section, so the behaviour seems to be either widgetset-dependant or "buggy".

Just testet with Laz 2.0.10 on LinuxMint 19.2 Cinnamon 64bit, works as expected there.
Title: Re: Getting basic state-dependent properties for a component
Post by: heebiejeebies on April 21, 2021, 03:08:22 pm
Thanks everyone for the suggestions!  I already had the workaround which was showing the PopupMenu when clicking a button, but to me (At least for my purposes) it looks clunky and non-standard.  Lucamar nailed it - I need a TCombobox with style set to csDropdownlist.  That works perfectly for me - I can't edit it at all?  Hope it is the same for my users.   %)  I'll try it anyway and see how it goes.  Thanks everyone!
Title: Re: Getting basic state-dependent properties for a component
Post by: lucamar on April 21, 2021, 05:35:47 pm
Just testet with Laz 2.0.10 on LinuxMint 19.2 Cinnamon 64bit, works as expected there.

You're right. I re-tested and it works as it should. I must heve done something wrong the first time ... like forgetting to set the correct Style :-[

Hope it is the same for my users.

It should; to pay for my carelessnes I tested both Windows (32 bit) and Linux (32/64 bits) and it worked correctly everywhere. Sorry about the previous "noise" :-[ :-[
Title: Re: Getting basic state-dependent properties for a component
Post by: heebiejeebies on April 22, 2021, 06:19:37 am
No problems at all, thanks heaps for finding the right component - I'd never have found it!  :D
Title: Re: Getting basic state-dependent properties for a component
Post by: heebiejeebies on April 22, 2021, 10:14:31 am
Btw just for any future Googlers, in answer to the initial question, it seems that, yes, typing the component name followed by a dot in the script editor does bring up all the relevant properties and procedures that can be applied to that component.  In this case, the original property that I was looking for was simply the Caption.  With a TComboBox, whatever the user selects becomes the caption. Easy  :D
Title: Re: Getting basic state-dependent properties for a component
Post by: lucamar on April 22, 2021, 11:21:36 am
In this case, the original property that I was looking for was simply the Caption.  With a TComboBox, whatever the user selects becomes the caption. Easy  :D

Rather than Caption, for a combo box I'd recommend you read the Text property. Though both will, probably, return the same.
TinyPortal © 2005-2018