mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-14 20:39:09 +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 ItemsCount: Integer;
|
||||||
function GetItemTextAt(ARow, ACol: Integer; var Text: String): Boolean;
|
function GetItemTextAt(ARow, ACol: Integer; var Text: String): Boolean;
|
||||||
function GetItemCheckedAt(ARow, ACol: Integer; var isChecked: Boolean): 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 SetItemTextAt(ARow, ACol: Integer; const Text: String);
|
||||||
procedure SetItemCheckedAt(ARow, ACol: Integer; isChecked: Boolean);
|
procedure SetItemCheckedAt(ARow, ACol: Integer; isChecked: Boolean);
|
||||||
procedure tableSelectionChange(ARow: Integer; Added, Removed: NSIndexSet);
|
procedure tableSelectionChange(ARow: Integer; Added, Removed: NSIndexSet);
|
||||||
@ -162,6 +164,8 @@ type
|
|||||||
isFirstColumnCheckboxes: Boolean;
|
isFirstColumnCheckboxes: Boolean;
|
||||||
checkedIdx : NSMutableIndexSet;
|
checkedIdx : NSMutableIndexSet;
|
||||||
|
|
||||||
|
smallimages : NSMutableDictionary;
|
||||||
|
|
||||||
function acceptsFirstResponder: Boolean; override;
|
function acceptsFirstResponder: Boolean; override;
|
||||||
function becomeFirstResponder: Boolean; override;
|
function becomeFirstResponder: Boolean; override;
|
||||||
function resignFirstResponder: Boolean; override;
|
function resignFirstResponder: Boolean; override;
|
||||||
@ -198,6 +202,9 @@ type
|
|||||||
procedure lclExpectedKeys(var wantTabs, wantKeys, wantAllKeys: Boolean); override;
|
procedure lclExpectedKeys(var wantTabs, wantKeys, wantAllKeys: Boolean); override;
|
||||||
procedure lclSetFirstColumCheckboxes(acheckboxes: Boolean); message 'lclSetFirstColumCheckboxes:';
|
procedure lclSetFirstColumCheckboxes(acheckboxes: Boolean); message 'lclSetFirstColumCheckboxes:';
|
||||||
|
|
||||||
|
procedure lclRegisterSmallImage(idx: Integer; img: NSImage); message 'lclRegisterSmallImage::';
|
||||||
|
function lclGetSmallImage(idx: INteger): NSImage; message 'lclGetSmallImage:';
|
||||||
|
|
||||||
// NSTableViewDataSourceProtocol
|
// NSTableViewDataSourceProtocol
|
||||||
function numberOfRowsInTableView(tableView: NSTableView): NSInteger; message 'numberOfRowsInTableView:';
|
function numberOfRowsInTableView(tableView: NSTableView): NSInteger; message 'numberOfRowsInTableView:';
|
||||||
function tableView_objectValueForTableColumn_row(tableView: NSTableView; tableColumn: NSTableColumn; row: NSInteger): id; message 'tableView:objectValueForTableColumn:row:';
|
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:';}
|
procedure tableViewSelectionIsChanging(notification: NSNotification); message 'tableViewSelectionIsChanging:';}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{ NSImageAndTextCell }
|
||||||
|
|
||||||
|
NSImageAndTextCell = objcclass(NSTextFieldCell)
|
||||||
|
drawImage : NSImage;
|
||||||
|
procedure drawWithFrame_inView(cellFrame: NSRect; controlView_: NSView); override;
|
||||||
|
end;
|
||||||
|
|
||||||
implementation
|
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 }
|
{ TCocoaListBox }
|
||||||
|
|
||||||
function TCocoaListBox.lclIsHandle: Boolean;
|
function TCocoaListBox.lclIsHandle: Boolean;
|
||||||
@ -585,6 +622,23 @@ begin
|
|||||||
reloadData();
|
reloadData();
|
||||||
end;
|
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;
|
function TCocoaTableListView.acceptsFirstResponder: Boolean;
|
||||||
begin
|
begin
|
||||||
Result := True;
|
Result := True;
|
||||||
@ -615,7 +669,8 @@ end;
|
|||||||
procedure TCocoaTableListView.dealloc;
|
procedure TCocoaTableListView.dealloc;
|
||||||
begin
|
begin
|
||||||
//if Assigned(Items) then FreeAndNil(Items);
|
//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;
|
inherited dealloc;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -937,14 +992,33 @@ var
|
|||||||
txt : string;
|
txt : string;
|
||||||
col : Integer;
|
col : Integer;
|
||||||
nstxt : NSString;
|
nstxt : NSString;
|
||||||
|
idx : Integer;
|
||||||
|
img : NSImage;
|
||||||
begin
|
begin
|
||||||
Result:=nil;
|
Result:=nil;
|
||||||
if not isFirstColumnCheckboxes then Exit;
|
|
||||||
//writeln('getting dataCell row=',row,' col=',getIndexOfColumn(tableColumn));
|
|
||||||
|
|
||||||
col := getIndexOfColumn(tableColumn);
|
col := getIndexOfColumn(tableColumn);
|
||||||
if (col <> 0) then Exit;
|
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 := '';
|
txt := '';
|
||||||
chk := false;
|
chk := false;
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ uses
|
|||||||
WSComCtrls,
|
WSComCtrls,
|
||||||
// Cocoa WS
|
// Cocoa WS
|
||||||
CocoaPrivate, CocoaScrollers, CocoaTabControls, CocoaUtils,
|
CocoaPrivate, CocoaScrollers, CocoaTabControls, CocoaUtils,
|
||||||
CocoaWSCommon, CocoaTables, cocoa_extra, CocoaWSStdCtrls;
|
CocoaWSCommon, CocoaTables, cocoa_extra, CocoaWSStdCtrls, CocoaGDIObjects;
|
||||||
|
|
||||||
type
|
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 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 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 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;*)
|
//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 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 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 ItemsCount: Integer;
|
||||||
function GetItemTextAt(ARow, ACol: Integer; var Text: String): Boolean;
|
function GetItemTextAt(ARow, ACol: Integer; var Text: String): Boolean;
|
||||||
function GetItemCheckedAt(ARow, ACol: Integer; var IsChecked: Boolean): 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 SetItemTextAt(ARow, ACol: Integer; const Text: String);
|
||||||
procedure SetItemCheckedAt(ARow, ACol: Integer; IsChecked: Boolean);
|
procedure SetItemCheckedAt(ARow, ACol: Integer; IsChecked: Boolean);
|
||||||
procedure tableSelectionChange(NewSel: Integer; Added, Removed: NSIndexSet);
|
procedure tableSelectionChange(NewSel: Integer; Added, Removed: NSIndexSet);
|
||||||
@ -1057,6 +1059,18 @@ begin
|
|||||||
lTableLV.reloadData();
|
lTableLV.reloadData();
|
||||||
end;
|
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;
|
class procedure TCocoaWSCustomListView.ItemSetState(const ALV: TCustomListView;
|
||||||
const AIndex: Integer; const AItem: TListItem; const AState: TListItemState;
|
const AIndex: Integer; const AItem: TListItem; const AState: TListItemState;
|
||||||
const AIsSet: Boolean);
|
const AIsSet: Boolean);
|
||||||
@ -1365,6 +1379,65 @@ begin
|
|||||||
IsChecked := listView.Items[ARow].Checked;
|
IsChecked := listView.Items[ARow].Checked;
|
||||||
end;
|
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;
|
procedure TLCLListViewCallback.SetItemTextAt(ARow, ACol: Integer;
|
||||||
const Text: String);
|
const Text: String);
|
||||||
begin
|
begin
|
||||||
|
Loading…
Reference in New Issue
Block a user