mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-12 18:39:52 +02:00
Cocoa: CocoaWinapi & TCocoaContext refactored
This commit is contained in:
parent
f49aedaf1f
commit
25f4ba3380
@ -397,6 +397,7 @@ type
|
|||||||
procedure ApplyTransform(Trans: CGAffineTransform);
|
procedure ApplyTransform(Trans: CGAffineTransform);
|
||||||
procedure ClearClipping;
|
procedure ClearClipping;
|
||||||
procedure AttachedBitmap_SetModified(); virtual;
|
procedure AttachedBitmap_SetModified(); virtual;
|
||||||
|
procedure DrawEdgeRect(const r: TRect; flags: Cardinal; LTColor, BRColor: TColor);
|
||||||
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
|
||||||
@ -429,8 +430,10 @@ type
|
|||||||
procedure BackgroundFill(dirtyRect:NSRect);
|
procedure BackgroundFill(dirtyRect:NSRect);
|
||||||
procedure Ellipse(X1, Y1, X2, Y2: Integer);
|
procedure Ellipse(X1, Y1, X2, Y2: Integer);
|
||||||
procedure TextOut(X, Y: Integer; Options: Longint; Rect: PRect; UTF8Chars: PChar; Count: Integer; CharsDelta: PInteger);
|
procedure TextOut(X, Y: Integer; Options: Longint; Rect: PRect; UTF8Chars: PChar; Count: Integer; CharsDelta: PInteger);
|
||||||
|
procedure DrawEdge(var Rect: TRect; edge: Cardinal; grfFlags: Cardinal);
|
||||||
procedure Frame(const R: TRect);
|
procedure Frame(const R: TRect);
|
||||||
procedure Frame3d(var ARect: TRect; const FrameWidth: integer; const Style: TBevelCut);
|
procedure Frame3dClassic(var ARect: TRect; const FrameWidth: integer; const Style: TBevelCut);
|
||||||
|
procedure Frame3dBox(var ARect: TRect; const FrameWidth: integer; const Style: TBevelCut);
|
||||||
procedure FrameRect(const ARect: TRect; const ABrush: TCocoaBrush);
|
procedure FrameRect(const ARect: TRect; const ABrush: TCocoaBrush);
|
||||||
procedure DrawBitmap(X, Y: Integer; ABitmap: TCocoaBitmap);
|
procedure DrawBitmap(X, Y: Integer; ABitmap: TCocoaBitmap);
|
||||||
function DrawImageRep(dstRect: NSRect; const srcRect: NSRect; ImageRep: NSBitmapImageRep): Boolean;
|
function DrawImageRep(dstRect: NSRect; const srcRect: NSRect; ImageRep: NSBitmapImageRep): Boolean;
|
||||||
@ -1992,13 +1995,115 @@ begin
|
|||||||
AttachedBitmap_SetModified();
|
AttachedBitmap_SetModified();
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TCocoaContext.DrawEdgeRect(const r: TRect; flags: Cardinal;
|
||||||
|
LTColor, BRColor: TColor);
|
||||||
|
begin
|
||||||
|
Pen.SetColor(LTColor, true);
|
||||||
|
Pen.Apply(self);
|
||||||
|
if flags and BF_LEFT > 0 then
|
||||||
|
begin
|
||||||
|
MoveTo(r.Left, r.Bottom);
|
||||||
|
LineTo(r.Left, r.Top);
|
||||||
|
end;
|
||||||
|
if flags and BF_TOP > 0 then
|
||||||
|
begin
|
||||||
|
MoveTo(r.Left, r.Top);
|
||||||
|
LineTo(r.Right, r.Top);
|
||||||
|
end;
|
||||||
|
|
||||||
|
Pen.SetColor(BRColor, true);
|
||||||
|
Pen.Apply(self);
|
||||||
|
if flags and BF_RIGHT > 0 then
|
||||||
|
begin
|
||||||
|
MoveTo(r.Right, r.Top);
|
||||||
|
LineTo(r.Right, r.Bottom);
|
||||||
|
end;
|
||||||
|
if flags and BF_BOTTOM > 0 then
|
||||||
|
begin
|
||||||
|
MoveTo(r.Right, r.Bottom);
|
||||||
|
// there's a missing pixel. Seems like it's accumulating an offset
|
||||||
|
LineTo(r.Left-1, r.Bottom);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCocoaContext.DrawEdge(var Rect: TRect; edge: Cardinal;
|
||||||
|
grfFlags: Cardinal);
|
||||||
|
var
|
||||||
|
r: TRect;
|
||||||
|
keepPen : TCocoaPen;
|
||||||
|
edgePen : TCocoaPen;
|
||||||
|
keepBrush : TCocoaBrush;
|
||||||
|
edgeBrush : TCocoaBrush;
|
||||||
|
const
|
||||||
|
OutLT = cl3DLight; // the next to hilight
|
||||||
|
OutBR = cl3DDkShadow; // the darkest (almost black)
|
||||||
|
InnLT = cl3DHiLight; // the lightest (almost white)
|
||||||
|
InnBR = cl3DShadow; // darker than light, lighter than dark shadow
|
||||||
|
begin
|
||||||
|
keepPen := Pen;
|
||||||
|
keepBrush := Brush;
|
||||||
|
try
|
||||||
|
edgePen := TCocoaPen.Create($FFFFFF, psSolid, false, 1, pmCopy, pecRound, pjsRound);
|
||||||
|
edgeBrush := TCocoaBrush.Create(NSColor.whiteColor, false);
|
||||||
|
edgeBrush.Solid := false;
|
||||||
|
Pen := edgePen;
|
||||||
|
Brush := edgeBrush;
|
||||||
|
|
||||||
|
r := Rect;
|
||||||
|
if (edge and BDR_OUTER > 0) then
|
||||||
|
begin
|
||||||
|
if edge and BDR_RAISEDOUTER > 0 then
|
||||||
|
DrawEdgeRect(r, grfFlags, OutLT, OutBR)
|
||||||
|
else
|
||||||
|
DrawEdgeRect(r, grfFlags, InnBR, InnLT);
|
||||||
|
InflateRect(r, -1, -1);
|
||||||
|
end;
|
||||||
|
|
||||||
|
if (edge and BDR_INNER > 0) then
|
||||||
|
begin
|
||||||
|
if edge and BDR_RAISEDINNER > 0 then
|
||||||
|
DrawEdgeRect(r, grfFlags, InnLT, InnBR)
|
||||||
|
else
|
||||||
|
DrawEdgeRect(r, grfFlags, OutBR, OutLT);
|
||||||
|
end;
|
||||||
|
|
||||||
|
finally
|
||||||
|
Pen := keepPen;
|
||||||
|
Brush := keepBrush;
|
||||||
|
edgeBrush.Free;
|
||||||
|
edgePen.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TCocoaContext.Frame(const R: TRect);
|
procedure TCocoaContext.Frame(const R: TRect);
|
||||||
begin
|
begin
|
||||||
Rectangle(R.Left, R.Top, R.Right + 1, R.Bottom + 1, False, nil);
|
Rectangle(R.Left, R.Top, R.Right + 1, R.Bottom + 1, False, nil);
|
||||||
AttachedBitmap_SetModified();
|
AttachedBitmap_SetModified();
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCocoaContext.Frame3d(var ARect: TRect; const FrameWidth: integer; const Style: TBevelCut);
|
procedure TCocoaContext.Frame3dClassic(var ARect: TRect; const FrameWidth: integer;
|
||||||
|
const Style: TBevelCut);
|
||||||
|
const
|
||||||
|
Edge: array[TBevelCut] of Integer =
|
||||||
|
(
|
||||||
|
{bvNone } 0,
|
||||||
|
{bvLowered} BDR_SUNKENOUTER,
|
||||||
|
{bvRaised } EDGE_RAISED,
|
||||||
|
{bvSpace } 0
|
||||||
|
);
|
||||||
|
var
|
||||||
|
I: Integer;
|
||||||
|
rect: TRect;
|
||||||
|
begin
|
||||||
|
rect:= ARect;
|
||||||
|
for I := 0 to FrameWidth - 1 do
|
||||||
|
begin
|
||||||
|
DrawEdge(rect, Edge[Style], BF_RECT or BF_ADJUST);
|
||||||
|
InflateRect(rect,-1,-1);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCocoaContext.Frame3dBox(var ARect: TRect; const FrameWidth: integer; const Style: TBevelCut);
|
||||||
var
|
var
|
||||||
dx,dy: integer;
|
dx,dy: integer;
|
||||||
ns : NSRect;
|
ns : NSRect;
|
||||||
|
@ -564,89 +564,17 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure DrawEdgeRect(dst: TCocoaContext; const r: TRect; flags: Cardinal;
|
|
||||||
LTColor, BRColor: TColor);
|
|
||||||
begin
|
|
||||||
dst.Pen.SetColor(LTColor, true);
|
|
||||||
dst.Pen.Apply(dst);
|
|
||||||
if flags and BF_LEFT > 0 then
|
|
||||||
begin
|
|
||||||
dst.MoveTo(r.Left, r.Bottom);
|
|
||||||
dst.LineTo(r.Left, r.Top);
|
|
||||||
end;
|
|
||||||
if flags and BF_TOP > 0 then
|
|
||||||
begin
|
|
||||||
dst.MoveTo(r.Left, r.Top);
|
|
||||||
dst.LineTo(r.Right, r.Top);
|
|
||||||
end;
|
|
||||||
|
|
||||||
dst.Pen.SetColor(BRColor, true);
|
|
||||||
dst.Pen.Apply(dst);
|
|
||||||
if flags and BF_RIGHT > 0 then
|
|
||||||
begin
|
|
||||||
dst.MoveTo(r.Right, r.Top);
|
|
||||||
dst.LineTo(r.Right, r.Bottom);
|
|
||||||
end;
|
|
||||||
if flags and BF_BOTTOM > 0 then
|
|
||||||
begin
|
|
||||||
dst.MoveTo(r.Right, r.Bottom);
|
|
||||||
// there's a missing pixel. Seems like it's accumulating an offset
|
|
||||||
dst.LineTo(r.Left-1, r.Bottom);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TCocoaWidgetSet.DrawEdge(DC: HDC; var Rect: TRect; edge: Cardinal;
|
function TCocoaWidgetSet.DrawEdge(DC: HDC; var Rect: TRect; edge: Cardinal;
|
||||||
grfFlags: Cardinal): Boolean;
|
grfFlags: Cardinal): Boolean;
|
||||||
var
|
var
|
||||||
ctx: TCocoaContext;
|
ctx: TCocoaContext;
|
||||||
r: TRect;
|
|
||||||
keepPen : TCocoaPen;
|
|
||||||
edgePen : TCocoaPen;
|
|
||||||
keepBrush : TCocoaBrush;
|
|
||||||
edgeBrush : TCocoaBrush;
|
|
||||||
const
|
|
||||||
OutLT = cl3DLight; // the next to hilight
|
|
||||||
OutBR = cl3DDkShadow; // the darkest (almost black)
|
|
||||||
InnLT = cl3DHiLight; // the lightest (almost white)
|
|
||||||
InnBR = cl3DShadow; // darker than light, lighter than dark shadow
|
|
||||||
begin
|
begin
|
||||||
|
Result := false;
|
||||||
ctx := CheckDC(DC);
|
ctx := CheckDC(DC);
|
||||||
Result := Assigned(ctx);
|
if not Assigned(ctx) then
|
||||||
if not Result then Exit;
|
Exit;
|
||||||
|
|
||||||
keepPen := ctx.Pen;
|
ctx.DrawEdge(Rect, edge, grfFlags);
|
||||||
keepBrush := ctx.Brush;
|
|
||||||
try
|
|
||||||
edgePen := TCocoaPen.Create($FFFFFF, psSolid, false, 1, pmCopy, pecRound, pjsRound);
|
|
||||||
edgeBrush := TCocoaBrush.Create(NSColor.whiteColor, false);
|
|
||||||
edgeBrush.Solid := false;
|
|
||||||
ctx.Pen := edgePen;
|
|
||||||
ctx.Brush := edgeBrush;
|
|
||||||
|
|
||||||
r := Rect;
|
|
||||||
if (edge and BDR_OUTER > 0) then
|
|
||||||
begin
|
|
||||||
if edge and BDR_RAISEDOUTER > 0 then
|
|
||||||
DrawEdgeRect(ctx, r, grfFlags, OutLT, OutBR)
|
|
||||||
else
|
|
||||||
DrawEdgeRect(ctx, r, grfFlags, InnBR, InnLT);
|
|
||||||
InflateRect(r, -1, -1);
|
|
||||||
end;
|
|
||||||
|
|
||||||
if (edge and BDR_INNER > 0) then
|
|
||||||
begin
|
|
||||||
if edge and BDR_RAISEDINNER > 0 then
|
|
||||||
DrawEdgeRect(ctx, r, grfFlags, InnLT, InnBR)
|
|
||||||
else
|
|
||||||
DrawEdgeRect(ctx, r, grfFlags, OutBR, OutLT);
|
|
||||||
end;
|
|
||||||
|
|
||||||
finally
|
|
||||||
ctx.Pen := keepPen;
|
|
||||||
ctx.Brush := keepBrush;
|
|
||||||
edgeBrush.Free;
|
|
||||||
edgePen.Free;
|
|
||||||
end;
|
|
||||||
|
|
||||||
Result := true;
|
Result := true;
|
||||||
end;
|
end;
|
||||||
@ -955,47 +883,31 @@ end;
|
|||||||
|
|
||||||
function TCocoaWidgetSet.Frame3d(DC: HDC; var ARect: TRect;
|
function TCocoaWidgetSet.Frame3d(DC: HDC; var ARect: TRect;
|
||||||
const FrameWidth: integer; const Style: TBevelCut): Boolean;
|
const FrameWidth: integer; const Style: TBevelCut): Boolean;
|
||||||
const
|
|
||||||
Edge: array[TBevelCut] of Integer =
|
|
||||||
(
|
|
||||||
{bvNone } 0,
|
|
||||||
{bvLowered} BDR_SUNKENOUTER,
|
|
||||||
{bvRaised } EDGE_RAISED,
|
|
||||||
{bvSpace } 0
|
|
||||||
);
|
|
||||||
var
|
var
|
||||||
I: Integer;
|
|
||||||
rect: TRect;
|
|
||||||
ctx: TCocoaContext;
|
ctx: TCocoaContext;
|
||||||
control: TWinControl;
|
control: TWinControl;
|
||||||
is3dStyle: Boolean;
|
is3dClassicStyle: Boolean;
|
||||||
begin
|
begin
|
||||||
|
Result := false;
|
||||||
|
if FrameWidth <= 0 then
|
||||||
|
Exit;
|
||||||
|
|
||||||
ctx := CheckDC(DC);
|
ctx := CheckDC(DC);
|
||||||
if not Assigned(ctx) then
|
if not Assigned(ctx) then
|
||||||
exit;
|
Exit;
|
||||||
|
|
||||||
control := ctx.control;
|
control := ctx.control;
|
||||||
if Assigned(control) then
|
if Assigned(control) then
|
||||||
is3dStyle := csParentBackground in control.ControlStyle
|
is3dClassicStyle := csParentBackground in control.ControlStyle
|
||||||
else
|
else
|
||||||
is3dStyle := true;
|
is3dClassicStyle := true;
|
||||||
|
|
||||||
if is3dStyle then
|
if is3dClassicStyle then
|
||||||
begin
|
ctx.Frame3dClassic(ARect, FrameWidth, Style)
|
||||||
Result := FrameWidth > 0;
|
|
||||||
if not Result then exit;
|
|
||||||
rect:= ARect;
|
|
||||||
for I := 0 to FrameWidth - 1 do
|
|
||||||
begin
|
|
||||||
Result := Boolean(DrawEdge(DC, rect, Edge[Style], BF_RECT or BF_ADJUST));
|
|
||||||
InflateRect(rect,-1,-1);
|
|
||||||
end;
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
begin
|
ctx.Frame3dBox(ARect, FrameWidth, Style);
|
||||||
if FrameWidth > 0 then
|
|
||||||
ctx.Frame3d(ARect, FrameWidth, Style);
|
Result := true;
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCocoaWidgetSet.FrameRect(DC: HDC; const ARect: TRect; hBr: HBRUSH): Integer;
|
function TCocoaWidgetSet.FrameRect(DC: HDC; const ARect: TRect; hBr: HBRUSH): Integer;
|
||||||
|
Loading…
Reference in New Issue
Block a user