mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-19 22:29:25 +02:00
customdrawn: Implements TButton clicking, implements InvalidateRect in X11
git-svn-id: trunk@33870 -
This commit is contained in:
parent
fdf484944c
commit
5774ecec7d
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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 }
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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]');
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -1511,7 +1511,7 @@ procedure Register;
|
||||
implementation
|
||||
|
||||
uses
|
||||
WSControls, WSStdCtrls; // Widgetset uses circle is allowed
|
||||
WSControls, WSStdCtrls, interfacebase; // Widgetset uses circle is allowed
|
||||
|
||||
|
||||
type
|
||||
|
Loading…
Reference in New Issue
Block a user