customdrawn: Implements TButton clicking, implements InvalidateRect in X11

git-svn-id: trunk@33870 -
This commit is contained in:
sekelsenmat 2011-11-30 14:05:01 +00:00
parent fdf484944c
commit 5774ecec7d
13 changed files with 108 additions and 62 deletions

View File

@ -64,6 +64,7 @@ type
destructor Destroy; override;
procedure EraseBackground(DC: HDC); override;
procedure Paint; override;
// Methods for use by LCL-CustomDrawn
procedure DrawToCanvas(ACanvas: TCanvas);
end;
TCDControlClass = class of TCDControl;

View File

@ -253,6 +253,7 @@ function TCustomButton.ChildClassAllowed(ChildClass: TClass): boolean;
begin
// no children
Result:=false;
if Widgetset.GetLCLCapability(lcAllowChildControlsInNativeControls) = LCL_CAPABILITY_YES then Result := True;
end;
class function TCustomButton.GetControlClassDefaultSize: TSize;

View File

@ -84,7 +84,8 @@ type
// is amDontCare = amOn for the widgetset
lcLMHelpSupport, // support for LM_HELP command
lcReceivesLMClearCutCopyPasteReliably, // In Carbon we do not receive LM_CLEAR, CUT, COPY, PASTE, etc reliably, and this affects DB controls. See bug http://bugs.freepascal.org/view.php?id=20394
lcSendsUTF8KeyPress // If the interface does not yet send UTF8KeyPress directly, then it will be emulated in TWinControl.CNChar
lcSendsUTF8KeyPress, // If the interface does not yet send UTF8KeyPress directly, then it will be emulated in TWinControl.CNChar
lcAllowChildControlsInNativeControls // Utilized by LCL-CustomDrawn so that it can inject child controls in native ones
);
{ TDialogButton }

View File

@ -492,6 +492,7 @@ begin
Result := LCL_CAPABILITY_NO;
{$endif}
lcAntialiasingEnabledByDefault: Result := LCL_CAPABILITY_NO;
lcAllowChildControlsInNativeControls: Result := LCL_CAPABILITY_YES
else
Result := inherited GetLCLCapability(ACapability);
end;

View File

