mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-27 00:03:48 +02:00
584 lines
19 KiB
ObjectPascal
584 lines
19 KiB
ObjectPascal
unit CocoaListView;
|
|
|
|
{$mode delphi}
|
|
{$modeswitch objectivec2}
|
|
{$include cocoadefines.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
// RTL, FCL, LCL
|
|
MacOSAll, CocoaAll,
|
|
Classes, LCLType, SysUtils, LCLMessageGlue, LMessages,
|
|
Controls, ComCtrls, Types, StdCtrls, LCLProc, Graphics, ImgList, Forms,
|
|
// Cocoa WS
|
|
CocoaPrivate, CocoaCallback, CocoaScrollers, CocoaWSScrollers,
|
|
CocoaWSCommon, cocoa_extra, CocoaGDIObjects;
|
|
|
|
type
|
|
{ TLCLListViewCallback }
|
|
|
|
TLCLListViewCallback = class(TLCLCommonCallback, IListViewCallback)
|
|
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(ARow, ACol: 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(ARow, ACol: Integer; IsChecked: Integer);
|
|
function getItemStableSelection(ARow: Integer): Boolean;
|
|
procedure selectOne(ARow: Integer; isSelected:Boolean );
|
|
function shouldSelectionChange(NewSel: Integer): Boolean;
|
|
procedure ColumnClicked(ACol: Integer);
|
|
procedure DrawRow(rowidx: Integer; ctx: TCocoaContext; const r: TRect;
|
|
state: TOwnerDrawState);
|
|
procedure GetRowHeight(rowidx: Integer; var h: Integer);
|
|
function GetBorderStyle: TBorderStyle;
|
|
procedure callTargetInitializeWnd;
|
|
end;
|
|
TLCLListViewCallBackClass = class of TLCLListViewCallback;
|
|
|
|
{ TCocoaWSListViewHandler }
|
|
|
|
TCocoaWSListViewHandler = class
|
|
public
|
|
// Column
|
|
procedure ColumnDelete( const AIndex: Integer ); virtual; abstract;
|
|
function ColumnGetWidth( const AIndex: Integer; const {%H-}AColumn: TListColumn): Integer; virtual; abstract;
|
|
procedure ColumnInsert( const AIndex: Integer; const AColumn: TListColumn); virtual; abstract;
|
|
procedure ColumnMove( const AOldIndex, ANewIndex: Integer; const AColumn: TListColumn); virtual; abstract;
|
|
procedure ColumnSetAlignment( const AIndex: Integer; const {%H-}AColumn: TListColumn; const AAlignment: TAlignment); virtual; abstract;
|
|
procedure ColumnSetAutoSize( const AIndex: Integer; const {%H-}AColumn: TListColumn; const AAutoSize: Boolean); virtual; abstract;
|
|
procedure ColumnSetCaption( const AIndex: Integer; const {%H-}AColumn: TListColumn; const ACaption: String); virtual; abstract;
|
|
procedure ColumnSetMaxWidth( const AIndex: Integer; const {%H-}AColumn: TListColumn; const AMaxWidth: Integer); virtual; abstract;
|
|
procedure ColumnSetMinWidth( const AIndex: Integer; const {%H-}AColumn: TListColumn; const AMinWidth: integer); virtual; abstract;
|
|
procedure ColumnSetWidth( const AIndex: Integer; const {%H-}AColumn: TListColumn; const AWidth: Integer); virtual; abstract;
|
|
procedure ColumnSetVisible( const AIndex: Integer; const {%H-}AColumn: TListColumn; const AVisible: Boolean); virtual; abstract;
|
|
procedure ColumnSetSortIndicator( const AIndex: Integer; const AColumn: TListColumn; const ASortIndicator: TSortIndicator); virtual; abstract;
|
|
|
|
// Item
|
|
procedure ItemDelete( const AIndex: Integer); virtual; abstract;
|
|
function ItemDisplayRect( const AIndex, ASubItem: Integer; ACode: TDisplayCode): TRect; virtual; abstract;
|
|
function ItemGetPosition( const AIndex: Integer): TPoint; virtual; abstract;
|
|
function ItemGetState( const AIndex: Integer; const {%H-}AItem: TListItem; const AState: TListItemState; out AIsSet: Boolean): Boolean; virtual; abstract; // returns True if supported
|
|
procedure ItemInsert( const AIndex: Integer; const {%H-}AItem: TListItem); virtual; abstract;
|
|
procedure ItemSetChecked( const AIndex: Integer; const {%H-}AItem: TListItem; const AChecked: Boolean); virtual; abstract;
|
|
procedure ItemSetImage( const AIndex: Integer; const {%H-}AItem: TListItem; const {%H-}ASubIndex, {%H-}AImageIndex: Integer); virtual; abstract;
|
|
procedure ItemSetState( const AIndex: Integer; const {%H-}AItem: TListItem; const AState: TListItemState; const AIsSet: Boolean); virtual; abstract;
|
|
procedure ItemSetText( const AIndex: Integer; const {%H-}AItem: TListItem; const {%H-}ASubIndex: Integer; const {%H-}AText: String); virtual; abstract;
|
|
procedure ItemShow( const AIndex: Integer; const {%H-}AItem: TListItem; const PartialOK: Boolean); virtual; abstract;
|
|
|
|
function GetFocused: Integer; virtual; abstract;
|
|
function GetItemAt( x,y: integer): Integer; virtual; abstract;
|
|
function GetSelCount: Integer; virtual; abstract;
|
|
function GetSelection: Integer; virtual; abstract;
|
|
function GetTopItem: Integer; virtual; abstract;
|
|
function GetVisibleRowCount: Integer; virtual; abstract;
|
|
|
|
procedure SelectAll( const AIsSet: Boolean); virtual; abstract;
|
|
procedure SetDefaultItemHeight( const AValue: Integer); virtual; abstract;
|
|
procedure SetImageList( const {%H-}AList: TListViewImageList; const {%H-}AValue: TCustomImageListResolution); virtual; abstract;
|
|
procedure SetItemsCount( const Avalue: Integer); virtual; abstract;
|
|
procedure SetProperty( const AProp: TListViewProperty; const AIsSet: Boolean); virtual; abstract;
|
|
procedure SetScrollBars( const AValue: TScrollStyle); virtual; abstract;
|
|
procedure SetSort( const {%H-}AType: TSortType; const {%H-}AColumn: Integer;
|
|
const {%H-}ASortDirection: TSortDirection); virtual; abstract;
|
|
end;
|
|
|
|
{ TCocoaListViewBackendControl }
|
|
TCocoaListViewBackendControlProtocol = objcprotocol
|
|
procedure backend_setCallback( cb: TLCLListViewCallback ); message 'backend_setCallback:';
|
|
procedure backend_reloadData; message 'backend_reloadData';
|
|
procedure backend_onInit; message 'backend_onInit';
|
|
end;
|
|
|
|
CocoaListViewAllocFunc = procedure (const listView: NSView; const viewStyle: TViewStyle; out backendControl: NSView; out WSHandler: TCocoaWSListViewHandler );
|
|
|
|
{ TCocoaListView }
|
|
|
|
TCocoaListView = objcclass(NSView)
|
|
private
|
|
_allocFunc: CocoaListViewAllocFunc;
|
|
_viewStyle: TViewStyle;
|
|
_scrollView: TCocoaScrollView;
|
|
_backendControl: NSView; // NSTableView or NSCollectionView
|
|
_WSHandler: TCocoaWSListViewHandler;
|
|
_needsCallLclInit: Boolean;
|
|
_initializing: Boolean;
|
|
private
|
|
procedure createControls; message 'createControls';
|
|
procedure releaseControls; message 'releaseControls';
|
|
procedure initData; message 'initData';
|
|
public
|
|
callback: TLCLListViewCallback;
|
|
function lclGetCallback: ICommonCallback; override;
|
|
procedure lclClearCallback; override;
|
|
function lclContentView: NSView; override;
|
|
public
|
|
class function alloc: id; override;
|
|
procedure dealloc; override;
|
|
public
|
|
procedure setAllocFunc( allocFunc: CocoaListViewAllocFunc ); message 'setAllocFunc:';
|
|
procedure setViewStyle( viewStyle: TViewStyle ); message 'setViewStyle:';
|
|
function documentView: NSView; message 'documentView';
|
|
function scrollView: TCocoaScrollView; message 'scrollView';
|
|
function WSHandler: TCocoaWSListViewHandler; message 'WSHandler';
|
|
function initializing: Boolean; message 'isinitializing';
|
|
end;
|
|
|
|
implementation
|
|
|
|
{ TCocoaListView }
|
|
type
|
|
TCustomListViewAccess = class(TCustomListView);
|
|
|
|
function TCocoaListView.documentView: NSView;
|
|
begin
|
|
Result:= _backendControl;
|
|
end;
|
|
|
|
function TCocoaListView.scrollView: TCocoaScrollView;
|
|
begin
|
|
Result:= _scrollView;
|
|
end;
|
|
|
|
function TCocoaListView.WSHandler: TCocoaWSListViewHandler;
|
|
begin
|
|
Result:= _WSHandler;
|
|
end;
|
|
|
|
function TCocoaListView.initializing: Boolean;
|
|
begin
|
|
Result:= _initializing;
|
|
end;
|
|
|
|
procedure TCocoaListView.setViewStyle(viewStyle: TViewStyle);
|
|
begin
|
|
if Assigned(_backendControl) and (_viewStyle=viewStyle) then
|
|
Exit;
|
|
|
|
_viewStyle:= viewStyle;
|
|
releaseControls;
|
|
createControls;
|
|
initData;
|
|
end;
|
|
|
|
procedure TCocoaListView.createControls;
|
|
var
|
|
controlFrame: NSRect;
|
|
backendControlAccess: TCocoaListViewBackendControlProtocol;
|
|
begin
|
|
_allocFunc( self, _viewStyle, _backendControl, _WSHandler );
|
|
|
|
controlFrame:= self.bounds;
|
|
_backendControl.initWithFrame( controlFrame );
|
|
_scrollView:= TCocoaScrollView.alloc.initWithFrame( controlFrame );
|
|
_scrollView.setDocumentView( _backendControl );
|
|
_scrollView.setAutoresizingMask( NSViewWidthSizable or NSViewHeightSizable );
|
|
_scrollView.callback:= self.callback;
|
|
self.addSubView( _scrollView );
|
|
ScrollViewSetBorderStyle( _scrollView, callback.getBorderStyle );
|
|
|
|
backendControlAccess:= TCocoaListViewBackendControlProtocol(_backendControl);
|
|
backendControlAccess.backend_setCallback( self.callback );
|
|
backendControlAccess.backend_onInit;
|
|
end;
|
|
|
|
type
|
|
TWinControlAccess = class(TWinControl);
|
|
|
|
// LCL has built-in editing functionality in TListItem.EditCaption(),
|
|
// which creates a TextEditor to Edit Caption. at the Cocoa level,
|
|
// it will be loaded into TCocoaListView.TCocoaScrollView.backendControl.
|
|
// because TCocoaScrollView and backendControl will be rebuilt when
|
|
// switching the viewStyle, the Editor handle needs to be destroyed at Cocoa,
|
|
// so that the Editor can be recreated normally when needed after the switch.
|
|
procedure releaseCaptionEditor( container:NSView );
|
|
var
|
|
view: NSView;
|
|
control: TWinControlAccess;
|
|
begin
|
|
for view in container.subviews do begin
|
|
control:= TWinControlAccess( view.lclGetTarget );
|
|
if Assigned(control) then begin
|
|
control.Hide;
|
|
control.DestroyHandle;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TCocoaListView.releaseControls;
|
|
begin
|
|
if not Assigned(_backendControl) then
|
|
Exit;
|
|
FreeAndNil( _WSHandler );
|
|
_scrollView.removeFromSuperview;
|
|
_scrollView.setDocumentView( nil );
|
|
_scrollView.release;
|
|
_scrollView:= nil;
|
|
releaseCaptionEditor( _backendControl );
|
|
_backendControl.release;
|
|
_backendControl:= nil;
|
|
end;
|
|
|
|
procedure TCocoaListView.initData;
|
|
var
|
|
needsInit: Boolean = False;
|
|
begin
|
|
needsInit:= _needsCallLclInit;
|
|
_needsCallLclInit:= False;
|
|
if needsInit then begin
|
|
_initializing:= True;
|
|
callback.callTargetInitializeWnd;
|
|
_initializing:= False;
|
|
TCocoaListViewBackendControlProtocol(_backendControl).backend_reloadData;
|
|
end;
|
|
_needsCallLclInit:= True;
|
|
end;
|
|
|
|
function TCocoaListView.lclGetCallback: ICommonCallback;
|
|
begin
|
|
Result:= callback;
|
|
end;
|
|
|
|
procedure TCocoaListView.lclClearCallback;
|
|
begin
|
|
callback:= nil;
|
|
end;
|
|
|
|
function TCocoaListView.lclContentView: NSView;
|
|
begin
|
|
Result:= documentView;
|
|
end;
|
|
|
|
class function TCocoaListView.alloc: id;
|
|
begin
|
|
Result:=inherited alloc;
|
|
end;
|
|
|
|
procedure TCocoaListView.dealloc;
|
|
begin
|
|
self.releaseControls;
|
|
inherited dealloc;
|
|
end;
|
|
|
|
procedure TCocoaListView.setAllocFunc( allocFunc: CocoaListViewAllocFunc );
|
|
begin
|
|
_allocFunc:= allocFunc;
|
|
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;
|
|
end;
|
|
|
|
function TLCLListViewCallback.GetItemTextAt(ARow, ACol: Integer;
|
|
var Text: String): Boolean;
|
|
begin
|
|
Result := (ACol>=0) and ( (ACol<listView.ColumnCount) or (ACol=0) )
|
|
and (ARow >= 0) and (ARow < listView.Items.Count);
|
|
|
|
if not Result then Exit;
|
|
|
|
if ACol = 0 then
|
|
Text := listView.Items[ARow].Caption
|
|
else
|
|
begin
|
|
Text := '';
|
|
dec(ACol);
|
|
if (ACol >=0) and (ACol < listView.Items[ARow].SubItems.Count) then
|
|
Text := listView.Items[ARow].SubItems[ACol];
|
|
end;
|
|
end;
|
|
|
|
function TLCLListViewCallback.GetItemCheckedAt(ARow, ACol: Integer;
|
|
var IsChecked: Integer): Boolean;
|
|
var
|
|
BoolState : array [Boolean] of Integer = (NSOffState, NSOnState);
|
|
begin
|
|
if ownerData and Assigned(listView) and (ARow>=0) and (ARow < listView.Items.Count) then
|
|
IsChecked := BoolState[listView.Items[ARow].Checked]
|
|
else
|
|
IsChecked := BoolState[checkedIndexSet.containsIndex(ARow)];
|
|
Result := true;
|
|
end;
|
|
|
|
function TLCLListViewCallback.GetItemImageAt(ARow, ACol: Integer;
|
|
var imgIdx: Integer): Boolean;
|
|
begin
|
|
imgIdx:= -1;
|
|
Result := (ACol >= 0) and ( (ACol<listView.ColumnCount) or ( ACol=0) )
|
|
and (ARow >= 0) and (ARow < listView.Items.Count);
|
|
|
|
if not Result then Exit;
|
|
|
|
if ACol = 0 then
|
|
imgIdx := listView.Items[ARow].ImageIndex
|
|
else
|
|
begin
|
|
dec(ACol);
|
|
if (ACol >=0) and (ACol < listView.Items[ARow].SubItems.Count) then
|
|
imgIdx := listView.Items[ARow].SubItemImages[ACol];
|
|
end;
|
|
end;
|
|
|
|
function TLCLListViewCallback.GetImageFromIndex(imgIdx: Integer): NSImage;
|
|
var
|
|
bmp : TBitmap;
|
|
lvil: TListViewImageList;
|
|
lst : TCustomImageList;
|
|
x,y : integer;
|
|
img : NSImage;
|
|
rep : NSBitmapImageRep;
|
|
cb : TCocoaBitmap;
|
|
begin
|
|
Result:= nil;
|
|
if imgIdx < 0 then
|
|
Exit;
|
|
|
|
if NOT self.GetImageListType( lvil ) then
|
|
Exit;
|
|
|
|
if lvil = lvilLarge then
|
|
lst:= TCustomListViewAccess(listView).LargeImages
|
|
else
|
|
lst:= TCustomListViewAccess(listView).SmallImages;
|
|
|
|
bmp := TBitmap.Create;
|
|
try
|
|
lst.GetBitmap(imgIdx, bmp);
|
|
if bmp.Handle = 0 then
|
|
Exit;
|
|
|
|
// Bitmap Handle should be nothing but TCocoaBitmap
|
|
cb := TCocoaBitmap(bmp.Handle);
|
|
|
|
// There's NSBitmapImageRep in TCocoaBitmap, but it depends on the availability
|
|
// of memory buffer stored with TCocoaBitmap. As soon as TCocoaBitmap is freed
|
|
// pixels are not available. For this reason, we're making a copy of the bitmapdata
|
|
// allowing Cocoa to allocate its own buffer (by passing nil for planes parameter)
|
|
rep := NSBitmapImageRep(NSBitmapImageRep.alloc).initWithBitmapDataPlanes_pixelsWide_pixelsHigh__colorSpaceName_bitmapFormat_bytesPerRow_bitsPerPixel(
|
|
nil, // planes, BitmapDataPlanes
|
|
Round(cb.ImageRep.size.Width), // width, pixelsWide
|
|
Round(cb.ImageRep.size.Height),// height, PixelsHigh
|
|
cb.ImageRep.bitsPerSample,// bitsPerSample, bps
|
|
cb.ImageRep.samplesPerPixel, // samplesPerPixel, spp
|
|
cb.ImageRep.hasAlpha, // hasAlpha
|
|
False, // isPlanar
|
|
cb.ImageRep.colorSpaceName, // colorSpaceName
|
|
cb.ImageRep.bitmapFormat, // bitmapFormat
|
|
cb.ImageRep.bytesPerRow, // bytesPerRow
|
|
cb.ImageRep.BitsPerPixel //bitsPerPixel
|
|
);
|
|
System.Move( cb.ImageRep.bitmapData^, rep.bitmapData^, cb.ImageRep.bytesPerRow * Round(cb.ImageRep.size.height));
|
|
img := NSImage(NSImage.alloc).initWithSize( rep.size );
|
|
img.addRepresentation(rep);
|
|
Result := img;
|
|
rep.release;
|
|
|
|
finally
|
|
bmp.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TLCLListViewCallback.SetItemTextAt(ARow, ACol: Integer;
|
|
const Text: String);
|
|
begin
|
|
// there's no notifcaiton to be sent to the TCustomListView;
|
|
if (ACol<>0) then Exit;
|
|
|
|
inc(isSetTextFromWS);
|
|
try
|
|
if (ACol=0) then
|
|
if (ARow>=0) and (ARow<listView.Items.Count) then
|
|
TCustomListViewAccess(listView).DoEndEdit(listView.Items[ARow], Text);
|
|
finally
|
|
dec(isSetTextFromWS);
|
|
end;
|
|
|
|
end;
|
|
|
|
procedure TLCLListViewCallback.SetItemCheckedAt(ARow, ACol: Integer;
|
|
IsChecked: Integer);
|
|
var
|
|
Msg: TLMNotify;
|
|
NMLV: TNMListView;
|
|
begin
|
|
if IsChecked = NSOnState
|
|
then checkedIndexSet.addIndex(ARow)
|
|
else checkedIndexSet.removeIndex(ARow);
|
|
|
|
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
|
FillChar(NMLV{%H-}, SizeOf(NMLV), #0);
|
|
|
|
Msg.Msg := CN_NOTIFY;
|
|
|
|
NMLV.hdr.hwndfrom := ListView.Handle;
|
|
NMLV.hdr.code := LVN_ITEMCHANGED;
|
|
NMLV.iItem := ARow;
|
|
NMLV.iSubItem := 0;
|
|
NMLV.uChanged := LVIF_STATE;
|
|
Msg.NMHdr := @NMLV.hdr;
|
|
|
|
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
|
|
Msg: TLMNotify;
|
|
NMLV: TNMListView;
|
|
begin
|
|
Msg:= Default( TLMNotify );
|
|
NMLV:= Default( TNMListView );
|
|
|
|
Msg.Msg := CN_NOTIFY;
|
|
|
|
NMLV.hdr.hwndfrom := ListView.Handle;
|
|
NMLV.hdr.code := LVN_ITEMCHANGED;
|
|
NMLV.iSubItem := 0;
|
|
NMLV.uChanged := LVIF_STATE;
|
|
Msg.NMHdr := @NMLV.hdr;
|
|
|
|
if isSelected then begin
|
|
NMLV.uNewState := LVIS_FOCUSED or LVIS_SELECTED;;
|
|
NMLV.uOldState := 0;
|
|
end else begin
|
|
NMLV.uNewState := 0;
|
|
NMLV.uOldState := LVIS_FOCUSED or LVIS_SELECTED;;
|
|
end;
|
|
|
|
NMLV.iItem := ARow;
|
|
LCLMessageGlue.DeliverMessage(ListView, Msg);
|
|
end;
|
|
begin
|
|
if isSelected then
|
|
self.selectionIndexSet.addIndex( ARow )
|
|
else
|
|
self.selectionIndexSet.removeIndex( ARow );
|
|
|
|
sendMsgToLCL;
|
|
end;
|
|
|
|
function TLCLListViewCallback.shouldSelectionChange(NewSel: Integer
|
|
): Boolean;
|
|
var
|
|
item: TListItem = nil;
|
|
begin
|
|
if (NewSel>=0) and (NewSel<self.listView.Items.Count) then
|
|
item:= self.listView.Items[NewSel];
|
|
Result:= TCustomListViewAccess(self.listView).CanChange( item, LVIF_TEXT );
|
|
end;
|
|
|
|
procedure TLCLListViewCallback.ColumnClicked(ACol: Integer);
|
|
var
|
|
Msg: TLMNotify;
|
|
NMLV: TNMListView;
|
|
begin
|
|
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
|
FillChar(NMLV{%H-}, SizeOf(NMLV), #0);
|
|
|
|
Msg.Msg := CN_NOTIFY;
|
|
|
|
NMLV.hdr.hwndfrom := ListView.Handle;
|
|
NMLV.hdr.code := LVN_COLUMNCLICK;
|
|
NMLV.iSubItem := ACol;
|
|
NMLV.uChanged := 0;
|
|
Msg.NMHdr := @NMLV.hdr;
|
|
|
|
LCLMessageGlue.DeliverMessage(ListView, Msg);
|
|
end;
|
|
|
|
procedure TLCLListViewCallback.DrawRow(rowidx: Integer; ctx: TCocoaContext;
|
|
const r: TRect; state: TOwnerDrawState);
|
|
var
|
|
ALV: TCustomListViewAccess;
|
|
begin
|
|
ALV:= TCustomListViewAccess(self.listView);
|
|
ALV.Canvas.Handle:= HDC(ctx);
|
|
ALV.IntfCustomDraw( dtItem, cdPrePaint, rowidx, 0, [], nil );
|
|
ALV.Canvas.Handle:= 0;
|
|
end;
|
|
|
|
procedure TLCLListViewCallback.GetRowHeight(rowidx: Integer; var h: Integer);
|
|
begin
|
|
|
|
end;
|
|
|
|
function TLCLListViewCallback.GetBorderStyle: TBorderStyle;
|
|
begin
|
|
Result:= TCustomListView(Target).BorderStyle;
|
|
end;
|
|
|
|
function TLCLListViewCallback.GetImageListType( out lvil: TListViewImageList ): Boolean;
|
|
const
|
|
preferredImages: array [TViewStyle] of TListViewImageList = (
|
|
lvilLarge, lvilSmall, lvilSmall, lvilSmall );
|
|
alternativeImages: array [TViewStyle] of TListViewImageList = (
|
|
lvilSmall, lvilLarge, lvilLarge, lvilLarge );
|
|
var
|
|
viewStyle: TViewStyle;
|
|
LVA: TCustomListViewAccess;
|
|
begin
|
|
Result:= True;
|
|
LVA:= TCustomListViewAccess(listView);
|
|
viewStyle:= LVA.ViewStyle;
|
|
|
|
lvil:= preferredImages[viewStyle];
|
|
if (lvil=lvilLarge) and Assigned(LVA.LargeImages) then
|
|
Exit;
|
|
if (lvil=lvilSmall) and Assigned(LVA.SmallImages) then
|
|
Exit;
|
|
|
|
lvil:= alternativeImages[viewStyle];
|
|
if (lvil=lvilLarge) and Assigned(LVA.LargeImages) then
|
|
Exit;
|
|
if (lvil=lvilSmall) and Assigned(LVA.SmallImages) then
|
|
Exit;
|
|
|
|
Result:= False;
|
|
end;
|
|
|
|
procedure TLCLListViewCallback.callTargetInitializeWnd;
|
|
begin
|
|
TCustomListViewAccess(Target).InitializeWnd;
|
|
end;
|
|
|
|
end.
|
|
|