Recent

Author Topic: Does Lazarus support event bubbling, event propagation?  (Read 1761 times)

tu

  • New Member
  • *
  • Posts: 12
Does Lazarus support event bubbling, event propagation?
« on: November 16, 2024, 05:36:29 am »
I have a navigation sidebar as in attached image. I want all click event on Label and Inner Panel buddled to Outer Panel click event handler.

I tried but it seems event bubbling does not work.

Thank you very much,

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1452
    • Lebeau Software
Re: Does Lazarus support event bubbling, event propagation?
« Reply #1 on: November 16, 2024, 07:52:07 am »
I have a navigation sidebar as in attached image. I want all click event on Label and Inner Panel buddled to Outer Panel click event handler.

Simply assign the same event handler to each object. You can use the Sender parameter to know which object received the click, if needed.

I tried but it seems event bubbling does not work.

It would help to see what you actually tried.
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

tu

  • New Member
  • *
  • Posts: 12
Re: Does Lazarus support event bubbling, event propagation?
« Reply #2 on: November 16, 2024, 11:23:36 am »
Yep, I assigned the same event handler to each control and it worked. But it seems too many duplicated code  ::)

Is there anyway better? What is the best way we should use to handle event propagation with deep nested controls in LCL?  :)

Thaddy

  • Hero Member
  • *****
  • Posts: 16363
  • Censorship about opinions does not belong here.
Re: Does Lazarus support event bubbling, event propagation?
« Reply #3 on: November 16, 2024, 11:32:24 am »
Do you want propagation or demotion?
Both can be done in code, the latter being much slower, because propagation goes from the containing window down to a nested control.
« Last Edit: November 16, 2024, 05:45:44 pm by Thaddy »
There is nothing wrong with being blunt. At a minimum it is also honest.

tu

  • New Member
  • *
  • Posts: 12
Re: Does Lazarus support event bubbling, event propagation?
« Reply #4 on: November 16, 2024, 11:54:06 am »
Do you want propagation or demotion?
Both can be done in code, the latter being much slower, because propagation goes from the contaning window down to a nested control.

Can you give me some example code for both usecase?  Thank you so much :)

Maybe I need propagation event or bubbling event because I'm building a navigation sidebar using deep nested controls.

For example:
Code: Pascal  [Select][+][-]
  1. TPanel (Level 1) > TPanel (Level 2) > TLabel (Level 3)
  2.  
  3. TPanel (Level 1) > TPanel (Level 2) > TPanel (Level 3) > TLabel (Level 4)
  4.  

When click on child control I want to bubble event to Level 1 event handler.

Warfley

  • Hero Member
  • *****
  • Posts: 1850
Re: Does Lazarus support event bubbling, event propagation?
« Reply #5 on: November 16, 2024, 05:23:06 pm »
To me it sounds more like what you actually want to do is to create your own control with it's own events. The easiest way to do this is to create a new package with said control and then add it to lazarus so you can use it in the Form editor.

Alternatively if you do not necessarily need to have it in the GUI editor but are able to create the control by code, you can also just create a custom control in your project and create it normally.

As an Example you can take a look at this list control I've built some time ago: https://github.com/Warfley/LazSetup/blob/master/GUI/detailedlist.pas

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1452
    • Lebeau Software
Re: Does Lazarus support event bubbling, event propagation?
« Reply #6 on: November 16, 2024, 08:15:49 pm »
Yep, I assigned the same event handler to each control and it worked. But it seems too many duplicated code  ::)

What's being duplicated? There would only be 1 event handler.  Are you doing the event assignments in code instead of at design-time? Again, can you please show what you are actually doing that you are struggling with?

Is there anyway better?

Better than what, exactly?

What is the best way we should use to handle event propagation with deep nested controls in LCL?  :)

Like Warfley said, probably best to move the nested controls into a new component that exposes 1 new event to the application. Then it can create its own panels internally and have their events fire the new event.
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

Joanna from IRC

  • Hero Member
  • *****
  • Posts: 1274
Re: Does Lazarus support event bubbling, event propagation?
« Reply #7 on: November 16, 2024, 11:16:38 pm »
I’ve done things like this although I’m unfamiliar with the term bubbling.
You can use loop to access the parent of deeply nested controls until you get to top level.
✨ 🙋🏻‍♀️ More Pascal enthusiasts are needed on IRC .. https://libera.chat/guides/ IRC.LIBERA.CHAT  Ports [6667 plaintext ] or [6697 secure] channel #fpc  #pascal Please private Message me if you have any questions or need assistance. 💁🏻‍♀️

