create method

  1. @override
Widget create(
  1. GridWidgetData data,
  2. Environment environment,
  3. BuildContext context
)
override

create the widget given a WidgetData type data the widget data environment the current Environment context the BuildContext

Implementation

@override
Widget create(GridWidgetData data, Environment environment, BuildContext context) {
  final spacing = data.spacing.toDouble();

  if (data.cols.isEmpty || data.rows.isEmpty) {
    return const Center(
      child: Text(
        'Grid has no rows or columns',
        style: TextStyle(color: Colors.grey),
      ),
    );
  }

  final columnWidths = <int, TableColumnWidth>{
    for (var i = 0; i < data.cols.length; i++)
      i: switch (data.cols[i].sizeMode) {
        GridSizeMode.fixed => FixedColumnWidth(data.cols[i].size),
        GridSizeMode.flex => FlexColumnWidth(data.cols[i].size),
        GridSizeMode.auto => const IntrinsicColumnWidth(),
      }
  };

  Widget _buildDropArea(int rowIndex, int colIndex) {
    return DragTarget<WidgetData>(
      onWillAccept: (widget) => data.acceptsChild(widget!),
      onAccept: (widget) {
        environment.get<CommandStack>().execute(
          ReparentCommand(
            bus: environment.get<MessageBus>(),
            widget: widget,
            newParent: data,
            newCell: Cell(row: rowIndex, col: colIndex),
          ),
        );
      },
      builder: (context, candidateData, rejectedData) {
        final isActive = candidateData.isNotEmpty;
        return Container(
          constraints: const BoxConstraints(minHeight: 60, minWidth: 60),
          decoration: BoxDecoration(
            border: Border.all(
              color: isActive ? Colors.blue : Colors.grey,
              width: 1,
              style: BorderStyle.solid,
            ),
            borderRadius: BorderRadius.circular(4),
          ),
          child: Center(
            child: Text(
              isActive ? "Drop here" : "Empty",
              style: TextStyle(
                fontSize: 12,
                color: isActive ? Colors.blue : Colors.grey,
                fontStyle: FontStyle.italic,
              ),
            ),
          ),
        );
      },
    );
  }

  // REMOVED _alignedCellContent to use TableCell properties instead
  // The old logic was redundant/incorrect for a Table structure.

  return Table(
    // Default vertical alignment for the table is fine, but it can be overridden per cell
    defaultVerticalAlignment: TableCellVerticalAlignment.middle,
    columnWidths: columnWidths,
    defaultColumnWidth: const FlexColumnWidth(1.0),
    children: List.generate(data.rows.length, (rowIndex) {
      final row = data.rows[rowIndex];
      return TableRow(
        children: List.generate(data.cols.length, (colIndex) {
          final col = data.cols[colIndex];
          final childModel = findElement(
            data.children,
                (w) => w.cell?.row == rowIndex && w.cell?.col == colIndex,
          );

          Widget content = childModel != null
              ? EditWidget(model: childModel)
              : _buildDropArea(rowIndex, colIndex);

          // 1. HORIZONTAL ALIGNMENT: Wrap the content in Align/Container
          //    to handle start/center/end/stretch horizontally.
          //    Note: Horizontal stretch is often handled by FlexColumnWidths.
          if (col.alignment != GridAlignment.stretch) {
            content = Align(
              alignment: _mapGridAlignmentToFlutterAlignment(col.alignment, GridAlignment.center),
              child: content,
            );
          }


          // 2. WRAP IN PADDING: Apply the spacing/padding
          content = Padding(
            padding: EdgeInsets.all(spacing / 2),
            child: content,
          );

          // 3. VERTICAL ALIGNMENT: MUST wrap in TableCell to communicate
          //    vertical alignment preference to the Table widget's layout.
          return TableCell(
            verticalAlignment: _mapGridAlignmentToVertical(row.alignment),
            child: content,
          );
        }),
      );
    }),
  );
}