Recent

Author Topic: Move Controls at Runtime  (Read 17176 times)

kupferstecher

  • Hero Member
  • *****
  • Posts: 604
Move Controls at Runtime
« on: January 09, 2016, 01:46:04 pm »
Hello All,

I'm trying to implement some kind of "Edit Mode" in my project where I can move controls and change their size. It should work in a similar way like the Lazarus form designer.

The moving I was able to implement by redirecting the OnMouseDown, OnMouseUp and OnMouseMove to custom methods.
But the problem is that the controls still receive some mouse events, TButton will change its color (in Win7) when the mouse is over it. TSpeedButton even fires a click event. Even if I redirect this as well then still the visual effect of the pushed button would be active.

I made trials with MouseCapture when entering the form area, but that resulted in other problems, that I couldn't handle (e.g. Menuebar didn't receive the first click after the mouse has been captured, etc.).

How can I prevent the controls to respond to the mouse?
or
What would be a good way to implement an "Edit Mode"?

Thanks for Your help!

PS: The solution should work as well under Linux.

Blaazen

  • Hero Member
  • *****
  • Posts: 3241
  • POKE 54296,15
    • Eye-Candy Controls
Re: Move Controls at Runtime
« Reply #1 on: January 09, 2016, 02:27:20 pm »
Lazarus uses flag csDesigning. Try to set:
Code: Pascal  [Select][+][-]
  1. ComponentState:=ComponentState+[csDesigning];
... now do the job ...
Code: Pascal  [Select][+][-]
  1. ComponentState:=ComponentState-[csDesigning];
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

kupferstecher

  • Hero Member
  • *****
  • Posts: 604
Re: Move Controls at Runtime
« Reply #2 on: January 09, 2016, 04:11:16 pm »
Thanks for the quick reply!

Unfortunately the bahaviour seems not to be changed, when moving the mouse over a Button, the color still changes and the button can be pressed.

There seems no writable access to ComponentState, what I did:
Code: Pascal  [Select][+][-]
  1. TEComponent = class(TComponent); //No idea why this is needed...
  2. IMPLEMENTATION
  3.  
  4. procedure TMainForm.BitBtn2Click(Sender: TObject);
  5. begin
  6.  cmdln('BitBtn2Click'); //Write to console
  7.  
  8.  if csDesigning in BitBtn2.ComponentState
  9.  then cmdln('csDesigning true')
  10.  else cmdln('csDesigning false');
  11.  
  12.  TEComponent(BitBtn2).SetDesigning(true,true);
  13.  
  14. //procedure SetDesigning(Value: Boolean; SetChildren : Boolean = True);
  15. end;                                        
  16.  

with the Console output after two clicks:
Code: Pascal  [Select][+][-]
  1. BitBtn2Click
  2. csDesigning false
  3. BitBtn2Click
  4. csDesigning true
  5.  
And no change of the Button behaviour.

What should actually happen after setting csDesigning?

Blaazen

  • Hero Member
  • *****
  • Posts: 3241
  • POKE 54296,15
    • Eye-Candy Controls
Re: Move Controls at Runtime
« Reply #3 on: January 09, 2016, 04:29:10 pm »
No idea. You will probably have to look to Lazaus sources.
There are more flags, [csNoStdEvents] in ControlStyle etc.
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

balazsszekely

  • Guest
Re: Move Controls at Runtime
« Reply #4 on: January 09, 2016, 04:45:20 pm »
I just converted the "SizeControl.pas" delphi unit(author: Angus Johnson) to lazarus. It works well on windows and although I removed any windows specific api's, it still not Linux/OSX ready. Feel free to make the necessary changes, for example replace messages from WM_  to LM_ , etc...

kupferstecher

  • Hero Member
  • *****
  • Posts: 604
Re: Move Controls at Runtime
« Reply #5 on: January 09, 2016, 06:52:18 pm »
I will have a closer look, thank You both!

KKAA

  • New Member
  • *
  • Posts: 20
Re: Move Controls at Runtime
« Reply #6 on: January 09, 2016, 07:23:21 pm »
Thanks for the quick reply!

Unfortunately the bahaviour seems not to be changed, when moving the mouse over a Button, the color still changes and the button can be pressed.


You can make descendant and override MouseMove and MouseEnter (or Paint thats a bit triky) by adding a left button verification, if its on, then you skip inherited part...
You get the idia? :)

kupferstecher

  • Hero Member
  • *****
  • Posts: 604
Re: Move Controls at Runtime
« Reply #7 on: January 09, 2016, 08:30:54 pm »
@KKAA
You mean a custom component like below? For TSpeedButton it actually works!
For TButton it doesn't. As far as I know the color change is done by Windows and not in a paint method by Lazarus. This could be an explanation.

So this could be an actual workaround, thanks!
Nevertheless I still have the hope for a more universal solution...

Code: Pascal  [Select][+][-]
  1. unit uPassiveButton;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5.   Classes, SysUtils, Buttons, Console;
  6.  
  7. Type
  8.   TPassiveButton = class(TSpeedButton) //won't work for TButton
  9.    public
  10.     passive: boolean;
  11.     Procedure MouseMove(Shift: TShiftState;X,Y: Integer);override;
  12.     Procedure MouseEnter();override;
  13.   end;
  14.  
  15. IMPLEMENTATION
  16.  
  17.  Procedure TPassiveButton.MouseMove(Shift: TShiftState;X,Y: Integer);
  18.  begin
  19.    if not passive then Inherited;
  20.  end;
  21.  
  22.  Procedure TPassiveButton.MouseEnter();
  23.  begin
  24.    if not passive then Inherited;
  25.  end;
  26.  
  27. end.  

