[Lazarus] RE : gtk2 TCustomControl.Paint, InvalidateRect

Armin Diehl ad at ardiehl.de
Sat Jul 9 00:06:55 CEST 2011


Sorry for not providing enough information, i thought this would be a 
general problem with the gtk2 interface, this is not the case.

i have tried to track it down with a small test program that invalidates 
a square of 11 pixels and this worked. I compared the test program with 
the real one and the real one has a TScrollBar created in the 
TCustomControl. Without that scroll bar is works fine with gtk2, when i 
call InvalidateRect, paint will get called only with that rect (of 
cause, the first time will be the full control):
   FormCreate
   Paint ClipRect: Top:0 Right: 500 Bottom: 500 Left:0
   Paint ClipRect: Top:0 Right: 10 Bottom: 10 Left:0
   ...

now i add the ScrollBar in TPaintTest.Create:

   FormCreate
   Paint ClipRect: Top:0 Right: 481 Bottom: 500 Left:0
   Paint ClipRect: Top:0 Right: 481 Bottom: 500 Left:0
   Paint ClipRect: Top:0 Right: 481 Bottom: 500 Left:0
   ...

now we always get the full area to be updated with gtk2. With gtk1 and 
windows i also get 0,10,10,0 as expected.

Test program (complete project @ http://www.ardiehl.de/temp/painttest.zip)

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, LCLintf,
   StdCtrls, ExtCtrls, ComCtrls;

type
   TPaintTest = class (TCustomControl)
   protected
     procedure paint; override;
   private
     t : TTimer;
     ScrollBar : TScrollBar;
   public
     constructor Create(AOwner: TComponent); override;
     procedure invalidateTest(Sender:TObject);
   end;

   { TForm1 }

   TForm1 = class(TForm)
     Panel1: TPanel;
     StatusBar1: TStatusBar;
     procedure FormCreate(Sender: TObject);
   private
     { private declarations }
   public
     { public declarations }
   end;

var
   Form1: TForm1;

implementation

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
var t : TPaintTest;
begin
   writeln('FormCreate');
   width := 600; height := 600;
   t := TPaintTest.Create(self);
   t.Parent := panel1;
end;

constructor TPaintTest.Create(AOwner: TComponent);
begin
   inherited Create(AOwner);
   // with this scroll bar, Canvas.ClipRect always returns full area
   ScrollBar:= TScrollBar.Create(Self);
   ScrollBar.Kind := sbVertical;  ScrollBar.Align := alRight;
   ScrollBar.LargeChange := 100;  ScrollBar.Max := 1000;
   ScrollBar.Parent := Self;

   self.width := 500; self.height := 500;
   t := TTimer.create(self);  t.interval := 1000;
   t.onTimer := @invalidateTest;  t.enabled := true;
end;

procedure TPaintTest.paint;
var r : TRect;
begin
   r := Canvas.ClipRect;
   writeln ('Paint ClipRect: Top:',r.top,' Right: ',r.right,' Bottom: 
',R.Bottom,' Left:',r.Left);
end;

procedure TPaintTest.invalidateTest(Sender:TObject);
var r : TRect;
begin
   r.top := 0; r.Left:=0; r.Right:=10; r.Bottom:=10;
   if assigned(Parent) then
     InvalidateRect(Handle, @r, FALSE);
end;



{$R *.lfm}

end.




>>> Any idea what i can do ?
>>
>>
>> How to get an idea with such informations ? What's wrong
>> a) TGtk2WidgetSet.InvalidateRect
>> b) Canvas.ClipRect
>> ?
> A little bit more information would be indeed helpfull.
>
> One thing I noticed on ubuntu gnome is that Canvas.ClipRect is always the
> full region even when the region was only partially masked by another
> window. On solaris 10 with Java Desktop System, also gtk2, Canvas.ClipRect
> returns the area masked by the other window. So, this could even be a window
> manager "thing".
>
> Ludo
>
>
>
> --
> _______________________________________________
> Lazarus mailing list
> Lazarus at lists.lazarus.freepascal.org
> http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


-- 

----------------
GrĂ¼sse
Armin Diehl
ad at ardiehl.de





More information about the Lazarus mailing list