selective_gesture_wrapper 0.0.2 copy "selective_gesture_wrapper: ^0.0.2" to clipboard
selective_gesture_wrapper: ^0.0.2 copied to clipboard

A lightweight widget that selectively absorbs or passes gestures to its child.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:selective_gesture_wrapper/selective_gesture_wrapper.dart';

void main() => runApp(const MaterialApp(home: EditorPage()));

class EditorPage extends StatefulWidget {
  const EditorPage({super.key});

  @override
  State<EditorPage> createState() => _EditorPageState();
}

class _EditorPageState extends State<EditorPage> {
  int? selectedId;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: List.generate(3, (index) {
          return SelectableDraggableWidget(
            key: ValueKey(index),
            id: index,
            isSelected: selectedId == index,
            onSelect: () => setState(() => selectedId = index),
            child: Container(
              width: 100,
              height: 100,
              color: Colors.primaries[index],
              child: Center(child: Text('Box $index')),
            ),
          );
        }),
      ),
    );
  }
}

class SelectableDraggableWidget extends StatefulWidget {
  final Widget child;
  final bool isSelected;
  final VoidCallback onSelect;
  final int id;

  const SelectableDraggableWidget({
    super.key,
    required this.child,
    required this.isSelected,
    required this.onSelect,
    required this.id,
  });

  @override
  State<SelectableDraggableWidget> createState() =>
      _SelectableDraggableWidgetState();
}

class _SelectableDraggableWidgetState extends State<SelectableDraggableWidget> {
  Offset position = const Offset(50, 50);
  double scale = 1.0;

  @override
  Widget build(BuildContext context) {
    // We wrap with Positioned to control position on screen
    return Positioned(
      left: position.dx,
      top: position.dy,
      child: Stack(
        children: [
          // This GestureDetector is for selection tap, covers the entire widget area including scale
          GestureDetector(
            behavior: HitTestBehavior.translucent,
            onTap: widget.onSelect,
            child: SizedBox(
              width: 100 * scale,
              height: 100 * scale,
            ),
          ),
          // This wrapper controls whether gestures inside are absorbed or passed
          SelectiveGestureWrapper(
            absorbGestures: !widget.isSelected, // absorb gestures when NOT selected
            child: GestureDetector(
              onScaleStart: widget.isSelected ? (_) {} : null,
              onScaleUpdate: widget.isSelected
                  ? (details) {
                setState(() {
                  scale = details.scale.clamp(0.5, 3.0);
                  position += details.focalPointDelta;
                });
              }
                  : null,
              child: Transform.scale(
                scale: scale,
                alignment: Alignment.topLeft,
                child: Container(
                  decoration: BoxDecoration(
                    border: widget.isSelected
                        ? Border.all(color: Colors.blue, width: 3)
                        : null,
                  ),
                  child: widget.child,
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}
0
likes
160
points
10
downloads

Publisher

verified publishersourabhsharma.work

Weekly Downloads

A lightweight widget that selectively absorbs or passes gestures to its child.

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

flutter

More

Packages that depend on selective_gesture_wrapper