Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2014-04

TCoolBar improvements

10 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Juha Manninen

TCoolBar was improved a lot by Vojtech Cihak.
See:
http://bugs.freepascal.org/view.php?id=25026

I am moving the discussion from bug tracker to here. Maybe others have comments, too.

> Drag cursor is wrong with QT but that is a QT widgetset issue. > With GTK2 it is better, although the left-right resize cursor for 2 bands side by side is wrong while moving mouse. Unfortunately, I cannot reproduce it here. Cursors look fine in both Qt4 and GTK2.

For me it happens with GTK2 and QT on Linux Mint 14.
1. Drag a band to the right side of another band.
2. Place mouse cursor on the grab-handle of the right side band. It is kind of between the 2 bands. Cursor correctly changes to horizontal resize.
3. Grab the handle (mouse down) and the cursor changes to "disallowed" sign. On Windows the cursor remains as "resize" which is correct.

On Windows the cursor changes to normal pointer when mouse goes over other controls on bands.
With QT + Linux the cursor is always "disallowed" when dragging.

With all widgetsets it is possible to drag and resize bands, only the cursor is wrong.

> For example the associated conrol's location goes wrong if you set its alignment. What does this mean: "set its alignment"? How can I see it? Do you mean changing control's --property Align when it is on band?

Yes, in Object Inspector set Align=alBottom or Align=alClient for a control which is attached to a band.
Strangely, after switching back to Align=alNone the positionsing logic is still broken. You can move the control manually. I still think the code should use AlignControls. It is part of LCL's design and solves cleanly exactly this kind of issues. I am afraid now you must do more hacks to fix the positioning and it will still not be good.

Juha

Reply by email

Vojtěch Čihák
to Juha Manninen

Hi,
?

Show quoted text 6 lines
For me it happens with GTK2 and QT on Linux Mint 14. 1. Drag a band to the right side of another band. 2. Place mouse cursor on the grab-handle of the right side band. It is kind of between the 2 bands. Cursor correctly changes to horizontal resize. 3. Grab the handle (mouse down) and the cursor changes to "disallowed" sign.

?> On Windows the cursor remains as "resize" which is correct.

On Windows the cursor changes to normal pointer when mouse goes over other controls on bands. With QT + Linux the cursor is always "disallowed" when dragging.

With all widgetsets it is possible to drag and resize bands, only the cursor is wrong.
?
I still cannot reproduce. I don't know why it happens, in the code is used only crDefault, crHSplit and crDrag.

Show quoted text 8 lines
Yes, in Object Inspector set Align=alBottom or Align=alClient for a control which is attached to a band. Strangely, after switching back to Align=alNone the positionsing logic is still broken. You can move the control manually. I still think the code should use AlignControls. It is part of LCL's design and solves cleanly exactly this kind of issues. I am afraid now you must do more hacks to fix the positioning and it will still not be good.

?
I see. I'll try to do something with it.
?
Coincidentaly, before two hours I installed Delphi7 Personal Edition to Wine and their implementation of TCoolBar isn't perfect too. For example, I can drag control away from band (on the second attempt). Also, when I put button on CoolBar it creates new band (it's OK) but it resizes the button to the full width of the CoolBar, which is pretty ugly. I tried to have more bands side by side in design time and in run time and I don't know how to it. II can only have each band on new line. Maybe it's possible only from code. But I believe it's possible somehow otehrwise the property Break shoudln't make sense. ?
On the other hand, TControlBar works fine in Delphi. That's where we loose yet. :D ?
I'll try to improve both.?
?
?
Have a nice day.
?
Vojt?ch?
?
PS: Did anyone try ECControls on Carbon already??

Reply by email

Juha Manninen
to Vojtěch Čihák
Vojt?ch ?ih?k wrote
I still cannot reproduce. I don't know why it happens, in the code is used only crDefault, crHSplit and crDrag.

Strange. How about others, can anybody reproduce the cursor issues?

I see. I'll try to do something with it.

Please consider using AlignControls. It gets called by LCL always at the right time when positioning is needed. You don't need to call the positioning code anywhere else from your code. It would be the optimal solution also performance-wise.
For dragging it may require extra state flags but should be doable.

Show quoted text 9 lines
Coincidentaly, before two hours I installed Delphi7 Personal Edition to Wine and their implementation of TCoolBar isn't perfect too. For example, I can drag control away from band (on the second attempt). Also, when I put button on CoolBar it creates new band (it's OK) but it resizes the button to the full width of the CoolBar, which is pretty ugly. I tried to have more bands side by side in design time and in run time and I don't know how to it. II can only have each band on new line. Maybe it's possible only from code. But I believe it's possible somehow otehrwise the property Break shoudln't make sense.

Yes, I mentioned the bugs in Delphi's Coolbar in our issue report note: http://bugs.freepascal.org/view.php?id=25026#c70092 It is very bad. If you look at the code you understand how they struggled to integrate a COM-control at design time. I think the Windows CoolBar works quite well at run-time, the problems are at design-time.

On the other hand, TControlBar works fine in Delphi. That's where we loose yet. :D I'll try to improve both.

Your thoughts are going the same route as mine when I initially made TCoolBar. First I though TControlBar was made after TCoolBar to solve the COM-control related issues. No, then I learned it is an older component, made already before Windows had a CoolBar COM-control.

I tried to learn the code of TControlBar, and maybe imitate its design (not copying code, just design) but it was a bad idea. It (also) is an absolute mess. I refactored some big functions into smaller ones and removed many "with"-blocks to understand it better. No...
Then I debugged the code but still could not really understand it. Uhhh... I wasted some time with it. For me it is amazing to see how poor quality code there is in parts of Delphi libraries. In general their design is very good but there are some really dark corners.

