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;
}