diff options
Diffstat (limited to 'libgtk_kylix/GTKView.pas')
| -rw-r--r-- | libgtk_kylix/GTKView.pas | 1376 |
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. |
