mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-06-24 00:48:22 +02:00
1392 lines
45 KiB
ObjectPascal
1392 lines
45 KiB
ObjectPascal
unit CocoaCollectionView;
|
|
|
|
{$mode objfpc}{$H+}
|
|
{$modeswitch objectivec2}
|
|
{$interfaces corba}
|
|
{$include cocoadefines.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils,
|
|
MacOSAll, CocoaAll,
|
|
CocoaPrivate, Cocoa_Extra, CocoaCallback, CocoaConfig, CocoaConst, CocoaUtils,
|
|
CocoaListView, CocoaTextEdits,
|
|
LCLType, Controls, ComCtrls, StdCtrls, ImgList, Forms;
|
|
|
|
type
|
|
|
|
{ TCocoaCollectionItem }
|
|
TCocoaCollectionItem = objcclass(NSCollectionViewItem)
|
|
private
|
|
_checkBox: NSButton;
|
|
private
|
|
procedure checkboxAction(sender: NSButton); message 'checkboxAction:';
|
|
public
|
|
procedure loadView; override;
|
|
function checkBox: NSButton; message 'checkBox';
|
|
procedure createCheckBox; message 'createCheckBox';
|
|
procedure prepareForReuse; message 'prepareForReuse';
|
|
procedure dealloc; override;
|
|
end;
|
|
|
|
{ TCocoaListView_CollectionView_StyleHandler }
|
|
TCocoaListView_CollectionView_StyleHandler = class
|
|
private
|
|
_collectionView: NSCollectionView;
|
|
public
|
|
constructor Create( collectionView: NSCollectionView ); virtual;
|
|
function hasCheckBoxes: Boolean;
|
|
public
|
|
procedure resetSize; virtual; abstract;
|
|
procedure onInit; virtual;
|
|
function isSupportIcon: Boolean; virtual;
|
|
procedure onUpdateItemSize( baseSize: NSSize ); virtual; abstract;
|
|
procedure onUpdateItemLayout( cocoaItem: TCocoaCollectionItem ); virtual; abstract;
|
|
procedure onAdjustTextEditor( lv: TCocoaListView; var aFrame: NSRect ); virtual; abstract;
|
|
end;
|
|
|
|
{ TCocoaCollectionItemView }
|
|
TCocoaCollectionItemView = objcclass(NSView)
|
|
private
|
|
item: TCocoaCollectionItem;
|
|
trackingArea: NSTrackingArea;
|
|
public
|
|
procedure updateTrackingAreas; override;
|
|
procedure mouseEntered(theEvent: NSEvent); override;
|
|
procedure mouseExited(theEvent: NSEvent); override;
|
|
procedure drawRect(dirtyRect: NSRect); override;
|
|
end;
|
|
|
|
{ TCocoaCollectionView }
|
|
TCocoaCollectionView = objcclass(
|
|
NSCollectionView,
|
|
NSCollectionViewDataSourceProtocol,
|
|
NSCollectionViewDelegateProtocol_1011,
|
|
TCocoaListViewBackendControlProtocol )
|
|
private
|
|
_checkBoxes: Boolean;
|
|
public
|
|
styleHandler: TCocoaListView_CollectionView_StyleHandler;
|
|
iconSize: NSSize;
|
|
itemSize: NSSize;
|
|
|
|
procedure lclSetCheckBoxes( checkBoxes: Boolean); message 'lclSetCheckBoxes:';
|
|
function lclHasCheckBoxes: Boolean; message 'lclHasCheckBoxes';
|
|
public
|
|
callback: TLCLListViewCallback;
|
|
function lclGetCallback: ICommonCallback; override;
|
|
procedure lclClearCallback; override;
|
|
procedure lclExpectedKeys(var wantTabs, wantKeys, wantReturn, wantAllKeys: Boolean); override;
|
|
|
|
procedure backend_setCallback( cb: TLCLListViewCallback );
|
|
procedure backend_reloadData;
|
|
procedure backend_onInit;
|
|
public
|
|
procedure dealloc; override;
|
|
procedure addSubview(aView: NSView); override;
|
|
public
|
|
procedure updateItemValue( indexPath:NSIndexPath; cocoaItem:TCocoaCollectionItem );
|
|
message 'updateItemValue:cocoaItem:';
|
|
procedure updateItemSize( baseSize: NSSize );
|
|
message 'updateItemSize:';
|
|
procedure updateItemLayout( item:TCocoaCollectionItem );
|
|
message 'updateItemLayout:';
|
|
|
|
procedure redrawVisibleItems; message 'redrawVisibleItems';
|
|
procedure restoreFromStableSelection; message 'restoreFromStableSelection';
|
|
procedure reloadData; override;
|
|
|
|
procedure selectOneItemByIndex( index: Integer; isSelected: Boolean );
|
|
message 'selectOneItemByIndex:isSelected:';
|
|
public
|
|
function collectionView_numberOfItemsInSection(
|
|
collectionView: NSCollectionView; section: NSInteger ): NSInteger;
|
|
function collectionView_itemForRepresentedObjectAtIndexPath(
|
|
collectionView: NSCollectionView; indexPath: NSIndexPath
|
|
): NSCollectionViewItem;
|
|
|
|
function collectionView_shouldChangeItemsAtIndexPaths_toHighlightState(
|
|
collectionView: NSCollectionView;
|
|
indexPaths: NSSet;
|
|
highlightState: NSCollectionViewItemHighlightState): NSSet;
|
|
procedure collectionView_didChangeItemsAtIndexPaths_toHighlightState(
|
|
collectionView: NSCollectionView;
|
|
indexPaths: NSSet;
|
|
highlightState: NSCollectionViewItemHighlightState );
|
|
|
|
procedure collectionView_willDisplayItem_forRepresentedObjectAtIndexPath(
|
|
collectionView: NSCollectionView;
|
|
item:NSCollectionViewItem;
|
|
indexPath:NSIndexPath );
|
|
procedure collectionView_didEndDisplayingItem_forRepresentedObjectAtIndexPath(
|
|
collectionView: NSCollectionView;
|
|
item:NSCollectionViewItem;
|
|
indexPath:NSIndexPath );
|
|
|
|
function collectionView_shouldSelectItemsAtIndexPaths(
|
|
collectionView: NSCollectionView; indexPaths:NSSet ): NSSet;
|
|
message 'collectionView:shouldSelectItemsAtIndexPaths:';
|
|
procedure collectionView_didSelectItemsAtIndexPaths(
|
|
collectionView: NSCollectionView; indexPaths:NSSet );
|
|
message 'collectionView:didSelectItemsAtIndexPaths:';
|
|
function collectionView_shouldDeselectItemsAtIndexPaths(
|
|
collectionView: NSCollectionView; indexPaths:NSSet ): NSSet;
|
|
message 'collectionView:shouldDeselectItemsAtIndexPaths:';
|
|
procedure collectionView_didDeselectItemsAtIndexPaths(
|
|
collectionView: NSCollectionView; indexPaths:NSSet );
|
|
message 'collectionView:didDeselectItemsAtIndexPaths:';
|
|
|
|
procedure mouseDown(event: NSEvent); override;
|
|
procedure mouseUp(event: NSEvent); override;
|
|
procedure mouseMoved(event: NSEvent); override;
|
|
procedure mouseDragged(event: NSEvent); override;
|
|
end;
|
|
|
|
{ TCocoaWSListView_CollectionViewHandler }
|
|
|
|
TCocoaWSListView_CollectionViewHandler = class(TCocoaWSListViewHandler)
|
|
private
|
|
_listView: TCocoaListView;
|
|
_collectionView: TCocoaCollectionView;
|
|
private
|
|
function getCallback: TLCLListViewCallback;
|
|
public
|
|
constructor Create( listView: TCocoaListView );
|
|
public
|
|
// Column
|
|
procedure ColumnDelete( const AIndex: Integer ); override;
|
|
function ColumnGetWidth( const AIndex: Integer; const {%H-}AColumn: TListColumn): Integer; override;
|
|
procedure ColumnInsert( const AIndex: Integer; const AColumn: TListColumn); override;
|
|
procedure ColumnMove( const AOldIndex, ANewIndex: Integer; const AColumn: TListColumn); override;
|
|
procedure ColumnSetAlignment( const AIndex: Integer; const {%H-}AColumn: TListColumn; const AAlignment: TAlignment); override;
|
|
procedure ColumnSetAutoSize( const AIndex: Integer; const {%H-}AColumn: TListColumn; const AAutoSize: Boolean); override;
|
|
procedure ColumnSetCaption( const AIndex: Integer; const {%H-}AColumn: TListColumn; const ACaption: String); override;
|
|
procedure ColumnSetMaxWidth( const AIndex: Integer; const {%H-}AColumn: TListColumn; const AMaxWidth: Integer); override;
|
|
procedure ColumnSetMinWidth( const AIndex: Integer; const {%H-}AColumn: TListColumn; const AMinWidth: integer); override;
|
|
procedure ColumnSetWidth( const AIndex: Integer; const {%H-}AColumn: TListColumn; const AWidth: Integer); override;
|
|
procedure ColumnSetVisible( const AIndex: Integer; const {%H-}AColumn: TListColumn; const AVisible: Boolean); override;
|
|
procedure ColumnSetSortIndicator( const AIndex: Integer; const AColumn: TListColumn; const ASortIndicator: TSortIndicator); override;
|
|
|
|
// Item
|
|
procedure ItemDelete( const AIndex: Integer); override;
|
|
function ItemDisplayRect( const AIndex, ASubItem: Integer; ACode: TDisplayCode): TRect; override;
|
|
procedure ItemExchange(const ALV: TCustomListView; AItem: TListItem; const AIndex1, AIndex2: Integer); override;
|
|
function ItemGetPosition( const AIndex: Integer): TPoint; override;
|
|
function ItemGetState( const AIndex: Integer; const {%H-}AItem: TListItem; const AState: TListItemState; out AIsSet: Boolean): Boolean; override; // returns True if supported
|
|
procedure ItemInsert( const AIndex: Integer; const {%H-}AItem: TListItem); override;
|
|
procedure ItemSetChecked( const AIndex: Integer; const {%H-}AItem: TListItem; const AChecked: Boolean); override;
|
|
procedure ItemSetImage( const AIndex: Integer; const {%H-}AItem: TListItem; const {%H-}ASubIndex, {%H-}AImageIndex: Integer); override;
|
|
procedure ItemSetState( const AIndex: Integer; const {%H-}AItem: TListItem; const AState: TListItemState; const AIsSet: Boolean); override;
|
|
procedure ItemSetText( const AIndex: Integer; const {%H-}AItem: TListItem; const {%H-}ASubIndex: Integer; const {%H-}AText: String); override;
|
|
procedure ItemShow( const AIndex: Integer; const {%H-}AItem: TListItem; const PartialOK: Boolean); override;
|
|
|
|
function GetFocused: Integer; override;
|
|
function GetItemAt( x,y: integer): Integer; override;
|
|
function GetSelCount: Integer; override;
|
|
function GetSelection: Integer; override;
|
|
function GetTopItem: Integer; override;
|
|
function GetVisibleRowCount: Integer; override;
|
|
|
|
procedure SelectAll( const AIsSet: Boolean); override;
|
|
procedure SetDefaultItemHeight( const AValue: Integer); override;
|
|
procedure SetImageList( const {%H-}AList: TListViewImageList; const {%H-}AValue: TCustomImageListResolution); override;
|
|
procedure SetItemsCount( const Avalue: Integer); override;
|
|
procedure SetProperty( const AProp: TListViewProperty; const AIsSet: Boolean); override;
|
|
procedure SetScrollBars( const AValue: TScrollStyle); override;
|
|
procedure SetSort( const {%H-}AType: TSortType; const {%H-}AColumn: Integer;
|
|
const {%H-}ASortDirection: TSortDirection); override;
|
|
end;
|
|
|
|
function AllocCocoaCollectionView( style: TViewStyle ): TCocoaCollectionView;
|
|
function indexPathsWithOneIndex( cv: NSCollectionView; AIndex: Integer ): NSSet;
|
|
function realVisibleItems( cv: NSCollectionView ): NSArray;
|
|
|
|
implementation
|
|
|
|
type
|
|
{ TCocoaListView_CollectionView_LargeIconHandler }
|
|
TCocoaListView_CollectionView_LargeIconHandler = class(TCocoaListView_CollectionView_StyleHandler)
|
|
procedure resetSize; override;
|
|
procedure onUpdateItemSize( baseSize: NSSize ); override;
|
|
procedure onUpdateItemLayout( cocoaItem: TCocoaCollectionItem ); override;
|
|
procedure onAdjustTextEditor( lv: TCocoaListView; var aFrame: NSRect ); override;
|
|
end;
|
|
|
|
{ TCocoaListView_CollectionView_SmallIconHandler }
|
|
TCocoaListView_CollectionView_SmallIconHandler = class(TCocoaListView_CollectionView_StyleHandler)
|
|
procedure resetSize; override;
|
|
procedure onUpdateItemSize( baseSize: NSSize ); override;
|
|
procedure onUpdateItemLayout( cocoaItem: TCocoaCollectionItem ); override;
|
|
procedure onAdjustTextEditor( lv: TCocoaListView; var aFrame: NSRect ); override;
|
|
end;
|
|
|
|
{ TCocoaListView_CollectionView_ListHandler }
|
|
TCocoaListView_CollectionView_ListHandler = class(TCocoaListView_CollectionView_StyleHandler)
|
|
procedure resetSize; override;
|
|
function isSupportIcon: Boolean; override;
|
|
procedure onUpdateItemSize( baseSize: NSSize ); override;
|
|
procedure onUpdateItemLayout( cocoaItem: TCocoaCollectionItem ); override;
|
|
procedure onAdjustTextEditor( lv: TCocoaListView; var aFrame: NSRect ); override;
|
|
end;
|
|
|
|
function AllocCocoaCollectionView( style: TViewStyle ): TCocoaCollectionView;
|
|
var
|
|
styleHandler: TCocoaListView_CollectionView_StyleHandler;
|
|
begin
|
|
Result:= TCocoaCollectionView.new;
|
|
|
|
case style of
|
|
vsIcon:
|
|
styleHandler:= TCocoaListView_CollectionView_LargeIconHandler.Create( Result );
|
|
vsSmallIcon:
|
|
styleHandler:= TCocoaListView_CollectionView_SmallIconHandler.Create( Result );
|
|
vsList:
|
|
styleHandler:= TCocoaListView_CollectionView_ListHandler.Create( Result );
|
|
end;
|
|
|
|
Result.styleHandler:= styleHandler;
|
|
Result.setDataSource( Result );
|
|
Result.setDelegate( NSCollectionViewDelegateProtocol_1011(Result) );
|
|
Result.setCollectionViewLayout( NSCollectionViewFlowLayout.new.autorelease );
|
|
Result.registerClass_forItemWithIdentifier( TCocoaCollectionItem, NSSTR('Cell') );
|
|
Result.setSelectable( True );
|
|
end;
|
|
|
|
function indexPathsWithOneIndex( cv: NSCollectionView; AIndex: Integer ): NSSet;
|
|
var
|
|
indexPath: NSIndexPath;
|
|
begin
|
|
indexPath:= NSIndexPath.indexPathForItem_inSection( AIndex, 0 );
|
|
Result:= NSSet.setWithObject( indexPath );
|
|
end;
|
|
|
|
// get the Real Visible Items.
|
|
// NSCollectionView returns the items that have been displayed.
|
|
function realVisibleItems( cv: NSCollectionView ): NSArray;
|
|
var
|
|
visibleRect: NSRect;
|
|
item: NSCollectionViewItem;
|
|
items: NSMutableArray Absolute Result;
|
|
begin
|
|
Result:= NSMutableArray.new.autorelease;
|
|
visibleRect:= cv.visibleRect;
|
|
for item in cv.visibleItems do begin
|
|
if NSIntersectsRect( item.view.frame, visibleRect ) then
|
|
items.addObject( item );
|
|
end;
|
|
end;
|
|
|
|
{ TCocoaListView_CollectionView_StyleHandler }
|
|
|
|
constructor TCocoaListView_CollectionView_StyleHandler.Create(
|
|
collectionView: NSCollectionView);
|
|
begin
|
|
_collectionView:= collectionView;
|
|
end;
|
|
|
|
function TCocoaListView_CollectionView_StyleHandler.hasCheckBoxes: Boolean;
|
|
begin
|
|
Result:= TCocoaCollectionView(_collectionView).lclHasCheckBoxes;
|
|
end;
|
|
|
|
procedure TCocoaListView_CollectionView_StyleHandler.onInit;
|
|
begin
|
|
self.resetSize;
|
|
end;
|
|
|
|
function TCocoaListView_CollectionView_StyleHandler.isSupportIcon: Boolean;
|
|
begin
|
|
Result:= True;
|
|
end;
|
|
|
|
{ TCocoaListView_CollectionView_LargeIconHandler }
|
|
|
|
procedure TCocoaListView_CollectionView_LargeIconHandler.resetSize;
|
|
var
|
|
layout: NSCollectionViewFlowLayout;
|
|
minSize: NSSize;
|
|
begin
|
|
layout:= NSCollectionViewFlowLayout(_collectionView.collectionViewLayout);
|
|
minSize.width:= CocoaConfigListView.vsIcon.item.minSize.width;
|
|
minSize.height:= CocoaConfigListView.vsIcon.item.minSize.height;
|
|
|
|
if self.hasCheckBoxes then
|
|
minSize.width:= minSize.width +
|
|
CocoaConfigListView.vsIcon.item.checkBoxOccupiedWidth;
|
|
|
|
TCocoaCollectionView(_collectionView).itemSize:= minSize;
|
|
layout.setItemSize( minSize );
|
|
layout.setMinimumInteritemSpacing( CocoaConfigListView.vsIcon.interitemSpacing );
|
|
layout.setMinimumLineSpacing( CocoaConfigListView.vsIcon.lineSpacing );
|
|
end;
|
|
|
|
procedure TCocoaListView_CollectionView_LargeIconHandler.onUpdateItemSize(
|
|
baseSize: NSSize);
|
|
var
|
|
cv: TCocoaCollectionView;
|
|
begin
|
|
cv:= TCocoaCollectionView(_collectionView);
|
|
cv.iconSize:= baseSize;
|
|
if cv.iconSize.Width < CocoaConfigListView.vsIcon.imageView.minSize.width then
|
|
cv.iconSize.Width:= CocoaConfigListView.vsIcon.imageView.minSize.width;
|
|
if cv.iconSize.Height < CocoaConfigListView.vsIcon.imageView.minSize.height then
|
|
cv.iconSize.Height:= CocoaConfigListView.vsIcon.imageView.minSize.height;
|
|
|
|
cv.itemSize.Width:= cv.iconSize.Width +
|
|
CocoaConfigListView.vsIcon.imageView.padding * 2;
|
|
cv.itemSize.Height:= cv.iconSize.Height +
|
|
CocoaConfigListView.vsIcon.imageView.padding * 2 +
|
|
CocoaConfigListView.vsIcon.item.controlSpacing +
|
|
CocoaConfigListView.vsIcon.textField.defaultHeight;
|
|
if cv.itemSize.Width < CocoaConfigListView.vsIcon.item.minSize.width then
|
|
cv.itemSize.Width:= CocoaConfigListView.vsIcon.item.minSize.width;
|
|
if cv.itemSize.Height < CocoaConfigListView.vsIcon.item.minSize.height then
|
|
cv.itemSize.Height:= CocoaConfigListView.vsIcon.item.minSize.height;
|
|
|
|
if self.hasCheckBoxes then
|
|
cv.itemSize.Width:= cv.itemSize.Width +
|
|
CocoaConfigListView.vsIcon.item.checkBoxOccupiedWidth;
|
|
end;
|
|
|
|
procedure TCocoaListView_CollectionView_LargeIconHandler.onUpdateItemLayout(
|
|
cocoaItem: TCocoaCollectionItem);
|
|
var
|
|
cv: TCocoaCollectionView;
|
|
aFrame: NSRect;
|
|
textField: NSTextField;
|
|
imageView: NSImageView;
|
|
checkBox: NSButton;
|
|
begin
|
|
textField:= cocoaItem.textField;
|
|
imageView:= cocoaItem.imageView;
|
|
checkBox:= cocoaItem.checkBox;
|
|
cv:= TCocoaCollectionView(_collectionView);
|
|
|
|
aFrame.origin.x:= round( (cv.itemSize.Width - cv.iconSize.Width) / 2 );
|
|
aFrame.origin.y:= cv.itemSize.Height - cv.iconSize.Height -
|
|
CocoaConfigListView.vsIcon.imageView.padding;
|
|
aFrame.size:= cv.iconSize;
|
|
if Assigned(checkBox) then
|
|
aFrame.origin.x:= aFrame.origin.x +
|
|
CocoaConfigListView.vsIcon.item.checkBoxOccupiedWidth / 2;
|
|
imageView.setFrame( aFrame );
|
|
|
|
textField.sizeToFit;
|
|
aFrame.size.height:= textField.frame.size.height;
|
|
aFrame.origin.y:= round( (aFrame.origin.y-aFrame.size.height) / 2 );
|
|
aFrame.origin.x:= 0;
|
|
if Assigned(checkBox) then
|
|
aFrame.origin.x:= aFrame.origin.x + CocoaConfigListView.vsIcon.item.checkBoxOccupiedWidth;
|
|
aFrame.size.width:= cv.itemSize.Width - aFrame.origin.x;
|
|
textField.setFrame( aFrame );
|
|
textField.setAlignment( CocoaConfigListView.vsIcon.item.textFieldAlignment );
|
|
|
|
if Assigned(checkBox) then begin
|
|
checkBox.sizeToFit;
|
|
aFrame.size:= checkBox.frame.size;
|
|
aFrame.origin.x:= CocoaConfigListView.vsIcon.item.checkBoxOccupiedWidth -
|
|
checkBox.frame.size.width;
|
|
aFrame.origin.y:= round( (cv.itemSize.Height-aFrame.size.height) / 2 );
|
|
checkBox.setFrame( aFrame );
|
|
end;
|
|
end;
|
|
|
|
procedure TCocoaListView_CollectionView_LargeIconHandler.onAdjustTextEditor(
|
|
lv: TCocoaListView; var aFrame: NSRect );
|
|
var
|
|
offset: Double; // FocusRing Occupied
|
|
begin
|
|
lv.setCaptionAlignment( CocoaConfigListView.vsIcon.item.textFieldAlignment );
|
|
|
|
offset:= 1;
|
|
if NOT hasCheckBoxes then
|
|
offset:= offset + 1;
|
|
aFrame.origin.x:= aFrame.origin.x + offset;
|
|
aFrame.size.Width:= aFrame.size.Width - offset*2;
|
|
end;
|
|
|
|
{ TCocoaListView_CollectionView_SmallIconHandler }
|
|
|
|
procedure TCocoaListView_CollectionView_SmallIconHandler.resetSize;
|
|
var
|
|
layout: NSCollectionViewFlowLayout;
|
|
minSize: NSSize;
|
|
begin
|
|
layout:= NSCollectionViewFlowLayout(_collectionView.collectionViewLayout);
|
|
minSize.width:= CocoaConfigListView.vsSmallIcon.item.minSize.width;
|
|
minSize.height:= CocoaConfigListView.vsSmallIcon.item.minSize.height;
|
|
if self.hasCheckBoxes then
|
|
minSize.width:= minSize.width + CocoaConfigListView.vsSmallIcon.item.checkBoxOccupiedWidth;
|
|
|
|
TCocoaCollectionView(_collectionView).itemSize:= minSize;
|
|
layout.setItemSize( minSize );
|
|
layout.setMinimumInteritemSpacing( CocoaConfigListView.vsSmallIcon.interitemSpacing );
|
|
layout.setMinimumLineSpacing( CocoaConfigListView.vsSmallIcon.lineSpacing );
|
|
end;
|
|
|
|
procedure TCocoaListView_CollectionView_SmallIconHandler.onUpdateItemSize(
|
|
baseSize: NSSize);
|
|
var
|
|
cv: TCocoaCollectionView;
|
|
textWidth: CGFloat;
|
|
begin
|
|
cv:= TCocoaCollectionView(_collectionView);
|
|
cv.iconSize:= baseSize;
|
|
if cv.iconSize.Width < CocoaConfigListView.vsSmallIcon.imageView.minSize.width then
|
|
cv.iconSize.Width:= CocoaConfigListView.vsSmallIcon.imageView.minSize.width;
|
|
if cv.iconSize.Height < CocoaConfigListView.vsSmallIcon.imageView.minSize.height then
|
|
cv.iconSize.Height:= CocoaConfigListView.vsSmallIcon.imageView.minSize.height;
|
|
|
|
textWidth:= Round( cv.iconSize.Width *
|
|
CocoaConfigListView.vsSmallIcon.textField.iconWidthFactor +
|
|
CocoaConfigListView.vsSmallIcon.textField.baseWidth );
|
|
if textWidth < CocoaConfigListView.vsSmallIcon.textField.minWidth then
|
|
textWidth:= CocoaConfigListView.vsSmallIcon.textField.minWidth;
|
|
cv.itemSize.Width:= cv.iconSize.Width +
|
|
CocoaConfigListView.vsSmallIcon.item.controlSpacing +
|
|
textWidth +
|
|
CocoaConfigListView.vsSmallIcon.imageView.padding * 2;
|
|
cv.itemSize.Height:= cv.iconSize.Height +
|
|
CocoaConfigListView.vsSmallIcon.imageView.padding * 2;
|
|
if cv.itemSize.Height < CocoaConfigListView.vsSmallIcon.item.minSize.height then
|
|
cv.itemSize.Height:= CocoaConfigListView.vsSmallIcon.item.minSize.height;
|
|
|
|
if self.hasCheckBoxes then
|
|
cv.itemSize.width:= cv.itemSize.width +
|
|
CocoaConfigListView.vsSmallIcon.item.checkBoxOccupiedWidth;
|
|
end;
|
|
|
|
procedure TCocoaListView_CollectionView_SmallIconHandler.onUpdateItemLayout(
|
|
cocoaItem: TCocoaCollectionItem);
|
|
var
|
|
cv: TCocoaCollectionView;
|
|
aFrame: NSRect;
|
|
textField: NSTextField;
|
|
imageView: NSImageView;
|
|
checkBox: NSButton;
|
|
begin
|
|
textField:= cocoaItem.textField;
|
|
imageView:= cocoaItem.imageView;
|
|
checkBox:= cocoaItem.checkBox;
|
|
cv:= TCocoaCollectionView(_collectionView);
|
|
|
|
aFrame:= NSZeroRect;
|
|
|
|
if Assigned(checkBox) then begin
|
|
checkBox.sizeToFit;
|
|
aFrame.size:= checkBox.frame.size;
|
|
aFrame.origin.x:= CocoaConfigListView.vsSmallIcon.item.checkBoxOccupiedWidth -
|
|
checkBox.frame.size.width;
|
|
aFrame.origin.y:= round( (cv.itemSize.Height - aFrame.size.height ) / 2 );
|
|
checkBox.setFrame( aFrame );
|
|
end;
|
|
|
|
aFrame.origin.x:= aFrame.origin.x + aFrame.size.width +
|
|
CocoaConfigListView.vsSmallIcon.imageView.padding +
|
|
CocoaConfigListView.vsSmallIcon.item.controlSpacing;
|
|
aFrame.origin.y:= round( (cv.itemSize.Height - cv.iconSize.height) / 2 );
|
|
aFrame.size:= cv.iconSize;
|
|
imageView.setFrame( aFrame );
|
|
|
|
textField.sizeToFit;
|
|
aFrame.origin.x:= aFrame.origin.x + aFrame.size.width +
|
|
CocoaConfigListView.vsSmallIcon.item.controlSpacing;
|
|
aFrame.origin.y:= round( (cv.itemSize.Height - textField.frame.size.height) / 2 );
|
|
aFrame.size.width:= cv.itemSize.Width - aFrame.origin.x -
|
|
CocoaConfigListView.vsSmallIcon.item.controlSpacing;
|
|
aFrame.size.height:= textField.frame.size.height;
|
|
textField.setFrame( aFrame );
|
|
textField.setAlignment( CocoaConfigListView.vsSmallIcon.item.textFieldAlignment );
|
|
end;
|
|
|
|
procedure TCocoaListView_CollectionView_SmallIconHandler.onAdjustTextEditor(
|
|
lv: TCocoaListView; var aFrame: NSRect );
|
|
begin
|
|
lv.setCaptionAlignment( CocoaConfigListView.vsSmallIcon.item.textFieldAlignment );
|
|
end;
|
|
|
|
{ TCocoaListView_CollectionView_ListHandler }
|
|
|
|
procedure TCocoaListView_CollectionView_ListHandler.resetSize;
|
|
var
|
|
cv: TCocoaCollectionView;
|
|
layout: NSCollectionViewFlowLayout;
|
|
minSize: NSSize;
|
|
begin
|
|
layout:= NSCollectionViewFlowLayout(_collectionView.collectionViewLayout);
|
|
minSize.width:= CocoaConfigListView.vsList.item.minSize.width;
|
|
minSize.height:= CocoaConfigListView.vsList.item.minSize.height;
|
|
if self.hasCheckBoxes then
|
|
minSize.width:= minSize.width + CocoaConfigListView.vsList.item.checkBoxOccupiedWidth;
|
|
|
|
TCocoaCollectionView(_collectionView).itemSize:= minSize;
|
|
layout.setItemSize( minSize );
|
|
layout.setMinimumInteritemSpacing( CocoaConfigListView.vsList.interitemSpacing );
|
|
layout.setMinimumLineSpacing( CocoaConfigListView.vsList.lineSpacing );
|
|
|
|
layout.setScrollDirection( NSCollectionViewScrollDirectionHorizontal );
|
|
end;
|
|
|
|
function TCocoaListView_CollectionView_ListHandler.isSupportIcon: Boolean;
|
|
begin
|
|
Result:= False;
|
|
end;
|
|
|
|
procedure TCocoaListView_CollectionView_ListHandler.onUpdateItemSize(
|
|
baseSize: NSSize);
|
|
begin
|
|
end;
|
|
|
|
procedure TCocoaListView_CollectionView_ListHandler.onUpdateItemLayout(
|
|
cocoaItem: TCocoaCollectionItem);
|
|
var
|
|
cv: TCocoaCollectionView;
|
|
aFrame: NSRect;
|
|
textField: NSTextField;
|
|
checkBox: NSButton;
|
|
begin
|
|
textField:= cocoaItem.textField;
|
|
checkBox:= cocoaItem.checkBox;
|
|
cv:= TCocoaCollectionView(_collectionView);
|
|
|
|
aFrame:= NSZeroRect;
|
|
|
|
if Assigned(checkBox) then begin
|
|
checkBox.sizeToFit;
|
|
aFrame.size:= checkBox.frame.size;
|
|
aFrame.origin.x:= CocoaConfigListView.vsList.item.checkBoxOccupiedWidth -
|
|
checkBox.frame.size.width;
|
|
aFrame.origin.y:= round( (cv.itemSize.Height - aFrame.size.height ) / 2 );
|
|
checkBox.setFrame( aFrame );
|
|
end;
|
|
|
|
textField.sizeToFit;
|
|
aFrame.origin.x:= aFrame.origin.x + aFrame.size.width +
|
|
CocoaConfigListView.vsList.item.controlSpacing;
|
|
aFrame.origin.y:= round( (cv.itemSize.Height - textField.frame.size.height) / 2 );
|
|
aFrame.size.width:= cv.itemSize.Width - aFrame.origin.x -
|
|
CocoaConfigListView.vsList.item.controlSpacing;
|
|
aFrame.size.height:= textField.frame.size.height;
|
|
textField.setFrame( aFrame );
|
|
textField.setAlignment( CocoaConfigListView.vsList.item.textFieldAlignment );
|
|
end;
|
|
|
|
procedure TCocoaListView_CollectionView_ListHandler.onAdjustTextEditor(
|
|
lv: TCocoaListView; var aFrame: NSRect );
|
|
begin
|
|
lv.setCaptionAlignment( CocoaConfigListView.vsList.item.textFieldAlignment );
|
|
end;
|
|
|
|
{ TCocoaCollectionItem }
|
|
|
|
procedure TCocoaCollectionItem.createCheckBox;
|
|
begin
|
|
if NOT Assigned(_checkBox) then begin
|
|
_checkBox:= NSButton.alloc.init;
|
|
_checkBox.setHidden( True );
|
|
_checkBox.setButtonType( NSSwitchButton );
|
|
_checkBox.setTitle( CocoaConst.NSSTR_EMPTY );
|
|
_checkBox.setTarget( self );
|
|
_checkBox.setAction( ObjCSelector('checkboxAction:') );
|
|
self.View.addSubview( _checkBox );
|
|
end;
|
|
end;
|
|
|
|
procedure TCocoaCollectionItem.checkboxAction(sender: NSButton);
|
|
var
|
|
row: Integer;
|
|
cv: TCocoaCollectionView;
|
|
indexPath: NSIndexPath;
|
|
begin
|
|
cv:= TCocoaCollectionView( self.collectionView );
|
|
indexPath:= cv.indexPathForItem( self );
|
|
row:= indexPath.item;
|
|
cv.callback.SetItemCheckedAt( row, sender.state );
|
|
if sender.state = NSOnState then begin
|
|
cv.selectOneItemByIndex( row, True );
|
|
self.view.window.makeFirstResponder( self.collectionView );
|
|
end;
|
|
end;
|
|
|
|
procedure TCocoaCollectionItem.loadView;
|
|
var
|
|
itemView: TCocoaCollectionItemView;
|
|
fieldControl: NSTextField;
|
|
imageControl: NSImageView;
|
|
cell: NSTextFieldCell;
|
|
begin
|
|
itemView:= TCocoaCollectionItemView.alloc.initWithFrame( NSZeroRect);
|
|
itemView.item:= self;
|
|
|
|
imageControl:= NSImageView.alloc.initWithFrame( NSZeroRect );
|
|
imageControl.setImageScaling( NSImageScaleProportionallyUpOrDown );
|
|
self.setImageView( imageControl );
|
|
itemView.addSubview( imageControl );
|
|
|
|
fieldControl:= NSTextField.alloc.initWithFrame(NSZeroRect);
|
|
fieldControl.setBordered( False );
|
|
fieldControl.setDrawsBackground( False );
|
|
fieldControl.setEditable( False );
|
|
fieldControl.setLineBreakMode( NSLineBreakByTruncatingTail );
|
|
fieldControl.setBezeled( False );
|
|
cell := NSTextFieldCell(fieldControl.cell);
|
|
cell.setWraps(false);
|
|
cell.setScrollable(false);
|
|
self.setTextField( fieldControl );
|
|
itemView.addSubview( fieldControl );
|
|
|
|
self.setView( itemView );
|
|
end;
|
|
|
|
function TCocoaCollectionItem.checkBox: NSButton;
|
|
begin
|
|
Result:= _checkBox;
|
|
end;
|
|
|
|
procedure TCocoaCollectionItem.prepareForReuse;
|
|
begin
|
|
if Assigned(_checkBox) then begin
|
|
_checkBox.removeFromSuperview;
|
|
_checkBox.release;
|
|
_checkBox:= nil;
|
|
end;
|
|
|
|
self.imageView.setImage( nil );
|
|
self.view.removeFromSuperview;
|
|
end;
|
|
|
|
procedure TCocoaCollectionItem.dealloc;
|
|
begin
|
|
self.imageView.removeFromSuperview;
|
|
self.imageView.release;
|
|
|
|
self.textField.removeFromSuperview;
|
|
self.textField.release;
|
|
|
|
if Assigned(_checkBox) then begin
|
|
_checkBox.removeFromSuperview;
|
|
_checkBox.release;
|
|
end;
|
|
|
|
self.view.removeFromSuperview;
|
|
self.view.release;
|
|
inherited dealloc;
|
|
end;
|
|
|
|
{ TCocoaCollectionItemView }
|
|
|
|
procedure TCocoaCollectionItemView.updateTrackingAreas;
|
|
const
|
|
options: NSTrackingAreaOptions = NSTrackingMouseEnteredAndExited
|
|
or NSTrackingActiveAlways;
|
|
begin
|
|
if Assigned(self.trackingArea) then begin
|
|
removeTrackingArea(self.trackingArea);
|
|
self.trackingArea.release;
|
|
end;
|
|
|
|
self.trackingArea:= NSTrackingArea.alloc.initWithRect_options_owner_userInfo(
|
|
self.bounds,
|
|
options,
|
|
self,
|
|
nil );
|
|
self.addTrackingArea( self.trackingArea );
|
|
end;
|
|
|
|
procedure TCocoaCollectionItemView.mouseEntered(theEvent: NSEvent);
|
|
begin
|
|
if Assigned(self.item.checkBox) then
|
|
self.item.checkBox.setHidden( False );
|
|
end;
|
|
|
|
procedure TCocoaCollectionItemView.mouseExited(theEvent: NSEvent);
|
|
var
|
|
checkBox: NSButton;
|
|
begin
|
|
checkBox:= self.item.checkBox;
|
|
if NOT Assigned(checkBox) then
|
|
Exit;
|
|
if checkBox.state = NSOnState then
|
|
Exit;
|
|
if self.item.isSelected then
|
|
Exit;
|
|
checkBox.setHidden( True );
|
|
end;
|
|
|
|
procedure TCocoaCollectionItemView.drawRect(dirtyRect: NSRect);
|
|
begin
|
|
inherited;
|
|
if self.item.isSelected then begin
|
|
NSColor.selectedControlColor.set_;
|
|
NSRectFill( dirtyRect );
|
|
end;
|
|
end;
|
|
|
|
{ TCocoaCollectionView }
|
|
|
|
procedure TCocoaCollectionView.lclSetCheckBoxes(checkBoxes: Boolean);
|
|
begin
|
|
if _checkBoxes = checkBoxes then
|
|
Exit;
|
|
|
|
_checkBoxes:= checkBoxes;
|
|
self.styleHandler.resetSize;
|
|
self.updateItemSize( self.iconSize );
|
|
self.reloadData;
|
|
end;
|
|
|
|
function TCocoaCollectionView.lclHasCheckBoxes: Boolean;
|
|
begin
|
|
Result:= _checkBoxes;
|
|
end;
|
|
|
|
function TCocoaCollectionView.lclGetCallback: ICommonCallback;
|
|
begin
|
|
Result:= callback;
|
|
end;
|
|
|
|
procedure TCocoaCollectionView.lclClearCallback;
|
|
begin
|
|
callback:= nil;
|
|
end;
|
|
|
|
procedure TCocoaCollectionView.lclExpectedKeys(var wantTabs, wantKeys,
|
|
wantReturn, wantAllKeys: Boolean);
|
|
begin
|
|
wantTabs := false;
|
|
wantKeys := true;
|
|
wantReturn := false; // todo: this should be "true" for editting purposes.
|
|
// or false, to let LCL handle editting
|
|
wantAllKeys := false;
|
|
end;
|
|
|
|
procedure TCocoaCollectionView.backend_setCallback(cb: TLCLListViewCallback);
|
|
begin
|
|
self.callback:= cb;
|
|
end;
|
|
|
|
procedure TCocoaCollectionView.backend_reloadData;
|
|
begin
|
|
self.reloadData;
|
|
end;
|
|
|
|
procedure TCocoaCollectionView.backend_onInit;
|
|
begin
|
|
self.styleHandler.onInit;
|
|
end;
|
|
|
|
procedure TCocoaCollectionView.dealloc;
|
|
begin
|
|
inherited dealloc;
|
|
FreeAndNil( self.styleHandler );
|
|
end;
|
|
|
|
procedure TCocoaCollectionView.addSubview(aView: NSView);
|
|
var
|
|
textField: TCocoaTextField Absolute aView;
|
|
begin
|
|
inherited;
|
|
if NOT aView.isKindOfClass(TCocoaTextField) then
|
|
Exit;
|
|
if NOT Assigned(self.callback) then
|
|
Exit;
|
|
TCocoaListView(self.callback.Owner).setCaptionEditor( textField );
|
|
end;
|
|
|
|
procedure TCocoaCollectionView.updateItemValue(
|
|
indexPath:NSIndexPath; cocoaItem: TCocoaCollectionItem );
|
|
var
|
|
row: Integer;
|
|
checkBox: NSButton;
|
|
checkedValue: Integer;
|
|
cocoaImage: NSImage;
|
|
lclImageIndex: Integer;
|
|
lclText: String;
|
|
isSelected: Boolean;
|
|
begin
|
|
if NOT Assigned(self.callback) then
|
|
Exit;
|
|
|
|
row:= indexPath.item;
|
|
|
|
isSelected:= self.callback.getItemStableSelection( row );
|
|
cocoaItem.setSelected( isSelected );
|
|
|
|
if _checkBoxes then
|
|
cocoaItem.createCheckBox;
|
|
checkBox:= cocoaItem.checkBox;
|
|
if Assigned(checkBox) then begin
|
|
self.callback.GetItemCheckedAt( row, checkedValue{%H-} );
|
|
checkBox.setState( checkedValue );
|
|
checkBox.setHidden( NOT ((checkedValue=NSOnState) or isSelected) );
|
|
end;
|
|
|
|
if self.styleHandler.isSupportIcon then begin
|
|
self.callback.GetItemImageAt( row, 0, lclImageIndex{%H-} );
|
|
cocoaImage:= self.callback.GetImageFromIndex( lclImageIndex );
|
|
cocoaItem.imageView.setImage( cocoaImage );
|
|
end;
|
|
|
|
self.callback.GetItemTextAt( row, 0, lclText{%H-} );
|
|
cocoaItem.textField.setStringValue( StrToNSString(lclText) );
|
|
end;
|
|
|
|
procedure TCocoaCollectionView.updateItemSize( baseSize: NSSize );
|
|
begin
|
|
self.styleHandler.onUpdateItemSize( baseSize );
|
|
NSCollectionViewFlowLayout(self.collectionViewLayout).setItemSize( self.itemSize );
|
|
end;
|
|
|
|
procedure TCocoaCollectionView.updateItemLayout(item: TCocoaCollectionItem);
|
|
begin
|
|
self.styleHandler.onUpdateItemLayout( item );
|
|
end;
|
|
|
|
procedure TCocoaCollectionView.redrawVisibleItems;
|
|
var
|
|
item: NSCollectionViewItem;
|
|
begin
|
|
for item in realVisibleItems(self) do begin
|
|
item.view.setNeedsDisplay_( True );
|
|
end;
|
|
end;
|
|
|
|
procedure TCocoaCollectionView.restoreFromStableSelection;
|
|
begin
|
|
if Assigned(self.callback) then
|
|
self.setSelectionIndexes( self.callback.selectionIndexSet );
|
|
end;
|
|
|
|
procedure TCocoaCollectionView.reloadData;
|
|
begin
|
|
if NOT Assigned(self.callback) then
|
|
Exit;
|
|
|
|
if NOT TCocoaListView(self.callback.Owner).initializing then begin
|
|
inherited reloadData;
|
|
self.cancelPreviousPerformRequestsWithTarget_selector_object(
|
|
self, ObjcSelector('restoreFromStableSelection'), nil );
|
|
self.performSelector_withObject_afterDelay(
|
|
ObjcSelector('restoreFromStableSelection'), nil, 0 );
|
|
end;
|
|
end;
|
|
|
|
procedure TCocoaCollectionView.selectOneItemByIndex(
|
|
index: Integer; isSelected: Boolean );
|
|
var
|
|
indexPath: NSIndexPath;
|
|
indexPaths: NSSet;
|
|
begin
|
|
indexPath:= NSIndexPath.indexPathForItem_inSection( index, 0 );
|
|
indexPaths:= NSSet.setWithObject( indexPath );
|
|
|
|
if isSelected then begin
|
|
if NOT self.allowsMultipleSelection then begin
|
|
if NOT self.selectionIndexPaths.containsObject(indexPath) then begin
|
|
self.deselectAll( self );
|
|
self.collectionView_didDeselectItemsAtIndexPaths( self, self.selectionIndexPaths );
|
|
end;
|
|
end;
|
|
if NOT self.selectionIndexPaths.containsObject(indexPath) then begin
|
|
self.selectItemsAtIndexPaths_scrollPosition(
|
|
indexPaths, NSCollectionViewScrollPositionNone );
|
|
self.collectionView_didSelectItemsAtIndexPaths( self, indexPaths );
|
|
end;
|
|
end else begin
|
|
if self.selectionIndexPaths.containsObject(indexPath) then begin
|
|
self.deselectItemsAtIndexPaths( indexPaths );
|
|
self.collectionView_didDeselectItemsAtIndexPaths( self, indexPaths );
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TCocoaCollectionView.collectionView_numberOfItemsInSection(
|
|
collectionView: NSCollectionView; section: NSInteger): NSInteger;
|
|
begin
|
|
Result:= 0;
|
|
if Assigned(self.callback) then
|
|
Result:= self.callback.ItemsCount;
|
|
end;
|
|
|
|
function TCocoaCollectionView.collectionView_itemForRepresentedObjectAtIndexPath
|
|
(collectionView: NSCollectionView; indexPath: NSIndexPath
|
|
): NSCollectionViewItem;
|
|
var
|
|
item: TCocoaCollectionItem Absolute Result;
|
|
begin
|
|
Result:= collectionView.makeItemWithIdentifier_forIndexPath(
|
|
NSSTR('Cell'), indexPath );
|
|
self.updateItemValue( indexPath, item );
|
|
self.updateItemLayout( item );
|
|
end;
|
|
|
|
function TCocoaCollectionView.collectionView_shouldChangeItemsAtIndexPaths_toHighlightState
|
|
(collectionView: NSCollectionView; indexPaths: NSSet;
|
|
highlightState: NSCollectionViewItemHighlightState): NSSet;
|
|
begin
|
|
Result:= indexPaths;
|
|
end;
|
|
|
|
// don't remove
|
|
procedure TCocoaCollectionView.collectionView_didChangeItemsAtIndexPaths_toHighlightState
|
|
(collectionView: NSCollectionView; indexPaths: NSSet;
|
|
highlightState: NSCollectionViewItemHighlightState);
|
|
begin
|
|
end;
|
|
|
|
// don't remove
|
|
procedure TCocoaCollectionView.collectionView_willDisplayItem_forRepresentedObjectAtIndexPath
|
|
(collectionView: NSCollectionView; item: NSCollectionViewItem;
|
|
indexPath: NSIndexPath);
|
|
begin
|
|
end;
|
|
|
|
// don't remove
|
|
procedure TCocoaCollectionView.collectionView_didEndDisplayingItem_forRepresentedObjectAtIndexPath
|
|
(collectionView: NSCollectionView; item: NSCollectionViewItem;
|
|
indexPath: NSIndexPath);
|
|
begin
|
|
end;
|
|
|
|
// don't remove
|
|
function TCocoaCollectionView.collectionView_shouldSelectItemsAtIndexPaths(
|
|
collectionView: NSCollectionView; indexPaths: NSSet): NSSet;
|
|
begin
|
|
Result:= indexPaths;
|
|
end;
|
|
|
|
procedure TCocoaCollectionView.collectionView_didSelectItemsAtIndexPaths(
|
|
collectionView: NSCollectionView; indexPaths: NSSet);
|
|
var
|
|
indexPath: NSIndexPath;
|
|
item: TCocoaCollectionItem;
|
|
begin
|
|
for indexPath in indexPaths do begin
|
|
item:= TCocoaCollectionItem( self.itemAtIndexPath(indexPath) );
|
|
if Assigned(item) then begin
|
|
item.setSelected( True );
|
|
item.textField.setToolTip( item.textField.stringValue );
|
|
if Assigned(item.checkBox) then
|
|
item.checkBox.setHidden( False );
|
|
item.view.setNeedsDisplay_(True);
|
|
end;
|
|
if Assigned(self.callback) then
|
|
self.callback.selectOne( indexPath.item, True );
|
|
end;
|
|
end;
|
|
|
|
function TCocoaCollectionView.collectionView_shouldDeselectItemsAtIndexPaths(
|
|
collectionView: NSCollectionView; indexPaths: NSSet): NSSet;
|
|
begin
|
|
Result:= indexPaths;
|
|
end;
|
|
|
|
procedure TCocoaCollectionView.collectionView_didDeselectItemsAtIndexPaths(
|
|
collectionView: NSCollectionView; indexPaths: NSSet);
|
|
var
|
|
indexPath: NSIndexPath;
|
|
item: TCocoaCollectionItem;
|
|
begin
|
|
for indexPath in indexPaths do begin
|
|
item:= TCocoaCollectionItem( self.itemAtIndexPath(indexPath) );
|
|
if Assigned(item) then begin
|
|
item.setSelected( False );
|
|
item.textField.setToolTip( nil );
|
|
if Assigned(item.checkBox) then
|
|
item.checkBox.setHidden( item.checkBox.state<>NSOnState );
|
|
item.view.setNeedsDisplay_(True);
|
|
end;
|
|
if Assigned(self.callback) then
|
|
self.callback.selectOne( indexPath.item, False );
|
|
end;
|
|
end;
|
|
|
|
procedure TCocoaCollectionView.mouseDown(event: NSEvent);
|
|
begin
|
|
if not Assigned(callback) or not callback.MouseUpDownEvent(event) then
|
|
inherited mouseDown(event);
|
|
end;
|
|
|
|
procedure TCocoaCollectionView.mouseUp(event: NSEvent);
|
|
begin
|
|
if Assigned(callback) and not callback.MouseUpDownEvent(event) then
|
|
inherited mouseUp(event);
|
|
end;
|
|
|
|
procedure TCocoaCollectionView.mouseMoved(event: NSEvent);
|
|
begin
|
|
if not Assigned(callback) or not callback.MouseMove(event) then
|
|
inherited mouseMoved(event);
|
|
end;
|
|
|
|
procedure TCocoaCollectionView.mouseDragged(event: NSEvent);
|
|
begin
|
|
if not Assigned(callback) or not callback.MouseMove(event) then
|
|
inherited mouseDragged(event);
|
|
end;
|
|
|
|
{ TCocoaWSListView_CollectionViewHandler }
|
|
|
|
constructor TCocoaWSListView_CollectionViewHandler.Create(
|
|
listView: TCocoaListView );
|
|
begin
|
|
_listView:= listView;
|
|
_collectionView:= TCocoaCollectionView(listView.documentView);
|
|
end;
|
|
|
|
function TCocoaWSListView_CollectionViewHandler.getCallback: TLCLListViewCallback;
|
|
begin
|
|
Result:= _collectionView.callback;
|
|
end;
|
|
|
|
procedure TCocoaWSListView_CollectionViewHandler.ColumnDelete(
|
|
const AIndex: Integer);
|
|
begin
|
|
end;
|
|
|
|
function TCocoaWSListView_CollectionViewHandler.ColumnGetWidth(
|
|
const AIndex: Integer; const AColumn: TListColumn): Integer;
|
|
begin
|
|
Result:= -1;
|
|
end;
|
|
|
|
procedure TCocoaWSListView_CollectionViewHandler.ColumnInsert(
|
|
const AIndex: Integer; const AColumn: TListColumn);
|
|
begin
|
|
end;
|
|
|
|
procedure TCocoaWSListView_CollectionViewHandler.ColumnMove(const AOldIndex,
|
|
ANewIndex: Integer; const AColumn: TListColumn);
|
|
begin
|
|
end;
|
|
|
|
procedure TCocoaWSListView_CollectionViewHandler.ColumnSetAlignment(
|
|
const AIndex: Integer; const AColumn: TListColumn;
|
|
const AAlignment: TAlignment);
|
|
begin
|
|
end;
|
|
|
|
procedure TCocoaWSListView_CollectionViewHandler.ColumnSetAutoSize(
|
|
const AIndex: Integer; const AColumn: TListColumn; const AAutoSize: Boolean);
|
|
begin
|
|
end;
|
|
|
|
procedure TCocoaWSListView_CollectionViewHandler.ColumnSetCaption(
|
|
const AIndex: Integer; const AColumn: TListColumn; const ACaption: String);
|
|
begin
|
|
end;
|
|
|
|
procedure TCocoaWSListView_CollectionViewHandler.ColumnSetMaxWidth(
|
|
const AIndex: Integer; const AColumn: TListColumn; const AMaxWidth: Integer);
|
|
begin
|
|
end;
|
|
|
|
procedure TCocoaWSListView_CollectionViewHandler.ColumnSetMinWidth(
|
|
const AIndex: Integer; const AColumn: TListColumn; const AMinWidth: integer);
|
|
begin
|
|
end;
|
|
|
|
procedure TCocoaWSListView_CollectionViewHandler.ColumnSetWidth(
|
|
const AIndex: Integer; const AColumn: TListColumn; const AWidth: Integer);
|
|
begin
|
|
end;
|
|
|
|
procedure TCocoaWSListView_CollectionViewHandler.ColumnSetVisible(
|
|
const AIndex: Integer; const AColumn: TListColumn; const AVisible: Boolean);
|
|
begin
|
|
end;
|
|
|
|
procedure TCocoaWSListView_CollectionViewHandler.ColumnSetSortIndicator(
|
|
const AIndex: Integer; const AColumn: TListColumn;
|
|
const ASortIndicator: TSortIndicator);
|
|
begin
|
|
end;
|
|
|
|
// when LCL call ItemDelete, the Item isn't Deleted at LCL
|
|
// delayed reload is necessary
|
|
procedure TCocoaWSListView_CollectionViewHandler.ItemDelete(
|
|
const AIndex: Integer);
|
|
begin
|
|
_collectionView.reloadData;
|
|
end;
|
|
|
|
function TCocoaWSListView_CollectionViewHandler.ItemDisplayRect(const AIndex,
|
|
ASubItem: Integer; ACode: TDisplayCode): TRect;
|
|
var
|
|
item: NSCollectionViewItem;
|
|
frame: NSRect;
|
|
begin
|
|
Result:= Bounds(0,0,0,0);
|
|
item:= _collectionView.itemAtIndex( AIndex );
|
|
if NOT Assigned(item) then
|
|
Exit;
|
|
|
|
frame:= item.view.frame;
|
|
case ACode of
|
|
drLabel:
|
|
begin
|
|
_listView.setCaptionFont( item.textField.font );
|
|
// to do: completely restore TFont
|
|
_listView.getLCLControlCanvas.Font.Height:= Round(item.textField.font.pointSize);
|
|
frame:= item.textField.frame;
|
|
frame:= item.view.convertRect_toView( frame, _collectionView );
|
|
_collectionView.styleHandler.onAdjustTextEditor( _listView, frame );
|
|
end;
|
|
drIcon:
|
|
begin
|
|
frame:= item.imageView.frame;
|
|
frame:= item.view.convertRect_toView( frame, _collectionView );
|
|
end
|
|
end;
|
|
|
|
Result:= NSRectToRect( frame );
|
|
end;
|
|
|
|
procedure TCocoaWSListView_CollectionViewHandler.ItemExchange(
|
|
const ALV: TCustomListView; AItem: TListItem; const AIndex1, AIndex2: Integer
|
|
);
|
|
begin
|
|
// not supported yet
|
|
end;
|
|
|
|
function TCocoaWSListView_CollectionViewHandler.ItemGetPosition(
|
|
const AIndex: Integer): TPoint;
|
|
var
|
|
rect: TRect;
|
|
begin
|
|
rect:= self.ItemDisplayRect( AIndex, 0, drBounds );
|
|
Result:= rect.TopLeft;
|
|
end;
|
|
|
|
function TCocoaWSListView_CollectionViewHandler.ItemGetState(
|
|
const AIndex: Integer; const AItem: TListItem; const AState: TListItemState;
|
|
out AIsSet: Boolean): Boolean;
|
|
var
|
|
lclcb : TLCLListViewCallback;
|
|
begin
|
|
Result:= false;
|
|
lclcb:= getCallback;
|
|
if NOT Assigned(lclcb) then
|
|
Exit;
|
|
|
|
case AState of
|
|
lisSelected: begin
|
|
Result:= (AIndex>=0) and (AIndex < _collectionView.numberOfItemsInSection(0));
|
|
AIsSet:= lclcb.getItemStableSelection( AIndex );
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TCocoaWSListView_CollectionViewHandler.ItemInsert(
|
|
const AIndex: Integer; const AItem: TListItem);
|
|
var
|
|
lclcb: TLCLListViewCallback;
|
|
begin
|
|
lclcb:= self.getCallback;
|
|
if NOT Assigned(lclcb) then
|
|
Exit;
|
|
|
|
if TCocoaListView(lclcb.Owner).initializing then
|
|
Exit;
|
|
|
|
lclcb.selectionIndexSet.shiftIndexesStartingAtIndex_by( AIndex, 1 );
|
|
_collectionView.reloadData;
|
|
end;
|
|
|
|
procedure TCocoaWSListView_CollectionViewHandler.ItemSetChecked(
|
|
const AIndex: Integer; const AItem: TListItem; const AChecked: Boolean);
|
|
begin
|
|
_collectionView.reloadData;
|
|
end;
|
|
|
|
procedure TCocoaWSListView_CollectionViewHandler.ItemSetImage(
|
|
const AIndex: Integer; const AItem: TListItem; const ASubIndex,
|
|
AImageIndex: Integer);
|
|
begin
|
|
_collectionView.reloadData;
|
|
end;
|
|
|
|
procedure TCocoaWSListView_CollectionViewHandler.ItemSetState(
|
|
const AIndex: Integer; const AItem: TListItem; const AState: TListItemState;
|
|
const AIsSet: Boolean);
|
|
var
|
|
lclcb: TLCLListViewCallback;
|
|
begin
|
|
lclcb:= self.getCallback;
|
|
if NOT Assigned(lclcb) then
|
|
Exit;
|
|
|
|
case AState of
|
|
lisFocused,
|
|
lisSelected: begin
|
|
if lclcb.getItemStableSelection(AIndex) <> AIsSet then begin
|
|
_collectionView.selectOneItemByIndex( AIndex, AIsSet );
|
|
_collectionView.redrawVisibleItems;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TCocoaWSListView_CollectionViewHandler.ItemSetText(
|
|
const AIndex: Integer; const AItem: TListItem; const ASubIndex: Integer;
|
|
const AText: String);
|
|
begin
|
|
_collectionView.reloadData;
|
|
end;
|
|
|
|
procedure TCocoaWSListView_CollectionViewHandler.ItemShow(
|
|
const AIndex: Integer; const AItem: TListItem; const PartialOK: Boolean);
|
|
var
|
|
indexPaths: NSSet;
|
|
begin
|
|
indexPaths:= CocoaCollectionView.indexPathsWithOneIndex( _collectionView, AIndex );
|
|
_collectionView.scrollToItemsAtIndexPaths_scrollPosition(
|
|
indexPaths, NSCollectionViewScrollPositionTop );
|
|
end;
|
|
|
|
// what is the function?
|
|
// never be called ???
|
|
function TCocoaWSListView_CollectionViewHandler.GetFocused: Integer;
|
|
begin
|
|
Result:= self.GetSelection;
|
|
end;
|
|
|
|
function TCocoaWSListView_CollectionViewHandler.GetItemAt(x, y: integer
|
|
): Integer;
|
|
var
|
|
cocoaPoint: NSPoint;
|
|
indexPath: NSIndexPath;
|
|
begin
|
|
Result:= -1;
|
|
cocoaPoint.x:= x;
|
|
cocoaPoint.y:= y;
|
|
indexPath:= _collectionView.indexPathForItemAtPoint( cocoaPoint );
|
|
if Assigned(indexPath) then
|
|
Result:= indexPath.item;
|
|
end;
|
|
|
|
function TCocoaWSListView_CollectionViewHandler.GetSelCount: Integer;
|
|
begin
|
|
Result:= _collectionView.selectionIndexPaths.count;
|
|
end;
|
|
|
|
function TCocoaWSListView_CollectionViewHandler.GetSelection: Integer;
|
|
var
|
|
lclListView: TCustomListView;
|
|
lclItem: TListItem;
|
|
begin
|
|
Result:= -1;
|
|
lclListView:= TCustomListView(_collectionView.lclGetTarget);
|
|
if Assigned(lclListView) then begin
|
|
lclItem:= lclListView.LastSelected;
|
|
if Assigned(lclItem) then
|
|
Result:= lclItem.Index;
|
|
end;
|
|
end;
|
|
|
|
function TCocoaWSListView_CollectionViewHandler.GetTopItem: Integer;
|
|
var
|
|
items: NSArray;
|
|
item: NSCollectionViewItem;
|
|
begin
|
|
Result:= -1;
|
|
items:= CocoaCollectionView.realVisibleItems( _collectionView );
|
|
if items.count > 0 then begin
|
|
item:= NSCollectionViewItem(items.firstObject);
|
|
Result:= _collectionView.indexPathForItem(item).item;
|
|
end;
|
|
end;
|
|
|
|
function TCocoaWSListView_CollectionViewHandler.GetVisibleRowCount: Integer;
|
|
begin
|
|
Result:= CocoaCollectionView.realVisibleItems(_collectionView).count;
|
|
end;
|
|
|
|
procedure TCocoaWSListView_CollectionViewHandler.SelectAll(const AIsSet: Boolean
|
|
);
|
|
begin
|
|
if AIsSet then
|
|
_collectionView.selectAll( _collectionView )
|
|
else
|
|
_collectionView.deselectAll( _collectionView );
|
|
end;
|
|
|
|
procedure TCocoaWSListView_CollectionViewHandler.SetDefaultItemHeight(
|
|
const AValue: Integer);
|
|
begin
|
|
end;
|
|
|
|
procedure TCocoaWSListView_CollectionViewHandler.SetImageList(
|
|
const AList: TListViewImageList; const AValue: TCustomImageListResolution);
|
|
var
|
|
lclcb: TLCLListViewCallback;
|
|
lvil: TListViewImageList;
|
|
iconSize: NSSize;
|
|
begin
|
|
lclcb:= getCallback;
|
|
if NOT Assigned(lclcb) then
|
|
Exit;
|
|
|
|
if NOT lclcb.GetImageListType(lvil) then
|
|
Exit;
|
|
|
|
if AList <> lvil then
|
|
Exit;
|
|
|
|
iconSize.Width:= AValue.Width;
|
|
iconSize.Height:= AValue.Height;
|
|
_collectionView.updateItemSize( iconSize );
|
|
end;
|
|
|
|
procedure TCocoaWSListView_CollectionViewHandler.SetItemsCount(
|
|
const Avalue: Integer);
|
|
begin
|
|
_collectionView.reloadData;
|
|
end;
|
|
|
|
procedure TCocoaWSListView_CollectionViewHandler.SetProperty(
|
|
const AProp: TListViewProperty; const AIsSet: Boolean);
|
|
var
|
|
lclListView: TCustomListView;
|
|
index: Integer;
|
|
begin
|
|
case AProp of
|
|
{lvpAutoArrange,}
|
|
lvpCheckboxes: _collectionView.lclSetCheckBoxes(AIsSet);
|
|
{lvpHideSelection,
|
|
lvpHotTrack,}
|
|
lvpMultiSelect: begin
|
|
_collectionView.setAllowsMultipleSelection( AIsSet );
|
|
if NOT AIsSet and (_collectionView.selectionIndexPaths.count>1) then begin
|
|
lclListView:= TCustomListView( _listView.lclGetTarget );
|
|
if Assigned(lclListView.ItemFocused) then begin
|
|
index:= lclListView.ItemFocused.Index;
|
|
_collectionView.deselectAll( nil );
|
|
_collectionView.selectOneItemByIndex( index, True );
|
|
end;
|
|
end;
|
|
end;
|
|
{lvpOwnerDraw,
|
|
lvpReadOnly:
|
|
lvpShowWorkAreas,
|
|
lvpWrapText,
|
|
lvpToolTips}
|
|
end;
|
|
end;
|
|
|
|
// scrollBars auto handled by NSCollectionView
|
|
procedure TCocoaWSListView_CollectionViewHandler.SetScrollBars(
|
|
const AValue: TScrollStyle);
|
|
begin
|
|
end;
|
|
|
|
procedure TCocoaWSListView_CollectionViewHandler.SetSort(
|
|
const AType: TSortType; const AColumn: Integer;
|
|
const ASortDirection: TSortDirection);
|
|
begin
|
|
_collectionView.reloadData();
|
|
end;
|
|
|
|
end.
|