mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-11-21 23:10:34 +01:00
Carbon intf:
- improved custom control focusing - fixed visibility in IDE designer - improved file dialog filtering using masks LCL masks: added TParseStringList for parsing mask lists git-svn-id: trunk@11944 -
This commit is contained in:
parent
61d494b039
commit
f488c6af5e
@ -468,7 +468,7 @@ begin
|
|||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
RegisterEvents;
|
RegisterEvents;
|
||||||
|
|
||||||
LCLObject.InvalidateClientRectCache(True);
|
LCLObject.InvalidateClientRectCache(True);
|
||||||
BoundsChanged;
|
BoundsChanged;
|
||||||
|
|
||||||
|
|||||||
@ -173,7 +173,6 @@ type
|
|||||||
FScrollOrigin: TPoint;
|
FScrollOrigin: TPoint;
|
||||||
FScrollSize: TPoint;
|
FScrollSize: TPoint;
|
||||||
FScrollPageSize: TPoint;
|
FScrollPageSize: TPoint;
|
||||||
FFocusPart: ControlPartCode;
|
|
||||||
protected
|
protected
|
||||||
procedure RegisterEvents; override;
|
procedure RegisterEvents; override;
|
||||||
procedure CreateWidget(const AParams: TCreateParams); override;
|
procedure CreateWidget(const AParams: TCreateParams); override;
|
||||||
@ -452,8 +451,6 @@ begin
|
|||||||
Widget := CreateCustomHIView(ParamsToHIRect(AParams));
|
Widget := CreateCustomHIView(ParamsToHIRect(AParams));
|
||||||
if Widget = nil then RaiseCreateWidgetError(LCLObject);
|
if Widget = nil then RaiseCreateWidgetError(LCLObject);
|
||||||
|
|
||||||
FFocusPart := kControlNoPart;
|
|
||||||
|
|
||||||
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);
|
||||||
|
|||||||
@ -40,6 +40,7 @@ function CarbonCommon_Draw(ANextHandler: EventHandlerCallRef;
|
|||||||
AWidget: TCarbonWidget): OSStatus; {$IFDEF darwin}mwpascal;{$ENDIF}
|
AWidget: TCarbonWidget): OSStatus; {$IFDEF darwin}mwpascal;{$ENDIF}
|
||||||
var
|
var
|
||||||
AStruct: PPaintStruct;
|
AStruct: PPaintStruct;
|
||||||
|
EraseMsg: TLMEraseBkgnd;
|
||||||
begin
|
begin
|
||||||
{$IFDEF VerbosePaint}
|
{$IFDEF VerbosePaint}
|
||||||
Debugln('CarbonCommon_Draw ', DbgSName(AWidget.LCLObject));
|
Debugln('CarbonCommon_Draw ', DbgSName(AWidget.LCLObject));
|
||||||
@ -54,9 +55,13 @@ begin
|
|||||||
SizeOf(CGContextRef), nil, @(AWidget.Context.CGContext)),
|
SizeOf(CGContextRef), nil, @(AWidget.Context.CGContext)),
|
||||||
'CarbonCommon_Draw', SGetEvent, 'kEventParamCGContextRef') then Exit;
|
'CarbonCommon_Draw', SGetEvent, 'kEventParamCGContextRef') then Exit;
|
||||||
|
|
||||||
|
// erase background
|
||||||
|
EraseMsg.Msg := LM_ERASEBKGND;
|
||||||
|
EraseMsg.DC := HDC(AWidget.Context);
|
||||||
|
DeliverMessage(AWidget.LCLObject, EraseMsg);
|
||||||
|
|
||||||
// let carbon draw/update
|
// let carbon draw/update
|
||||||
Result := CallNextEventHandler(ANextHandler, AEvent);
|
Result := CallNextEventHandler(ANextHandler, AEvent);
|
||||||
|
|
||||||
|
|
||||||
if (AWidget is TCarbonControl) and
|
if (AWidget is TCarbonControl) and
|
||||||
(cceDraw in (AWidget as TCarbonControl).GetValidEvents) then
|
(cceDraw in (AWidget as TCarbonControl).GetValidEvents) then
|
||||||
@ -304,14 +309,13 @@ function CarbonCommon_SetFocusPart(ANextHandler: EventHandlerCallRef;
|
|||||||
AEvent: EventRef;
|
AEvent: EventRef;
|
||||||
AWidget: TCarbonWidget): OSStatus; {$IFDEF darwin}mwpascal;{$ENDIF}
|
AWidget: TCarbonWidget): OSStatus; {$IFDEF darwin}mwpascal;{$ENDIF}
|
||||||
var
|
var
|
||||||
|
CurrentFocus,
|
||||||
FocusPart: ControlPartCode;
|
FocusPart: ControlPartCode;
|
||||||
const
|
const
|
||||||
SName = 'CarbonCommon_SetFocusPart';
|
SName = 'CarbonCommon_SetFocusPart';
|
||||||
begin
|
begin
|
||||||
if not (AWidget.LCLObject is TCustomControl) then
|
if not (AWidget is TCarbonCustomControl) then
|
||||||
Result := CallNextEventHandler(ANextHandler, AEvent)
|
Result := CallNextEventHandler(ANextHandler, AEvent);
|
||||||
else
|
|
||||||
Result := noErr;
|
|
||||||
|
|
||||||
if OSError(
|
if OSError(
|
||||||
GetEventParameter(AEvent, kEventParamControlPart, typeControlPartCode, nil,
|
GetEventParameter(AEvent, kEventParamControlPart, typeControlPartCode, nil,
|
||||||
@ -322,6 +326,28 @@ begin
|
|||||||
DebugLn('CarbonCommon_SetFocusPart: ', DbgSName(AWidget.LCLObject), ' ' +
|
DebugLn('CarbonCommon_SetFocusPart: ', DbgSName(AWidget.LCLObject), ' ' +
|
||||||
IntToStr(Integer(FocusPart)));
|
IntToStr(Integer(FocusPart)));
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
|
if AWidget is TCarbonCustomControl then
|
||||||
|
begin
|
||||||
|
OSError(HIViewGetFocusPart(AWidget.Content, CurrentFocus),
|
||||||
|
SName, 'HIViewGetFocusPart');
|
||||||
|
|
||||||
|
case FocusPart of
|
||||||
|
kControlFocusPrevPart,
|
||||||
|
kControlFocusNextPart:
|
||||||
|
if CurrentFocus = kControlNoPart then FocusPart := kControlEditTextPart
|
||||||
|
else FocusPart := kControlEditTextPart;
|
||||||
|
kControlEditTextPart:;
|
||||||
|
else
|
||||||
|
FocusPart := kControlNoPart;
|
||||||
|
end;
|
||||||
|
|
||||||
|
OSError(
|
||||||
|
SetEventParameter(AEvent, kEventParamControlPart, typeControlPartCode,
|
||||||
|
SizeOf(ControlPartCode), @FocusPart), SName, SSetEvent, SControlPart);
|
||||||
|
|
||||||
|
Result := noErr;
|
||||||
|
end;
|
||||||
|
|
||||||
if FocusPart <> kControlFocusNoPart then
|
if FocusPart <> kControlFocusNoPart then
|
||||||
LCLSendSetFocusMsg(AWidget.LCLObject)
|
LCLSendSetFocusMsg(AWidget.LCLObject)
|
||||||
|
|||||||
@ -853,7 +853,8 @@ var
|
|||||||
begin
|
begin
|
||||||
//DebugLn('TCarbonControl.ShowHide ' + DbgSName(LCLobject),' ', DbgS(AVisible));
|
//DebugLn('TCarbonControl.ShowHide ' + DbgSName(LCLobject),' ', DbgS(AVisible));
|
||||||
for I := 0 to GetFrameCount - 1 do
|
for I := 0 to GetFrameCount - 1 do
|
||||||
OSError(HIViewSetVisible(Frames[I], AVisible), Self, 'ShowHide', SViewVisible);
|
OSError(HIViewSetVisible(Frames[I], AVisible or (csDesigning in LCLobject.ComponentState)),
|
||||||
|
Self, 'ShowHide', SViewVisible);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{------------------------------------------------------------------------------
|
{------------------------------------------------------------------------------
|
||||||
|
|||||||
@ -978,7 +978,7 @@ begin
|
|||||||
|
|
||||||
SetBounds(Bounds(AParams.X, AParams.Y, AParams.Width, AParams.Height));
|
SetBounds(Bounds(AParams.X, AParams.Y, AParams.Width, AParams.Height));
|
||||||
SetText(AParams.Caption);
|
SetText(AParams.Caption);
|
||||||
DebugLn('TCarbonWindow.CreateWidget succeeds');
|
//DebugLn('TCarbonWindow.CreateWidget succeeds');
|
||||||
SetColor(LCLObject.Color);
|
SetColor(LCLObject.Color);
|
||||||
|
|
||||||
MinSize.width := LCLObject.Constraints.EffectiveMinWidth;
|
MinSize.width := LCLObject.Constraints.EffectiveMinWidth;
|
||||||
@ -1303,7 +1303,9 @@ end;
|
|||||||
------------------------------------------------------------------------------}
|
------------------------------------------------------------------------------}
|
||||||
procedure TCarbonWindow.ShowHide(AVisible: Boolean);
|
procedure TCarbonWindow.ShowHide(AVisible: Boolean);
|
||||||
begin
|
begin
|
||||||
if AVisible then
|
//DebugLn('TCarbonWindow.ShowHide ' + DbgSName(LCLobject),' ', DbgS(AVisible));
|
||||||
|
|
||||||
|
if AVisible or (csDesigning in LCLobject.ComponentState) then
|
||||||
FPCMacOSAll.ShowWindow(WindowRef(Widget))
|
FPCMacOSAll.ShowWindow(WindowRef(Widget))
|
||||||
else
|
else
|
||||||
FPCMacOSAll.HideWindow(WindowRef(Widget));
|
FPCMacOSAll.HideWindow(WindowRef(Widget));
|
||||||
|
|||||||
@ -33,7 +33,7 @@ uses
|
|||||||
// libs
|
// libs
|
||||||
FPCMacOSAll,
|
FPCMacOSAll,
|
||||||
// LCL
|
// LCL
|
||||||
SysUtils, Controls, Dialogs, LCLType, LCLProc,
|
Classes, SysUtils, Controls, Dialogs, LCLType, LCLProc, Masks,
|
||||||
// widgetset
|
// widgetset
|
||||||
WSLCLClasses, WSProc, WSDialogs,
|
WSLCLClasses, WSProc, WSDialogs,
|
||||||
// LCL Carbon
|
// LCL Carbon
|
||||||
@ -115,15 +115,17 @@ uses
|
|||||||
|
|
||||||
{ TCarbonWSFileDialog }
|
{ TCarbonWSFileDialog }
|
||||||
|
|
||||||
function FilterByExtCallback(var theItem: AEDesc; info: NavFileOrFolderInfoPtr;
|
var
|
||||||
|
FilterMask: TMaskList;
|
||||||
|
|
||||||
|
function FilterCallback(var theItem: AEDesc; info: NavFileOrFolderInfoPtr;
|
||||||
callbackUD: UnivPtr; filterMode: NavFilterModes): Boolean; stdcall;
|
callbackUD: UnivPtr; filterMode: NavFilterModes): Boolean; stdcall;
|
||||||
{Custom filter callback function. Pointer to this function is passed as
|
{Custom filter callback function. Pointer to this function is passed as
|
||||||
inFilterProc to NavCreateGetFileDialog and NavCreateChooseFolderDialog.
|
inFilterProc to NavCreateGetFileDialog and NavCreateChooseFolderDialog.
|
||||||
If theItem file should be highlighted in file dialog, return True;
|
If theItem file should be highlighted in file dialog, return True;
|
||||||
if it should be dimmed in file dialog, return False.
|
if it should be dimmed in file dialog, return False.
|
||||||
The callbackUD param contains file dialog object passed as inClientData
|
The callbackUD param contains file dialog object passed as inClientData
|
||||||
to NavCreateGetFileDialog and NavCreateChooseFolderDialog.
|
to NavCreateGetFileDialog and NavCreateChooseFolderDialog.}
|
||||||
Note: This function filters only by file extension, not by wildcard file spec.}
|
|
||||||
var
|
var
|
||||||
FileRef: FSRef;
|
FileRef: FSRef;
|
||||||
FileURL: CFURLRef;
|
FileURL: CFURLRef;
|
||||||
@ -161,11 +163,9 @@ begin
|
|||||||
FreeCFString(FileURL);
|
FreeCFString(FileURL);
|
||||||
FreeCFString(FileCFStr);
|
FreeCFString(FileCFStr);
|
||||||
|
|
||||||
// TODO: use mask for filtering
|
Result := (FilterMask = nil) or FilterMask.Matches(ExtractFilename(FilePath));
|
||||||
Result := Pos(LowerCase(ExtractFileExt(FilePath)),
|
//DebugLn('FilterCallback ' + DbgS(FilterMask) + ' ' + ExtractFilename(FilePath) + ' ' + DbgS(Result));
|
||||||
LowerCase(TFileDialog(callbackUD).Filter)) > 0;
|
end; {FilterCallback}
|
||||||
|
|
||||||
end; {FilterByExtCallback}
|
|
||||||
|
|
||||||
|
|
||||||
{------------------------------------------------------------------------------
|
{------------------------------------------------------------------------------
|
||||||
@ -195,6 +195,8 @@ var
|
|||||||
FileRef: FSRef;
|
FileRef: FSRef;
|
||||||
FileURL: CFURLRef;
|
FileURL: CFURLRef;
|
||||||
FileCFStr: CFStringRef;
|
FileCFStr: CFStringRef;
|
||||||
|
Filters: TParseStringList;
|
||||||
|
I: Integer;
|
||||||
begin
|
begin
|
||||||
{$IFDEF VerboseWSClass}
|
{$IFDEF VerboseWSClass}
|
||||||
DebugLn('TCarbonWSFileDialog.ShowModal for ' + ACommonDialog.Name);
|
DebugLn('TCarbonWSFileDialog.ShowModal for ' + ACommonDialog.Name);
|
||||||
@ -211,8 +213,20 @@ begin
|
|||||||
|
|
||||||
FileDialog.UserChoice := mrCancel; // Return this if user cancels or we need to exit
|
FileDialog.UserChoice := mrCancel; // Return this if user cancels or we need to exit
|
||||||
|
|
||||||
FilterUPP := NewNavObjectFilterUPP(NavObjectFilterProcPtr(@FilterByExtCallback));
|
FilterUPP := NewNavObjectFilterUPP(NavObjectFilterProcPtr(@FilterCallback));
|
||||||
|
|
||||||
|
Filters := TParseStringList.Create(FileDialog.Filter, '|');
|
||||||
|
try
|
||||||
|
if (FileDialog.FilterIndex >= 0) and
|
||||||
|
(FileDialog.FilterIndex * 2 + 1 < Filters.Count) then
|
||||||
|
begin
|
||||||
|
//DebugLn('Filter ' + Filters[FileDialog.FilterIndex * 2 + 1]);
|
||||||
|
FilterMask := TMaskList.Create(Filters[FileDialog.FilterIndex * 2 + 1]);
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
Filters.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
try
|
try
|
||||||
if FileDialog is TSaveDialog then
|
if FileDialog is TSaveDialog then
|
||||||
begin // Checking for TSaveDialog first since it's descendent of TOpenDialog
|
begin // Checking for TSaveDialog first since it's descendent of TOpenDialog
|
||||||
@ -315,6 +329,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
finally
|
finally
|
||||||
|
FreeAndNil(FilterMask);
|
||||||
DisposeNavObjectFilterUPP(FilterUPP);
|
DisposeNavObjectFilterUPP(FilterUPP);
|
||||||
FreeCFString(CreationOptions.windowTitle);
|
FreeCFString(CreationOptions.windowTitle);
|
||||||
FreeCFString(CreationOptions.saveFileName);
|
FreeCFString(CreationOptions.saveFileName);
|
||||||
|
|||||||
@ -58,6 +58,13 @@ type
|
|||||||
function Matches(const AFileName: String): Boolean;
|
function Matches(const AFileName: String): Boolean;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TParseStringList }
|
||||||
|
|
||||||
|
TParseStringList = class(TStringList)
|
||||||
|
public
|
||||||
|
constructor Create(const AText, ASeparators: String);
|
||||||
|
end;
|
||||||
|
|
||||||
{ TMaskList }
|
{ TMaskList }
|
||||||
|
|
||||||
TMaskList = class
|
TMaskList = class
|
||||||
@ -322,6 +329,27 @@ begin
|
|||||||
Result := MatchToEnd(0, 1);
|
Result := MatchToEnd(0, 1);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TParseStringList }
|
||||||
|
|
||||||
|
constructor TParseStringList.Create(const AText, ASeparators: String);
|
||||||
|
var
|
||||||
|
I, S: Integer;
|
||||||
|
begin
|
||||||
|
inherited Create;
|
||||||
|
|
||||||
|
S := 1;
|
||||||
|
for I := 1 to Length(AText) do
|
||||||
|
begin
|
||||||
|
if Pos(AText[I], ASeparators) > 0 then
|
||||||
|
begin
|
||||||
|
if I > S then Add(Copy(AText, S, I - S));
|
||||||
|
S := I + 1;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if Length(AText) > S then Add(Copy(AText, S, Length(AText) - S + 1));
|
||||||
|
end;
|
||||||
|
|
||||||
{ TMaskList }
|
{ TMaskList }
|
||||||
|
|
||||||
function TMaskList.GetItem(Index: Integer): TMask;
|
function TMaskList.GetItem(Index: Integer): TMask;
|
||||||
@ -336,16 +364,13 @@ end;
|
|||||||
|
|
||||||
constructor TMaskList.Create(const AValue: String; ASeparator: Char);
|
constructor TMaskList.Create(const AValue: String; ASeparator: Char);
|
||||||
var
|
var
|
||||||
S: TStringList;
|
S: TParseStringList;
|
||||||
I: Integer;
|
I: Integer;
|
||||||
begin
|
begin
|
||||||
FMasks := TObjectList.Create(True);
|
FMasks := TObjectList.Create(True);
|
||||||
|
|
||||||
S := TStringList.Create;
|
S := TParseStringList.Create(AValue, ASeparator + ' ');
|
||||||
try
|
try
|
||||||
S.Delimiter := ASeparator;
|
|
||||||
S.DelimitedText := AValue;
|
|
||||||
|
|
||||||
for I := 0 to S.Count - 1 do
|
for I := 0 to S.Count - 1 do
|
||||||
FMasks.Add(TMask.Create(S[I]));
|
FMasks.Add(TMask.Create(S[I]));
|
||||||
finally
|
finally
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user