@ -25,6 +25,7 @@ type
Region: TLazRegionWithChilds;
WinControl: TWinControl;
CDControl: TCDControl;
Children: TFPList;
end;
TCDNonNativeForm = class
@ -197,9 +198,10 @@ procedure RenderChildWinControls(var AImage: TLazIntfImage;
var
i, lChildrenCount: Integer;
lCDWinControl: TCDWinControl;
lWinControl: TWinControl;
lWinControl, lParentControl: TWinControl;
struct : TPaintStruct;
lCanvas: TCanvas;
lBaseWindowOrg: TPoint;
begin
lChildrenCount := ACDControlsList.Count;
{$ifdef VerboseCDWinControl}
@ -214,44 +216,47 @@ begin
lCDWinControl := TCDWinControl(ACDControlsList.Items[i]);
lWinControl := lCDWinControl.WinControl;
{$ifdef VerboseCDWinControl}
DebugLn(Format('[RenderChildWinControls] i=%d lWinControl=%x Left=%d'
+ ' Top=%d Width=%d Height=%d', [i, PtrInt(lWinControl),
DebugLn(Format('[RenderChildWinControls] i=%d lWinControl=%x Name=%s:%s Left=%d'
+ ' Top=%d Width=%d Height=%d', [i, PtrInt(lWinControl), lWinControl.Name, lWinControl.ClassName,
lWinControl.Left, lWinControl.Top, lWinControl.Width, lWinControl.Height]));
{$endif}
if lWinControl.Visible = False then Continue;
// Prepare the clippping
// lBaseWindowOrg makes debugging easier
// Iterate to find the appropriate BaseWindowOrg relative to the parent control
lBaseWindowOrg := Point(lWinControl.Left, lWinControl.Top);
lParentControl := lWinControl.Parent;
while (lParentControl <> nil) and not (lParentControl is TCustomForm) do
begin
lBaseWindowOrg.X := lBaseWindowOrg.X + lParentControl.Left;
lBaseWindowOrg.Y := lBaseWindowOrg.Y + lParentControl.Top;
lParentControl := lParentControl.Parent;
end;
ACanvas.BaseWindowOrg := lBaseWindowOrg;
ACanvas.WindowOrg := Point(0, 0);
// Prepare the clippping relative to the form
ACanvas.Clipping := True;
lCDWinControl.Region.Rect := Bounds(lWinControl.Left, lWinControl.Top, lWinControl.Width, lWinControl.Height);
lCDWinControl.Region.Rect := Bounds(lBaseWindowOrg.X, lBaseWindowOrg.Y, lWinControl.Width, lWinControl.Height);
ACanvas.ClipRegion := lCDWinControl.Region;
ACanvas.UseRegionClipping := True;
ACanvas.BaseWindowOrg := Point(lWinControl.Left, lWinControl.Top);
ACanvas.WindowOrg := Point(0, 0);
// Save the Canvas state
ACanvas.SaveState;
ACanvas.ResetCanvasState;
// For custom controls
if lCDWinControl.CDControl = nil then
begin
{$ifdef VerboseCDWinControl}
DebugLn(Format('[RenderChildWinControls] i=%d before LCLSendPaintMsg', [i]));
{$endif}
LCLSendPaintMsg(lCDWinControl.WinControl, struct.hdc, @struct);
end
// For LCL native controls
else
begin
lCanvas := TCanvas.Create;
try
lCanvas.Handle := struct.hdc;
lCDWinControl.CDControl.DrawToCanvas(lCanvas);
finally
lCanvas.Handle := 0;
lCanvas.Free;
end;
end;
{$ifdef VerboseCDWinControl}
DebugLn(Format('[RenderChildWinControls] i=%d before LCLSendPaintMsg', [i]));
{$endif}
LCLSendPaintMsg(lCDWinControl.WinControl, struct.hdc, @struct);
// Now Draw all sub-controls
if lCDWinControl.Children <> nil then
RenderChildWinControls(AImage, ACanvas, lCDWinControl.Children);
{$ifdef VerboseCDWinControl}
DebugLn(Format('[RenderChildWinControls] i=%d Finished child controls', [i]));
{$endif}
// Now restore it
ACanvas.RestoreState;
@ -280,6 +285,11 @@ begin
if lRegionOfEvent.UserData = nil then
raise Exception.Create('[FindControlWhichReceivedEvent] Malformed tree of regions');
Result := TWinControl(lRegionOfEvent.UserData);
// If it is a native LCL control, redirect to the CDControl
if lCurCDControl.CDControl <> nil then
Result := lCurCDControl.CDControl;
Exit;
end;
end;

View File

@ -4656,7 +4656,7 @@ end;
function TQtWidgetSet.IsZoomed(Handle: HWND): boolean;
begin
Result := TQtWidget(Handle).isMaximized;
end;
end;*)
{------------------------------------------------------------------------------
Function: InvalidateRect
@ -4666,26 +4666,39 @@ end;
Returns:
------------------------------------------------------------------------------}
function TQtWidgetSet.InvalidateRect(aHandle: HWND; Rect: pRect; bErase: Boolean): Boolean;
function TCDWidgetSet.InvalidateRect(aHandle: HWND; Rect: pRect; bErase: Boolean): Boolean;
var
lHandle: TObject;
lControlHandle: TCDWinControl;
lControl: TWinControl;
begin
{$ifdef VerboseQtWinAPI}
{$ifdef VerboseCDWinAPI}
WriteLn('[WinAPI InvalidateRect]');
{$endif}
if AHandle = 0 then
exit(False);
if Rect <> nil then
if AHandle = 0 then exit(False);
lHandle := TObject(AHandle);
// Invalidate on a child control
if lHandle is TCDWinControl then
begin
with TQtWidget(aHandle).getClientOffset do
OffsetRect(Rect^, x, y);
// no need to handle bErase. Qt automatically erase rect on paint event according to docs
TQtWidget(aHandle).Update(Rect);
end else
TQtWidget(aHandle).Update;
lControlHandle := TCDWinControl(lHandle);
lControl := lControlHandle.WinControl;
while (lControl <> nil) and not (lControl is TCustomForm) do
lControl := lControl.Parent;
Result := BackendInvalidateRect(lControl.Handle, Rect, BErase);
end
// Invalidate on a form
else
begin
Result := BackendInvalidateRect(AHandle, Rect, BErase);
end;
Result := True;
end;
{------------------------------------------------------------------------------
(*{------------------------------------------------------------------------------
Function: InvalidateRgn
Params: aHandle:
Rect:

View File

@ -4650,7 +4650,7 @@ end;*)
Returns:
------------------------------------------------------------------------------}
function TCDWidgetSet.InvalidateRect(aHandle: HWND; Rect: pRect; bErase: Boolean): Boolean;
function TCDWidgetSet.BackendInvalidateRect(aHandle: HWND; Rect: pRect; bErase: Boolean): Boolean;
begin
{$ifdef VerboseCDWinAPI}
WriteLn('[TCDWidgetSet.InvalidateRect]');

View File

@ -4650,21 +4650,12 @@ end;*)
Returns:
------------------------------------------------------------------------------}
function TCDWidgetSet.InvalidateRect(aHandle: HWND; Rect: pRect; bErase: Boolean): Boolean;
function TCDWidgetSet.BackendInvalidateRect(aHandle: HWND; Rect: pRect; bErase: Boolean): Boolean;
var
lFormHandle: TX11WindowInfo;
begin
{$ifdef VerboseCDWinAPI}
WriteLn('[WinAPI InvalidateRect]');
{$endif}
if AHandle = 0 then
exit(False);
{ if Rect <> nil then
begin
with TQtWidget(aHandle).getClientOffset do
OffsetRect(Rect^, x, y);
// no need to handle bErase. Qt automatically erase rect on paint event according to docs
TQtWidget(aHandle).Update(Rect);
end else
TQtWidget(aHandle).Update;}
lFormHandle := TX11WindowInfo(AHandle);
TCDWSCustomForm.EvPaint(lFormHandle.LCLControl, lFormHandle);
Result := True;
end;

View File

@ -147,6 +147,7 @@ function GetWindowSize(Handle: hwnd; var Width, Height: Integer): boolean; overr
function HideCaret(hWnd: HWND): Boolean; override;*)
function InvalidateRect(aHandle : HWND; Rect : pRect; bErase : Boolean) : Boolean; override;
function BackendInvalidateRect(aHandle : HWND; Rect : pRect; bErase : Boolean) : Boolean;
(*function InvalidateRgn(aHandle: HWND; Rgn: HRGN; Erase: Boolean): Boolean; override;
procedure InitializeCriticalSection(var CritSection: TCriticalSection); override;
function IntersectClipRect(dc: hdc; Left, Top, Right, Bottom: Integer): Integer; override;

View File

@ -84,7 +84,7 @@ end;
class function TCDWSWinControl.CreateHandle(const AWinControl: TWinControl;
const AParams: TCreateParams): HWND;
var
lCDWinControl: TCDWinControl;
lCDWinControl, lCDParent: TCDWinControl;
begin
lCDWinControl := TCDWinControl.Create;
lCDWinControl.WinControl := AWinControl;
@ -94,7 +94,18 @@ begin
Result := HWND(lCDWinControl);
TCDWSCustomForm.BackendAddCDWinControlToForm(TCustomForm(AWinControl.Parent), lCDWinControl);
// Adding on a form
if AWinControl.Parent is TCustomForm then
begin
TCDWSCustomForm.BackendAddCDWinControlToForm(TCustomForm(AWinControl.Parent), lCDWinControl);
end
// Adding on another control
else if AWinControl.Parent is TWinControl then
begin
lCDParent := TCDWinControl(AWinControl.Parent.Handle);
if lCDParent.Children = nil then lCDParent.Children := TFPList.Create;
lCDParent.Children.Add(lCDWinControl);
end;
end;
class procedure TCDWSWinControl.DestroyHandle(const AWinControl: TWinControl);
@ -104,7 +115,7 @@ end;
class procedure TCDWSWinControl.Invalidate(const AWinControl: TWinControl);
begin
// lpRect = nil updates entire client area of window
//InvalidateRect(AWinControl.Handle, nil, true);
CDWidgetset.InvalidateRect(AWinControl.Handle, nil, true);
end;
class procedure TCDWSWinControl.ShowHide(const AWinControl: TWinControl);

View File

@ -530,7 +530,7 @@ begin
if XButtonToMouseButton(Event.button, MouseButton) then
begin
LCLSendMouseDownMsg(lTarget, Event.x, Event.y, MouseButton, []);
LCLSendMouseDownMsg(lTarget, Event.x, Event.y, MouseButton, [])
end
else
begin

View File

@ -199,6 +199,7 @@ type
class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; override;
// class procedure SetDefault(const AButton: TCustomButton; ADefault: Boolean); override;
// class procedure SetShortcut(const AButton: TCustomButton; const ShortCutK1, ShortCutK2: TShortcut); override;
class procedure ShowHide(const AWinControl: TWinControl); override;
end;
{ TCDWSCustomCheckBox }
@ -1083,7 +1084,22 @@ var
begin
Result := TCDWSWinControl.CreateHandle(AWinControl, AParams);
lCDWinControl := TCDWinControl(Result);
lCDWinControl.CDControl := TCDButton.Create(nil);
end;
class procedure TCDWSButton.ShowHide(const AWinControl: TWinControl);
var
lCDWinControl: TCDWinControl;
begin
lCDWinControl := TCDWinControl(AWinControl.Handle);
TCDWSWinControl.ShowHide(AWinControl);
if lCDWinControl.CDControl = nil then
begin
lCDWinControl.CDControl := TCDButton.Create(AWinControl);
lCDWinControl.CDControl.Parent := AWinControl;
lCDWinControl.CDControl.Align := alClient;
end;
end;
(*class procedure TCDWSButton.SetDefault(const AButton: TCustomButton;

View File

@ -1511,7 +1511,7 @@ procedure Register;
implementation
uses
WSControls, WSStdCtrls; // Widgetset uses circle is allowed
WSControls, WSStdCtrls, interfacebase; // Widgetset uses circle is allowed
type