cocoa: initial support for imageIndex in listview

git-svn-id: trunk@58780 -
This commit is contained in:
dmitry 2018-08-26 18:39:25 +00:00
parent d2ae489674
commit b0c54b56dc
2 changed files with 153 additions and 6 deletions

View File

@ -50,6 +50,8 @@ type
function ItemsCount: Integer;
function GetItemTextAt(ARow, ACol: Integer; var Text: String): Boolean;
function GetItemCheckedAt(ARow, ACol: Integer; var isChecked: Boolean): 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: Boolean);
procedure tableSelectionChange(ARow: Integer; Added, Removed: NSIndexSet);
@ -162,6 +164,8 @@ type
isFirstColumnCheckboxes: Boolean;
checkedIdx : NSMutableIndexSet;
smallimages : NSMutableDictionary;
function acceptsFirstResponder: Boolean; override;
function becomeFirstResponder: Boolean; override;
function resignFirstResponder: Boolean; override;
@ -198,6 +202,9 @@ type
procedure lclExpectedKeys(var wantTabs, wantKeys, wantAllKeys: Boolean); override;
procedure lclSetFirstColumCheckboxes(acheckboxes: Boolean); message 'lclSetFirstColumCheckboxes:';
procedure lclRegisterSmallImage(idx: Integer; img: NSImage); message 'lclRegisterSmallImage::';
function lclGetSmallImage(idx: INteger): NSImage; message 'lclGetSmallImage:';
// NSTableViewDataSourceProtocol
function numberOfRowsInTableView(tableView: NSTableView): NSInteger; message 'numberOfRowsInTableView:';
function tableView_objectValueForTableColumn_row(tableView: NSTableView; tableColumn: NSTableColumn; row: NSInteger): id; message 'tableView:objectValueForTableColumn:row:';
@ -237,8 +244,38 @@ type
procedure tableViewSelectionIsChanging(notification: NSNotification); message 'tableViewSelectionIsChanging:';}
end;
{ NSImageAndTextCell }
NSImageAndTextCell = objcclass(NSTextFieldCell)
drawImage : NSImage;
procedure drawWithFrame_inView(cellFrame: NSRect; controlView_: NSView); override;
end;
implementation
{ NSImageAndTextCell }
procedure NSImageAndTextCell.drawWithFrame_inView(cellFrame: NSRect;
controlView_: NSView);
var
r : NSRect;
srcsz : NSSize;
begin
r:=cellFrame;
cellFrame.origin.x:=cellFrame.origin.x+cellFrame.size.height;
cellFrame.size.width:=cellFrame.size.width-cellFrame.size.height;
inherited drawWithFrame_inView(cellFrame, controlView_);
if Assigned(drawImage) then
begin
r.size.width:=r.size.height;
srcsz := drawImage.size;
drawImage.drawInRect_fromRect_operation_fraction_respectFlipped_hints(
r, NSMakeRect(0,0, srcsz.width, srcsz.height), NSCompositeSourceOver, 1, true, nil
);
end;
end;
{ TCocoaListBox }
function TCocoaListBox.lclIsHandle: Boolean;
@ -585,6 +622,23 @@ begin
reloadData();
end;
procedure TCocoaTableListView.lclRegisterSmallImage(idx: Integer; img: NSImage);
begin
if not Assigned(smallimages) then
smallimages := (NSMutableDictionary.alloc).init;
if Assigned(img) then
smallimages.setObject_forKey(img, NSNumber.numberWithInt(idx) )
else
smallimages.removeObjectForKey( NSNumber.numberWithInt(idx) );
end;
function TCocoaTableListView.lclGetSmallImage(idx: INteger): NSImage;
begin
if not Assigned(smallimages) then Result := nil;
Result := NSImage(smallimages.objectForKey( NSNumber.numberWithInt(idx) ) );
end;
function TCocoaTableListView.acceptsFirstResponder: Boolean;
begin
Result := True;
@ -615,7 +669,8 @@ end;
procedure TCocoaTableListView.dealloc;
begin
//if Assigned(Items) then FreeAndNil(Items);
checkedIdx.release;
if Assigned(checkedIdx) then checkedIdx.release;
if Assigned(smallimages) then smallimages.release; // all contents is released automatically
inherited dealloc;
end;
@ -937,14 +992,33 @@ var
txt : string;
col : Integer;
nstxt : NSString;
idx : Integer;
img : NSImage;
begin
Result:=nil;
if not isFirstColumnCheckboxes then Exit;
//writeln('getting dataCell row=',row,' col=',getIndexOfColumn(tableColumn));
col := getIndexOfColumn(tableColumn);
if (col <> 0) then Exit;
if not isFirstColumnCheckboxes then begin
idx := -1;
callback.GetItemImageAt(row, col, idx);
if idx>=0 then
begin
img := lclGetSmallImage(idx);
if not Assigned(img) then begin
img := callback.GetImageFromIndex(idx);
if Assigned(img) then lclRegisterSmallImage(idx, img);
end;
end else
img := nil;
if Assigned(img) then begin
Result := NSImageAndTextCell(NSImageAndTextCell.alloc).initTextCell(NSSTR(''));
NSImageAndTextCell(Result).drawImage := img; // if "image" is assigned, text won't be drawn :(
end;
Exit;
end;
txt := '';
chk := false;

