fix for #11190, implicit invalidates by SetBounds or SetVisibility inside OnPaint events are supported

git-svn-id: trunk@19601 -
This commit is contained in:
dmitry 2009-04-24 08:54:55 +00:00
parent fa42e89af3
commit 4ff5a5562a
3 changed files with 55 additions and 4 deletions

View File

@ -294,6 +294,16 @@ implementation
uses InterfaceBase, CarbonInt, CarbonProc, CarbonDbgConsts, CarbonUtils,
CarbonWSStdCtrls, CarbonCanvas, CarbonCaret;
var
// recursive number of draw events called by OSX
IsDrawEvent : Integer = 0;
// invalidated inside OnPaint event
InvalidPaint : Boolean = false;
// invalidating
IsRepaint : Boolean = false;
{------------------------------------------------------------------------------
Name: GetCarbonWidget
Params: AWidget - Pointer to control or window widget

View File

@ -39,13 +39,17 @@ function CarbonCommon_Draw(ANextHandler: EventHandlerCallRef;
AEvent: EventRef;
AWidget: TCarbonWidget): OSStatus; {$IFDEF darwin}mwpascal;{$ENDIF}
var
AStruct: PPaintStruct;
AStruct : PPaintStruct;
Win : WindowRef;
Content : HIViewRef;
begin
{$IFDEF VerbosePaint}
Debugln('CarbonCommon_Draw ', DbgSName(AWidget.LCLObject));
{$ENDIF}
inc(IsDrawEvent);
AWidget.Context := TCarbonControlContext.Create(AWidget);
try
// set canvas context
@ -57,11 +61,17 @@ begin
AWidget.Context.Reset;
// let carbon draw/update
Result := CallNextEventHandler(ANextHandler, AEvent);
if not isRepaint or ( AWidget.InheritsFrom(TCarbonCustomControl) and not (AWidget is TCarbonScrollingWinControl)) then
Result := CallNextEventHandler(ANextHandler, AEvent)
else
Result := noErr;
if (AWidget is TCarbonControl) and
(cceDraw in (AWidget as TCarbonControl).GetValidEvents) then
begin
// todo: find a way to erase old content
(AWidget as TCarbonControl).Draw;
end;
New(AStruct);
FillChar(AStruct^, SizeOf(TPaintStruct), 0);
@ -76,8 +86,23 @@ begin
end;
if AWidget.HasCaret then DrawCaret;
finally
FreeAndNil(AWidget.Context);
dec(IsDrawEvent);
if (IsDrawEvent = 0) and InvalidPaint then
begin
if not IsRepaint then
begin
IsRepaint := true;
Win:=HIViewGetWindow(AWidget.Widget);
HIViewFindByID( HIViewGetRoot(Win), kHIViewWindowContentID, Content);
HIViewSetNeedsDisplay(Content, true);
HIViewRender(Content);
IsRepaint:=false;
end;
InvalidPaint:=false;
end;
end;
{$IFDEF VerbosePaint}
Debugln('CarbonCommon_Draw end ', DbgSName(AWidget.LCLObject));
@ -453,3 +478,5 @@ begin
SizeOf(TLMessage), @AMessage);
end;
end;

View File

@ -748,13 +748,21 @@ end;
parent
------------------------------------------------------------------------------}
function TCarbonControl.SetBounds(const ARect: TRect): Boolean;
var
B :CGRect;
begin
Result := False;
if (IsDrawEvent > 0) then HIViewGetBounds(Frames[0], B);
if OSError(HIViewSetFrame(Frames[0], RectToCGRect(ARect)),
Self, SSetBounds, SViewFrame) then Exit;
// ensure bounds are send back to LCL once after creation
BoundsChanged;
if (IsDrawEvent > 0) and not Types.EqualRect( CGRectToRect(B), ARect) then
InvalidPaint := true;
Result := True;
end;
@ -885,11 +893,17 @@ end;
procedure TCarbonControl.ShowHide(AVisible: Boolean);
var
I: Integer;
v: Boolean;
begin
//DebugLn('TCarbonControl.ShowHide ' + DbgSName(LCLobject),' ', DbgS(AVisible));
v := IsVisible;
for I := 0 to GetFrameCount - 1 do
OSError(HIViewSetVisible(Frames[I], AVisible or (csDesigning in LCLobject.ComponentState)),
Self, 'ShowHide', SViewVisible);
if (IsDrawEvent > 0) and (AVisible <> v) and (AVisible or (csDesigning in LCLobject.ComponentState)) and (GetFrameCount>0) then
InvalidPaint := true;
end;
{------------------------------------------------------------------------------