Recent

Author Topic: TScrollBox issue with scrollbars visible  (Read 11559 times)

mmxngg

  • New Member
  • *
  • Posts: 29
TScrollBox issue with scrollbars visible
« on: February 14, 2012, 10:30:30 am »
I have an application that create many components at runtime and i have a problem with TScrollBox when scrollbars are visible.

Try this example (with ScrollBox1 aligned to client)

Code: [Select]
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    ScrollBox1: TScrollBox;
    procedure Button1Click(Sender: TObject);
    procedure ScrollBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
var
  AddToLeft, AddToTop, X, Y: Integer;
  Test: TButton;
begin
  AddToTop := 0;
  for Y := 0 to 16 do
  begin
    AddToLeft := 0;
    for X := 0 to 16 do
    begin
      Test := TButton.Create(Form1);
      Test.Parent := ScrollBox1;
      Test.Top := AddToTop;
      Test.Left := AddToLeft;
      Test.Width := 80;
      Test.Height := 20;
      Inc(AddToLeft, 80);
    end;
    Inc(AddToTop, 20);
  end;
end;

procedure TForm1.ScrollBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  if (Shift = [ssLeft]) then
  begin
    Button1.Left :=X;
    Button1.Top :=Y;
  end;
end;

end.

When scrollbars are hidden it's all ok but when they are visible all buttons are redrawn. It happens only with TScrollBox and is very very slow  :(

It's a bug ?
Now i'm on Win7/32bits with Lazarus 1.0.4 FPC 2.6.0

User137

  • Hero Member
  • *****
  • Posts: 1791
    • Nxpascal home
Re: TScrollBox issue with scrollbars visible
« Reply #1 on: February 14, 2012, 01:45:22 pm »
That is 289 buttons  ::)  That might get slow on any system.

Depending what they are for, i'd replace them with 1 TPaintBox, and then draw buttons as images on it (drawn to canvas from TBitmap). You can use onMouseDown and onMouseUp events to register clicks.

mmxngg

  • New Member
  • *
  • Posts: 29
Re: TScrollBox issue with scrollbars visible
« Reply #2 on: February 14, 2012, 02:37:39 pm »
A bad way for skip a problem  ::) Without scrollbars you can have 1000 buttons on screen without a problem. Scrollbars seems call full repaint when not needed and yes...redraw 289 buttons is slow, but why redraw all for 1 pixel changed on other side ?

TPaintBox....it's a OOL ?  :-[

I can use it but i need to simulate all event (not just clicks) because i need a real object that can change size, position ecc. ecc. (ah real application don't use button, it's just an example)
Now i'm on Win7/32bits with Lazarus 1.0.4 FPC 2.6.0

theo

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1946
Re: TScrollBox issue with scrollbars visible
« Reply #3 on: February 14, 2012, 06:08:09 pm »
I don't understand. What is slow? Scrolling?

I don't have any problems here using Lazarus 0.9.31 r35319M FPC 2.6.0 x86_64-linux-gtk 2.
Creating 289 buttons takes a while, but after that it works fine.

mmxngg

  • New Member
  • *
  • Posts: 29
Re: TScrollBox issue with scrollbars visible
« Reply #4 on: February 14, 2012, 11:56:23 pm »
Move one components or simply make any visible change inside a scrollbox with scrollbars visible. It's recall paint method always on all descendant components, even when not need it. Take my example, click button1 and then try to move it around the scrollbox with and without scrollbars visible (maximize window or decrease buttons size if needed).

I tried with 200 roundrect. Move button1 by 1 pixel without scrollbars is immediate, with scrollbars takes 0.6 sec. on a 3.2Ghz....it's comic.

Tried on Delphi and it works well in both case.
« Last Edit: February 15, 2012, 08:49:13 am by mmxngg »
Now i'm on Win7/32bits with Lazarus 1.0.4 FPC 2.6.0

mmxngg

  • New Member
  • *
  • Posts: 29
Re: TScrollBox issue with scrollbars visible
« Reply #5 on: February 16, 2012, 04:42:28 am »
TScrollBox is too buggy with scroll active :(

- Some components inside it (TShape for example) need manual repaint when changed (i don't understand why)
- Force a repaint on all children when a component is moved inside it
- Strange SIGSEGV error when i try to draw inside it with canvas (but probabily it's a my wrong)

I replaced it with a custom control (from a TPanel) and i discovered that original TScrollBox is also really slow, not only on scrolling but also on create children inside it....what work does on this step ?
« Last Edit: February 16, 2012, 07:54:30 am by mmxngg »
Now i'm on Win7/32bits with Lazarus 1.0.4 FPC 2.6.0

theo

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1946

mmxngg

  • New Member
  • *
  • Posts: 29
Re: TScrollBox issue with scrollbars visible
« Reply #7 on: February 16, 2012, 01:13:27 pm »
Sorry but it's my first time with Lazarus and i'm very confused. I can't really understand what's my wrong and what needs a real fix. Now i maked a report with an example for all issues  :)
Now i'm on Win7/32bits with Lazarus 1.0.4 FPC 2.6.0

zeljko

  • Hero Member
  • *****
  • Posts: 1927
    • http://wiki.lazarus.freepascal.org/User:Zeljan
Re: TScrollBox issue with scrollbars visible
« Reply #8 on: February 17, 2012, 10:42:00 am »
Yes, win32 have really strange behaviour in this case. gtk2 and qt works fine.
Cannot remember form example, but maybe Tracking := True for scrollbars could help.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12345
  • Debugger - SynEdit - and more
    • wiki
Re: TScrollBox issue with scrollbars visible
« Reply #9 on: February 17, 2012, 12:14:18 pm »
The problem is in lcl\include\scrollingwincontrol.inc around line 200

Code: [Select]
procedure TScrollingWinControl.ScrollBy(DeltaX, DeltaY: Integer);
begin
  if HandleAllocated and IsWindowVisible(Handle) then
  begin
    TWSScrollingWinControlClass(WidgetSetClass).ScrollBy(Self, DeltaX, DeltaY);
    Invalidate;
  end
  else
    inherited ScrollBy(DeltaX, DeltaY);
end;

No idea, why there is an Invalidate.

At least on Windows it can be commented out.
And, then only the focused Control, will get repainted (even that may not be needed, but it is just one)

Commenting this out, may mean, that other WidgetSet need to be fixed then.


Please report on Mantis

zeljko

  • Hero Member
  • *****
  • Posts: 1927
    • http://wiki.lazarus.freepascal.org/User:Zeljan
Re: TScrollBox issue with scrollbars visible
« Reply #10 on: February 29, 2012, 02:27:14 pm »
@Martin ... yes there should not be invalidate. I guess it's there because of gtk or even gtk2.It's up to WS to call invalidate or not in this case..so Invalidate() should be removed from there.
I'll test those days all available platforms to me (carbon + qt on mac, gtk, gtk2 and qt on linux and win32 (but you've already tested as I can ssee)) and remove that (and fix ws which does not call update on handle after ScrollBy call).

 

TinyPortal © 2005-2018