VisualLab

  • Hero Member
  • *****
  • Posts: 614
Re: Does Lazarus support event bubbling, event propagation?
« Reply #8 on: November 17, 2024, 02:31:20 am »
I’ve done things like this although I’m unfamiliar with the term bubbling.
You can use loop to access the parent of deeply nested controls until you get to top level.

Someone asked about this before (last year or two). Just to be clear: event handling in Object Pascal does not work like in JavaScript. GUI of window programs is not a website.

Generally: you don't need event propagation via bubbling. Use what was suggested to you. If something is unclear, show the code you have written so far, we will fix it. Or describe what you want to achieve in simple words (especially without JavaScript terms).

tu

  • New Member
  • *
  • Posts: 12
Re: Does Lazarus support event bubbling, event propagation?
« Reply #9 on: November 17, 2024, 05:40:07 am »
I’ve done things like this although I’m unfamiliar with the term bubbling.
You can use loop to access the parent of deeply nested controls until you get to top level.

Someone asked about this before (last year or two). Just to be clear: event handling in Object Pascal does not work like in JavaScript. GUI of window programs is not a website.

Generally: you don't need event propagation via bubbling. Use what was suggested to you. If something is unclear, show the code you have written so far, we will fix it. Or describe what you want to achieve in simple words (especially without JavaScript terms).

Yep I got the idea, I come from web so don't know much about desktop app  :)
What I want is just centralized event handler, so just assign each nested control with the same event handler of top-level parent control.
The reason I have many nested controls is for decorating/theming visual GUI  :)

VisualLab

  • Hero Member
  • *****
  • Posts: 614
Re: Does Lazarus support event bubbling, event propagation?
« Reply #10 on: November 17, 2024, 02:12:44 pm »
I have a navigation sidebar as in attached image. I want all click event on Label and Inner Panel buddled to Outer Panel click event handler.

Now after exchanging some information I think I know what the above question is about. If there are several controls on the form that are supposed to react to a click (OnClick), they can be handled by one procedure. All you need to do is attach this procedure to the OnClick event in: (1) the Object Inspector or in (2) the source code. I am attaching a small sample program. The click handler of individual controls is assigned to their OnClick event in the OnCreate event handler of the form (the main program window).

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls;
  9.  
  10. type
  11.   {TForm1}
  12.   TForm1 = class(TForm)
  13.     LabelA: TLabel;
  14.     LabelB: TLabel;
  15.     MemoInfo: TMemo;
  16.     PanelOne: TPanel;
  17.     PanelFour: TPanel;
  18.     PanelTwo: TPanel;
  19.     PanelNavigation: TPanel;
  20.     PanelThree: TPanel;
  21.     procedure FormCreate(Sender: TObject);
  22.     procedure PanelNavigationClick(Sender: TObject);
  23.   private
  24.  
  25.   public
  26.  
  27.   end;
  28.  
  29. var
  30.   Form1: TForm1;
  31.  
  32. implementation
  33.  
  34. {$R *.lfm}
  35.  
  36. {TForm1}
  37.  
  38. procedure TForm1.FormCreate(Sender: TObject);
  39. begin
  40.   {assigning the click handler to the events in the controls}
  41.   PanelOne.OnClick := @PanelNavigationClick;
  42.   PanelTwo.OnClick := @PanelNavigationClick;
  43.   PanelThree.OnClick := @PanelNavigationClick;
  44.   PanelFour.OnClick := @PanelNavigationClick;
  45.   LabelA.OnClick := @PanelNavigationClick;
  46.   LabelB.OnClick := @PanelNavigationClick;
  47. end;
  48.  
  49. procedure TForm1.PanelNavigationClick(Sender: TObject);
  50. var
  51.   LControl: TControl;
  52.   LText: String;
  53. begin
  54.   {control click handling}
  55.   LText := 'Clicked: ' + Sender.ClassName;
  56.   if Sender is TControl
  57.    then
  58.     begin
  59.      LControl := Sender as TControl;
  60.      LText := LText + ', ' + LControl.Name;
  61.     end;
  62.   MemoInfo.Lines.Add(LText);
  63. end;
  64.  
  65. end.

Joanna from IRC

  • Hero Member
  • *****
  • Posts: 1274
