DVUI

bodyCell

Create a body cell for the requested column and row Returns a hbox for the created cell.

  • deinit() must be called on this hbox before any new body cells are created.

If row_height_variable is false:

  • body cells can be created using any order of col_num and row_num if row_height_variable is true then either:

  • All rows for a column must be created in ascending row order.

  • All columns for a row must be created before creating moving to the next row.

  • Widths If col_widths is passed to cols during init, then size.w is ignored. If a different size.w is specified for any cells in the same column, the max size.w is used for that column.

  • Heights If row_height_variable is true, size.h is always used as the row height, otherwise the height for all body cells in the grid is set to the max size.h

Parameters

#
self:*GridWidget
*GridWidget
src:std.builtin.SourceLocation
std.builtin.SourceLocation
cell:Cell
Cell
opts:CellOptions
CellOptions

Source

Implementation

#
pub fn bodyCell(self: *GridWidget, src: std.builtin.SourceLocation, cell: Cell, opts: CellOptions) *BoxWidget {
    if (cell.row_num < self.cur_row) {
        self.this_row_y = self.rows_y_offset;
        self.next_row_y = self.rows_y_offset;
        self.cur_row = cell.row_num;
    } else if (cell.row_num > self.cur_row) {
        self.this_row_y = self.next_row_y;
        self.cur_row = cell.row_num;
    }
    self.max_row = @max(self.max_row, cell.row_num);
    if (self.bscroll == null) {
        self.bodyScrollContainerCreate();
    }
    const cell_width = width: {
        if (opts.width() > 0) {
            break :width opts.width();
        } else {
            break :width self.colWidth(cell.col_num);
        }
    };
    const cell_height: f32 = height: {
        if (opts.height() > 0) {
            // If the user specifies a height, use that if it is bigger than the current height.
            // If using row_height_variable or resizing then always use the height the user supplied.
            break :height if (self.resizing or self.init_opts.row_height_variable) opts.height() else @max(opts.height(), self.row_height);
        } else {
            break :height if (self.resizing) 0 else self.row_height;
        }
    };

    const row_num_f: f32 = @floatFromInt(cell.row_num);
    const pos_x = self.posX(cell.col_num);
    const pos_y = if (self.init_opts.row_height_variable) self.this_row_y else self.row_height * row_num_f;
    var cell_opts = opts.toOptions();
    cell_opts.rect = .{ .x = pos_x, .y = pos_y, .w = cell_width, .h = cell_height };

    // To support being called in a loop, combine col and row numbers as id_extra.
    // 9_223_372_036_854_775K cols should be enough for anybody.
    cell_opts.id_extra = (cell.col_num << @bitSizeOf(usize) / 2) | cell.row_num;

    defer dvui.currentWindow().accesskit.grid_cell_row = .zero;
    if (dvui.accesskit_enabled) {
        // If this is a new row, then create an accessible row node to parent all the cells
        // grid_cell_row must be set before the cell's box widget is created.
        if (self.rows.get(cell.row_num)) |row_id| {
            dvui.currentWindow().accesskit.grid_cell_row = row_id;
        } else {
            var vp = dvui.overlay(@src(), .{ .role = .row, .name = "GridWidgetRow", .id_extra = cell.row_num, .rect = cell_opts.rect.? });
            defer vp.deinit();
            if (vp.data().accesskit_node()) |_| {
                self.rows.put(dvui.currentWindow().arena(), cell.row_num, vp.data().id) catch {};
                dvui.currentWindow().accesskit.grid_cell_row = vp.data().id;
            } else {
                self.rows.put(dvui.currentWindow().arena(), cell.row_num, .zero) catch {};
                dvui.currentWindow().accesskit.grid_cell_row = .zero;
            }
        }
    }

    var cell_box = dvui.box(src, .{ .dir = .horizontal }, cell_opts);
    const first_frame = dvui.firstFrame(cell_box.data().id);
    // Determine heights for next frame.
    if (!first_frame) {
        const cell_size = cell_box.data().rect.size();
        self.row_height = @max(self.row_height, cell_size.h);
        self.colWidthSet(cell.col_num, cell_size.w);
    }
    self.next_row_y = @max(self.next_row_y, self.this_row_y + if (opts.height() > 0) opts.height() else self.row_height);

    if (cell_box.data().accesskit_node()) |ak_node| {
        AccessKit.nodeSetRowIndex(ak_node, cell.row_num);
        AccessKit.nodeSetColumnIndex(ak_node, cell.col_num);
    }

    return cell_box;
}