Cocoa: remove circular unit references, add CocoaCallback/CocoaListView/CocoaWSListView unit

This commit is contained in:
rich2014 2024-07-27 23:40:16 +08:00
parent 35b44a860b
commit b1e0da3394
22 changed files with 2465 additions and 2365 deletions

View File

@ -26,7 +26,7 @@ uses
// rtl+ftl
Types, Classes, SysUtils,
// Libs
MacOSAll, CocoaAll, CocoaUtils, CocoaPrivate,
MacOSAll, CocoaAll, CocoaUtils, CocoaPrivate, CocoaCallback,
// LCL
Graphics;

View File

@ -0,0 +1,122 @@
unit CocoaCallback;
{$mode ObjFPC}{$H+}
{$modeswitch objectivec2}
{$interfaces corba}
interface
uses
Classes, SysUtils,
LclType, Controls,
MacOSAll, CocoaAll, CocoaGDIObjects;
type
{ ICommonCallback }
ICommonCallback = interface
// mouse events
function MouseUpDownEvent(Event: NSEvent; AForceAsMouseUp: Boolean = False; AOverrideBlock: Boolean = False): Boolean;
procedure MouseClick;
function MouseMove(Event: NSEvent): Boolean;
// KeyEvXXX methods were introduced to allow a better control
// over when Cocoa keys processing is being called.
// (The initial KeyEvent() replicates Carbon implementation, and it's not
// suitable for Cocoa, due to the use of OOP and the extual "inherited Key..."needs to be called
// where for Carbon there's a special fucntion to call the "next event handler" present)
//
// The desired use is as following:
// Call KeyEvPrepare and pass NSEvent object
// after that call KeyEvBefore and pass a flag if AllowCocoaHandle
//
// The call would populate the flag. If it's "True" you should call "inherited" method (to let Cocoa handle the key).
// If the flag returned "False", you should not call inherited.
//
// No matter what the flag value was you should call KeyEvAfter.
procedure KeyEvBefore(Event: NSEvent; out AllowCocoaHandle: boolean);
procedure KeyEvAfter;
procedure KeyEvAfterDown(out AllowCocoaHandle: boolean);
procedure KeyEvHandled;
procedure SetTabSuppress(ASuppress: Boolean);
// only Cocoa Event Mechanism (no LCL Event), if the IME is in use
function IsCocoaOnlyState: Boolean;
procedure SetCocoaOnlyState( state:Boolean );
function scrollWheel(Event: NSEvent): Boolean;
function CanFocus: Boolean;
// size, pos events
procedure frameDidChange(sender: id);
procedure boundsDidChange(sender: id);
// misc events
procedure Draw(ctx: NSGraphicsContext; const bounds, dirty: NSRect);
procedure DrawBackground(ctx: NSGraphicsContext; const bounds, dirty: NSRect);
procedure DrawOverlay(ctx: NSGraphicsContext; const bounds, dirty: NSRect);
procedure BecomeFirstResponder;
procedure ResignFirstResponder;
procedure DidBecomeKeyNotification;
procedure DidResignKeyNotification;
function SendOnEditCut: Boolean;
function SendOnEditPaste: Boolean;
procedure SendOnChange;
procedure SendOnTextChanged;
procedure scroll(isVert: Boolean; Pos: Integer; AScrollPart: NSScrollerPart = NSScrollerNoPart);
// non event methods
function DeliverMessage(Msg: Cardinal; WParam: WParam; LParam: LParam): LResult;
function GetPropStorage: TStringList;
function GetContext: TCocoaContext;
function GetTarget: TObject;
function GetHasCaret: Boolean;
function GetCallbackObject: TObject;
procedure SetHasCaret(AValue: Boolean);
function GetIsOpaque: Boolean;
procedure SetIsOpaque(AValue: Boolean);
function GetShouldBeEnabled: Boolean;
// the method is called, when handle is being destroyed.
// the callback object to stay alive a little longer than LCL object (Target)
// thus it needs to know that LCL object has been destroyed.
// After this called has been removed, any Cocoa events should not be
// forwarded to LCL target
procedure RemoveTarget;
procedure InputClientInsertText(const utf8: string);
// properties
property HasCaret: Boolean read GetHasCaret write SetHasCaret;
property IsOpaque: Boolean read GetIsOpaque write SetIsOpaque;
property CocoaOnlyState: Boolean read IsCocoaOnlyState write SetCocoaOnlyState;
end;
{ IListViewCallBack }
IListViewCallBack = interface(ICommonCallback)
function ItemsCount: Integer;
function GetItemTextAt(ARow, ACol: Integer; var Text: String): Boolean;
function GetItemCheckedAt(ARow, ACol: 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(ARow, ACol: Integer; CheckState: Integer);
procedure selectionChanged(ARow: Integer; Added, Removed: NSIndexSet);
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 height: Integer);
function GetBorderStyle: TBorderStyle;
end;
{ TCocoaStatusBar }
IStatusBarCallback = interface {(ICommonCallback) // not needed to inherit from ICommonCallback}
function GetBarsCount: Integer;
//todo: consider the use Cocoa native types, instead of FPC TAlignment
function GetBarItem(idx: Integer; var txt: String;
var width: Integer; var align: TAlignment): Boolean;
procedure DrawPanel(idx: Integer; const r: TRect);
end;
implementation
end.

View File

@ -1,7 +1,6 @@
unit CocoaCollectionView;
{$mode objfpc}{$H+}
{$modeswitch objectivec1}
{$modeswitch objectivec2}
{$interfaces corba}
{$include cocoadefines.inc}
@ -9,9 +8,14 @@ unit CocoaCollectionView;
interface
uses
Classes, SysUtils, Controls, ComCtrls,
MacOSAll, CocoaAll, CocoaPrivate, Cocoa_Extra, CocoaUtils,
CocoaWSComCtrls, CocoaTextEdits;
// rtl+ftl
Classes, SysUtils,
// Libs
MacOSAll, CocoaAll,
CocoaPrivate, Cocoa_Extra, CocoaCallback, CocoaConfig, CocoaUtils,
CocoaListView, CocoaTextEdits,
// LCL
LCLType, Controls, ComCtrls, StdCtrls, ImgList, Forms;
type
@ -123,6 +127,62 @@ type
procedure mouseDown(theEvent: NSEvent); override;
end;
{ TCocoaWSListView_CollectionViewHandler }
TCocoaWSListView_CollectionViewHandler = class(TCocoaWSListViewHandler)
private
_listView: TCocoaListView;
_collectionView: TCocoaCollectionView;
private
function getCallback: TLCLListViewCallback;
procedure doReloadDataAfterDelete( AIndex: PtrInt );
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;
function ItemGetChecked( const AIndex: Integer; const {%H-}AItem: TListItem): Boolean; 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;
@ -130,7 +190,8 @@ function realVisibleItems( cv: NSCollectionView ): NSArray;
implementation
type
TCustomListViewAccess = class(TCustomListView);
{ TCocoaListView_CollectionView_LargeIconHandler }
TCocoaListView_CollectionView_LargeIconHandler = class(TCocoaListView_CollectionView_StyleHandler)
procedure onInit; override;
@ -723,4 +784,368 @@ begin
inherited mouseDown(theEvent);
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
Application.QueueAsyncCall( @doReloadDataAfterDelete, AIndex );
end;
procedure TCocoaWSListView_CollectionViewHandler.doReloadDataAfterDelete( AIndex: PtrInt );
var
lclcb : TLCLListViewCallback;
begin
lclcb:= getCallback;
if NOT Assigned(lclcb) then
Exit;
lclcb.selectionIndexSet.shiftIndexesStartingAtIndex_by( AIndex+1, -1 );
_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;
case ACode of
drLabel:
begin
frame:= item.textField.frame;
frame:= item.view.convertRect_toView( frame, _collectionView );
_collectionView.styleHandler.onAdjustTextEditorRect( frame );
end;
drIcon:
begin
frame:= item.imageView.frame;
frame:= item.view.convertRect_toView( frame, _collectionView );
end
else
frame:= item.view.frame;
end;
Result:= NSRectToRect( frame );
end;
function TCocoaWSListView_CollectionViewHandler.ItemGetChecked(
const AIndex: Integer; const AItem: TListItem): Boolean;
begin
Result:= False;
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
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
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);
begin
case AProp of
{lvpHideSelection,
lvpHotTrack,}
lvpMultiSelect: _collectionView.setAllowsMultipleSelection(AIsSet);
{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);
var
lclcb : TLCLListViewCallback;
begin
lclcb:= getCallback;
if NOT Assigned(lclcb) then
Exit;
if TCocoaListView(lclcb.Owner).initializing then
Exit;
lclcb.selectionIndexSet.removeAllIndexes;
_collectionView.reloadData();
end;
end.

View File

@ -7,7 +7,7 @@ interface
uses
Classes, SysUtils,
CocoaAll, CocoaUtils, CocoaPrivate, cocoa_extra;
CocoaAll, CocoaUtils, CocoaPrivate, CocoaCallback, cocoa_extra;
type

View File

@ -33,7 +33,7 @@ uses
// darwin bindings
MacOSAll,
// private
CocoaAll, CocoaConst, CocoaConfig, CocoaPrivate, CocoaUtils, Cocoa_Extra,
CocoaAll, CocoaConst, CocoaConfig, CocoaPrivate, CocoaCallback, CocoaUtils, Cocoa_Extra,
CocoaGDIObjects, CocoaCursor, CocoaMenus, CocoaWindows,
CocoaScrollers, CocoaWSScrollers,
CocoaWSClipboard, CocoaTextEdits,

