mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-10 11:56:09 +02:00
Carbon intf: TSynEdit fixed textout, improved scrolling
- enhanced clipboard to use more text formats - TComboBox.OnDropDown and OnCloseUp partial implementation git-svn-id: trunk@12509 -
This commit is contained in:
parent
3badd0dfcc
commit
1a9ab26796
@ -609,6 +609,7 @@ var
|
|||||||
W: WideString;
|
W: WideString;
|
||||||
Tag: ATSUAttributeTag;
|
Tag: ATSUAttributeTag;
|
||||||
DataSize: ByteCount;
|
DataSize: ByteCount;
|
||||||
|
Options: ATSLineLayoutOptions;
|
||||||
PValue: ATSUAttributeValuePtr;
|
PValue: ATSUAttributeValuePtr;
|
||||||
const
|
const
|
||||||
SName = 'BeginTextRender';
|
SName = 'BeginTextRender';
|
||||||
@ -643,7 +644,19 @@ begin
|
|||||||
PValue := @(CurrentFont.LineRotation);
|
PValue := @(CurrentFont.LineRotation);
|
||||||
if OSError(ATSUSetLayoutControls(ALayout, 1, @Tag, @DataSize, @PValue),
|
if OSError(ATSUSetLayoutControls(ALayout, 1, @Tag, @DataSize, @PValue),
|
||||||
Self, SName, 'ATSUSetLayoutControls', 'LineRotation') then Exit;
|
Self, SName, 'ATSUSetLayoutControls', 'LineRotation') then Exit;
|
||||||
|
|
||||||
|
// disable fractional positions of glyphs in layout
|
||||||
|
// TODO: restrict to monspaced fonts only
|
||||||
|
Tag := kATSULineLayoutOptionsTag;
|
||||||
|
DataSize := SizeOf(ATSLineLayoutOptions);
|
||||||
|
|
||||||
|
Options := kATSLineFractDisable or kATSLineDisableAutoAdjustDisplayPos or
|
||||||
|
kATSLineDisableAllLayoutOperations or kATSLineUseDeviceMetrics;
|
||||||
|
PValue := @Options;
|
||||||
|
if OSError(ATSUSetLayoutControls(ALayout, 1, @Tag, @DataSize, @PValue),
|
||||||
|
Self, SName, 'ATSUSetLayoutControls', 'LineLayoutOptions') then Exit;
|
||||||
|
|
||||||
|
|
||||||
// set layout context
|
// set layout context
|
||||||
Tag := kATSUCGContextTag;
|
Tag := kATSUCGContextTag;
|
||||||
DataSize := SizeOf(CGContextRef);
|
DataSize := SizeOf(CGContextRef);
|
||||||
|
@ -38,9 +38,10 @@ type
|
|||||||
{ TCarbonClipboard }
|
{ TCarbonClipboard }
|
||||||
|
|
||||||
TCarbonClipboard = class
|
TCarbonClipboard = class
|
||||||
|
FOwnerShips: Integer;
|
||||||
private
|
private
|
||||||
FPasteboards: Array [TClipboardType] of PasteboardRef;
|
FPasteboards: Array [TClipboardType] of PasteboardRef;
|
||||||
FFormats: TList; // list of CFStringRef UTIs, 1 is reserved for text/plain
|
FFormats: TList; // list of CFStringRef UTIs
|
||||||
FOnClipboardRequest: Array [TClipboardType] of TClipboardRequestEvent;
|
FOnClipboardRequest: Array [TClipboardType] of TClipboardRequestEvent;
|
||||||
|
|
||||||
function FindFormat(const UTI: CFStringRef): TClipboardFormat;
|
function FindFormat(const UTI: CFStringRef): TClipboardFormat;
|
||||||
@ -59,14 +60,16 @@ type
|
|||||||
OnRequestProc: TClipboardRequestEvent; FormatCount: Integer;
|
OnRequestProc: TClipboardRequestEvent; FormatCount: Integer;
|
||||||
Formats: PClipboardFormat): Boolean;
|
Formats: PClipboardFormat): Boolean;
|
||||||
function RegisterFormat(const AMimeType: String): TClipboardFormat;
|
function RegisterFormat(const AMimeType: String): TClipboardFormat;
|
||||||
|
public
|
||||||
|
property OwnerShips: Integer read FOwnerShips;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
ClipboardTypeToPasteboard: Array [TClipboardType] of CFStringRef =
|
ClipboardTypeToPasteboard: Array [TClipboardType] of CFStringRef =
|
||||||
(
|
(
|
||||||
{ctPrimarySelection } kPasteboardUniqueName, // local application pasteboard
|
{ctPrimarySelection } kPasteboardUniqueName, // local application pasteboard
|
||||||
{ctSecondarySelection} nil, // Find pasteboard
|
{ctSecondarySelection} nil, // Find pasteboard
|
||||||
{ctClipboard } nil // standard global pasteboard
|
{ctClipboard } nil // standard global pasteboard
|
||||||
);
|
);
|
||||||
Clipboard: TCarbonClipboard;
|
Clipboard: TCarbonClipboard;
|
||||||
|
|
||||||
@ -88,7 +91,7 @@ var
|
|||||||
begin
|
begin
|
||||||
for I := 1 to FFormats.Count - 1 do
|
for I := 1 to FFormats.Count - 1 do
|
||||||
begin
|
begin
|
||||||
if UTTypeConformsTo(UTI, CFStringRef(FFormats[I])) then
|
if UTTypeEqual(UTI, CFStringRef(FFormats[I])) then
|
||||||
begin
|
begin
|
||||||
Result := I;
|
Result := I;
|
||||||
Exit;
|
Exit;
|
||||||
@ -113,8 +116,14 @@ begin
|
|||||||
|
|
||||||
FOnClipboardRequest[T] := nil;
|
FOnClipboardRequest[T] := nil;
|
||||||
end;
|
end;
|
||||||
|
FOwnerShips := 0;
|
||||||
|
|
||||||
FFormats := TList.Create;
|
FFormats := TList.Create;
|
||||||
FFormats.Add(nil);
|
|
||||||
|
FFormats.Add(nil); // add default supported text formats
|
||||||
|
FFormats.Add(kUTTypePlainText);
|
||||||
|
FFormats.Add(kUTTypeUTF8PlainText);
|
||||||
|
FFormats.Add(kUTTypeUTF16PlainText);
|
||||||
|
|
||||||
RegisterFormat(PredefinedClipboardMimeTypes[pcfText]);
|
RegisterFormat(PredefinedClipboardMimeTypes[pcfText]);
|
||||||
end;
|
end;
|
||||||
@ -128,7 +137,7 @@ var
|
|||||||
I: Integer;
|
I: Integer;
|
||||||
S: CFStringRef;
|
S: CFStringRef;
|
||||||
begin
|
begin
|
||||||
for I := 0 to FFormats.Count - 1 do
|
for I := 4 to FFormats.Count - 1 do // 0..3 are predefined
|
||||||
begin
|
begin
|
||||||
S := FFormats[I];
|
S := FFormats[I];
|
||||||
FreeCFString(S);
|
FreeCFString(S);
|
||||||
@ -157,6 +166,7 @@ begin
|
|||||||
if (PasteboardSynchronize(FPasteboards[T]) and
|
if (PasteboardSynchronize(FPasteboards[T]) and
|
||||||
kPasteboardClientIsOwner) = 0 then
|
kPasteboardClientIsOwner) = 0 then
|
||||||
begin // inform LCL about ownership lost
|
begin // inform LCL about ownership lost
|
||||||
|
Dec(FOwnerShips);
|
||||||
FOnClipboardRequest[T](0, nil);
|
FOnClipboardRequest[T](0, nil);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -192,12 +202,6 @@ var
|
|||||||
begin
|
begin
|
||||||
if (FormatID > 0) and (FormatID < FFormats.Count) then
|
if (FormatID > 0) and (FormatID < FFormats.Count) then
|
||||||
begin
|
begin
|
||||||
if FormatID = 1 then
|
|
||||||
begin
|
|
||||||
Result := PredefinedClipboardMimeTypes[pcfText];
|
|
||||||
Exit;
|
|
||||||
end;
|
|
||||||
|
|
||||||
S := UTTypeCopyPreferredTagWithClass(CFStringRef(FFormats[FormatID]), kUTTagClassMIMEType);
|
S := UTTypeCopyPreferredTagWithClass(CFStringRef(FFormats[FormatID]), kUTTagClassMIMEType);
|
||||||
try
|
try
|
||||||
Result := CFStringToStr(S);
|
Result := CFStringToStr(S);
|
||||||
@ -221,17 +225,34 @@ function TCarbonClipboard.GetData(ClipboardType: TClipboardType;
|
|||||||
FormatID: TClipboardFormat; Stream: TStream): Boolean;
|
FormatID: TClipboardFormat; Stream: TStream): Boolean;
|
||||||
var
|
var
|
||||||
Pasteboard: PasteboardRef;
|
Pasteboard: PasteboardRef;
|
||||||
I, J: Integer;
|
I: Integer;
|
||||||
L: SizeUInt;
|
UTI, CFString: CFStringRef;
|
||||||
|
Encoding: CFStringEncoding;
|
||||||
Flavors: CFArrayRef;
|
Flavors: CFArrayRef;
|
||||||
UTI: CFStringRef;
|
|
||||||
FlavorCount: CFIndex;
|
|
||||||
FlavorData: CFDataRef;
|
FlavorData: CFDataRef;
|
||||||
Count: ItemCount;
|
Count: ItemCount;
|
||||||
ID: PasteboardItemID;
|
ID: PasteboardItemID;
|
||||||
S: String;
|
S: String;
|
||||||
const
|
const
|
||||||
SName = 'GetData';
|
SName = 'GetData';
|
||||||
|
|
||||||
|
function HasFormat(Format: CFStringRef): Boolean;
|
||||||
|
var
|
||||||
|
FlavorCount: CFIndex;
|
||||||
|
J: Integer;
|
||||||
|
begin
|
||||||
|
Result := False;
|
||||||
|
FlavorCount := CFArrayGetCount(Flavors);
|
||||||
|
|
||||||
|
for J := 0 to FlavorCount - 1 do
|
||||||
|
if UTTypeEqual(Format, CFArrayGetValueAtIndex(Flavors, J)) then
|
||||||
|
begin
|
||||||
|
//DebugLn('Has UTI ' + CFStringToStr(Format));
|
||||||
|
Result := True;
|
||||||
|
Break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Result := False;
|
Result := False;
|
||||||
|
|
||||||
@ -255,46 +276,55 @@ begin
|
|||||||
if OSError(PasteboardCopyItemFlavors(Pasteboard, ID, Flavors), Self, SName,
|
if OSError(PasteboardCopyItemFlavors(Pasteboard, ID, Flavors), Self, SName,
|
||||||
'PasteboardCopyItemFlavors') then Continue;
|
'PasteboardCopyItemFlavors') then Continue;
|
||||||
|
|
||||||
FlavorCount := CFArrayGetCount(Flavors);
|
UTI := FFormats[FormatID];
|
||||||
for J := 0 to FlavorCount - 1 do
|
if FormatID = 1 then
|
||||||
begin
|
begin
|
||||||
UTI := CFArrayGetValueAtIndex(Flavors, J);
|
if HasFormat(FFormats[2]) then UTI := FFormats[2] // check UTF-8 text
|
||||||
//DebugLn('TCarbonClipboard.GetData FlavorType: ' + CFStringToStr(UTI) +
|
else
|
||||||
// ' ' + CFStringToStr(FFormats[FormatID]));
|
if HasFormat(FFormats[3]) then UTI := FFormats[3] // check UTF-16 text
|
||||||
if UTTypeConformsTo(FFormats[FormatID], UTI) then
|
else
|
||||||
|
if not HasFormat(UTI) then Exit; // check plain text
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if not HasFormat(UTI) then Exit;
|
||||||
|
|
||||||
|
//DebugLn('TCarbonClipboard.GetData Paste FlavorType: ' + CFStringToStr(UTI));
|
||||||
|
|
||||||
|
if OSError(PasteboardCopyItemFlavorData(Pasteboard, ID, UTI, FlavorData),
|
||||||
|
Self, SGetData, 'PasteboardCopyItemFlavorData') then Continue;
|
||||||
|
try
|
||||||
|
if CFDataGetLength(FlavorData) = 0 then
|
||||||
begin
|
begin
|
||||||
//DebugLn('TCarbonClipboard.GetData Paste FlavorType: ' + CFStringToStr(UTI));
|
|
||||||
|
|
||||||
if OSError(PasteboardCopyItemFlavorData(Pasteboard, ID, UTI, FlavorData),
|
|
||||||
Self, SGetData, 'PasteboardCopyItemFlavorData') then Continue;
|
|
||||||
try
|
|
||||||
if CFDataGetLength(FlavorData) = 0 then
|
|
||||||
begin
|
|
||||||
Result := True;
|
|
||||||
Exit;
|
|
||||||
end;
|
|
||||||
//DebugLn('TCarbonClipboard.GetData Paste FlavordataLength: ' + DbgS(CFDataGetLength(FlavorData)));
|
|
||||||
|
|
||||||
if FormatID = 1 then // convert text/plain UTF-16 to UTF-8
|
|
||||||
begin
|
|
||||||
SetLength(S, (CFDataGetLength(FlavorData) div 2) * 3);
|
|
||||||
if ConvertUTF16ToUTF8(PChar(S), Length(S) + 1,
|
|
||||||
PWideChar(CFDataGetBytePtr(FlavorData)), CFDataGetLength(FlavorData) div 2,
|
|
||||||
[toInvalidCharToSymbol], L) <> trNoError then Exit;
|
|
||||||
|
|
||||||
SetLength(S, L - 1);
|
|
||||||
Stream.Write(S[1], L - 1);
|
|
||||||
end
|
|
||||||
else
|
|
||||||
Stream.Write(CFDataGetBytePtr(FlavorData)^, CFDataGetLength(FlavorData));
|
|
||||||
finally
|
|
||||||
CFRelease(FlavorData);
|
|
||||||
end;
|
|
||||||
|
|
||||||
Result := True;
|
Result := True;
|
||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
|
//DebugLn('TCarbonClipboard.GetData Paste FlavordataLength: ' + DbgS(CFDataGetLength(FlavorData)));
|
||||||
|
|
||||||
|
if FormatID = 1 then
|
||||||
|
begin
|
||||||
|
if UTI = FFormats[2] then // UTF-8 text
|
||||||
|
Encoding := kCFStringEncodingUTF8;
|
||||||
|
if UTI = FFormats[3] then // UTF-16 text
|
||||||
|
Encoding := kCFStringEncodingUTF16;
|
||||||
|
if UTI = FFormats[1] then // plain text
|
||||||
|
Encoding := CFStringGetSystemEncoding;
|
||||||
|
|
||||||
|
CreateCFString(FlavorData, Encoding, CFString);
|
||||||
|
try
|
||||||
|
S := CFStringtoStr(CFString);
|
||||||
|
Stream.Write(S[1], Length(S));
|
||||||
|
finally
|
||||||
|
FreeCFString(CFString);
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
Stream.Write(CFDataGetBytePtr(FlavorData)^, CFDataGetLength(FlavorData));
|
||||||
|
finally
|
||||||
|
CFRelease(FlavorData);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Result := True;
|
||||||
|
Exit;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -343,10 +373,14 @@ begin
|
|||||||
for J := 0 to FlavorCount - 1 do
|
for J := 0 to FlavorCount - 1 do
|
||||||
begin
|
begin
|
||||||
UTI := CFArrayGetValueAtIndex(Flavors, J);
|
UTI := CFArrayGetValueAtIndex(Flavors, J);
|
||||||
|
//DebugLn('TCarbonClipboard.GetFormats ' + CFStringToStr(UTI));
|
||||||
|
|
||||||
FormatID := FindFormat(UTI);
|
FormatID := FindFormat(UTI);
|
||||||
if FormatID = 0 then
|
if FormatID = 0 then
|
||||||
FormatID := FFormats.Add(UTI);
|
FormatID := FFormats.Add(UTI);
|
||||||
|
if FormatID < 4 then // if it is text format, add plain text format
|
||||||
|
if Formats.IndexOf(Pointer(1)) = -1 then Formats.Add(Pointer(1));
|
||||||
|
|
||||||
|
|
||||||
if Formats.IndexOf(Pointer(FormatID)) = -1 then
|
if Formats.IndexOf(Pointer(FormatID)) = -1 then
|
||||||
begin
|
begin
|
||||||
@ -388,46 +422,53 @@ function TCarbonClipboard.GetOwnerShip(ClipboardType: TClipboardType;
|
|||||||
OnRequestProc: TClipboardRequestEvent; FormatCount: Integer;
|
OnRequestProc: TClipboardRequestEvent; FormatCount: Integer;
|
||||||
Formats: PClipboardFormat): Boolean;
|
Formats: PClipboardFormat): Boolean;
|
||||||
|
|
||||||
|
procedure AddData(Format: CFStringRef; CFData: CFDataRef);
|
||||||
|
begin
|
||||||
|
if CFData = nil then Exit;
|
||||||
|
//DebugLn('Add Data ' + CFStringToStr(Format));
|
||||||
|
|
||||||
|
OSError(PasteboardPutItemFlavor(FPasteboards[ClipboardType],
|
||||||
|
PasteboardItemID(1), Format, CFData, 0),
|
||||||
|
Self, 'GetOwnerShip', 'PasteboardPutItemFlavor');
|
||||||
|
end;
|
||||||
|
|
||||||
procedure PutOnClipboard;
|
procedure PutOnClipboard;
|
||||||
var
|
var
|
||||||
Data: CFDataRef;
|
DataStream: TStringStream;
|
||||||
UTI: CFStringRef;
|
|
||||||
DataStream: TMemoryStream;
|
|
||||||
I: Integer;
|
I: Integer;
|
||||||
L: SizeUInt;
|
CFString: CFStringRef;
|
||||||
W: WideString;
|
|
||||||
begin
|
begin
|
||||||
DataStream := TMemoryStream.Create;
|
DataStream := TStringStream.Create('');
|
||||||
|
|
||||||
for I := 0 to FormatCount - 1 do
|
for I := 0 to FormatCount - 1 do
|
||||||
begin
|
begin
|
||||||
DataStream.Size := 0;
|
|
||||||
DataStream.Position := 0;
|
|
||||||
|
|
||||||
if not ((Formats[I] > 0) and (Formats[I] < FFormats.Count)) then
|
if not ((Formats[I] > 0) and (Formats[I] < FFormats.Count)) then
|
||||||
begin
|
begin
|
||||||
DebugLn('TCarbonClipboard.GetOwnerShip Error: Invalid Format ' + DbgS(Formats[I]) + ' specified!');
|
DebugLn('TCarbonClipboard.GetOwnerShip Error: Invalid Format ' + DbgS(Formats[I]) + ' specified!');
|
||||||
Continue;
|
Continue;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
UTI := CFStringRef(FFormats[Formats[I]]);
|
DataStream.Size := 0;
|
||||||
|
DataStream.Position := 0;
|
||||||
FOnClipBoardRequest[ClipboardType](Formats[I], DataStream);
|
FOnClipBoardRequest[ClipboardType](Formats[I], DataStream);
|
||||||
|
|
||||||
if Formats[I] = 1 then // convert plain/text UTF-8 to UTF-16
|
if Formats[I] = 1 then // add more unicode and mac text formats
|
||||||
begin
|
begin
|
||||||
SetLength(W, DataStream.Size);
|
CreateCFString(DataStream.DataString, CFString);
|
||||||
if ConvertUTF8ToUTF16(PWideChar(W), Length(W) + 1, PChar(DataStream.Memory),
|
try
|
||||||
DataStream.Size, [toInvalidCharToSymbol], L) <> trNoError then Exit;
|
// UTF-8 text
|
||||||
|
AddData(FFormats[2], CFStringToData(CFString, kCFStringEncodingUTF8));
|
||||||
SetLength(W, L - 1);
|
// UTF-16 text
|
||||||
Data := CFDataCreate(nil, PChar(W), (L - 1) * 2);
|
AddData(FFormats[3], CFStringToData(CFString, kCFStringEncodingUTF16));
|
||||||
|
// plain text
|
||||||
|
AddData(FFormats[1], CFStringToData(CFString, CFStringGetSystemEncoding));
|
||||||
|
finally
|
||||||
|
FreeCFString(CFString);
|
||||||
|
end;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
Data := CFDataCreate(nil, DataStream.Memory, DataStream.Size);
|
AddData(FFormats[Formats[I]], CFDataCreate(nil, @DataStream.DataString[1],
|
||||||
|
DataStream.Size));
|
||||||
OSError(PasteboardPutItemFlavor(FPasteboards[ClipboardType],
|
|
||||||
PasteboardItemID(1), UTI, Data, 0),
|
|
||||||
Self, 'GetOwnerShip', 'PasteboardPutItemFlavor');
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
DataStream.Free;
|
DataStream.Free;
|
||||||
@ -435,13 +476,14 @@ function TCarbonClipboard.GetOwnerShip(ClipboardType: TClipboardType;
|
|||||||
|
|
||||||
begin
|
begin
|
||||||
Result := False;
|
Result := False;
|
||||||
DebugLn('TCarbonClipboard.GetOwnerShip');
|
//DebugLn('TCarbonClipboard.GetOwnerShip');
|
||||||
|
|
||||||
if (FormatCount = 0) or (OnRequestProc = nil) then
|
if (FormatCount = 0) or (OnRequestProc = nil) then
|
||||||
begin
|
begin
|
||||||
// The LCL indicates it doesn't have the clipboard data anymore
|
// The LCL indicates it doesn't have the clipboard data anymore
|
||||||
// and the interface can't use the OnRequestProc anymore.
|
// and the interface can't use the OnRequestProc anymore.
|
||||||
FOnClipboardRequest[ClipboardType] := nil;
|
FOnClipboardRequest[ClipboardType] := nil;
|
||||||
|
Dec(FOwnerShips);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
@ -450,6 +492,7 @@ begin
|
|||||||
FOnClipboardRequest[ClipboardType] := nil;
|
FOnClipboardRequest[ClipboardType] := nil;
|
||||||
if not Clear(ClipboardType) then Exit;
|
if not Clear(ClipboardType) then Exit;
|
||||||
|
|
||||||
|
Inc(FOwnerShips);
|
||||||
FOnClipboardRequest[ClipboardType] := OnRequestProc;
|
FOnClipboardRequest[ClipboardType] := OnRequestProc;
|
||||||
PutOnClipboard;
|
PutOnClipboard;
|
||||||
end;
|
end;
|
||||||
@ -467,16 +510,11 @@ function TCarbonClipboard.RegisterFormat(const AMimeType: String): TClipboardFor
|
|||||||
var
|
var
|
||||||
UTI, M: CFStringRef;
|
UTI, M: CFStringRef;
|
||||||
begin
|
begin
|
||||||
if AMimeType = PredefinedClipboardMimeTypes[pcfText] then
|
CreateCFString(AMimeType, M);
|
||||||
CreateCFString('public.utf16-plain-text', UTI)
|
try
|
||||||
else
|
UTI := UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, M, nil);
|
||||||
begin
|
finally
|
||||||
CreateCFString(AMimeType, M);
|
FreeCFString(M);
|
||||||
try
|
|
||||||
UTI := UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, M, nil);
|
|
||||||
finally
|
|
||||||
FreeCFString(M);
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
Result := FindFormat(UTI);
|
Result := FindFormat(UTI);
|
||||||
@ -497,7 +535,7 @@ initialization
|
|||||||
|
|
||||||
finalization
|
finalization
|
||||||
|
|
||||||
Clipboard.Free;
|
FreeAndNil(Clipboard);
|
||||||
FreeCFString(ClipboardTypeToPasteboard[ctSecondarySelection]);
|
FreeCFString(ClipboardTypeToPasteboard[ctSecondarySelection]);
|
||||||
FreeCFString(ClipboardTypeToPasteboard[ctClipboard]);
|
FreeCFString(ClipboardTypeToPasteboard[ctClipboard]);
|
||||||
|
|
||||||
|
@ -75,11 +75,14 @@ type
|
|||||||
LCLObject: TWinControl; // LCL control which created this widget
|
LCLObject: TWinControl; // LCL control which created this widget
|
||||||
Context: TCarbonContext; // Carbon content area context
|
Context: TCarbonContext; // Carbon content area context
|
||||||
Widget: Pointer; // Reference to the Carbon window or control
|
Widget: Pointer; // Reference to the Carbon window or control
|
||||||
|
public
|
||||||
|
procedure FocusSet; dynamic;
|
||||||
|
procedure FocusKilled; dynamic;
|
||||||
|
procedure BoundsChanged; virtual;
|
||||||
public
|
public
|
||||||
constructor Create(const AObject: TWinControl; const AParams: TCreateParams);
|
constructor Create(const AObject: TWinControl; const AParams: TCreateParams);
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
procedure AddToWidget(AParent: TCarbonWidget); virtual; abstract;
|
procedure AddToWidget(AParent: TCarbonWidget); virtual; abstract;
|
||||||
procedure BoundsChanged; virtual;
|
|
||||||
function GetClientRect(var ARect: TRect): Boolean; virtual; abstract;
|
function GetClientRect(var ARect: TRect): Boolean; virtual; abstract;
|
||||||
function GetPreferredSize: TPoint; virtual;
|
function GetPreferredSize: TPoint; virtual;
|
||||||
function GetMousePos: TPoint; virtual; abstract;
|
function GetMousePos: TPoint; virtual; abstract;
|
||||||
@ -373,6 +376,26 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{------------------------------------------------------------------------------
|
||||||
|
Method: TCarbonWidget.FocusSet
|
||||||
|
|
||||||
|
Handles set focus
|
||||||
|
------------------------------------------------------------------------------}
|
||||||
|
procedure TCarbonWidget.FocusSet;
|
||||||
|
begin
|
||||||
|
LCLSendSetFocusMsg(LCLObject);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{------------------------------------------------------------------------------
|
||||||
|
Method: TCarbonWidget.FocusKilled
|
||||||
|
|
||||||
|
Handles kill focus
|
||||||
|
------------------------------------------------------------------------------}
|
||||||
|
procedure TCarbonWidget.FocusKilled;
|
||||||
|
begin
|
||||||
|
LCLSendKillFocusMsg(LCLObject);
|
||||||
|
end;
|
||||||
|
|
||||||
{------------------------------------------------------------------------------
|
{------------------------------------------------------------------------------
|
||||||
Method: TCarbonWidget.BoundsChanged
|
Method: TCarbonWidget.BoundsChanged
|
||||||
|
|
||||||
|
@ -82,6 +82,8 @@ type
|
|||||||
class function GetValidEvents: TCarbonControlEvents; override;
|
class function GetValidEvents: TCarbonControlEvents; override;
|
||||||
procedure ListItemSelected(AIndex: Integer); virtual;
|
procedure ListItemSelected(AIndex: Integer); virtual;
|
||||||
procedure ValueChanged; override;
|
procedure ValueChanged; override;
|
||||||
|
procedure FocusSet; override;
|
||||||
|
procedure FocusKilled; override;
|
||||||
public
|
public
|
||||||
function GetText(var S: String): Boolean; override;
|
function GetText(var S: String): Boolean; override;
|
||||||
procedure SetReadOnly(AReadOnly: Boolean); override;
|
procedure SetReadOnly(AReadOnly: Boolean); override;
|
||||||
@ -630,6 +632,30 @@ begin
|
|||||||
if FReadOnly then ListItemSelected(GetValue - 1);
|
if FReadOnly then ListItemSelected(GetValue - 1);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{------------------------------------------------------------------------------
|
||||||
|
Method: TCarbonComboBox.FocusSet
|
||||||
|
|
||||||
|
Handles set focus
|
||||||
|
------------------------------------------------------------------------------}
|
||||||
|
procedure TCarbonComboBox.FocusSet;
|
||||||
|
begin
|
||||||
|
inherited;
|
||||||
|
// emulate DropDown event here
|
||||||
|
LCLSendDropDownMsg(LCLObject);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{------------------------------------------------------------------------------
|
||||||
|
Method: TCarbonComboBox.FocusKilled
|
||||||
|
|
||||||
|
Handles kill focus
|
||||||
|
------------------------------------------------------------------------------}
|
||||||
|
procedure TCarbonComboBox.FocusKilled;
|
||||||
|
begin
|
||||||
|
inherited;
|
||||||
|
// emulate CloseUp event here
|
||||||
|
LCLSendCloseUpMsg(LCLObject);
|
||||||
|
end;
|
||||||
|
|
||||||
{------------------------------------------------------------------------------
|
{------------------------------------------------------------------------------
|
||||||
Method: TCarbonComboBox.GetText
|
Method: TCarbonComboBox.GetText
|
||||||
Params: S - Text
|
Params: S - Text
|
||||||
|
@ -471,7 +471,8 @@ begin
|
|||||||
SendEventToEventTarget(Event, Target);
|
SendEventToEventTarget(Event, Target);
|
||||||
ReleaseEvent(Event);
|
ReleaseEvent(Event);
|
||||||
|
|
||||||
Clipboard.CheckOwnerShip;
|
if Clipboard <> nil then
|
||||||
|
if Clipboard.OwnerShips > 0 then Clipboard.CheckOwnerShip;
|
||||||
|
|
||||||
until Application.Terminated;
|
until Application.Terminated;
|
||||||
|
|
||||||
|
@ -171,17 +171,19 @@ type
|
|||||||
TCarbonCustomControl = class(TCarbonControl)
|
TCarbonCustomControl = class(TCarbonControl)
|
||||||
private
|
private
|
||||||
FScrollView: HIViewRef;
|
FScrollView: HIViewRef;
|
||||||
FScrollOrigin: TPoint;
|
FScrollOrigin: HIPoint;
|
||||||
FScrollSize: TPoint;
|
FScrollSize: TPoint;
|
||||||
FScrollPageSize: TPoint;
|
FScrollPageSize: TPoint;
|
||||||
|
FMulX: Single; // multiply x coords to fit real page size
|
||||||
|
FMulY: Single; // multiply y coords to fit real page size
|
||||||
protected
|
protected
|
||||||
procedure RegisterEvents; override;
|
procedure RegisterEvents; override;
|
||||||
procedure CreateWidget(const AParams: TCreateParams); override;
|
procedure CreateWidget(const AParams: TCreateParams); override;
|
||||||
procedure DestroyWidget; override;
|
procedure DestroyWidget; override;
|
||||||
function GetFrame(Index: Integer): ControlRef; override;
|
function GetFrame(Index: Integer): ControlRef; override;
|
||||||
public
|
public
|
||||||
procedure GetInfo(out AImageSize, AViewSize, ALineSize, AOrigin: TPoint); dynamic;
|
procedure GetInfo(out AImageSize, AViewSize, ALineSize: HISize; out AOrigin: HIPoint); virtual;
|
||||||
procedure ScrollTo(const ANewOrigin: TPoint); dynamic;
|
procedure ScrollTo(const ANewOrigin: HIPoint); virtual;
|
||||||
public
|
public
|
||||||
procedure SetColor(const AColor: TColor); override;
|
procedure SetColor(const AColor: TColor); override;
|
||||||
procedure SetFont(const AFont: TFont); override;
|
procedure SetFont(const AFont: TFont); override;
|
||||||
@ -363,7 +365,6 @@ function CarbonScrollable_GetInfo(ANextHandler: EventHandlerCallRef;
|
|||||||
AEvent: EventRef;
|
AEvent: EventRef;
|
||||||
AWidget: TCarbonWidget): OSStatus; {$IFDEF darwin}mwpascal;{$ENDIF}
|
AWidget: TCarbonWidget): OSStatus; {$IFDEF darwin}mwpascal;{$ENDIF}
|
||||||
var
|
var
|
||||||
ImageSize, ViewSize, LineSize, Origin: TPoint;
|
|
||||||
ImageHISize, ViewHISize, LineHISize: HISize;
|
ImageHISize, ViewHISize, LineHISize: HISize;
|
||||||
HIOrigin: HIPoint;
|
HIOrigin: HIPoint;
|
||||||
const
|
const
|
||||||
@ -373,12 +374,7 @@ begin
|
|||||||
DebugLn('CarbonScrollable_GetInfo ', DbgSName(AWidget.LCLObject));
|
DebugLn('CarbonScrollable_GetInfo ', DbgSName(AWidget.LCLObject));
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
(AWidget as TCarbonCustomControl).GetInfo(ImageSize, ViewSize, LineSize, Origin);
|
(AWidget as TCarbonCustomControl).GetInfo(ImageHISize, ViewHISize, LineHISize, HIOrigin);
|
||||||
|
|
||||||
ImageHISize := PointToHISize(ImageSize);
|
|
||||||
ViewHISize := PointToHISize(ViewSize);
|
|
||||||
LineHISize := PointToHISize(LineSize);
|
|
||||||
HIOrigin := PointToHIPoint(Origin);
|
|
||||||
|
|
||||||
OSError(SetEventParameter(AEvent, kEventParamImageSize, typeHISize,
|
OSError(SetEventParameter(AEvent, kEventParamImageSize, typeHISize,
|
||||||
SizeOf(HISize), @ImageHISize), SName, SSetEvent, 'kEventParamImageSize');
|
SizeOf(HISize), @ImageHISize), SName, SSetEvent, 'kEventParamImageSize');
|
||||||
@ -411,7 +407,7 @@ begin
|
|||||||
SizeOf(HIPoint), nil, @Origin), 'CarbonScrollable_ScrollTo', SGetEvent,
|
SizeOf(HIPoint), nil, @Origin), 'CarbonScrollable_ScrollTo', SGetEvent,
|
||||||
'kEventParamOrigin') then Exit;
|
'kEventParamOrigin') then Exit;
|
||||||
|
|
||||||
(AWidget as TCarbonCustomControl).ScrollTo(HIPointToPoint(Origin));
|
(AWidget as TCarbonCustomControl).ScrollTo(Origin);
|
||||||
|
|
||||||
Result := noErr;
|
Result := noErr;
|
||||||
end;
|
end;
|
||||||
@ -455,7 +451,9 @@ begin
|
|||||||
FScrollView := EmbedInScrollView(AParams);
|
FScrollView := EmbedInScrollView(AParams);
|
||||||
FScrollSize := Classes.Point(0, 0);
|
FScrollSize := Classes.Point(0, 0);
|
||||||
FScrollPageSize := Classes.Point(0, 0);
|
FScrollPageSize := Classes.Point(0, 0);
|
||||||
FScrollOrigin := Classes.Point(0, 0);
|
FScrollOrigin := GetHIPoint(0, 0);
|
||||||
|
FMulX := 1;
|
||||||
|
FMulY := 1;
|
||||||
|
|
||||||
inherited;
|
inherited;
|
||||||
end;
|
end;
|
||||||
@ -489,15 +487,27 @@ end;
|
|||||||
ALineSize - Size of scrollable line
|
ALineSize - Size of scrollable line
|
||||||
AOrigin - Scroll position
|
AOrigin - Scroll position
|
||||||
|
|
||||||
Handles scrollableget info event
|
Handles scrollable get info event
|
||||||
------------------------------------------------------------------------------}
|
------------------------------------------------------------------------------}
|
||||||
procedure TCarbonCustomControl.GetInfo(out AImageSize, AViewSize,
|
procedure TCarbonCustomControl.GetInfo(out AImageSize, AViewSize, ALineSize: HISize;
|
||||||
ALineSize, AOrigin: TPoint);
|
out AOrigin: HIPoint);
|
||||||
|
var
|
||||||
|
C: TRect;
|
||||||
begin
|
begin
|
||||||
AOrigin := FScrollOrigin;
|
// modify coordinates to fit real page size
|
||||||
AImageSize := FScrollSize;
|
GetClientRect(C);
|
||||||
AViewSize := FScrollPageSize;
|
|
||||||
ALineSize := Classes.Point(10, 10);
|
if FScrollPageSize.X = 0 then FMulX := 1
|
||||||
|
else
|
||||||
|
FMulX := (C.Right - C.Left) / FScrollPageSize.X;
|
||||||
|
if FScrollPageSize.Y = 0 then FMulY := 1
|
||||||
|
else
|
||||||
|
FMulY := (C.Bottom - C.Top) / FScrollPageSize.Y;
|
||||||
|
|
||||||
|
AOrigin := GetHIPoint(FScrollOrigin.X * FMulX, FScrollOrigin.Y * FMulY);
|
||||||
|
AImageSize := GetHISize(FScrollSize.X * FMulX, FScrollSize.Y * FMulY);
|
||||||
|
AViewSize := GetHISize(C.Right - C.Left, C.Bottom - C.Top);
|
||||||
|
ALineSize := GetHISize(FScrollPageSize.X * FMulX / 40, FScrollPageSize.Y * FMulY / 40);
|
||||||
|
|
||||||
{$IFDEF VerboseScroll}
|
{$IFDEF VerboseScroll}
|
||||||
DebugLn('TCarbonCustomControl.GetInfo ' + LCLObject.Name + ' Origin: ' +
|
DebugLn('TCarbonCustomControl.GetInfo ' + LCLObject.Name + ' Origin: ' +
|
||||||
@ -512,7 +522,7 @@ end;
|
|||||||
|
|
||||||
Handles scrollable scroll to event
|
Handles scrollable scroll to event
|
||||||
------------------------------------------------------------------------------}
|
------------------------------------------------------------------------------}
|
||||||
procedure TCarbonCustomControl.ScrollTo(const ANewOrigin: TPoint);
|
procedure TCarbonCustomControl.ScrollTo(const ANewOrigin: HIPoint);
|
||||||
var
|
var
|
||||||
ScrollMsg: TLMScroll;
|
ScrollMsg: TLMScroll;
|
||||||
begin
|
begin
|
||||||
@ -521,14 +531,19 @@ begin
|
|||||||
DbgS(ANewOrigin));
|
DbgS(ANewOrigin));
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
FScrollOrigin := ANewOrigin;
|
if FMulX = 0 then FScrollOrigin.X := 0
|
||||||
|
else
|
||||||
|
FScrollOrigin.X := ANewOrigin.X / FMulX;
|
||||||
|
if FMulY = 0 then FScrollOrigin.Y := 0
|
||||||
|
else
|
||||||
|
FScrollOrigin.Y := ANewOrigin.Y / FMulY;
|
||||||
|
|
||||||
// send vertical scroll
|
// send vertical scroll
|
||||||
FillChar(ScrollMsg, SizeOf(TLMScroll), 0);
|
FillChar(ScrollMsg, SizeOf(TLMScroll), 0);
|
||||||
with ScrollMsg do
|
with ScrollMsg do
|
||||||
begin
|
begin
|
||||||
Msg := LM_VSCROLL;
|
Msg := LM_VSCROLL;
|
||||||
Pos := ANewOrigin.Y;
|
Pos := Round(FScrollOrigin.Y);
|
||||||
ScrollCode := SB_THUMBPOSITION;
|
ScrollCode := SB_THUMBPOSITION;
|
||||||
end;
|
end;
|
||||||
DeliverMessage(LCLObject, ScrollMsg);
|
DeliverMessage(LCLObject, ScrollMsg);
|
||||||
@ -538,7 +553,7 @@ begin
|
|||||||
with ScrollMsg do
|
with ScrollMsg do
|
||||||
begin
|
begin
|
||||||
Msg := LM_HSCROLL;
|
Msg := LM_HSCROLL;
|
||||||
Pos := ANewOrigin.X;
|
Pos := Round(FScrollOrigin.X);
|
||||||
ScrollCode := SB_THUMBPOSITION;
|
ScrollCode := SB_THUMBPOSITION;
|
||||||
end;
|
end;
|
||||||
DeliverMessage(LCLObject, ScrollMsg);
|
DeliverMessage(LCLObject, ScrollMsg);
|
||||||
@ -590,9 +605,9 @@ begin
|
|||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
if SBStyle = SB_HORZ then
|
if SBStyle = SB_HORZ then
|
||||||
Result := FScrollOrigin.X;
|
Result := Round(FScrollOrigin.X);
|
||||||
if SBStyle = SB_VERT then
|
if SBStyle = SB_VERT then
|
||||||
Result := FScrollOrigin.Y;
|
Result := Round(FScrollOrigin.Y);
|
||||||
|
|
||||||
if (SIF_RANGE and ScrollInfo.fMask) > 0 then
|
if (SIF_RANGE and ScrollInfo.fMask) > 0 then
|
||||||
begin
|
begin
|
||||||
@ -665,9 +680,9 @@ begin
|
|||||||
if (SIF_POS and ScrollInfo.fMask) > 0 then
|
if (SIF_POS and ScrollInfo.fMask) > 0 then
|
||||||
begin
|
begin
|
||||||
if SBStyle = SB_HORZ then
|
if SBStyle = SB_HORZ then
|
||||||
ScrollInfo.nPos := FScrollOrigin.X;
|
ScrollInfo.nPos := Round(FScrollOrigin.X);
|
||||||
if SBStyle = SB_VERT then
|
if SBStyle = SB_VERT then
|
||||||
ScrollInfo.nPos := FScrollOrigin.Y;
|
ScrollInfo.nPos := Round(FScrollOrigin.Y);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if (SIF_PAGE and ScrollInfo.fMask) > 0 then
|
if (SIF_PAGE and ScrollInfo.fMask) > 0 then
|
||||||
|
@ -350,9 +350,9 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
if FocusPart <> kControlFocusNoPart then
|
if FocusPart <> kControlFocusNoPart then
|
||||||
LCLSendSetFocusMsg(AWidget.LCLObject)
|
AWidget.FocusSet
|
||||||
else
|
else
|
||||||
LCLSendKillFocusMsg(AWidget.LCLObject);
|
AWidget.FocusKilled;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{------------------------------------------------------------------------------
|
{------------------------------------------------------------------------------
|
||||||
|
@ -78,8 +78,10 @@ const
|
|||||||
DEFAULT_CFSTRING_ENCODING = kCFStringEncodingUTF8;
|
DEFAULT_CFSTRING_ENCODING = kCFStringEncodingUTF8;
|
||||||
|
|
||||||
procedure CreateCFString(const S: String; out AString: CFStringRef);
|
procedure CreateCFString(const S: String; out AString: CFStringRef);
|
||||||
|
procedure CreateCFString(const Data: CFDataRef; Encoding: CFStringEncoding; out AString: CFStringRef);
|
||||||
procedure FreeCFString(var AString: CFStringRef);
|
procedure FreeCFString(var AString: CFStringRef);
|
||||||
function CFStringToStr(AString: CFStringRef): String;
|
function CFStringToStr(AString: CFStringRef; Encoding: CFStringEncoding = DEFAULT_CFSTRING_ENCODING): String;
|
||||||
|
function CFStringToData(AString: CFStringRef; Encoding: CFStringEncoding = DEFAULT_CFSTRING_ENCODING): CFDataRef;
|
||||||
|
|
||||||
function RoundFixed(const F: Fixed): Integer;
|
function RoundFixed(const F: Fixed): Integer;
|
||||||
|
|
||||||
@ -104,6 +106,8 @@ function HIRectToCarbonRect(const ARect: HIRect): FPCMacOSAll.Rect;
|
|||||||
function PointToHIPoint(const APoint: TPoint): HIPoint;
|
function PointToHIPoint(const APoint: TPoint): HIPoint;
|
||||||
function PointToHISize(const APoint: TPoint): HISize;
|
function PointToHISize(const APoint: TPoint): HISize;
|
||||||
function HIPointToPoint(const APoint: HIPoint): TPoint;
|
function HIPointToPoint(const APoint: HIPoint): TPoint;
|
||||||
|
function GetHIPoint(X, Y: Single): HIPoint;
|
||||||
|
function GetHISize(X, Y: Single): HISize;
|
||||||
|
|
||||||
function ColorToRGBColor(const AColor: TColor): RGBColor;
|
function ColorToRGBColor(const AColor: TColor): RGBColor;
|
||||||
function RGBColorToColor(const AColor: RGBColor): TColor;
|
function RGBColorToColor(const AColor: RGBColor): TColor;
|
||||||
@ -111,6 +115,8 @@ function CreateCGColor(const AColor: TColor): CGColorRef;
|
|||||||
|
|
||||||
function DbgS(const ARect: FPCMacOSAll.Rect): string; overload;
|
function DbgS(const ARect: FPCMacOSAll.Rect): string; overload;
|
||||||
function DbgS(const AColor: FPCMacOSAll.RGBColor): string; overload;
|
function DbgS(const AColor: FPCMacOSAll.RGBColor): string; overload;
|
||||||
|
function DbgS(const APoint: HIPoint): string; overload;
|
||||||
|
function DbgS(const ASize: HISize): string; overload;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
@ -493,13 +499,30 @@ end;
|
|||||||
Params: S - UTF-8 string
|
Params: S - UTF-8 string
|
||||||
AString - Core Foundation string ref
|
AString - Core Foundation string ref
|
||||||
|
|
||||||
Creates new Core Foundation string form specified string
|
Creates new Core Foundation string from the specified string
|
||||||
------------------------------------------------------------------------------}
|
------------------------------------------------------------------------------}
|
||||||
procedure CreateCFString(const S: String; out AString: CFStringRef);
|
procedure CreateCFString(const S: String; out AString: CFStringRef);
|
||||||
begin
|
begin
|
||||||
AString := CFStringCreateWithCString(nil, Pointer(PChar(S)), DEFAULT_CFSTRING_ENCODING);
|
AString := CFStringCreateWithCString(nil, Pointer(PChar(S)), DEFAULT_CFSTRING_ENCODING);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{------------------------------------------------------------------------------
|
||||||
|
Name: CreateCFString
|
||||||
|
Params: Data - CFDataRef
|
||||||
|
Encoding - Data encoding format
|
||||||
|
AString - Core Foundation string ref
|
||||||
|
|
||||||
|
Creates new Core Foundation string from the specified data and format
|
||||||
|
------------------------------------------------------------------------------}
|
||||||
|
procedure CreateCFString(const Data: CFDataRef; Encoding: CFStringEncoding; out
|
||||||
|
AString: CFStringRef);
|
||||||
|
begin
|
||||||
|
AString := nil;
|
||||||
|
if Data = nil then Exit;
|
||||||
|
AString := CFStringCreateWithBytes(nil, CFDataGetBytePtr(Data),
|
||||||
|
CFDataGetLength(Data), Encoding, False);
|
||||||
|
end;
|
||||||
|
|
||||||
{------------------------------------------------------------------------------
|
{------------------------------------------------------------------------------
|
||||||
Name: FreeCFString
|
Name: FreeCFString
|
||||||
Params: AString - Core Foundation string ref to free
|
Params: AString - Core Foundation string ref to free
|
||||||
@ -514,12 +537,13 @@ end;
|
|||||||
|
|
||||||
{------------------------------------------------------------------------------
|
{------------------------------------------------------------------------------
|
||||||
Name: CFStringToStr
|
Name: CFStringToStr
|
||||||
Params: AString - Core Foundation string ref
|
Params: AString - Core Foundation string ref
|
||||||
|
Encoding - Result data encoding format
|
||||||
Returns: UTF-8 string
|
Returns: UTF-8 string
|
||||||
|
|
||||||
Converts Core Foundation string to string
|
Converts Core Foundation string to string
|
||||||
------------------------------------------------------------------------------}
|
------------------------------------------------------------------------------}
|
||||||
function CFStringToStr(AString: CFStringRef): String;
|
function CFStringToStr(AString: CFStringRef; Encoding: CFStringEncoding): String;
|
||||||
var
|
var
|
||||||
Str: Pointer;
|
Str: Pointer;
|
||||||
StrSize: CFIndex;
|
StrSize: CFIndex;
|
||||||
@ -532,7 +556,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
// Try the quick way first
|
// Try the quick way first
|
||||||
Str := CFStringGetCStringPtr(AString, DEFAULT_CFSTRING_ENCODING);
|
Str := CFStringGetCStringPtr(AString, Encoding);
|
||||||
if Str <> nil then
|
if Str <> nil then
|
||||||
Result := PChar(Str)
|
Result := PChar(Str)
|
||||||
else
|
else
|
||||||
@ -541,16 +565,35 @@ begin
|
|||||||
StrRange.location := 0;
|
StrRange.location := 0;
|
||||||
StrRange.length := CFStringGetLength(AString);
|
StrRange.length := CFStringGetLength(AString);
|
||||||
|
|
||||||
CFStringGetBytes(AString, StrRange, DEFAULT_CFSTRING_ENCODING,
|
CFStringGetBytes(AString, StrRange, Encoding,
|
||||||
0, False, nil, 0, StrSize);
|
Ord('?'), False, nil, 0, StrSize);
|
||||||
SetLength(Result, StrSize);
|
SetLength(Result, StrSize);
|
||||||
|
|
||||||
if StrSize > 0 then
|
if StrSize > 0 then
|
||||||
CFStringGetBytes(AString, StrRange, DEFAULT_CFSTRING_ENCODING,
|
CFStringGetBytes(AString, StrRange, Encoding,
|
||||||
0, False, @Result[1], StrSize, StrSize);
|
Ord('?'), False, @Result[1], StrSize, StrSize);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{------------------------------------------------------------------------------
|
||||||
|
Name: CFStringToData
|
||||||
|
Params: AString - Core Foundation string ref
|
||||||
|
Encoding - Result data encoding format
|
||||||
|
Returns: CFDataRef
|
||||||
|
|
||||||
|
Converts Core Foundation string to data
|
||||||
|
------------------------------------------------------------------------------}
|
||||||
|
function CFStringToData(AString: CFStringRef; Encoding: CFStringEncoding): CFDataRef;
|
||||||
|
var
|
||||||
|
S: String;
|
||||||
|
begin
|
||||||
|
Result := nil;
|
||||||
|
if AString = nil then Exit;
|
||||||
|
S := CFStringToStr(AString, Encoding);
|
||||||
|
|
||||||
|
Result := CFDataCreate(nil, @S[1], Length(S));
|
||||||
|
end;
|
||||||
|
|
||||||
{------------------------------------------------------------------------------
|
{------------------------------------------------------------------------------
|
||||||
Name: RoundFixed
|
Name: RoundFixed
|
||||||
Params: F - Fixed value
|
Params: F - Fixed value
|
||||||
@ -810,6 +853,28 @@ begin
|
|||||||
Result.Y := Trunc(APoint.Y);
|
Result.Y := Trunc(APoint.Y);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{------------------------------------------------------------------------------
|
||||||
|
Name: GetHIPoint
|
||||||
|
Params: X, Y
|
||||||
|
Returns: HIPoint
|
||||||
|
------------------------------------------------------------------------------}
|
||||||
|
function GetHIPoint(X, Y: Single): HIPoint;
|
||||||
|
begin
|
||||||
|
Result.X := X;
|
||||||
|
Result.Y := Y;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{------------------------------------------------------------------------------
|
||||||
|
Name: GetHISize
|
||||||
|
Params: X, Y
|
||||||
|
Returns: HISize
|
||||||
|
------------------------------------------------------------------------------}
|
||||||
|
function GetHISize(X, Y: Single): HISize;
|
||||||
|
begin
|
||||||
|
Result.width := X;
|
||||||
|
Result.height := Y;
|
||||||
|
end;
|
||||||
|
|
||||||
{------------------------------------------------------------------------------
|
{------------------------------------------------------------------------------
|
||||||
Name: ColorToRGBColor
|
Name: ColorToRGBColor
|
||||||
Params: AColor - Color
|
Params: AColor - Color
|
||||||
@ -875,6 +940,16 @@ begin
|
|||||||
' B: ' + IntToHex(AColor.Blue, 4);
|
' B: ' + IntToHex(AColor.Blue, 4);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function DbgS(const APoint: HIPoint): string;
|
||||||
|
begin
|
||||||
|
Result := 'X: ' + DbgS(APoint.X) + ' Y: ' + DbgS(APoint.Y);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function DbgS(const ASize: HISize): string;
|
||||||
|
begin
|
||||||
|
Result := 'W: ' + DbgS(ASize.width) + ' H: ' + DbgS(ASize.height);
|
||||||
|
end;
|
||||||
|
|
||||||
{------------------------------------------------------------------------------
|
{------------------------------------------------------------------------------
|
||||||
Name: CustomControlHandler
|
Name: CustomControlHandler
|
||||||
Handles custom control class methods
|
Handles custom control class methods
|
||||||
|
Loading…
Reference in New Issue
Block a user