mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-10 14:16:25 +02:00
cocoa: initial support for imageIndex in listview
git-svn-id: trunk@58780 -
This commit is contained in:
parent
d2ae489674
commit
b0c54b56dc
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user