DVUI

gridHeadingSortable

Create a heading and allow the column to be sorted.

Returns true if the sort direction has changed. sort_dir is an out parameter containing the current sort direction.

Parameters

#
src:std.builtin.SourceLocation
std.builtin.SourceLocation
g:*GridWidget
*GridWidget
col_num:usize
usize
heading:[]const u8
[]const u8
dir:*GridWidget.SortDirection
*GridWidget.SortDirection
resize_opts:?GridWidget.HeaderResizeWidget.InitOptions
?GridWidget.HeaderResizeWidget.InitOptions
cell_style:anytype
anytype

Source

Implementation

#
pub fn gridHeadingSortable(
    src: std.builtin.SourceLocation,
    g: *GridWidget,
    col_num: usize,
    heading: []const u8,
    dir: *GridWidget.SortDirection,
    resize_opts: ?GridWidget.HeaderResizeWidget.InitOptions,
    cell_style: anytype, // GridWidget.CellStyle
) bool {
    const icon_ascending = dvui.entypo.chevron_small_up;
    const icon_descending = dvui.entypo.chevron_small_down;

    // Pad buttons with extra space if there is no sort indicator.
    const heading_defaults: Options = .{
        .expand = .horizontal,
        .corners = .square,
    };
    const opts = if (@TypeOf(cell_style) == @TypeOf(.{})) GridWidget.CellStyle.none else cell_style;
    var heading_opts = heading_defaults.override(opts.options(.col(col_num)));
    const label_wd: *WidgetData = wd: {
        if (heading_opts.data_out) |data_out| break :wd data_out;

        var internal_wd: WidgetData = undefined;
        heading_opts.data_out = &internal_wd;
        break :wd &internal_wd;
    };

    var cell = g.headerCell(src, col_num, opts.cellOptions(.col(col_num)));
    defer cell.deinit();

    gridHeadingSeparator(resize_opts);

    const sort_changed = switch (g.colSortOrder(col_num)) {
        // Use same src for each button so they get the same id and can retain focus accross frames.
        .unsorted => button(src, heading, .{}, heading_opts),
        .ascending => buttonLabelAndIcon(src, .{ .label = heading, .icon_label = "sorted ascending", .tvg_bytes = icon_ascending, .button_opts = .{} }, heading_opts),
        .descending => buttonLabelAndIcon(src, .{ .label = heading, .icon_label = "sorted descending", .tvg_bytes = icon_descending, .button_opts = .{} }, heading_opts),
    };

    if (sort_changed) {
        g.sortChanged(col_num);
    }
    dir.* = g.sort_direction;

    if (label_wd.accesskit_node()) |ak_node| {
        switch (dir.*) {
            .ascending => AccessKit.nodeSetSortDirection(ak_node, AccessKit.SortDirection.ascending),
            .descending => AccessKit.nodeSetSortDirection(ak_node, AccessKit.SortDirection.descending),
            .unsorted => {},
        }
    }

    return sort_changed;
}