cocoa: implementation of DesignDC for forms

git-svn-id: trunk@57083 -
This commit is contained in:
dmitry 2018-01-14 06:14:12 +00:00
parent 81c4a099c2
commit 5c58ede9d0
6 changed files with 101 additions and 13 deletions

View File

@ -400,6 +400,7 @@ type
public
ctx: NSGraphicsContext;
isControlDC: Boolean; // control DCs should never be freed by ReleaseDC as the control will free it by itself
isDesignDC: Boolean; // this is a special Designer Overlay DC
constructor Create(AGraphicsContext: NSGraphicsContext); virtual;
destructor Destroy; override;

View File

@ -137,24 +137,17 @@ begin
DebugLn('TCarbonWidgetSet.GetLCLOwnerObject Result: ' + DbgS(Result));
{$ENDIF}
end;
*)
{------------------------------------------------------------------------------
Method: IsDesignerDC
Params: WindowHandle - Handle of window
DC - Handle of device context
Returns: If the device context is designer
------------------------------------------------------------------------------}
function TCarbonWidgetSet.IsDesignerDC(WindowHandle: HWND; DC: HDC): Boolean;
function TCocoaWidgetSet.IsDesignerDC(WindowHandle: HWND; DC: HDC): Boolean;
begin
Result := False;
{$IFDEF VerboseLCLIntf}
DebugLn('TCarbonWidgetSet.IsDesignerDC Handle: ' + DbgS(WindowHandle), ' DC: ' + DbgS(DC));
{$ENDIF}
if not CheckWidget(WindowHandle, 'IsDesignerDC', TCarbonDesignWindow) then Exit;
Result := DC = HDC(TCarbonDesignWindow(WindowHandle).GetDesignContext);
Result := (WindowHandle <> 0) and (DC <> 0) and TCocoaContext(DC).isDesignDC;
end;
*)
procedure TCocoaWidgetSet.InitClipboard;
begin

View File

