mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-06-03 02:58:14 +02:00
cocoa: started reimplementing ListView. Remove the dependancy on LCL code. Move the direct storage from NSTableView to the callback object
git-svn-id: trunk@58667 -
This commit is contained in:
parent
23c3367033
commit
39cd9e7b38
@ -32,7 +32,7 @@ uses
|
||||
cocoa_extra, CocoaPrivate,
|
||||
// LCL
|
||||
LMessages, LCLMessageGlue, ExtCtrls,
|
||||
LCLType, LCLProc, Controls, ComCtrls, StdCtrls;
|
||||
LCLType, LCLProc, Controls, StdCtrls;
|
||||
|
||||
type
|
||||
|
||||
@ -46,6 +46,10 @@ type
|
||||
|
||||
IListViewCallBack = interface(ICommonCallback)
|
||||
procedure delayedSelectionDidChange_OnTimer(ASender: TObject);
|
||||
|
||||
function ItemsCount: Integer;
|
||||
function GetItemTextAt(ARow, ACol: Integer; var Text: String): Boolean;
|
||||
procedure tableSelectionChange(ARow: Integer);
|
||||
end;
|
||||
|
||||
TCocoaListBox = objcclass;
|
||||
@ -143,12 +147,12 @@ type
|
||||
|
||||
TCocoaTableListView = objcclass(NSTableView, NSTableViewDelegateProtocol, NSTableViewDataSourceProtocol)
|
||||
public
|
||||
ListView: TCustomListView; // just reference, don't release
|
||||
callback: IListViewCallback;
|
||||
|
||||
// Owned Pascal classes which need to be released
|
||||
Items: TStringList; // Object are TStringList for sub-items
|
||||
//Items: TStringList; // Object are TStringList for sub-items
|
||||
Timer: TTimer;
|
||||
readOnly: Boolean;
|
||||
|
||||
function acceptsFirstResponder: Boolean; override;
|
||||
function becomeFirstResponder: Boolean; override;
|
||||
@ -157,9 +161,9 @@ type
|
||||
procedure lclClearCallback; override;
|
||||
|
||||
// Own methods, mostly convenience methods
|
||||
procedure setStringValue_forCol_row(AStr: NSString; col, row: NSInteger); message 'setStringValue:forCol:row:';
|
||||
procedure deleteItemForRow(row: NSInteger); message 'deleteItemForRow:';
|
||||
procedure setListViewStringValue_forCol_row(AStr: NSString; col, row: NSInteger); message 'setListViewStringValue:forCol:row:';
|
||||
//procedure setStringValue_forCol_row(AStr: NSString; col, row: NSInteger); message 'setStringValue:forCol:row:';
|
||||
//procedure deleteItemForRow(row: NSInteger); message 'deleteItemForRow:';
|
||||
//procedure setListViewStringValue_forCol_row(AStr: NSString; col, row: NSInteger); message 'setListViewStringValue:forCol:row:';
|
||||
function getIndexOfColumn(ACol: NSTableColumn): NSInteger; message 'getIndexOfColumn:';
|
||||
procedure reloadDataForRow_column(ARow, ACol: NSInteger); message 'reloadDataForRow:column:';
|
||||
procedure scheduleSelectionDidChange(); message 'scheduleSelectionDidChange';
|
||||
@ -220,9 +224,9 @@ type
|
||||
procedure tableViewSelectionIsChanging(notification: NSNotification); message 'tableViewSelectionIsChanging:';}
|
||||
end;
|
||||
|
||||
// todo: this NSScrollView should go away. TCocoaScrollView must be used instead
|
||||
TCocoaListView = objcclass(NSScrollView)
|
||||
public
|
||||
ListView: TCustomListView; // just reference, don't release
|
||||
callback: ICommonCallback;
|
||||
// For report style:
|
||||
TableListView: TCocoaTableListView;
|
||||
@ -592,7 +596,7 @@ end;
|
||||
|
||||
procedure TCocoaTableListView.dealloc;
|
||||
begin
|
||||
if Assigned(Items) then FreeAndNil(Items);
|
||||
//if Assigned(Items) then FreeAndNil(Items);
|
||||
inherited dealloc;
|
||||
end;
|
||||
|
||||
@ -601,7 +605,7 @@ begin
|
||||
if not callback.resetCursorRects then
|
||||
inherited resetCursorRects;
|
||||
end;
|
||||
|
||||
(*
|
||||
procedure TCocoaTableListView.setStringValue_forCol_row(
|
||||
AStr: NSString; col, row: NSInteger);
|
||||
var
|
||||
@ -681,7 +685,7 @@ begin
|
||||
lSubItems.Strings[col-1] := lNewValue;
|
||||
end;
|
||||
end;
|
||||
|
||||
*)
|
||||
function TCocoaTableListView.getIndexOfColumn(ACol: NSTableColumn): NSInteger;
|
||||
begin
|
||||
Result := tableColumns.indexOfObject(ACol);
|
||||
@ -770,10 +774,11 @@ end;
|
||||
function TCocoaTableListView.numberOfRowsInTableView(tableView: NSTableView
|
||||
): NSInteger;
|
||||
begin
|
||||
if Assigned(Items) then
|
||||
Result := Items.Count
|
||||
if Assigned(callback) then
|
||||
Result := callback.ItemsCount
|
||||
else
|
||||
Result := 0;
|
||||
writeln('items.Count = ',Result);
|
||||
end;
|
||||
|
||||
function TCocoaTableListView.tableView_objectValueForTableColumn_row(
|
||||
@ -782,12 +787,23 @@ var
|
||||
lStringList: TStringList;
|
||||
col: NSInteger;
|
||||
StrResult: NSString;
|
||||
txt : string;
|
||||
begin
|
||||
col := tableColumns.indexOfObject(tableColumn);
|
||||
{$IFDEF COCOA_DEBUG_TABCONTROL}
|
||||
WriteLn(Format('[TCocoaTableListView.tableView_objectValueForTableColumn_row] col=%d row=%d Items.Count=%d',
|
||||
[col, row, Items.Count]));
|
||||
{$ENDIF}
|
||||
|
||||
Result := nil;
|
||||
if not Assigned(callback) then Exit;
|
||||
col := tableColumns.indexOfObject(tableColumn);
|
||||
|
||||
txt := '';
|
||||
if callback.GetItemTextAt(row, col, txt) then begin
|
||||
if txt = '' then Result := NSString.string_
|
||||
else Result := NSString.stringWithUTF8String(@txt[1])
|
||||
end;
|
||||
(*
|
||||
if row > Items.Count-1 then begin
|
||||
Result := nil;
|
||||
Exit;
|
||||
@ -800,6 +816,7 @@ begin
|
||||
StrResult := NSStringUTF8(lStringList.Strings[col-1]);
|
||||
end;
|
||||
Result := StrResult;
|
||||
*)
|
||||
end;
|
||||
|
||||
procedure TCocoaTableListView.tableView_setObjectValue_forTableColumn_row(
|
||||
@ -810,58 +827,33 @@ var
|
||||
lNewValue: NSString;
|
||||
begin
|
||||
//WriteLn('[TCocoaTableListView.tableView_setObjectValue_forTableColumn_row]');
|
||||
lNewValue := NSString(object_);
|
||||
if not NSObject(object_).isKindOfClass(NSString) then Exit;
|
||||
//WriteLn('[TCocoaTableListView.tableView_setObjectValue_forTableColumn_row] A');
|
||||
if ListView.ReadOnly then Exit;
|
||||
lNewValue := NSString(object_);
|
||||
//WriteLn('[TCocoaTableListView.tableView_setObjectValue_forTableColumn_row] A');}
|
||||
if ReadOnly then Exit;
|
||||
|
||||
lColumnIndex := getIndexOfColumn(tableColumn);
|
||||
|
||||
{
|
||||
setListViewStringValue_forCol_row(lNewValue, lColumnIndex, row);
|
||||
setStringValue_forCol_row(lNewValue, lColumnIndex, row);
|
||||
//setStringValue_forCol_row(lNewValue, lColumnIndex, row);
|
||||
}
|
||||
reloadDataForRow_column(lColumnIndex, row);
|
||||
end;
|
||||
|
||||
function TCocoaTableListView.tableView_shouldEditTableColumn_row(tableView: NSTableView; tableColumn: NSTableColumn; row: NSInteger): Boolean;
|
||||
begin
|
||||
Result := not ListView.ReadOnly;
|
||||
Result := not readOnly;
|
||||
end;
|
||||
|
||||
procedure TCocoaTableListView.tableViewSelectionDidChange(notification: NSNotification);
|
||||
var
|
||||
Msg: TLMNotify;
|
||||
NMLV: TNMListView;
|
||||
OldSel, NewSel: Integer;
|
||||
NewSel: Integer;
|
||||
begin
|
||||
NewSel := Self.selectedRow();
|
||||
{$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 NewSel >= 0 then
|
||||
if Assigned(callback) then
|
||||
begin
|
||||
NMLV.iItem := NewSel;
|
||||
NMLV.uNewState := LVIS_SELECTED;
|
||||
end
|
||||
else
|
||||
begin
|
||||
NMLV.iItem := 0;
|
||||
NMLV.uNewState := 0;
|
||||
NMLV.uOldState := LVIS_SELECTED;
|
||||
NewSel := Self.selectedRow();
|
||||
callback.tableSelectionChange(NewSel);
|
||||
end;
|
||||
|
||||
LCLMessageGlue.DeliverMessage(ListView, Msg);
|
||||
end;
|
||||
|
||||
{ TCocoaStringList }
|
||||
|
@ -221,7 +221,13 @@ type
|
||||
|
||||
TLCLListViewCallback = class(TLCLCommonCallback, IListViewCallback)
|
||||
public
|
||||
listView: TCustomListView;
|
||||
tempItemsCountDelta : Integer;
|
||||
procedure delayedSelectionDidChange_OnTimer(ASender: TObject);
|
||||
|
||||
function ItemsCount: Integer;
|
||||
function GetItemTextAt(ARow, ACol: Integer; var Text: String): Boolean;
|
||||
procedure tableSelectionChange(NewSel: Integer);
|
||||
end;
|
||||
TLCLListViewCallBackClass = class of TLCLListViewCallback;
|
||||
|
||||
@ -684,6 +690,7 @@ var
|
||||
lCocoaLV: TCocoaListView;
|
||||
lTableLV: TCocoaTableListView;
|
||||
ns: NSRect;
|
||||
lclcb: TLCLListViewCallback;
|
||||
begin
|
||||
{$IFDEF COCOA_DEBUG_LISTVIEW}
|
||||
WriteLn('[TCocoaWSCustomListView.CreateHandle] AWinControl='+IntToStr(PtrInt(AWinControl)));
|
||||
@ -706,13 +713,12 @@ begin
|
||||
// 2-> To get proper scrolling use NSScrollView.setDocumentView instead of addSubview
|
||||
// Source: http://stackoverflow.com/questions/13872642/nstableview-scrolling-does-not-work
|
||||
lCocoaLV.TableListView := lTableLV;
|
||||
lCocoaLV.ListView := TCustomListView(AWinControl);
|
||||
lCocoaLV.setDocumentView(lTableLV);
|
||||
lCocoaLV.setHasVerticalScroller(True);
|
||||
|
||||
lTableLV.callback := TLCLListViewCallback.Create(lTableLV, AWinControl);
|
||||
lTableLV.Items := TStringList.Create;
|
||||
lTableLV.ListView := TCustomListView(AWinControl);
|
||||
lclcb := TLCLListViewCallback.Create(lTableLV, AWinControl);
|
||||
lclcb.listView := TCustomListView(AWinControl);
|
||||
lTableLV.callback := lclcb;
|
||||
lTableLV.setDataSource(lTableLV);
|
||||
lTableLV.setDelegate(lTableLV);
|
||||
lTableLV.setAllowsColumnReordering(False);
|
||||
@ -899,14 +905,24 @@ class procedure TCocoaWSCustomListView.ItemDelete(const ALV: TCustomListView;
|
||||
var
|
||||
lCocoaLV: TCocoaListView;
|
||||
lTableLV: TCocoaTableListView;
|
||||
lclcb : TLCLListViewCallback;
|
||||
lStr: NSString;
|
||||
begin
|
||||
{$IFDEF COCOA_DEBUG_TABCONTROL}
|
||||
WriteLn(Format('[TCocoaWSCustomListView.ItemDelete] AIndex=%d', [AIndex]));
|
||||
{$ENDIF}
|
||||
if not CheckParams(lCocoaLV, lTableLV, ALV) then Exit;
|
||||
lTableLV.deleteItemForRow(AIndex);
|
||||
//lTableLV.deleteItemForRow(AIndex);
|
||||
|
||||
lclcb := TLCLListViewCallback(lTableLV.callback.GetCallbackObject);
|
||||
// TListView item would actually be removed after call to ItemDelete()
|
||||
// thus have to decrease the count, as reloadDate might
|
||||
// request the updated itemCount immediately
|
||||
lclcb.tempItemsCountDelta := -1;
|
||||
|
||||
lTableLV.reloadData();
|
||||
|
||||
lclcb.tempItemsCountDelta := 0;
|
||||
lTableLV.scheduleSelectionDidChange();
|
||||
end;
|
||||
|
||||
@ -978,7 +994,7 @@ begin
|
||||
{$IFDEF COCOA_DEBUG_TABCONTROL}
|
||||
WriteLn(Format('[TCocoaWSCustomListView.ItemInsert]=> lColumnCount=%d', [lColumnCount]));
|
||||
{$ENDIF}
|
||||
for i := 0 to lColumnCount-1 do
|
||||
{for i := 0 to lColumnCount-1 do
|
||||
begin
|
||||
lColumn := lTableLV.tableColumns.objectAtIndex(i);
|
||||
if i = 0 then
|
||||
@ -990,7 +1006,7 @@ begin
|
||||
lNSStr := NSStringUTF8(lStr);
|
||||
lTableLV.setStringValue_forCol_row(lNSStr, i, AIndex);
|
||||
lNSStr.release;
|
||||
end;
|
||||
end;}
|
||||
lTableLV.reloadData();
|
||||
lTableLV.sizeToFit();
|
||||
end;
|
||||
@ -1004,9 +1020,11 @@ var
|
||||
lStr: NSString;
|
||||
begin
|
||||
if not CheckParams(lCocoaLV, lTableLV, ALV) then Exit;
|
||||
lStr := NSStringUTF8(AText);
|
||||
lTableLV.setStringValue_forCol_row(lStr, ASubIndex, AItem.Index);
|
||||
lStr.release;
|
||||
// todo: make a specific row/column reload data!
|
||||
lTableLV.reloadData();
|
||||
//lStr := NSStringUTF8(AText);
|
||||
//lTableLV.setStringValue_forCol_row(lStr, ASubIndex, AItem.Index);
|
||||
//lStr.release;
|
||||
end;
|
||||
|
||||
class procedure TCocoaWSCustomListView.ItemShow(const ALV: TCustomListView;
|
||||
@ -1136,9 +1154,9 @@ begin
|
||||
lvpHideSelection,
|
||||
lvpHotTrack,}
|
||||
lvpMultiSelect: lTableLV.setAllowsMultipleSelection(AIsSet);
|
||||
{lvpOwnerDraw,
|
||||
//lvpReadOnly, implemented elsewhere, no need for this here
|
||||
lvpRowSelect,
|
||||
{lvpOwnerDraw,}
|
||||
lvpReadOnly: lTableLv.readOnly := AIsSet;
|
||||
{ lvpRowSelect,
|
||||
lvpShowColumnHeaders,
|
||||
lvpShowWorkAreas,
|
||||
lvpWrapText,
|
||||
@ -1255,6 +1273,7 @@ end; *)
|
||||
|
||||
{ TLCLListViewCallback }
|
||||
|
||||
|
||||
procedure TLCLListViewCallback.delayedSelectionDidChange_OnTimer(
|
||||
ASender: TObject);
|
||||
begin
|
||||
@ -1262,6 +1281,62 @@ begin
|
||||
TCocoaTableListView(Owner).tableViewSelectionDidChange(nil);
|
||||
end;
|
||||
|
||||
function TLCLListViewCallback.ItemsCount: Integer;
|
||||
begin
|
||||
Result:=listView.Items.Count + tempItemsCountDelta;
|
||||
end;
|
||||
|
||||
function TLCLListViewCallback.GetItemTextAt(ARow, ACol: Integer;
|
||||
var Text: String): Boolean;
|
||||
begin
|
||||
Result := (ACol>=0) and (ACol<listView.ColumnCount)
|
||||
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 := '';
|
||||
if (ACol >=0) and (ACol < listView.Items[ARow].SubItems.Count) then
|
||||
Text := listView.Items[ARow].SubItems[ACol];
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TLCLListViewCallback.tableSelectionChange(NewSel: Integer);
|
||||
var
|
||||
Msg: TLMNotify;
|
||||
NMLV: TNMListView;
|
||||
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 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;
|
||||
|
||||
{ TCocoaWSTrackBar }
|
||||
|
||||
{------------------------------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user