View File

@ -0,0 +1,657 @@
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,
Math,
// WS
WSComCtrls,
// Cocoa WS
CocoaPrivate, CocoaCallback, CocoaScrollers, CocoaWSScrollers, CocoaTabControls, CocoaUtils,
CocoaWSCommon, cocoa_extra, CocoaGDIObjects, CocoaButtons;
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;
checkedIdx : NSMutableIndexSet;
ownerData : Boolean;
constructor Create(AOwner: NSObject; ATarget: TWinControl; AHandleView: NSView); override;
destructor Destroy; override;
function ItemsCount: Integer;
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 selectionChanged(NewSel: Integer; Added, Removed: NSIndexSet);
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;
function GetImageListType( out lvil: TListViewImageList ): Boolean;
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 ItemGetChecked( const AIndex: Integer; const {%H-}AItem: TListItem): Boolean; 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
Writeln( HexStr(@_allocFunc) );
_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;
checkedIdx:= NSMutableIndexSet.new;
end;
destructor TLCLListViewCallback.Destroy;
begin
selectionIndexSet.release;
selectionIndexSet:= nil;
checkedIdx.release;
checkedIdx:= 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[checkedIdx.containsIndex(ARow)];
Result := true;
end;
function TLCLListViewCallback.GetItemImageAt(ARow, ACol: Integer;
var imgIdx: Integer): 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
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 checkedIdx.addIndex(ARow)
else checkedIdx.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.selectionChanged(NewSel: Integer; Added, Removed: NSIndexSet);
var
Msg: TLMNotify;
NMLV: TNMListView;
procedure RunIndex(idx: NSIndexSet);
var
buf : array [0..256-1] of NSUInteger;
rng : NSRange;
cnt : Integer;
i : Integer;
itm : NSUInteger;
begin
rng.location := idx.firstIndex;
repeat
rng.length := idx.lastIndex - rng.location + 1;
cnt := idx.getIndexes_maxCount_inIndexRange(@buf[0], length(buf), @rng);
for i := 0 to cnt - 1 do begin
NMLV.iItem := buf[i];
LCLMessageGlue.DeliverMessage(ListView, Msg);
end;
if cnt < length(buf) then cnt := 0
else rng.location := buf[cnt-1]+1;
until cnt = 0;
end;
begin
{$IFDEF COCOA_DEBUG_LISTVIEW}
WriteLn(Format('[TLCLListViewCallback.SelectionChanged] NewSel=%d', [NewSel]));
{$ENDIF}
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.iSubItem := 0;
NMLV.uChanged := LVIF_STATE;
Msg.NMHdr := @NMLV.hdr;
if Removed.count>0 then
begin
NMLV.uNewState := 0;
NMLV.uOldState := LVIS_SELECTED;
RunIndex( Removed );
end;
if Added.count > 0 then begin
NMLV.uNewState := LVIS_SELECTED;
NMLV.uOldState := 0;
RunIndex( Added );
end;
{if NewSel >= 0 then
begin
NMLV.iItem := NewSel;
NMLV.uNewState := LVIS_SELECTED;
end
else
begin
NMLV.iItem := 0;
NMLV.uNewState := 0;
NMLV.uOldState := LVIS_SELECTED;
end;
LCLMessageGlue.DeliverMessage(ListView, Msg);}
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_SELECTED;
NMLV.uOldState := 0;
end else begin
NMLV.uNewState := 0;
NMLV.uOldState := 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.

View File

@ -12,7 +12,7 @@ uses
// LCL
Forms, Menus, LCLType, Classes, LCLStrConsts,
// LCL Cocoa
CocoaAll, CocoaPrivate, CocoaUtils, CocoaConst;
CocoaAll, CocoaPrivate, CocoaCallback, CocoaUtils, CocoaConst;
type
IMenuItemCallback = interface(ICommonCallBack)

View File

