mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-18 02:59:17 +02:00
Cocoa: integrate ScrollView / ScrollBar / Legacy Implement
This commit is contained in:
parent
b1529da111
commit
b081e349c1
@ -113,7 +113,9 @@ type
|
|||||||
|
|
||||||
TCocoaScrollBar = objcclass(NSScroller)
|
TCocoaScrollBar = objcclass(NSScroller)
|
||||||
private
|
private
|
||||||
|
manager: TCocoaScrollBarStyleManager;
|
||||||
effect: TCocoaScrollBarEffect;
|
effect: TCocoaScrollBarEffect;
|
||||||
|
trackingArea: NSTrackingArea;
|
||||||
public
|
public
|
||||||
callback: ICommonCallback;
|
callback: ICommonCallback;
|
||||||
preventBlock : Boolean;
|
preventBlock : Boolean;
|
||||||
@ -125,6 +127,16 @@ type
|
|||||||
largeInc: Integer;
|
largeInc: Integer;
|
||||||
smallInc: Integer;
|
smallInc: Integer;
|
||||||
|
|
||||||
|
procedure dealloc; override;
|
||||||
|
|
||||||
|
procedure drawKnob; override;
|
||||||
|
procedure drawKnobSlotInRect_highlight(slotRect: NSRect; flag: ObjCBOOL); override;
|
||||||
|
procedure setDoubleValue(newValue: double); override;
|
||||||
|
procedure setKnobProportion(newValue: CGFloat); override;
|
||||||
|
procedure updateTrackingAreas; override;
|
||||||
|
procedure mouseEntered(theEvent: NSEvent); override;
|
||||||
|
procedure mouseExited(theEvent: NSEvent); override;
|
||||||
|
|
||||||
procedure actionScrolling(sender: NSObject); message 'actionScrolling:';
|
procedure actionScrolling(sender: NSObject); message 'actionScrolling:';
|
||||||
function IsHorizontal: Boolean; message 'IsHorizontal';
|
function IsHorizontal: Boolean; message 'IsHorizontal';
|
||||||
function acceptsFirstResponder: LCLObjCBoolean; override;
|
function acceptsFirstResponder: LCLObjCBoolean; override;
|
||||||
@ -151,12 +163,16 @@ type
|
|||||||
|
|
||||||
TCocoaManualScrollView = objcclass(NSView)
|
TCocoaManualScrollView = objcclass(NSView)
|
||||||
private
|
private
|
||||||
|
manager: TCocoaScrollStyleManager;
|
||||||
fdocumentView: NSView;
|
fdocumentView: NSView;
|
||||||
fhscroll : NSScroller;
|
fhscroll : TCocoaScrollBar;
|
||||||
fvscroll : NSScroller;
|
fvscroll : TCocoaScrollBar;
|
||||||
public
|
public
|
||||||
callback: ICommonCallback;
|
callback: ICommonCallback;
|
||||||
|
function initWithFrame(frameRect: NSRect): id; override;
|
||||||
procedure dealloc; override;
|
procedure dealloc; override;
|
||||||
|
procedure setFrame(newValue: NSRect); override;
|
||||||
|
|
||||||
function lclGetCallback: ICommonCallback; override;
|
function lclGetCallback: ICommonCallback; override;
|
||||||
procedure lclClearCallback; override;
|
procedure lclClearCallback; override;
|
||||||
function lclContentView: NSView; override;
|
function lclContentView: NSView; override;
|
||||||
@ -177,8 +193,8 @@ type
|
|||||||
function horizontalScroller: NSScroller; message 'horizontalScroller';
|
function horizontalScroller: NSScroller; message 'horizontalScroller';
|
||||||
function verticalScroller: NSScroller; message 'verticalScroller';
|
function verticalScroller: NSScroller; message 'verticalScroller';
|
||||||
|
|
||||||
function allocHorizontalScroller(avisible: Boolean): NSScroller; message 'allocHorizontalScroller:';
|
function allocHorizontalScroller(avisible: Boolean): TCocoaScrollBar; message 'allocHorizontalScroller:';
|
||||||
function allocVerticalScroller(avisible: Boolean): NSScroller; message 'allocVerticalScroller:';
|
function allocVerticalScroller(avisible: Boolean): TCocoaScrollBar; message 'allocVerticalScroller:';
|
||||||
// mouse
|
// mouse
|
||||||
function acceptsFirstMouse(event: NSEvent): LCLObjCBoolean; override;
|
function acceptsFirstMouse(event: NSEvent): LCLObjCBoolean; override;
|
||||||
end;
|
end;
|
||||||
@ -228,8 +244,6 @@ type
|
|||||||
procedure fade( inc:Double; max:Double );
|
procedure fade( inc:Double; max:Double );
|
||||||
message 'fadeInc:max:';
|
message 'fadeInc:max:';
|
||||||
procedure onDestroy; override;
|
procedure onDestroy; override;
|
||||||
public
|
|
||||||
procedure dealloc; override;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TCocoaScrollStyleManagerLegacy }
|
{ TCocoaScrollStyleManagerLegacy }
|
||||||
@ -409,65 +423,29 @@ begin
|
|||||||
sc.setAction(objcselector('actionScrolling:'));
|
sc.setAction(objcselector('actionScrolling:'));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure updateDocSize(parent: NSView; doc: NSView; hScroller, vScroller: NSScroller);
|
function allocScroller(parent: TCocoaManualScrollView; dst: NSRect; aVisible: Boolean)
|
||||||
|
:TCocoaScrollBar;
|
||||||
var
|
var
|
||||||
docFrame : NSRect;
|
scrollBar: TCocoaScrollBar;
|
||||||
hScrollerFrame : NSRect;
|
|
||||||
vScrollerFrame : NSRect;
|
|
||||||
hScrollerHeight : CGFLoat;
|
|
||||||
vScrollerWidth : CGFLoat;
|
|
||||||
begin
|
begin
|
||||||
if not Assigned(parent) or not Assigned(doc) then
|
scrollBar:= TCocoaScrollBar(TCocoaScrollBar.alloc).initWithFrame(dst);
|
||||||
Exit;
|
scrollBar.manager:= parent.manager;
|
||||||
|
scrollBar.effect:= parent.manager.createScrollBarEffect(scrollBar);
|
||||||
docFrame := parent.frame;
|
parent.addSubview(scrollBar);
|
||||||
docFrame.origin := NSZeroPoint;
|
{$ifdef BOOLFIX}
|
||||||
hScrollerFrame := docFrame;
|
scrollBar.setEnabled_(Ord(true));
|
||||||
vScrollerFrame := docFrame;
|
scrollBar.setHidden_(Ord(not AVisible));
|
||||||
|
{$else}
|
||||||
if Assigned(hScroller) and (not hScroller.isHidden) then
|
scrollBar.setEnabled(true);
|
||||||
begin
|
scrollBar.setHidden(not AVisible);
|
||||||
hScrollerHeight := NSScroller.scrollerWidthForControlSize_scrollerStyle(
|
{$endif}
|
||||||
hScroller.controlSize, hScroller.preferredScrollerStyle);
|
scrollBar.preventBlock := true;
|
||||||
hScrollerFrame.size.height := hScrollerHeight;
|
//Suppress scrollers notifications.
|
||||||
|
scrollBar.callback := parent.callback;
|
||||||
docFrame.size.height := docFrame.size.height - hScrollerHeight;
|
scrollBar.suppressLCLMouse := true;
|
||||||
if docFrame.size.height < 0 then
|
scrollBar.setTarget(scrollBar);
|
||||||
docFrame.size.height := 0;
|
scrollBar.setAction(objcselector('actionScrolling:'));
|
||||||
docFrame.origin.y := hScrollerHeight;
|
Result:= scrollBar;
|
||||||
end;
|
|
||||||
|
|
||||||
if Assigned(vScroller) and (not vScroller.isHidden) then
|
|
||||||
begin
|
|
||||||
vScrollerWidth := NSScroller.scrollerWidthForControlSize_scrollerStyle(
|
|
||||||
vScroller.controlSize, vScroller.preferredScrollerStyle);
|
|
||||||
vScrollerFrame.size.width := vScrollerWidth;
|
|
||||||
|
|
||||||
docFrame.size.width := docFrame.size.width - vScrollerWidth;
|
|
||||||
if docFrame.size.width < 0 then
|
|
||||||
docFrame.size.width:= 0;
|
|
||||||
end;
|
|
||||||
|
|
||||||
hScrollerFrame.size.width := docFrame.size.width;
|
|
||||||
vScrollerFrame.size.height := docFrame.size.height;
|
|
||||||
vScrollerFrame.origin.x := docFrame.size.width;
|
|
||||||
vScrollerFrame.origin.y := docFrame.origin.y;
|
|
||||||
|
|
||||||
if Assigned(hScroller) then
|
|
||||||
hScroller.setFrame(hScrollerFrame);
|
|
||||||
|
|
||||||
if Assigned(vScroller) then
|
|
||||||
vScroller.setFrame(vScrollerFrame);
|
|
||||||
|
|
||||||
if not NSEqualRects(doc.frame, docFrame) then
|
|
||||||
begin
|
|
||||||
doc.setFrame(docFrame);
|
|
||||||
{$ifdef BOOLFIX}
|
|
||||||
doc.setNeedsDisplay__(Ord(true));
|
|
||||||
{$else}
|
|
||||||
doc.setNeedsDisplay_(true);
|
|
||||||
{$endif}
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TCocoaManualScrollHost }
|
{ TCocoaManualScrollHost }
|
||||||
@ -509,16 +487,35 @@ begin
|
|||||||
scFrame.origin:= NSZeroPoint;
|
scFrame.origin:= NSZeroPoint;
|
||||||
scFrame.size:= self.contentSize;
|
scFrame.size:= self.contentSize;
|
||||||
sc.setFrame( scFrame );
|
sc.setFrame( scFrame );
|
||||||
updateDocSize(sc, sc.documentView, sc.horizontalScroller, sc.verticalScroller);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TCocoaManualScrollView }
|
{ TCocoaManualScrollView }
|
||||||
|
|
||||||
|
function TCocoaManualScrollView.initWithFrame(frameRect: NSRect): id;
|
||||||
|
begin
|
||||||
|
Result:=inherited;
|
||||||
|
self.manager:= TCocoaScrollStyleManagerLegacy.createForScrollView(self);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TCocoaManualScrollView.dealloc;
|
procedure TCocoaManualScrollView.dealloc;
|
||||||
begin
|
begin
|
||||||
if Assigned(fhscroll) then fhscroll.release;
|
if Assigned(fhscroll) then begin
|
||||||
if Assigned(fvscroll) then fvscroll.release;
|
fhscroll.removeFromSuperview;
|
||||||
inherited dealloc;
|
fhscroll.manager:= nil;
|
||||||
|
fhscroll.release;
|
||||||
|
end;
|
||||||
|
if Assigned(fvscroll) then begin
|
||||||
|
fvscroll.removeFromSuperview;
|
||||||
|
fvscroll.manager:= nil;
|
||||||
|
fvscroll.release;
|
||||||
|
end;
|
||||||
|
FreeAndNil(manager);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCocoaManualScrollView.setFrame(newValue: NSRect);
|
||||||
|
begin
|
||||||
|
inherited setFrame(newValue);
|
||||||
|
manager.updateLayout;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCocoaManualScrollView.lclGetCallback: ICommonCallback;
|
function TCocoaManualScrollView.lclGetCallback: ICommonCallback;
|
||||||
@ -592,58 +589,18 @@ end;
|
|||||||
|
|
||||||
procedure TCocoaManualScrollView.setHasVerticalScroller(doshow: Boolean);
|
procedure TCocoaManualScrollView.setHasVerticalScroller(doshow: Boolean);
|
||||||
begin
|
begin
|
||||||
if doshow then
|
if NOT Assigned(fvscroll) and doshow then
|
||||||
begin
|
fvscroll:= self.allocVerticalScroller( True );
|
||||||
if not Assigned(fvscroll) then
|
manager.activeScrollBar( fvscroll, doshow );
|
||||||
fvscroll := allocVerticalScroller(true);
|
manager.updateLayout;
|
||||||
|
|
||||||
if fvscroll.isHidden then
|
|
||||||
begin
|
|
||||||
{$ifdef BOOLFIX}
|
|
||||||
fvscroll.setHidden_(Ord(false));
|
|
||||||
{$else}
|
|
||||||
fvscroll.setHidden(false);
|
|
||||||
{$endif}
|
|
||||||
end;
|
|
||||||
end
|
|
||||||
else if Assigned(fvscroll) and not fvscroll.isHidden then
|
|
||||||
begin
|
|
||||||
{$ifdef BOOLFIX}
|
|
||||||
fvscroll.setHidden_(Ord(true));
|
|
||||||
{$else}
|
|
||||||
fvscroll.setHidden(true);
|
|
||||||
{$endif}
|
|
||||||
end;
|
|
||||||
|
|
||||||
updateDocSize(self, fdocumentView, fhscroll, fvscroll);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCocoaManualScrollView.setHasHorizontalScroller(doshow: Boolean);
|
procedure TCocoaManualScrollView.setHasHorizontalScroller(doshow: Boolean);
|
||||||
begin
|
begin
|
||||||
if doshow then
|
if NOT Assigned(fhscroll) and doshow then
|
||||||
begin
|
fhscroll:= self.allocHorizontalScroller( True );
|
||||||
if not Assigned(fhscroll) then
|
manager.activeScrollBar( fhscroll, doshow );
|
||||||
fhscroll := allocHorizontalScroller(true);
|
manager.updateLayout;
|
||||||
|
|
||||||
if fhscroll.isHidden then
|
|
||||||
begin
|
|
||||||
{$ifdef BOOLFIX}
|
|
||||||
fhscroll.setHidden_(Ord(false));
|
|
||||||
{$else}
|
|
||||||
fhscroll.setHidden(false);
|
|
||||||
{$endif}
|
|
||||||
end;
|
|
||||||
end
|
|
||||||
else if Assigned(fhscroll) and (not fhscroll.isHidden) then
|
|
||||||
begin
|
|
||||||
{$ifdef BOOLFIX}
|
|
||||||
fhscroll.setHidden_(Ord(true));
|
|
||||||
{$else}
|
|
||||||
fhscroll.setHidden(true);
|
|
||||||
{$endif}
|
|
||||||
end;
|
|
||||||
|
|
||||||
updateDocSize(self, fdocumentView, fhscroll, fvscroll);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCocoaManualScrollView.hasVerticalScroller: Boolean;
|
function TCocoaManualScrollView.hasVerticalScroller: Boolean;
|
||||||
@ -666,7 +623,7 @@ begin
|
|||||||
Result:=fvscroll;
|
Result:=fvscroll;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCocoaManualScrollView.allocHorizontalScroller(avisible: Boolean): NSScroller;
|
function TCocoaManualScrollView.allocHorizontalScroller(avisible: Boolean): TCocoaScrollBar;
|
||||||
var
|
var
|
||||||
r : NSRect;
|
r : NSRect;
|
||||||
f : NSRect;
|
f : NSRect;
|
||||||
@ -680,13 +637,13 @@ begin
|
|||||||
w := NSScroller.scrollerWidthForControlSize_scrollerStyle(
|
w := NSScroller.scrollerWidthForControlSize_scrollerStyle(
|
||||||
fhscroll.controlSize, fhscroll.preferredScrollerStyle);
|
fhscroll.controlSize, fhscroll.preferredScrollerStyle);
|
||||||
r := NSMakeRect(0, 0, Max(f.size.width,w+1), w); // width<height to create a horizontal scroller
|
r := NSMakeRect(0, 0, Max(f.size.width,w+1), w); // width<height to create a horizontal scroller
|
||||||
allocScroller( self, fhscroll, r, avisible);
|
fhscroll := allocScroller( self, r, avisible);
|
||||||
fhscroll.setAutoresizingMask(NSViewWidthSizable);
|
fhscroll.setAutoresizingMask(NSViewWidthSizable);
|
||||||
Result := fhscroll;
|
Result := fhscroll;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCocoaManualScrollView.allocVerticalScroller(avisible: Boolean): NSScroller;
|
function TCocoaManualScrollView.allocVerticalScroller(avisible: Boolean): TCocoaScrollBar;
|
||||||
var
|
var
|
||||||
r : NSRect;
|
r : NSRect;
|
||||||
f : NSRect;
|
f : NSRect;
|
||||||
@ -700,7 +657,7 @@ begin
|
|||||||
w := NSScroller.scrollerWidthForControlSize_scrollerStyle(
|
w := NSScroller.scrollerWidthForControlSize_scrollerStyle(
|
||||||
fvscroll.controlSize, fvscroll.preferredScrollerStyle);
|
fvscroll.controlSize, fvscroll.preferredScrollerStyle);
|
||||||
r := NSMakeRect(0, 0, w, Max(f.size.height,w+1)); // height<width to create a vertical scroller
|
r := NSMakeRect(0, 0, w, Max(f.size.height,w+1)); // height<width to create a vertical scroller
|
||||||
allocScroller( self, fvscroll, r, avisible);
|
fvscroll := allocScroller( self, r, avisible);
|
||||||
if self.isFlipped then
|
if self.isFlipped then
|
||||||
fvscroll.setAutoresizingMask(NSViewHeightSizable or NSViewMaxXMargin)
|
fvscroll.setAutoresizingMask(NSViewHeightSizable or NSViewMaxXMargin)
|
||||||
else
|
else
|
||||||
@ -922,6 +879,81 @@ end;
|
|||||||
|
|
||||||
{ TCocoaScrollBar }
|
{ TCocoaScrollBar }
|
||||||
|
|
||||||
|
procedure TCocoaScrollBar.dealloc;
|
||||||
|
begin
|
||||||
|
FreeAndNil(manager);
|
||||||
|
effect.onDestroy;
|
||||||
|
effect.release;
|
||||||
|
inherited dealloc;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCocoaScrollBar.drawKnob;
|
||||||
|
var
|
||||||
|
rect: NSRect;
|
||||||
|
path: NSBezierPath;
|
||||||
|
begin
|
||||||
|
self.manager.onDrawKnob(self);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCocoaScrollBar.drawKnobSlotInRect_highlight(slotRect: NSRect;
|
||||||
|
flag: ObjCBOOL);
|
||||||
|
var
|
||||||
|
drawSlot: Boolean;
|
||||||
|
begin
|
||||||
|
drawSlot:= self.manager.onDrawKnobSlot(self, slotRect);
|
||||||
|
if drawSlot then
|
||||||
|
Inherited;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCocoaScrollBar.setDoubleValue(newValue: double);
|
||||||
|
var
|
||||||
|
proportion: CGFloat;
|
||||||
|
begin
|
||||||
|
proportion:= self.knobProportion;
|
||||||
|
manager.onKnobValueUpdated( self, newValue, proportion );
|
||||||
|
inherited;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCocoaScrollBar.setKnobProportion(newValue: CGFloat);
|
||||||
|
var
|
||||||
|
position: CGFloat;
|
||||||
|
begin
|
||||||
|
position:= self.doubleValue;
|
||||||
|
manager.onKnobValueUpdated( self, position, newValue );
|
||||||
|
inherited;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCocoaScrollBar.updateTrackingAreas;
|
||||||
|
var
|
||||||
|
i: NSTrackingArea;
|
||||||
|
const
|
||||||
|
options: NSTrackingAreaOptions = NSTrackingMouseEnteredAndExited
|
||||||
|
or NSTrackingActiveAlways;
|
||||||
|
begin
|
||||||
|
if Assigned(trackingArea) then begin
|
||||||
|
removeTrackingArea(trackingArea);
|
||||||
|
trackingArea:= nil;
|
||||||
|
end;
|
||||||
|
|
||||||
|
trackingArea:= NSTrackingArea.alloc.initWithRect_options_owner_userInfo(
|
||||||
|
self.bounds,
|
||||||
|
options,
|
||||||
|
self,
|
||||||
|
nil);
|
||||||
|
self.addTrackingArea( trackingArea );
|
||||||
|
trackingArea.release;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCocoaScrollBar.mouseEntered(theEvent: NSEvent);
|
||||||
|
begin
|
||||||
|
manager.onMouseEntered(self);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCocoaScrollBar.mouseExited(theEvent: NSEvent);
|
||||||
|
begin
|
||||||
|
manager.onMouseExited( self );
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TCocoaScrollBar.actionScrolling(sender: NSObject);
|
procedure TCocoaScrollBar.actionScrolling(sender: NSObject);
|
||||||
var
|
var
|
||||||
event : NSEvent;
|
event : NSEvent;
|
||||||
@ -1160,12 +1192,6 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCocoaScrollBarEffectAlpha.dealloc;
|
|
||||||
begin
|
|
||||||
Writeln( 'TCocoaScrollBarEffectAlpha.dealloc' );
|
|
||||||
inherited dealloc;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ TCocoaScrollStyleManager }
|
{ TCocoaScrollStyleManager }
|
||||||
|
|
||||||
constructor TCocoaScrollStyleManager.createForScrollBar;
|
constructor TCocoaScrollStyleManager.createForScrollBar;
|
||||||
@ -1324,7 +1350,6 @@ procedure TCocoaScrollStyleManagerLegacy.onMouseEntered(scroller: NSScroller
|
|||||||
var
|
var
|
||||||
effect: TCocoaScrollBarEffectAlpha;
|
effect: TCocoaScrollBarEffectAlpha;
|
||||||
begin
|
begin
|
||||||
Writeln( 'onMouseEntered' );
|
|
||||||
effect:= TCocoaScrollBarEffectAlpha(TCocoaScrollBar(scroller).effect);
|
effect:= TCocoaScrollBarEffectAlpha(TCocoaScrollBar(scroller).effect);
|
||||||
effect.fade( 0.05, 0.5 );
|
effect.fade( 0.05, 0.5 );
|
||||||
end;
|
end;
|
||||||
@ -1334,7 +1359,6 @@ procedure TCocoaScrollStyleManagerLegacy.onMouseExited(scroller: NSScroller
|
|||||||
var
|
var
|
||||||
effect: TCocoaScrollBarEffectAlpha;
|
effect: TCocoaScrollBarEffectAlpha;
|
||||||
begin
|
begin
|
||||||
Writeln( 'onMouseExited' );
|
|
||||||
effect:= TCocoaScrollBarEffectAlpha(TCocoaScrollBar(scroller).effect);
|
effect:= TCocoaScrollBarEffectAlpha(TCocoaScrollBar(scroller).effect);
|
||||||
effect.fade( -0.05, 0.25 );
|
effect.fade( -0.05, 0.25 );
|
||||||
end;
|
end;
|
||||||
|
Loading…
Reference in New Issue
Block a user