mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-17 19:59:17 +02:00
cocoa: implementation of DesignDC for forms
git-svn-id: trunk@57083 -
This commit is contained in:
parent
81c4a099c2
commit
5c58ede9d0
@ -400,6 +400,7 @@ type
|
|||||||
public
|
public
|
||||||
ctx: NSGraphicsContext;
|
ctx: NSGraphicsContext;
|
||||||
isControlDC: Boolean; // control DCs should never be freed by ReleaseDC as the control will free it by itself
|
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;
|
constructor Create(AGraphicsContext: NSGraphicsContext); virtual;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
|
|
||||||
|
@ -137,24 +137,17 @@ begin
|
|||||||
DebugLn('TCarbonWidgetSet.GetLCLOwnerObject Result: ' + DbgS(Result));
|
DebugLn('TCarbonWidgetSet.GetLCLOwnerObject Result: ' + DbgS(Result));
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
end;
|
end;
|
||||||
|
*)
|
||||||
{------------------------------------------------------------------------------
|
{------------------------------------------------------------------------------
|
||||||
Method: IsDesignerDC
|
Method: IsDesignerDC
|
||||||
Params: WindowHandle - Handle of window
|
Params: WindowHandle - Handle of window
|
||||||
DC - Handle of device context
|
DC - Handle of device context
|
||||||
Returns: If the device context is designer
|
Returns: If the device context is designer
|
||||||
------------------------------------------------------------------------------}
|
------------------------------------------------------------------------------}
|
||||||
function TCarbonWidgetSet.IsDesignerDC(WindowHandle: HWND; DC: HDC): Boolean;
|
function TCocoaWidgetSet.IsDesignerDC(WindowHandle: HWND; DC: HDC): Boolean;
|
||||||
begin
|
begin
|
||||||
Result := False;
|
Result := (WindowHandle <> 0) and (DC <> 0) and TCocoaContext(DC).isDesignDC;
|
||||||
{$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);
|
|
||||||
end;
|
end;
|
||||||
*)
|
|
||||||
|
|
||||||
procedure TCocoaWidgetSet.InitClipboard;
|
procedure TCocoaWidgetSet.InitClipboard;
|
||||||
begin
|
begin
|
||||||
|
@ -31,9 +31,9 @@ function GetAcceleratorString(const AVKey: Byte; const AShiftState: TShiftState)
|
|||||||
function GetControlConstraints(Constraints: TObject): boolean; override;
|
function GetControlConstraints(Constraints: TObject): boolean; override;
|
||||||
function GetDesignerDC(WindowHandle: HWND): HDC; override;
|
function GetDesignerDC(WindowHandle: HWND): HDC; override;
|
||||||
function GetLCLOwnerObject(Handle: HWnd): TObject; override;
|
function GetLCLOwnerObject(Handle: HWnd): TObject; override;
|
||||||
|
}
|
||||||
function IsDesignerDC(WindowHandle: HWND; DC: HDC): Boolean; override;
|
function IsDesignerDC(WindowHandle: HWND; DC: HDC): Boolean; override;
|
||||||
|
{
|
||||||
function PromptUser(const DialogCaption : string;
|
function PromptUser(const DialogCaption : string;
|
||||||
const DialogMessage : string;
|
const DialogMessage : string;
|
||||||
DialogType : LongInt;
|
DialogType : LongInt;
|
||||||
|
@ -58,6 +58,7 @@ type
|
|||||||
// misc events
|
// misc events
|
||||||
procedure Draw(ctx: NSGraphicsContext; const bounds, dirty: NSRect);
|
procedure Draw(ctx: NSGraphicsContext; const bounds, dirty: NSRect);
|
||||||
procedure DrawBackground(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;
|
function ResetCursorRects: Boolean;
|
||||||
procedure BecomeFirstResponder;
|
procedure BecomeFirstResponder;
|
||||||
procedure ResignFirstResponder;
|
procedure ResignFirstResponder;
|
||||||
@ -414,6 +415,17 @@ type
|
|||||||
procedure lclItemSelected(sender: id); message 'lclItemSelected:';
|
procedure lclItemSelected(sender: id); message 'lclItemSelected:';
|
||||||
end;
|
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 }
|
||||||
|
|
||||||
TCocoaCustomControl = objcclass(NSControl)
|
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;
|
isembedded: Boolean; // true - if the content is inside of another control, false - if the content is in its own window;
|
||||||
ownwin: NSWindow;
|
ownwin: NSWindow;
|
||||||
popup_parent: HWND; // if not 0, indicates that we should set the popup parent
|
popup_parent: HWND; // if not 0, indicates that we should set the popup parent
|
||||||
|
overlay: NSView;
|
||||||
procedure resolvePopupParent(); message 'resolvePopupParent';
|
procedure resolvePopupParent(); message 'resolvePopupParent';
|
||||||
function lclOwnWindow: NSWindow; message 'lclOwnWindow';
|
function lclOwnWindow: NSWindow; message 'lclOwnWindow';
|
||||||
procedure lclSetFrame(const r: TRect); override;
|
procedure lclSetFrame(const r: TRect); override;
|
||||||
@ -479,6 +492,7 @@ type
|
|||||||
procedure dealloc; override;
|
procedure dealloc; override;
|
||||||
procedure setHidden(aisHidden: Boolean); override;
|
procedure setHidden(aisHidden: Boolean); override;
|
||||||
function lclIsHandle: Boolean; override;
|
function lclIsHandle: Boolean; override;
|
||||||
|
procedure didAddSubview(aview: NSView); override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TCocoaScrollView }
|
{ TCocoaScrollView }
|
||||||
@ -1032,6 +1046,35 @@ begin
|
|||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
end;
|
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 }
|
{ TCocoaManualScrollView }
|
||||||
|
|
||||||
function TCocoaManualScrollView.lclGetCallback: ICommonCallback;
|
function TCocoaManualScrollView.lclGetCallback: ICommonCallback;
|
||||||
@ -1272,6 +1315,17 @@ begin
|
|||||||
Result:=true;
|
Result:=true;
|
||||||
end;
|
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);
|
procedure TCocoaWindowContent.didBecomeKeyNotification(sender: NSNotification);
|
||||||
begin
|
begin
|
||||||
if Assigned(callback) then
|
if Assigned(callback) then
|
||||||
|
@ -70,6 +70,7 @@ type
|
|||||||
function DeliverMessage(Msg: Cardinal; WParam: WParam; LParam: LParam): LResult; virtual; overload;
|
function DeliverMessage(Msg: Cardinal; WParam: WParam; LParam: LParam): LResult; virtual; overload;
|
||||||
procedure Draw(ControlContext: NSGraphicsContext; const bounds, dirty: NSRect); virtual;
|
procedure Draw(ControlContext: NSGraphicsContext; const bounds, dirty: NSRect); virtual;
|
||||||
procedure DrawBackground(ctx: NSGraphicsContext; const bounds, dirtyRect: NSRect); virtual;
|
procedure DrawBackground(ctx: NSGraphicsContext; const bounds, dirtyRect: NSRect); virtual;
|
||||||
|
procedure DrawOverlay(ControlContext: NSGraphicsContext; const bounds, dirty: NSRect); virtual;
|
||||||
function ResetCursorRects: Boolean; virtual;
|
function ResetCursorRects: Boolean; virtual;
|
||||||
|
|
||||||
property HasCaret: Boolean read GetHasCaret write SetHasCaret;
|
property HasCaret: Boolean read GetHasCaret write SetHasCaret;
|
||||||
@ -1191,6 +1192,35 @@ begin
|
|||||||
end;
|
end;
|
||||||
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;
|
function TLCLCommonCallback.ResetCursorRects: Boolean;
|
||||||
var
|
var
|
||||||
ACursor: TCursor;
|
ACursor: TCursor;
|
||||||
|
@ -483,7 +483,8 @@ var
|
|||||||
R: NSRect;
|
R: NSRect;
|
||||||
pool:NSAutoReleasePool;
|
pool:NSAutoReleasePool;
|
||||||
lDestView: NSView;
|
lDestView: NSView;
|
||||||
begin
|
ds: TCocoaDesignOverlay;
|
||||||
|
begin
|
||||||
//todo: create TCocoaWindow or TCocoaPanel depending on the border style
|
//todo: create TCocoaWindow or TCocoaPanel depending on the border style
|
||||||
// if parent is specified neither Window nor Panel needs to be created
|
// if parent is specified neither Window nor Panel needs to be created
|
||||||
// the only thing that needs to be created is Content
|
// the only thing that needs to be created is Content
|
||||||
@ -537,6 +538,15 @@ var
|
|||||||
|
|
||||||
// support for drag & drop
|
// support for drag & drop
|
||||||
win.registerForDraggedTypes(NSArray.arrayWithObjects_count(@NSFilenamesPboardType, 1));
|
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
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
|
Loading…
Reference in New Issue
Block a user