@ -29,10 +29,10 @@ interface
uses
// rtl+ftl
Types, Classes, SysUtils, LazLoggerBase, Forms,
Types, Classes, SysUtils, Forms,
// Libs
MacOSAll, CocoaAll, CocoaUtils, CocoaGDIObjects, CocoaCursor,
cocoa_extra,
MacOSAll, CocoaAll, CocoaCallback, CocoaGDIObjects, CocoaCursor, cocoa_extra,
CocoaUtils,
// LCL
LCLType,
LazUTF8;
@ -47,82 +47,6 @@ type
// Thus this declaration needs to be here.
LCLObjCBoolean = cocoa_extra.LCLObjCBoolean;
{ ICommonCallback }
ICommonCallback = interface
// mouse events
function MouseUpDownEvent(Event: NSEvent; AForceAsMouseUp: Boolean = False; AOverrideBlock: Boolean = False): Boolean;
procedure MouseClick;
function MouseMove(Event: NSEvent): Boolean;
// KeyEvXXX methods were introduced to allow a better control
// over when Cocoa keys processing is being called.
// (The initial KeyEvent() replicates Carbon implementation, and it's not
// suitable for Cocoa, due to the use of OOP and the extual "inherited Key..."needs to be called
// where for Carbon there's a special fucntion to call the "next event handler" present)
//
// The desired use is as following:
// Call KeyEvPrepare and pass NSEvent object
// after that call KeyEvBefore and pass a flag if AllowCocoaHandle
//
// The call would populate the flag. If it's "True" you should call "inherited" method (to let Cocoa handle the key).
// If the flag returned "False", you should not call inherited.
//
// No matter what the flag value was you should call KeyEvAfter.
procedure KeyEvBefore(Event: NSEvent; out AllowCocoaHandle: boolean);
procedure KeyEvAfter;
procedure KeyEvAfterDown(out AllowCocoaHandle: boolean);
procedure KeyEvHandled;
procedure SetTabSuppress(ASuppress: Boolean);
// only Cocoa Event Mechanism (no LCL Event), if the IME is in use
function IsCocoaOnlyState: Boolean;
procedure SetCocoaOnlyState( state:Boolean );
function scrollWheel(Event: NSEvent): Boolean;
function CanFocus: Boolean;
// size, pos events
procedure frameDidChange(sender: id);
procedure boundsDidChange(sender: id);
// misc events
procedure Draw(ctx: NSGraphicsContext; const bounds, dirty: NSRect);
procedure DrawBackground(ctx: NSGraphicsContext; const bounds, dirty: NSRect);
procedure DrawOverlay(ctx: NSGraphicsContext; const bounds, dirty: NSRect);
procedure BecomeFirstResponder;
procedure ResignFirstResponder;
procedure DidBecomeKeyNotification;
procedure DidResignKeyNotification;
function SendOnEditCut: Boolean;
function SendOnEditPaste: Boolean;
procedure SendOnChange;
procedure SendOnTextChanged;
procedure scroll(isVert: Boolean; Pos: Integer; AScrollPart: NSScrollerPart = NSScrollerNoPart);
// non event methods
function DeliverMessage(Msg: Cardinal; WParam: WParam; LParam: LParam): LResult;
function GetPropStorage: TStringList;
function GetContext: TCocoaContext;
function GetTarget: TObject;
function GetHasCaret: Boolean;
function GetCallbackObject: TObject;
procedure SetHasCaret(AValue: Boolean);
function GetIsOpaque: Boolean;
procedure SetIsOpaque(AValue: Boolean);
function GetShouldBeEnabled: Boolean;
// the method is called, when handle is being destroyed.
// the callback object to stay alive a little longer than LCL object (Target)
// thus it needs to know that LCL object has been destroyed.
// After this called has been removed, any Cocoa events should not be
// forwarded to LCL target
procedure RemoveTarget;
procedure InputClientInsertText(const utf8: string);
// properties
property HasCaret: Boolean read GetHasCaret write SetHasCaret;
property IsOpaque: Boolean read GetIsOpaque write SetIsOpaque;
property CocoaOnlyState: Boolean read IsCocoaOnlyState write SetCocoaOnlyState;
end;
{ LCLObjectExtension }
LCLObjectExtension = objccategory(NSObject)
@ -326,16 +250,6 @@ type
TStatusItemDataArray = array of TStatusItemData;
{ TCocoaStatusBar }
IStatusBarCallback = interface {(ICommonCallback) // not needed to inherit from ICommonCallback}
function GetBarsCount: Integer;
//todo: consider the use Cocoa native types, instead of FPC TAlignment
function GetBarItem(idx: Integer; var txt: String;
var width: Integer; var align: TAlignment): Boolean;
procedure DrawPanel(idx: Integer; const r: TRect);
end;
TCocoaStatusBar = objcclass(TCocoaCustomControl)
public
//StatusBar : TStatusBar;

View File

@ -27,7 +27,7 @@ uses
Math, Classes, SysUtils, LclType,
// Libs
Controls, Forms,
MacOSAll, CocoaAll, CocoaUtils, CocoaPrivate, CocoaConfig;
MacOSAll, CocoaAll, CocoaUtils, CocoaPrivate, CocoaCallback, CocoaConfig;
type
{ TCocoaScrollView }

View File

@ -26,7 +26,7 @@ uses
// rtl+ftl
Types, Classes, SysUtils,
// Libs
MacOSAll, CocoaAll, CocoaUtils, CocoaPrivate, CocoaConst;
MacOSAll, CocoaAll, CocoaUtils, CocoaPrivate, CocoaCallback, CocoaConst;
type

View File

@ -15,7 +15,6 @@
unit CocoaTables;
{$mode objfpc}{$H+}
{$modeswitch objectivec1}
{$modeswitch objectivec2}
{$interfaces corba}
{$include cocoadefines.inc}
@ -26,33 +25,17 @@ interface
uses
// rtl+ftl
Types, Classes, SysUtils,
Classes, SysUtils,
// Libs
MacOSAll, CocoaAll, CocoaUtils, CocoaGDIObjects,
cocoa_extra, CocoaPrivate, CocoaConst, CocoaConfig,
MacOSAll, CocoaAll,
CocoaPrivate, Cocoa_Extra, CocoaCallback, CocoaConst, CocoaConfig,
CocoaWSCommon, CocoaUtils, CocoaGDIObjects,
CocoaListView,
// LCL
LCLType, Controls;
LCLType, Controls, ComCtrls, StdCtrls, ImgList, Forms;
type
{ IListViewCallBack }
IListViewCallBack = interface(ICommonCallback)
function ItemsCount: Integer;
function GetItemTextAt(ARow, ACol: Integer; var Text: String): Boolean;
function GetItemCheckedAt(ARow, ACol: 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(ARow, ACol: Integer; CheckState: Integer);
procedure selectionChanged(ARow: Integer; Added, Removed: NSIndexSet);
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 height: Integer);
function GetBorderStyle: TBorderStyle;
end;
{ TCocoaStringList }
TCocoaStringList = class(TStringList)
@ -226,6 +209,62 @@ type
procedure lclSetEnabled(AEnabled: Boolean); override;
end;
{ TCocoaWSListView_TableViewHandler }
TCocoaWSListView_TableViewHandler = class(TCocoaWSListViewHandler)
private
_listView: TCocoaListView;
_tableView: TCocoaTableListView;
private
function getCallback: TLCLListViewCallback;
procedure doReloadDataAfterDelete( AIndex: PtrInt );
public
constructor Create( listView: TCocoaListView );
function getColumnFromIndex( const AIndex: Integer ): NSTableColumn;
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;
function ItemGetChecked( const AIndex: Integer; const {%H-}AItem: TListItem): Boolean; 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 AllocCocoaTableListView: TCocoaTableListView;
@ -238,9 +277,6 @@ const
implementation
uses
CocoaWSComCtrls, CocoaWSCommon;
type
{ TCellCocoaTableListView }
@ -250,7 +286,7 @@ type
NSTableViewDataSourceProtocol,
TCocoaListViewBackendControlProtocol )
public
procedure backend_setCallback( cb: TLCLListViewCallback );
procedure backend_setCallback( cb:TLCLListViewCallback );
procedure backend_reloadData;
procedure backend_onInit;
public
@ -1388,5 +1424,528 @@ begin
end;
end;
{ TCocoaWSListView_TableViewHandler }
constructor TCocoaWSListView_TableViewHandler.Create(
listView: TCocoaListView );
begin
_listView:= listView;
_tableView:= TCocoaTableListView(listView.documentView);
end;
function TCocoaWSListView_TableViewHandler.getColumnFromIndex(
const AIndex: Integer): NSTableColumn;
begin
Result:= nil;
if (AIndex < 0) or (AIndex >= _tableView.tableColumns.count) then
Exit;
Result:= NSTableColumn( _tableView.tableColumns.objectAtIndex(AIndex) );
end;
function TCocoaWSListView_TableViewHandler.getCallback: TLCLListViewCallback;
begin
Result:= TLCLListViewCallback( _tableView.lclGetCallback.GetCallbackObject );
end;
procedure TCocoaWSListView_TableViewHandler.doReloadDataAfterDelete( AIndex: PtrInt);
var
lclcb : TLCLListViewCallback;
begin
lclcb:= getCallback;
if NOT Assigned(lclcb) then
Exit;
lclcb.checkedIdx.shiftIndexesStartingAtIndex_by( AIndex+1, -1);
lclcb.selectionIndexSet.shiftIndexesStartingAtIndex_by( AIndex+1, -1 );
_tableView.selectRowIndexesByProgram( lclcb.selectionIndexSet );
_tableView.lclInsDelRow(AIndex, false);
end;
procedure TCocoaWSListView_TableViewHandler.ColumnDelete(
const AIndex: Integer);
var
cocoaColumn: NSTableColumn;
begin
cocoaColumn:= getColumnFromIndex( AIndex );
if Assigned(cocoaColumn) then
_tableView.removeTableColumn( cocoaColumn );
end;
function TCocoaWSListView_TableViewHandler.ColumnGetWidth(
const AIndex: Integer; const AColumn: TListColumn): Integer;
var
cocoaColumn: NSTableColumn;
begin
Result:= 0;
cocoaColumn:= getColumnFromIndex( AIndex );
if Assigned(cocoaColumn) then
Result:= Round( cocoaColumn.width );
end;
procedure TCocoaWSListView_TableViewHandler.ColumnInsert(
const AIndex: Integer; const AColumn: TListColumn);
var
cocoaColumn: NSTableColumn;
cocoaTitle: NSString;
begin
if (AIndex < 0) or (AIndex > _tableView.tableColumns.count) then
Exit;
cocoaTitle := NSStringUTF8(AColumn.Caption);
cocoaColumn := NSTableColumn.alloc.initWithIdentifier(cocoaTitle);
cocoaColumn.headerCell.setStringValue(cocoaTitle);
cocoaColumn.setResizingMask(NSTableColumnUserResizingMask);
_tableView.addTableColumn(cocoaColumn);
cocoaColumn.release;
cocoaTitle.release;
end;
procedure TCocoaWSListView_TableViewHandler.ColumnMove(const AOldIndex,
ANewIndex: Integer; const AColumn: TListColumn);
var
columnCount: NSUInteger;
begin
columnCount:= _tableView.tableColumns.count;
if columnCount <= 1 then
Exit;
if (AOldIndex < 0) or (AOldIndex >= columnCount) then
Exit;
if (ANewIndex < 0) or (ANewIndex >= columnCount) then
Exit;
_tableView.moveColumn_toColumn(AOldIndex, ANewIndex);
end;
procedure TCocoaWSListView_TableViewHandler.ColumnSetAlignment(
const AIndex: Integer; const AColumn: TListColumn;
const AAlignment: TAlignment);
var
cocoaColumn: NSTableColumn;
const
txtAlign : array[TAlignment] of NSTextAlignment = (
NSLeftTextAlignment, NSRightTextAlignment, NSCenterTextAlignment
);
begin
cocoaColumn:= getColumnFromIndex( AIndex );
if NOT Assigned(cocoaColumn) then
Exit;
_tableView.lclSetColumnAlign(cocoaColumn, txtAlign[AAlignment]);
_tableView.setNeedsDisplayInRect(_tableView.rectOfColumn(AIndex));
_tableView.headerView.setNeedsDisplayInRect( _tableView.headerView.headerRectOfColumn(AIndex) );
end;
procedure TCocoaWSListView_TableViewHandler.ColumnSetAutoSize(
const AIndex: Integer; const AColumn: TListColumn; const AAutoSize: Boolean);
var
cocoaColumn: NSTableColumn;
mask: NSUInteger;
begin
cocoaColumn:= getColumnFromIndex( AIndex );
if NOT Assigned(cocoaColumn) then
Exit;
if AAutoSize then
mask := NSTableColumnAutoresizingMask or NSTableColumnUserResizingMask
else
mask := NSTableColumnUserResizingMask;
cocoaColumn.setResizingMask(mask);
end;
procedure TCocoaWSListView_TableViewHandler.ColumnSetCaption(
const AIndex: Integer; const AColumn: TListColumn; const ACaption: String);
var
cocoaColumn: NSTableColumn;
cocoaTitle: NSString;
begin
cocoaColumn:= getColumnFromIndex( AIndex );
if NOT Assigned(cocoaColumn) then
Exit;
cocoaTitle := NSStringUtf8(ACaption);
if cocoaColumn.respondsToSelector(ObjCSelector('setTitle:')) then
cocoaColumn.setTitle(cocoaTitle)
else
cocoaColumn.headerCell.setStringValue(cocoaTitle);
{$ifdef BOOLFIX}
_tableView.headerView.setNeedsDisplay__(Ord(true)); // forces the newly set Value (even for setTitle!)
{$else}
_tableView.headerView.setNeedsDisplay_(true); // forces the newly set Value (even for setTitle!)
{$endif}
cocoaTitle.release;
end;
procedure TCocoaWSListView_TableViewHandler.ColumnSetMaxWidth(
const AIndex: Integer; const AColumn: TListColumn; const AMaxWidth: Integer);
var
cocoaColumn: NSTableColumn;
begin
cocoaColumn:= getColumnFromIndex( AIndex );
if NOT Assigned(cocoaColumn) then
Exit;
if AMaxWidth <= 0 then
cocoaColumn.setMaxWidth($FFFFFFFF)
else
cocoaColumn.setMaxWidth(AMaxWidth);
end;
procedure TCocoaWSListView_TableViewHandler.ColumnSetMinWidth(
const AIndex: Integer; const AColumn: TListColumn; const AMinWidth: integer);
var
cocoaColumn: NSTableColumn;
begin
cocoaColumn:= getColumnFromIndex( AIndex );
if NOT Assigned(cocoaColumn) then
Exit;
cocoaColumn.setMinWidth(AMinWidth);
end;
procedure TCocoaWSListView_TableViewHandler.ColumnSetWidth(
const AIndex: Integer; const AColumn: TListColumn; const AWidth: Integer);
var
cocoaColumn: NSTableColumn;
begin
cocoaColumn:= getColumnFromIndex( AIndex );
if NOT Assigned(cocoaColumn) then
Exit;
cocoaColumn.setWidth(AWidth);
end;
procedure TCocoaWSListView_TableViewHandler.ColumnSetVisible(
const AIndex: Integer; const AColumn: TListColumn; const AVisible: Boolean);
var
cocoaColumn: NSTableColumn;
begin
cocoaColumn:= getColumnFromIndex( AIndex );
if NOT Assigned(cocoaColumn) then
Exit;
{$ifdef BOOLFIX}
cocoaColumn.setHidden_(Ord(not AVisible));
{$else}
cocoaColumn.setHidden(not AVisible);
{$endif}
end;
procedure TCocoaWSListView_TableViewHandler.ColumnSetSortIndicator(
const AIndex: Integer; const AColumn: TListColumn;
const ASortIndicator: TSortIndicator);
var
cocoaColumn: NSTableColumn;
begin
cocoaColumn:= getColumnFromIndex( AIndex );
if NOT Assigned(cocoaColumn) then
Exit;
case ASortIndicator of
siNone:
_tableView.setIndicatorImage_inTableColumn(nil, cocoaColumn);
siAscending:
_tableView.setIndicatorImage_inTableColumn(
NSImage.imageNamed(NSSTR('NSAscendingSortIndicator')),
cocoaColumn);
siDescending:
_tableView.setIndicatorImage_inTableColumn(
NSImage.imageNamed(NSSTR('NSDescendingSortIndicator')),
cocoaColumn);
end;
end;
procedure TCocoaWSListView_TableViewHandler.ItemDelete(const AIndex: Integer
);
begin
Application.QueueAsyncCall( @doReloadDataAfterDelete, AIndex );
end;
function TCocoaWSListView_TableViewHandler.ItemDisplayRect(const AIndex,
ASubItem: Integer; ACode: TDisplayCode): TRect;
begin
LCLGetItemRect(_tableView, AIndex, ASubItem, Result);
case ACode of
drLabel: Result:= _tableView.lclGetLabelRect(AIndex, ASubItem, Result);
drIcon: Result:= _tableView.lclGetIconRect(AIndex, ASubItem, Result);
end;
end;
function TCocoaWSListView_TableViewHandler.ItemGetChecked(
const AIndex: Integer; const AItem: TListItem): Boolean;
var
lclcb : TLCLListViewCallback;
begin
Result:= False;
lclcb:= getCallback;
if NOT Assigned(lclcb) then
Exit;
Result := lclcb.checkedIdx.containsIndex(AIndex);
end;
function TCocoaWSListView_TableViewHandler.ItemGetPosition(
const AIndex: Integer): TPoint;
var
rect: NSRect;
begin
rect:= _tableView.rectOfRow(AIndex);
Result.X := Round(rect.origin.X);
Result.Y := Round(_listView.scrollView.frame.size.height - rect.origin.Y);
end;
function TCocoaWSListView_TableViewHandler.ItemGetState(
const AIndex: Integer; const AItem: TListItem; const AState: TListItemState;
out AIsSet: Boolean): Boolean;
begin
Result:= false;
case AState of
lisSelected: begin
Result:= (AIndex>=0) and (AIndex <= _tableView.numberOfRows);
AIsSet:= _tableView.isRowSelected(AIndex);
end;
end;
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.checkedIdx.shiftIndexesStartingAtIndex_by(AIndex, 1);
lclcb.selectionIndexSet.shiftIndexesStartingAtIndex_by( AIndex, 1 );
_tableView.lclInsDelRow(AIndex, true);
_tableView.selectRowIndexesByProgram( lclcb.selectionIndexSet );
_tableView.sizeToFit();
end;
procedure TCocoaWSListView_TableViewHandler.ItemSetChecked(
const AIndex: Integer; const AItem: TListItem; const AChecked: Boolean);
var
lclcb: TLCLListViewCallback;
begin
lclcb:= getCallback;
if NOT Assigned(lclcb) then
Exit;
if AChecked and not lclcb.checkedIdx.containsIndex(AIndex) then begin
lclcb.checkedIdx.addIndex(AIndex);
_tableView.reloadDataForRow_column(AIndex, 0);
end else if not AChecked and lclcb.checkedIdx.containsIndex(AIndex) then begin
lclcb.checkedIdx.removeIndex(AIndex);
_tableView.reloadDataForRow_column(AIndex, 0);
end;
end;
procedure TCocoaWSListView_TableViewHandler.ItemSetImage(
const AIndex: Integer; const AItem: TListItem; const ASubIndex,
AImageIndex: Integer);
begin
_tableView.reloadDataForRow_column(AIndex, ASubIndex);
end;
procedure TCocoaWSListView_TableViewHandler.ItemSetState(
const AIndex: Integer; const AItem: TListItem; const AState: TListItemState;
const AIsSet: Boolean);
var
row: Integer;
isSel: Boolean;
begin
row := AItem.Index;
if (row < 0) or (row >= _tableView.numberOfRows) then Exit;
case AState of
lisSelected:
begin
isSel := _tableView.selectedRowIndexes.containsIndex(row);
if AIsSet and not isSel then
_tableView.selectRowIndexesByProgram( NSIndexSet.indexSetWithIndex(row) )
else if not AIsSet and isSel then
_tableView.deselectRow(row);
end;
end;
end;
procedure TCocoaWSListView_TableViewHandler.ItemSetText(
const AIndex: Integer; const AItem: TListItem; const ASubIndex: Integer;
const AText: String);
begin
_tableView.reloadDataForRow_column(AIndex, ASubIndex);
end;
procedure TCocoaWSListView_TableViewHandler.ItemShow(const AIndex: Integer;
const AItem: TListItem; const PartialOK: Boolean);
begin
_tableView.scrollRowToVisible(AItem.Index);
end;
function TCocoaWSListView_TableViewHandler.GetFocused: Integer;
begin
Result := _tableView.selectedRow;
end;
function TCocoaWSListView_TableViewHandler.GetItemAt(x, y: integer
): Integer;
begin
Result:= LCLCoordToRow(_tableView, x,y);
end;
function TCocoaWSListView_TableViewHandler.GetSelCount: Integer;
begin
Result:= _tableView.selectedRowIndexes.count;
end;
function TCocoaWSListView_TableViewHandler.GetSelection: Integer;
begin
Result:= _tableView.selectedRow;
end;
function TCocoaWSListView_TableViewHandler.GetTopItem: Integer;
begin
Result:= LCLGetTopRow( _tableView );
end;
function TCocoaWSListView_TableViewHandler.GetVisibleRowCount: Integer;
var
rows: NSRange;
begin
rows := _tableView.rowsInRect(_tableView.visibleRect());
Result := rows.length;
end;
procedure TCocoaWSListView_TableViewHandler.SelectAll(const AIsSet: Boolean
);
begin
if AIsSet then
_tableView.selectAll(_tableView)
else
_tableView.deselectAll(_tableView);
end;
procedure TCocoaWSListView_TableViewHandler.SetDefaultItemHeight(
const AValue: Integer);
begin
if AValue > 0 then
_tableView.CustomRowHeight:= AValue;
// setRowSizeStyle could be used here but is available only in 10.7+
end;
procedure TCocoaWSListView_TableViewHandler.SetImageList(
const AList: TListViewImageList; const AValue: TCustomImageListResolution);
var
lclcb: TLCLListViewCallback;
lvil: TListViewImageList;
spacing: NSSize;
begin
lclcb:= getCallback;
if NOT Assigned(lclcb) then
Exit;
if NOT lclcb.GetImageListType(lvil) then
Exit;
if AList <> lvil then
Exit;
_tableView.lclSetImagesInCell(Assigned(AValue));
if NOT Assigned(AValue) then
Exit;
spacing:= _tableView.intercellSpacing;
spacing.height:= AValue.Height / 3 + 2;
if spacing.height < 6 then
spacing.height:= 6
else if spacing.height > 12 then
spacing.height:= 12;
_tableView.setIntercellSpacing( spacing );
end;
procedure TCocoaWSListView_TableViewHandler.SetItemsCount(
const Avalue: Integer);
begin
_tableView.noteNumberOfRowsChanged();
end;
procedure TCocoaWSListView_TableViewHandler.SetProperty(
const AProp: TListViewProperty; const AIsSet: Boolean);
const
GridStyle : array [boolean] of NSUInteger = (
NSTableViewGridNone,
NSTableViewSolidHorizontalGridLineMask or NSTableViewSolidVerticalGridLineMask
);
begin
case AProp of
{lvpAutoArrange,}
lvpCheckboxes: _tableView.lclSetFirstColumCheckboxes(AIsSet);
// lvpColumnClick: lTableLV.setAllowsColumnSelection(AIsSet);
{ lvpFlatScrollBars,
lvpFullDrag,}
lvpGridLines: _tableView.setGridStyleMask(GridStyle[AIsSet]);
{lvpHideSelection,
lvpHotTrack,}
lvpMultiSelect: _tableView.setAllowsMultipleSelection(AIsSet);
{lvpOwnerDraw,}
lvpReadOnly: _tableView.readOnly := AIsSet;
{ lvpRowSelect,}
lvpShowColumnHeaders:
if (AIsSet <> Assigned(_tableView.headerView)) then
begin
if AIsSet then _tableView.setHeaderView ( NSTableHeaderView.alloc.init.autorelease )
else _tableView.setHeaderView(nil);
end;
{ lvpShowWorkAreas,
lvpWrapText,
lvpToolTips}
end;
end;
procedure TCocoaWSListView_TableViewHandler.SetScrollBars(
const AValue: TScrollStyle);
begin
ScrollViewSetScrollStyles(_listView.scrollView, AValue);
{$ifdef BOOLFIX}
_listView.setNeedsDisplay__(Ord(true));
{$else}
_listView.setNeedsDisplay_(true);
{$endif}
{$ifdef BOOLFIX}
_tableView.setNeedsDisplay__(Ord(true));
{$else}
_tableView.setNeedsDisplay_(true);
{$endif}
end;
procedure TCocoaWSListView_TableViewHandler.SetSort(const AType: TSortType;
const AColumn: Integer; const ASortDirection: TSortDirection);
var
lclcb: TLCLListViewCallback;
begin
lclcb:= getCallback;
if NOT Assigned(lclcb) then
Exit;
if TCocoaListView(lclcb.Owner).initializing then
Exit;
if Assigned(lclcb.checkedIdx) then
lclcb.checkedIdx.removeAllIndexes;
lclcb.selectionIndexSet.removeAllIndexes;
_tableView.reloadData();
{ //todo:
lNSColumn.setSortDescriptorPrototype(
NSSortDescriptor.sortDescriptorWithKey_ascending_selector(
NSSTR('none'),
ASortDirection=sdAscending,
objcselector('none:')
)
);}
end;
end.

