cocoa: redo private classes - use corba interfaces instead for simplification of implementation and better inheritance, implement few combobox events, redo gdi object handling and implement most of brush properties

git-svn-id: trunk@33689 -
This commit is contained in:
paul 2011-11-22 10:52:25 +00:00
parent e78539be74
commit 4f99496446
9 changed files with 578 additions and 128 deletions

View File

@ -8,8 +8,8 @@ interface
{$modeswitch objectivec1}
uses
SysUtils, MacOSAll, // for CGContextRef
LCLtype, LCLProc,
MacOSAll, // for CGContextRef
LCLtype, LCLProc, Graphics,
CocoaAll, CocoaUtils,
Classes, Types;
@ -36,13 +36,22 @@ const
cbtMask = cbtMono;
type
TCocoaBitmap = class;
TCocoaContext = class;
{ TCocoaGDIObject }
TCocoaGDIObject = class(TObject)
private
FRefCount: Integer;
FGlobal: Boolean;
public
RefCount: Integer;
constructor Create(AGlobal: Boolean); virtual;
procedure AddRef;
procedure Release;
property Global: Boolean read FGlobal write FGlobal;
property RefCount: Integer read FRefCount;
end;
TCocoaRegionType = (crt_Empty, crt_Rectangle, crt_Complex);
@ -70,11 +79,40 @@ type
property Shape: HIShapeRef read FShape write SetShape;
end;
{ TCocoaColorObject }
TCocoaColorObject = class(TCocoaGDIObject)
private
FR, FG, FB: Byte;
FA: Boolean; // alpha: True - solid, False - clear
function GetColorRef: TColorRef;
public
constructor Create(const AColor: TColor; ASolid, AGlobal: Boolean);
procedure SetColor(const AColor: TColor; ASolid: Boolean);
procedure GetRGBA(AROP2: Integer; out AR, AG, AB, AA: Single);
function CreateNSColor: NSColor;
property Red: Byte read FR write FR;
property Green: Byte read FG write FG;
property Blue: Byte read FB write FB;
property Solid: Boolean read FA write FA;
property ColorRef: TColorRef read GetColorRef;
end;
{ TCocoaBrush }
TCocoaBrush = class(TCocoaGDIObject)
R,G,B : Single;
procedure Apply(cg: CGContextRef);
TCocoaBrush = class(TCocoaColorObject)
FCGPattern: CGPatternRef;
FColored: Boolean;
FImage: CGImageRef;
protected
procedure SetHatchStyle(AHatch: PtrInt);
procedure SetBitmap(ABitmap: TCocoaBitmap);
public
constructor CreateDefault;
constructor Create(const ALogBrush: TLogBrush; const AGlobal: Boolean = False);
destructor Destroy; override;
procedure Apply(ADC: TCocoaContext);
end;
{ TCocoaPen }
@ -85,6 +123,7 @@ type
Width : Integer;
R,G,B : Single;
procedure Apply(cg: CGContextRef);
constructor CreateDefault;
constructor Create;
end;
@ -97,6 +136,7 @@ type
Size : Integer;
Style : TCocoaFontStyle;
Antialiased: Boolean;
constructor CreateDefault;
end;
{ TCocoaBitmap }
@ -174,12 +214,12 @@ type
TCocoaContext = class(TObject)
private
fText : TCocoaTextLayout;
fBrush : TCocoaBrush;
fPen : TCocoaPen;
fFont : TCocoaFont;
fRegion : TCocoaRegion;
fBitmap : TCocoaBitmap;
FText : TCocoaTextLayout;
FBrush : TCocoaBrush;
FPen : TCocoaPen;
FFont : TCocoaFont;
FRegion : TCocoaRegion;
FBitmap : TCocoaBitmap;
procedure SetBitmap(const AValue: TCocoaBitmap);
procedure SetBrush(const AValue: TCocoaBrush);
procedure SetFont(const AValue: TCocoaFont);
@ -207,11 +247,11 @@ type
procedure SetOrigin(X,Y: Integer);
procedure GetOrigin(var X,Y: Integer);
function CGContext: CGContextRef; virtual;
property Brush: TCocoaBrush read fBrush write SetBrush;
property Pen: TCocoaPen read fPen write SetPen;
property Font: TCocoaFont read fFont write SetFont;
property Region: TCocoaRegion read fRegion write SetRegion;
property Bitmap: TCocoaBitmap read fBitmap write SetBitmap;
property Brush: TCocoaBrush read FBrush write SetBrush;
property Pen: TCocoaPen read FPen write SetPen;
property Font: TCocoaFont read FFont write SetFont;
property Region: TCocoaRegion read FRegion write SetRegion;
property Bitmap: TCocoaBitmap read FBitmap write SetBitmap;
end;
var
@ -262,6 +302,88 @@ type
function initWithBitmapDataPlanes_pixelsWide_pixelsHigh__colorSpaceName_bitmapFormat_bytesPerRow_bitsPerPixel(planes: PPByte; width: NSInteger; height: NSInteger; bps: NSInteger; spp: NSInteger; alpha: Boolean; isPlanar_: Boolean; colorSpaceName_: NSString; bitmapFormat_: NSBitmapFormat; rBytes: NSInteger; pBits: NSInteger): id; message 'initWithBitmapDataPlanes:pixelsWide:pixelsHigh:bitsPerSample:samplesPerPixel:hasAlpha:isPlanar:colorSpaceName:bitmapFormat:bytesPerRow:bitsPerPixel:';
end;
{ TCocoaFont }
constructor TCocoaFont.CreateDefault;
begin
inherited Create(False);
end;
{ TCocoaColorObject }
function TCocoaColorObject.GetColorRef: TColorRef;
begin
Result := TColorRef(RGBToColor(FR, FG, FB));
end;
constructor TCocoaColorObject.Create(const AColor: TColor; ASolid,
AGlobal: Boolean);
begin
inherited Create(AGlobal);
SetColor(AColor, ASolid);
end;
procedure TCocoaColorObject.SetColor(const AColor: TColor; ASolid: Boolean);
begin
RedGreenBlue(ColorToRGB(AColor), FR, FG, FB);
FA := ASolid;
end;
procedure TCocoaColorObject.GetRGBA(AROP2: Integer; out AR, AG, AB, AA: Single
);
begin
case AROP2 of
R2_BLACK:
begin
AR := 0;
AG := 0;
AB := 0;
AA := Byte(FA);
end;
R2_WHITE:
begin
AR := 1;
AG := 1;
AB := 1;
AA := Byte(FA);
end;
R2_NOP:
begin
AR := 1;
AG := 1;
AB := 1;
AA := 0;
end;
R2_NOT:
begin
AR := 1;
AG := 1;
AB := 1;
AA := Byte(FA);
end;
R2_NOTCOPYPEN:
begin
AR := (255 - FR) / 255;
AG := (255 - FG) / 255;
AB := (255 - FB) / 255;
AA := Byte(FA);
end;
else // copy
begin
AR := FR / 255;
AG := FG / 255;
AB := FB / 255;
AA := Byte(FA);
end;
end;
end;
function TCocoaColorObject.CreateNSColor: NSColor;
begin
Result := NSColor.colorWithCalibratedRed_green_blue_alpha(FR / 255, FG / 255, FB / 255, Byte(FA));
end;
{------------------------------------------------------------------------------
Method: TCocoaBitmap.Create
Params: AWidth - Bitmap width
@ -281,6 +403,7 @@ var
HasAlpha: Boolean;
BitmapFormat: NSBitmapFormat;
begin
inherited Create(False);
{$ifdef VerboseBitmaps}
DebugLn(Format('[TCocoaBitmap.Create] AWidth=%d AHeight=%d ADepth=%d ABitsPerPixel=%d'
+ ' AAlignment=%d AType=%d AData=? ACopyData=%d',
@ -453,8 +576,8 @@ end;
procedure TCocoaContext.SetBrush(const AValue: TCocoaBrush);
begin
fBrush:=AValue;
if Assigned(fBrush) then fBrush.Apply(CGContext);
FBrush := AValue;
if Assigned(FBrush) then FBrush.Apply(Self);
end;
procedure TCocoaContext.SetFont(const AValue: TCocoaFont);
@ -475,12 +598,19 @@ end;
constructor TCocoaContext.Create;
begin
fText:=TextLayoutClass.Create;
inherited Create;
FBrush := TCocoaBrush.CreateDefault;
FBrush.AddRef;
FPen := TCocoaPen.CreateDefault;
FPen.AddRef;
FFont := TCocoaFont.CreateDefault;
FFont.AddRef;
FText := TextLayoutClass.Create;
end;
destructor TCocoaContext.Destroy;
begin
fText.Free;
FText.Free;
inherited Destroy;
end;
@ -630,10 +760,10 @@ begin
CGContextAddLCLRect(cg, X1,Y1,X2,Y2);
if FillRect then begin
//using the brush
if Assigned(UseBrush) then UseBrush.Apply(cg);
if Assigned(UseBrush) then UseBrush.Apply(Self);
CGContextFillPath(cg);
//restore the brush
if Assigned(UseBrush) and Assigned(fBrush) then fBrush.Apply(cg);
if Assigned(UseBrush) and Assigned(FBrush) then FBrush.Apply(Self);
end else
CGContextStrokePath(cg);
end;
@ -669,7 +799,7 @@ begin
fText.SetText(UTF8Chars, Count);
fText.Draw(cg, X, ContextSize.cy-Y, CharsDelta);
if Assigned(fBrush) then fBrush.Apply(cg);
if Assigned(FBrush) then FBrush.Apply(Self);
CGContextTranslateCTM(cg, 0, ContextSize.cy);
CGContextScaleCTM(cg, 1, -1);
@ -818,7 +948,7 @@ end;
------------------------------------------------------------------------------}
constructor TCocoaRegion.Create;
begin
inherited Create;
inherited Create(False);
FShape := HIShapeCreateEmpty;
end;
@ -831,7 +961,7 @@ end;
------------------------------------------------------------------------------}
constructor TCocoaRegion.Create(const X1, Y1, X2, Y2: Integer);
begin
inherited Create;
inherited Create(False);
FShape := HIShapeCreateWithRect(GetCGRect(X1, Y1, X2, Y2));
end;
@ -884,7 +1014,7 @@ var
end;
begin
inherited Create;
inherited Create(False);
(*
The passed polygon is drawed into grayscale context, the region is constructed
@ -1082,18 +1212,153 @@ begin
//todo: style
end;
constructor TCocoaPen.CreateDefault;
begin
inherited Create(False);
Width := 1;
end;
constructor TCocoaPen.Create;
begin
inherited Create;
inherited Create(False);
Width:=1;
end;
{ TCocoaBrush }
procedure TCocoaBrush.Apply(cg:CGContextRef);
procedure DrawBitmapPattern(info: UnivPtr; c: CGContextRef); MWPascal;
var
ABrush: TCocoaBrush absolute info;
AImage: CGImageRef;
begin
if cg = nil then Exit;
CGContextSetRGBFillColor(cg, R,G,B, 1);
AImage := ABrush.FImage;
CGContextDrawImage(c, GetCGRect(0, 0, CGImageGetWidth(AImage), CGImageGetHeight(AImage)),
AImage);
end;
procedure TCocoaBrush.SetHatchStyle(AHatch: PtrInt);
const
HATCH_DATA: array[HS_HORIZONTAL..HS_DIAGCROSS] of array[0..7] of Byte =
(
{ HS_HORIZONTAL } ($FF, $FF, $FF, $00, $FF, $FF, $FF, $FF),
{ HS_VERTICAL } ($F7, $F7, $F7, $F7, $F7, $F7, $F7, $F7),
{ HS_FDIAGONAL } ($7F, $BF, $DF, $EF, $F7, $FB, $FD, $FE),
{ HS_BDIAGONAL } ($FE, $FD, $FB, $F7, $EF, $DF, $BF, $7F),
{ HS_CROSS } ($F7, $F7, $F7, $00, $F7, $F7, $F7, $F7),
{ HS_DIAGCROSS } ($7E, $BD, $DB, $E7, $E7, $DB, $BD, $7E)
);
var
ACallBacks: CGPatternCallbacks;
ABitmap: TCocoaBitmap;
begin
if AHatch in [HS_HORIZONTAL..HS_DIAGCROSS] then
begin
FillChar(ACallBacks, SizeOf(ACallBacks), 0);
ACallBacks.drawPattern := @DrawBitmapPattern;
ABitmap := TCocoaBitmap.Create(8, 8, 1, 1, cbaByte, cbtMask, @HATCH_DATA[AHatch]);
FImage := ABitmap.ImageRep.CGImageForProposedRect_context_hints(nil, nil, nil);
ABitmap.Free;
FColored := False;
FCGPattern := CGPatternCreate(Self, GetCGRect(0, 0, 8, 8),
CGAffineTransformIdentity, 8, 8, kCGPatternTilingConstantSpacing,
Ord(FColored), ACallBacks);
end;
end;
procedure TCocoaBrush.SetBitmap(ABitmap: TCocoaBitmap);
var
AWidth, AHeight: Integer;
ACallBacks: CGPatternCallbacks;
begin
AWidth := ABitmap.Width;
AHeight := ABitmap.Height;
FillChar(ACallBacks, SizeOf(ACallBacks), 0);
ACallBacks.drawPattern := @DrawBitmapPattern;
FImage := ABitmap.imageRep.CGImageForProposedRect_context_hints(nil, nil, nil);
FColored := True;
FCGPattern := CGPatternCreate(Self, GetCGRect(0, 0, AWidth, AHeight),
CGAffineTransformIdentity, AWidth, AHeight, kCGPatternTilingConstantSpacing,
Ord(FColored), ACallBacks);
end;
constructor TCocoaBrush.CreateDefault;
begin
inherited Create(clWhite, True, False);
end;
constructor TCocoaBrush.Create(const ALogBrush: TLogBrush; const AGlobal: Boolean = False);
begin
FCGPattern := nil;
FImage := nil;
case ALogBrush.lbStyle of
BS_SOLID:
inherited Create(ColorToRGB(TColor(ALogBrush.lbColor)), True, AGlobal);
BS_HATCHED: // Hatched brush.
begin
inherited Create(ColorToRGB(TColor(ALogBrush.lbColor)), True, AGlobal);
SetHatchStyle(ALogBrush.lbHatch);
end;
BS_DIBPATTERN,
BS_DIBPATTERN8X8,
BS_DIBPATTERNPT,
BS_PATTERN,
BS_PATTERN8X8:
begin
inherited Create(ColorToRGB(TColor(ALogBrush.lbColor)), False, AGlobal);
SetBitmap(TCocoaBitmap(ALogBrush.lbHatch));
end
else
inherited Create(ColorToRGB(TColor(ALogBrush.lbColor)), False, AGlobal);
end;
end;
destructor TCocoaBrush.Destroy;
begin
if FCGPattern <> nil then
CGPatternRelease(FCGPattern);
if FImage <> nil then
CGImageRelease(FImage);
inherited Destroy;
end;
procedure TCocoaBrush.Apply(ADC: TCocoaContext);
var
RGBA: array[0..3] of Single;
AROP2: Integer;
APatternSpace: CGColorSpaceRef;
BaseSpace : CGColorSpaceRef;
begin
if ADC = nil then Exit;
{ if UseROP2 then
AROP2 := ADC.ROP2
else
AROP2 := R2_COPYPEN;}
GetRGBA(AROP2, RGBA[0], RGBA[1], RGBA[2], RGBA[3]);
// if AROP2 <> R2_NOT then
CGContextSetBlendMode(ADC.CGContext, kCGBlendModeNormal);
// else
// CGContextSetBlendMode(ADC.CGContext, kCGBlendModeDifference);
if FCGPattern <> nil then
begin
if not FColored then
BaseSpace:=CGColorSpaceCreateDeviceRGB
else
begin
BaseSpace:=nil;
RGBA[0] := 1.0;
end;
APatternSpace := CGColorSpaceCreatePattern(BaseSpace);
CGContextSetFillColorSpace(ADC.CGContext, APatternSpace);
CGColorSpaceRelease(APatternSpace);
if Assigned(BaseSpace) then CGColorSpaceRelease(BaseSpace);
CGContextSetFillPattern(ADC.CGcontext, FCGPattern, @RGBA[0]);
end
else
CGContextSetRGBFillColor(ADC.CGContext, RGBA[0], RGBA[1], RGBA[2], RGBA[3]);
end;
{ TCocoaTextLayout }
@ -1105,15 +1370,27 @@ end;
{ TCocoaGDIObject }
constructor TCocoaGDIObject.Create(AGlobal: Boolean);
begin
FRefCount := 0;
FGlobal := AGlobal;
end;
procedure TCocoaGDIObject.AddRef;
begin
if RefCount>=0 then inc(RefCount);
if FGlobal then Exit;
if FRefCount >= 0 then inc(FRefCount);
end;
procedure TCocoaGDIObject.Release;
begin
if RefCount>0 then Dec(RefCount)
else if RefCount=0 then Free;
if FGlobal then Exit;
if FRefCount > 0 then
Dec(FRefCount)
else
begin
//DebugLn('TCocoaGDIObject.Release Error - ', dbgsName(self), ' RefCount = ', dbgs(FRefCount));
end;
end;
end.

View File

@ -70,6 +70,18 @@ type
FNSApp : NSApplication;
delegate : TCocoaAppDelegate;
protected
FStockNullBrush: HBRUSH;
FStockBlackBrush: HBRUSH;
FStockLtGrayBrush: HBRUSH;
FStockGrayBrush: HBRUSH;
FStockDkGrayBrush: HBRUSH;
FStockWhiteBrush: HBRUSH;
FStockNullPen: HPEN;
FStockBlackPen: HPEN;
FStockWhitePen: HPEN;
FStockSystemFont: HFONT;
function GetAppHandle: THandle; override;
public
constructor Create; override;
@ -91,6 +103,9 @@ type
function CreateTimer(Interval: integer; TimerFunc: TWSTimerProc): THandle; override;
function DestroyTimer(TimerHandle: THandle): boolean; override;
procedure InitStockItems;
procedure FreeStockItems;
{todo:}
function DCGetPixel(CanvasHandle: HDC; X, Y: integer): TGraphicsColor; override;
procedure DCSetPixel(CanvasHandle: HDC; X, Y: integer; AColor: TGraphicsColor); override;

View File

@ -107,6 +107,7 @@ begin
{ Creates the AutoreleasePool }
pool := NSAutoreleasePool(NSAutoreleasePool.alloc).init;
InitStockItems;
end;
{------------------------------------------------------------------------------
@ -117,6 +118,8 @@ end;
destructor TCocoaWidgetSet.Destroy;
begin
inherited Destroy;
FreeStockItems;
CocoaWidgetSet := nil;
{ Releases the AutoreleasePool }
@ -244,6 +247,72 @@ begin
NSTimer(obj).invalidate;
end;
procedure TCocoaWidgetSet.InitStockItems;
var
LogBrush: TLogBrush;
logPen : TLogPen;
begin
FillChar(LogBrush,SizeOf(TLogBrush),0);
LogBrush.lbStyle := BS_NULL;
FStockNullBrush := HBrush(TCocoaBrush.Create(LogBrush, True));
LogBrush.lbStyle := BS_SOLID;
LogBrush.lbColor := $000000;
FStockBlackBrush := HBrush(TCocoaBrush.Create(LogBrush, True));
LogBrush.lbColor := $C0C0C0;
FStockLtGrayBrush := HBrush(TCocoaBrush.Create(LogBrush, True));
LogBrush.lbColor := $808080;
FStockGrayBrush := HBrush(TCocoaBrush.Create(LogBrush, True));
LogBrush.lbColor := $404040;
FStockDkGrayBrush := HBrush(TCocoaBrush.Create(LogBrush, True));
LogBrush.lbColor := $FFFFFF;
FStockWhiteBrush := HBrush(TCocoaBrush.Create(LogBrush, True));
{ LogPen.lopnStyle := PS_NULL;
LogPen.lopnWidth := Point(0, 0); // create cosmetic pens
LogPen.lopnColor := $FFFFFF;
FStockNullPen := CreatePenIndirect(LogPen);
TQtPen(FStockNullPen).FShared := True;
LogPen.lopnStyle := PS_SOLID;
FStockWhitePen := CreatePenIndirect(LogPen);
TQtPen(FStockWhitePen).FShared := True;
LogPen.lopnColor := $000000;
FStockBlackPen := CreatePenIndirect(LogPen);
TQtPen(FStockBlackPen).FShared := True;
}
end;
procedure TCocoaWidgetSet.FreeStockItems;
procedure DeleteAndNilObject(var h: HGDIOBJ);
begin
if h <> 0 then
TCocoaGDIObject(h).Global := False;
DeleteObject(h);
h := 0;
end;
begin
DeleteAndNilObject(FStockNullBrush);
DeleteAndNilObject(FStockBlackBrush);
DeleteAndNilObject(FStockLtGrayBrush);
DeleteAndNilObject(FStockGrayBrush);
DeleteAndNilObject(FStockDkGrayBrush);
DeleteAndNilObject(FStockWhiteBrush);
DeleteAndNilObject(FStockNullPen);
DeleteAndNilObject(FStockBlackPen);
DeleteAndNilObject(FStockWhitePen);
DeleteAndNilObject(FStockSystemFont);
end;
{------------------------------------------------------------------------------
Method: TCocoaWidgetSet.GetAppHandle
Returns: Returns NSApp object, created via NSApplication.sharedApplication

View File

@ -22,6 +22,7 @@ unit CocoaPrivate;
{$mode objfpc}{$H+}
{$modeswitch objectivec1}
{$interfaces corba}
interface
@ -82,31 +83,25 @@ type
function lclClientFrame: TRect; message 'lclClientFrame'; reintroduce;
end;
{ TCommonCallback }
{ ICommonCallback }
TCommonCallback = class(TObject)
public
Owner : NSObject;
constructor Create(AOwner: NSObject);
procedure MouseDown(x,y: Integer); virtual; abstract;
procedure MouseUp(x,y: Integer); virtual; abstract;
procedure MouseClick(ClickCount: Integer); virtual; abstract;
procedure MouseMove(x,y: Integer); virtual; abstract;
procedure Draw(ctx: NSGraphicsContext; const bounds, dirty: NSRect); virtual; abstract;
function ResetCursorRects: Boolean; virtual; abstract;
ICommonCallback = interface
procedure MouseDown(x,y: Integer);
procedure MouseUp(x,y: Integer);
procedure MouseClick(ClickCount: Integer);
procedure MouseMove(x,y: Integer);
procedure Draw(ctx: NSGraphicsContext; const bounds, dirty: NSRect);
function ResetCursorRects: Boolean;
end;
{ TWindowCallback }
{ IWindowCallback }
TWindowCallback = class(TObject)
public
Owner : NSWindow;
constructor Create(AOwner: NSWindow);
procedure Activate; virtual; abstract;
procedure Deactivate; virtual; abstract;
procedure CloseQuery(var CanClose: Boolean); virtual; abstract;
procedure Close; virtual; abstract;
procedure Resize; virtual; abstract;
IWindowCallback = interface(ICommonCallBack)
procedure Activate;
procedure Deactivate;
procedure CloseQuery(var CanClose: Boolean);
procedure Close;
procedure Resize;
end;
{ TCocoaMenu }
@ -129,7 +124,7 @@ type
protected
procedure actionButtonClick(sender: NSObject); message 'actionButtonClick:';
public
callback : TCommonCallback;
callback : ICommonCallback;
function initWithFrame(frameRect: NSRect): id; override;
function acceptsFirstResponder: Boolean; override;
procedure mouseDown(event: NSEvent); override;
@ -144,7 +139,7 @@ type
{ TCocoaTextField }
TCocoaTextField = objcclass(NSTextField)
callback : TCommonCallback;
callback : ICommonCallback;
function acceptsFirstResponder: Boolean; override;
procedure resetCursorRects; override;
end;
@ -152,7 +147,7 @@ type
{ TCocoaSecureTextField }
TCocoaSecureTextField = objcclass(NSSecureTextField)
callback : TCommonCallback;
callback : ICommonCallback;
function acceptsFirstResponder: Boolean; override;
procedure resetCursorRects; override;
end;
@ -161,7 +156,7 @@ type
{ TCocoaTextView }
TCocoaTextView = objcclass(NSTextView)
callback : TCommonCallback;
callback : ICommonCallback;
function acceptsFirstResponder: Boolean; override;
procedure resetCursorRects; override;
end;
@ -176,8 +171,7 @@ type
procedure windowDidResignKey(notification: NSNotification); message 'windowDidResignKey:';
procedure windowDidResize(notification: NSNotification); message 'windowDidResize:';
public
callback : TCommonCallback;
wincallback : TWindowCallback;
callback : IWindowCallback;
function acceptsFirstResponder: Boolean; override;
procedure mouseUp(event: NSEvent); override;
procedure mouseDown(event: NSEvent); override;
@ -190,7 +184,7 @@ type
{ TCocoaCustomControl }
TCocoaCustomControl = objcclass(NSControl)
callback : TCommonCallback;
callback : ICommonCallback;
procedure drawRect(dirtyRect: NSRect); override;
procedure resetCursorRects; override;
end;
@ -198,7 +192,7 @@ type
{ TCocoaScrollView }
TCocoaScrollView = objcclass(NSScrollView)
callback : TCommonCallback;
callback : ICommonCallback;
procedure resetCursorRects; override;
end;
@ -217,10 +211,17 @@ type
property Owner: TCocoaComboBox read fOwner;
end;
IComboboxCallBack = interface(ICommonCallBack)
procedure ComboBoxWillPopUp;
procedure ComboBoxWillDismiss;
procedure ComboBoxSelectionDidChange;
procedure ComboBoxSelectionIsChanging;
end;
{ TCocoaComboBox }
TCocoaComboBox = objcclass(NSComboBox, NSComboBoxDataSourceProtocol)
callback : TCommonCallback;
TCocoaComboBox = objcclass(NSComboBox, NSComboBoxDataSourceProtocol, NSComboBoxDelegateProtocol)
callback : IComboboxCallBack;
list : TCocoaComboBoxList;
resultNS : NSString; //use to return values to combo
function comboBox_objectValueForItemAtIndex_(combo: TCocoaComboBox; row: NSInteger): id;
@ -229,12 +230,16 @@ type
message 'numberOfItemsInComboBox:';
procedure dealloc; override;
procedure resetCursorRects; override;
procedure comboBoxWillPopUp(notification: NSNotification); message 'comboBoxWillPopUp:';
procedure comboBoxWillDismiss(notification: NSNotification); message 'comboBoxWillDismiss:';
procedure comboBoxSelectionDidChange(notification: NSNotification); message 'comboBoxSelectionDidChange:';
procedure comboBoxSelectionIsChanging(notification: NSNotification); message 'comboBoxSelectionIsChanging:';
end;
{ TCocoaScrollBar }
TCocoaScrollBar = objcclass(NSScroller)
callback : TCommonCallback;
callback : ICommonCallback;
procedure resetCursorRects; override;
end;
@ -253,7 +258,7 @@ type
{ TCocoaListView }
TCocoaListView = objcclass(NSTableView, NSTableViewDataSourceProtocol)
callback : TCommonCallback;
callback : ICommonCallback;
list : TCocoaStringList;
resultNS : NSString; //use to return values to combo
function numberOfRowsInTableView(aTableView: NSTableView): NSInteger; message 'numberOfRowsInTableView:';
@ -267,7 +272,7 @@ type
{ TCocoaGroupBox }
TCocoaGroupBox = objcclass(NSBox)
callback : TCommonCallback;
callback : ICommonCallback;
procedure resetCursorRects; override;
end;
@ -399,28 +404,28 @@ var
canClose : Boolean;
begin
canClose:=true;
wincallback.CloseQuery(canClose);
callback.CloseQuery(canClose);
Result:=canClose;
end;
procedure TCocoaWindow.windowWillClose(notification: NSNotification);
begin
wincallback.Close;
callback.Close;
end;
procedure TCocoaWindow.windowDidBecomeKey(notification: NSNotification);
begin
wincallback.Activate;
callback.Activate;
end;
procedure TCocoaWindow.windowDidResignKey(notification: NSNotification);
begin
wincallback.Deactivate;
callback.Deactivate;
end;
procedure TCocoaWindow.windowDidResize(notification: NSNotification);
begin
wincallback.Resize;
callback.Resize;
end;
function TCocoaWindow.acceptsFirstResponder: Boolean;
@ -478,13 +483,6 @@ begin
inherited mouseExited(event);
end;
{ TCommonCallback }
constructor TCommonCallback.Create(AOwner: NSObject);
begin
Owner:=AOwner;
end;
{ TCocoaSecureTextField }
function TCocoaSecureTextField.acceptsFirstResponder: Boolean;
@ -498,13 +496,6 @@ begin
inherited resetCursorRects;
end;
{ TWindowCallback }
constructor TWindowCallback.Create(AOwner: NSWindow);
begin
Owner:=AOwner;
end;
{ TCocoaCustomControl }
procedure TCocoaCustomControl.drawRect(dirtyRect:NSRect);
@ -815,6 +806,26 @@ begin
inherited resetCursorRects;
end;
procedure TCocoaComboBox.comboBoxWillPopUp(notification: NSNotification);
begin
callback.ComboBoxWillPopUp;
end;
procedure TCocoaComboBox.comboBoxWillDismiss(notification: NSNotification);
begin
callback.ComboBoxWillDismiss;
end;
procedure TCocoaComboBox.comboboxSelectionDidChange(notification: NSNotification);
begin
callback.ComboBoxSelectionDidChange;
end;
procedure TCocoaComboBox.comboBoxSelectionIsChanging(notification: NSNotification);
begin
callback.ComboBoxSelectionIsChanging;
end;
{ TCocoaMenu }
procedure TCocoaMenu.lclItemSelected(sender:id);

View File

@ -103,12 +103,8 @@ begin
end;
function TCocoaWidgetSet.CreateBrushIndirect(const LogBrush: TLogBrush): HBRUSH;
var
b : TCocoaBrush;
begin
b:=TCocoaBrush.Create;
with b do ColorToRGBFloat(LogBrush.lbColor, R, G, B);
Result:=HBRUSH(b);
Result := HBrush(TCocoaBrush.Create(LogBrush));
end;
function TCocoaWidgetSet.CreateCompatibleBitmap(DC: HDC; Width, Height: Integer): HBITMAP;
@ -151,7 +147,7 @@ function TCocoaWidgetSet.CreateFontIndirectEx(const LogFont: TLogFont;
var
cf : TCocoaFont;
begin
cf:=TCocoaFont.Create;
cf:=TCocoaFont.Create(False);
cf.Size:=LogFont.lfHeight;
cf.Name:=LongFontName;
if LogFont.lfWeight>FW_NORMAL then Include(cf.Style, cfs_Bold);
@ -281,9 +277,19 @@ function TCocoaWidgetSet.DeleteObject(GDIObject: HGDIOBJ): Boolean;
var
gdi: TCocoaGDIObject;
begin
Result:=True;
gdi:=CheckGDIOBJ(GdiObject);
if Assigned(gdi) then gdi.Release;
Result := False;
if GDIObject = 0 then
Exit(True);
gdi := CheckGDIOBJ(GdiObject);
if not Assigned(gdi) then
Exit;
if gdi.Global then
Exit;
if gdi.RefCount = 0 then gdi.Destroy;
end;
function TCocoaWidgetSet.DestroyIcon(Handle: HICON): Boolean;
@ -572,6 +578,51 @@ begin
Result:=False;
end;
function TCocoaWidgetSet.GetStockObject(Value: Integer): THandle;
begin
Result := 0;
case Value of
BLACK_BRUSH: // Black brush.
Result := FStockBlackBrush;
DKGRAY_BRUSH: // Dark gray brush.
Result := FStockDKGrayBrush;
GRAY_BRUSH: // Gray brush.
Result := FStockGrayBrush;
LTGRAY_BRUSH: // Light gray brush.
Result := FStockLtGrayBrush;
NULL_BRUSH: // Null brush (equivalent to HOLLOW_BRUSH).
Result := FStockNullBrush;
WHITE_BRUSH: // White brush.
Result := FStockWhiteBrush;
BLACK_PEN: // Black pen.
Result := FStockBlackPen;
NULL_PEN: // Null pen.
Result := FStockNullPen;
WHITE_PEN: // White pen.
Result := FStockWhitePen;
{System font. By default, Windows uses the system font to draw menus,
dialog box controls, and text. In Windows versions 3.0 and later,
the system font is a proportionally spaced font; earlier versions of
Windows used a monospace system font.}
{ DEFAULT_GUI_FONT, SYSTEM_FONT:
begin
If FStockSystemFont <> 0 then
begin
DeleteObject(FStockSystemFont);
FStockSystemFont := 0;
end;
If FStockSystemFont = 0 then
FStockSystemFont := CreateDefaultFont;
Result := FStockSystemFont;
end;}
end;
end;
function TCocoaWidgetSet.SetScrollInfo(Handle : HWND; SBStyle : Integer; ScrollInfo: TScrollInfo; bRedraw : Boolean): Integer;
begin
Result:=0;
@ -737,7 +788,7 @@ begin
Result := HFONT(dc.Font);
dc.Font := TCocoaFont(gdi);
end else if gdi is TCocoaRegion then begin // select region
Result := HBRUSH(dc.Region);
Result := HRGN(dc.Region);
dc.Region := TCocoaRegion(gdi);
end else if gdi is TCocoaBitmap then begin // select bitmap
{if not (ADC is TCarbonBitmapContext) then

View File

@ -114,8 +114,8 @@ function GetROP2(DC: HDC): Integer; override;}
function GetScrollBarSize(Handle: HWND; BarKind: Integer): integer; override;
function GetScrollbarVisible(Handle: HWND; SBStyle: Integer): boolean; override;
function GetScrollInfo(Handle: HWND; BarFlag: Integer; Var ScrollInfo: TScrollInfo): Boolean; override;
{function GetStockObject(Value: Integer): THandle; override;
function GetSysColor(nIndex: Integer): DWORD; override;}
function GetStockObject(Value: Integer): THandle; override;
{function GetSysColor(nIndex: Integer): DWORD; override;}
function GetSystemMetrics(nIndex: Integer): Integer; override;
function GetTextColor(DC: HDC) : TColorRef; Override;
function GetTextExtentPoint(DC: HDC; Str: PChar; Count: Integer; var Size: TSize): Boolean; override;

View File

@ -23,18 +23,19 @@ type
{ TLCLCommonCallback }
TLCLCommonCallback = class(TCommonCallback)
TLCLCommonCallback = class(TObject, ICommonCallBack)
public
Owner: NSObject;
Target : TControl;
Context : TCocoaContext;
constructor Create(AOwner: NSObject; ATarget: TControl);
constructor Create(AOwner: NSObject; ATarget: TControl); virtual;
destructor Destroy; override;
procedure MouseDown(x,y: Integer); override;
procedure MouseUp(x,y: Integer); override;
procedure MouseClick(clickCount: Integer); override;
procedure MouseMove(x,y: Integer); override;
procedure Draw(ControlContext: NSGraphicsContext; const bounds, dirty: NSRect); override;
function ResetCursorRects: Boolean; override;
procedure MouseDown(x,y: Integer); virtual;
procedure MouseUp(x,y: Integer); virtual;
procedure MouseClick(clickCount: Integer); virtual;
procedure MouseMove(x,y: Integer); virtual;
procedure Draw(ControlContext: NSGraphicsContext; const bounds, dirty: NSRect); virtual;
function ResetCursorRects: Boolean; virtual;
end;
{ TCocoaWSWinControl }
@ -110,8 +111,9 @@ end;
constructor TLCLCommonCallback.Create(AOwner: NSObject; ATarget: TControl);
begin
inherited Create(AOwner);
Target:=ATarget;
inherited Create;
Owner := AOwner;
Target := ATarget;
end;
destructor TLCLCommonCallback.Destroy;

View File

@ -40,15 +40,13 @@ uses
type
{ TLCLWindowCallback }
TLCLWindowCallback=class(TWindowCallback)
TLCLWindowCallback=class(TLCLCommonCallBack, IWindowCallback)
public
Target : TControl;
constructor Create(AOwner: NSWindow; ATarget: TControl);
procedure Activate; override;
procedure Deactivate; override;
procedure CloseQuery(var CanClose: Boolean); override;
procedure Close; override;
procedure Resize; override;
procedure Activate; virtual;
procedure Deactivate; virtual;
procedure CloseQuery(var CanClose: Boolean); virtual;
procedure Close; virtual;
procedure Resize; virtual;
end;
@ -148,12 +146,6 @@ implementation
{ TLCLWindowCallback }
constructor TLCLWindowCallback.Create(AOwner: NSWindow; ATarget: TControl);
begin
inherited Create(AOwner);
Target:=ATarget;
end;
procedure TLCLWindowCallback.Activate;
begin
LCLSendActivateMsg(Target, True, false);
@ -180,7 +172,7 @@ var
sz : NSSize;
r : TRect;
begin
sz := Owner.frame.size;
sz := NSWindow(Owner).frame.size;
TCocoaWSCustomForm.GetClientBounds(TWinControl(Target), r);
if Assigned(Target) then
LCLSendSizeMsg(Target, Round(sz.width), Round(sz.height), SIZENORMAL);
@ -216,8 +208,7 @@ begin
win:=TCocoaWindow(win.initWithContentRect_styleMask_backing_defer(CreateParamsToNSRect(AParams), WinMask, NSBackingStoreBuffered, False));
win.enableCursorRects;
TCocoaWindow(win).callback:=TLCLCommonCallback.Create(win, AWinControl);
TCocoaWindow(win).wincallback:=TLCLWindowCallback.Create(win, AWinControl);
TCocoaWindow(win).callback:=TLCLWindowCallback.Create(win, AWinControl);
win.setDelegate(win);
ns:=NSStringUtf8(AWinControl.Caption);
win.setTitle(ns);

View File

@ -31,7 +31,7 @@ uses
// Libs
MacOSAll, CocoaAll,
// LCL
Controls, StdCtrls, Graphics, LCLType, LMessages, LCLProc, Classes,
Controls, StdCtrls, Graphics, LCLType, LMessages, LCLProc, LCLMessageGlue, Classes,
// Widgetset
WSStdCtrls, WSLCLClasses, WSControls, WSProc,
// LCL Cocoa
@ -54,6 +54,15 @@ type
class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; override;
end;
{ TLCLComboboxCallback }
TLCLComboboxCallback = class(TLCLCommonCallback, IComboBoxCallback)
procedure ComboBoxWillPopUp;
procedure ComboBoxWillDismiss;
procedure ComboBoxSelectionDidChange;
procedure ComboBoxSelectionIsChanging;
end;
{ TCocoaWSCustomComboBox }
TCocoaWSCustomComboBox = class(TWSCustomComboBox)
@ -231,6 +240,30 @@ begin
end;
end;
{ TLCLComboboxCallback }
procedure TLCLComboboxCallback.ComboBoxWillPopUp;
begin
LCLSendDropDownMsg(Target);
end;
procedure TLCLComboboxCallback.ComboBoxWillDismiss;
begin
LCLSendCloseUpMsg(Target);
end;
procedure TLCLComboboxCallback.ComboBoxSelectionDidChange;
begin
// todo: send correct messages here. LM_CHANGED must be sent on editbox change
SendSimpleMessage(Target, LM_CHANGED);
SendSimpleMessage(Target, LM_SELCHANGE);
end;
procedure TLCLComboboxCallback.ComboBoxSelectionIsChanging;
begin
end;
{ TCocoaWSButton }
@ -610,10 +643,11 @@ begin
Exit;
end;
cmb.callback:=TLCLCommonCallback.Create(cmb, AWinControl);
cmb.callback:=TLCLComboboxCallback.Create(cmb, AWinControl);
cmb.list:=TCocoaComboBoxList.Create(cmb);
cmb.setUsesDataSource(true);
cmb.setDataSource(cmb);
cmb.setDelegate(cmb);
Result:=TLCLIntfHandle(cmb);
//todo: 26 pixels is the height of 'normal' combobox. The value is taken from the Interface Builder!
// use the correct way to set the size constraints