From edee7ec8eff72062b7f9ce014edfeb7b95d91620 Mon Sep 17 00:00:00 2001 From: dmitry Date: Thu, 4 Jan 2018 00:49:03 +0000 Subject: [PATCH] cocoa: remove isAllowCustomScroll from TCocoaScrollView. Instead, introducing TCocoaManualScrollView to support non-control size based ScrollInfo api git-svn-id: trunk@56943 - --- lcl/interfaces/cocoa/cocoaprivate.pp | 195 ++++++++++++++++++++++++- lcl/interfaces/cocoa/cocoawinapi.inc | 78 +++++++++- lcl/interfaces/cocoa/cocoawscommon.pas | 30 +++- 3 files changed, 292 insertions(+), 11 deletions(-) diff --git a/lcl/interfaces/cocoa/cocoaprivate.pp b/lcl/interfaces/cocoa/cocoaprivate.pp index 200ea3a3ec..045731864a 100644 --- a/lcl/interfaces/cocoa/cocoaprivate.pp +++ b/lcl/interfaces/cocoa/cocoaprivate.pp @@ -439,6 +439,8 @@ type procedure keyDown(event: NSEvent); override; procedure keyUp(event: NSEvent); override; procedure flagsChanged(event: NSEvent); override; + // nsview + procedure setFrame(aframe: NSRect); override; // other procedure resetCursorRects; override; function lclIsHandle: Boolean; override; @@ -474,7 +476,6 @@ type TCocoaScrollView = objcclass(NSScrollView) public callback: ICommonCallback; - isAllowCustomScroll : Boolean; function acceptsFirstResponder: Boolean; override; function becomeFirstResponder: Boolean; override; function resignFirstResponder: Boolean; override; @@ -484,6 +485,30 @@ type function lclIsHandle: Boolean; override; end; + { TCocoaManualScrollView } + + TCocoaManualScrollView = objcclass(NSView) + private + fdocumentView: NSView; + fhscroll : NSScroller; + fvscroll : NSScroller; + public + callback: ICommonCallback; + function lclGetCallback: ICommonCallback; override; + procedure lclClearCallback; override; + function lclIsHandle: Boolean; override; + function lclContentView: NSView; override; + function lclClientFrame: TRect; override; + + procedure setDocumentView(AView: NSView); message 'setDocumentView:'; + function documentView: NSView; message 'documentView'; + + procedure setHasVerticalScroller(doshow: Boolean); message 'setHasVerticalScroller:'; + procedure setHasHorizontalScroller(doshow: Boolean); message 'setHasHorizontalScroller:'; + function hasVerticalScroller: Boolean; message 'hasVerticalScroller'; + function hasHorizontalScroller: Boolean; message 'hasHorizontalScroller'; + end; + TStatusItemData = record Text : NSString; Width : Integer; @@ -959,6 +984,167 @@ begin {$ENDIF} end; +{ TCocoaManualScrollView } + +function TCocoaManualScrollView.lclGetCallback: ICommonCallback; +begin + Result := callback; +end; + +procedure TCocoaManualScrollView.lclClearCallback; +begin + callback := nil; +end; + +function TCocoaManualScrollView.lclIsHandle: Boolean; +begin + Result := true; +end; + +function TCocoaManualScrollView.lclContentView: NSView; +begin + Result:=fdocumentView; +end; + +function TCocoaManualScrollView.lclClientFrame: TRect; +begin + if Assigned(fdocumentView) then + begin + Result:=fdocumentView.lclClientFrame; + end + else Result:=inherited lclClientFrame; +end; + +procedure TCocoaManualScrollView.setDocumentView(AView: NSView); +var + f : NSrect; +begin + if fdocumentView=AView then Exit; + if Assigned(fdocumentView) then + fdocumentView.removeFromSuperview; + + fdocumentView:=AView; + if Assigned(fdocumentView) then + begin + addSubview(fdocumentView); + f:=fdocumentView.frame; + f.origin.x:=0; + f.origin.y:=0; + fdocumentView.setFrame(f); + fdocumentView.setAutoresizingMask(NSViewWidthSizable or NSViewHeightSizable); + end; +end; + +function TCocoaManualScrollView.documentView: NSView; +begin + Result:=fdocumentView; +end; + +procedure allocScroller(parent: NSView; var sc: NSScroller; dst: NSRect); +begin + if Assigned(sc) then Exit; + sc:=NSScroller(NSScroller.alloc).initWithFrame(dst); + parent.addSubview(sc); +end; + +procedure updateDocSize(parent: NSView; doc: NSView; hrz, vrt: NSScroller); +var + f : NSRect; + hr : NSRect; + vr : NSRect; +begin + if not Assigned(parent) or not Assigned(doc) then Exit; + + f := parent.frame; + f.origin.x := 0; + f.origin.y := 0; + hr := f; + vr := f; + vr.size.width:=vrt.scrollerWidth; + vr.origin.x:=f.size.width-vr.size.width; + hr.size.height:=hrz.scrollerWidth; + + if Assigned(hrz) and (not hrz.isHidden) then + begin + f.size.height := f.size.height-hrz.scrollerWidth; + f.origin.y := hrz.scrollerWidth; + + vr.origin.y := hrz.scrollerWidth; + vr.size.height := vr.size.height - hrz.scrollerWidth; + if Assigned(vrt) and (not vrt.isHidden) then + hr.size.width:=hr.size.width-vrt.scrollerWidth; + + hrz.setFrame(hr); + end; + + if Assigned(vrt) and (not vrt.isHidden) then + begin + f.size.width := f.size.width-vrt.scrollerWidth; + vrt.setFrame(vr); + end; + + + if not NSEqualRects(doc.frame, f) then + begin + doc.setFrame(f); + doc.setNeedsDisplay_(true); + end; +end; + +procedure TCocoaManualScrollView.setHasVerticalScroller(doshow: Boolean); +var + r : NSRect; + f : NSRect; + w : CGFloat; +begin + f:=frame; + if doshow then + begin + w := NSScroller.scrollerWidth; + if not Assigned(fvscroll) then + begin + r:=NSMakeRect(f.size.width-w, 0, w, f.size.height); + allocScroller( self, fvscroll, r); + fvscroll.setAutoresizingMask(NSViewHeightSizable or NSViewMinXMargin); + end; + fvscroll.setHidden(false); + end + else if Assigned(fvscroll) then + fvscroll.setHidden(true); + updateDocSize(self, fdocumentView, fhscroll, fvscroll); +end; + +procedure TCocoaManualScrollView.setHasHorizontalScroller(doshow: Boolean); +var + r : NSRect; + f : NSRect; +begin + f:=frame; + if doshow then + begin + if not Assigned(fhscroll) then + begin + r:=NSMakeRect(0, 0, f.size.width, NSScroller.scrollerWidth); + allocScroller( self, fhscroll, r); + fhscroll.setAutoresizingMask(NSViewWidthSizable); + end; + fhscroll.setHidden(false); + end + else if Assigned(fhscroll) then + fhscroll.setHidden(true); + updateDocSize(self, fdocumentView, fhscroll, fvscroll); +end; + +function TCocoaManualScrollView.hasVerticalScroller: Boolean; +begin + Result:=Assigned(fvscroll) and (not fvscroll.isHidden); +end; + +function TCocoaManualScrollView.hasHorizontalScroller: Boolean; +begin + Result:=Assigned(fhscroll) and (not fhscroll.isHidden); +end; + { TCocoaWindowContent } function TCocoaWindowContent.lclIsHandle: Boolean; @@ -2361,6 +2547,13 @@ begin inherited flagsChanged(event); end; +procedure TCocoaCustomControl.setFrame(aframe: NSRect); +begin + inherited setFrame(aframe); + // it actually should come from a notifcation + if Assigned(callback) then callback.frameDidChange; +end; + procedure TCocoaCustomControl.mouseUp(event: NSEvent); begin if not Assigned(callback) or not callback.MouseUpDownEvent(event) then diff --git a/lcl/interfaces/cocoa/cocoawinapi.inc b/lcl/interfaces/cocoa/cocoawinapi.inc index d582adca21..19a8f04206 100644 --- a/lcl/interfaces/cocoa/cocoawinapi.inc +++ b/lcl/interfaces/cocoa/cocoawinapi.inc @@ -1577,8 +1577,37 @@ begin end; function TCocoaWidgetSet.GetScrollbarVisible(Handle: HWND; SBStyle: Integer): boolean; +var + obj : NSObject; + sc : NSScrollView; + mn : TCocoaManualScrollView; begin - Result:=False; + obj := HandleToNSObject(Handle); + Result := Assigned(obj); + if not Result then Exit; + + if obj.isKindOfClass(NSScrollView) then + begin + sc := NSScrollView(obj); + case SBStyle of + SB_Vert: Result := sc.hasVerticalScroller; + SB_Horz: Result := sc.hasHorizontalScroller; + else + Result := sc.hasHorizontalScroller and sc.hasVerticalScroller; + end; + end + else if obj.isKindOfClass(TCocoaManualScrollView) then + begin + mn := TCocoaManualScrollView(obj); + case SBStyle of + SB_Vert: Result := mn.hasVerticalScroller; + SB_Horz: Result := mn.hasHorizontalScroller; + else + Result := mn.hasHorizontalScroller and mn.hasVerticalScroller; + end; + end + else + Result := False; end; function TCocoaWidgetSet.GetScrollInfo(Handle: HWND; BarFlag: Integer; @@ -1722,22 +1751,55 @@ function TCocoaWidgetSet.SetScrollInfo(Handle : HWND; SBStyle : Integer; ScrollI var si : TScrollInfo; obj : NSObject; + sc : TCocoaScrollView; begin obj := HandleToNSObject(Handle); Result := 0; if not Assigned(obj) then Exit; - if obj.isKindOfClass(NSScrollView) then - begin - NSScrollViewSetScrollInfo(NSScrollView(obj), SBStyle, ScrollInfo); - NSScrollViewGetScrollInfo(NSScrollView(obj), SBStyle, si); - Result:=si.nPos; - end; + if not obj.isKindOfClass(TCocoaScrollView) then Exit; + + 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; function TCocoaWidgetSet.ShowScrollBar(Handle: HWND; wBar: Integer; bShow: Boolean): Boolean; +var + obj : NSObject; + sc : TCocoaScrollView; + mn : TCocoaManualScrollView; begin - Result:=False; + obj := NSObject(HandleToNSObject(Handle)); + Result := Assigned(obj); + if not Result then Exit; + + if obj.isKindOfClass(TCocoaScrollView) + then begin + Result := true; + sc := TCocoaScrollView(obj); + if wBar in [SB_Vert, SB_Both] then + sc.setHasVerticalScroller(bShow); + + if wBar in [SB_Horz, SB_Both] then + sc.setHasHorizontalScroller(bShow); + end + else if obj.isKindOfClass(TCocoaManualScrollView) + then begin + mn := TCocoaManualScrollView(obj); + + if wBar in [SB_Vert, SB_Both] then + mn.setHasVerticalScroller(bShow); + + if wBar in [SB_Horz, SB_Both] then + mn.setHasHorizontalScroller(bShow); + + Result := true; + end else + Result := false; end; {----------------------------------- DRAWING ----------------------------------} diff --git a/lcl/interfaces/cocoa/cocoawscommon.pas b/lcl/interfaces/cocoa/cocoawscommon.pas index f49177db9a..4d8b18b060 100644 --- a/lcl/interfaces/cocoa/cocoawscommon.pas +++ b/lcl/interfaces/cocoa/cocoawscommon.pas @@ -152,6 +152,27 @@ begin SetViewDefaults(Result); end; +function EmbedInManualScrollView(AView: NSView): TCocoaManualScrollView; +var + r: TRect; + p: NSView; +begin + if not Assigned(AView) then + begin + Result:=nil; + Exit; + end; + r := AView.lclFrame; + p := AView.superview; + Result := TCocoaManualScrollView.alloc.initWithFrame(NSNullRect); + if Assigned(p) then p.addSubView(Result); + Result.lclSetFrame(r); + Result.setHidden(p.isHidden); + Result.setDocumentView(AView); + AView.setHidden(false); + SetViewDefaults(Result); +end; + { TLCLCustomControlCallback } function TLCLCustomControlCallback.MouseMove(Event: NSEvent): Boolean; @@ -1463,11 +1484,16 @@ end; class function TCocoaWSCustomControl.CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; var - ctrl: TCocoaCustomControl; + ctrl : TCocoaCustomControl; + sl : TCocoaManualScrollView; begin ctrl := TCocoaCustomControl(TCocoaCustomControl.alloc.lclInitWithCreateParams(AParams)); ctrl.callback := TLCLCustomControlCallback.Create(ctrl, AWinControl); - Result := TLCLIntfHandle(ctrl); + + sl := EmbedInManualScrollView(ctrl); + sl.callback := ctrl.callback; + + Result := TLCLIntfHandle(sl); end; end.