Cocoa: improve ListBox/CheckListBox, Merge branch 'cocoa/list'

This commit is contained in:
rich2014 2024-08-18 15:21:57 +08:00
commit 9d47231bd0
8 changed files with 534 additions and 487 deletions

View File

@ -8,7 +8,7 @@ interface
uses
Classes, SysUtils,
LclType, Controls, ComCtrls,
LclType,
MacOSAll, CocoaAll, CocoaGDIObjects;
type
@ -88,34 +88,6 @@ type
property CocoaOnlyState: Boolean read IsCocoaOnlyState write SetCocoaOnlyState;
end;
{
currently the following callbacks implement IListViewCallBack,
need to be considered before modification:
1. TLCLListViewCallback
2. TLCLListBoxCallback
3. TLCLCheckboxListCallback
}
{ IListViewCallBack }
IListViewCallBack = interface(ICommonCallback)
function ItemsCount: Integer;
function GetImageListType( out lvil: TListViewImageList ): Boolean;
function GetItemTextAt(ARow, ACol: Integer; var Text: String): Boolean;
function GetItemCheckedAt( row: Integer; var CheckState: Integer): Boolean;
function GetItemImageAt(ARow, ACol: Integer; var imgIdx: Integer): Boolean;
function GetImageFromIndex(imgIdx: Integer): NSImage;
procedure SetItemTextAt(ARow, ACol: Integer; const Text: String);
procedure SetItemCheckedAt( row: Integer; CheckState: Integer);
function shouldSelectionChange(NewSel: Integer): Boolean;
procedure ColumnClicked(ACol: Integer);
function drawItem( row: Integer; ctx: TCocoaContext; const r: TRect; state: TOwnerDrawState ): Boolean;
function customDraw( row: Integer; col: Integer; ctx: TCocoaContext; state: TCustomDrawState ): Boolean;
function isCustomDrawSupported: Boolean;
procedure GetRowHeight(rowidx: Integer; var height: Integer);
function GetBorderStyle: TBorderStyle;
function onAddSubview( aView:NSView ): Boolean;
end;
{ TCocoaStatusBar }
IStatusBarCallback = interface {(ICommonCallback) // not needed to inherit from ICommonCallback}

View File

@ -0,0 +1,233 @@
unit CocoaListControl;
{$mode objfpc}{$H+}
{$modeswitch objectivec2}
interface
uses
Classes, SysUtils,
LclType, Controls, ComCtrls,
CocoaAll, CocoaPrivate, CocoaCallback, CocoaWSCommon, CocoaGDIObjects;
type
{
currently the following callbacks implement IListViewCallBack,
need to be considered before modification:
1. TLCLListViewCallback
2. TLCLListBoxCallback
3. TLCLCheckboxListCallback
}
{ IListViewCallBack }
IListViewCallBack = interface(ICommonCallback)
function ItemsCount: Integer;
procedure GetRowHeight(rowidx: Integer; var height: Integer);
function GetBorderStyle: TBorderStyle;
function GetImageListType( out lvil: TListViewImageList ): Boolean;
function GetItemTextAt(ARow, ACol: Integer; var Text: String): Boolean;
function GetItemCheckedAt( row: Integer; var CheckState: Integer): Boolean;
function GetItemImageAt(ARow, ACol: Integer; var imgIdx: Integer): Boolean;
function GetImageFromIndex(imgIdx: Integer): NSImage;
procedure SetItemTextAt(ARow, ACol: Integer; const Text: String);
procedure SetItemCheckedAt( row: Integer; CheckState: Integer);
function selectionIndexSet: NSMutableIndexSet;
function checkedIndexSet: NSMutableIndexSet;
function shouldSelectionChange(NewSel: Integer): Boolean;
function getItemStableSelection(ARow: Integer): Boolean;
procedure ColumnClicked(ACol: Integer);
function onAddSubview( aView:NSView ): Boolean;
function drawItem( row: Integer; ctx: TCocoaContext; const r: TRect; state: TOwnerDrawState ): Boolean;
function customDraw( row: Integer; col: Integer; ctx: TCocoaContext; state: TCustomDrawState ): Boolean;
function isCustomDrawSupported: Boolean;
end;
{ TLCLListControlCallback }
TLCLListControlCallback = class abstract(TLCLCommonCallback, IListViewCallback)
private
_selectionIndexSet: NSMutableIndexSet;
_checkedIndexSet: NSMutableIndexSet;
public
constructor Create(AOwner: NSObject; ATarget: TWinControl; AHandleFrame: NSView = nil); override;
destructor Destroy; override;
function selectionIndexSet: NSMutableIndexSet; virtual;
function checkedIndexSet: NSMutableIndexSet; virtual;
function GetItemCheckedAt( row: Integer; var CheckState: Integer): Boolean; virtual;
procedure SetItemCheckedAt( row: Integer; CheckState: Integer); virtual;
function getItemStableSelection(ARow: Integer): Boolean; virtual;
public
function ItemsCount: Integer; virtual; abstract;
procedure GetRowHeight(rowidx: Integer; var height: Integer); virtual; abstract;
function GetBorderStyle: TBorderStyle; virtual; abstract;
function GetImageListType( out lvil: TListViewImageList ): Boolean; virtual; abstract;
function GetItemTextAt(ARow, ACol: Integer; var Text: String): Boolean; virtual; abstract;
function GetItemImageAt(ARow, ACol: Integer; var imgIdx: Integer): Boolean; virtual; abstract;
function GetImageFromIndex(imgIdx: Integer): NSImage; virtual; abstract;
procedure SetItemTextAt(ARow, ACol: Integer; const Text: String); virtual; abstract;
function shouldSelectionChange(NewSel: Integer): Boolean; virtual; abstract;
procedure ColumnClicked(ACol: Integer); virtual; abstract;
function onAddSubview( aView:NSView ): Boolean; virtual; abstract;
function drawItem( row: Integer; ctx: TCocoaContext; const r: TRect; state: TOwnerDrawState ): Boolean; virtual; abstract;
function customDraw( row: Integer; col: Integer; ctx: TCocoaContext; state: TCustomDrawState ): Boolean; virtual; abstract;
function isCustomDrawSupported: Boolean; virtual; abstract;
end;
{
1. TCocoaTableListView related need to support
TListView/TListBox/TCheckListBox, etc.
2. the differences between these controls can be considered to be
implemented in the callback.
3. however, after careful consideration, we tried to keep the original
intention of the callback, and added TCocoaTableViewProcessor to
isolate these differences.
}
{ TCocoaTableViewProcessor }
TCocoaTableViewProcessor = class
function isInitializing( tv: NSTableView ): Boolean; virtual; abstract;
procedure onReloadData( tv: NSTableView ); virtual; abstract;
procedure onSelectOneItem( tv: NSTableView; selection: NSIndexSet ); virtual; abstract;
procedure onSelectionChanged( tv: NSTableView ); virtual; abstract;
end;
{ TCocoaTableListControlProcessor }
TCocoaTableListControlProcessor = class( TCocoaTableViewProcessor )
protected
function getCallback( tv: NSTableView ): TLCLListControlCallback;
public
procedure onReloadData( tv: NSTableView ); override;
procedure onSelectOneItem( tv: NSTableView; selection: NSIndexSet ); override;
end;
{ TCocoaListControlStringList }
TCocoaListControlStringList = class(TStringList)
protected
procedure Changed; override;
public
Owner: NSTableView;
// some notificaitons (i.e. selection change)
// should not be passed to LCL while clearing
isClearing: Boolean;
constructor Create(AOwner: NSTableView);
procedure Clear; override;
end;
implementation
{ TLCLListControlCallback }
constructor TLCLListControlCallback.Create(AOwner: NSObject;
ATarget: TWinControl; AHandleFrame: NSView);
begin
inherited;
_selectionIndexSet:= NSMutableIndexSet.new;
_checkedIndexSet:= NSMutableIndexSet.new;
end;
destructor TLCLListControlCallback.Destroy;
begin
_selectionIndexSet.release;
_checkedIndexSet.release;
inherited Destroy;
end;
function TLCLListControlCallback.selectionIndexSet: NSMutableIndexSet;
begin
Result:= _selectionIndexSet;
end;
function TLCLListControlCallback.checkedIndexSet: NSMutableIndexSet;
begin
Result:= _checkedIndexSet;
end;
function TLCLListControlCallback.GetItemCheckedAt(row: Integer;
var CheckState: Integer): Boolean;
var
BoolState : array [Boolean] of Integer = (NSOffState, NSOnState);
begin
CheckState := BoolState[self.checkedIndexSet.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 );
end;
function TLCLListControlCallback.getItemStableSelection(ARow: Integer): Boolean;
begin
Result:= selectionIndexSet.containsIndex( ARow );
end;
{ TCocoaTableListControlProcessor }
function TCocoaTableListControlProcessor.getCallback(tv: NSTableView
): TLCLListControlCallback;
begin
Result:= TLCLListControlCallback( tv.lclGetCallback.GetCallbackObject );
end;
procedure TCocoaTableListControlProcessor.onReloadData( tv: NSTableView );
begin
tv.cancelPreviousPerformRequestsWithTarget_selector_object(
tv, ObjcSelector('restoreFromStableSelection'), nil );
tv.performSelector_withObject_afterDelay(
ObjcSelector('restoreFromStableSelection'), nil, 0 );
end;
procedure TCocoaTableListControlProcessor.onSelectOneItem(tv: NSTableView;
selection: NSIndexSet);
var
lclcb: TLCLListControlCallback;
begin
lclcb:= self.getCallback(tv);
if NOT Assigned(lclcb) then
Exit;
lclcb.selectionIndexSet.removeAllIndexes;
lclcb.selectionIndexSet.addIndexes( selection );
end;
{ TCocoaListControlStringList }
procedure TCocoaListControlStringList.Changed;
begin
inherited Changed;
Owner.reloadData;
end;
constructor TCocoaListControlStringList.Create(AOwner: NSTableView);
begin
Owner:=AOwner;
inherited Create;
end;
procedure TCocoaListControlStringList.Clear;
begin
isClearing := true;
try
inherited Clear;
finally
isClearing := false;
end;
end;
end.

View File

@ -12,8 +12,9 @@ uses
Classes, LCLType, SysUtils, LCLMessageGlue, LMessages,
Controls, ComCtrls, Types, StdCtrls, LCLProc, Graphics, ImgList, Forms,
// Cocoa WS
CocoaPrivate, CocoaCallback, CocoaScrollers, CocoaWSScrollers, CocoaTextEdits,
CocoaWSCommon, cocoa_extra, CocoaGDIObjects, CocoaUtils;
CocoaPrivate, CocoaCallback, CocoaListControl, CocoaWSCommon,
CocoaScrollers, CocoaWSScrollers, CocoaTextEdits, CocoaGDIObjects, CocoaUtils,
cocoa_extra;
type
{
@ -80,38 +81,34 @@ type
{ TLCLListViewCallback }
TLCLListViewCallback = class(TLCLCommonCallback, IListViewCallback)
TLCLListViewCallback = class(TLCLListControlCallback)
public
listView: TCustomListView;
isSetTextFromWS: Integer; // allows to suppress the notifation about text change
// when initiated by Cocoa itself.
selectionIndexSet: NSMutableIndexSet;
checkedIndexSet: NSMutableIndexSet;
ownerData: Boolean;
constructor Create(AOwner: NSObject; ATarget: TWinControl; AHandleView: NSView); override;
destructor Destroy; override;
function ItemsCount: Integer;
function GetImageListType( out lvil: TListViewImageList ): Boolean;
function GetItemTextAt(ARow, ACol: Integer; var Text: String): Boolean;
function GetItemCheckedAt( row: Integer; var IsChecked: Integer): Boolean;
function GetItemImageAt(ARow, ACol: Integer; var imgIdx: Integer): Boolean;
function GetImageFromIndex(imgIdx: Integer): NSImage;
procedure SetItemTextAt(ARow, ACol: Integer; const Text: String);
procedure SetItemCheckedAt( row: Integer; IsChecked: Integer);
function getItemStableSelection(ARow: Integer): Boolean;
procedure selectOne(ARow: Integer; isSelected:Boolean );
function shouldSelectionChange(NewSel: Integer): Boolean;
procedure ColumnClicked(ACol: Integer);
function ItemsCount: Integer; override;
function GetImageListType( out lvil: TListViewImageList ): Boolean; override;
function GetItemTextAt(ARow, ACol: Integer; var Text: String): Boolean; override;
function GetItemCheckedAt( row: Integer; var IsChecked: Integer): Boolean; override;
function GetItemImageAt(ARow, ACol: Integer; var imgIdx: Integer): Boolean; override;
function GetImageFromIndex(imgIdx: Integer): NSImage; override;
procedure SetItemTextAt(ARow, ACol: Integer; const Text: String); override;
procedure SetItemCheckedAt( row: Integer; IsChecked: Integer); override;
function shouldSelectionChange(NewSel: Integer): Boolean; override;
procedure ColumnClicked(ACol: Integer); override;
function drawItem( row: Integer; ctx: TCocoaContext; const r: TRect;
state: TOwnerDrawState): Boolean;
state: TOwnerDrawState): Boolean; override;
function customDraw( row: Integer; col: Integer;
ctx: TCocoaContext; state: TCustomDrawState ): Boolean;
function isCustomDrawSupported: Boolean;
procedure GetRowHeight(rowidx: Integer; var h: Integer);
function GetBorderStyle: TBorderStyle;
function onAddSubview(aView: NSView): Boolean;
ctx: TCocoaContext; state: TCustomDrawState ): Boolean; override;
function isCustomDrawSupported: Boolean; override;
procedure GetRowHeight(rowidx: Integer; var h: Integer); override;
function GetBorderStyle: TBorderStyle; override;
function onAddSubview(aView: NSView): Boolean; override;
procedure selectOne(ARow: Integer; isSelected:Boolean );
procedure callTargetInitializeWnd;
end;
TLCLListViewCallBackClass = class of TLCLListViewCallback;
@ -328,22 +325,6 @@ end;
{ TLCLListViewCallback }
constructor TLCLListViewCallback.Create(AOwner: NSObject; ATarget: TWinControl; AHandleView: NSView);
begin
inherited Create(AOwner, ATarget, AHandleView);
selectionIndexSet:= NSMutableIndexSet.new;
checkedIndexSet:= NSMutableIndexSet.new;
end;
destructor TLCLListViewCallback.Destroy;
begin
selectionIndexSet.release;
selectionIndexSet:= nil;
checkedIndexSet.release;
checkedIndexSet:= nil;
inherited Destroy;
end;
function TLCLListViewCallback.ItemsCount: Integer;
begin
Result:= listView.Items.Count;
@ -372,13 +353,11 @@ function TLCLListViewCallback.GetItemCheckedAt( row: Integer;
var IsChecked: Integer): Boolean;
var
BoolState : array [Boolean] of Integer = (NSOffState, NSOnState);
indexSet: NSIndexSet;
begin
indexSet:= self.checkedIndexSet;
if ownerData and Assigned(listView) and (row>=0) and (row < listView.Items.Count) then
IsChecked := BoolState[listView.Items[row].Checked]
else
IsChecked := BoolState[checkedIndexSet.containsIndex(row)];
Inherited GetItemCheckedAt( row, IsChecked );
Result := true;
end;
@ -483,9 +462,7 @@ var
Msg: TLMNotify;
NMLV: TNMListView;
begin
if IsChecked = NSOnState
then checkedIndexSet.addIndex(row)
else checkedIndexSet.removeIndex(row);
Inherited;
FillChar(Msg{%H-}, SizeOf(Msg), #0);
FillChar(NMLV{%H-}, SizeOf(NMLV), #0);
@ -502,11 +479,6 @@ begin
LCLMessageGlue.DeliverMessage(ListView, Msg);
end;
function TLCLListViewCallback.getItemStableSelection(ARow: Integer): Boolean;
begin
Result:= selectionIndexSet.containsIndex( ARow );
end;
procedure TLCLListViewCallback.selectOne(ARow: Integer; isSelected: Boolean);
procedure sendMsgToLCL;
var

View File

@ -25,28 +25,14 @@ interface
uses
Classes, SysUtils,
MacOSAll, CocoaAll,
CocoaPrivate, Cocoa_Extra, CocoaCallback, CocoaConst, CocoaConfig,
CocoaWSCommon, CocoaUtils, CocoaGDIObjects,
MacOSAll, CocoaAll, LazLogger,
CocoaPrivate, Cocoa_Extra, CocoaCallback, CocoaListControl,
CocoaConst, CocoaConfig, CocoaWSCommon, CocoaUtils, CocoaGDIObjects,
CocoaListView, CocoaTextEdits,
LCLType, LCLMessageGlue, LMessages, Controls, ComCtrls, StdCtrls, ImgList, Forms;
type
{ TCocoaStringList }
TCocoaStringList = class(TStringList)
protected
procedure Changed; override;
public
Owner: NSTableView;
// some notificaitons (i.e. selection change)
// should not be passed to LCL while clearing
isClearing: Boolean;
constructor Create(AOwner: NSTableView);
procedure Clear; override;
end;
{ TCocoaTableListItem }
TCocoaTableListItem = objcclass(NSTableCellView)
@ -76,24 +62,6 @@ type
procedure dealloc; override;
end;
{
1. TCocoaTableListView related need to support
TListView/TListBox/TCheckListBox, etc.
2. the differences between these controls can be considered to be
implemented in the callback.
3. however, after careful consideration, we tried to keep the original
intention of the callback, and added TCocoaTableViewProcessor to
isolate these differences.
}
{ TCocoaTableViewProcessor }
TCocoaTableViewProcessor = class
function isInitializing( tv: NSTableView ): Boolean; virtual; abstract;
procedure onReloadData( tv: NSTableView ); virtual; abstract;
procedure onSelectOneItem( tv: NSTableView; selection: NSIndexSet ); virtual; abstract;
procedure onSelectionChanged( tv: NSTableView ); virtual; abstract;
end;
{ TCocoaTableListView }
TCocoaTableListView = objcclass(
@ -106,7 +74,7 @@ type
_checkBoxes: Boolean;
public
iconSize: NSSize;
callback: IListViewCallback;
callback: TLCLListControlCallback;
selectingByProgram: Boolean;
readOnly: Boolean;
isOwnerDraw : Boolean;
@ -128,6 +96,10 @@ type
function tableView_viewForTableColumn_row(tableView: NSTableView; tableColumn: NSTableColumn; row: NSInteger): NSView;
function tableView_rowViewForRow(tableView: NSTableView; row: NSInteger): NSTableRowView;
procedure lclInsertItem(const AIndex: Integer); message 'lclInsertItem:';
procedure lclDeleteItem(const AIndex: Integer); message 'lclDeleteItem:';
procedure lclExchangeItem(const AIndex1: Integer; const AIndex2: Integer); message 'lclExchangeItem:AIndex2:';
procedure lclClearItem; message 'lclClearItem';
procedure checkboxAction(sender: NSButton); message 'checkboxAction:';
function acceptsFirstResponder: LCLObjCBoolean; override;
function lclGetCallback: ICommonCallback; override;
@ -262,13 +234,9 @@ type
{ TCocoaTableListViewProcessor }
TCocoaTableListViewProcessor = class( TCocoaTableViewProcessor )
private
function getCallback( tv: NSTableView ): TLCLListViewCallback;
TCocoaTableListViewProcessor = class( TCocoaTableListControlProcessor )
public
function isInitializing( tv: NSTableView ): Boolean; override;
procedure onReloadData( tv: NSTableView ); override;
procedure onSelectOneItem( tv: NSTableView; selection: NSIndexSet ); override;
procedure onSelectionChanged( tv: NSTableView ); override;
end;
@ -409,13 +377,10 @@ begin
end;
procedure TCocoaTableListView.backend_reloadData;
var
lclcb: TLCLListViewCallback;
begin
self.reloadData;
if Assigned(self.callback) then begin
lclcb:= TLCLListViewCallback( self.callback.GetCallbackObject );
self.selectRowIndexesByProgram( lclcb.selectionIndexSet );
self.selectRowIndexesByProgram( self.callback.selectionIndexSet );
end;
end;
@ -505,8 +470,9 @@ begin
Result:= False;
if NOT self.isOwnerDraw then
Exit;
if not Assigned(self.callback) then
Exit;
if not Assigned(callback) then Exit;
ctx := TCocoaContext.Create(NSGraphicsContext.currentContext);
ctx.InitDraw(Round(ctxSize.width), Round(ctxSize.height));
try
@ -518,7 +484,7 @@ begin
if isChecked(self,row) then
Include(ItemState, odChecked);
Result:= callback.drawItem(row, ctx, NSRectToRect(clipRect), ItemState);
Result:= self.callback.drawItem(row, ctx, NSRectToRect(clipRect), ItemState);
finally
ctx.Free;
end;
@ -531,9 +497,9 @@ var
state: TCustomDrawState;
begin
Result:= False;
if NOT Assigned(callback) then
if NOT Assigned(self.callback) then
Exit;
if NOT callback.isCustomDrawSupported then
if NOT self.callback.isCustomDrawSupported then
Exit;
ctx := TCocoaContext.Create(NSGraphicsContext.currentContext);
@ -547,7 +513,7 @@ begin
if isChecked(self,row) then
Include(state, cdsChecked);
Result:= callback.customDraw(row, col, ctx, state);
Result:= self.callback.customDraw(row, col, ctx, state);
finally
ctx.Free;
end;
@ -557,8 +523,8 @@ procedure TCocoaTableListView.drawRect(dirtyRect: NSRect);
var
done: Boolean;
begin
if CheckMainThread and Assigned(callback) then
callback.Draw(NSGraphicsContext.currentContext, bounds, dirtyRect);
if CheckMainThread and Assigned(self.callback) then
self.callback.Draw(NSGraphicsContext.currentContext, bounds, dirtyRect);
done:= self.lclCallCustomDraw( -1, -1, self.bounds.size, dirtyRect );
@ -583,14 +549,11 @@ begin
end;
procedure TCocoaTableListView.restoreFromStableSelection;
var
lclcb: TLCLListViewCallback;
begin
if NOT Assigned(self.callback) then
Exit;
lclcb:= TLCLListViewCallback( self.callback.GetCallbackObject );
self.selectRowIndexesByProgram( lclcb.selectionIndexSet );
self.selectRowIndexesByProgram( self.callback.selectionIndexSet );
end;
procedure TCocoaTableListView.reloadData;
@ -716,8 +679,8 @@ end;
function TCocoaTableListView.numberOfRowsInTableView(tableView: NSTableView
): NSInteger;
begin
if Assigned(callback) then
Result := callback.ItemsCount
if Assigned(self.callback) then
Result := self.callback.ItemsCount
else
Result := 0;
end;
@ -737,14 +700,14 @@ end;
function TCocoaTableListView.tableView_shouldSelectRow(tableView: NSTableView;
row: NSInteger): Boolean;
begin
Result:= callback.shouldSelectionChange( row );
Result:= self.callback.shouldSelectionChange( row );
end;
procedure TCocoaTableListView.tableView_didClickTableColumn(
tableView: NSTableView; tableColumn: NSTableColumn);
begin
if Assigned(callback) then
callback.ColumnClicked(getIndexOfColumn(tableColumn));
if Assigned(self.callback) then
self.callback.ColumnClicked(getIndexOfColumn(tableColumn));
end;
function TCocoaTableListView.tableView_heightOfRow(tableView: NSTableView;
@ -755,9 +718,9 @@ begin
h := CustomRowHeight;
if h = 0 then h := DefaultRowHeight;
if isDynamicRowHeight and Assigned(callback) then
if isDynamicRowHeight and Assigned(self.callback) then
begin
callback.GetRowHeight(Integer(row), h);
self.callback.GetRowHeight(Integer(row), h);
if h<=0 then h:=1; // must be positive (non-zero)
end;
Result := h;
@ -1045,9 +1008,23 @@ begin
end;
procedure TCocoaTableListView.tableViewSelectionDidChange(notification: NSNotification);
var
selectionIndexSet: NSMutableIndexSet;
begin
if Assigned(_processor) then
if NOT Assigned(self.callback) then
Exit;
if Assigned(_processor) then begin
if _processor.isInitializing(self) then
Exit;
_processor.onSelectionChanged( self );
end;
if NOT self.selectingByProgram then begin
selectionIndexSet:= self.callback.selectionIndexSet;
selectionIndexSet.removeAllIndexes;
selectionIndexSet.addIndexes( self.selectedRowIndexes );
end;
end;
procedure TCocoaTableListView.tableViewColumnDidResize(
@ -1056,30 +1033,6 @@ begin
self.reloadData;
end;
{ TCocoaStringList }
procedure TCocoaStringList.Changed;
begin
inherited Changed;
Owner.reloadData;
end;
constructor TCocoaStringList.Create(AOwner: NSTableView);
begin
Owner:=AOwner;
inherited Create;
end;
procedure TCocoaStringList.Clear;
begin
isClearing := true;
try
inherited Clear;
finally
isClearing := false;
end;
end;
{ TCocoaTableListItem }
function TCocoaTableListItem.checkBox: NSButton;
@ -1345,14 +1298,79 @@ begin
rowView.row:= row;
end;
procedure TCocoaTableListView.lclInsertItem(const AIndex: Integer);
begin
if NOT Assigned(self.callback) then
Exit;
if _processor.isInitializing(self) then
Exit;
self.callback.checkedIndexSet.shiftIndexesStartingAtIndex_by( AIndex, 1 );
self.callback.selectionIndexSet.shiftIndexesStartingAtIndex_by( AIndex, 1 );
self.selectRowIndexesByProgram( self.callback.selectionIndexSet );
self.reloadData;
self.sizeToFit();
end;
procedure TCocoaTableListView.lclDeleteItem(const AIndex: Integer);
begin
if NOT Assigned(self.callback) then
Exit;
self.callback.checkedIndexSet.shiftIndexesStartingAtIndex_by( AIndex+1, -1);
self.callback.selectionIndexSet.shiftIndexesStartingAtIndex_by( AIndex+1, -1 );
self.selectRowIndexesByProgram( self.callback.selectionIndexSet );
self.reloadData;
end;
procedure ExchangeIndexSetItem( indexSet: NSMutableIndexSet;
const AIndex1: Integer; const AIndex2: Integer );
var
hasIndex1: Boolean;
hasIndex2: Boolean;
begin
hasIndex1:= indexSet.containsIndex(AIndex1);
hasIndex2:= indexSet.containsIndex(AIndex2);
if hasIndex1 = hasIndex2 then
Exit;
if hasIndex1 then begin
indexSet.removeIndex( AIndex1 );
indexSet.addIndex( AIndex2 );
end;
if hasIndex2 then begin
indexSet.removeIndex( AIndex2 );
indexSet.addIndex( AIndex1 );
end;
end;
procedure TCocoaTableListView.lclExchangeItem(const AIndex1: Integer;
const AIndex2: Integer);
begin
if NOT Assigned(self.callback) then
Exit;
ExchangeIndexSetItem( self.callback.checkedIndexSet, AIndex1, AIndex2 );
ExchangeIndexSetItem( self.callback.selectionIndexSet, AIndex1, AIndex2 );
self.reloadData;
end;
procedure TCocoaTableListView.lclClearItem;
begin
self.callback.checkedIndexSet.removeAllIndexes;
self.callback.selectionIndexSet.removeAllIndexes;
self.reloadData;
end;
procedure TCocoaTableListView.checkboxAction(sender: NSButton);
var
row: NSInteger;
begin
if not Assigned(callback) then Exit;
if not Assigned(self.callback) then Exit;
row := rowForView(sender.superview);
callback.SetItemCheckedAt(row, sender.state);
self.callback.SetItemCheckedAt(row, sender.state);
if sender.state = NSOnState then begin
self.selectOneItemByIndex(row, True);
self.window.makeFirstResponder( self );
@ -1383,17 +1401,8 @@ begin
end;
procedure TCocoaWSListView_TableViewHandler.doReloadDataAfterDelete( AIndex: PtrInt);
var
lclcb : TLCLListViewCallback;
begin
lclcb:= getCallback;
if NOT Assigned(lclcb) then
Exit;
lclcb.checkedIndexSet.shiftIndexesStartingAtIndex_by( AIndex+1, -1);
lclcb.selectionIndexSet.shiftIndexesStartingAtIndex_by( AIndex+1, -1 );
_tableView.selectRowIndexesByProgram( lclcb.selectionIndexSet );
_tableView.reloadData;
_tableView.lclDeleteItem( AIndex );
end;
procedure TCocoaWSListView_TableViewHandler.ColumnDelete(
@ -1640,21 +1649,8 @@ end;
procedure TCocoaWSListView_TableViewHandler.ItemInsert(
const AIndex: Integer; const AItem: TListItem);
var
lclcb: TLCLListViewCallback;
begin
lclcb:= getCallback;
if NOT Assigned(lclcb) then
Exit;
if TCocoaListView(lclcb.Owner).initializing then
Exit;
lclcb.checkedIndexSet.shiftIndexesStartingAtIndex_by( AIndex, 1 );
lclcb.selectionIndexSet.shiftIndexesStartingAtIndex_by( AIndex, 1 );
_tableView.selectRowIndexesByProgram( lclcb.selectionIndexSet );
_tableView.reloadData;
_tableView.sizeToFit();
_tableView.lclInsertItem( AIndex );
end;
procedure TCocoaWSListView_TableViewHandler.ItemSetChecked(
@ -1855,13 +1851,6 @@ end;
{ TCocoaTableListViewProcessor }
function TCocoaTableListViewProcessor.getCallback( tv: NSTableView ): TLCLListViewCallback;
var
cocoaTLV: TCocoaTableListView Absolute tv;
begin
Result:= TLCLListViewCallback( cocoaTLV.callback.GetCallbackObject );
end;
function TCocoaTableListViewProcessor.isInitializing( tv: NSTableView ): Boolean;
var
cocoaTLV: TCocoaTableListView Absolute tv;
@ -1869,28 +1858,8 @@ begin
Result:= False;
if NOT Assigned(cocoaTLV.callback) then
Exit;
Result:= TCocoaListView( self.getCallback(tv).Owner).initializing;
end;
procedure TCocoaTableListViewProcessor.onReloadData( tv: NSTableView );
begin
tv.cancelPreviousPerformRequestsWithTarget_selector_object(
tv, ObjcSelector('restoreFromStableSelection'), nil );
tv.performSelector_withObject_afterDelay(
ObjcSelector('restoreFromStableSelection'), nil, 0 );
end;
procedure TCocoaTableListViewProcessor.onSelectOneItem(tv: NSTableView;
selection: NSIndexSet);
var
lclcb: TLCLListViewCallback;
begin
lclcb:= self.getCallback(tv);
if NOT Assigned(lclcb) then
Exit;
lclcb.selectionIndexSet.removeAllIndexes;
lclcb.selectionIndexSet.addIndexes( selection );
Result:= TCocoaListView( self.getCallback(tv).Owner ).initializing;
end;
procedure TCocoaTableListViewProcessor.onSelectionChanged(tv: NSTableView);
@ -1902,27 +1871,16 @@ var
lclListView: TCustomListView;
cocoaTLV: TCocoaTableListView Absolute tv;
lclcb: TLCLListViewCallback;
lclcb: TLCLListControlCallback;
begin
if NOT Assigned(cocoaTLV.callback) then
Exit;
lclcb:= self.getCallback( tv );
lclListView:= TCustomListView( lclcb.Target );
if self.isInitializing(tv) then
Exit;
selectionIndexSet:= lclcb.selectionIndexSet;
CompareIndexSets(selectionIndexSet, cocoaTLV.selectedRowIndexes, rm, ad);
NewSel := cocoaTLV.selectedRow();
sendSelectionChangedMsgToLCL( lclListView, NewSel, ad, rm );
if NOT cocoaTLV.selectingByProgram then begin
selectionIndexSet.removeAllIndexes;
selectionIndexSet.addIndexes( cocoaTLV.selectedRowIndexes );
end;
end;
end.

View File

@ -30,38 +30,21 @@ uses
WSCheckLst, WSLCLClasses,
// LCL Cocoa
CocoaWSCommon, CocoaPrivate, CocoaCallback, CocoaWSStdCtrls,
CocoaTables, CocoaScrollers, CocoaWSScrollers;
CocoaListControl, CocoaTables, CocoaScrollers, CocoaWSScrollers;
type
{ TCocoaCheckStringList }
TCocoaCheckStringList = class(TCocoaStringList)
protected
procedure ExchangeItems(Index1, Index2: Integer); override;
public
ChkState : array of SInt8;
procedure InsertItem(Index: Integer; const S: string; O: TObject); override;
procedure Delete(Index: Integer); override;
procedure Clear; override;
end;
{ TLCLCheckboxListCallback }
TLCLCheckboxListCallback = class(TLCLListBoxCallback, IListViewCallback)
TLCLCheckboxListCallback = class(TLCLListBoxCallback)
protected
function AllocStrings(ATable: NSTableView): TCocoaStringList; override;
function AllocStrings(ATable: NSTableView): TCocoaListControlStringList; override;
public
checklist: TCustomCheckListBox;
constructor Create(AOwner: NSObject; ATarget: TWinControl; AHandleView: NSView); override;
function GetItemCheckedAt( row: Integer; var CheckState: Integer): Boolean; override;
procedure SetItemCheckedAt( row: Integer; CheckState: Integer); override;
function GetCheckState(Index: Integer; var AState: Integer): Boolean;
function SetCheckState(Index: Integer; AState: Integer; InvalidateCocoa: Boolean = true): Boolean;
end;
{ TCocoaWSCustomCheckListBox }
TCocoaWSCustomCheckListBox = class(TWSCustomCheckListBox)
@ -71,77 +54,13 @@ type
class procedure SetState(const ACheckListBox: TCustomCheckListBox; const AIndex: integer; const AState: TCheckBoxState); override;
end;
function CtrlToCheckList(ctrl: TWinControl; out tbl: TCocoaTableListView; out cb: TLCLCheckboxListCallback): Boolean;
implementation
function CtrlToCheckList(ctrl: TWinControl; out tbl: TCocoaTableListView; out cb: TLCLCheckboxListCallback): Boolean;
begin
Result := Assigned(ctrl) and (ctrl.HandleAllocated) and (ctrl.Handle <> 0);
if not Result then begin
tbl := nil;
cb := nil;
Exit;
end;
tbl:=TCocoaTableListView(NSSCrollView(ctrl.Handle).documentView);
Result := Assigned(tbl);
if Result then
cb := TLCLCheckboxListCallback(tbl.lclGetCallback.GetCallbackObject)
else
cb := nil;
end;
{ TCocoaCheckStringList }
procedure TCocoaCheckStringList.ExchangeItems(Index1, Index2: Integer);
var
t : Integer;
begin
inherited ExchangeItems(Index1, Index2);
t := ChkState[Index1];
ChkState[Index1] := ChkState[Index2];
ChkState[Index2] := t;
end;
procedure TCocoaCheckStringList.InsertItem(Index: Integer; const S: string;
O: TObject);
var
cnt : integer;
sz : integer;
begin
cnt := Count;
inherited InsertItem(Index, S, O);
if length(ChkState)<Capacity then
SetLength(ChkState, Capacity);
sz := (cnt - Index) * sizeof(SInt8);
if sz>0 then System.Move(ChkState[Index], ChkState[Index+1], sz);
ChkState[Index] := 0;
end;
procedure TCocoaCheckStringList.Delete(Index: Integer);
var
sz : Integer;
begin
inherited Delete(Index);
sz := (Count - Index) * sizeof(SInt8);
if (sz>0) and (Index < Count) then
System.Move(ChkState[Index+1], ChkState[Index], sz);
end;
procedure TCocoaCheckStringList.Clear;
begin
inherited Clear;
SetLength(ChkState, 0);
end;
{ TLCLCheckboxListCallback }
function TLCLCheckboxListCallback.AllocStrings(ATable: NSTableView): TCocoaStringList;
function TLCLCheckboxListCallback.AllocStrings(ATable: NSTableView): TCocoaListControlStringList;
begin
Result:=TCocoaCheckStringList.Create(ATable);
Result:=TCocoaListBoxStringList.Create(ATable);
end;
constructor TLCLCheckboxListCallback.Create(AOwner: NSObject; ATarget: TWinControl; AHandleView: NSView);
@ -151,50 +70,11 @@ begin
checklist := TCustomCheckListBox(ATarget);
end;
function TLCLCheckboxListCallback.GetItemCheckedAt( row: Integer;
var CheckState: Integer): Boolean;
begin
Result := GetCheckState(row, CheckState);
end;
procedure TLCLCheckboxListCallback.SetItemCheckedAt( row: Integer;
CheckState: Integer);
var
changed : Boolean;
begin
changed := SetCheckState(row, CheckState, false); // returns true, if changed!s
if changed then LCLSendChangedMsg(Target, row);
end;
function TLCLCheckboxListCallback.GetCheckState(Index: Integer; var AState: Integer): Boolean;
var
chkstr : TCocoaCheckStringList;
begin
Result := Assigned(strings) and (Index>=0) and (Index<strings.Count);
if Result then
begin
chkstr := TCocoaCheckStringList(strings);
AState := chkstr.ChkState[Index];
end
else
ASTate := 0;
end;
function TLCLCheckboxListCallback.SetCheckState(Index: Integer; AState: Integer;
InvalidateCocoa: Boolean = true): Boolean;
var
chkstr : TCocoaCheckStringList;
begin
Result := Assigned(Strings) and (Index>=0) and (Index<strings.Count);
if not Result then Exit;
chkstr := TCocoaCheckStringList(strings);
Result := chkstr.ChkState[Index] <> AState;
if Result then
begin
chkstr.ChkState[Index] := AState;
if InvalidateCocoa and Assigned(listview) then
listview.reloadDataForRow_column(Index, 0);
end;
Inherited;
LCLSendChangedMsg( self.Target, row );
end;
{ TCocoaWSCustomCheckListBox }
@ -213,6 +93,7 @@ var
list: TCocoaTableListView;
scroll: TCocoaScrollView;
processor: TCocoaTableViewProcessor;
lclCheckListBox: TCustomCheckListBox absolute AWinControl;
begin
list := AllocCocoaTableListView.lclInitWithCreateParams(AParams);
if not Assigned(list) then
@ -229,10 +110,11 @@ begin
list.setHeaderView(nil);
list.setDataSource(list);
list.setDelegate(list);
list.setAllowsMultipleSelection(lclCheckListBox.MultiSelect);
list.readOnly := true;
//todo:
//list.AllowMixedState := TCustomCheckListBox(AWinControl).AllowGrayed;
list.isOwnerDraw := TCustomCheckListBox(AWinControl).Style in [lbOwnerDrawFixed, lbOwnerDrawVariable];
list.isOwnerDraw := lclCheckListBox.Style in [lbOwnerDrawFixed, lbOwnerDrawVariable];
scroll := EmbedInScrollView(list);
if not Assigned(scroll) then
@ -244,7 +126,7 @@ begin
scroll.setHasVerticalScroller(true);
scroll.setAutohidesScrollers(true);
ScrollViewSetBorderStyle(scroll, TCustomCheckListBox(AWinControl).BorderStyle);
ScrollViewSetBorderStyle(scroll, lclCheckListBox.BorderStyle);
UpdateControlFocusRing(list, AWinControl);
Result := TLCLHandle(scroll);
@ -260,23 +142,19 @@ end;
class function TCocoaWSCustomCheckListBox.GetState(
const ACheckListBox: TCustomCheckListBox; const AIndex: integer): TCheckBoxState;
var
tbl: TCocoaTableListView;
cb : TLCLCheckboxListCallback;
cocoaSt: Integer;
lclcb : TLCLCheckboxListCallback;
checkState: Integer;
begin
if not CtrlToCheckList(ACheckListBox, tbl, cb) then begin
Result := cbUnchecked;
Result:= cbUnchecked;
lclcb:= TLCLCheckboxListCallback( getCallbackFromLCLListBox(ACheckListBox) );
if NOT Assigned(lclcb) then
Exit;
if lclcb.GetItemCheckedAt(AIndex, checkState) then begin
if checkState <> NSOffState then
Result:= cbChecked;
end;
if cb.GetCheckState(AIndex, cocoaSt) then
case cocoaSt of
NSOnState : Result := cbChecked;
NSMixedState : Result := cbGrayed;
else
Result := cbUnchecked;
end
else
Result := cbUnchecked;
end;
{------------------------------------------------------------------------------
@ -292,19 +170,23 @@ class procedure TCocoaWSCustomCheckListBox.SetState(
const ACheckListBox: TCustomCheckListBox; const AIndex: integer;
const AState: TCheckBoxState);
var
tbl: TCocoaTableListView;
cb : TLCLCheckboxListCallback;
cocoaSt: Integer;
cocoaTLV: TCocoaTableListView;
lclcb : TLCLCheckboxListCallback;
checkState: Integer;
begin
if not CtrlToCheckList(ACheckListBox, tbl, cb) then Exit;
lclcb:= TLCLCheckboxListCallback( getCallbackFromLCLListBox(ACheckListBox) );
if NOT Assigned(lclcb) then
Exit;
case AState of
cbChecked: cocoaSt := NSOnState;
cbGrayed: cocoaSt := NSMixedState;
if AState <> cbUnchecked then
checkState:= NSOnState
else
cocoaSt := NSOffState;
end;
cb.SetCheckState(AIndex, cocoaSt, true);
checkState:= NSOffState;
lclcb.SetItemCheckedAt( AIndex, checkState );
cocoaTLV:= getTableViewFromLCLListBox( ACheckListBox );
cocoaTLV.reloadDataForRow_column( AIndex, 0 );
end;
end.

View File

@ -11,7 +11,7 @@ uses
Controls, ComCtrls, Types, StdCtrls, LCLProc, Graphics, ImgList, Forms,
WSComCtrls,
CocoaAll, CocoaPrivate, CocoaWSCommon,
CocoaListView, CocoaTables, CocoaCollectionView;
CocoaListControl, CocoaListView, CocoaTables, CocoaCollectionView;
type
{ TCocoaWSCustomListView }

View File

@ -34,9 +34,10 @@ uses
// Widgetset
WSStdCtrls, WSLCLClasses,
// LCL Cocoa
CocoaConst, CocoaConfig,
CocoaWSCommon, CocoaPrivate, CocoaCallback, CocoaUtils, CocoaGDIObjects, CocoaButtons,
CocoaTables, CocoaTextEdits, CocoaScrollers, CocoaWSScrollers, Cocoa_Extra;
CocoaPrivate, CocoaCallback, CocoaListControl, CocoaTables,
CocoaConst, CocoaConfig, CocoaWSCommon, CocoaUtils,
CocoaGDIObjects, CocoaButtons, CocoaTextEdits,
CocoaScrollers, CocoaWSScrollers, Cocoa_Extra;
type
@ -131,10 +132,8 @@ type
{ TCocoaTableListBoxProcessor }
TCocoaTableListBoxProcessor = class( TCocoaTableViewProcessor )
TCocoaTableListBoxProcessor = class( TCocoaTableListControlProcessor )
function isInitializing( tv: NSTableView ): Boolean; override;
procedure onReloadData(tv: NSTableView); override;
procedure onSelectOneItem( tv: NSTableView; selection: NSIndexSet ); override;
procedure onSelectionChanged(tv: NSTableView); override;
end;
@ -269,35 +268,44 @@ type
{ TLCLListBoxCallback }
TLCLListBoxCallback = class(TLCLCommonCallback, IListViewCallBack)
TLCLListBoxCallback = class(TLCLListControlCallback)
protected
function AllocStrings(ATable: NSTableView): TCocoaStringList; virtual;
function AllocStrings(ATable: NSTableView): TCocoaListControlStringList; virtual;
public
listview : TCocoaTableListView;
strings : TCocoaStringList;
strings : TCocoaListControlStringList;
constructor CreateWithView(AOwner: TCocoaTableListView; ATarget: TWinControl);
destructor Destroy; override;
function ItemsCount: Integer; virtual;
function GetImageListType(out lvil: TListViewImageList): Boolean; virtual;
function GetItemTextAt(ARow, ACol: Integer; var Text: String): Boolean; virtual;
function GetItemCheckedAt( row: Integer; var isChecked: Integer): Boolean; virtual;
function GetItemImageAt(ARow, ACol: Integer; var imgIdx: Integer): Boolean; virtual;
function GetImageFromIndex(imgIdx: Integer): NSImage; virtual;
procedure SetItemTextAt(ARow, ACol: Integer; const Text: String); virtual;
procedure SetItemCheckedAt( row: Integer; isChecked: Integer); virtual;
function shouldSelectionChange(NewSel: Integer): Boolean; virtual;
procedure ColumnClicked(ACol: Integer); virtual;
function ItemsCount: Integer; override;
function GetImageListType(out lvil: TListViewImageList): Boolean; override;
function GetItemTextAt(ARow, ACol: Integer; var Text: String): Boolean; override;
function GetItemImageAt(ARow, ACol: Integer; var imgIdx: Integer): Boolean; override;
function GetImageFromIndex(imgIdx: Integer): NSImage; override;
procedure SetItemTextAt(ARow, ACol: Integer; const Text: String); override;
function shouldSelectionChange(NewSel: Integer): Boolean; override;
procedure ColumnClicked(ACol: Integer); override;
function drawItem( row: Integer; ctx: TCocoaContext; const r: TRect;
state: TOwnerDrawState ): Boolean; virtual;
state: TOwnerDrawState ): Boolean; override;
function customDraw( row: Integer; col: Integer;
ctx: TCocoaContext; state: TCustomDrawState ): Boolean; virtual;
function isCustomDrawSupported: Boolean; virtual;
procedure GetRowHeight(rowidx: integer; var h: Integer); virtual;
function GetBorderStyle: TBorderStyle;
function onAddSubview(aView: NSView): Boolean;
ctx: TCocoaContext; state: TCustomDrawState ): Boolean; override;
function isCustomDrawSupported: Boolean; override;
procedure GetRowHeight(rowidx: integer; var h: Integer); override;
function GetBorderStyle: TBorderStyle; override;
function onAddSubview(aView: NSView): Boolean; override;
end;
TLCLListBoxCallBackClass = class of TLCLListBoxCallBack;
{ TCocoaListBoxStringList }
TCocoaListBoxStringList = class( TCocoaListControlStringList )
protected
procedure InsertItem(Index: Integer; const S: string; O: TObject); override;
public
procedure Delete(Index: Integer); override;
procedure Exchange(Index1, Index2: Integer); override;
procedure Clear; override;
end;
{ TCocoaWSButton }
TCocoaWSButton = class(TWSButton)
@ -369,7 +377,10 @@ function AllocButton(const ATarget: TWinControl; const ACallBackClass: TLCLButto
function AllocTextField(ATarget: TWinControl; const AParams: TCreateParams): TCocoaTextField;
function AllocSecureTextField(ATarget: TWinControl; const AParams: TCreateParams): TCocoaSecureTextField;
function GetListBox(AWinControl: TWinControl): TCocoaTableListView;
function getCallbackFromLCLListBox( const AListBox: TCustomListBox ):
TLCLListBoxCallback;
function getTableViewFromLCLListBox( const AListBox: TCustomListBox ):
TCocoaTableListView;
procedure ListBoxSetStyle(list: TCocoaTableListView; AStyle: TListBoxStyle);
procedure TextViewSetWordWrap(txt: NSTextView; lScroll: NSScrollView; NewWordWrap: Boolean);
@ -600,9 +611,9 @@ end;
{ TLCLListBoxCallback }
function TLCLListBoxCallback.AllocStrings(ATable: NSTableView
): TCocoaStringList;
): TCocoaListControlStringList;
begin
Result := TCocoaStringList.Create(ATable);
Result := TCocoaListBoxStringList.Create(ATable);
end;
constructor TLCLListBoxCallback.CreateWithView(AOwner: TCocoaTableListView;
@ -637,12 +648,6 @@ begin
if Result then Text := strings[ARow];
end;
function TLCLListBoxCallback.GetItemCheckedAt( row: Integer;
var isChecked: Integer): Boolean;
begin
Result := false;
end;
function TLCLListBoxCallback.GetItemImageAt(ARow, ACol: Integer;
var imgIdx: Integer): Boolean;
begin
@ -660,12 +665,6 @@ begin
// todo:
end;
procedure TLCLListBoxCallback.SetItemCheckedAt( row: Integer;
isChecked: Integer);
begin
// do nothing
end;
function TLCLListBoxCallback.shouldSelectionChange(NewSel: Integer
): Boolean;
begin
@ -721,6 +720,33 @@ begin
Result:= False;
end;
{ TCocoaListBoxStringList }
procedure TCocoaListBoxStringList.InsertItem(Index: Integer; const S: string;
O: TObject);
begin
inherited;
TCocoaTableListView(self.Owner).lclInsertItem(Index);
end;
procedure TCocoaListBoxStringList.Delete(Index: Integer);
begin
inherited;
TCocoaTableListView(self.Owner).lclDeleteItem(Index);
end;
procedure TCocoaListBoxStringList.Exchange(Index1, Index2: Integer);
begin
inherited;
TCocoaTableListView(self.Owner).lclExchangeItem(Index1, Index2);
end;
procedure TCocoaListBoxStringList.Clear;
begin
inherited;
TCocoaTableListView(self.Owner).lclClearItem();
end;
{ TLCLCheckBoxCallback }
procedure TLCLCheckBoxCallback.ButtonClick;
@ -2392,24 +2418,29 @@ end;
{ TCocoaWSCustomListBox }
function GetListBox(AWinControl: TWinControl): TCocoaTableListView;
function getTableViewFromLCLListBox( const AListBox: TCustomListBox ):
TCocoaTableListView;
var
scrollView: NSScrollView;
begin
if not Assigned(AWinControl) or (AWinControl.Handle=0) then
Result := nil
else
Result := TCocoaTableListView(TCocoaScrollView(AWinControl.Handle).documentView);
Result:= nil;
if NOT Assigned(AListBox) or NOT AListBox.HandleAllocated then
Exit;
scrollView:= NSSCrollView( AListBox.Handle );
Result:= TCocoaTableListView( scrollView.documentView );
end;
function GetListBoxWithCb(AWinControl: TWinControl; out cb: TLCLListBoxCallback): TCocoaTableListView;
function getCallbackFromLCLListBox( const AListBox: TCustomListBox ):
TLCLListBoxCallback;
var
cocoaListView: TCocoaTableListView;
begin
Result := GetListBox(AWinControl);
if not Assigned(Result) then
cb := nil
else
cb := TLCLListBoxCallback(Result.lclGetCallback.GetCallbackObject)
Result:= nil;
cocoaListView:= getTableViewFromLCLListBox( AListBox );
if Assigned(cocoaListView) then
Result:= TLCLListBoxCallback( cocoaListView.callback );
end;
procedure ListBoxSetStyle(list: TCocoaTableListView; AStyle: TListBoxStyle);
begin
if not Assigned(list) then Exit;
@ -2422,12 +2453,12 @@ end;
class procedure TCocoaWSCustomListBox.DragStart(
const ACustomListBox: TCustomListBox);
var
view: TCocoaTableListView;
cb : TLCLListBoxCallback;
lclcb : TLCLListBoxCallback;
begin
view := GetListBoxWithCb(ACustomListBox, cb);
if not Assigned(view) or not Assigned(cb) then Exit;
cb.BlockCocoaMouseMove:=true;
lclcb:= getCallbackFromLCLListBox( ACustomListBox );
if NOT Assigned(lclcb) then
Exit;
lclcb.BlockCocoaMouseMove:=true;
end;
function TCocoaTableListBoxProcessor.isInitializing(tv: NSTableView): Boolean;
@ -2435,30 +2466,23 @@ begin
Result:= False;
end;
procedure TCocoaTableListBoxProcessor.onReloadData(tv: NSTableView);
begin
end;
procedure TCocoaTableListBoxProcessor.onSelectOneItem(tv: NSTableView;
selection: NSIndexSet);
begin
end;
procedure TCocoaTableListBoxProcessor.onSelectionChanged(tv: NSTableView);
var
lclListView: TCustomListView;
lclListBox: TCustomListBox;
cocoaTLV: TCocoaTableListView Absolute tv;
lclcb: TLCLListBoxCallback;
begin
if NOT Assigned(cocoaTLV.callback) then
Exit;
lclcb:= TLCLListBoxCallback( cocoaTLV.callback.GetCallbackObject );
lclListView:= TCustomListView( lclcb.Target );
lclcb:= TLCLListBoxCallback( cocoaTLV.callback );
lclListBox:= TCustomListBox( lclcb.Target );
if lclListBox = nil then
Exit;
// do not notify about selection changes while clearing
if Assigned(lclcb.strings) and (lclcb.strings.isClearing) then Exit;
SendSimpleMessage(lclListView, LM_SELCHANGE);
SendSimpleMessage(lclListBox, LM_SELCHANGE);
end;
class function TCocoaWSCustomListBox.CreateHandle(const AWinControl:TWinControl;
@ -2528,7 +2552,7 @@ var
list: TCocoaTableListView;
lPoint: NSPoint;
begin
list := GetListBox(ACustomListBox);
list := getTableViewFromLCLListBox(ACustomListBox);
if not Assigned(list) then
begin
Result:=-1;
@ -2545,7 +2569,7 @@ var
begin
Result := False;
view := GetListBox(ACustomListBox);
view := getTableViewFromLCLListBox(ACustomListBox);
if not Assigned(view) then Exit(False);
Result := LCLGetItemRect(view, Index, 0, ARect);
end;
@ -2554,7 +2578,7 @@ class function TCocoaWSCustomListBox.GetScrollWidth(const ACustomListBox: TCusto
var
view: TCocoaTableListView;
begin
view := GetListBox(ACustomListBox);
view := getTableViewFromLCLListBox(ACustomListBox);
if not Assigned(view) then Exit(0);
Result := view.ScrollWidth;
end;
@ -2564,7 +2588,7 @@ var
view: TCocoaTableListView;
indexset: NSIndexSet;
begin
view:=GetListBox(ACustomListBox);
view:=getTableViewFromLCLListBox(ACustomListBox);
if not Assigned(view) then Exit(-1);
indexset:=view.selectedRowIndexes();
@ -2579,7 +2603,7 @@ var
view: TCocoaTableListView;
selection: NSIndexSet;
begin
view := GetListBox(ACustomListBox);
view := getTableViewFromLCLListBox(ACustomListBox);
if not Assigned(view) then Exit(0);
selection := view.selectedRowIndexes();
Result := selection.count();
@ -2591,7 +2615,7 @@ var
view: TCocoaTableListView;
selection: NSIndexSet;
begin
view := GetListBox(ACustomListBox);
view := getTableViewFromLCLListBox(ACustomListBox);
if not Assigned(view) then Exit(False);
if AIndex < 0 then Exit(False);
selection := view.selectedRowIndexes();
@ -2600,35 +2624,36 @@ end;
class function TCocoaWSCustomListBox.GetStrings(const ACustomListBox: TCustomListBox):TStrings;
var
view: TCocoaTableListView;
cb : TLCLListBoxCallback;
lclcb : TLCLListBoxCallback;
begin
view := GetListBoxWithCb(ACustomListBox, cb);
if not Assigned(view) then Exit(nil);
Result := cb.strings;
lclcb:= getCallbackFromLCLListBox( ACustomListBox );
if NOT Assigned(lclcb) then
Exit;
Result:= lclcb.strings;
end;
class function TCocoaWSCustomListBox.GetTopIndex(const ACustomListBox: TCustomListBox): integer;
var
view: TCocoaTableListView;
begin
view := GetListBox(ACustomListBox);
view := getTableViewFromLCLListBox(ACustomListBox);
if not Assigned(view) then Exit(-1);
Result := LCLGetTopRow(view);
end;
class procedure TCocoaWSCustomListBox.SelectItem(const ACustomListBox: TCustomListBox; AIndex: integer; ASelected: boolean);
var
list: TCocoaTableListView;
cocoaTLV:TCocoaTableListView;
lclcb: TLCLListBoxCallback;
begin
list := GetListBox(ACustomListBox);
if not Assigned(list) then Exit();
if ASelected then
begin
list.selectRowIndexes_byExtendingSelection(NSIndexSet.indexSetWithIndex(AIndex), True)
end
else
list.deselectRow(AIndex);
lclcb:= getCallbackFromLCLListBox( ACustomListBox );
if NOT Assigned(lclcb) then
Exit;
if lclcb.getItemStableSelection(AIndex) <> ASelected then begin
cocoaTLV:= getTableViewFromLCLListBox( ACustomListBox );
cocoaTLV.selectOneItemByIndex( AIndex, ASelected );
end;
end;
class procedure TCocoaWSCustomListBox.SetBorderStyle(
@ -2636,7 +2661,7 @@ class procedure TCocoaWSCustomListBox.SetBorderStyle(
var
list: TCocoaTableListView;
begin
list := GetListBox(AWinControl);
list := getTableViewFromLCLListBox( TCustomListBox(AWinControl) );
if not Assigned(list) then Exit;
ScrollViewSetBorderStyle(list.enclosingScrollView, ABorderStyle);
@ -2647,7 +2672,7 @@ class procedure TCocoaWSCustomListBox.SetItemIndex(const ACustomListBox: TCustom
var
list: TCocoaTableListView;
begin
list := GetListBox(ACustomListBox);
list := getTableViewFromLCLListBox(ACustomListBox);
if not Assigned(list) then Exit();
if (AIndex < 0) then
@ -2664,7 +2689,7 @@ var
view: TCocoaTableListView;
column: NSTableColumn;
begin
view := GetListBox(ACustomListBox);
view := getTableViewFromLCLListBox(ACustomListBox);
if not Assigned(view) then Exit;
view.ScrollWidth := AScrollWidth;
column := NSTableColumn(view.tableColumns.objectAtIndex(0));
@ -2684,7 +2709,7 @@ class procedure TCocoaWSCustomListBox.SetSelectionMode(const ACustomListBox: TCu
var
list: TCocoaTableListView;
begin
list := GetListBox(ACustomListBox);
list := getTableViewFromLCLListBox(ACustomListBox);
if not Assigned(list) then Exit();
list.setAllowsMultipleSelection(AMultiSelect);
end;
@ -2693,7 +2718,7 @@ class procedure TCocoaWSCustomListBox.SetStyle(const ACustomListBox: TCustomList
var
view: TCocoaTableListView;
begin
view := GetListBox(ACustomListBox);
view := getTableViewFromLCLListBox(ACustomListBox);
ListBoxSetStyle(view, TCustomListBox(ACustomListBox).Style);
view.setNeedsDisplay_(true);
end;
@ -2702,7 +2727,7 @@ class procedure TCocoaWSCustomListBox.SetTopIndex(const ACustomListBox: TCustomL
var
view: TCocoaTableListView;
begin
view := GetListBox(ACustomListBox);
view := getTableViewFromLCLListBox(ACustomListBox);
if not Assigned(view) then Exit();
view.scrollRowToVisible(NewTopIndex);
end;

View File

@ -131,7 +131,7 @@ end;"/>
<License Value="modified LGPL-2
"/>
<Version Major="3" Minor="99"/>
<Files Count="540">
<Files Count="541">
<Item1>
<Filename Value="carbon/agl.pp"/>
<AddToUsesPkgSection Value="False"/>
@ -2668,6 +2668,11 @@ end;"/>
<AddToUsesPkgSection Value="False"/>
<UnitName Value="CocoaCallback"/>
</Item540>
<Item541>
<Filename Value="cocoa/cocoalistcontrol.pas"/>
<AddToUsesPkgSection Value="False"/>
<UnitName Value="cocoalistcontrol"/>
</Item541>
</Files>
<CompatibilityMode Value="True"/>
<LazDoc Paths="../../docs/xml/lcl"/>