mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-22 05:59:28 +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 ClearClipping;
|
||||
procedure AttachedBitmap_SetModified(); virtual;
|
||||
procedure DrawEdgeRect(const r: TRect; flags: Cardinal; LTColor, BRColor: TColor);
|
||||
public
|
||||
ctx: NSGraphicsContext;
|
||||
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 Ellipse(X1, Y1, X2, Y2: Integer);
|
||||
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 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 DrawBitmap(X, Y: Integer; ABitmap: TCocoaBitmap);
|
||||
function DrawImageRep(dstRect: NSRect; const srcRect: NSRect; ImageRep: NSBitmapImageRep): Boolean;
|
||||
@ -1992,13 +1995,115 @@ begin
|
||||
AttachedBitmap_SetModified();
|
||||
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);
|
||||
begin
|
||||
Rectangle(R.Left, R.Top, R.Right + 1, R.Bottom + 1, False, nil);
|
||||
AttachedBitmap_SetModified();
|
||||
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
|
||||
dx,dy: integer;
|
||||
ns : NSRect;
|
||||
|
@ -564,89 +564,17 @@ begin
|
||||
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;
|
||||
grfFlags: Cardinal): Boolean;
|
||||
var
|
||||
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
|
||||
Result := false;
|
||||
ctx := CheckDC(DC);
|
||||
Result := Assigned(ctx);
|
||||
if not Result then Exit;
|
||||
if not Assigned(ctx) then
|
||||
Exit;
|
||||
|
||||
keepPen := ctx.Pen;
|
||||
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;
|
||||
ctx.DrawEdge(Rect, edge, grfFlags);
|
||||
|
||||
Result := true;
|
||||
end;
|
||||
@ -955,47 +883,31 @@ end;
|
||||
|
||||
function TCocoaWidgetSet.Frame3d(DC: HDC; var ARect: TRect;
|
||||
const FrameWidth: integer; const Style: TBevelCut): Boolean;
|
||||
const
|
||||
Edge: array[TBevelCut] of Integer =
|
||||
(
|
||||
{bvNone } 0,
|
||||
{bvLowered} BDR_SUNKENOUTER,
|
||||
{bvRaised } EDGE_RAISED,
|
||||
{bvSpace } 0
|
||||
);
|
||||
var
|
||||
I: Integer;
|
||||
rect: TRect;
|
||||
ctx: TCocoaContext;
|
||||
control: TWinControl;
|
||||
is3dStyle: Boolean;
|
||||
is3dClassicStyle: Boolean;
|
||||
begin
|
||||
Result := false;
|
||||
if FrameWidth <= 0 then
|
||||
Exit;
|
||||
|
||||
ctx := CheckDC(DC);
|
||||
if not Assigned(ctx) then
|
||||
exit;
|
||||
Exit;
|
||||
|
||||
control := ctx.control;
|
||||
if Assigned(control) then
|
||||
is3dStyle := csParentBackground in control.ControlStyle
|
||||
is3dClassicStyle := csParentBackground in control.ControlStyle
|
||||
else
|
||||
is3dStyle := true;
|
||||
is3dClassicStyle := true;
|
||||
|
||||
if is3dStyle then
|
||||
begin
|
||||
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
|
||||
if is3dClassicStyle then
|
||||
ctx.Frame3dClassic(ARect, FrameWidth, Style)
|
||||
else
|
||||
begin
|
||||
if FrameWidth > 0 then
|
||||
ctx.Frame3d(ARect, FrameWidth, Style);
|
||||
end;
|
||||
ctx.Frame3dBox(ARect, FrameWidth, Style);
|
||||
|
||||
Result := true;
|
||||
end;
|
||||
|
||||
function TCocoaWidgetSet.FrameRect(DC: HDC; const ARect: TRect; hBr: HBRUSH): Integer;
|
||||
|
Loading…
Reference in New Issue
Block a user