What more, Delphi's TControlBar has lots of code compared to its features. It has more or less the same features than our TCoolBar has now, but maybe 10 times more code.

My plan was to share code between TCoolBar and TControlBar in LCL. It would make sense because they are so similar.
I implemented TCoolBar first because I needed it for my Delphi porting exercises and it is used more commonly than TControlBar. If you improve TControlBar, consider sharing code between them. It may require moving one or both of the components to another unit, which is OK.

Juha

Reply by email

Juha Manninen
to Juha Manninen

I move a note from issue #26096 here.

Vojtech Cihak: ... LCL triggers 6-12 AlignControls on one CalculateAndAlign (just uncomment DebugLn() in these methods).

Naturally AlignControls and Resize are called often because you call CalculateAndAlign and Invalidate from around your code. CalculateAndAlign even calls ReAlign.
I have a feeling you did not study my original component design enough. It was very much based on AlignControls and CalculatePreferredSize.
After that no hacks were needed for the positioning. No ReAlign, no Invalidate (except for few special places)...
It followed the design of LCL and the intended usage of those functions. I also implemented BiDiMode after lots of trial and error and scratching my head. Your version does not support tried to change the code to use AlignControls and CalculatePreferredSize better but it requires many changes now. I will look at it later again (unless you do it).

On the other hand, the Drag'n'Drop and images in your version are _cool_ features, so the component is getting to hold up to its name. :)

Show quoted text 5 lines
I already observed TControlBar in Delphi7. It has no (published) bands. Components can be in multiple rows and height of higher controls is always rounded to integer-multiple of the first row. Control are movable at design time. I think it is not so hard task. I try to move common code of TCoolBar and TControlBar to some TCustomBar (or TBaseBar - if there'll be some abstract methods) - as you wrote on ML.

Yes. I don't know how much code can be shared. Having bands and not having bands is a big difference after all.

Juha

Reply by email

Vojtěch Čihák
to Juha Manninen

Hello,
?
BiDi mode for TCoolBar is on myToDo. I can also look for some optimalization, CalculateAndAlign is the most time consuming method, so I'll check if it's not called redundantly. I already started work on TControlBar but it will be pretty tricky to (almost) fully mimic Delphi behaviour. Both components and their bands are movable at design time. ?
For Juha: You mentioned on bugtracker (26199):
"Maybe Vojtech could add the relevant revisions to http://wiki.freepascal.org/Lazarus_1.2_fixes_branch [^] ?and they will go to Lazarus 1.2.4."
?
How can I do it? Simply by editing the wiki? I thought only Laz. developers can decide what will come to branch. ?
Thanks.
Vojt?ch?

Reply by email

Juha Manninen
to Vojtěch Čihák
Vojt?ch ?ih?k wrote
How can I do it? Simply by editing the wiki? I thought only Laz. developers can decide what will come to branch.

Yes, there is the "Submitted by others" section. The wiki history shows who has added the lines.
You are the author of the current version of TCoolBar and I recommend backporting it. I don't believe anybody else has objections.

Juha

Reply by email

Juha Manninen
to Vojtěch Čihák: ? BiDi mode for TCoolBar is on myToDo. I can also look for some optimalization,…
Vojt?ch ?ih?k wrote
I can also look for some optimalization, CalculateAndAlign is the most time consuming method, so I'll check if it's not called redundantly.

I don't think it is called redundantly but the calls to Invalidate and ReAlign trigger LCL to call AlignControls and Resize excessively. The right way is to move the logic from CalculateAndAlign to AlignControls and CalculatePreferredSize. See my original component, IMO this part of its design was good.

Juha

Reply by email

Vojtěch Čihák
to Juha Manninen

I've got one objection to AlignControls() method. It's implementation in LCL differs from Delphi. While in Delphi it comes with parameter AControl: TControl - currently aligned control, in LCL is this parameter always nil but method is triggered many times (as many controls container has). Therefore I am careful with using it; it can easily lead to redundant calculations. ?
Vojt?ch?

Reply by email

Mattias Gaertner
to Vojtěch Čihák
I've got one objection to AlignControls() method. It's implementation in LCL differs from Delphi. While in Delphi it comes with parameter AControl: TControl - currently aligned control, in LCL is this parameter always nil but method is triggered many times (as many controls container has). Therefore I am careful with using it; it can easily lead to redundant calculations.

Hint: When changing multiple properties use Disable/EnableAutoSizing:

http://wiki.lazarus.freepascal.org/Autosize_/_Layout#Reduce_overhead_with_DisableAutoSizing.2C_EnableAutoSizing

Mattias

Reply by email

Vojtěch Čihák
to Mattias Gaertner

Thanks.
?
It maybe help in TCoolBar but I guess it will be even more useful for TControlBar.? ?
I already edited the wiki (Merge requests / Submitted by others). ?
Vojt?ch?
______________________________________________________________

Show quoted text 5 lines
Od: Mattias Gaertner Komu: Datum: 22.05.2014 14:17 P?edm?t: Re: [Lazarus] TCoolBar improvements
I've got one objection to AlignControls() method. It's implementation in LCL differs from Delphi. While in Delphi it comes with parameter AControl: TControl - currently aligned control, in LCL is this parameter always nil but method is triggered many times (as many controls container has). Therefore I am careful with using it; it can easily lead to redundant calculations.

Hint: When changing multiple properties use Disable/EnableAutoSizing:

http://wiki.lazarus.freepascal.org/Autosize_/_Layout#Reduce_overhead_with_DisableAutoSizing.2C_EnableAutoSizing <http://wiki.lazarus.freepascal.org/Autosize_/_Layout#Reduce_overhead_with_DisableAutoSizing.2C_EnableAutoSizing>

Mattias

Reply by email