Is there a way to make the text in a column sortable? #1141
-
|
I've been trying to implement a sorter into the columns of my project, but so far from searching online has not really shown much in the way of information on how to implement them. I'm currently using Gtk.ColumnView and Gtk.ColumnViewColumn for the layout, but I'd really like to know what I actually need to use to make the header columns clickable so the contents in the ColumnViewColumn can be sorted. Apparently this guide for Gtkmm (the C++ bindings for GTK4) tell me that I have to use this for auto size_expression = Gtk::ClosureExpression<Glib::ustring::size_type>::create(
[](const Glib::RefPtr<Glib::ObjectBase>& item)->Glib::ustring::size_type
{
const auto col = std::dynamic_pointer_cast<ModelColumns>(item);
return col ? col->m_col_name.size() : 0;
});But I can't find any C# equivalent of this (unless I really have to use the Gtk.Internal ones). Here's what I currently have for the column view: using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Gtk;
using Kermalis.VGMusicStudio.Core;
using static Gtk.SignalListItemFactory;
namespace Kermalis.VGMusicStudio.GTK4.Util;
internal class SoundSequenceList : Viewport
{
public int? Id { get; set; }
public string? InternalName { get; set; }
public string? PlaylistName { get; set; }
public string? Offset { get; set; }
private bool IsSongTable = false;
private Gio.ListStore Model = Gio.ListStore.New(GetGType());
private SelectionModel? SelectionModel { get; set; }
private SortListModel? SortModel { get; set; }
private Sorter? ColumnSorter { get; set; }
private ColumnView? ColumnView { get; set; }
public SoundSequenceList[]? SoundData { get; set; }
public SoundSequenceList(int id, string name, string plistname, string offset)
: base()
{
Id = id;
InternalName = name;
PlaylistName = plistname;
if (offset is not null)
{
Offset = offset;
}
}
public void AddEntries(long numSongs, List<Config.InternalSongName> internalSongNames, List<Config.Playlist> playlists, int[] songTableOffsets)
{
SoundData = new SoundSequenceList[numSongs];
var sNames = new string[numSongs];
for (int i = 0; i < sNames.Length; i++)
{
sNames[i] = "";
}
if (internalSongNames is not null)
{
foreach (Config.InternalSongName sf in internalSongNames)
{
foreach (Config.Song s in sf.Songs)
{
sNames[s.Index] = s.Name;
}
}
}
var plistNames = new string[numSongs];
for (int i = 0; i < plistNames.Length; i++)
{
plistNames[i] = "";
}
if (playlists is not null)
{
foreach (Config.Playlist p in playlists)
{
foreach (Config.Song s in p.Songs)
{
plistNames[s.Index] = s.Name;
}
}
}
var offset = new string[numSongs];
if (songTableOffsets is not null)
{
IsSongTable = true;
for (int i = 0, s = 0; i < SoundData.Length; i++)
{
_ = new byte[4];
Span<byte> b = BitConverter.GetBytes(songTableOffsets[s] + (i * 8));
b.Reverse();
offset[i] = "0x" + Convert.ToHexString(b);
if (s < songTableOffsets.Length - 1)
{
s++;
}
}
}
else
{
IsSongTable = false;
}
for (int i = 0; i < SoundData!.Length; i++)
{
SoundData[i] = new SoundSequenceList(i, sNames[i], plistNames[i], offset[i]);
}
foreach (var data in SoundData!)
{
Model.Append(data);
}
}
internal SoundSequenceList()
{
var scrolledWindow = ScrolledWindow.New();
scrolledWindow.SetSizeRequest(200, 100);
SelectionModel = SingleSelection.New(Model);
ColumnView = ColumnView.New(SelectionModel);
ColumnView.AddCssClass("data-table");
ColumnView.SetShowColumnSeparators(true);
ColumnView.SetShowRowSeparators(true);
ColumnView.SetReorderable(false);
ColumnSorter = ColumnView.GetSorter()!;
SortModel = SortListModel.New(Model, ColumnSorter);
scrolledWindow.SetChild(ColumnView);
Child = scrolledWindow;
SetVexpand(true);
}
internal void Init()
{
// ID Column
var listItemFactory = SignalListItemFactory.New();
listItemFactory.OnSetup += (_, args) => OnSetupLabel(args, Align.Center);
listItemFactory.OnBind += (_, args) => OnBindText(args, (ud) => ud.Id.ToString()!);
var idColumn = ColumnViewColumn.New("#", listItemFactory);
// idColumn.SetSorter(ColumnSorter);
ColumnView!.AppendColumn(idColumn);
// Internal Name Column
listItemFactory = SignalListItemFactory.New();
listItemFactory.OnSetup += (_, args) => OnSetupLabel(args, Align.Start);
listItemFactory.OnBind += (_, args) => OnBindText(args, (ud) => ud.InternalName!);
var nameColumn = ColumnViewColumn.New("Internal Name", listItemFactory);
// nameColumn.SetSorter(ColumnSorter);
ColumnView.AppendColumn(nameColumn);
ColumnViewColumn offsetColumn = null!;
ColumnViewColumn plistColumn = null!;
if (IsSongTable)
{
// Playlist Name Column
listItemFactory = SignalListItemFactory.New();
listItemFactory.OnSetup += (_, args) => OnSetupLabel(args, Align.Start);
listItemFactory.OnBind += (_, args) => OnBindText(args, (ud) => ud.PlaylistName!);
plistColumn = ColumnViewColumn.New("Playlist Name", listItemFactory);
// plistColumn.SetSorter(ColumnSorter);
ColumnView.AppendColumn(plistColumn);
// Offset Column
listItemFactory = SignalListItemFactory.New();
listItemFactory.OnSetup += (_, args) => OnSetupLabel(args, Align.Start);
listItemFactory.OnBind += (_, args) => OnBindText(args, (ud) => ud.Offset!);
offsetColumn = ColumnViewColumn.New(nameof(Offset), listItemFactory);
// offsetColumn.SetSorter(ColumnSorter);
ColumnView.AppendColumn(offsetColumn);
}
else
{
if (plistColumn is not null)
{
ColumnView.RemoveColumn(plistColumn);
}
if (offsetColumn is not null)
{
ColumnView.RemoveColumn(offsetColumn);
}
}
}
private void OnSetupLabel(SetupSignalArgs args, Align align)
{
if (args.Object is not ListItem listItem)
{
return;
}
var label = Label.New(null);
label.Halign = align;
listItem.Child = label;
}
private void OnBindText(BindSignalArgs args, Func<SoundSequenceList, string> getText)
{
if (args.Object is not ListItem listItem)
{
return;
}
if (listItem.Child is not Label label) return;
if (listItem.Item is not SoundSequenceList userData) return;
label.SetText(getText(userData));
}
}Any help would be greatly appreciated! |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 7 replies
-
|
I did not check your code but while reading the docs I stumbled upon the ColumnViewSorter. It reads from the docs like this could help you sorting a column? |
Beta Was this translation helpful? Give feedback.
Please see this issue.
There are links to a third party repository and a possible solution via a
CustomSorter.