View File

@ -31,7 +31,7 @@ uses
Types, Classes, SysUtils,
Math, // needed for MinDouble, MaxDouble
// Libs
MacOSAll, CocoaAll, CocoaUtils, CocoaGDIObjects, CocoaPrivate,
MacOSAll, CocoaAll, CocoaUtils, CocoaGDIObjects, CocoaPrivate, CocoaCallback,
// LCL
LCLType;

View File

@ -27,7 +27,7 @@ uses
Types, Classes, SysUtils,
// Libs
MacOSAll, CocoaAll, CocoaUtils, CocoaCursor,
cocoa_extra, CocoaPrivate, CocoaTextEdits, CocoaScrollers,
cocoa_extra, CocoaPrivate, CocoaCallback, CocoaTextEdits, CocoaScrollers,
// LCL
//Forms,
LCLType, LCLProc;

View File

@ -29,8 +29,8 @@ uses
// Widgetset
WSCheckLst, WSLCLClasses,
// LCL Cocoa
CocoaWSCommon, CocoaPrivate, CocoaUtils, CocoaWSStdCtrls, CocoaTables,
CocoaScrollers, CocoaWSScrollers;
CocoaWSCommon, CocoaPrivate, CocoaCallback, CocoaUtils, CocoaWSStdCtrls,
CocoaTables, CocoaScrollers, CocoaWSScrollers;
type

