From 10862c1ceff1c18e09f36cc991f6892e373832c6 Mon Sep 17 00:00:00 2001 From: rich2014 Date: Sun, 1 Oct 2023 23:56:11 +0800 Subject: [PATCH 1/2] Cocoa/TabControl: jumping to the First/Last tab supported by Click+ModifierKey Click the Arrow Button with any key in [Shift,Control,Option,Command] --- lcl/interfaces/cocoa/cocoatabcontrols.pas | 79 +++++++++++++++++------ 1 file changed, 59 insertions(+), 20 deletions(-) diff --git a/lcl/interfaces/cocoa/cocoatabcontrols.pas b/lcl/interfaces/cocoa/cocoatabcontrols.pas index 45aa8a7a8c..a377e1328d 100644 --- a/lcl/interfaces/cocoa/cocoatabcontrols.pas +++ b/lcl/interfaces/cocoa/cocoatabcontrols.pas @@ -98,14 +98,22 @@ type message 'exttabRemoveTabViewItem:'; function exttabIndexOfTabViewItem(lTabPage: NSTabViewItem): NSInteger; message 'exttabIndexOfTabViewItem:'; - procedure extTabPrevButtonClick(sender: id); - message 'extTabPrevButtonClick:'; - procedure extTabNextButtonClick(sender: id); - message 'extTabNextButtonClick:'; procedure extselectTabViewItemAtIndex(index: NSInteger); message 'extselectTabViewItemAtIndex:'; end; + { TCocoaTabControlArrow } + + TCocoaTabControlArrow = objcclass(NSButton) + private + _tabControl: TCocoaTabControl; + private + function speedUp(): Boolean; message 'speedUp'; + public + procedure prevClick(sender: id); message 'prevClick:'; + procedure nextClick(sender: id); message 'nextClick:'; + end; + { TCocoaTabPageView } TCocoaTabPageView = objcclass(TCocoaCustomControl) @@ -159,18 +167,19 @@ begin Result:=false; end; -function AllocArrowButton(isPrev: Boolean): NSButton; +function AllocArrowButton(tabControl:TCocoaTabControl; isPrev:Boolean): NSButton; var - btn : NSButton; + btn : TCocoaTabControlArrow; begin - btn:=NSButton(NSButton.alloc).initWithFrame(NSZeroRect); + btn := TCocoaTabControlArrow.alloc.initWithFrame(NSZeroRect); + btn._tabControl := tabControl; btn.setBezelStyle(NSRegularSquareBezelStyle); btn.setButtonType(NSMomentaryLightButton); if isPrev then btn.setTitle( StrToNSString('◀') ) else - btn.setTitle( StrToNSString('▶') ); + btn.setTitle( StrToNSString('▶') ); {$ifdef BOOLFIX} btn.setBordered_(Ord(false)); @@ -208,14 +217,15 @@ end; procedure AllocPrevNext(aview: TCocoaTabControl); begin - aview.prevarr := AllocArrowButton(true); + aview.prevarr := AllocArrowButton(aview, true); aview.addSubview(aview.prevarr); - aview.nextarr := AllocArrowButton(false); + aview.prevarr.setTarget(aview.prevarr); + aview.prevarr.setAction( ObjCSelector('prevClick:') ); + + aview.nextarr := AllocArrowButton(aview, false); aview.addSubview(aview.nextarr); - aview.prevarr.setTarget(aview); - aview.prevarr.setAction( ObjCSelector('extTabPrevButtonClick:')); - aview.nextarr.setTarget(aview); - aview.nextarr.setAction( ObjCSelector('extTabNextButtonClick:')); + aview.nextarr.setTarget(aview.nextarr); + aview.nextarr.setAction( ObjCSelector('nextClick:') ); end; // only missing ViewItems inserted, RemoveAllTabs() is no longer needed, @@ -771,18 +781,47 @@ begin Result := fulltabs.indexOfObject(lTabPage); end; -procedure TCocoaTabControl.extTabPrevButtonClick(sender: id); +{ TCocoaTabControlArrow } + +function TCocoaTabControlArrow.speedUp(): Boolean; +const + FOUR_MODIFIER_FLAGS = NSShiftKeyMask + or NSControlKeyMask + or NSAlternateKeyMask + or NSCommandKeyMask; begin - if currentIndex = 0 then Exit; - extselectTabViewItemAtIndex( currentIndex-1 ); + if (NSApp.currentEvent.modifierFlags and FOUR_MODIFIER_FLAGS)<>0 then + exit(true); + Result := false; end; -procedure TCocoaTabControl.extTabNextButtonClick(sender: id); +procedure TCocoaTabControlArrow.prevClick(sender: id); +var + currentIndex: Integer; begin - if currentIndex = fulltabs.count - 1 then Exit; - extselectTabViewItemAtIndex( currentIndex+1 ); + currentIndex := _tabControl.currentIndex; + if currentIndex = 0 then + Exit; + if speedUp() then + currentIndex := 0 + else + dec(currentIndex); + _tabControl.extselectTabViewItemAtIndex(currentIndex); end; +procedure TCocoaTabControlArrow.nextClick(sender: id); +var + currentIndex: Integer; +begin + currentIndex := _tabControl.currentIndex; + if currentIndex = _tabControl.fulltabs.count - 1 then + Exit; + if speedUp() then + currentIndex := _tabControl.fulltabs.count - 1 + else + inc(currentIndex); + _tabControl.extselectTabViewItemAtIndex(currentIndex); +end; end. From e4a5170e36b29558df3ffcf7e215db9ce803e42f Mon Sep 17 00:00:00 2001 From: rich2014 Date: Mon, 2 Oct 2023 00:02:52 +0800 Subject: [PATCH 2/2] Cocoa/TabControl: jumping to the First/Last tab supported by the Arrow Button long pressed Arrow Button pressed longer than NSEvent.doubleClickInterval (usually 0.5 seconds) --- lcl/interfaces/cocoa/cocoatabcontrols.pas | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/lcl/interfaces/cocoa/cocoatabcontrols.pas b/lcl/interfaces/cocoa/cocoatabcontrols.pas index a377e1328d..ac99a17b4c 100644 --- a/lcl/interfaces/cocoa/cocoatabcontrols.pas +++ b/lcl/interfaces/cocoa/cocoatabcontrols.pas @@ -107,9 +107,11 @@ type TCocoaTabControlArrow = objcclass(NSButton) private _tabControl: TCocoaTabControl; + _lastMouseDownTime: NSDate; private - function speedUp(): Boolean; message 'speedUp'; + function shouldSpeedUp(): Boolean; message 'shouldSpeedUp'; public + procedure mouseDown(theEvent: NSEvent); override; procedure prevClick(sender: id); message 'prevClick:'; procedure nextClick(sender: id); message 'nextClick:'; end; @@ -783,7 +785,14 @@ end; { TCocoaTabControlArrow } -function TCocoaTabControlArrow.speedUp(): Boolean; +procedure TCocoaTabControlArrow.mouseDown(theEvent: NSEvent); +begin + _lastMouseDownTime := NSDate.date; + inherited; + _lastMouseDownTime := nil; +end; + +function TCocoaTabControlArrow.shouldSpeedUp(): Boolean; const FOUR_MODIFIER_FLAGS = NSShiftKeyMask or NSControlKeyMask @@ -792,6 +801,8 @@ const begin if (NSApp.currentEvent.modifierFlags and FOUR_MODIFIER_FLAGS)<>0 then exit(true); + if NSDate.date.timeIntervalSinceDate(_lastMouseDownTime) > NSEvent.doubleClickInterval then + exit(true); Result := false; end; @@ -802,7 +813,7 @@ begin currentIndex := _tabControl.currentIndex; if currentIndex = 0 then Exit; - if speedUp() then + if shouldSpeedUp() then currentIndex := 0 else dec(currentIndex); @@ -816,7 +827,7 @@ begin currentIndex := _tabControl.currentIndex; if currentIndex = _tabControl.fulltabs.count - 1 then Exit; - if speedUp() then + if shouldSpeedUp() then currentIndex := _tabControl.fulltabs.count - 1 else inc(currentIndex);