How to call setState using class instance

34 views Asked by At

I am working on a shape management application. I need to add the selection box for selected shape if there is any shape selected while selecting another shape the previous selected shape needs to be deselected. I am storing the Shape class instance in a global variable Shape? selectedShape; how to call this setState() using the stored instance.

class Layer {
  final LayerListData layerDetails;
  final List<ShapeData> shapes;
  Layer({required this.layerDetails, required this.shapes});
}

class LayerStack extends StatelessWidget {
  final List<Layer> layers;
  final int selectedLayerIndex;
  final Function(int) onLayerTap;

  const LayerStack({
    Key? key,
    required this.layers,
    required this.selectedLayerIndex,
    required this.onLayerTap,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        for (int i = 0; i < layers.length; i++)
          LayerWidget(
            layer: layers[i],
          ),
      ],
    );
  }
}

class LayerWidget extends StatefulWidget {
  final Layer layer;

  const LayerWidget({
    Key? key,
    required this.layer,
  }) : super(key: key);

  @override
  State<LayerWidget> createState() => _LayerWidgetState();
}

class _LayerWidgetState extends State<LayerWidget> {
  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        for (final shapeData in widget.layer.shapes)
          Shape(
            shapeData: shapeData,
            isSelected: true,
            onTap: (value) {},
          ),
      ],
    );
  }
} 

class ShapeData {
  ShapeListData shapeData;
  ShapeTextData shapeTextData;
  ShapeArrangeData shapeArrangeData;
  ShapeStyleData shapeStyleData;

  ShapeData(
      {required this.shapeData,
      required this.shapeStyleData,
      required this.shapeTextData,
      required this.shapeArrangeData});
}

class Shape extends StatefulWidget {
  final ShapeData shapeData;
  bool isSelected;
  final Function(bool) onTap;
  final VoidCallback? updateStateCallback;

  Shape(
      {Key? key,
      required this.shapeData,
      this.isSelected = false,
      required this.onTap,
      this.updateStateCallback})
      : super(key: key);

  @override
  State<Shape> createState() => _ShapeState();
}

class _ShapeState extends State<Shape> {
  @override
  void initState() {
    super.initState();
    widget.isSelected = false;
  }

  @override
  void dispose() {
    super.dispose();
    widget.isSelected = false;
  }

  @override
  Widget build(BuildContext context) {
    return Positioned(
      left:
          double.tryParse(widget.shapeData.shapeArrangeData.positionX ?? '0.0'),
      top:
          double.tryParse(widget.shapeData.shapeArrangeData.positionY ?? '0.0'),
      child: GestureDetector(
        onTap: () {
          setState(() {
            // Deselect the previously selected shape
            if (selectedShape != null && selectedShape != widget) {
              selectedShape!.isSelected = false;
              selectedShape!.updateStateCallback?.call();
            }
            // Select the newly tapped shape
            selectedShape = widget;
            widget.isSelected = true;
            widget.updateStateCallback?.call();
          });
        },
        child: Stack(
          children: [
            // CustomPaint for drawing the shape
            CustomPaint(
              painter: ShapeCustomPainter(shapeData: widget.shapeData),
              size: const Size(45, 50),
            ),
            // selection indicator if the shape is selected
            if (widget.isSelected)
              Container(
                width: 50,
                height: 50,
                decoration: BoxDecoration(
                  border: Border.all(color: Colors.blue, width: 2.0),
                ),
              ),
          ],
        ),
      ),
    );
  }
}

class ShapeCustomPainter extends CustomPainter {
  ShapeData shapeData;

  ShapeCustomPainter({required this.shapeData});

  @override
  void paint(Canvas canvas, Size size) {
    final Paint fillPaint = Paint()
      ..color = Color(int.parse(
          shapeData.shapeStyleData.lineColor?.replaceFirst('#', '0xFF') ??
              '0xFF000000'))
      ..strokeWidth = (shapeData.shapeStyleData.strokeSize)?.toDouble() ?? 1.0
      ..style = PaintingStyle.stroke;

    final Paint strokePaint = Paint()
      ..color = Color(int.parse(
          shapeData.shapeStyleData.lineColor?.replaceFirst('#', '0xFF') ??
              '0xFFFFFFFF'))
      ..style = PaintingStyle.fill;

    final Path shapePath =
        ShapePathGenerator(shapeString: shapeData.shapeData.shapeString ?? '')
            .getPath();

    canvas.drawPath(shapePath, fillPaint);
    canvas.drawPath(shapePath, strokePaint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true;
  }
} ```
0

There are 0 answers