mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-22 11:19:26 +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);
|
||||
|
||||
//WriteClientRect('A');
|
||||
if Assigned(Parent) then
|
||||
if Assigned(Parent) and (Params.Style and WS_POPUP = 0) then
|
||||
AddControl
|
||||
else
|
||||
if ParentWindow <> 0 then
|
||||
|
@ -74,6 +74,7 @@ type
|
||||
function GetContent: ControlRef; virtual; abstract;
|
||||
procedure UpdateLCLClientRect; virtual;
|
||||
public
|
||||
FPopupWin: WindowRef;
|
||||
FNeedFree: Boolean;
|
||||
procedure BeginEventProc;
|
||||
procedure EndEventProc;
|
||||
|
@ -121,6 +121,7 @@ type
|
||||
|
||||
TCarbonCustomControl = class(TCarbonControl)
|
||||
private
|
||||
FForceEmbedded: Boolean;
|
||||
FScrollView: HIViewRef;
|
||||
FScrollOrigin: HIPoint;
|
||||
FScrollSize: TPoint;
|
||||
@ -763,9 +764,109 @@ end;
|
||||
Creates Carbon custom control
|
||||
------------------------------------------------------------------------------}
|
||||
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
|
||||
TmpSpec: EventTypeSpec;
|
||||
AStyle: TControlStyle;
|
||||
ContentViewRef: HIViewRef;
|
||||
begin
|
||||
AStyle := LCLObject.ControlStyle;
|
||||
|
||||
@ -781,6 +882,11 @@ begin
|
||||
RegisterEventHandler(@CarbonScrollable_GetInfo),
|
||||
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);
|
||||
FScrollSize := Classes.Point(0, 0);
|
||||
FScrollMin := Classes.Point(0, 0);
|
||||
@ -788,7 +894,18 @@ begin
|
||||
FScrollOrigin := GetHIPoint(0, 0);
|
||||
FMulX := 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
|
||||
FTextFractional := False
|
||||
else
|
||||
@ -828,7 +945,7 @@ end;
|
||||
|
||||
function TCarbonCustomControl.GetForceEmbedInScrollView:Boolean;
|
||||
begin
|
||||
Result:=True;
|
||||
Result := FForceEmbedded;
|
||||
end;
|
||||
|
||||
{------------------------------------------------------------------------------
|
||||
|
@ -1189,6 +1189,10 @@ begin
|
||||
GetClientRect(before{%H-});
|
||||
OSError(SendEventToEventTarget(Event, GetControlEventTarget(FScrollView)),
|
||||
Self, SName, 'SendEventToEventTarget');
|
||||
|
||||
if Assigned(FPopupWin) then
|
||||
InvalidPaint:=True; // Needed to get scrollbars updated
|
||||
|
||||
GetClientRect(after{%H-});
|
||||
if not CompareRect(@before, @after) then
|
||||
UpdateLCLClientRect;
|
||||
@ -1372,6 +1376,9 @@ begin
|
||||
Exit;
|
||||
end;
|
||||
|
||||
if Assigned(FPopupWin) then
|
||||
GetWindowBounds(FPopupWin, kWindowContentRgn, BoundsRect);
|
||||
|
||||
ARect := SortRect(CarbonRectToRect(BoundsRect));
|
||||
Result := True;
|
||||
end;
|
||||
@ -1432,12 +1439,24 @@ end;
|
||||
function TCarbonControl.SetBounds(const ARect: TRect): Boolean;
|
||||
var
|
||||
B :CGRect;
|
||||
T: TRect;
|
||||
begin
|
||||
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;
|
||||
// ensure bounds are send back to LCL once after creation
|
||||
BoundsChanged;
|
||||
@ -1588,6 +1607,9 @@ begin
|
||||
OSError(HIViewSetVisible(Frames[I], AVisible or (csDesigning in LCLobject.ComponentState)),
|
||||
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
|
||||
InvalidPaint := true;
|
||||
end;
|
||||
@ -1678,6 +1700,9 @@ var
|
||||
begin
|
||||
Window := LCLObject.GetTopParent;
|
||||
|
||||
if Assigned(FPopupWin) then
|
||||
Result := FPopupWin
|
||||
else
|
||||
if (Window is TWinControl) and (Window.Parent = nil) and (TWinControl(Window).ParentWindow <> 0) then
|
||||
Result := TCarbonControl(TWinControl(Window).ParentWindow).GetTopParentWindow
|
||||
else
|
||||
|
@ -915,21 +915,29 @@ begin
|
||||
Result := EventNotHandledErr;
|
||||
|
||||
Control := nil;
|
||||
if OSError(GetKeyboardFocus( TCarbonWindow(AWidget).fWindowRef, Control), SName,
|
||||
SGetKeyboardFocus) then Exit;
|
||||
if Control = nil then Control := AWidget.Content;
|
||||
|
||||
// if a control other than root is found, send the message
|
||||
// to the control instead of the window
|
||||
// if a lower control without widget is found, use its parent
|
||||
Widget := nil;
|
||||
while Control <> AWidget.Content do
|
||||
if Assigned(AWidget.FPopupWin) then
|
||||
begin
|
||||
Widget := GetCarbonControl(Pointer(Control));
|
||||
if Widget <> nil then Break;
|
||||
Control := HIViewGetSuperview(Control);
|
||||
end;
|
||||
if (Widget = nil) or (Control = AWidget.Content) then Widget := AWidget;
|
||||
if OSError(GetKeyboardFocus(AWidget.FPopupWin, Control), SName, SGetKeyboardFocus) then Exit;
|
||||
Widget := AWidget;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if OSError(GetKeyboardFocus( TCarbonWindow(AWidget).fWindowRef, Control), SName,
|
||||
SGetKeyboardFocus) then Exit;
|
||||
if Control = nil then Control := AWidget.Content;
|
||||
|
||||
// if a control other than root is found, send the message
|
||||
// to the control instead of the window
|
||||
// if a lower control without widget is found, use its parent
|
||||
Widget := nil;
|
||||
while Control <> AWidget.Content do
|
||||
begin
|
||||
Widget := GetCarbonControl(Pointer(Control));
|
||||
if Widget <> nil then Break;
|
||||
Control := HIViewGetSuperview(Control);
|
||||
end;
|
||||
if (Widget = nil) or (Control = AWidget.Content) then Widget := AWidget;
|
||||
end;
|
||||
|
||||
Widget.BeginEventProc;
|
||||
try
|
||||
|
Loading…
Reference in New Issue
Block a user