File diff suppressed because it is too large Load Diff

View File

@ -10,7 +10,8 @@ interface
uses
Types, Classes, Controls, SysUtils,
WSControls, LCLType, LCLMessageGlue, LMessages, LCLProc, LCLIntf, Graphics, Forms,
CocoaAll, CocoaInt, CocoaConfig, CocoaPrivate, CocoaUtils,
StdCtrls,
CocoaAll, CocoaInt, CocoaConfig, CocoaPrivate, CocoaCallback, CocoaUtils,
CocoaScrollers, CocoaWSScrollers,
CocoaGDIObjects, CocoaCursor, CocoaCaret, cocoa_extra;
@ -172,6 +173,8 @@ type
end;
procedure UpdateFocusRing(v: NSView; astyle: TBorderStyle);
procedure ScrollViewSetScrollStyles(AScroll: TCocoaScrollView; AStyles: TScrollStyle);
procedure ScrollViewSetBorderStyle(sv: NSScrollView; astyle: TBorderStyle);
function ButtonStateToShiftState(BtnState: PtrUInt): TShiftState;
function CocoaModifiersToKeyState(AModifiers: NSUInteger): PtrInt;
@ -182,6 +185,37 @@ function NSObjectDebugStr(obj: NSObject): string;
function CallbackDebugStr(cb: ICommonCallback): string;
procedure DebugDumpParents(fromView: NSView);
const
VerticalScrollerVisible: array[TScrollStyle] of boolean = (
{ssNone } false,
{ssHorizontal } false,
{ssVertical } true,
{ssBoth } true,
{ssAutoHorizontal} false,
{ssAutoVertical } true,
{ssAutoBoth } true
);
HorizontalScrollerVisible: array[TScrollStyle] of boolean = (
{ssNone } false,
{ssHorizontal } true,
{ssVertical } false,
{ssBoth } true,
{ssAutoHorizontal} true,
{ssAutoVertical } false,
{ssAutoBoth } true
);
ScrollerAutoHide: array[TScrollStyle] of boolean = (
{ssNone } false,
{ssHorizontal } false,
{ssVertical } false,
{ssBoth } false,
{ssAutoHorizontal} true,
{ssAutoVertical } true,
{ssAutoBoth } true
);
implementation
uses
@ -230,6 +264,13 @@ begin
v.setFocusRingType( NSFocusRing[astyle] );
end;
procedure ScrollViewSetScrollStyles(AScroll: TCocoaScrollView; AStyles: TScrollStyle);
begin
AScroll.setHasVerticalScroller(VerticalScrollerVisible[AStyles]);
AScroll.setHasHorizontalScroller(HorizontalScrollerVisible[AStyles]);
AScroll.setAutohidesScrollers(ScrollerAutoHide[AStyles]);
end;
{ TLCLCommonCallback }
function TLCLCommonCallback.GetHasCaret: Boolean;
@ -1982,6 +2023,17 @@ begin
end;
end;
procedure ScrollViewSetBorderStyle(sv: NSScrollView; astyle: TBorderStyle);
const
NSBorderStyle : array [TBorderStyle] of NSBorderType = (
NSNoBorder, // bsNone
NSBezelBorder // bsSingle (NSLineBorder is too thick)
);
begin
if not Assigned(sv) then Exit;
sv.setBorderType( NSBorderStyle[astyle] );
end;
initialization
ASyncLCLControlAdjustSizer:= TASyncLCLControlAdjustSizer.Create;

View File

@ -18,7 +18,8 @@ uses
CocoaWSDialogs,
CocoaWSSpin,
CocoaWSCheckLst,
CocoaWSDatePicker;
CocoaWSDatePicker,
CocoaWSListView;
// imglist
function RegisterCustomImageListResolution: Boolean;

View File

@ -30,7 +30,7 @@ uses
// Widgetset
WSForms, WSLCLClasses, LCLMessageGlue,
// LCL Cocoa
CocoaInt, CocoaConfig, CocoaPrivate, CocoaUtils, CocoaWSCommon, CocoaMenus,
CocoaInt, CocoaConfig, CocoaPrivate, CocoaCallback, CocoaUtils, CocoaWSCommon, CocoaMenus,
CocoaGDIObjects,
CocoaWindows, CocoaScrollers, CocoaWSScrollers, cocoa_extra;

View File

