From 62c26af930d1f4fc05aed1374ba7c67c67f2da86 Mon Sep 17 00:00:00 2001 From: rich2014 Date: Fri, 30 Aug 2024 21:17:01 +0800 Subject: [PATCH] Cocoa: TCheckBoxState.cbGray supported in TCheckListBox #41100 --- lcl/interfaces/cocoa/cocoalistcontrol.pas | 36 ++++++++++++++++++----- lcl/interfaces/cocoa/cocoatables.pas | 7 ++++- lcl/interfaces/cocoa/cocoawschecklst.pas | 18 ++++++------ lcl/interfaces/cocoa/cocoawslistview.pas | 8 +++-- 4 files changed, 49 insertions(+), 20 deletions(-) diff --git a/lcl/interfaces/cocoa/cocoalistcontrol.pas b/lcl/interfaces/cocoa/cocoalistcontrol.pas index 85babb62a9..412b0d8314 100644 --- a/lcl/interfaces/cocoa/cocoalistcontrol.pas +++ b/lcl/interfaces/cocoa/cocoalistcontrol.pas @@ -7,7 +7,7 @@ interface uses Classes, SysUtils, - LCLType, Graphics, Controls, ComCtrls, + LCLType, Graphics, Controls, ComCtrls, StdCtrls, CocoaAll, CocoaPrivate, CocoaCallback, CocoaWSCommon, CocoaGDIObjects, CocoaUtils; @@ -54,11 +54,13 @@ type private _selectionIndexSet: NSMutableIndexSet; _checkedIndexSet: NSMutableIndexSet; + _mixedCheckedIndexSet: NSMutableIndexSet; public constructor Create(AOwner: NSObject; ATarget: TWinControl; AHandleFrame: NSView = nil); override; destructor Destroy; override; function selectionIndexSet: NSMutableIndexSet; virtual; function checkedIndexSet: NSMutableIndexSet; virtual; + function mixedCheckedIndexSet: NSMutableIndexSet; virtual; function GetItemCheckedAt( row: Integer; var CheckState: Integer): Boolean; virtual; procedure SetItemCheckedAt( row: Integer; CheckState: Integer); virtual; function getItemStableSelection(ARow: Integer): Boolean; virtual; @@ -136,12 +138,14 @@ begin inherited; _selectionIndexSet:= NSMutableIndexSet.new; _checkedIndexSet:= NSMutableIndexSet.new; + _mixedCheckedIndexSet:= NSMutableIndexSet.new; end; destructor TLCLListControlCallback.Destroy; begin _selectionIndexSet.release; _checkedIndexSet.release; + _mixedCheckedIndexSet.release; inherited Destroy; end; @@ -155,22 +159,40 @@ begin Result:= _checkedIndexSet; end; +function TLCLListControlCallback.mixedCheckedIndexSet: NSMutableIndexSet; +begin + Result:= _mixedCheckedIndexSet; +end; + function TLCLListControlCallback.GetItemCheckedAt(row: Integer; var CheckState: Integer): Boolean; var - BoolState : array [Boolean] of Integer = (NSOffState, NSOnState); + checkStateArray : array [Boolean] of Integer = (NSOffState, NSOnState); + mixStateArray : array [Boolean] of Integer = (NSOffState, NSMixedState); begin - CheckState := BoolState[self.checkedIndexSet.containsIndex(row)]; + CheckState := checkStateArray[self.checkedIndexSet.containsIndex(row)]; + if CheckState = NSOffState then + CheckState := mixStateArray[self.mixedCheckedIndexSet.containsIndex(row)]; Result := true; end; procedure TLCLListControlCallback.SetItemCheckedAt(row: Integer; CheckState: Integer); begin - if CheckState = NSOnState then - self.checkedIndexSet.addIndex( row ) - else - self.checkedIndexSet.removeIndex( row ); + case CheckState of + NSOnState: begin + self.checkedIndexSet.addIndex( row ); + self.mixedCheckedIndexSet.removeIndex( row ); + end; + NSMixedState: begin + self.checkedIndexSet.removeIndex( row ); + self.mixedCheckedIndexSet.addIndex( row ); + end; + else begin + self.checkedIndexSet.removeIndex( row ); + self.mixedCheckedIndexSet.removeIndex( row ); + end; + end; end; function TLCLListControlCallback.getItemStableSelection(ARow: Integer): Boolean; diff --git a/lcl/interfaces/cocoa/cocoatables.pas b/lcl/interfaces/cocoa/cocoatables.pas index 13d9dfd573..360588e594 100644 --- a/lcl/interfaces/cocoa/cocoatables.pas +++ b/lcl/interfaces/cocoa/cocoatables.pas @@ -520,7 +520,7 @@ begin Exit; tv.callback.GetItemCheckedAt( row, checked ); - Result:= checked=NSOnState; + Result:= checked<>NSOffState; end; function TCocoaTableListView.lclCallDrawItem(row: NSInteger; @@ -1198,6 +1198,7 @@ begin _checkBox:= NSButton.alloc.init; _checkBox.setButtonType( NSSwitchButton ); + _checkBox.setAllowsMixedState( True ); _checkBox.setTitle( CocoaConst.NSSTR_EMPTY ); _checkBox.setTarget( _tableView ); _checkBox.setAction( ObjCSelector('checkboxAction:') ); @@ -1393,6 +1394,7 @@ begin Exit; self.callback.checkedIndexSet.shiftIndexesStartingAtIndex_by( AIndex, 1 ); + self.callback.mixedCheckedIndexSet.shiftIndexesStartingAtIndex_by( AIndex, 1 ); self.callback.selectionIndexSet.shiftIndexesStartingAtIndex_by( AIndex, 1 ); self.selectRowIndexesByProgram( self.callback.selectionIndexSet ); self.reloadData; @@ -1405,6 +1407,7 @@ begin Exit; self.callback.checkedIndexSet.shiftIndexesStartingAtIndex_by( AIndex+1, -1); + self.callback.mixedCheckedIndexSet.shiftIndexesStartingAtIndex_by( AIndex+1, -1); self.callback.selectionIndexSet.shiftIndexesStartingAtIndex_by( AIndex+1, -1 ); self.selectRowIndexesByProgram( self.callback.selectionIndexSet ); self.reloadData; @@ -1438,6 +1441,7 @@ begin Exit; ExchangeIndexSetItem( self.callback.checkedIndexSet, AIndex1, AIndex2 ); + ExchangeIndexSetItem( self.callback.mixedCheckedIndexSet, AIndex1, AIndex2 ); ExchangeIndexSetItem( self.callback.selectionIndexSet, AIndex1, AIndex2 ); self.reloadData; end; @@ -1445,6 +1449,7 @@ end; procedure TCocoaTableListView.lclClearItem; begin self.callback.checkedIndexSet.removeAllIndexes; + self.callback.mixedCheckedIndexSet.removeAllIndexes; self.callback.selectionIndexSet.removeAllIndexes; self.reloadData; end; diff --git a/lcl/interfaces/cocoa/cocoawschecklst.pas b/lcl/interfaces/cocoa/cocoawschecklst.pas index c9bf3b9a44..06eaa91a87 100644 --- a/lcl/interfaces/cocoa/cocoawschecklst.pas +++ b/lcl/interfaces/cocoa/cocoawschecklst.pas @@ -183,6 +183,9 @@ end; ------------------------------------------------------------------------------} class function TCocoaWSCustomCheckListBox.GetState( const ACheckListBox: TCustomCheckListBox; const AIndex: integer): TCheckBoxState; +const + checkStateArray: Array [NSMixedState..NSOnState] of TCheckBoxState = + ( cbGrayed, cbUnchecked, cbChecked ); var lclcb : TLCLCheckboxListCallback; checkState: Integer; @@ -193,10 +196,8 @@ begin if NOT Assigned(lclcb) then Exit; - if lclcb.GetItemCheckedAt(AIndex, checkState) then begin - if checkState <> NSOffState then - Result:= cbChecked; - end; + if lclcb.GetItemCheckedAt(AIndex, checkState) then + Result:= checkStateArray[checkState]; end; {------------------------------------------------------------------------------ @@ -211,6 +212,9 @@ end; class procedure TCocoaWSCustomCheckListBox.SetState( const ACheckListBox: TCustomCheckListBox; const AIndex: integer; const AState: TCheckBoxState); +const + checkStateArray: Array [TCheckBoxState] of Integer = + ( NSOffState, NSOnState, NSMixedState ); var cocoaTLV: TCocoaTableListView; lclcb : TLCLCheckboxListCallback; @@ -220,11 +224,7 @@ begin if NOT Assigned(lclcb) then Exit; - if AState <> cbUnchecked then - checkState:= NSOnState - else - checkState:= NSOffState; - + checkState:= checkStateArray[AState]; lclcb.SetItemCheckedAt( AIndex, checkState ); cocoaTLV:= getTableViewFromLCLListBox( ACheckListBox ); diff --git a/lcl/interfaces/cocoa/cocoawslistview.pas b/lcl/interfaces/cocoa/cocoawslistview.pas index beb851f384..b2074a49ee 100644 --- a/lcl/interfaces/cocoa/cocoawslistview.pas +++ b/lcl/interfaces/cocoa/cocoawslistview.pas @@ -554,8 +554,10 @@ begin Exit; lclcb.ownerData := AValue; - if lclcb.ownerData then + if lclcb.ownerData then begin lclcb.checkedIndexSet.removeAllIndexes; // releasing memory + lclcb.mixedCheckedIndexSet.removeAllIndexes; // releasing memory + end; end; class procedure TCocoaWSCustomListView.SetProperty(const ALV: TCustomListView; @@ -592,8 +594,8 @@ begin if TCocoaListView(lclcb.Owner).initializing then Exit; - if Assigned(lclcb.checkedIndexSet) then - lclcb.checkedIndexSet.removeAllIndexes; + lclcb.checkedIndexSet.removeAllIndexes; + lclcb.mixedCheckedIndexSet.removeAllIndexes; lclcb.selectionIndexSet.removeAllIndexes; WSHandler:= getWSHandler( ALV );