View File

@ -18,7 +18,7 @@ uses
WSComCtrls,
// Cocoa WS
CocoaPrivate, CocoaScrollers, CocoaTabControls, CocoaUtils,
CocoaWSCommon, CocoaTables, cocoa_extra, CocoaWSStdCtrls;
CocoaWSCommon, CocoaTables, cocoa_extra, CocoaWSStdCtrls, CocoaGDIObjects;
type
@ -124,7 +124,7 @@ type
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;
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;
@ -240,6 +240,8 @@ type
function ItemsCount: Integer;
function GetItemTextAt(ARow, ACol: Integer; var Text: String): Boolean;
function GetItemCheckedAt(ARow, ACol: Integer; var IsChecked: Boolean): 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: Boolean);
procedure tableSelectionChange(NewSel: Integer; Added, Removed: NSIndexSet);
@ -1057,6 +1059,18 @@ begin
lTableLV.reloadData();
end;
class procedure TCocoaWSCustomListView.ItemSetImage(const ALV: TCustomListView;
const AIndex: Integer; const AItem: TListItem; const ASubIndex,
AImageIndex: Integer);
var
lCocoaLV: TCocoaListView;
lTableLV: TCocoaTableListView;
begin
if not CheckParams(lCocoaLV, lTableLV, ALV) then Exit;
// todo: make a specific row/column reload data!
lTableLV.reloadData();
end;
class procedure TCocoaWSCustomListView.ItemSetState(const ALV: TCustomListView;
const AIndex: Integer; const AItem: TListItem; const AState: TListItemState;
const AIsSet: Boolean);
@ -1365,6 +1379,65 @@ begin
IsChecked := listView.Items[ARow].Checked;
end;
function TLCLListViewCallback.GetItemImageAt(ARow, ACol: Integer;
var imgIdx: Integer): Boolean;
begin
Result := (ARow >= 0) and (ARow<listView.Items.Count);
if not Result then Exit;
imgIdx := listView.Items[ARow].ImageIndex;
end;
type
TSmallImagesAccess = class(TCustomListView);
function TLCLListViewCallback.GetImageFromIndex(imgIdx: Integer): NSImage;
var
bmp : TBitmap;
lst : TCustomImageList;
x,y : integer;
img : NSImage;
rep : NSBitmapImageRep;
cb : TCocoaBitmap;
begin
lst := TSmallImagesAccess(listView).SmallImages;
bmp := TBitmap.Create;
try
lst.GetBitmap(imgIdx, bmp);
if bmp.Handle = 0 then begin
Result := nil;
Exit;
end;
// 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;
finally
bmp.Free;
end;
end;
procedure TLCLListViewCallback.SetItemTextAt(ARow, ACol: Integer;
const Text: String);
begin