Recent

Author Topic: Custom component: Capture clicks and select an item in Designer  (Read 1954 times)

hukka

  • New Member
  • *
  • Posts: 26
    • Github
Custom component: Capture clicks and select an item in Designer
« on: January 06, 2023, 08:16:07 pm »
Hello,

I have a custom Toolbar component which represents its buttons as TCollectionItems in a TOwnedCollection. These items are drawn by the toolbar component itself. Now I would like to capture clicks in the toolbar component in the IDE Designer and select the corresponding TCollectionItem to be edited in the IDE. This is easy to do runtime with the TTIPropertyGrid component:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.cvToolBarMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  2. begin
  3.     TIPropertyGrid1.TIObject := cvToolbar.ClickedItem; // <- ClickedItem = a TCollectionItem variable of the toolbar
  4. end;

How would I accomplish the same in the Lazarus IDE itself? That is,
  • Capture mouse clicks (with X, Y location) on my component while in Designer?
  • Select the corresponding TCollectionItem (Toolbar.Items[N]) in the Object Inspector?

JuhaManninen

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4459
  • I like bugs.
Re: Custom component: Capture clicks and select an item in Designer
« Reply #1 on: January 07, 2023, 08:04:49 am »
Code: Pascal  [Select][+][-]
  1. procedure TForm1.cvToolBarMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  2. begin
  3.     TIPropertyGrid1.TIObject := cvToolbar.ClickedItem; // <- ClickedItem = a TCollectionItem variable of the toolbar
  4. end;
How is the cvToolbar.ClickedItem updated before the MouseDown event?
It would be useful to see source code of your component.
Mostly Lazarus trunk and FPC 3.2 on Manjaro Linux 64-bit.

hukka

  • New Member
  • *
  • Posts: 26
    • Github
Re: Custom component: Capture clicks and select an item in Designer
« Reply #2 on: January 07, 2023, 03:16:22 pm »
How is the cvToolbar.ClickedItem updated before the MouseDown event?
It would be useful to see source code of your component.
Thanks for the reply. Getting the clicked item at runtime amounts to this:

Code: Pascal  [Select][+][-]
  1. function TcvToolbar.GetItemAt(X, Y: Integer): TcvToolbarItem;
  2. var
  3.     i: Integer;
  4.     P: TPoint;
  5. begin
  6.     Result := nil;
  7.     if csCreating in ControlState then Exit;
  8.     if (FItems = nil) or (FItems.Count < 1) then Exit;
  9.  
  10.     P := Point(X, Y);
  11.  
  12.     for i := 0 to FItems.Count-1 do
  13.     begin
  14.         if PtInRect(P, FItems[i].Bounds) then Exit(FItems[i]);
  15.     end;
  16. end;
  17.  
  18. procedure TcvToolbar.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  19. begin
  20.     ClickedItem := GetItemAt(X, Y);
  21.     ....
  22. end;

I'm attaching the source; requires BGRABitmap. My mousedown handler and some commented code from playing around with the IDE are around the bottom of cvToolbar.pas.
« Last Edit: January 07, 2023, 03:21:02 pm by hukka »

JuhaManninen

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4459
  • I like bugs.
Re: Custom component: Capture clicks and select an item in Designer
« Reply #3 on: January 07, 2023, 05:15:48 pm »
I see you have studied the designer and property editing interfaces.
I am not sure if they ever have been used the way you want to use them, but it should be possible.
Usually there is a dedicated component editor for collections.
For example see RegisterComponentEditor(TStatusBar, TStatusBarComponentEditor); (unit StatusBarPropEdit).
You can follow the code and try to make the same effect without a component editor. I don't know right away how to do it. Component and property editors are a complex issue with messages going back and forth.

To debug your code you must install your component and debug the whole IDE. It is not a problem, lazarus.lpi project can be used for it.
Mostly Lazarus trunk and FPC 3.2 on Manjaro Linux 64-bit.

hukka

  • New Member
  • *
  • Posts: 26
    • Github
Re: Custom component: Capture clicks and select an item in Designer
« Reply #4 on: January 07, 2023, 06:08:32 pm »
All right, thanks for the answer. I'll have a look at the component editor code. It's not a big deal anyway, just something I thought would've been nice to have in my component. At least the TTIPropertyGrid component works great and I can use it to let the user customize the toolbar in my app. 8)

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Custom component: Capture clicks and select an item in Designer
« Reply #5 on: January 07, 2023, 06:22:31 pm »
Your ClickedItem and HoveredItem are public, and so not available in the Object Inspector.
And your published Items property is the entire collection, so cannot show selection of any individual item, and your
Code: [Select]
Items.Item[x]array property is a type of property that cannot be published.



hukka

  • New Member
  • *
  • Posts: 26
    • Github
Re: Custom component: Capture clicks and select an item in Designer
« Reply #6 on: January 07, 2023, 06:35:39 pm »
Your ClickedItem and HoveredItem are public, and so not available in the Object Inspector.
And your published Items property is the entire collection, so cannot show selection of any individual item, and your
Code: [Select]
Items.Item[x]array property is a type of property that cannot be published.

Hi,
The items are already visible and editable in the component editor. I'd only like to automatically select the one I click on the toolbar component. I should've just posted an image to clarify in my first post:

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Custom component: Capture clicks and select an item in Designer
« Reply #7 on: January 07, 2023, 10:19:44 pm »
Are you able to post a compilable project that produces the screenshot you show?
The code in your earlier post cannot be made into a compilable project because of missing BCxxxx unit dependencies.

JuhaManninen

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4459
  • I like bugs.
Re: Custom component: Capture clicks and select an item in Designer
« Reply #8 on: January 08, 2023, 11:08:48 am »
Are you able to post a compilable project that produces the screenshot you show?
The code in your earlier post cannot be made into a compilable project because of missing BCxxxx unit dependencies.
Actually it is not a project but a package, although the .lpk file was not provided.
Yes, a full package ready to compile and install would be nice. Somebody could maybe help solving the designer integration problem. I don't promise to do that myself though.
Mostly Lazarus trunk and FPC 3.2 on Manjaro Linux 64-bit.

hukka

  • New Member
  • *
  • Posts: 26
    • Github
Re: Custom component: Capture clicks and select an item in Designer
« Reply #9 on: January 08, 2023, 04:12:10 pm »
Sure, here's the installable package. Requires BGRABitmap and BGRAControls.

hukka

  • New Member
  • *
  • Posts: 26
    • Github
Re: Custom component: Capture clicks and select an item in Designer
« Reply #10 on: January 21, 2023, 03:29:44 am »
I have now managed to solve it – turns out the solution was in the wiki.
Specifically this:
Code: Pascal  [Select][+][-]
  1. procedure ThToolbar.CMDesignHitTest(var Message: TLMessage);
  2. begin
  3.   Message.Result := 1;
  4. end;
  5.  
  6. procedure ThToolbar.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  7. begin
  8.   ClickedItem := GetItemAt(X, Y);
  9.   if csDesigning in ComponentState then
  10.   begin
  11.         GlobalDesignHook.SelectOnlyThis(ClickedItem);
  12.         Exit;
  13.   end;
  14.   ...
  15.  

and now my MouseDown handler gets called in the IDE and the proper toolbar item gets selected as I click on it.

 

TinyPortal © 2005-2018