GTK2 ScrollWindowEx

git-svn-id: trunk@34872 -
This commit is contained in:
martin 2012-01-22 18:12:29 +00:00
parent 8d75d1d603
commit b46ea85bc3

View File

@ -7386,8 +7386,9 @@ var
Window: PGdkWindow;
{$ifdef GTK_2_8}
Region: PGdkRegion;
Rect1: TGdkRectangle;
Rect2: TRect;
Rect1: TGdkRectangle; // full source rect
Rect1a: TGdkRectangle; // source rect for clip
Rect2: TRect; // area to invalidate
WidgetInfo: PWidgetInfo;
{$ENDIF}
begin
@ -7410,50 +7411,84 @@ begin
Rect1.Y := 0; //Widget^.Allocation.Y;
Rect1.width := Widget^.Allocation.Width;
Rect1.height := Widget^.Allocation.Height;
WidgetInfo := GetWidgetInfo(Widget, False);
if WidgetInfo <> nil then begin
if (dy < 0) then begin
if (WidgetInfo^.UpdateRect.Bottom > 0) then
Rect1.Height := Min(Rect1.height, WidgetInfo^.UpdateRect.Top);
Rect2 := Rect(0, Rect1.height + dy, Rect1.width, Widget^.Allocation.Height);
end;
if dy > 0 then begin
Rect1.y := Max(Rect1.y, WidgetInfo^.UpdateRect.Bottom);
Rect2 := Rect(0, 0, Rect1.width, Rect1.y + dy);
end;
end;
DebugLn(['ScrollWindowEx A ', dbgs(Rect1),' dy=',dy, ' scroll=',dbgs(prcScroll^), ' clip=',dbgs(prcClip^)]);
if PrcScroll <> nil then
begin
Rect1.x := PrcScroll^.Left;
Rect1.y := PrcScroll^.Top;
Rect1.width := PrcScroll^.Right - PrcScroll^.Left;
Rect1.height := PrcScroll^.Bottom - PrcScroll^.Top;
if (PrcClip <> nil) and EqualRect(PrcClip^, PrcScroll^) then
// do nothing
else
begin
Region := gdk_region_rectangle(@Rect1);
gdk_window_move_region(Window, Region, dx, dy);
Rect1.x := Max(Rect1.x, PrcScroll^.Left);
Rect1.y := Max(Rect1.y, PrcScroll^.Top);
Rect1.width := Min(Rect1.width - Rect1.x, PrcScroll^.Right - PrcScroll^.Left);
//Rect1.width := Min(Rect1.width - (Rect1.x - Widget^.Allocation.X), PrcScroll^.Right - PrcScroll^.Left);
Rect1.height := Min(Rect1.height - Rect1.y, PrcScroll^.Bottom - PrcScroll^.Top);
end;
if (PrcClip <> nil) then begin
// Limit the source rect, so it will fit into PrcClip
Rect1a.x := Max(PrcClip^.Left - dx, Rect1.x);
Rect1a.y := Max(PrcClip^.Top - dy, Rect1.y);
Rect1a.width := Min(PrcClip^.Right - dx - Rect1.x, Rect1.width);
Rect1a.height := Min(PrcClip^.Bottom - dy - Rect1.y, Rect1.height);
end
else
Rect1a := Rect1;
DebugLn(['ScrollWindowEx B ', dbgs(Rect1), ' ', dbgs(Rect1a)]);
WidgetInfo := GetWidgetInfo(Widget, False);
if WidgetInfo <> nil then begin
DebugLn(['ScrollWindowEx C ', dbgs(WidgetInfo^.UpdateRect)]);
// exclude allready invalidated area
if (WidgetInfo^.UpdateRect.Right >= Rect1a.x + Rect1a.width) and
(WidgetInfo^.UpdateRect.Left <= Rect1a.x)
then begin
if (dy < 0) and (WidgetInfo^.UpdateRect.Bottom > 0) then
Rect1a.Height := Min(Rect1a.y + Rect1a.height,
WidgetInfo^.UpdateRect.Top) - Rect1a.y;
if (dy > 0) and (Rect1a.y < WidgetInfo^.UpdateRect.Bottom) then begin
Rect1a.height := Rect1a.height - (WidgetInfo^.UpdateRect.Bottom - Rect1a.y);
Rect1a.y := WidgetInfo^.UpdateRect.Bottom;
end;
end;
end else
begin
Region := gdk_region_rectangle(@Rect1);
// TODO: content moved into currently invalidated space, may reduce the inval rect
if (WidgetInfo^.UpdateRect.Bottom >= Rect1a.y + Rect1a.height) and
(WidgetInfo^.UpdateRect.Top <= Rect1a.y)
then begin
if (dx < 0) and (WidgetInfo^.UpdateRect.Right > 0) then
Rect1a.width := Min(Rect1a.x + Rect1a.width,
WidgetInfo^.UpdateRect.Left) - Rect1a.x;
if (dx > 0) and (Rect1a.x < WidgetInfo^.UpdateRect.Right) then begin
Rect1a.width := Rect1a.width - (WidgetInfo^.UpdateRect.Right - Rect1a.x);
Rect1a.x := WidgetInfo^.UpdateRect.Right;
end;
end;
end;
DebugLn(['ScrollWindowEx D ', dbgs(Rect1a)]);
if (Rect1a.height > 0) and (Rect1a.width > 0) then begin
// Calculate area to invalidate
// Rect1a.y may either be equal or greater than Rect1.y
// Rect1a.height may either be equal or less than Rect1.height
if (dy < 0) then
Rect2 := Rect(Rect1.x, Rect1a.y + Rect1a.height + dy,
Rect1.width, Rect1.y + Rect1.height);
if dy > 0 then
Rect2 := Rect(Rect1.x, Rect1.y,
Rect1.width, Rect1a.y + dy);
// Todo dx
DebugLn(['ScrollWindowEx E ', dbgs(Rect2)]);
Region := gdk_region_rectangle(@Rect1a);
gdk_window_move_region(Window, Region, dx, dy);
end
else begin
// invalidate, nothing to scroll
Rect2 := Rect(Rect1.x, Rect1.y, Rect1.x + Rect1.width, Rect1.y + Rect1.height);
DebugLn(['ScrollWindowEx F ', dbgs(Rect2)]);
end;
// Rect2 includes the Area at the scroll-in side of Rect1
// gdk_window_move_region is supposed to have invalidated it, but some
// implementations seem not to do this. (bug 14297)
if (prcScroll <> nil) then
begin
if prcClip <> nil then
Rect1 := GdkRectFromRect(prcClip^)
else
Rect1 := GdkRectFromRect(prcScroll^);
gtk_widget_draw(Widget, @Rect1);
end else
if (dy <> 0) then
InvalidateRect(hWnd, @Rect2, false);
{$ELSE}