@ -31,9 +31,9 @@ function GetAcceleratorString(const AVKey: Byte; const AShiftState: TShiftState)
function GetControlConstraints(Constraints: TObject): boolean; override;
function GetDesignerDC(WindowHandle: HWND): HDC; override;
function GetLCLOwnerObject(Handle: HWnd): TObject; override;
}
function IsDesignerDC(WindowHandle: HWND; DC: HDC): Boolean; override;
{
function PromptUser(const DialogCaption : string;
const DialogMessage : string;
DialogType : LongInt;

View File

@ -58,6 +58,7 @@ type
// misc events
procedure Draw(ctx: NSGraphicsContext; const bounds, dirty: NSRect);
procedure DrawBackground(ctx: NSGraphicsContext; const bounds, dirty: NSRect);
procedure DrawOverlay(ctx: NSGraphicsContext; const bounds, dirty: NSRect);
function ResetCursorRects: Boolean;
procedure BecomeFirstResponder;
procedure ResignFirstResponder;
@ -414,6 +415,17 @@ type
procedure lclItemSelected(sender: id); message 'lclItemSelected:';
end;
{ TCocoaDesignOverlay }
TCocoaDesignOverlay = objcclass(NSView)
callback : ICommonCallback;
procedure drawRect(r: NSRect); override;
function acceptsFirstResponder: Boolean; override;
function hitTest(aPoint: NSPoint): NSView; override;
function lclGetCallback: ICommonCallback; override;
procedure lclClearCallback; override;
end;
{ TCocoaCustomControl }
TCocoaCustomControl = objcclass(NSControl)
@ -469,6 +481,7 @@ type
isembedded: Boolean; // true - if the content is inside of another control, false - if the content is in its own window;
ownwin: NSWindow;
popup_parent: HWND; // if not 0, indicates that we should set the popup parent
overlay: NSView;
procedure resolvePopupParent(); message 'resolvePopupParent';
function lclOwnWindow: NSWindow; message 'lclOwnWindow';
procedure lclSetFrame(const r: TRect); override;
@ -479,6 +492,7 @@ type
procedure dealloc; override;
procedure setHidden(aisHidden: Boolean); override;
function lclIsHandle: Boolean; override;
procedure didAddSubview(aview: NSView); override;
end;
{ TCocoaScrollView }
@ -1032,6 +1046,35 @@ begin
{$ENDIF}
end;
{ TCocoaDesignOverlay }
procedure TCocoaDesignOverlay.drawRect(r: NSRect);
begin
if Assigned(callback) then
callback.DrawOverlay(NSGraphicsContext.currentContext, bounds, r);
inherited drawRect(r);
end;
function TCocoaDesignOverlay.acceptsFirstResponder: Boolean;
begin
Result:=false; // no focus
end;
function TCocoaDesignOverlay.hitTest(aPoint: NSPoint): NSView;
begin
Result:=nil; // no mouse
end;
function TCocoaDesignOverlay.lclGetCallback: ICommonCallback;
begin
Result := callback;
end;
procedure TCocoaDesignOverlay.lclClearCallback;
begin
callback := nil;
end;
{ TCocoaManualScrollView }
function TCocoaManualScrollView.lclGetCallback: ICommonCallback;
@ -1272,6 +1315,17 @@ begin
Result:=true;
end;
procedure TCocoaWindowContent.didAddSubview(aview: NSView);
begin
if Assigned(aview) and Assigned(overlay) and (overlay<>aview) then
begin
overlay.retain;
overlay.removeFromSuperview;
addSubview_positioned_relativeTo(overlay, NSWindowAbove, nil);
end;
inherited didAddSubview(aview);
end;
procedure TCocoaWindowContent.didBecomeKeyNotification(sender: NSNotification);
begin
if Assigned(callback) then

View File

@ -70,6 +70,7 @@ type
function DeliverMessage(Msg: Cardinal; WParam: WParam; LParam: LParam): LResult; virtual; overload;
procedure Draw(ControlContext: NSGraphicsContext; const bounds, dirty: NSRect); virtual;
procedure DrawBackground(ctx: NSGraphicsContext; const bounds, dirtyRect: NSRect); virtual;
procedure DrawOverlay(ControlContext: NSGraphicsContext; const bounds, dirty: NSRect); virtual;
function ResetCursorRects: Boolean; virtual;
property HasCaret: Boolean read GetHasCaret write SetHasCaret;
@ -1191,6 +1192,35 @@ begin
end;
end;
procedure TLCLCommonCallback.DrawOverlay(ControlContext: NSGraphicsContext;
const bounds, dirty: NSRect);
var
PS : TPaintStruct;
nsr : NSRect;
begin
// todo: think more about draw call while previous draw still active
if Assigned(FContext) then
Exit;
FContext := TCocoaContext.Create(ControlContext);
FContext.isControlDC := True;
FContext.isDesignDC := True;
try
// debugln('Draw '+Target.name+' bounds='+Dbgs(NSRectToRect(bounds))+' dirty='+Dbgs(NSRectToRect(dirty)));
if FContext.InitDraw(Round(bounds.size.width), Round(bounds.size.height)) then
begin
nsr:=dirty;
nsr.origin.y:=bounds.size.height-dirty.origin.y-dirty.size.height;
FillChar(PS, SizeOf(TPaintStruct), 0);
PS.hdc := HDC(FContext);
PS.rcPaint := NSRectToRect(nsr);
LCLSendPaintMsg(Target, HDC(FContext), @PS);
end;
finally
FreeAndNil(FContext);
end;
end;
function TLCLCommonCallback.ResetCursorRects: Boolean;
var
ACursor: TCursor;

View File

@ -483,7 +483,8 @@ var
R: NSRect;
pool:NSAutoReleasePool;
lDestView: NSView;
begin
ds: TCocoaDesignOverlay;
begin
//todo: create TCocoaWindow or TCocoaPanel depending on the border style
// if parent is specified neither Window nor Panel needs to be created
// the only thing that needs to be created is Content
@ -537,6 +538,15 @@ var
// support for drag & drop
win.registerForDraggedTypes(NSArray.arrayWithObjects_count(@NSFilenamesPboardType, 1));
if IsFormDesign(AWinControl) then begin
ds:=(TCocoaDesignOverlay.alloc).initWithFrame(cnt.frame);
ds.callback := cnt.callback;
ds.setAutoresizingMask(NSViewWidthSizable or NSViewHeightSizable);
cnt.addSubview_positioned_relativeTo(ds, NSWindowAbove, nil);
cnt.overlay := ds;
end;
end
else
begin