KKAA

  • New Member
  • *
  • Posts: 20
Re: Move Controls at Runtime
« Reply #8 on: January 09, 2016, 09:02:48 pm »

For TButton it doesn't. As far as I know the color change is done by Windows and not in a paint method by Lazarus. This could be an explanation.


Yes, windows handeling almost all buttoncontrol behevior, so it is not much you can do with it. I prefer to use TBitBtn, or TSpeedBtn instead.

BTW you say that you use OnMouseMove, OnMouseEnter events. In your code they are never gonna fire when button have passive state, you need to handle it urself, like that, for example

Code: Pascal  [Select][+][-]
  1. unit PassiveButton;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Buttons;
  9.  
  10. type
  11.  
  12.   { TPassiveButton }
  13.  
  14.   TPassiveButton = class(TCustomSpeedButton)
  15.   private
  16.     FPassive: Boolean;
  17.   protected
  18.     procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
  19.   end;
  20.  
  21. implementation
  22.  
  23. { TPassiveButton }
  24.  
  25. procedure TPassiveButton.MouseMove(Shift: TShiftState; X, Y: Integer);
  26. begin
  27.   if not FPassive
  28.     then inherited MouseMove(Shift, X, Y)
  29.     else
  30.       if Assigned(OnMouseMove)
  31.         then OnMouseMove(Self,Shift,X,Y);
  32. end;
  33.  
  34. end.

kupferstecher

  • Hero Member
  • *****
  • Posts: 604
Re: Move Controls at Runtime
« Reply #9 on: January 11, 2016, 06:53:30 pm »
although I removed any windows specific api's, it still not Linux/OSX ready.

What would be necessary to make it suitable for Linux? I already had a closer look to the sources, but handling internal messages is new for me.
Is it correct that the messages defined in LMessages are already wrapped and available on all plattforms?

How about the color change when hovering TButton with the mouse, is this avoided with SizeControl.pas?

@KKAA Sure, this was just the minimal example for the test. But Thanks!

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Move Controls at Runtime
« Reply #10 on: January 11, 2016, 07:02:10 pm »
Just a FYI there is a sizeMove control in the cindy component library which has been ported to lcl from typhon guys you will have to download their tool and extract it from there your self though.
« Last Edit: January 11, 2016, 07:09:42 pm by taazz »
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

balazsszekely

  • Guest
Re: Move Controls at Runtime
« Reply #11 on: January 11, 2016, 09:27:41 pm »
Quote
@kupferstecher
What would be necessary to make it suitable for Linux? I already had a closer look to the sources, but handling internal messages is new for me.
Is it correct that the messages defined in LMessages are already wrapped and available on all plattforms?
It's a non-trivial task, that's for sure. The messages are defined in LMessages and available on every major platform, but the message handling system is different.

Quote
How about the color change when hovering TButton with the mouse, is this avoided with SizeControl.pas?
Yes, it's avoided.

Quote
@taazz
Just a FYI there is a sizeMove control in the cindy component library which has been ported to lcl from typhon guys you will have to download their tool and extract it from
there your self though.
Same as Sizecontrol, only works on windows. I did extract the component and converted back to lazarus + created a demo project:
   https://drive.google.com/file/d/0B9Me_c5onmWoZ0w4UjdJd3BZMjA/view?usp=sharing

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Move Controls at Runtime
« Reply #12 on: January 11, 2016, 11:58:46 pm »
Quote
@kupferstecher
What would be necessary to make it suitable for Linux? I already had a closer look to the sources, but handling internal messages is new for me.
Is it correct that the messages defined in LMessages are already wrapped and available on all plattforms?
It's a non-trivial task, that's for sure. The messages are defined in LMessages and available on every major platform, but the message handling system is different.

Quote
How about the color change when hovering TButton with the mouse, is this avoided with SizeControl.pas?
Yes, it's avoided.

Quote
@taazz
Just a FYI there is a sizeMove control in the cindy component library which has been ported to lcl from typhon guys you will have to download their tool and extract it from
there your self though.
Same as Sizecontrol, only works on windows. I did extract the component and converted back to lazarus + created a demo project:
   https://drive.google.com/file/d/0B9Me_c5onmWoZ0w4UjdJd3BZMjA/view?usp=sharing
I see. I have downloaded the files from the link above after I close a couple tasks on my list, I'll boot up my linux VM and see if I can do anything. BUT I'm not linux friendly, so I wouldn't get my hopes up in your position.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

balazsszekely

  • Guest
Re: Move Controls at Runtime
« Reply #13 on: January 12, 2016, 06:58:30 am »
Quote
@taazz
I see. I have downloaded the files from the link above after I close a couple tasks on my list, I'll boot up my linux VM and see if I can do anything. BUT I'm not linux friendly, so I wouldn't get my hopes up in your position.
It shouldn't be to difficult, but moving/resizing components on runtime isn't on my priority list + I spent way to much time with this. I guess it's up to OP now.

kupferstecher

  • Hero Member
  • *****
  • Posts: 604
Re: Move Controls at Runtime
« Reply #14 on: January 14, 2016, 12:31:15 pm »
I did extract the component and converted back to lazarus + created a demo project:
   https://drive.google.com/file/d/0B9Me_c5onmWoZ0w4UjdJd3BZMjA/view?usp=sharing
@GetMem: Thanks a lot! The demo works as expected.

I tried to understand the code, the actions responding to the mouse and keys are clear for me so far. But I can't find the place where the MouseDown and KeyDown is triggered or how the components are registered or if the Panel PanDesign somehow is registered.

@taazz: No hurry~

 

TinyPortal © 2005-2018