@ -0,0 +1,577 @@
unit CocoaWSListView;
{$mode delphi}
{$modeswitch objectivec2}
{$include cocoadefines.inc}
interface
uses
Classes, SysUtils, LCLType,
Controls, ComCtrls, Types, StdCtrls, LCLProc, Graphics, ImgList, Forms,
WSComCtrls,
MacOSAll, CocoaAll, CocoaPrivate, CocoaWSCommon,
CocoaListView, CocoaTables, CocoaCollectionView;
type
{ TCocoaWSCustomListView }
TCocoaWSCustomListView = class(TWSCustomListView)
private
class function getWSHandler( const lclListView: TCustomListView ):
TCocoaWSListViewHandler;
class function getCallback( const lclListView: TCustomListView ):
TLCLListViewCallback;
published
class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLHandle; override;
class procedure SetBorderStyle(const AWinControl: TWinControl; const ABorderStyle: TBorderStyle); override;
// Column
class procedure ColumnDelete(const ALV: TCustomListView; const AIndex: Integer); override;
class function ColumnGetWidth(const ALV: TCustomListView; const AIndex: Integer; const {%H-}AColumn: TListColumn): Integer; override;
class procedure ColumnInsert(const ALV: TCustomListView; const AIndex: Integer; const AColumn: TListColumn); override;
class procedure ColumnMove(const ALV: TCustomListView; const AOldIndex, ANewIndex: Integer; const AColumn: TListColumn); override;
class procedure ColumnSetAlignment(const ALV: TCustomListView; const AIndex: Integer; const {%H-}AColumn: TListColumn; const AAlignment: TAlignment); override;
class procedure ColumnSetAutoSize(const ALV: TCustomListView; const AIndex: Integer; const {%H-}AColumn: TListColumn; const AAutoSize: Boolean); override;
class procedure ColumnSetCaption(const ALV: TCustomListView; const AIndex: Integer; const {%H-}AColumn: TListColumn; const ACaption: String); override;
class procedure ColumnSetMaxWidth(const ALV: TCustomListView; const AIndex: Integer; const {%H-}AColumn: TListColumn; const AMaxWidth: Integer); override;
class procedure ColumnSetMinWidth(const ALV: TCustomListView; const AIndex: Integer; const {%H-}AColumn: TListColumn; const AMinWidth: integer); override;
class procedure ColumnSetWidth(const ALV: TCustomListView; const AIndex: Integer; const {%H-}AColumn: TListColumn; const AWidth: Integer); override;
class procedure ColumnSetVisible(const ALV: TCustomListView; const AIndex: Integer; const {%H-}AColumn: TListColumn; const AVisible: Boolean); override;
class procedure ColumnSetSortIndicator(const ALV: TCustomListView; const AIndex: Integer; const AColumn: TListColumn; const ASortIndicator: TSortIndicator); override;
// Item
class procedure ItemDelete(const ALV: TCustomListView; const AIndex: Integer); override;
class function ItemDisplayRect(const ALV: TCustomListView; const AIndex, ASubItem: Integer; ACode: TDisplayCode): TRect; override;
class function ItemGetChecked(const ALV: TCustomListView; const AIndex: Integer; const {%H-}AItem: TListItem): Boolean; override;
class function ItemGetPosition(const ALV: TCustomListView; const AIndex: Integer): TPoint; override;
class function ItemGetState(const ALV: TCustomListView; const AIndex: Integer; const {%H-}AItem: TListItem; const AState: TListItemState; out AIsSet: Boolean): Boolean; override; // returns True if supported
class procedure ItemInsert(const ALV: TCustomListView; const AIndex: Integer; const {%H-}AItem: TListItem); override;
class procedure ItemSetChecked(const ALV: TCustomListView; const AIndex: Integer; const {%H-}AItem: TListItem; const AChecked: Boolean); override;
class procedure ItemSetImage(const ALV: TCustomListView; const AIndex: Integer; const {%H-}AItem: TListItem; const {%H-}ASubIndex, {%H-}AImageIndex: Integer); override;
//carbon//class function ItemSetPosition(const ALV: TCustomListView; const AIndex: Integer; const ANewPosition: TPoint): Boolean; override;*)
class procedure ItemSetState(const ALV: TCustomListView; const AIndex: Integer; const {%H-}AItem: TListItem; const AState: TListItemState; const AIsSet: Boolean); override;
class procedure ItemSetText(const ALV: TCustomListView; const AIndex: Integer; const {%H-}AItem: TListItem; const {%H-}ASubIndex: Integer; const {%H-}AText: String); override;
class procedure ItemShow(const ALV: TCustomListView; const AIndex: Integer; const {%H-}AItem: TListItem; const PartialOK: Boolean); override;
// LV
//available in 10.7 only//class procedure BeginUpdate(const ALV: TCustomListView); override;
//available in 10.7 only//class procedure EndUpdate(const ALV: TCustomListView); override;
//class function GetBoundingRect(const ALV: TCustomListView): TRect; override;
//carbon//class function GetDropTarget(const ALV: TCustomListView): Integer; override;
class function GetFocused(const ALV: TCustomListView): Integer; override;
//carbon//class function GetHoverTime(const ALV: TCustomListView): Integer; override;
class function GetItemAt(const ALV: TCustomListView; x,y: integer): Integer; override;
class function GetSelCount(const ALV: TCustomListView): Integer; override;
class function GetSelection(const ALV: TCustomListView): Integer; override;
class function GetTopItem(const ALV: TCustomListView): Integer; override;
//class function GetViewOrigin(const ALV: TCustomListView): TPoint; override;
class function GetVisibleRowCount(const ALV: TCustomListView): Integer; override;
class procedure SelectAll(const ALV: TCustomListView; const AIsSet: Boolean); override;
//carbon//class procedure SetAllocBy(const ALV: TCustomListView; const AValue: Integer); override;
class procedure SetDefaultItemHeight(const ALV: TCustomListView; const AValue: Integer); override;
//carbon//class procedure SetHotTrackStyles(const ALV: TCustomListView; const AValue: TListHotTrackStyles); override;
//carbon//class procedure SetHoverTime(const ALV: TCustomListView; const AValue: Integer); override;
class procedure SetImageList(const ALV: TCustomListView; const {%H-}AList: TListViewImageList; const {%H-}AValue: TCustomImageListResolution); override;
class procedure SetItemsCount(const ALV: TCustomListView; const Avalue: Integer); override;
class procedure SetOwnerData(const ALV: TCustomListView; const {%H-}AValue: Boolean); override;
class procedure SetProperty(const ALV: TCustomListView; const AProp: TListViewProperty; const AIsSet: Boolean); override;
//class procedure SetProperties(const ALV: TCustomListView; const AProps: TListViewProperties); override;
class procedure SetScrollBars(const ALV: TCustomListView; const AValue: TScrollStyle); override;
class procedure SetSort(const ALV: TCustomListView; const {%H-}AType: TSortType; const {%H-}AColumn: Integer;
const {%H-}ASortDirection: TSortDirection); override;
class function RestoreItemCheckedAfterSort(const ALV: TCustomListView): Boolean; override;
(*class procedure SetViewOrigin(const ALV: TCustomListView; const AValue: TPoint); override;*)
class procedure SetViewStyle(const ALV: TCustomListView; const AValue: TViewStyle); override;
end;
implementation
type
TCustomListViewAccess = class(TCustomListView);
procedure CocoaListViewAllocFuncImpl(const listView: NSView; const viewStyle: TViewStyle; out backendControl: NSView; out WSHandler: TCocoaWSListViewHandler );
var
cocoaListView: TCocoaListView Absolute listView;
begin
if viewStyle = vsReport then begin
backendControl:= AllocCocoaTableListView;
WSHandler:= TCocoaWSListView_TableViewHandler.Create( cocoaListView );
end else begin
backendControl:= AllocCocoaCollectionView( viewStyle );
WSHandler:= TCocoaWSListView_CollectionViewHandler.Create( cocoaListView );
end;
end;
{ TCocoaWSCustomListView }
class function TCocoaWSCustomListView.getWSHandler(
const lclListView: TCustomListView): TCocoaWSListViewHandler;
var
cocoaListView: TCocoaListView;
begin
Result:= nil;
if NOT Assigned(lclListView) or NOT lclListView.HandleAllocated then
Exit;
cocoaListView:= TCocoaListView( lclListView.Handle );
if NOT Assigned(cocoaListView) then
Exit;
Result:= cocoaListView.WSHandler;
end;
class function TCocoaWSCustomListView.getCallback(
const lclListView: TCustomListView): TLCLListViewCallback;
var
cocoaListView: TCocoaListView;
begin
Result:= nil;
if NOT Assigned(lclListView) or NOT lclListView.HandleAllocated then
Exit;
cocoaListView:= TCocoaListView( lclListView.Handle );
if NOT Assigned(cocoaListView) then
Exit;
Result:= cocoaListView.callback;
end;
class function TCocoaWSCustomListView.CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLHandle;
var
cocoaListView: TCocoaListView;
lclListView: TCustomListViewAccess Absolute AWinControl;
lclcb: TLCLListViewCallback;
begin
cocoaListView:= TCocoaListView.alloc.lclInitWithCreateParams(AParams);
cocoaListView.setAutoresizesSubviews( True );
cocoaListView.setAllocFunc( CocoaListViewAllocFuncImpl );
lclcb := TLCLListViewCallback.Create( cocoaListView, lclListView, cocoaListView );
lclcb.listView := lclListView;
cocoaListView.callback:= lclcb;
Result:= TLCLHandle( cocoaListView );
end;
class procedure TCocoaWSCustomListView.SetBorderStyle(
const AWinControl: TWinControl; const ABorderStyle: TBorderStyle);
var
cocoaListView: TCocoaListView;
begin
if not Assigned(AWinControl) or not AWinControl.HandleAllocated then Exit;
cocoaListView:= TCocoaListView(AWinControl.Handle);
ScrollViewSetBorderStyle(cocoaListView.scrollView, ABorderStyle);
UpdateFocusRing(cocoaListView.documentView, ABorderStyle);
end;
class procedure TCocoaWSCustomListView.ColumnDelete(const ALV: TCustomListView;
const AIndex: Integer);
var
WSHandler: TCocoaWSListViewHandler;
begin
WSHandler:= getWSHandler( ALV );
if Assigned(WSHandler) then
WSHandler.ColumnDelete( AIndex );
end;
class function TCocoaWSCustomListView.ColumnGetWidth(
const ALV: TCustomListView; const AIndex: Integer; const AColumn: TListColumn
): Integer;
var
WSHandler: TCocoaWSListViewHandler;
begin
Result:= 0;
WSHandler:= getWSHandler( ALV );
if Assigned(WSHandler) then
Result:= WSHandler.ColumnGetWidth( AIndex, AColumn );
end;
class procedure TCocoaWSCustomListView.ColumnInsert(const ALV: TCustomListView;
const AIndex: Integer; const AColumn: TListColumn);
var
WSHandler: TCocoaWSListViewHandler;
begin
WSHandler:= getWSHandler( ALV );
if Assigned(WSHandler) then
WSHandler.ColumnInsert( AIndex, AColumn );
end;
class procedure TCocoaWSCustomListView.ColumnMove(const ALV: TCustomListView;
const AOldIndex, ANewIndex: Integer; const AColumn: TListColumn);
var
WSHandler: TCocoaWSListViewHandler;
begin
WSHandler:= getWSHandler( ALV );
if Assigned(WSHandler) then
WSHandler.ColumnMove( AOldIndex, ANewIndex, AColumn );
end;
class procedure TCocoaWSCustomListView.ColumnSetAlignment(
const ALV: TCustomListView; const AIndex: Integer;
const AColumn: TListColumn; const AAlignment: TAlignment);
var
WSHandler: TCocoaWSListViewHandler;
begin
WSHandler:= getWSHandler( ALV );
if Assigned(WSHandler) then
WSHandler.ColumnSetAlignment( AIndex, AColumn, AAlignment );
end;
class procedure TCocoaWSCustomListView.ColumnSetAutoSize(
const ALV: TCustomListView; const AIndex: Integer;
const AColumn: TListColumn; const AAutoSize: Boolean);
var
WSHandler: TCocoaWSListViewHandler;
begin
WSHandler:= getWSHandler( ALV );
if Assigned(WSHandler) then
WSHandler.ColumnSetAutoSize( AIndex, AColumn, AAutoSize );
end;
class procedure TCocoaWSCustomListView.ColumnSetCaption(
const ALV: TCustomListView; const AIndex: Integer;
const AColumn: TListColumn; const ACaption: String);
var
WSHandler: TCocoaWSListViewHandler;
begin
WSHandler:= getWSHandler( ALV );
if Assigned(WSHandler) then
WSHandler.ColumnSetCaption( AIndex, AColumn, ACaption );
end;
class procedure TCocoaWSCustomListView.ColumnSetMaxWidth(
const ALV: TCustomListView; const AIndex: Integer;
const AColumn: TListColumn; const AMaxWidth: Integer);
var
WSHandler: TCocoaWSListViewHandler;
begin
WSHandler:= getWSHandler( ALV );
if Assigned(WSHandler) then
WSHandler.ColumnSetMaxWidth( AIndex, AColumn, AMaxWidth );
end;
class procedure TCocoaWSCustomListView.ColumnSetMinWidth(
const ALV: TCustomListView; const AIndex: Integer;
const AColumn: TListColumn; const AMinWidth: integer);
var
WSHandler: TCocoaWSListViewHandler;
begin
WSHandler:= getWSHandler( ALV );
if Assigned(WSHandler) then
WSHandler.ColumnSetMinWidth( AIndex, AColumn, AMinWidth );
end;
class procedure TCocoaWSCustomListView.ColumnSetWidth(
const ALV: TCustomListView; const AIndex: Integer;
const AColumn: TListColumn; const AWidth: Integer);
var
WSHandler: TCocoaWSListViewHandler;
begin
WSHandler:= getWSHandler( ALV );
if Assigned(WSHandler) then
WSHandler.ColumnSetWidth( AIndex, AColumn, AWidth );
end;
class procedure TCocoaWSCustomListView.ColumnSetVisible(
const ALV: TCustomListView; const AIndex: Integer;
const AColumn: TListColumn; const AVisible: Boolean);
var
WSHandler: TCocoaWSListViewHandler;
begin
WSHandler:= getWSHandler( ALV );
if Assigned(WSHandler) then
WSHandler.ColumnSetVisible( AIndex, AColumn, AVisible );
end;
class procedure TCocoaWSCustomListView.ColumnSetSortIndicator(
const ALV: TCustomListView; const AIndex: Integer;
const AColumn: TListColumn; const ASortIndicator: TSortIndicator);
var
WSHandler: TCocoaWSListViewHandler;
begin
WSHandler:= getWSHandler( ALV );
if Assigned(WSHandler) then
WSHandler.ColumnSetSortIndicator( AIndex, AColumn, ASortIndicator );
end;
class procedure TCocoaWSCustomListView.ItemDelete(const ALV: TCustomListView;
const AIndex: Integer);
var
WSHandler: TCocoaWSListViewHandler;
begin
WSHandler:= getWSHandler( ALV );
if Assigned(WSHandler) then
WSHandler.ItemDelete( AIndex );
end;
class function TCocoaWSCustomListView.ItemDisplayRect(
const ALV: TCustomListView; const AIndex, ASubItem: Integer;
ACode: TDisplayCode): TRect;
var
WSHandler: TCocoaWSListViewHandler;
begin
Result:= Bounds(0,0,0,0);
WSHandler:= getWSHandler( ALV );
if Assigned(WSHandler) then
Result:= WSHandler.ItemDisplayRect( AIndex, ASubItem, ACode );
end;
class function TCocoaWSCustomListView.ItemGetChecked(
const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem
): Boolean;
var
WSHandler: TCocoaWSListViewHandler;
begin
Result:= False;
WSHandler:= getWSHandler( ALV );
if Assigned(WSHandler) then
Result:= WSHandler.ItemGetChecked( AIndex, AItem );
end;
class function TCocoaWSCustomListView.ItemGetPosition(
const ALV: TCustomListView; const AIndex: Integer): TPoint;
var
WSHandler: TCocoaWSListViewHandler;
begin
Result:= TPoint.Create( 0, 0 );
WSHandler:= getWSHandler( ALV );
if Assigned(WSHandler) then
Result:= WSHandler.ItemGetPosition( AIndex );
end;
class function TCocoaWSCustomListView.ItemGetState(const ALV: TCustomListView;
const AIndex: Integer; const AItem: TListItem; const AState: TListItemState;
out AIsSet: Boolean): Boolean;
var
WSHandler: TCocoaWSListViewHandler;
begin
Result:= False;
WSHandler:= getWSHandler( ALV );
if Assigned(WSHandler) then
Result:= WSHandler.ItemGetState( AIndex, AItem, AState, AIsSet );
end;
class procedure TCocoaWSCustomListView.ItemInsert(const ALV: TCustomListView;
const AIndex: Integer; const AItem: TListItem);
var
WSHandler: TCocoaWSListViewHandler;
begin
WSHandler:= getWSHandler( ALV );
if Assigned(WSHandler) then
WSHandler.ItemInsert( AIndex, AItem );
end;
class procedure TCocoaWSCustomListView.ItemSetChecked(
const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem;
const AChecked: Boolean);
var
WSHandler: TCocoaWSListViewHandler;
begin
WSHandler:= getWSHandler( ALV );
if Assigned(WSHandler) then
WSHandler.ItemSetChecked( AIndex, AItem, AChecked );
end;
class procedure TCocoaWSCustomListView.ItemSetImage(const ALV: TCustomListView;
const AIndex: Integer; const AItem: TListItem; const ASubIndex,
AImageIndex: Integer);
var
WSHandler: TCocoaWSListViewHandler;
begin
WSHandler:= getWSHandler( ALV );
if Assigned(WSHandler) then
WSHandler.ItemSetImage( AIndex, AItem, ASubIndex, AImageIndex );
end;
class procedure TCocoaWSCustomListView.ItemSetState(const ALV: TCustomListView;
const AIndex: Integer; const AItem: TListItem; const AState: TListItemState;
const AIsSet: Boolean);
var
WSHandler: TCocoaWSListViewHandler;
begin
WSHandler:= getWSHandler( ALV );
if Assigned(WSHandler) then
WSHandler.ItemSetState( AIndex, AItem, AState, AIsSet );
end;
class procedure TCocoaWSCustomListView.ItemSetText(const ALV: TCustomListView;
const AIndex: Integer; const AItem: TListItem; const ASubIndex: Integer;
const AText: String);
var
WSHandler: TCocoaWSListViewHandler;
begin
WSHandler:= getWSHandler( ALV );
if Assigned(WSHandler) then
WSHandler.ItemSetText( AIndex, AItem, ASubIndex, AText );
end;
class procedure TCocoaWSCustomListView.ItemShow(const ALV: TCustomListView;
const AIndex: Integer; const AItem: TListItem; const PartialOK: Boolean);
var
WSHandler: TCocoaWSListViewHandler;
begin
WSHandler:= getWSHandler( ALV );
if Assigned(WSHandler) then
WSHandler.ItemShow( AIndex, AItem, PartialOK );
end;
class function TCocoaWSCustomListView.GetFocused(const ALV: TCustomListView): Integer;
var
WSHandler: TCocoaWSListViewHandler;
begin
Result:= -1;
WSHandler:= getWSHandler( ALV );
if Assigned(WSHandler) then
Result:= WSHandler.GetFocused();
end;
class function TCocoaWSCustomListView.GetItemAt(const ALV: TCustomListView; x,
y: integer): Integer;
var
WSHandler: TCocoaWSListViewHandler;
begin
Result:= -1;
WSHandler:= getWSHandler( ALV );
if Assigned(WSHandler) then
Result:= WSHandler.GetItemAt( x, y );
end;
class function TCocoaWSCustomListView.GetSelCount(const ALV: TCustomListView): Integer;
var
WSHandler: TCocoaWSListViewHandler;
begin
Result:= 0;
WSHandler:= getWSHandler( ALV );
if Assigned(WSHandler) then
Result:= WSHandler.GetSelCount();
end;
class function TCocoaWSCustomListView.GetSelection(const ALV: TCustomListView): Integer;
var
WSHandler: TCocoaWSListViewHandler;
begin
Result:= -1;
WSHandler:= getWSHandler( ALV );
if Assigned(WSHandler) then
Result:= WSHandler.GetSelection();
end;
class function TCocoaWSCustomListView.GetTopItem(const ALV: TCustomListView): Integer;
var
WSHandler: TCocoaWSListViewHandler;
begin
Result:= 0;
WSHandler:= getWSHandler( ALV );
if Assigned(WSHandler) then
Result:= WSHandler.GetTopItem();
end;
class function TCocoaWSCustomListView.GetVisibleRowCount(
const ALV: TCustomListView): Integer;
var
WSHandler: TCocoaWSListViewHandler;
begin
Result:= 0;
WSHandler:= getWSHandler( ALV );
if Assigned(WSHandler) then
Result:= WSHandler.GetVisibleRowCount();
end;
class procedure TCocoaWSCustomListView.SelectAll(const ALV: TCustomListView;
const AIsSet: Boolean);
var
WSHandler: TCocoaWSListViewHandler;
begin
WSHandler:= getWSHandler( ALV );
if Assigned(WSHandler) then
WSHandler.SelectAll( AIsSet );
end;
class procedure TCocoaWSCustomListView.SetDefaultItemHeight(
const ALV: TCustomListView; const AValue: Integer);
var
WSHandler: TCocoaWSListViewHandler;
begin
WSHandler:= getWSHandler( ALV );
if Assigned(WSHandler) then
WSHandler.SetDefaultItemHeight( AValue );
end;
class procedure TCocoaWSCustomListView.SetImageList(const ALV: TCustomListView;
const AList: TListViewImageList; const AValue: TCustomImageListResolution);
var
WSHandler: TCocoaWSListViewHandler;
begin
WSHandler:= getWSHandler( ALV );
if Assigned(WSHandler) then
WSHandler.SetImageList( AList, AValue );
end;
class procedure TCocoaWSCustomListView.SetItemsCount(
const ALV: TCustomListView; const Avalue: Integer);
var
WSHandler: TCocoaWSListViewHandler;
begin
WSHandler:= getWSHandler( ALV );
if Assigned(WSHandler) then
WSHandler.SetItemsCount( AValue );
end;
class procedure TCocoaWSCustomListView.SetOwnerData(const ALV: TCustomListView;
const AValue: Boolean);
var
lclcb: TLCLListViewCallback;
begin
lclcb:= self.getCallback( ALV );
if NOT Assigned(lclcb) then
Exit;
lclcb.ownerData := AValue;
if lclcb.ownerData then
lclcb.checkedIdx.removeAllIndexes; // releasing memory
end;
class procedure TCocoaWSCustomListView.SetProperty(const ALV: TCustomListView;
const AProp: TListViewProperty; const AIsSet: Boolean);
var
WSHandler: TCocoaWSListViewHandler;
begin
WSHandler:= getWSHandler( ALV );
if Assigned(WSHandler) then
WSHandler.SetProperty( AProp, AIsSet );
end;
class procedure TCocoaWSCustomListView.SetScrollBars(
const ALV: TCustomListView; const AValue: TScrollStyle);
var
WSHandler: TCocoaWSListViewHandler;
begin
WSHandler:= getWSHandler( ALV );
if Assigned(WSHandler) then
WSHandler.SetScrollBars( AValue );
end;
class procedure TCocoaWSCustomListView.SetSort(const ALV: TCustomListView;
const AType: TSortType; const AColumn: Integer;
const ASortDirection: TSortDirection);
var
WSHandler: TCocoaWSListViewHandler;
begin
WSHandler:= getWSHandler( ALV );
if Assigned(WSHandler) then
WSHandler.SetSort( AType, AColumn, ASortDirection );
end;
class function TCocoaWSCustomListView.RestoreItemCheckedAfterSort(
const ALV: TCustomListView): Boolean;
begin
Result:= True;
end;
class procedure TCocoaWSCustomListView.SetViewStyle(const ALV: TCustomListView;
const AValue: TViewStyle);
var
cocoalistView: TCocoaListView;
begin
cocoalistView:= TCocoaListView( ALV.Handle );
cocoalistView.setViewStyle( AValue );
end;
end.

