@@ -172,18 +172,33 @@ class _YourRoomPageState extends ConsumerState<YourRoomPage> {
172172 : 0.0 ;
173173 final roomOrigin = Offset (originX, originY);
174174
175- return GestureDetector (
175+ return Listener (
176176 behavior: HitTestBehavior .translucent,
177- onTapDown : (details ) {
178- final position = details .localPosition;
177+ onPointerDown : (event ) {
178+ final position = event .localPosition;
179179 final insideRoom = position.dx >= roomOrigin.dx &&
180180 position.dy >= roomOrigin.dy &&
181181 position.dx <= roomOrigin.dx + roomSize.width &&
182182 position.dy <= roomOrigin.dy + roomSize.height;
183183
184- if (insideRoom) {
185- _handleTap (position - roomOrigin);
186- } else {
184+ if (! insideRoom) {
185+ _clearSelection ();
186+ return ;
187+ }
188+
189+ final roomLocal = position - roomOrigin;
190+ final handled = _handleTap (roomLocal);
191+
192+ if (! handled) {
193+ final selected = _selectedItemId;
194+ if (selected != null ) {
195+ final selectionRect = _selectionRectFor (selected);
196+ if (selectionRect != null &&
197+ selectionRect.contains (roomLocal)) {
198+ return ;
199+ }
200+ }
201+
187202 _clearSelection ();
188203 }
189204 },
@@ -347,7 +362,7 @@ class _YourRoomPageState extends ConsumerState<YourRoomPage> {
347362 return widgets;
348363 }
349364
350- void _handleTap (Offset localPosition) {
365+ bool _handleTap (Offset localPosition) {
351366 for (final id in _hitOrder.reversed) {
352367 final rect = _currentHitRects[id];
353368 if (rect == null || ! rect.contains (localPosition)) continue ;
@@ -365,16 +380,33 @@ class _YourRoomPageState extends ConsumerState<YourRoomPage> {
365380 if (_selectedItemId != id) {
366381 setState (() => _selectedItemId = id);
367382 }
368- return ;
383+ return true ;
369384 }
370385
371- _clearSelection () ;
386+ return false ;
372387 }
373388
374389 void _clearSelection () {
375390 if (_selectedItemId == null ) return ;
376391 setState (() => _selectedItemId = null );
377392 }
393+
394+ Rect ? _selectionRectFor (String id) {
395+ final layout = _currentLayouts[id];
396+ if (layout == null ) return null ;
397+
398+ final bounds = _contentBounds[id];
399+ final resolved = (bounds != null && bounds.width > 0 && bounds.height > 0 )
400+ ? bounds
401+ : Rect .fromLTWH (0 , 0 , layout.size.width, layout.size.height);
402+
403+ return Rect .fromLTWH (
404+ layout.topLeft.dx + resolved.left - _SelectionFrame .padding.left,
405+ layout.topLeft.dy + resolved.top - _SelectionFrame .padding.top,
406+ resolved.width + _SelectionFrame .padding.horizontal,
407+ resolved.height + _SelectionFrame .padding.vertical,
408+ );
409+ }
378410}
379411
380412Size _resolveRoomSize (BoxConstraints constraints, Size fallbackSize) {
@@ -1109,22 +1141,7 @@ class _InteractiveRoomAssetState extends State<_InteractiveRoomAsset> {
11091141
11101142 final bounds = _lastContentBounds;
11111143 if (bounds != null ) {
1112- final expanded = Rect .fromLTRB (
1113- (bounds.left - _SelectionFrame .padding.left)
1114- .clamp (0.0 , widget.layout.size.width),
1115- (bounds.top - _SelectionFrame .padding.top)
1116- .clamp (0.0 , widget.layout.size.height),
1117- (bounds.right + _SelectionFrame .padding.right)
1118- .clamp (0.0 , widget.layout.size.width),
1119- (bounds.bottom + _SelectionFrame .padding.bottom)
1120- .clamp (0.0 , widget.layout.size.height),
1121- );
1122-
1123- if (expanded.contains (localPosition)) {
1124- return true ;
1125- }
1126-
1127- return false ;
1144+ return bounds.contains (localPosition);
11281145 }
11291146
11301147 return _isOpaqueHit (localPosition);
0 commit comments