mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-12 04:16:06 +02:00
cocoa: rework TCocoaScrollBar implementation - removed direct binding to LCL control. Initial implementation of ScrollWindowsEx. added scrolling messages for TCocoaManualScrollView
git-svn-id: trunk@56944 -
This commit is contained in:
parent
edee7ec8ef
commit
98712b414a
@ -188,6 +188,8 @@ type
|
|||||||
var
|
var
|
||||||
CocoaWidgetSet: TCocoaWidgetSet;
|
CocoaWidgetSet: TCocoaWidgetSet;
|
||||||
|
|
||||||
|
function CocoaScrollBarSetScrollInfo(bar: TCocoaScrollBar; const ScrollInfo: TScrollInfo): Integer;
|
||||||
|
function CocoaScrollBarGetScrollInfo(bar: TCocoaScrollBar; var ScrollInfo: TScrollInfo): Boolean;
|
||||||
procedure NSScrollerGetScrollInfo(docSz, pageSz: CGFloat; rl: NSSCroller; Var ScrollInfo: TScrollInfo);
|
procedure NSScrollerGetScrollInfo(docSz, pageSz: CGFloat; rl: NSSCroller; Var ScrollInfo: TScrollInfo);
|
||||||
procedure NSScrollViewGetScrollInfo(sc: NSScrollView; BarFlag: Integer; Var ScrollInfo: TScrollInfo);
|
procedure NSScrollViewGetScrollInfo(sc: NSScrollView; BarFlag: Integer; Var ScrollInfo: TScrollInfo);
|
||||||
procedure NSScrollerSetScrollInfo(docSz, pageSz: CGFloat; rl: NSSCroller; const ScrollInfo: TScrollInfo);
|
procedure NSScrollerSetScrollInfo(docSz, pageSz: CGFloat; rl: NSSCroller; const ScrollInfo: TScrollInfo);
|
||||||
@ -204,6 +206,66 @@ uses
|
|||||||
CocoaCaret,
|
CocoaCaret,
|
||||||
CocoaThemes;
|
CocoaThemes;
|
||||||
|
|
||||||
|
function CocoaScrollBarSetScrollInfo(bar: TCocoaScrollBar; const ScrollInfo: TScrollInfo): Integer;
|
||||||
|
var
|
||||||
|
pg : Integer;
|
||||||
|
mn : Integer;
|
||||||
|
mx : Integer;
|
||||||
|
dl : Integer;
|
||||||
|
pos : CGFloat;
|
||||||
|
begin
|
||||||
|
if not Assigned(bar) then
|
||||||
|
begin
|
||||||
|
Result := 0;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if ScrollInfo.fMask and SIF_PAGE>0 then
|
||||||
|
begin
|
||||||
|
pg:=ScrollInfo.nPage;
|
||||||
|
if pg=0 then pg:=1; // zero page is not allowed?
|
||||||
|
end
|
||||||
|
else pg:=bar.pageInt;
|
||||||
|
|
||||||
|
if ScrollInfo.fMask and SIF_RANGE>0 then
|
||||||
|
begin
|
||||||
|
mn:=ScrollInfo.nMin;
|
||||||
|
mx:=ScrollInfo.nMax;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
mn:=bar.minInt;
|
||||||
|
mx:=bar.maxInt;
|
||||||
|
end;
|
||||||
|
|
||||||
|
dl:=mx-mn;
|
||||||
|
if ScrollInfo.fMask and SIF_POS > 0 then
|
||||||
|
begin
|
||||||
|
if dl<>0 then
|
||||||
|
bar.setDoubleValue( ScrollInfo.nPos / dl )
|
||||||
|
else
|
||||||
|
bar.setDoubleValue( 0 )
|
||||||
|
end;
|
||||||
|
|
||||||
|
bar.setEnabled(dl<>0);
|
||||||
|
|
||||||
|
// if changed page or range, the knob changes
|
||||||
|
if ScrollInfo.fMask and (SIF_RANGE or SIF_PAGE)>0 then
|
||||||
|
begin
|
||||||
|
if dl<>0 then
|
||||||
|
//bar.setKnobProportion(pg/dl)
|
||||||
|
bar.setKnobProportion(0.5)
|
||||||
|
else
|
||||||
|
bar.setKnobProportion(1);
|
||||||
|
bar.pageInt:=pg;
|
||||||
|
bar.minInt:=mn;
|
||||||
|
bar.maxInt:=mx;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function CocoaScrollBarGetScrollInfo(bar: TCocoaScrollBar; var ScrollInfo: TScrollInfo): Boolean;
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
procedure NSScrollerGetScrollInfo(docSz, pageSz: CGFloat; rl: NSSCroller; Var ScrollInfo: TScrollInfo);
|
procedure NSScrollerGetScrollInfo(docSz, pageSz: CGFloat; rl: NSSCroller; Var ScrollInfo: TScrollInfo);
|
||||||
begin
|
begin
|
||||||
|
@ -65,6 +65,7 @@ type
|
|||||||
procedure DidResignKeyNotification;
|
procedure DidResignKeyNotification;
|
||||||
procedure SendOnChange;
|
procedure SendOnChange;
|
||||||
procedure SendOnTextChanged;
|
procedure SendOnTextChanged;
|
||||||
|
procedure scroll(isVert: Boolean; Pos: Integer);
|
||||||
// non event methods
|
// non event methods
|
||||||
function DeliverMessage(Msg: Cardinal; WParam: WParam; LParam: LParam): LResult;
|
function DeliverMessage(Msg: Cardinal; WParam: WParam; LParam: LParam): LResult;
|
||||||
function GetPropStorage: TStringList;
|
function GetPropStorage: TStringList;
|
||||||
@ -507,6 +508,10 @@ type
|
|||||||
procedure setHasHorizontalScroller(doshow: Boolean); message 'setHasHorizontalScroller:';
|
procedure setHasHorizontalScroller(doshow: Boolean); message 'setHasHorizontalScroller:';
|
||||||
function hasVerticalScroller: Boolean; message 'hasVerticalScroller';
|
function hasVerticalScroller: Boolean; message 'hasVerticalScroller';
|
||||||
function hasHorizontalScroller: Boolean; message 'hasHorizontalScroller';
|
function hasHorizontalScroller: Boolean; message 'hasHorizontalScroller';
|
||||||
|
|
||||||
|
function horizontalScroller: NSScroller; message 'horizontalScroller';
|
||||||
|
function verticalScroller: NSScroller; message 'verticalScroller';
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TStatusItemData = record
|
TStatusItemData = record
|
||||||
@ -605,7 +610,10 @@ type
|
|||||||
TCocoaScrollBar = objcclass(NSScroller)
|
TCocoaScrollBar = objcclass(NSScroller)
|
||||||
public
|
public
|
||||||
callback: ICommonCallback;
|
callback: ICommonCallback;
|
||||||
LCLScrollBar: TCustomScrollBar;
|
// minInt,maxInt are used to calculate POS on callback event
|
||||||
|
minInt : Integer;
|
||||||
|
maxInt : Integer;
|
||||||
|
pageInt : Integer;
|
||||||
procedure actionScrolling(sender: NSObject); message 'actionScrolling:';
|
procedure actionScrolling(sender: NSObject); message 'actionScrolling:';
|
||||||
function IsHorizontal: Boolean; message 'IsHorizontal';
|
function IsHorizontal: Boolean; message 'IsHorizontal';
|
||||||
function acceptsFirstResponder: Boolean; override;
|
function acceptsFirstResponder: Boolean; override;
|
||||||
@ -1040,11 +1048,15 @@ begin
|
|||||||
Result:=fdocumentView;
|
Result:=fdocumentView;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure allocScroller(parent: NSView; var sc: NSScroller; dst: NSRect);
|
procedure allocScroller(parent: TCocoaManualScrollView; var sc: NSScroller; dst: NSRect);
|
||||||
begin
|
begin
|
||||||
if Assigned(sc) then Exit;
|
if Assigned(sc) then Exit;
|
||||||
sc:=NSScroller(NSScroller.alloc).initWithFrame(dst);
|
sc:=TCocoaScrollBar(TCocoaScrollBar.alloc).initWithFrame(dst);
|
||||||
parent.addSubview(sc);
|
parent.addSubview(sc);
|
||||||
|
TCocoaScrollBar(sc).callback:=parent.callback;
|
||||||
|
sc.setTarget(sc);
|
||||||
|
sc.setAction(objcselector('actionScrolling:'));
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure updateDocSize(parent: NSView; doc: NSView; hrz, vrt: NSScroller);
|
procedure updateDocSize(parent: NSView; doc: NSView; hrz, vrt: NSScroller);
|
||||||
@ -1145,6 +1157,16 @@ begin
|
|||||||
Result:=Assigned(fhscroll) and (not fhscroll.isHidden);
|
Result:=Assigned(fhscroll) and (not fhscroll.isHidden);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TCocoaManualScrollView.horizontalScroller: NSScroller;
|
||||||
|
begin
|
||||||
|
Result:=fhscroll;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TCocoaManualScrollView.verticalScroller: NSScroller;
|
||||||
|
begin
|
||||||
|
Result:=fvscroll;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TCocoaWindowContent }
|
{ TCocoaWindowContent }
|
||||||
|
|
||||||
function TCocoaWindowContent.lclIsHandle: Boolean;
|
function TCocoaWindowContent.lclIsHandle: Boolean;
|
||||||
@ -1840,22 +1862,9 @@ end;
|
|||||||
{ TCocoaScrollBar }
|
{ TCocoaScrollBar }
|
||||||
|
|
||||||
procedure TCocoaScrollBar.actionScrolling(sender: NSObject);
|
procedure TCocoaScrollBar.actionScrolling(sender: NSObject);
|
||||||
var
|
|
||||||
LMScroll: TLMScroll;
|
|
||||||
b: Boolean;
|
|
||||||
begin
|
begin
|
||||||
FillChar(LMScroll{%H-}, SizeOf(LMScroll), #0);
|
if Assigned(callback) then
|
||||||
LMScroll.ScrollBar := PtrUInt(Self);
|
callback.scroll( not IsHorizontal(), Round(floatValue * (maxInt-minInt)));
|
||||||
|
|
||||||
if IsHorizontal() then
|
|
||||||
LMScroll.Msg := LM_HSCROLL
|
|
||||||
else
|
|
||||||
LMScroll.Msg := LM_VSCROLL;
|
|
||||||
|
|
||||||
LMScroll.Pos := Round(floatValue * LCLScrollBar.Max);
|
|
||||||
LMScroll.ScrollCode := SIF_POS;
|
|
||||||
|
|
||||||
LCLMessageGlue.DeliverMessage(LCLScrollBar, LMScroll);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCocoaScrollBar.IsHorizontal: Boolean;
|
function TCocoaScrollBar.IsHorizontal: Boolean;
|
||||||
|
@ -1752,19 +1752,47 @@ var
|
|||||||
si : TScrollInfo;
|
si : TScrollInfo;
|
||||||
obj : NSObject;
|
obj : NSObject;
|
||||||
sc : TCocoaScrollView;
|
sc : TCocoaScrollView;
|
||||||
|
bar : TCocoaScrollBar;
|
||||||
begin
|
begin
|
||||||
obj := HandleToNSObject(Handle);
|
obj := HandleToNSObject(Handle);
|
||||||
Result := 0;
|
Result := 0;
|
||||||
if not Assigned(obj) then Exit;
|
if not Assigned(obj) then Exit;
|
||||||
|
|
||||||
if not obj.isKindOfClass(TCocoaScrollView) then Exit;
|
if obj.isKindOfClass(TCocoaScrollView) then
|
||||||
|
begin
|
||||||
|
sc:=TCocoaScrollView(obj);
|
||||||
|
NSScrollViewSetScrollInfo(NSScrollView(obj), SBStyle, ScrollInfo);
|
||||||
|
FillChar(si, sizeof(si), 0);
|
||||||
|
si.cbSize:=sizeof(si);
|
||||||
|
NSScrollViewGetScrollInfo(NSScrollView(obj), SBStyle, si);
|
||||||
|
Result:=si.nPos;
|
||||||
|
end else if obj.isKindOfClass(TCocoaManualScrollView) then
|
||||||
|
begin
|
||||||
|
bar:=nil;
|
||||||
|
if SBStyle=SB_Vert then
|
||||||
|
begin
|
||||||
|
// Win32 forced the scrollbar to show up on SetScrollInfo
|
||||||
|
// TCocoaManualScrollView - also allocates on setting visible
|
||||||
|
TCocoaManualScrollView(obj).setHasVerticalScroller(true);
|
||||||
|
bar:=TCocoaScrollBar(TCocoaManualScrollView(obj).verticalScroller);
|
||||||
|
end
|
||||||
|
else if SBStyle=SB_Horz then
|
||||||
|
begin
|
||||||
|
TCocoaManualScrollView(obj).setHasHorizontalScroller(true);
|
||||||
|
bar := TCocoaScrollBar(TCocoaManualScrollView(obj).horizontalScroller);
|
||||||
|
end;
|
||||||
|
|
||||||
sc:=TCocoaScrollView(obj);
|
if Assigned(bar) then
|
||||||
NSScrollViewSetScrollInfo(NSScrollView(obj), SBStyle, ScrollInfo);
|
Result := CocoaScrollBarSetScrollInfo(bar, ScrollInfo)
|
||||||
FillChar(si, sizeof(si), 0);
|
else
|
||||||
si.cbSize:=sizeof(si);
|
Result := 0;
|
||||||
NSScrollViewGetScrollInfo(NSScrollView(obj), SBStyle, si);
|
|
||||||
Result:=si.nPos;
|
end else if obj.isKindOfClass(TCocoaScrollBar) then
|
||||||
|
begin
|
||||||
|
Result := CocoaScrollBarSetScrollInfo(TCocoaScrollBar(obj), ScrollInfo);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
Result := 0;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCocoaWidgetSet.ShowScrollBar(Handle: HWND; wBar: Integer; bShow: Boolean): Boolean;
|
function TCocoaWidgetSet.ShowScrollBar(Handle: HWND; wBar: Integer; bShow: Boolean): Boolean;
|
||||||
@ -2583,6 +2611,26 @@ begin
|
|||||||
NSObject(Handle).lclScreenToLocal(P.X, P.Y);
|
NSObject(Handle).lclScreenToLocal(P.X, P.Y);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TCocoaWidgetSet.ScrollWindowEx(hWnd: HWND; dx, dy: Integer; prcScroll, prcClip: PRect; hrgnUpdate: HRGN; prcUpdate: PRect; flags: UINT): Boolean;
|
||||||
|
var
|
||||||
|
obj: NSOBject;
|
||||||
|
b: NSRect;
|
||||||
|
v : NSView;
|
||||||
|
begin
|
||||||
|
obj:=NSObject(HandleToNSObject(hWnd));
|
||||||
|
Result:=Assigned(obj) and (obj.isKindOfClass(NSView));
|
||||||
|
if not Result then Exit;
|
||||||
|
|
||||||
|
v:=NSView(obj).lclContentView;
|
||||||
|
|
||||||
|
b:=v.bounds;
|
||||||
|
b.origin.x:=b.origin.x-dx;
|
||||||
|
b.origin.y:=b.origin.y+dy; // reversed
|
||||||
|
v.setBounds(b);
|
||||||
|
// ignore all updates
|
||||||
|
v.setNeedsDisplay_(true);
|
||||||
|
end;
|
||||||
|
|
||||||
function TCocoaWidgetSet.SelectClipRGN(DC: hDC; RGN: HRGN): Longint;
|
function TCocoaWidgetSet.SelectClipRGN(DC: hDC; RGN: HRGN): Longint;
|
||||||
begin
|
begin
|
||||||
Result := ExtSelectClipRgn(DC, RGN, RGN_COPY);
|
Result := ExtSelectClipRgn(DC, RGN, RGN_COPY);
|
||||||
|
@ -155,6 +155,7 @@ function RoundRect(DC: HDC; X1, Y1, X2, Y2: Integer; RX, RY : Integer): Boolean;
|
|||||||
|
|
||||||
function SaveDC(DC: HDC): Integer; override;
|
function SaveDC(DC: HDC): Integer; override;
|
||||||
function ScreenToClient(Handle: HWND; var P: TPoint): Integer; override;
|
function ScreenToClient(Handle: HWND; var P: TPoint): Integer; override;
|
||||||
|
function ScrollWindowEx(hWnd: HWND; dx, dy: Integer; prcScroll, prcClip: PRect; hrgnUpdate: HRGN; prcUpdate: PRect; flags: UINT): Boolean; override;
|
||||||
function SelectClipRGN(DC : hDC; RGN : HRGN) : Longint; override;
|
function SelectClipRGN(DC : hDC; RGN : HRGN) : Longint; override;
|
||||||
function SelectObject(ADC: HDC; GDIObj: HGDIOBJ): HGDIOBJ; override;
|
function SelectObject(ADC: HDC; GDIObj: HGDIOBJ): HGDIOBJ; override;
|
||||||
function SendMessage(Handle: HWND; Msg: Cardinal; WParam: WParam; LParam: LParam): LResult; override;
|
function SendMessage(Handle: HWND; Msg: Cardinal; WParam: WParam; LParam: LParam): LResult; override;
|
||||||
|
@ -63,7 +63,7 @@ type
|
|||||||
procedure DidResignKeyNotification; virtual;
|
procedure DidResignKeyNotification; virtual;
|
||||||
procedure SendOnChange; virtual;
|
procedure SendOnChange; virtual;
|
||||||
procedure SendOnTextChanged; virtual; // text controls (like spin) respond to OnChange for this event, but not for SendOnChange
|
procedure SendOnTextChanged; virtual; // text controls (like spin) respond to OnChange for this event, but not for SendOnChange
|
||||||
|
procedure scroll(isVert: Boolean; Pos: Integer); virtual;
|
||||||
function DeliverMessage(var Msg): LRESULT; virtual; overload;
|
function DeliverMessage(var Msg): LRESULT; virtual; overload;
|
||||||
function DeliverMessage(Msg: Cardinal; WParam: WParam; LParam: LParam): LResult; virtual; overload;
|
function DeliverMessage(Msg: Cardinal; WParam: WParam; LParam: LParam): LResult; virtual; overload;
|
||||||
procedure Draw(ControlContext: NSGraphicsContext; const bounds, dirty: NSRect); virtual;
|
procedure Draw(ControlContext: NSGraphicsContext; const bounds, dirty: NSRect); virtual;
|
||||||
@ -1042,6 +1042,26 @@ begin
|
|||||||
SendSimpleMessage(Target, CM_TEXTCHANGED);
|
SendSimpleMessage(Target, CM_TEXTCHANGED);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TLCLCommonCallback.scroll(isVert: Boolean; Pos: Integer);
|
||||||
|
var
|
||||||
|
LMScroll: TLMScroll;
|
||||||
|
b: Boolean;
|
||||||
|
begin
|
||||||
|
FillChar(LMScroll{%H-}, SizeOf(LMScroll), #0);
|
||||||
|
//todo: this should be a part of a parameter
|
||||||
|
//LMScroll.ScrollBar := Target.Handle;
|
||||||
|
|
||||||
|
if IsVert then
|
||||||
|
LMScroll.Msg := LM_VSCROLL
|
||||||
|
else
|
||||||
|
LMScroll.Msg := LM_HSCROLL;
|
||||||
|
|
||||||
|
LMScroll.Pos := Pos;
|
||||||
|
LMScroll.ScrollCode := SB_THUMBPOSITION; //SIF_POS;
|
||||||
|
|
||||||
|
LCLMessageGlue.DeliverMessage(Target, LMScroll);
|
||||||
|
end;
|
||||||
|
|
||||||
function TLCLCommonCallback.DeliverMessage(var Msg): LRESULT;
|
function TLCLCommonCallback.DeliverMessage(var Msg): LRESULT;
|
||||||
begin
|
begin
|
||||||
Result := LCLMessageGlue.DeliverMessage(Target, Msg);
|
Result := LCLMessageGlue.DeliverMessage(Target, Msg);
|
||||||
|
@ -1387,10 +1387,13 @@ begin
|
|||||||
scr.callback:=TLCLCommonCallback.Create(scr, AWinControl);
|
scr.callback:=TLCLCommonCallback.Create(scr, AWinControl);
|
||||||
|
|
||||||
// OnChange (scrolling) event handling
|
// OnChange (scrolling) event handling
|
||||||
scr.LCLScrollBar := TCustomScrollBar(AWinControl);
|
|
||||||
scr.setTarget(scr);
|
scr.setTarget(scr);
|
||||||
scr.setAction(objcselector('actionScrolling:'));
|
scr.setAction(objcselector('actionScrolling:'));
|
||||||
|
|
||||||
|
scr.minInt:=TCustomScrollBar(AWinControl).Min;
|
||||||
|
scr.maxInt:=TCustomScrollBar(AWinControl).Max;
|
||||||
|
scr.pageInt:=TCustomScrollBar(AWinControl).PageSize;
|
||||||
|
|
||||||
Result:=TLCLIntfHandle(scr);
|
Result:=TLCLIntfHandle(scr);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user