View File

@ -25,7 +25,6 @@ function EmbedInScrollView(AView: NSView; AReleaseView: Boolean = true): TCocoaS
function EmbedInManualScrollView(AView: NSView): TCocoaManualScrollView;
function EmbedInManualScrollHost(AView: TCocoaManualScrollView): TCocoaManualScrollHost;
procedure ScrollViewSetBorderStyle(sv: NSScrollView; astyle: TBorderStyle);
procedure LCLScrollViewAdjustSize(control: TWinControl);
var
@ -128,17 +127,6 @@ begin
SetViewDefaults(Result);
end;
procedure ScrollViewSetBorderStyle(sv: NSScrollView; astyle: TBorderStyle);
const
NSBorderStyle : array [TBorderStyle] of NSBorderType = (
NSNoBorder, // bsNone
NSBezelBorder // bsSingle (NSLineBorder is too thick)
);
begin
if not Assigned(sv) then Exit;
sv.setBorderType( NSBorderStyle[astyle] );
end;
procedure LCLScrollViewAdjustSize(control: TWinControl);
begin
if NSScroller.preferredScrollerStyle = NSScrollerStyleOverlay then

View File

@ -34,7 +34,7 @@ uses
WSStdCtrls, WSLCLClasses,
// LCL Cocoa
CocoaConst, CocoaConfig,
CocoaWSCommon, CocoaPrivate, CocoaUtils, CocoaGDIObjects, CocoaButtons,
CocoaWSCommon, CocoaPrivate, CocoaCallback, CocoaUtils, CocoaGDIObjects, CocoaButtons,
CocoaTables, CocoaTextEdits, CocoaScrollers, CocoaWSScrollers, Cocoa_Extra;
type
@ -368,8 +368,6 @@ procedure ButtonSetState(btn: NSButton; NewState: TCheckBoxState;
procedure TextFieldSetTextHint(txt: NSTextField; const str: string);
procedure ObjSetTextHint(obj: NSObject; const str: string);
procedure ScrollViewSetScrollStyles(AScroll: TCocoaScrollView; AStyles: TScrollStyle);
function ComboBoxStyleIsReadOnly(AStyle: TComboBoxStyle): Boolean;
function ComboBoxIsReadOnly(cmb: TCustomComboBox): Boolean;
function ComboBoxIsOwnerDrawn(AStyle: TComboBoxStyle): Boolean;
@ -384,37 +382,6 @@ procedure ControlSetTextWithChangeEvent(ctrl: NSControl; const text: string);
implementation
const
VerticalScrollerVisible: array[TScrollStyle] of boolean = (
{ssNone } false,
{ssHorizontal } false,
{ssVertical } true,
{ssBoth } true,
{ssAutoHorizontal} false,
{ssAutoVertical } true,
{ssAutoBoth } true
);
HorizontalScrollerVisible: array[TScrollStyle] of boolean = (
{ssNone } false,
{ssHorizontal } true,
{ssVertical } false,
{ssBoth } true,
{ssAutoHorizontal} true,
{ssAutoVertical } false,
{ssAutoBoth } true
);
ScrollerAutoHide: array[TScrollStyle] of boolean = (
{ssNone } false,
{ssHorizontal } false,
{ssVertical } false,
{ssBoth } false,
{ssAutoHorizontal} true,
{ssAutoVertical } true,
{ssAutoBoth } true
);
function AllocButton(const ATarget: TWinControl; const ACallBackClass: TLCLButtonCallBackClass; const AParams: TCreateParams; btnBezel: NSBezelStyle; btnType: NSButtonType): TCocoaButton;
begin
Result := TCocoaButton.alloc.lclInitWithCreateParams(AParams);
@ -510,13 +477,6 @@ begin
btn.setState(buttonState[NewState]);
end;
procedure ScrollViewSetScrollStyles(AScroll: TCocoaScrollView; AStyles: TScrollStyle);
begin
AScroll.setHasVerticalScroller(VerticalScrollerVisible[AStyles]);
AScroll.setHasHorizontalScroller(HorizontalScrollerVisible[AStyles]);
AScroll.setAutohidesScrollers(ScrollerAutoHide[AStyles]);
end;
procedure TextFieldSetTextHint(txt: NSTextField; const str: string);
var
ns : NSString;

View File

@ -131,7 +131,7 @@ end;"/>
<License Value="modified LGPL-2
"/>
<Version Major="3" Minor="99"/>
<Files Count="537">
<Files Count="540">
<Item1>
<Filename Value="carbon/agl.pp"/>
<AddToUsesPkgSection Value="False"/>
@ -2653,6 +2653,21 @@ end;"/>
<AddToUsesPkgSection Value="False"/>
<UnitName Value="cocoacollectionview"/>
</Item537>
<Item538>
<Filename Value="cocoa/cocoalistview.pas"/>
<AddToUsesPkgSection Value="False"/>
<UnitName Value="CocoaListView"/>
</Item538>
<Item539>
<Filename Value="cocoa/cocoawslistview.pas"/>
<AddToUsesPkgSection Value="False"/>
<UnitName Value="CocoaWSListView"/>
</Item539>
<Item540>
<Filename Value="cocoa/cocoacallback.pas"/>
<AddToUsesPkgSection Value="False"/>
<UnitName Value="CocoaCallback"/>
</Item540>
</Files>
<CompatibilityMode Value="True"/>
<LazDoc Paths="../../docs/xml/lcl"/>