Re: Does Lazarus support event bubbling, event propagation?
« Reply #11 on: November 17, 2024, 03:57:21 pm »
@vieuallab assigning events to controls can also be done recursively passing the event address as a parameter and going through the lis of child controls of every child control.

If the event code is always the same For every control it simplifies it  a lot.
✨ 🙋🏻‍♀️ More Pascal enthusiasts are needed on IRC .. https://libera.chat/guides/ IRC.LIBERA.CHAT  Ports [6667 plaintext ] or [6697 secure] channel #fpc  #pascal Please private Message me if you have any questions or need assistance. 💁🏻‍♀️

VisualLab

  • Hero Member
  • *****
  • Posts: 614
Re: Does Lazarus support event bubbling, event propagation?
« Reply #12 on: November 17, 2024, 04:36:45 pm »
@vieuallab assigning events to controls can also be done recursively passing the event address as a parameter and going through the lis of child controls of every child control.

If the event code is always the same For every control it simplifies it  a lot.

Do you mean the Controls property? Yes, you can do that if the parent control (i.e. the one that holds the list of child controls) is of class TWinControl (or a derivative), for example TPanel (as in the example). But then you have to add code to select (filter) controls according to some criterion (which the programmer sets). Otherwise, each control present on the form (or other visual container) will get a pointer to the OnClick event handler. And there can be more controls on the form than those used for navigation. It all depends on whether the navigation panel has a fixed number of controls or if they are added dynamically at runtime. I am attaching a modified project for assigning events to controls.

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls;
  9.  
  10. type
  11.   {TForm1}
  12.   TForm1 = class(TForm)
  13.     LabelA: TLabel;
  14.     LabelB: TLabel;
  15.     MemoInfo: TMemo;
  16.     PanelOne: TPanel;
  17.     PanelFour: TPanel;
  18.     PanelTwo: TPanel;
  19.     PanelThree: TPanel;
  20.     PanelNavigation: TPanel;
  21.     procedure FormCreate(Sender: TObject);
  22.     procedure PanelNavigationClick(Sender: TObject);
  23.   private
  24.     procedure AssignClickHandler(AParent: TWinControl; const AHandler: TNotifyEvent);
  25.   public
  26.  
  27.   end;
  28.  
  29. var
  30.   Form1: TForm1;
  31.  
  32. implementation
  33.  
  34. {$R *.lfm}
  35.  
  36. {TForm1}
  37.  
  38. procedure TForm1.FormCreate(Sender: TObject);
  39. begin
  40.   {assigning the click handler to the events in the controls}
  41.   AssignClickHandler(PanelNavigation, @PanelNavigationClick);
  42. end;
  43.  
  44. procedure TForm1.AssignClickHandler(AParent: TWinControl; const AHandler: TNotifyEvent);
  45. var
  46.   i: Integer;
  47.   LAnyControl: TControl;
  48.   LWinControl: TWinControl;
  49. begin
  50.   {assigning the "PanelNavigationClick" event handler to the "OnClick" event in
  51.    all child controls belonging to the navigation panel}
  52.   for i := 0 to AParent.ControlCount - 1 do
  53.    begin
  54.     LAnyControl := AParent.Controls[i];
  55.     LAnyControl.OnClick := AHandler;
  56.     {if the selected control is of the TWinControl class, it can have sub-controls
  57.      (i.e. it has the "Controls" property), but if it is of the "TGraphicControl"
  58.      class (such as "TLabel"), then this is not possible}
  59.     if LAnyControl is TWinControl
  60.      then
  61.       begin
  62.        LWinControl := LAnyControl as TWinControl;
  63.        if LWinControl.ControlCount > 0
  64.         then AssignClickHandler(Self, AHandler);
  65.       end;
  66.    end;
  67. end;
  68.  
  69. procedure TForm1.PanelNavigationClick(Sender: TObject);
  70. var
  71.   LControl: TControl;
  72.   LText: String;
  73. begin
  74.   {control click handling}
  75.   LText := 'Clicked: ' + Sender.ClassName;
  76.   if Sender is TControl
  77.    then
  78.     begin
  79.      LControl := Sender as TControl;
  80.      LText := LText + ', ' + LControl.Name;
  81.     end;
  82.   MemoInfo.Lines.Add(LText);
  83. end;
  84.  
  85. end.
« Last Edit: November 17, 2024, 04:39:05 pm by VisualLab »

 

TinyPortal © 2005-2018