diff --git a/lcl/interfaces/cocoa/cocoagdiobjects.pas b/lcl/interfaces/cocoa/cocoagdiobjects.pas index 8a732a38b2..868e7f956d 100644 --- a/lcl/interfaces/cocoa/cocoagdiobjects.pas +++ b/lcl/interfaces/cocoa/cocoagdiobjects.pas @@ -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; diff --git a/lcl/interfaces/cocoa/cocoawinapi.inc b/lcl/interfaces/cocoa/cocoawinapi.inc index 442b875444..6aa15c6417 100644 --- a/lcl/interfaces/cocoa/cocoawinapi.inc +++ b/lcl/interfaces/cocoa/cocoawinapi.inc @@ -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;