mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-17 06:49:12 +02:00
Carbon: Support a WS_POPUP type floating window. Issue #21746, patch from David Jenkins and AlexeyT.
git-svn-id: trunk@54966 -
This commit is contained in:
parent
d88911aefa
commit
8bcb1a543e
@ -7499,7 +7499,7 @@ begin
|
|||||||
TWSWinControlClass(WidgetSetClass).ConstraintsChange(Self);
|
TWSWinControlClass(WidgetSetClass).ConstraintsChange(Self);
|
||||||
|
|
||||||
//WriteClientRect('A');
|
//WriteClientRect('A');
|
||||||
if Assigned(Parent) then
|
if Assigned(Parent) and (Params.Style and WS_POPUP = 0) then
|
||||||
AddControl
|
AddControl
|
||||||
else
|
else
|
||||||
if ParentWindow <> 0 then
|
if ParentWindow <> 0 then
|
||||||
|
@ -74,6 +74,7 @@ type
|
|||||||
function GetContent: ControlRef; virtual; abstract;
|
function GetContent: ControlRef; virtual; abstract;
|
||||||
procedure UpdateLCLClientRect; virtual;
|
procedure UpdateLCLClientRect; virtual;
|
||||||
public
|
public
|
||||||
|
FPopupWin: WindowRef;
|
||||||
FNeedFree: Boolean;
|
FNeedFree: Boolean;
|
||||||
procedure BeginEventProc;
|
procedure BeginEventProc;
|
||||||
procedure EndEventProc;
|
procedure EndEventProc;
|
||||||
|
@ -121,6 +121,7 @@ type
|
|||||||
|
|
||||||
TCarbonCustomControl = class(TCarbonControl)
|
TCarbonCustomControl = class(TCarbonControl)
|
||||||
private
|
private
|
||||||
|
FForceEmbedded: Boolean;
|
||||||
FScrollView: HIViewRef;
|
FScrollView: HIViewRef;
|
||||||
FScrollOrigin: HIPoint;
|
FScrollOrigin: HIPoint;
|
||||||
FScrollSize: TPoint;
|
FScrollSize: TPoint;
|
||||||
@ -763,9 +764,109 @@ end;
|
|||||||
Creates Carbon custom control
|
Creates Carbon custom control
|
||||||
------------------------------------------------------------------------------}
|
------------------------------------------------------------------------------}
|
||||||
procedure TCarbonCustomControl.CreateWidget(const AParams: TCreateParams);
|
procedure TCarbonCustomControl.CreateWidget(const AParams: TCreateParams);
|
||||||
|
procedure RegisterWindowEvents(AWindowRef: WindowRef);
|
||||||
|
var
|
||||||
|
MouseSpec: array [0..6] of EventTypeSpec;
|
||||||
|
TmpSpec: EventTypeSpec;
|
||||||
|
KeySpecs: array[0..3] of EventTypeSpec;
|
||||||
|
ActivateSpecs: array[0..1] of EventTypeSpec;
|
||||||
|
ShowWindowSpecs: array[0..2] of EventTypeSpec;
|
||||||
|
WinContent: HIViewRef;
|
||||||
|
begin
|
||||||
|
// Window Events
|
||||||
|
|
||||||
|
TmpSpec := MakeEventSpec(kEventClassWindow, kEventWindowClose);
|
||||||
|
InstallWindowEventHandler(AWindowRef,
|
||||||
|
RegisterEventHandler(@CarbonWindow_Close),
|
||||||
|
1, @TmpSpec, Pointer(Self), nil);
|
||||||
|
|
||||||
|
TmpSpec := MakeEventSpec(kEventClassWindow, kEventWindowClosed);
|
||||||
|
InstallWindowEventHandler(AWindowRef,
|
||||||
|
RegisterEventHandler(@CarbonCommon_Dispose),
|
||||||
|
1, @TmpSpec, Pointer(Self), nil);
|
||||||
|
|
||||||
|
MouseSpec[0].eventClass := kEventClassMouse;
|
||||||
|
MouseSpec[0].eventKind := kEventMouseDown;
|
||||||
|
MouseSpec[1].eventClass := kEventClassMouse;
|
||||||
|
MouseSpec[1].eventKind := kEventMouseUp;
|
||||||
|
MouseSpec[2].eventClass := kEventClassMouse;
|
||||||
|
MouseSpec[2].eventKind := kEventMouseMoved;
|
||||||
|
MouseSpec[3].eventClass := kEventClassMouse;
|
||||||
|
MouseSpec[3].eventKind := kEventMouseDragged;
|
||||||
|
MouseSpec[4].eventClass := kEventClassMouse;
|
||||||
|
MouseSpec[4].eventKind := kEventMouseEntered;
|
||||||
|
MouseSpec[5].eventClass := kEventClassMouse;
|
||||||
|
MouseSpec[5].eventKind := kEventMouseExited;
|
||||||
|
MouseSpec[6].eventClass := kEventClassMouse;
|
||||||
|
MouseSpec[6].eventKind := kEventMouseWheelMoved;
|
||||||
|
|
||||||
|
InstallWindowEventHandler(AWindowRef,
|
||||||
|
RegisterEventHandler(@CarbonWindow_MouseProc),
|
||||||
|
7, @MouseSpec[0], Pointer(Self), nil);
|
||||||
|
|
||||||
|
KeySpecs[0].eventClass := kEventClassKeyboard;
|
||||||
|
KeySpecs[0].eventKind := kEventRawKeyDown;
|
||||||
|
KeySpecs[1].eventClass := kEventClassKeyboard;
|
||||||
|
KeySpecs[1].eventKind := kEventRawKeyRepeat;
|
||||||
|
KeySpecs[2].eventClass := kEventClassKeyboard;
|
||||||
|
KeySpecs[2].eventKind := kEventRawKeyUp;
|
||||||
|
KeySpecs[3].eventClass := kEventClassKeyboard;
|
||||||
|
KeySpecs[3].eventKind := kEventRawKeyModifiersChanged;
|
||||||
|
|
||||||
|
InstallWindowEventHandler(AWindowRef,
|
||||||
|
RegisterEventHandler(@CarbonWindow_KeyboardProc),
|
||||||
|
4, @KeySpecs[0], Pointer(Self), nil);
|
||||||
|
|
||||||
|
ActivateSpecs[0].eventClass := kEventClassWindow;
|
||||||
|
ActivateSpecs[0].eventKind := kEventWindowActivated;
|
||||||
|
ActivateSpecs[1].eventClass := kEventClassWindow;
|
||||||
|
ActivateSpecs[1].eventKind := kEventWindowDeactivated;
|
||||||
|
|
||||||
|
InstallWindowEventHandler(AWindowRef,
|
||||||
|
RegisterEventHandler(@CarbonWindow_ActivateProc),
|
||||||
|
2, @ActivateSpecs[0], Pointer(Self), nil);
|
||||||
|
|
||||||
|
ShowWindowSpecs[0].eventClass := kEventClassWindow;
|
||||||
|
ShowWindowSpecs[0].eventKind := kEventWindowCollapsed;
|
||||||
|
ShowWindowSpecs[1].eventClass := kEventClassWindow;
|
||||||
|
ShowWindowSpecs[1].eventKind := kEventWindowExpanded;
|
||||||
|
ShowWindowSpecs[2].eventClass := kEventClassWindow;
|
||||||
|
ShowWindowSpecs[2].eventKind := kEventWindowZoomed;
|
||||||
|
|
||||||
|
InstallWindowEventHandler(AWindowRef,
|
||||||
|
RegisterEventHandler(@CarbonWindow_ShowWindow),
|
||||||
|
3, @ShowWindowSpecs[0], Pointer(Self), nil);
|
||||||
|
|
||||||
|
TmpSpec := MakeEventSpec(kEventClassWindow, kEventWindowBoundsChanged);
|
||||||
|
InstallWindowEventHandler(AWindowRef,
|
||||||
|
RegisterEventHandler(@CarbonCommon_BoundsChanged),
|
||||||
|
1, @TmpSpec, Pointer(Self), nil);
|
||||||
|
|
||||||
|
// cursor change
|
||||||
|
TmpSpec := MakeEventSpec(kEventClassWindow, kEventWindowCursorChange);
|
||||||
|
InstallWindowEventHandler(AWindowRef,
|
||||||
|
RegisterEventHandler(@CarbonCommon_CursorChange),
|
||||||
|
1, @TmpSpec, Pointer(Self), nil);
|
||||||
|
|
||||||
|
// user messages
|
||||||
|
TmpSpec := MakeEventSpec(LCLCarbonEventClass, LCLCarbonEventKindUser);
|
||||||
|
InstallWindowEventHandler(AWindowRef,
|
||||||
|
RegisterEventHandler(@CarbonCommon_User),
|
||||||
|
1, @TmpSpec, Pointer(Self), nil);
|
||||||
|
|
||||||
|
// paint content message
|
||||||
|
if (HIViewFindByID( HIViewGetRoot(AWindowRef), kHIViewWindowContentID, WinContent) = noErr) then
|
||||||
|
begin
|
||||||
|
TmpSpec := MakeEventSpec(kEventClassControl, kEventControlDraw);
|
||||||
|
InstallControlEventHandler(WinContent,
|
||||||
|
RegisterEventHandler(@CarbonWindow_ContentDraw),
|
||||||
|
1, @TmpSpec, Pointer(Self), nil);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
var
|
var
|
||||||
TmpSpec: EventTypeSpec;
|
TmpSpec: EventTypeSpec;
|
||||||
AStyle: TControlStyle;
|
AStyle: TControlStyle;
|
||||||
|
ContentViewRef: HIViewRef;
|
||||||
begin
|
begin
|
||||||
AStyle := LCLObject.ControlStyle;
|
AStyle := LCLObject.ControlStyle;
|
||||||
|
|
||||||
@ -781,6 +882,11 @@ begin
|
|||||||
RegisterEventHandler(@CarbonScrollable_GetInfo),
|
RegisterEventHandler(@CarbonScrollable_GetInfo),
|
||||||
1, @TmpSpec, Pointer(Self), nil);
|
1, @TmpSpec, Pointer(Self), nil);
|
||||||
|
|
||||||
|
FForceEmbedded := True;
|
||||||
|
if (AParams.Style and WS_POPUP <> 0) and
|
||||||
|
(AParams.Style and (WS_VSCROLL or WS_HSCROLL) = 0) then
|
||||||
|
FForceEmbedded := False;
|
||||||
|
|
||||||
FScrollView := EmbedInScrollView(AParams);
|
FScrollView := EmbedInScrollView(AParams);
|
||||||
FScrollSize := Classes.Point(0, 0);
|
FScrollSize := Classes.Point(0, 0);
|
||||||
FScrollMin := Classes.Point(0, 0);
|
FScrollMin := Classes.Point(0, 0);
|
||||||
@ -789,6 +895,17 @@ begin
|
|||||||
FMulX := 1;
|
FMulX := 1;
|
||||||
FMulY := 1;
|
FMulY := 1;
|
||||||
|
|
||||||
|
if AParams.Style and WS_POPUP <> 0 then begin
|
||||||
|
CreateNewWindow(kFloatingWindowClass,
|
||||||
|
kWindowOpaqueForEventsAttribute or kWindowNoTitleBarAttribute or kWindowCompositingAttribute or kWindowStandardHandlerAttribute,
|
||||||
|
GetCarbonRect(0, 0, 0, 0),
|
||||||
|
FPopupWin);
|
||||||
|
RegisterWindowEvents(FPopupWin);
|
||||||
|
HIViewFindByID(HIViewGetRoot(FPopupWin), kHIViewWindowContentID, ContentViewRef);
|
||||||
|
OSError(HIViewAddSubview(ContentViewRef, FScrollView), Self, 'AddToWidget',
|
||||||
|
SViewAddView);
|
||||||
|
end
|
||||||
|
else
|
||||||
if LCLObject.ClassNameIs('TSynEdit') then
|
if LCLObject.ClassNameIs('TSynEdit') then
|
||||||
FTextFractional := False
|
FTextFractional := False
|
||||||
else
|
else
|
||||||
@ -828,7 +945,7 @@ end;
|
|||||||
|
|
||||||
function TCarbonCustomControl.GetForceEmbedInScrollView:Boolean;
|
function TCarbonCustomControl.GetForceEmbedInScrollView:Boolean;
|
||||||
begin
|
begin
|
||||||
Result:=True;
|
Result := FForceEmbedded;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{------------------------------------------------------------------------------
|
{------------------------------------------------------------------------------
|
||||||
|
@ -1189,6 +1189,10 @@ begin
|
|||||||
GetClientRect(before{%H-});
|
GetClientRect(before{%H-});
|
||||||
OSError(SendEventToEventTarget(Event, GetControlEventTarget(FScrollView)),
|
OSError(SendEventToEventTarget(Event, GetControlEventTarget(FScrollView)),
|
||||||
Self, SName, 'SendEventToEventTarget');
|
Self, SName, 'SendEventToEventTarget');
|
||||||
|
|
||||||
|
if Assigned(FPopupWin) then
|
||||||
|
InvalidPaint:=True; // Needed to get scrollbars updated
|
||||||
|
|
||||||
GetClientRect(after{%H-});
|
GetClientRect(after{%H-});
|
||||||
if not CompareRect(@before, @after) then
|
if not CompareRect(@before, @after) then
|
||||||
UpdateLCLClientRect;
|
UpdateLCLClientRect;
|
||||||
@ -1372,6 +1376,9 @@ begin
|
|||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
if Assigned(FPopupWin) then
|
||||||
|
GetWindowBounds(FPopupWin, kWindowContentRgn, BoundsRect);
|
||||||
|
|
||||||
ARect := SortRect(CarbonRectToRect(BoundsRect));
|
ARect := SortRect(CarbonRectToRect(BoundsRect));
|
||||||
Result := True;
|
Result := True;
|
||||||
end;
|
end;
|
||||||
@ -1432,12 +1439,24 @@ end;
|
|||||||
function TCarbonControl.SetBounds(const ARect: TRect): Boolean;
|
function TCarbonControl.SetBounds(const ARect: TRect): Boolean;
|
||||||
var
|
var
|
||||||
B :CGRect;
|
B :CGRect;
|
||||||
|
T: TRect;
|
||||||
begin
|
begin
|
||||||
Result := False;
|
Result := False;
|
||||||
|
|
||||||
if (IsDrawEvent > 0) then HIViewGetBounds(Frames[0], B{%H-});
|
if (IsDrawEvent > 0) then
|
||||||
|
if Assigned(FPopupWin) then
|
||||||
|
HIWindowGetBounds(FPopupWin, kWindowContentRgn, kHICoordSpaceWindow, B)
|
||||||
|
else
|
||||||
|
HIViewGetBounds(Frames[0], B{%H-});
|
||||||
|
|
||||||
if OSError(HIViewSetFrame(Frames[0], RectToCGRect(ARect)),
|
T := ARect;
|
||||||
|
if Assigned(FPopupWin) then
|
||||||
|
begin
|
||||||
|
SetWindowBounds(FPopupWin, kWindowContentRgn, GetCarbonRect(ARect));
|
||||||
|
T := Classes.Rect(0, 0, ARect.Right - ARect.Left, ARect.Bottom - ARect.Top);
|
||||||
|
end;
|
||||||
|
|
||||||
|
if OSError(HIViewSetFrame(Frames[0], RectToCGRect(T)),
|
||||||
Self, SSetBounds, SViewFrame) then Exit;
|
Self, SSetBounds, SViewFrame) then Exit;
|
||||||
// ensure bounds are send back to LCL once after creation
|
// ensure bounds are send back to LCL once after creation
|
||||||
BoundsChanged;
|
BoundsChanged;
|
||||||
@ -1588,6 +1607,9 @@ begin
|
|||||||
OSError(HIViewSetVisible(Frames[I], AVisible or (csDesigning in LCLobject.ComponentState)),
|
OSError(HIViewSetVisible(Frames[I], AVisible or (csDesigning in LCLobject.ComponentState)),
|
||||||
Self, 'ShowHide', SViewVisible);
|
Self, 'ShowHide', SViewVisible);
|
||||||
|
|
||||||
|
if Assigned(FPopupWin) then
|
||||||
|
MacOSAll.ShowHide(FPopupWin, AVisible);
|
||||||
|
|
||||||
if (IsDrawEvent > 0) and (AVisible <> v) and (AVisible or (csDesigning in LCLobject.ComponentState)) and (GetFrameCount>0) then
|
if (IsDrawEvent > 0) and (AVisible <> v) and (AVisible or (csDesigning in LCLobject.ComponentState)) and (GetFrameCount>0) then
|
||||||
InvalidPaint := true;
|
InvalidPaint := true;
|
||||||
end;
|
end;
|
||||||
@ -1678,6 +1700,9 @@ var
|
|||||||
begin
|
begin
|
||||||
Window := LCLObject.GetTopParent;
|
Window := LCLObject.GetTopParent;
|
||||||
|
|
||||||
|
if Assigned(FPopupWin) then
|
||||||
|
Result := FPopupWin
|
||||||
|
else
|
||||||
if (Window is TWinControl) and (Window.Parent = nil) and (TWinControl(Window).ParentWindow <> 0) then
|
if (Window is TWinControl) and (Window.Parent = nil) and (TWinControl(Window).ParentWindow <> 0) then
|
||||||
Result := TCarbonControl(TWinControl(Window).ParentWindow).GetTopParentWindow
|
Result := TCarbonControl(TWinControl(Window).ParentWindow).GetTopParentWindow
|
||||||
else
|
else
|
||||||
|
@ -915,6 +915,13 @@ begin
|
|||||||
Result := EventNotHandledErr;
|
Result := EventNotHandledErr;
|
||||||
|
|
||||||
Control := nil;
|
Control := nil;
|
||||||
|
if Assigned(AWidget.FPopupWin) then
|
||||||
|
begin
|
||||||
|
if OSError(GetKeyboardFocus(AWidget.FPopupWin, Control), SName, SGetKeyboardFocus) then Exit;
|
||||||
|
Widget := AWidget;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
if OSError(GetKeyboardFocus( TCarbonWindow(AWidget).fWindowRef, Control), SName,
|
if OSError(GetKeyboardFocus( TCarbonWindow(AWidget).fWindowRef, Control), SName,
|
||||||
SGetKeyboardFocus) then Exit;
|
SGetKeyboardFocus) then Exit;
|
||||||
if Control = nil then Control := AWidget.Content;
|
if Control = nil then Control := AWidget.Content;
|
||||||
@ -930,6 +937,7 @@ begin
|
|||||||
Control := HIViewGetSuperview(Control);
|
Control := HIViewGetSuperview(Control);
|
||||||
end;
|
end;
|
||||||
if (Widget = nil) or (Control = AWidget.Content) then Widget := AWidget;
|
if (Widget = nil) or (Control = AWidget.Content) then Widget := AWidget;
|
||||||
|
end;
|
||||||
|
|
||||||
Widget.BeginEventProc;
|
Widget.BeginEventProc;
|
||||||
try
|
try
|
||||||
|
Loading…
Reference in New Issue
Block a user