mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-18 10:39:09 +02:00
* gtk2 Listview now uses custom GtktreeModel that gets it's data directly from TListItems. Old behavior can be restored by compiling lcl with -dUseOrigTreeModel
git-svn-id: trunk@22945 -
This commit is contained in:
parent
b8581d21e4
commit
e49b42439b
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -4724,6 +4724,7 @@ lcl/interfaces/gtk2/gtk2extrah.inc svneol=native#text/pascal
|
|||||||
lcl/interfaces/gtk2/gtk2int.pas svneol=native#text/pascal
|
lcl/interfaces/gtk2/gtk2int.pas svneol=native#text/pascal
|
||||||
lcl/interfaces/gtk2/gtk2lclintf.inc svneol=native#text/pascal
|
lcl/interfaces/gtk2/gtk2lclintf.inc svneol=native#text/pascal
|
||||||
lcl/interfaces/gtk2/gtk2lclintfh.inc svneol=native#text/pascal
|
lcl/interfaces/gtk2/gtk2lclintfh.inc svneol=native#text/pascal
|
||||||
|
lcl/interfaces/gtk2/gtk2listviewtreemodel.pas svneol=native#text/plain
|
||||||
lcl/interfaces/gtk2/gtk2memostrings.inc svneol=native#text/pascal
|
lcl/interfaces/gtk2/gtk2memostrings.inc svneol=native#text/pascal
|
||||||
lcl/interfaces/gtk2/gtk2privatelist.inc svneol=native#text/pascal
|
lcl/interfaces/gtk2/gtk2privatelist.inc svneol=native#text/pascal
|
||||||
lcl/interfaces/gtk2/gtk2privatewidget.inc svneol=native#text/plain
|
lcl/interfaces/gtk2/gtk2privatewidget.inc svneol=native#text/plain
|
||||||
|
@ -796,6 +796,10 @@ type
|
|||||||
property Current: TListItem read GetCurrent;
|
property Current: TListItem read GetCurrent;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
TListItemsFlag = (lisfWSItemsCreated);
|
||||||
|
TListItemsFlags = set of TListItemsFlag;
|
||||||
|
|
||||||
|
|
||||||
{ TListItems }
|
{ TListItems }
|
||||||
{
|
{
|
||||||
Listitems have a build in cache of the last accessed item.
|
Listitems have a build in cache of the last accessed item.
|
||||||
@ -808,6 +812,7 @@ type
|
|||||||
private
|
private
|
||||||
FOwner: TCustomListView;
|
FOwner: TCustomListView;
|
||||||
FItems: TList;
|
FItems: TList;
|
||||||
|
FFlags: TListItemsFlags;
|
||||||
FCacheIndex: Integer; // Caches the last used item
|
FCacheIndex: Integer; // Caches the last used item
|
||||||
FCacheItem: TListItem; //
|
FCacheItem: TListItem; //
|
||||||
procedure WSCreateCacheItem;
|
procedure WSCreateCacheItem;
|
||||||
@ -842,6 +847,7 @@ type
|
|||||||
function IndexOf(const AItem: TListItem): Integer;
|
function IndexOf(const AItem: TListItem): Integer;
|
||||||
function Insert(const AIndex: Integer) : TListItem;
|
function Insert(const AIndex: Integer) : TListItem;
|
||||||
procedure InsertItem(AItem: TListItem; const AIndex: Integer);
|
procedure InsertItem(AItem: TListItem; const AIndex: Integer);
|
||||||
|
property Flags: TListItemsFlags read FFlags;
|
||||||
property Count: Integer read GetCount write SetCount;
|
property Count: Integer read GetCount write SetCount;
|
||||||
property Item[const AIndex: Integer]: TListItem read GetItem write SetItem; default;
|
property Item[const AIndex: Integer]: TListItem read GetItem write SetItem; default;
|
||||||
property Owner : TCustomListView read FOwner;
|
property Owner : TCustomListView read FOwner;
|
||||||
|
@ -193,6 +193,7 @@ begin
|
|||||||
FCacheIndex := n;
|
FCacheIndex := n;
|
||||||
WSCreateCacheItem;
|
WSCreateCacheItem;
|
||||||
end;
|
end;
|
||||||
|
Include(FFlags, lisfWSItemsCreated);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{------------------------------------------------------------------------------}
|
{------------------------------------------------------------------------------}
|
||||||
|
379
lcl/interfaces/gtk2/gtk2listviewtreemodel.pas
Normal file
379
lcl/interfaces/gtk2/gtk2listviewtreemodel.pas
Normal file
@ -0,0 +1,379 @@
|
|||||||
|
{ $Id$
|
||||||
|
|
||||||
|
*****************************************************************************
|
||||||
|
* *
|
||||||
|
* This file is part of the Lazarus Component Library (LCL) *
|
||||||
|
* *
|
||||||
|
* See the file COPYING.modifiedLGPL.txt, included in this distribution, *
|
||||||
|
* for details about the copyright. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||||
|
* *
|
||||||
|
*****************************************************************************
|
||||||
|
}
|
||||||
|
|
||||||
|
unit Gtk2ListViewTreeModel;
|
||||||
|
|
||||||
|
{$mode objfpc}{$H+}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
// FPC
|
||||||
|
Classes, SysUtils,
|
||||||
|
// Gtk
|
||||||
|
gtk2, glib2,
|
||||||
|
// LCL
|
||||||
|
ComCtrls;
|
||||||
|
type
|
||||||
|
|
||||||
|
{ TLCLTreeModel }
|
||||||
|
PLCLListViewModel = ^TLCLListViewModel;
|
||||||
|
|
||||||
|
{ TLCLListViewModel }
|
||||||
|
|
||||||
|
TLCLListViewModel = object
|
||||||
|
{%REGION GObject} // Add nothing in or before this region!!
|
||||||
|
g_type_instance : TGTypeInstance;
|
||||||
|
ref_count : guint;
|
||||||
|
qdata : PGData;
|
||||||
|
{%ENDREGION}
|
||||||
|
{%REGION Interface methods in order!}
|
||||||
|
procedure row_changed(path:PGtkTreePath; iter:PGtkTreeIter); cdecl;
|
||||||
|
procedure row_inserted(path:PGtkTreePath; iter:PGtkTreeIter); cdecl;
|
||||||
|
procedure row_has_child_toggled(path:PGtkTreePath; iter:PGtkTreeIter); cdecl;
|
||||||
|
procedure row_deleted(path:PGtkTreePath); cdecl;
|
||||||
|
procedure rows_reordered(path:PGtkTreePath; iter:PGtkTreeIter; new_order:Pgint); cdecl;
|
||||||
|
function get_flags():TGtkTreeModelFlags; cdecl;
|
||||||
|
function get_n_columns():gint; cdecl;
|
||||||
|
function get_column_type(index:gint):GType; cdecl;
|
||||||
|
function get_iter(iter:PGtkTreeIter; path:PGtkTreePath):gboolean; cdecl;
|
||||||
|
function get_path(iter:PGtkTreeIter):PGtkTreePath; cdecl;
|
||||||
|
procedure get_value(iter:PGtkTreeIter; column:gint; value:PGValue); cdecl;
|
||||||
|
function iter_next(iter:PGtkTreeIter):gboolean; cdecl;
|
||||||
|
function iter_children(iter:PGtkTreeIter; parent:PGtkTreeIter):gboolean; cdecl;
|
||||||
|
function iter_has_child(iter:PGtkTreeIter):gboolean; cdecl;
|
||||||
|
function iter_n_children(iter:PGtkTreeIter):gint; cdecl;
|
||||||
|
function iter_nth_child(iter:PGtkTreeIter; parent:PGtkTreeIter; n:gint):gboolean; cdecl;
|
||||||
|
function iter_parent(iter:PGtkTreeIter; child:PGtkTreeIter):gboolean; cdecl;
|
||||||
|
procedure ref_node(iter:PGtkTreeIter); cdecl;
|
||||||
|
procedure unref_node(iter:PGtkTreeIter); cdecl;
|
||||||
|
{%ENDREGION}
|
||||||
|
procedure NotifyRowInserted(AIndex: PtrUInt);
|
||||||
|
procedure NotifyRowDeleted(AIndex: PtrUInt);
|
||||||
|
function TreeModel: PGtkTreeModel; inline;
|
||||||
|
public
|
||||||
|
ListView: TCustomListView;
|
||||||
|
end;
|
||||||
|
|
||||||
|
PMyTreeModelObjectClass = ^TLCLTreeModelClass;
|
||||||
|
TLCLTreeModelClass = record
|
||||||
|
parent_class: TGObjectClass;
|
||||||
|
end;
|
||||||
|
TLVItemHack = class(TListItem)
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function LCLListViewModelNew(AListView: TCustomListView): PLCLListViewModel;
|
||||||
|
function LCLLISTVIEW_MODEL_TYPE: GType;
|
||||||
|
|
||||||
|
|
||||||
|
procedure LCLListViewModelClassInit(g_class:gpointer; class_data:gpointer); cdecl;
|
||||||
|
procedure LCLListViewModelInit(instance:PGTypeInstance; g_class:gpointer); cdecl;
|
||||||
|
procedure LCLListViewModelInterfaceInit(g_iface:PGtkTreeModelIface; iface_data:gpointer); cdecl;
|
||||||
|
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
var
|
||||||
|
_LCLLISTVIEW_MODEL_TYPE: gulong = 0;
|
||||||
|
|
||||||
|
function LCLListViewModelNew(AListView: TCustomListView): PLCLListViewModel;
|
||||||
|
begin
|
||||||
|
Result := g_object_new(LCLLISTVIEW_MODEL_TYPE, nil);
|
||||||
|
Result^.ListView := AListView;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function LCLLISTVIEW_MODEL_TYPE: GType;
|
||||||
|
var
|
||||||
|
TypeInfo: TGTypeInfo;
|
||||||
|
INterfaceINfo: TGInterfaceInfo;
|
||||||
|
begin
|
||||||
|
if _LCLLISTVIEW_MODEL_TYPE = 0 then
|
||||||
|
begin
|
||||||
|
with TypeInfo do
|
||||||
|
begin
|
||||||
|
class_size:= SizeOf(TLCLTreeModelClass);
|
||||||
|
base_init := nil;//TGBaseInitFunc;
|
||||||
|
base_finalize:= nil;// TGBaseFinalizeFunc;
|
||||||
|
class_init := @LCLListViewModelClassInit;// TGClassInitFunc;
|
||||||
|
class_finalize := nil;// TGClassFinalizeFunc;
|
||||||
|
class_data := nil;// gconstpointer;
|
||||||
|
instance_size := SizeOf(TLCLListViewModel);// guint16;
|
||||||
|
n_preallocs := 0;// guint16;
|
||||||
|
instance_init := @LCLListViewModelInit;// TGInstanceInitFunc;
|
||||||
|
value_table := nil;// PGTypeValueTable;
|
||||||
|
end;
|
||||||
|
with InterfaceInfo do
|
||||||
|
begin
|
||||||
|
interface_init := TGInterfaceInitFunc(@LCLListViewModelInterfaceInit);// TGInterfaceInitFunc;
|
||||||
|
interface_finalize := nil; //TGInterfaceFinalizeFunc;
|
||||||
|
interface_data := nil;//gpointer;
|
||||||
|
end;
|
||||||
|
_LCLLISTVIEW_MODEL_TYPE := g_type_register_static(G_TYPE_OBJECT, 'LCLListViewModel', @TypeInfo, 0);
|
||||||
|
g_type_add_interface_static(_LCLLISTVIEW_MODEL_TYPE, GTK_TYPE_TREE_MODEL, @InterfaceInfo);
|
||||||
|
|
||||||
|
|
||||||
|
end;
|
||||||
|
Result := _LCLLISTVIEW_MODEL_TYPE;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure LCLListViewModelClassInit(g_class:gpointer; class_data:gpointer); cdecl;
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure LCLListViewModelInit(instance:PGTypeInstance; g_class:gpointer); cdecl;
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure LCLListViewModelInterfaceInit(g_iface:PGtkTreeModelIface; iface_data:gpointer); cdecl;
|
||||||
|
var
|
||||||
|
P: PPointer;
|
||||||
|
begin
|
||||||
|
// Do not change the order here!!
|
||||||
|
P := @g_iface^.row_changed;
|
||||||
|
|
||||||
|
P^ := @TLCLListViewModel.row_changed; Inc(P);
|
||||||
|
P^ := @TLCLListViewModel.row_inserted; Inc(P);
|
||||||
|
P^ := @TLCLListViewModel.row_has_child_toggled; Inc(P);
|
||||||
|
P^ := @TLCLListViewModel.row_deleted; Inc(P);
|
||||||
|
P^ := @TLCLListViewModel.rows_reordered; Inc(P);
|
||||||
|
P^ := @TLCLListViewModel.get_flags; Inc(P);
|
||||||
|
P^ := @TLCLListViewModel.get_n_columns; Inc(P);
|
||||||
|
P^ := @TLCLListViewModel.get_column_type; Inc(P);
|
||||||
|
P^ := @TLCLListViewModel.get_iter; Inc(P);
|
||||||
|
P^ := @TLCLListViewModel.get_path; Inc(P);
|
||||||
|
P^ := @TLCLListViewModel.get_value; Inc(P);
|
||||||
|
P^ := @TLCLListViewModel.iter_next; Inc(P);
|
||||||
|
P^ := @TLCLListViewModel.iter_children; Inc(P);
|
||||||
|
P^ := @TLCLListViewModel.iter_has_child; Inc(P);
|
||||||
|
P^ := @TLCLListViewModel.iter_n_children; Inc(P);
|
||||||
|
P^ := @TLCLListViewModel.iter_nth_child; Inc(P);
|
||||||
|
P^ := @TLCLListViewModel.iter_parent; Inc(P);
|
||||||
|
P^ := @TLCLListViewModel.ref_node; Inc(P);
|
||||||
|
P^ := @TLCLListViewModel.unref_node; Inc(P);
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TLCLListViewModel }
|
||||||
|
|
||||||
|
|
||||||
|
procedure TLCLListViewModel.row_changed(path: PGtkTreePath; iter: PGtkTreeIter
|
||||||
|
); cdecl;
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLCLListViewModel.row_inserted(path: PGtkTreePath; iter: PGtkTreeIter); cdecl;
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLCLListViewModel.row_has_child_toggled(path: PGtkTreePath;
|
||||||
|
iter: PGtkTreeIter); cdecl;
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLCLListViewModel.row_deleted(path: PGtkTreePath); cdecl;
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLCLListViewModel.rows_reordered(path: PGtkTreePath;
|
||||||
|
iter: PGtkTreeIter; new_order: Pgint); cdecl;
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLCLListViewModel.get_flags(): TGtkTreeModelFlags; cdecl;
|
||||||
|
begin
|
||||||
|
Result := GTK_TREE_MODEL_LIST_ONLY or 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLCLListViewModel.get_n_columns(): gint; cdecl;
|
||||||
|
begin
|
||||||
|
Result := 1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLCLListViewModel.get_column_type(index: gint): GType; cdecl;
|
||||||
|
begin
|
||||||
|
Result := G_TYPE_POINTER;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLCLListViewModel.get_iter(iter: PGtkTreeIter; path: PGtkTreePath): gboolean; cdecl;
|
||||||
|
var
|
||||||
|
Index: PtrUInt;
|
||||||
|
begin
|
||||||
|
Result := False;
|
||||||
|
Index := gtk_tree_path_get_indices(path)[0];
|
||||||
|
if Index < ListView.Items.Count then
|
||||||
|
begin
|
||||||
|
ITer^.user_data:= Pointer(Index);
|
||||||
|
Exit(True);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLCLListViewModel.get_path(iter: PGtkTreeIter): PGtkTreePath; cdecl;
|
||||||
|
var
|
||||||
|
Index: PtrUint;
|
||||||
|
begin
|
||||||
|
Result := nil;
|
||||||
|
if iter = nil then
|
||||||
|
Exit;
|
||||||
|
Index := PtrUint(Iter^.user_data);
|
||||||
|
Result := gtk_tree_path_new_from_indices(Index, -1);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLCLListViewModel.get_value(iter: PGtkTreeIter; column: gint;
|
||||||
|
value: PGValue); cdecl;
|
||||||
|
var
|
||||||
|
Index: Integer;
|
||||||
|
ValueType: GType;
|
||||||
|
Item: TLVItemHack;
|
||||||
|
SubIndex: Integer;
|
||||||
|
begin
|
||||||
|
Index := PtrUint(Iter^.user_data);
|
||||||
|
Item := TLVItemHack(ListView.Items.Item[Index]);
|
||||||
|
|
||||||
|
g_value_init(value, G_TYPE_POINTER);
|
||||||
|
g_value_set_pointer(value, Pointer(Item));
|
||||||
|
|
||||||
|
|
||||||
|
// We use custom renderers so the below is not needed and was never tested :)
|
||||||
|
|
||||||
|
{
|
||||||
|
Listview Columns in the tree model are stored like so
|
||||||
|
[ 0: Checked. 1: Pixbuf. 2: Caption. 3: Subitem(x) Pixbuf. 4: Subitem(x) Text etc
|
||||||
|
}
|
||||||
|
|
||||||
|
{ Case column of
|
||||||
|
0:
|
||||||
|
begin
|
||||||
|
g_value_init(value, G_TYPE_BOOLEAN);
|
||||||
|
g_value_set_boolean(value, Item.GetCheckedInternal);
|
||||||
|
end;
|
||||||
|
1:
|
||||||
|
begin
|
||||||
|
g_value_init(value, GTK_TYPE_PIXMAP);
|
||||||
|
//g_value_set_pointer(ListView.im); !!
|
||||||
|
g_value_set_pointer(value, nil);
|
||||||
|
end;
|
||||||
|
2:
|
||||||
|
begin
|
||||||
|
g_value_init(value, G_TYPE_STRING);
|
||||||
|
g_value_set_static_string(value,PChar(Item.Caption));
|
||||||
|
end;
|
||||||
|
else
|
||||||
|
SubIndex := (column - 3) div 2;
|
||||||
|
if Column and 1 = 0 then // Picbuf
|
||||||
|
begin
|
||||||
|
g_value_init(value, GTK_TYPE_PIXMAP);
|
||||||
|
//g_value_set_pointer(ListView.im); !!
|
||||||
|
g_value_set_pointer(value, nil);
|
||||||
|
end
|
||||||
|
else // Text;
|
||||||
|
begin
|
||||||
|
g_value_init(value, G_TYPE_STRING);
|
||||||
|
if SubIndex >= Item.SubItems.Count then
|
||||||
|
g_value_set_static_string(value,PChar(''))
|
||||||
|
else
|
||||||
|
g_value_set_static_string(value,PChar(Item.SubItems.Strings[SubIndex]));
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
}
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLCLListViewModel.iter_next(iter: PGtkTreeIter): gboolean; cdecl;
|
||||||
|
begin
|
||||||
|
Result := False;
|
||||||
|
if ListView = nil then
|
||||||
|
Exit;
|
||||||
|
Inc(PtrUInt(Iter^.user_data));
|
||||||
|
Result := PtrUint(Iter^.user_data) < ListView.items.Count;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLCLListViewModel.iter_children(iter: PGtkTreeIter;
|
||||||
|
parent: PGtkTreeIter): gboolean; cdecl;
|
||||||
|
begin
|
||||||
|
Result := False;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLCLListViewModel.iter_has_child(iter: PGtkTreeIter): gboolean;
|
||||||
|
cdecl;
|
||||||
|
begin
|
||||||
|
Result := false;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLCLListViewModel.iter_n_children(iter: PGtkTreeIter): gint; cdecl;
|
||||||
|
begin
|
||||||
|
Result := 0;
|
||||||
|
if (Iter = nil) and (ListView <> nil) then
|
||||||
|
Result := ListView.Items.Count;
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLCLListViewModel.iter_nth_child(iter: PGtkTreeIter;
|
||||||
|
parent: PGtkTreeIter; n: gint): gboolean; cdecl;
|
||||||
|
begin
|
||||||
|
Result := False;
|
||||||
|
if (ListView = nil) or (parent <> nil) then
|
||||||
|
Exit;
|
||||||
|
if (Iter = nil) and (n < ListView.Items.Count) then begin
|
||||||
|
PtrUint(Iter^.user_data):=n;
|
||||||
|
Result := True;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLCLListViewModel.iter_parent(iter: PGtkTreeIter; child: PGtkTreeIter
|
||||||
|
): gboolean; cdecl;
|
||||||
|
begin
|
||||||
|
Result := False;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLCLListViewModel.ref_node(iter: PGtkTreeIter); cdecl;
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLCLListViewModel.unref_node(iter: PGtkTreeIter); cdecl;
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLCLListViewModel.NotifyRowInserted(AIndex: PtrUInt);
|
||||||
|
var
|
||||||
|
Path: PGtkTreePath;
|
||||||
|
Iter: TGtkTreeIter;
|
||||||
|
begin
|
||||||
|
Iter.user_data:= Pointer(AIndex);
|
||||||
|
path :=gtk_tree_path_new_from_indices(AIndex, -1);
|
||||||
|
//emits a signal
|
||||||
|
gtk_tree_model_row_inserted(TreeModel, path, @iter);
|
||||||
|
gtk_tree_path_free(path);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLCLListViewModel.NotifyRowDeleted(AIndex: PtrUInt);
|
||||||
|
var
|
||||||
|
Path: PGtkTreePath;
|
||||||
|
begin
|
||||||
|
path :=gtk_tree_path_new_from_indices(AIndex, -1);
|
||||||
|
//emits a signal
|
||||||
|
gtk_tree_model_row_deleted(TreeModel, path);
|
||||||
|
gtk_tree_path_free(path);
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLCLListViewModel.TreeModel: PGtkTreeModel; inline;
|
||||||
|
begin
|
||||||
|
Result := PGtkTreeModel(@Self);
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
@ -231,7 +231,7 @@ type
|
|||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses Gtk2CellRenderer, GtkExtra;
|
uses Gtk2CellRenderer, GtkExtra{$IFNDEF USEORIGTREEMODEL}, Gtk2ListViewTreeModel{$ENDIF};
|
||||||
|
|
||||||
// Will be used commonly for ListViews and TreeViews
|
// Will be used commonly for ListViews and TreeViews
|
||||||
procedure GetCommonTreeViewWidgets(ATreeViewHandle: PGtkWidget;
|
procedure GetCommonTreeViewWidgets(ATreeViewHandle: PGtkWidget;
|
||||||
|
@ -764,10 +764,14 @@ begin
|
|||||||
GetCommonTreeViewWidgets(PGtkWidget(ALV.Handle), Widgets);
|
GetCommonTreeViewWidgets(PGtkWidget(ALV.Handle), Widgets);
|
||||||
|
|
||||||
with Widgets^ do begin
|
with Widgets^ do begin
|
||||||
|
{$IFDEF USEORIGTREEMODEL}
|
||||||
if gtk_tree_model_iter_nth_child(TreeModel, @Iter, nil, AIndex) then
|
if gtk_tree_model_iter_nth_child(TreeModel, @Iter, nil, AIndex) then
|
||||||
begin
|
begin
|
||||||
gtk_list_store_remove(TreeModel, @Iter);
|
gtk_list_store_remove(TreeModel, @Iter);
|
||||||
end;
|
end;
|
||||||
|
{$ELSE}
|
||||||
|
PLCLListViewModel(TreeModel)^.NotifyRowDeleted(AIndex);
|
||||||
|
{$ENDIF}
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -832,17 +836,25 @@ begin
|
|||||||
if not WSCheckHandleAllocated(ALV, 'ItemInsert')
|
if not WSCheckHandleAllocated(ALV, 'ItemInsert')
|
||||||
then Exit;
|
then Exit;
|
||||||
|
|
||||||
|
|
||||||
GetCommonTreeViewWidgets(PGtkWidget(ALV.Handle), Widgets);
|
GetCommonTreeViewWidgets(PGtkWidget(ALV.Handle), Widgets);
|
||||||
|
|
||||||
with Widgets^ do
|
with Widgets^ do
|
||||||
begin
|
begin
|
||||||
if ItemCache = nil then
|
if ItemCache = nil then
|
||||||
ItemCache := TStringList.Create;
|
ItemCache := TStringList.Create;
|
||||||
|
{$IFDEF USEORIGTREEMODEL}
|
||||||
if AIndex = -1 then
|
if AIndex = -1 then
|
||||||
Index := gtk_tree_model_iter_n_children(TreeModel, nil)
|
Index := gtk_tree_model_iter_n_children(TreeModel, nil)
|
||||||
else
|
else
|
||||||
Index := AIndex;
|
Index := AIndex;
|
||||||
gtk_list_store_insert_with_values(PGtkListStore(TreeModel), @Iter, Index, 0, Pointer(AItem), -1);
|
gtk_list_store_insert_with_values(PGtkListStore(TreeModel), @Iter, Index, 0, Pointer(AItem), -1);
|
||||||
|
{$ELSE}
|
||||||
|
if not (lisfWSItemsCreated in ALV.Items.Flags) then
|
||||||
|
Exit;
|
||||||
|
|
||||||
|
PLCLListViewModel(TreeModel)^.NotifyRowInserted(AIndex);
|
||||||
|
{$ENDIF}
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1016,12 +1028,13 @@ var
|
|||||||
begin
|
begin
|
||||||
if not WSCheckHandleAllocated(ALV, 'ItemUpdate')
|
if not WSCheckHandleAllocated(ALV, 'ItemUpdate')
|
||||||
then Exit;
|
then Exit;
|
||||||
|
{$IFDEF USEORIGTREEMODEL}
|
||||||
GetCommonTreeViewWidgets(PGtkWidget(ALV.Handle), Widgets);
|
GetCommonTreeViewWidgets(PGtkWidget(ALV.Handle), Widgets);
|
||||||
|
|
||||||
with Widgets^ do
|
with Widgets^ do
|
||||||
if gtk_tree_model_iter_nth_child(TreeModel, @Iter, nil, AIndex) then
|
if gtk_tree_model_iter_nth_child(TreeModel, @Iter, nil, AIndex) then
|
||||||
gtk_list_store_set(PGtkListStore(TreeModel), @Iter, [0, Pointer(AItem), -1]);
|
gtk_list_store_set(PGtkListStore(TreeModel), @Iter, [0, Pointer(AItem), -1]);
|
||||||
|
{$ENDIF}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
class function TGtk2WSCustomListView.CreateHandle(const AWinControl: TWinControl;
|
class function TGtk2WSCustomListView.CreateHandle(const AWinControl: TWinControl;
|
||||||
@ -1056,12 +1069,16 @@ begin
|
|||||||
Images := nil;
|
Images := nil;
|
||||||
PtrType := G_TYPE_POINTER;
|
PtrType := G_TYPE_POINTER;
|
||||||
|
|
||||||
|
{$IFDEF USEORIGTREEMODEL}
|
||||||
TreeModel := gtk_list_store_newv(1, @PtrType);
|
TreeModel := gtk_list_store_newv(1, @PtrType);
|
||||||
|
{$ENDIF}
|
||||||
|
TreeModel:= LCLListViewModelNew(TCustomListView(AWinControl));
|
||||||
|
|
||||||
|
|
||||||
MainView:=gtk_tree_view_new_with_model(TreeModel);
|
MainView:=gtk_tree_view_new_with_model(TreeModel);
|
||||||
//MainView:=gtk_tree_view_new;
|
//MainView:=gtk_tree_view_new;
|
||||||
g_object_unref (G_OBJECT (TreeModel));
|
g_object_unref (G_OBJECT (TreeModel));
|
||||||
|
//gtk_tree_view_set_fixed_height_mode(PGtkTreeView(MainView), True);
|
||||||
|
|
||||||
TreeSelection := PGtkTreeSelection(gtk_tree_view_get_selection(PGtkTreeView(MainView)));
|
TreeSelection := PGtkTreeSelection(gtk_tree_view_get_selection(PGtkTreeView(MainView)));
|
||||||
|
|
||||||
@ -1440,11 +1457,18 @@ begin
|
|||||||
|
|
||||||
with Widgets^ do
|
with Widgets^ do
|
||||||
begin
|
begin
|
||||||
|
{$IFNDEF USEORIGTREEMODEL}
|
||||||
|
g_object_ref(TreeModel);
|
||||||
|
gtk_tree_view_set_model(PGtkTreeView(MainView), nil);
|
||||||
|
gtk_tree_view_set_model(PGtkTreeView(MainView), TreeModel);
|
||||||
|
g_object_unref(TreeModel);
|
||||||
|
{$ELSE}
|
||||||
if ItemCache = nil then
|
if ItemCache = nil then
|
||||||
ItemCache := TStringList.Create;
|
ItemCache := TStringList.Create;
|
||||||
gtk_list_store_clear(PGtkListStore(TreeModel));
|
gtk_list_store_clear(PGtkListStore(TreeModel));
|
||||||
for Index := 0 to AValue - 1 do
|
for Index := 0 to AValue - 1 do
|
||||||
gtk_list_store_insert_with_values(PGtkListStore(TreeModel), @Iter, Index, 0, nil, -1);
|
gtk_list_store_insert_with_values(PGtkListStore(TreeModel), @Iter, Index, 0, nil, -1);
|
||||||
|
{$ENDIF}
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user