Skip to content

Commit db5ca73

Browse files
committed
feat: enhance tap handling and selection management in YourRoomPage
1 parent c6ba4b9 commit db5ca73

File tree

2 files changed

+42
-25
lines changed

2 files changed

+42
-25
lines changed

assets/your_room/weather-rain.png

-492 Bytes
Loading

lib/src/features/home/presentation/your_room/your_room_page.dart

Lines changed: 42 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -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

380412
Size _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

Comments
 (0)