summaryrefslogtreecommitdiff
path: root/libgtk_kylix/GTKView.pas
diff options
context:
space:
mode:
authorTomas Bzatek <tbzatek@users.sourceforge.net>2008-06-07 20:34:49 +0200
committerTomas Bzatek <tbzatek@users.sourceforge.net>2008-06-07 20:34:49 +0200
commitecde167da74c86bc047aaf84c5e548cf65a5da98 (patch)
treea015dfda84f28a65811e3aa0d369f8f211ec8c60 /libgtk_kylix/GTKView.pas
downloadtuxcmd-ecde167da74c86bc047aaf84c5e548cf65a5da98.tar.xz
Diffstat (limited to 'libgtk_kylix/GTKView.pas')
-rw-r--r--libgtk_kylix/GTKView.pas1376
1 files changed, 1376 insertions, 0 deletions
diff --git a/libgtk_kylix/GTKView.pas b/libgtk_kylix/GTKView.pas
new file mode 100644
index 0000000..a8b80fc
--- /dev/null
+++ b/libgtk_kylix/GTKView.pas
@@ -0,0 +1,1376 @@
+(*
+ GTK-Kylix Library: GTKView - GtkTreeView and its modifications
+ Version 0.6.21 (last updated 2006-05-06)
+ Copyright (C) 2006 Tomas Bzatek <tbzatek@users.sourceforge.net>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307 USA.
+
+*)
+
+unit GTKView;
+{ $WEAKPACKAGEUNIT}
+{$O+} // Optimization needs to be enabled for this unit due to bug in compiler (fixed columns doesn't work)
+
+interface
+
+uses gtk2, gdk2, gdk2pixbuf, glib2, Classes, GTKControls, GTKConsts, GTKUtils, GTKClasses, GTKForms, GTKPixbuf;
+ // Quick jump: QForms QControls QStdCtrls QComCtrls
+
+
+type
+ TGTKListItem = class;
+ TGTKTreeViewColumn = class;
+
+(****************************************** TGTKTREEVIEWCOLUMN ******************************************************************)
+ TGTKTreeViewColumnSizingMode = (smGrowOnly, smAutoSize, smFixed);
+ TGTKTreeViewSortOrder = (soAscending, soDescending, soNone);
+ TGTKTreeViewColumnType = (ctText, ctToggle, ctImageText);
+ TGTKTreeViewColumnEditedEvent = procedure(Sender: TObject; Column: TGTKTreeViewColumn; Item: TGTKListItem; var NewText: string; var AllowChange: boolean; var DataColumn: integer) of object;
+ TGTKTreeViewColumnToggledEvent = procedure(Sender: TObject; Column: TGTKTreeViewColumn; Item: TGTKListItem) of object;
+ TGTKTreeViewColumn = class(TComponent)
+ private
+ FOwner: TComponent;
+ FColumnType: TGTKTreeViewColumnType;
+ FOnEdited: TGTKTreeViewColumnEditedEvent;
+ FOnToggled: TGTKTreeViewColumnToggledEvent;
+ FOnClicked: TNotifyEvent;
+ FIndex: integer;
+ function GetCaption: string;
+ function GetVisible: boolean;
+ function GetResizable: boolean;
+ function GetSizingMode: TGTKTreeViewColumnSizingMode;
+ function GetWidth: integer;
+ function GetFixedWidth: integer;
+ function GetMinWidth: integer;
+ function GetMaxWidth: integer;
+ function GetClickable: boolean;
+ function GetAlignment: Double;
+ function GetReorderable: boolean;
+ function GetSortID: integer;
+ function GetShowSortIndicator: boolean;
+ function GetSortOrder: TGTKTreeViewSortOrder;
+ procedure SetCaption(Value: string);
+ procedure SetVisible(Value: boolean);
+ procedure SetResizable(Value: boolean);
+ procedure SetSizingMode(Value: TGTKTreeViewColumnSizingMode);
+ procedure SetFixedWidth(Value: integer);
+ procedure SetMinWidth(Value: integer);
+ procedure SetMaxWidth(Value: integer);
+ procedure SetClickable(Value: boolean);
+ procedure SetAlignment(Value: Double);
+ procedure SetReorderable(Value: boolean);
+ procedure SetSortID(Value: integer);
+ procedure SetShowSortIndicator(Value: boolean);
+ procedure SetSortOrder(Value: TGTKTreeViewSortOrder);
+ procedure SetColumnType(Value: TGTKTreeViewColumnType);
+ public
+ FColumn: PGtkTreeViewColumn;
+ FRenderer, FPixbufRenderer: PGtkCellRenderer;
+ constructor Create(AOwner: TComponent); override;
+ constructor CreateTyped(AOwner: TComponent; ColType: TGTKTreeViewColumnType);
+ destructor Destroy; override;
+ procedure AddAttribute(Attribute: string; Value: integer);
+ procedure SetProperty(AProperty: string; Value: integer); overload;
+ procedure SetProperty(AProperty: string; Value: string); overload;
+ procedure SetProperty(AProperty: string; Value: Double); overload;
+ procedure SetProperty(AProperty: string; Value: pointer); overload;
+ procedure AddImageAttribute(Attribute: string; Value: integer);
+ procedure SetImageProperty(AProperty: string; Value: integer); overload;
+ procedure SetImageProperty(AProperty: string; Value: string); overload;
+ procedure SetImageProperty(AProperty: string; Value: Double); overload;
+ procedure SetImageProperty(AProperty: string; Value: pointer); overload;
+ procedure ClearAttributes;
+ property Parent: TComponent read FOwner;
+ published
+ property Caption: string read GetCaption write SetCaption;
+ property Visible: boolean read GetVisible write SetVisible;
+ property Resizable: boolean read GetResizable write SetResizable;
+ property SizingMode: TGTKTreeViewColumnSizingMode read GetSizingMode write SetSizingMode;
+ property Width: integer read GetWidth;
+ property FixedWidth: integer read GetFixedWidth write SetFixedWidth;
+ property MinWidth: integer read GetMinWidth write SetMinWidth;
+ property MaxWidth: integer read GetMaxWidth write SetMaxWidth;
+ property Clickable: boolean read GetClickable write SetClickable;
+ property Alignment: Double read GetAlignment write SetAlignment;
+ property Reorderable: boolean read GetReorderable write SetReorderable;
+ property SortID: integer read GetSortID write SetSortID;
+ property ShowSortIndicator: boolean read GetShowSortIndicator write SetShowSortIndicator;
+ property SortOrder: TGTKTreeViewSortOrder read GetSortOrder write SetSortOrder;
+ property ColumnType: TGTKTreeViewColumnType read FColumnType write SetColumnType;
+ property Index: integer read FIndex;
+ property OnEdited: TGTKTreeViewColumnEditedEvent read FOnEdited write FOnEdited;
+ property OnToggled: TGTKTreeViewColumnToggledEvent read FOnToggled write FOnToggled;
+ property OnClicked: TNotifyEvent read FOnClicked write FOnClicked;
+ end;
+
+(****************************************** TGTKTREEVIEWCOLUMNS *****************************************************************)
+ TGTKTreeViewColumns = class(TComponent)
+ private
+ FOwner: TComponent;
+ FList: TList;
+ function GetCount: Integer;
+ function GetItem(Index: Integer): TGTKTreeViewColumn;
+ procedure SetItem(Index: Integer; Value: TGTKTreeViewColumn);
+ public
+ constructor Create(AOwner: TComponent); override;
+ destructor Destroy; override;
+ function Add: TGTKTreeViewColumn;
+ function AddTyped(ColType: TGTKTreeViewColumnType): TGTKTreeViewColumn;
+ procedure Insert(Index: Integer; Item: TGTKTreeViewColumn);
+ procedure Delete(Index: Integer);
+ procedure Clear;
+ procedure AutosizeColumns;
+ property Items[Index: Integer]: TGTKTreeViewColumn read GetItem write SetItem; default;
+ property Parent: TComponent read FOwner;
+ published
+ property Count: Integer read GetCount;
+ end;
+
+(****************************************** TGTKLISTITEM ************************************************************************)
+ TGTKListItem = class(TComponent)
+ private
+ FOwner: TComponent;
+ FIndex: longint;
+ FData: pointer;
+ function GetSelected: boolean;
+ procedure SetSelected(Value: boolean);
+ public
+ constructor Create(AOwner: TComponent); override;
+ destructor Destroy; override;
+ function AsString(Index: longint): string;
+ function AsInteger(Index: longint): integer;
+ function AsPointer(Index: longint): pointer;
+ function AsBoolean(Index: longint): boolean;
+ procedure SetValue(Index: longint; Value: string); overload;
+ procedure SetValue(Index: longint; Value: integer); overload;
+ procedure SetValue(Index: longint; Value: pointer); overload;
+ procedure SetValue(Index: longint; Value: boolean); overload;
+ procedure SetCursor(const FocusColumnNo: integer; const StartEditing, UseAlignment: boolean; const AlignX, AlignY: Double);
+ procedure StartEditing(ColumnNo: integer);
+ procedure RedrawRow;
+ property Data: pointer read FData write FData;
+ property Parent: TComponent read FOwner;
+ function IsVisible: boolean;
+ published
+ property Selected: boolean read GetSelected write SetSelected;
+ property Index: integer read FIndex;
+ end;
+
+(****************************************** TGTKLISTITEMS ***********************************************************************)
+ TGTKListColumnType = (lcText, lcNumber, lcPointer, lcPixbuf, lcBoolean);
+ TGTKListItems = class(TComponent)
+ private
+ FStore: PGtkListStore;
+ FOwner: TComponent;
+ FList: TList;
+ function GetCount: longint;
+ function GetItem(Index: longint): TGTKListItem;
+ procedure SetItem(Index: longint; Value: TGTKListItem);
+ public
+ constructor Create(AOwner: TComponent); override;
+ constructor CreateTyped(AOwner: TComponent; ColumnTypes: array of TGTKListColumnType);
+ destructor Destroy; override;
+ procedure SetColumnTypes(Types: array of TGTKListColumnType);
+ function Add: TGTKListItem;
+ procedure Insert(Index: longint; Item: TGTKListItem);
+ procedure Append(Item: TGTKListItem);
+ procedure Delete(Index: longint);
+ procedure Clear;
+ property Items[Index: longint]: TGTKListItem read GetItem write SetItem; default;
+ property Parent: TComponent read FOwner;
+ published
+ property Count: longint read GetCount;
+ end;
+
+(****************************************** TGTKVIEW ****************************************************************************)
+ TGTKSelectionMode = (smNone, smSingle, smBrowse, smMultiple);
+ TGTKCellDataFunc = procedure (Sender: TObject; tree_view: PGtkTreeView; tree_column : PGtkTreeViewColumn; cell : PGtkCellRenderer; tree_model : PGtkTreeModel; iter : PGtkTreeIter) of object;
+ TGTKSortCoversionFunc = function (Sender: TObject; const Index: integer): integer of object;
+ TGTKView = class(TGTKContainer)
+ private
+ FColumns: TGTKTreeViewColumns;
+ FOnSelectionChanged: TNotifyEvent;
+ FTreeModelSort: PGtkTreeModelSort;
+ FCellDataFunc: TGTKCellDataFunc;
+ FTreeModel: PGtkTreeModel;
+ FToSortedConvFunc, FFromSortedConvFunc: TGTKSortCoversionFunc;
+ function GetSelectionMode: TGTKSelectionMode;
+ function GetShowHeaders: boolean;
+ function GetRulesHint: boolean;
+ function GetReorderable: boolean;
+ function GetEnableSearch: boolean;
+ function GetSearchColumn: integer;
+ function GetSortColumnID: integer;
+ function GetSortOrder: TGTKTreeViewSortOrder;
+ procedure SetSelectionMode(Value: TGTKSelectionMode);
+ procedure SetShowHeaders(Value: boolean);
+ procedure SetRulesHint(Value: boolean);
+ procedure SetReorderable(Value: boolean);
+ procedure SetEnableSearch(Value: boolean);
+ procedure SetSearchColumn(Value: integer);
+ procedure SetSortColumnID(Value: integer);
+ procedure SetSortOrder(Value: TGTKTreeViewSortOrder);
+ protected
+ public
+ FSelection: PGtkTreeSelection;
+ constructor Create(AOwner: TComponent); override;
+ destructor Destroy; override;
+ procedure SelectAll;
+ procedure DeselectAll;
+ procedure SetSortInfo(ColumnID: integer; Order: TGTKTreeViewSortOrder);
+ function ConvertToSorted(Index: integer): integer;
+ function ConvertFromSorted(Index: integer): integer;
+ procedure ConvertPathToChild(var Path: PGtkTreePath);
+ procedure ConvertChildToPath(var Path: PGtkTreePath);
+ published
+ property Columns: TGTKTreeViewColumns read FColumns write FColumns;
+ property SelectionMode: TGTKSelectionMode read GetSelectionMode write SetSelectionMode;
+ property OnSelectionChanged: TNotifyEvent read FOnSelectionChanged write FOnSelectionChanged;
+ property ShowHeaders: boolean read GetShowHeaders write SetShowHeaders;
+ property RulesHint: boolean read GetRulesHint write SetRulesHint;
+ property Reorderable: boolean read GetReorderable write SetReorderable;
+ property EnableSearch: boolean read GetEnableSearch write SetEnableSearch;
+ property SearchColumn: integer read GetSearchColumn write SetSearchColumn;
+ property SortColumnID: integer read GetSortColumnID write SetSortColumnID;
+ property SortOrder: TGTKTreeViewSortOrder read GetSortOrder write SetSortOrder;
+ property CellDataFunc: TGTKCellDataFunc read FCellDataFunc write FCellDataFunc;
+ property FromSortedCoversionFunc: TGTKSortCoversionFunc read FFromSortedConvFunc write FFromSortedConvFunc;
+ property ToSortedCoversionFunc: TGTKSortCoversionFunc read FToSortedConvFunc write FToSortedConvFunc;
+ end;
+
+(****************************************** TGTKLISTVIEW ************************************************************************)
+ TGTKLVItemActivateEvent = procedure (Sender: TObject; Item: TGTKListItem) of object;
+ TGTKTreeViewCompareFunc = function (Sender: TObject; var model: PGtkTreeModel; var a, b: PGtkTreeIter): integer of object;
+ TGTKListView = class(TGTKView)
+ private
+ FOnItemActivate: TGTKLVItemActivateEvent;
+ FSortable: boolean;
+ FCompareFunc: TGTKTreeViewCompareFunc;
+ FOnColumnsChanged: TNotifyEvent;
+ protected
+ FListItems: TGTKListItems;
+ procedure Recreate;
+ function GetSelected: TGTKListItem;
+ procedure SetSelected(Value: TGTKListItem);
+ public
+ constructor Create(AOwner: TComponent); override;
+ constructor CreateTyped(AOwner: TComponent; Sortable: boolean; ColumnTypes: array of TGTKListColumnType);
+ destructor Destroy; override;
+ procedure StartEditing(ColumnNo: integer);
+ function GetItemAtPos(X, Y: integer): TGTKListItem;
+ published
+ property Items: TGTKListItems read FListItems write FListItems;
+ property Selected: TGTKListItem read GetSelected write SetSelected;
+ property OnItemActivate: TGTKLVItemActivateEvent read FOnItemActivate write FOnItemActivate;
+ property CompareFunc: TGTKTreeViewCompareFunc read FCompareFunc write FCompareFunc;
+ property OnColumnsChanged: TNotifyEvent read FOnColumnsChanged write FOnColumnsChanged;
+ end;
+
+
+(********************************************************************************************************************************)
+(********************************************************************************************************************************)
+implementation
+
+uses SysUtils, DateUtils;
+
+
+(********************************************************************************************************************************)
+(********************************************************************************************************************************)
+constructor TGTKView.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FColumns := TGTKTreeViewColumns.Create(Self);
+ FOnSelectionChanged := nil;
+ FToSortedConvFunc := nil;
+ FFromSortedConvFunc := nil;
+end;
+
+destructor TGTKView.Destroy;
+begin
+ FColumns.Free;
+ inherited Destroy;
+end;
+
+function TGTKView.GetSelectionMode: TGTKSelectionMode;
+begin
+ Result := TGTKSelectionMode(gtk_tree_selection_get_mode(FSelection));
+end;
+
+procedure TGTKView.SetSelectionMode(Value: TGTKSelectionMode);
+begin
+ gtk_tree_selection_set_mode(FSelection, Integer(Value));
+end;
+
+procedure TGTKView.SelectAll;
+begin
+ gtk_tree_selection_select_all(FSelection);
+end;
+
+procedure TGTKView.DeselectAll;
+begin
+ gtk_tree_selection_unselect_all(FSelection);
+end;
+
+function TGTKView.GetShowHeaders: boolean;
+begin
+ Result := gtk_tree_view_get_headers_visible(PGtkTreeView(FWidget));
+end;
+
+procedure TGTKView.SetShowHeaders(Value: boolean);
+begin
+ gtk_tree_view_set_headers_visible(PGtkTreeView(FWidget), Value);
+end;
+
+function TGTKView.GetRulesHint: boolean;
+begin
+ Result := gtk_tree_view_get_rules_hint(PGtkTreeView(FWidget));
+end;
+
+procedure TGTKView.SetRulesHint(Value: boolean);
+begin
+ gtk_tree_view_set_rules_hint(PGtkTreeView(FWidget), Value);
+end;
+
+function TGTKView.GetReorderable: boolean;
+begin
+ Result := gtk_tree_view_get_reorderable(PGtkTreeView(FWidget));
+end;
+
+procedure TGTKView.SetReorderable(Value: boolean);
+begin
+ gtk_tree_view_set_reorderable(PGtkTreeView(FWidget), Value);
+end;
+
+function TGTKView.GetEnableSearch: boolean;
+begin
+ Result := gtk_tree_view_get_enable_search(PGtkTreeView(FWidget));
+end;
+
+procedure TGTKView.SetEnableSearch(Value: boolean);
+begin
+ gtk_tree_view_set_enable_search(PGtkTreeView(FWidget), Value);
+end;
+
+function TGTKView.GetSearchColumn: integer;
+begin
+ Result := gtk_tree_view_get_search_column(PGtkTreeView(FWidget));
+end;
+
+procedure TGTKView.SetSearchColumn(Value: integer);
+begin
+ gtk_tree_view_set_search_column(PGtkTreeView(FWidget), Value);
+end;
+
+function TGTKView.GetSortColumnID: integer;
+var sort_column_id: gint;
+ order: TGtkSortType;
+begin
+ Result := -1;
+ if (FTreeModelSort <> nil) and gtk_tree_sortable_get_sort_column_id(PGtkTreeSortable(FTreeModelSort), @sort_column_id, @order)
+ then Result := sort_column_id;
+end;
+
+procedure TGTKView.SetSortColumnID(Value: integer);
+begin
+ if FTreeModelSort <> nil then
+ gtk_tree_sortable_set_sort_column_id(PGtkTreeSortable(FTreeModelSort), Value, TGtkSortType(GetSortOrder));
+end;
+
+procedure TGTKView.ConvertChildToPath(var Path: PGtkTreePath);
+var NewPath: PGtkTreePath;
+begin
+ if Assigned(FTreeModelSort) then
+ if not Assigned(FToSortedConvFunc) then begin
+ NewPath := gtk_tree_model_sort_convert_child_path_to_path(FTreeModelSort, Path);
+ Path := NewPath;
+ end else begin
+ NewPath := gtk_tree_path_new_from_string(PChar(IntToStr(FToSortedConvFunc(Self, StrToIntDef(gtk_tree_path_to_string(Path), 0)))));
+ Path := NewPath;
+ end;
+end;
+
+procedure TGTKView.ConvertPathToChild(var Path: PGtkTreePath);
+var NewPath: PGtkTreePath;
+begin
+ if Assigned(FTreeModelSort) then
+ if not Assigned(FFromSortedConvFunc) then begin
+ NewPath := gtk_tree_model_sort_convert_path_to_child_path(FTreeModelSort, Path);
+ Path := NewPath;
+ end else begin
+ NewPath := gtk_tree_path_new_from_string(PChar(IntToStr(FFromSortedConvFunc(Self, StrToIntDef(gtk_tree_path_to_string(Path), 0)))));
+ Path := NewPath;
+ end;
+end;
+
+function TGTKView.GetSortOrder: TGTKTreeViewSortOrder;
+var sort_column_id: gint;
+ order: TGtkSortType;
+begin
+ Result := soNone;
+ if (FTreeModelSort <> nil) and gtk_tree_sortable_get_sort_column_id(PGtkTreeSortable(FTreeModelSort), @sort_column_id, @order)
+ then Result := TGTKTreeViewSortOrder(order);
+end;
+
+procedure TGTKView.SetSortOrder(Value: TGTKTreeViewSortOrder);
+begin
+ if FTreeModelSort <> nil then
+ gtk_tree_sortable_set_sort_column_id(PGtkTreeSortable(FTreeModelSort), GetSortColumnID, TGtkSortType(Value));
+end;
+
+procedure TGTKView.SetSortInfo(ColumnID: integer; Order: TGTKTreeViewSortOrder);
+begin
+ if FTreeModelSort <> nil then
+ gtk_tree_sortable_set_sort_column_id(PGtkTreeSortable(FTreeModelSort), ColumnID, TGtkSortType(Order));
+end;
+
+function TGTKView.ConvertToSorted(Index: integer): integer;
+var Path: PGtkTreePath;
+ Iter: TGtkTreeIter;
+begin
+ Result := Index;
+ if Application.GTKVersion_2_0_5_Up then begin
+ Path := gtk_tree_path_new_from_string(StringToPgchar(IntToStr(Index)));
+ if not Assigned(Path) then Exit;
+ if Assigned(FTreeModelSort) then Path := gtk_tree_model_sort_convert_child_path_to_path(FTreeModelSort, Path);
+ if not Assigned(Path) then Exit;
+ Result := gtk_tree_path_get_indices(Path)^;
+ gtk_tree_path_free(Path);
+ end else
+ if Assigned(FToSortedConvFunc) then Result := FToSortedConvFunc(Self, Index) else begin
+ gtk_tree_model_get_iter_from_string(FTreeModel, @Iter, PChar(IntToStr(Index)));
+// gtk_tree_model_sort_convert_child_iter_to_iter(FTreeModelSort, @NewIter, @Iter);
+ Path := gtk_tree_model_get_path(FTreeModel, @Iter);
+ if not Assigned(Path) then Exit;
+ if Assigned(FTreeModelSort) then Path := gtk_tree_model_sort_convert_child_path_to_path(FTreeModelSort, Path);
+ if not Assigned(Path) then Exit;
+ Result := StrToIntDef(String(gtk_tree_path_to_string(Path)), Index);
+ gtk_tree_path_free(Path);
+ end;
+end;
+
+function TGTKView.ConvertFromSorted(Index: integer): integer;
+var Path: PGtkTreePath;
+ Iter: TGtkTreeIter;
+begin
+ Result := Index;
+ if Application.GTKVersion_2_0_5_Up then begin
+ Path := gtk_tree_path_new_from_string(StringToPgchar(IntToStr(Index)));
+ if not Assigned(Path) then Exit;
+ if Assigned(FTreeModelSort) then Path := gtk_tree_model_sort_convert_path_to_child_path(FTreeModelSort, Path);
+ if not Assigned(Path) then Exit;
+ Result := gtk_tree_path_get_indices(Path)^;
+ gtk_tree_path_free(Path);
+ end else
+ if Assigned(FFromSortedConvFunc) then Result := FFromSortedConvFunc(Self, Index) else begin
+ gtk_tree_model_get_iter_from_string(FTreeModel, @Iter, PChar(IntToStr(Index)));
+// gtk_tree_model_sort_convert_child_iter_to_iter(FTreeModelSort, @NewIter, @Iter);
+ Path := gtk_tree_model_get_path(FTreeModel, @Iter);
+ if not Assigned(Path) then Exit;
+ if Assigned(FTreeModelSort) then Path := gtk_tree_model_sort_convert_path_to_child_path(FTreeModelSort, Path);
+ if not Assigned(Path) then Exit;
+ Result := StrToIntDef(String(gtk_tree_path_to_string(Path)), Index);
+ gtk_tree_path_free(Path);
+ end;
+end;
+
+procedure CellDataFunc(tree_column : PGtkTreeViewColumn; cell : PGtkCellRenderer; tree_model : PGtkTreeModel; iter : PGtkTreeIter; data : gpointer); cdecl;
+begin
+ if Assigned(TGTKView(data).FCellDataFunc) then TGTKView(data).FCellDataFunc(TGTKView(data), PGtkTreeView(TGTKView(data).FWidget), tree_column, cell, tree_model, iter);
+end;
+
+
+(********************************************************************************************************************************)
+(********************************************************************************************************************************)
+constructor TGTKListView.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FListItems := TGTKListItems.Create(Self);
+ FSortable := False;
+ FCompareFunc := nil;
+ Recreate;
+end;
+
+destructor TGTKListView.Destroy;
+begin
+ FListItems.Free;
+ inherited Destroy;
+end;
+
+procedure TGTKListView_changed(treeselection: PGtkTreeSelection; user_data: gpointer); cdecl;
+begin
+ if Assigned(TGTKListView(user_data).FOnSelectionChanged) then TGTKListView(user_data).FOnSelectionChanged(TGTKListView(user_data));
+end;
+
+procedure TGTKListView_row_activated(treeview: PGtkTreeView; arg1: PGtkTreePath; arg2: PGtkTreeViewColumn; user_data: gpointer); cdecl;
+var Item: TGTKListItem;
+ AIndex: integer;
+begin
+ Item := nil;
+ if Assigned(arg1) then begin
+ TGTKListView(user_data).ConvertPathToChild(arg1);
+ if Application.GTKVersion_2_0_5_Up then AIndex := gtk_tree_path_get_indices(arg1)^
+ else AIndex := StrToIntDef(String(gtk_tree_path_to_string(arg1)), 0);
+ Item := TGTKListView(user_data).Items[AIndex];
+ Item.FIndex := AIndex;
+ end;
+ if Assigned(TGTKListView(user_data).FOnItemActivate) then TGTKListView(user_data).FOnItemActivate(TGTKListView(user_data), Item);
+end;
+
+procedure TGTKListView_columns_changed(treeselection: PGtkTreeSelection; user_data: gpointer); cdecl;
+begin
+ if Assigned(TGTKListView(user_data).FOnColumnsChanged) then TGTKListView(user_data).FOnColumnsChanged(TGTKListView(user_data));
+end;
+
+procedure TGTKListView.Recreate;
+begin
+ if Assigned(FWidget) then gtk_widget_destroy(PGtkWidget(FWidget));
+ FTreeModelSort := nil;
+ if not FSortable then FWidget := gtk_tree_view_new_with_model(PGtkTreeModel(FListItems.FStore))
+ else begin
+ FTreeModelSort := gtk_tree_model_sort_new_with_model(FListItems.FStore);
+ FWidget := gtk_tree_view_new_with_model(FTreeModelSort);
+ end;
+ FSelection := gtk_tree_view_get_selection(PGtkTreeView(FWidget));
+ g_signal_connect(FSelection, 'changed', G_CALLBACK(@TGTKListView_changed), Self);
+ g_signal_connect(FWidget, 'row-activated', G_CALLBACK(@TGTKListView_row_activated), Self);
+ g_signal_connect(FWidget, 'columns-changed', G_CALLBACK(@TGTKListView_columns_changed), Self);
+ FTreeModel := gtk_tree_view_get_model(PGtkTreeView(FWidget));
+ Show;
+end;
+
+constructor TGTKListView.CreateTyped(AOwner: TComponent; Sortable: boolean; ColumnTypes: array of TGTKListColumnType);
+begin
+ inherited Create(AOwner);
+ FListItems := TGTKListItems.CreateTyped(Self, ColumnTypes);
+ FSortable := Sortable;
+ FCompareFunc := nil;
+ Recreate;
+end;
+
+function TGTKListView.GetSelected: TGTKListItem;
+var Iter{, NewIter}: TGtkTreeIter;
+ Path: PGtkTreePath;
+ AIndex: integer;
+ i: integer;
+begin
+ Result := nil;
+ Path := nil;
+ if not Application.GTKVersion_2_0_5_Up then begin
+ for i := 0 to Items.Count - 1 do begin
+ Path := gtk_tree_path_new_from_string(PChar(IntToStr(i)));
+ if gtk_tree_selection_path_is_selected(gtk_tree_view_get_selection(PGtkTreeView(FWidget)), Path) then Break else
+// WriteLn('Index ', i, ', Selected: ', gtk_tree_selection_path_is_selected(gtk_tree_view_get_selection(PGtkTreeView(FWidget)), Path));
+ gtk_tree_path_free(Path);
+ Path := nil;
+ end;
+// WriteLn('Selected: ', String(gtk_tree_path_to_string(Path)));
+ ConvertPathToChild(Path);
+(* gtk_tree_model_get_iter_from_string(gtk_tree_view_get_model(PGtkTreeView(FWidget)){FTreeModelSort}, @Iter, gtk_tree_path_to_string(Path));
+ gtk_tree_model_sort_convert_child_iter_to_iter(FTreeModelSort, @NewIter, @Iter);
+ Path := gtk_tree_model_get_path({FTreeModelSort}gtk_tree_view_get_model(PGtkTreeView(FWidget)), @NewIter);
+ *)
+// gtk_tree_model_sort_clear_cache(FTreeModelSort);
+// Path := gtk_tree_model_sort_convert_path_to_child_path(FTreeModelSort, Path);
+ end else begin
+ if not gtk_tree_selection_get_selected(gtk_tree_view_get_selection(PGtkTreeView(FWidget)), nil, @Iter) then Exit;
+ Path := gtk_tree_model_get_path(gtk_tree_view_get_model(PGtkTreeView(FWidget)), @iter);
+ if not Assigned(Path) then Exit;
+ ConvertPathToChild(Path);
+ end;
+// WriteLn('Selected Converted: ', String(gtk_tree_path_to_string(Path)));
+ if Assigned(Path) then begin
+ if Application.GTKVersion_2_0_5_Up then AIndex := gtk_tree_path_get_indices(Path)^
+ else AIndex := StrToIntDef(String(gtk_tree_path_to_string(Path)), 0);
+ Result := Items[AIndex];
+ Result.FIndex := AIndex;
+ gtk_tree_path_free(Path);
+ end;
+end;
+
+procedure TGTKListView.SetSelected(Value: TGTKListItem);
+var Path: PGtkTreePath;
+begin
+ Path := gtk_tree_path_new_from_string(StringToPgchar(IntToStr(Value.FIndex)));
+ ConvertChildToPath(Path);
+ gtk_tree_selection_select_path(FSelection, Path);
+ gtk_tree_path_free(Path);
+end;
+
+function GtkTreeIterCompareFunc(model: PGtkTreeModel; a: PGtkTreeIter; b: PGtkTreeIter; user_data: gpointer): gint; cdecl;
+var Value: TGValue;
+ s: string;
+begin
+ if not Assigned(TGTKListView(user_data).FCompareFunc) then begin
+ Value.g_type := 0;
+ gtk_tree_model_get_value(model, a, TGTKView(user_data).GetSortColumnID, @Value);
+ s := string(PChar(Value.data[0].v_pointer));
+ Value.g_type := 0;
+ gtk_tree_model_get_value(model, b, TGTKView(user_data).GetSortColumnID, @Value);
+ Result := AnsiCompareStr(s, PChar(Value.data[0].v_pointer));
+ end else Result := TGTKListView(user_data).FCompareFunc(TGTKView(user_data), model, a, b);
+end;
+
+procedure TGTKListView.StartEditing(ColumnNo: integer);
+var Iter: TGtkTreeIter;
+ Path: PGtkTreePath;
+begin
+ if not gtk_tree_selection_get_selected(FSelection, nil, @Iter) then Exit;
+ Path := gtk_tree_model_get_path(FTreeModel, @iter);
+ if not Assigned(Path) then Exit;
+ gtk_tree_view_set_cursor(PGtkTreeView(FWidget), Path, FColumns[ColumnNo].FColumn, True);
+end;
+
+function TGTKListView.GetItemAtPos(X, Y: integer): TGTKListItem;
+var Path: PGtkTreePath;
+ Column: PGtkTreeViewColumn;
+ AIndex: integer;
+begin
+ Result := nil;
+ if gtk_tree_view_get_path_at_pos(PGtkTreeView(FWidget), X, Y, Path, Column, nil, nil) then begin
+ if not Assigned(Path) then Exit;
+ ConvertPathToChild(Path);
+ if Application.GTKVersion_2_0_5_Up then AIndex := gtk_tree_path_get_indices(Path)^
+ else AIndex := StrToIntDef(String(gtk_tree_path_to_string(Path)), 0);
+ Result := Items[AIndex];
+ Result.FIndex := AIndex;
+ gtk_tree_path_free(Path);
+ end;
+end;
+
+
+(********************************************************************************************************************************)
+(********************************************************************************************************************************)
+constructor TGTKListItems.Create(AOwner: TComponent);
+const Types : GType = G_TYPE_STRING;
+begin
+ inherited Create(AOwner);
+ FOwner := AOwner;
+ FStore := gtk_list_store_newv(1, @Types);
+ FList := TList.Create;
+end;
+
+destructor TGTKListItems.Destroy;
+begin
+ if not (csDestroying in ComponentState) then begin
+ Clear;
+ FList.Free;
+ gtk_object_destroy(PGtkObject(FStore));
+ end;
+ inherited Destroy;
+end;
+
+constructor TGTKListItems.CreateTyped(AOwner: TComponent; ColumnTypes: array of TGTKListColumnType);
+var i: integer;
+ Cols : array[0..255] of GType;
+begin
+ inherited Create(AOwner);
+ FOwner := AOwner;
+ FList := TList.Create;
+ for i := Low(ColumnTypes) to High(ColumnTypes) do
+ case ColumnTypes[i] of
+ lcText : Cols[i] := G_TYPE_STRING;
+ lcNumber : Cols[i] := G_TYPE_LONG;
+ lcPointer : Cols[i] := G_TYPE_POINTER;
+ lcPixbuf : Cols[i] := GDK_TYPE_PIXBUF;
+ lcBoolean : Cols[i] := G_TYPE_BOOLEAN;
+ end;
+ FStore := gtk_list_store_newv(Length(ColumnTypes), @Cols);
+end;
+
+procedure TGTKListItems.SetColumnTypes(Types: array of TGTKListColumnType);
+var i: integer;
+ Cols : array[0..255] of GType;
+begin
+ for i := Low(Types) to High(Types) do
+ case Types[i] of
+ lcText : Cols[i] := G_TYPE_STRING;
+ lcNumber : Cols[i] := G_TYPE_LONG;
+ lcPointer : Cols[i] := G_TYPE_POINTER;
+ lcPixbuf : Cols[i] := GDK_TYPE_PIXBUF;
+ lcBoolean : Cols[i] := G_TYPE_BOOLEAN;
+ end;
+ g_object_unref(PGObject(FStore));
+ FStore := gtk_list_store_newv(Length(Types), @Cols);
+ (FOwner as TGTKListView).Recreate;
+end;
+
+function TGTKListItems.GetItem(Index: longint): TGTKListItem;
+begin
+ Result := TGTKListItem(FList[Index]);
+ Result.FIndex := Index;
+end;
+
+procedure TGTKListItems.SetItem(Index: longint; Value: TGTKListItem);
+begin
+ FList[Index] := Value;
+end;
+
+function TGTKListItems.Add: TGTKListItem;
+begin
+ Result := TGTKListItem.Create(Self);
+ Result.FIndex := GetCount;
+// Insert(GetCount, Result);
+ Append(Result);
+end;
+
+function TGTKListItems.GetCount: longint;
+begin
+ Result := FList.Count;
+end;
+
+procedure TGTKListItems.Clear;
+var i: longint;
+begin
+ for i := Count - 1 downto 0 do Delete(i); // !!!! DON'T use here gtk_list_store_clear(FStore), because it causes memory leaks !!!!
+end;
+
+procedure TGTKListItems.Delete(Index: longint);
+var x: pointer;
+ Iter: TGtkTreeIter;
+begin
+ x := FList[Index];
+ if gtk_tree_model_get_iter_from_string(PGtkTreeModel(FStore), @Iter, StringToPgchar(IntToStr(Index))) then begin
+// (FOwner as TGTKView).CovertSortableIter(Iter);
+ gtk_list_store_remove(FStore, @Iter);
+ end;
+ FList.Delete(Index);
+ TObject(x).Free;
+end;
+
+procedure TGTKListItems.Insert(Index: longint; Item: TGTKListItem);
+var Iter: TGtkTreeIter;
+begin
+ FList.Insert(Index, Item);
+ gtk_list_store_insert(FStore, @Iter, Index);
+end;
+
+procedure TGTKListItems.Append(Item: TGTKListItem);
+var Iter: TGtkTreeIter;
+begin
+ FList.Add(Item);
+ gtk_list_store_append(FStore, @Iter);
+end;
+
+(********************************************************************************************************************************)
+(********************************************************************************************************************************)
+constructor TGTKTreeViewColumns.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FOwner := AOwner;
+ FList := TList.Create;
+end;
+
+destructor TGTKTreeViewColumns.Destroy;
+begin
+ if not (csDestroying in ComponentState) then begin
+ Clear;
+ FList.Free;
+ end;
+ inherited Destroy;
+end;
+
+function TGTKTreeViewColumns.GetItem(Index: Integer): TGTKTreeViewColumn;
+begin
+ Result := TGTKTreeViewColumn(FList[Index]);
+ Result.FIndex := Index;
+end;
+
+procedure TGTKTreeViewColumns.SetItem(Index: Integer; Value: TGTKTreeViewColumn);
+begin
+ FList[Index] := Value;
+end;
+
+function TGTKTreeViewColumns.Add: TGTKTreeViewColumn;
+begin
+ Result := TGTKTreeViewColumn.Create(Self);
+ Result.FIndex := GetCount;
+ Insert(GetCount, Result);
+end;
+
+function TGTKTreeViewColumns.AddTyped(ColType: TGTKTreeViewColumnType): TGTKTreeViewColumn;
+begin
+ Result := TGTKTreeViewColumn.CreateTyped(Self, ColType);
+ Result.FIndex := GetCount;
+ Insert(GetCount, Result);
+end;
+
+function TGTKTreeViewColumns.GetCount: Integer;
+begin
+ Result := FList.Count;
+end;
+
+procedure TGTKTreeViewColumns.Clear;
+var i: Integer;
+begin
+ for i := Count - 1 downto 0 do Delete(i);
+end;
+
+procedure TGTKTreeViewColumns.Delete(Index: Integer);
+var x : pointer;
+begin
+ if not (csDestroying in ComponentState) then
+ gtk_tree_view_remove_column(PGtkTreeView((FOwner as TGTKControl).FWidget), TGTKTreeViewColumn(FList[Index]).FColumn);
+ x := FList[Index];
+ FList.Delete(Index);
+ TObject(x).Free;
+end;
+
+procedure TGTKTreeViewColumns.Insert(Index: Integer; Item: TGTKTreeViewColumn);
+begin
+ FList.Insert(Index, Item);
+ Item.FIndex := Index;
+ gtk_tree_view_insert_column(PGtkTreeView((FOwner as TGTKControl).FWidget), Item.FColumn, Index);
+ if Assigned((FOwner as TGTKView).FTreeModelSort) then
+ gtk_tree_sortable_set_sort_func(PGtkTreeSortable((FOwner as TGTKView).FTreeModelSort), Index, TGtkTreeIterCompareFunc(@GtkTreeIterCompareFunc), FOwner, nil);
+ gtk_tree_view_column_set_cell_data_func(Item.FColumn, Item.FRenderer, @CellDataFunc, (FOwner as TGTKView), nil);
+ if Item.ColumnType = ctImageText then gtk_tree_view_column_set_cell_data_func(Item.FColumn, Item.FPixbufRenderer, @CellDataFunc, (FOwner as TGTKView), nil);
+end;
+
+procedure TGTKTreeViewColumns.AutosizeColumns;
+begin
+ gtk_tree_view_columns_autosize(PGtkTreeView((FOwner as TGTKControl).FWidget));
+end;
+
+(********************************************************************************************************************************)
+(********************************************************************************************************************************)
+constructor TGTKTreeViewColumn.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FOwner := AOwner;
+ FColumn := gtk_tree_view_column_new;
+ FRenderer := nil;
+ FPixbufRenderer := nil;
+ FOnEdited := nil;
+ FOnToggled := nil;
+ FOnClicked := nil;
+ SetColumnType(ctText);
+end;
+
+constructor TGTKTreeViewColumn.CreateTyped(AOwner: TComponent; ColType: TGTKTreeViewColumnType);
+begin
+ inherited Create(AOwner);
+ FOwner := AOwner;
+ FColumn := gtk_tree_view_column_new;
+ FRenderer := nil;
+ FPixbufRenderer := nil;
+ FOnEdited := nil;
+ FOnToggled := nil;
+ FOnClicked := nil;
+ SetColumnType(ColType);
+end;
+
+destructor TGTKTreeViewColumn.Destroy;
+begin
+ if not (csDestroying in ComponentState) then begin
+ gtk_object_destroy(PGtkObject(FRenderer));
+ if GTK_IS_OBJECT(FColumn) then gtk_object_destroy(PGtkObject(FColumn));
+ end;
+ inherited Destroy;
+end;
+
+function TGTKTreeViewColumn.GetCaption: string;
+begin
+ Result := PgcharToString(gtk_tree_view_column_get_title(FColumn));
+end;
+
+procedure TGTKTreeViewColumn.SetCaption(Value: string);
+begin
+ gtk_tree_view_column_set_title(FColumn, StringToPgchar(Value));
+end;
+
+function TGTKTreeViewColumn.GetVisible: boolean;
+begin
+ Result := gtk_tree_view_column_get_visible(FColumn);
+end;
+
+procedure TGTKTreeViewColumn.SetVisible(Value: boolean);
+begin
+ gtk_tree_view_column_set_visible(FColumn, Value);
+end;
+
+function TGTKTreeViewColumn.GetResizable: boolean;
+begin
+ Result := gtk_tree_view_column_get_resizable(FColumn);
+end;
+
+procedure TGTKTreeViewColumn.SetResizable(Value: boolean);
+begin
+ gtk_tree_view_column_set_resizable(FColumn, Value);
+end;
+
+function TGTKTreeViewColumn.GetSizingMode: TGTKTreeViewColumnSizingMode;
+begin
+ Result := TGTKTreeViewColumnSizingMode(gtk_tree_view_column_get_sizing(FColumn));
+end;
+
+procedure TGTKTreeViewColumn.SetSizingMode(Value: TGTKTreeViewColumnSizingMode);
+begin
+ gtk_tree_view_column_set_sizing(FColumn, TGtkTreeViewColumnSizing(Value));
+end;
+
+function TGTKTreeViewColumn.GetWidth: integer;
+begin
+ Result := gtk_tree_view_column_get_width(FColumn);
+end;
+
+function TGTKTreeViewColumn.GetFixedWidth: integer;
+begin
+ Result := gtk_tree_view_column_get_fixed_width(FColumn);
+end;
+
+procedure TGTKTreeViewColumn.SetFixedWidth(Value: integer);
+begin
+ gtk_tree_view_column_set_fixed_width(FColumn, Value);
+end;
+
+function TGTKTreeViewColumn.GetMinWidth: integer;
+begin
+ Result := gtk_tree_view_column_get_min_width(FColumn);
+end;
+
+procedure TGTKTreeViewColumn.SetMinWidth(Value: integer);
+begin
+ gtk_tree_view_column_set_min_width(FColumn, Value);
+end;
+
+function TGTKTreeViewColumn.GetMaxWidth: integer;
+begin
+ Result := gtk_tree_view_column_get_max_width(FColumn);
+end;
+
+procedure TGTKTreeViewColumn.SetMaxWidth(Value: integer);
+begin
+ gtk_tree_view_column_set_max_width(FColumn, Value);
+end;
+
+function TGTKTreeViewColumn.GetClickable: boolean;
+begin
+ Result := gtk_tree_view_column_get_clickable(FColumn);
+end;
+
+procedure TGTKTreeViewColumn.SetClickable(Value: boolean);
+begin
+ gtk_tree_view_column_set_clickable(FColumn, Value);
+end;
+
+function TGTKTreeViewColumn.GetAlignment: Double;
+begin
+ Result := gtk_tree_view_column_get_alignment(FColumn);
+end;
+
+procedure TGTKTreeViewColumn.SetAlignment(Value: Double);
+begin
+ gtk_tree_view_column_set_alignment(FColumn, Value);
+end;
+
+function TGTKTreeViewColumn.GetReorderable: boolean;
+begin
+ Result := gtk_tree_view_column_get_reorderable(FColumn);
+end;
+
+procedure TGTKTreeViewColumn.SetReorderable(Value: boolean);
+begin
+ gtk_tree_view_column_set_reorderable(FColumn, Value);
+end;
+
+function TGTKTreeViewColumn.GetSortID: integer;
+begin
+ Result := gtk_tree_view_column_get_sort_column_id(FColumn);
+end;
+
+procedure TGTKTreeViewColumn.SetSortID(Value: integer);
+begin
+ gtk_tree_view_column_set_sort_column_id(FColumn, Value);
+end;
+
+function TGTKTreeViewColumn.GetShowSortIndicator: boolean;
+begin
+ Result := gtk_tree_view_column_get_sort_indicator(FColumn);
+end;
+
+procedure TGTKTreeViewColumn.SetShowSortIndicator(Value: boolean);
+begin
+ gtk_tree_view_column_set_sort_indicator(FColumn, Value);
+end;
+
+function TGTKTreeViewColumn.GetSortOrder: TGTKTreeViewSortOrder;
+begin
+ Result := TGTKTreeViewSortOrder(gtk_tree_view_column_get_sort_order(FColumn));
+end;
+
+procedure TGTKTreeViewColumn.SetSortOrder(Value: TGTKTreeViewSortOrder);
+begin
+ gtk_tree_view_column_set_sort_order(FColumn, TGtkSortType(Value));
+end;
+
+procedure TGTKTreeViewColumn_edited(cell: PGtkCellRendererText; const path_string, new_text: pgchar; data: gpointer); cdecl;
+var NewText: string;
+ AllowChange: boolean;
+ DataColumn, AIndex: integer;
+ Path: PGtkTreePath;
+begin
+ if Assigned(TGTKTreeViewColumn(data).FOnEdited) then begin
+ NewText := PgcharToString(new_text);
+ AllowChange := True;
+ DataColumn := TGTKTreeViewColumn(data).FIndex;
+ Path := gtk_tree_path_new_from_string(path_string);
+ if not Assigned(Path) then Exit;
+ if Application.GTKVersion_2_0_5_Up then AIndex := gtk_tree_path_get_indices(Path)^
+ else AIndex := StrToIntDef(String(gtk_tree_path_to_string(Path)), 0);
+ TGTKTreeViewColumn(data).FOnEdited(TGTKTreeViewColumn(data), TGTKTreeViewColumn(data), ((TGTKTreeViewColumn(data).FOwner as TGTKTreeViewColumns).FOwner as TGTKListView).Items[AIndex], NewText, AllowChange, DataColumn);
+ if AllowChange and (((TGTKTreeViewColumn(data).FOwner as TGTKTreeViewColumns).FOwner as TGTKListView).Items.Count < AIndex) then
+ ((TGTKTreeViewColumn(data).FOwner as TGTKTreeViewColumns).FOwner as TGTKListView).Items[AIndex].SetValue(DataColumn, NewText);
+ gtk_tree_path_free(Path);
+ end;
+end;
+
+procedure TGTKTreeViewColumn_toggled(cell: PGtkCellRendererToggle; const path_string: pgchar; data: gpointer); cdecl;
+var Path: PGtkTreePath;
+ AIndex: integer;
+begin
+ if Assigned(data) and Assigned(TGTKTreeViewColumn(data).FOnToggled) then begin
+ Path := gtk_tree_path_new_from_string(path_string);
+ if not Assigned(Path) then Exit;
+ if Application.GTKVersion_2_0_5_Up then AIndex := gtk_tree_path_get_indices(Path)^
+ else AIndex := StrToIntDef(String(gtk_tree_path_to_string(Path)), 0);
+ TGTKTreeViewColumn(data).FOnToggled(TGTKTreeViewColumn(data), TGTKTreeViewColumn(data), ((TGTKTreeViewColumn(data).FOwner as TGTKTreeViewColumns).FOwner as TGTKListView).Items[AIndex]);
+ end;
+end;
+
+procedure TGTKTreeViewColumn_clicked(treeviewcolumn: PGtkTreeViewColumn; user_data: gpointer); cdecl;
+begin
+ if Assigned(user_data) and Assigned(TGTKTreeViewColumn(user_data).FOnClicked) then
+ TGTKTreeViewColumn(user_data).FOnClicked(TGTKTreeViewColumn(user_data));
+end;
+
+procedure TGTKTreeViewColumn.SetColumnType(Value: TGTKTreeViewColumnType);
+begin
+ FColumnType := Value;
+ if Assigned(FRenderer) then begin
+ gtk_tree_view_column_clear(FColumn);
+ gtk_object_destroy(PGtkObject(FRenderer));
+ end;
+ case Value of
+ ctText : FRenderer := gtk_cell_renderer_text_new;
+ ctToggle : FRenderer := gtk_cell_renderer_toggle_new;
+ ctImageText : begin
+ FRenderer := gtk_cell_renderer_text_new;
+ FPixbufRenderer := gtk_cell_renderer_pixbuf_new;
+ end;
+ end;
+ if Value = ctImageText then gtk_tree_view_column_pack_start(FColumn, FPixbufRenderer, False);
+ gtk_tree_view_column_pack_start(FColumn, FRenderer, True);
+ if (Value = ctImageText) or (Value = ctText) then g_signal_connect(FRenderer, 'edited', G_CALLBACK(@TGTKTreeViewColumn_edited), Self);
+ if Value = ctToggle then g_signal_connect(FRenderer, 'toggled', G_CALLBACK(@TGTKTreeViewColumn_toggled), Self);
+ g_signal_connect_after(FColumn, 'clicked', G_CALLBACK(@TGTKTreeViewColumn_clicked), Self);
+end;
+
+procedure TGTKTreeViewColumn.AddAttribute(Attribute: string; Value: integer);
+begin
+ gtk_tree_view_column_add_attribute(FColumn, FRenderer, StringToPgchar(Attribute), Value);
+end;
+
+procedure TGTKTreeViewColumn.AddImageAttribute(Attribute: string; Value: integer);
+begin
+ gtk_tree_view_column_add_attribute(FColumn, FPixbufRenderer, StringToPgchar(Attribute), Value);
+end;
+
+procedure TGTKTreeViewColumn.ClearAttributes;
+begin
+ gtk_tree_view_column_clear_attributes(FColumn, FRenderer);
+end;
+
+procedure TGTKTreeViewColumn.SetProperty(AProperty: string; Value: integer);
+var AValue: TGValue;
+begin
+ AValue.g_type := G_TYPE_LONG;
+ AValue.data[0].v_long := Value;
+ g_object_set_property(PGObject(FRenderer), StringToPgchar(AProperty), @AValue);
+end;
+
+procedure TGTKTreeViewColumn.SetProperty(AProperty: string; Value: string);
+var AValue: TGValue;
+begin
+ AValue.g_type := G_TYPE_STRING;
+ AValue.data[0].v_pointer := StringToPgchar(Value);
+ g_object_set_property(PGObject(FRenderer), StringToPgchar(AProperty), @AValue);
+end;
+
+procedure TGTKTreeViewColumn.SetProperty(AProperty: string; Value: Double);
+var AValue: TGValue;
+begin
+ AValue.g_type := G_TYPE_DOUBLE;
+ AValue.data[0].v_double := Value;
+ g_object_set_property(PGObject(FRenderer), StringToPgchar(AProperty), @AValue);
+end;
+
+procedure TGTKTreeViewColumn.SetProperty(AProperty: string; Value: pointer);
+var AValue: TGValue;
+begin
+ AValue.g_type := G_TYPE_POINTER;
+ AValue.data[0].v_pointer := Value;
+ g_object_set_property(PGObject(FRenderer), StringToPgchar(AProperty), @AValue);
+end;
+
+procedure TGTKTreeViewColumn.SetImageProperty(AProperty: string; Value: integer);
+var AValue: TGValue;
+begin
+ AValue.g_type := G_TYPE_LONG;
+ AValue.data[0].v_long := Value;
+ g_object_set_property(PGObject(FPixbufRenderer), StringToPgchar(AProperty), @AValue);
+end;
+
+procedure TGTKTreeViewColumn.SetImageProperty(AProperty: string; Value: string);
+var AValue: TGValue;
+begin
+ AValue.g_type := G_TYPE_STRING;
+ AValue.data[0].v_pointer := StringToPgchar(Value);
+ g_object_set_property(PGObject(FPixbufRenderer), StringToPgchar(AProperty), @AValue);
+end;
+
+procedure TGTKTreeViewColumn.SetImageProperty(AProperty: string; Value: Double);
+var AValue: TGValue;
+begin
+ AValue.g_type := G_TYPE_DOUBLE;
+ AValue.data[0].v_double := Value;
+ g_object_set_property(PGObject(FPixbufRenderer), StringToPgchar(AProperty), @AValue);
+end;
+
+procedure TGTKTreeViewColumn.SetImageProperty(AProperty: string; Value: pointer);
+var AValue: TGValue;
+begin
+ AValue.g_type := G_TYPE_POINTER;
+ AValue.data[0].v_pointer := Value;
+ g_object_set_property(PGObject(FPixbufRenderer), StringToPgchar(AProperty), @AValue);
+end;
+
+(********************************************************************************************************************************)
+(********************************************************************************************************************************)
+constructor TGTKListItem.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FOwner := AOwner;
+ FData := nil;
+end;
+
+destructor TGTKListItem.Destroy;
+begin
+ inherited Destroy;
+end;
+
+function TGTKListItem.AsString(Index: longint): string;
+var Iter: TGtkTreeIter;
+ AValue: TGValue;
+begin
+ Result := '';
+ if gtk_tree_model_get_iter_from_string(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, StringToPgchar(IntToStr(FIndex))) then
+ begin
+ AValue.g_type := 0;
+ gtk_tree_model_get_value(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, Index, @AValue);
+ Result := PgcharToString(AValue.data[0].v_pointer);
+ end;
+end;
+
+function TGTKListItem.AsInteger(Index: longint): integer;
+var Iter: TGtkTreeIter;
+ AValue: TGValue;
+begin
+ Result := 0;
+ if gtk_tree_model_get_iter_from_string(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, StringToPgchar(IntToStr(FIndex))) then
+ begin
+ AValue.g_type := 0;
+ gtk_tree_model_get_value(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, Index, @AValue);
+ Result := AValue.data[0].v_long;
+ end;
+end;
+
+function TGTKListItem.AsPointer(Index: longint): pointer;
+var Iter: TGtkTreeIter;
+ AValue: TGValue;
+begin
+ Result := nil;
+ if gtk_tree_model_get_iter_from_string(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, StringToPgchar(IntToStr(FIndex))) then
+ begin
+ AValue.g_type := 0;
+ gtk_tree_model_get_value(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, Index, @AValue);
+ Result := AValue.data[0].v_pointer;
+ end;
+end;
+
+function TGTKListItem.AsBoolean(Index: longint): boolean;
+var Iter: TGtkTreeIter;
+ AValue: TGValue;
+begin
+ Result := False;
+ if gtk_tree_model_get_iter_from_string(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, StringToPgchar(IntToStr(FIndex))) then
+ begin
+ AValue.g_type := 0;
+ gtk_tree_model_get_value(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, Index, @AValue);
+ Result := boolean(AValue.data[0].v_int);
+ end;
+end;
+
+procedure TGTKListItem.SetValue(Index: longint; Value: string);
+var Iter: TGtkTreeIter;
+begin
+ if gtk_tree_model_get_iter_from_string(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, StringToPgchar(IntToStr(FIndex)))
+ then gtk_list_store_set(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, Index, StringToPgchar(Value), -1);
+end;
+
+procedure TGTKListItem.SetValue(Index: longint; Value: integer);
+var Iter: TGtkTreeIter;
+begin
+ if gtk_tree_model_get_iter_from_string(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, StringToPgchar(IntToStr(FIndex)))
+ then gtk_list_store_set(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, Index, Value, -1);
+end;
+
+procedure TGTKListItem.SetValue(Index: longint; Value: pointer);
+var Iter: TGtkTreeIter;
+begin
+ if gtk_tree_model_get_iter_from_string(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, StringToPgchar(IntToStr(FIndex)))
+ then gtk_list_store_set(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, Index, Value, -1);
+end;
+
+procedure TGTKListItem.SetValue(Index: longint; Value: boolean);
+var Iter: TGtkTreeIter;
+begin
+ if gtk_tree_model_get_iter_from_string(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, StringToPgchar(IntToStr(FIndex)))
+ then gtk_list_store_set(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, Index, Value, -1);
+end;
+
+function TGTKListItem.GetSelected: boolean;
+var Iter: TGtkTreeIter;
+begin
+ Result := False;
+ if gtk_tree_model_get_iter_from_string(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, StringToPgchar(IntToStr(FIndex))) then begin
+// ((FOwner as TGTKListItems).FOwner as TGTKView).ConvertSortableIter(Iter);
+ Result := gtk_tree_selection_iter_is_selected(((FOwner as TGTKListItems).FOwner as TGTKView).FSelection, @Iter);
+ end;
+end;
+
+procedure TGTKListItem.SetSelected(Value: boolean);
+var Iter, NewIter: TGtkTreeIter;
+ Path: PGtkTreePath;
+begin
+ try
+ if not Application.GTKVersion_2_0_5_Up then begin
+ Path := gtk_tree_path_new_from_string(StringToPgchar(IntToStr(FIndex)));
+ ((FOwner as TGTKListItems).FOwner as TGTKView).ConvertChildToPath(Path);
+ gtk_tree_selection_select_path(((FOwner as TGTKListItems).FOwner as TGTKView).FSelection, Path);
+ gtk_tree_path_free(Path);
+ end else
+ if gtk_tree_model_get_iter_from_string(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, StringToPgchar(IntToStr(FIndex))) then begin
+ if Assigned(((FOwner as TGTKListItems).FOwner as TGTKView).FTreeModelSort) then begin
+ gtk_tree_model_sort_convert_child_iter_to_iter(((FOwner as TGTKListItems).FOwner as TGTKView).FTreeModelSort, @NewIter, @Iter);
+ Iter := NewIter;
+ end;
+ if Value then gtk_tree_selection_select_iter(((FOwner as TGTKListItems).FOwner as TGTKView).FSelection, @Iter)
+ else gtk_tree_selection_unselect_iter(((FOwner as TGTKListItems).FOwner as TGTKView).FSelection, @Iter);
+ end;
+ except end;
+end;
+
+procedure TGTKListItem.SetCursor(const FocusColumnNo: integer; const StartEditing, UseAlignment: boolean; const AlignX, AlignY: Double);
+var Path: PGtkTreePath;
+ Column: PGtkTreeViewColumn;
+// Renderer: PGtkCellRenderer;
+ i : integer;
+begin
+ Path := gtk_tree_path_new_from_string(StringToPgchar(IntToStr(FIndex)));
+ if not Assigned(Path) then Exit;
+ ((FOwner as TGTKListItems).FOwner as TGTKView).ConvertChildToPath(Path);
+ if not Assigned(Path) then Exit;
+
+ Column := ((FOwner as TGTKListItems).FOwner as TGTKView).Columns[FocusColumnNo].FColumn;
+// Renderer := ((FOwner as TGTKListItems).FOwner as TGTKView).Columns[FocusColumnNo].FRenderer;
+
+// if not Application.GTKVersion_2_0_5_Up then
+ for i := 1 to 2 do gtk_main_iteration_do(False); // This ugly piece of code HAVE TO BE HERE due some focus-related problems in GtkTreeView
+ gtk_tree_view_set_cursor(PGtkTreeView(((FOwner as TGTKListItems).FOwner as TGTKView).FWidget), Path, Column, StartEditing);
+// gtk_tree_view_set_cursor(PGtkTreeView(((FOwner as TGTKListItems).FOwner as TGTKView).FWidget), Path, Column, StartEditing);
+// gtk_tree_view_set_cursor_on_cell(PGtkTreeView(((FOwner as TGTKListItems).FOwner as TGTKView).FWidget), Path, Column, Renderer, StartEditing);
+ gtk_tree_view_scroll_to_cell(PGtkTreeView(((FOwner as TGTKListItems).FOwner as TGTKView).FWidget), Path, nil, UseAlignment, AlignX, AlignY);
+
+ gtk_tree_path_free(Path);
+end;
+
+procedure TGTKListItem.StartEditing(ColumnNo: integer);
+var CellEditable: PGtkCellEditable;
+ Path: PGtkTreePath;
+ Column: PGtkTreeViewColumn;
+ BackgroundRect, CellRect: TGdkRectangle;
+begin
+ Path := gtk_tree_path_new_from_string(StringToPgchar(IntToStr(FIndex)));
+ if not Assigned(Path) then Exit;
+ ((FOwner as TGTKListItems).FOwner as TGTKView).ConvertChildToPath(Path);
+ if not Assigned(Path) then Exit;
+ Column := ((FOwner as TGTKListItems).FOwner as TGTKView).Columns[ColumnNo].FColumn;
+ gtk_tree_view_get_background_area(PGtkTreeView(((FOwner as TGTKListItems).FOwner as TGTKView).FWidget), Path, Column, @BackgroundRect);
+ gtk_tree_view_get_cell_area(PGtkTreeView(((FOwner as TGTKListItems).FOwner as TGTKView).FWidget), Path, Column, @CellRect);
+
+ gtk_tree_view_column_focus_cell(Column, ((FOwner as TGTKListItems).FOwner as TGTKView).Columns[ColumnNo].FRenderer);
+ CellEditable := gtk_cell_renderer_start_editing(((FOwner as TGTKListItems).FOwner as TGTKView).Columns[ColumnNo].FRenderer,
+ nil, ((FOwner as TGTKListItems).FOwner as TGTKView).FWidget, PChar(StringToPgchar(IntToStr(FIndex))),
+ @BackgroundRect, @CellRect, {GTK_CELL_RENDERER_SELECTED or GTK_CELL_RENDERER_SORTED} 0);
+ gtk_widget_show(CellEditable);
+// gtk_cell_editable_start_editing(CellEditable, nil);
+
+
+ gtk_tree_path_free(Path);
+end;
+
+procedure TGTKListItem.RedrawRow;
+var Rect, BackgroundRect: TGdkRectangle;
+ Path: PGtkTreePath;
+ Column: PGtkTreeViewColumn;
+begin
+ Path := gtk_tree_path_new_from_string(StringToPgchar(IntToStr(FIndex)));
+ if not Assigned(Path) then Exit;
+ ((FOwner as TGTKListItems).FOwner as TGTKView).ConvertChildToPath(Path);
+ if not Assigned(Path) then Exit;
+ Column := ((FOwner as TGTKListItems).FOwner as TGTKView).Columns[0].FColumn;
+ gtk_tree_view_get_background_area(PGtkTreeView(((FOwner as TGTKListItems).FOwner as TGTKView).FWidget), Path, Column, @BackgroundRect);
+
+ Rect.x := 0;
+ Rect.width := ((FOwner as TGTKListItems).FOwner as TGTKView).FWidget^.allocation.width;
+ Rect.y := BackgroundRect.y;
+ Rect.height := BackgroundRect.height;
+ gdk_window_invalidate_rect(gtk_tree_view_get_bin_window(PGtkTreeView(((FOwner as TGTKListItems).FOwner as TGTKView).FWidget)), @Rect, True);
+
+ gtk_tree_path_free(Path);
+end;
+
+function TGTKListItem.IsVisible: boolean;
+var CellRect, VisibleRect: TGdkRectangle;
+ Path: PGtkTreePath;
+begin
+ Result := False;
+ gtk_tree_view_get_visible_rect(PGtkTreeView(((FOwner as TGTKListItems).FOwner as TGTKView).FWidget), @VisibleRect);
+ if not Assigned(Path) then Exit;
+ Path := gtk_tree_path_new_from_string(StringToPgchar(IntToStr(FIndex)));
+ ((FOwner as TGTKListItems).FOwner as TGTKView).ConvertChildToPath(Path);
+ if not Assigned(Path) then Exit;
+ gtk_tree_view_get_background_area(PGtkTreeView(((FOwner as TGTKListItems).FOwner as TGTKView).FWidget), Path, nil, @CellRect);
+ gtk_tree_path_free(Path);
+ Result := (CellRect.y > VisibleRect.y) and (CellRect.y + CellRect.height < VisibleRect.y + VisibleRect.height);
+end;
+
+
+(********************************************************************************************************************************)
+(********************************************************************************************************************************)
+
+
+end.