Moving the right direction I think

This commit is contained in:
stopflock
2025-10-02 17:23:17 -05:00
parent 408b52cdb0
commit 763fa31266
5 changed files with 106 additions and 57 deletions

View File

@@ -356,6 +356,7 @@ class _HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin {
sheetHeight: activeSheetHeight,
selectedNodeId: _selectedNodeId,
onNodeTap: openNodeTagSheet,
onSearchPressed: _onNavigationButtonPressed,
onUserGesture: () {
if (appState.followMeMode != FollowMeMode.off) {
appState.setFollowMeMode(FollowMeMode.off);
@@ -438,16 +439,6 @@ class _HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin {
),
),
),
// Search button as floating map control
Positioned(
bottom: 200, // Position above other controls
right: 16,
child: FloatingActionButton(
onPressed: _onNavigationButtonPressed,
tooltip: appState.hasActiveRoute ? 'Route Overview' : 'Search Location',
child: Icon(appState.hasActiveRoute ? Icons.route : Icons.search),
),
),
],
),
),

View File

@@ -109,7 +109,17 @@ class NavigationState extends ChangeNotifier {
_provisionalPinLocation = null;
_provisionalPinAddress = null;
_clearSearchResults();
debugPrint('[NavigationState] Cancelled search mode');
// Also clear any partial route data
if (_routeStart != null && _routeEnd == null) {
_routeStart = null;
_routeStartAddress = null;
} else if (_routeEnd != null && _routeStart == null) {
_routeEnd = null;
_routeEndAddress = null;
}
debugPrint('[NavigationState] Cancelled search mode - cleaned up provisional pin');
notifyListeners();
}
@@ -137,15 +147,32 @@ class NavigationState extends ChangeNotifier {
/// Start route setup (user clicked "route to" or "route from")
void startRouteSetup({required bool settingStart}) {
if (_mode != AppNavigationMode.search || _provisionalPinLocation == null) return;
debugPrint('[NavigationState] startRouteSetup called - settingStart: $settingStart, mode: $_mode, location: $_provisionalPinLocation');
if (_mode != AppNavigationMode.search || _provisionalPinLocation == null) {
debugPrint('[NavigationState] startRouteSetup - early return');
return;
}
// Clear any previous route data
_routeStart = null;
_routeEnd = null;
_routeStartAddress = null;
_routeEndAddress = null;
_routePath = null;
_routeDistance = null;
_settingRouteStart = settingStart;
if (settingStart) {
// "Route From" - this location is the START, we need to pick END
_routeStart = _provisionalPinLocation;
_routeStartAddress = _provisionalPinAddress;
debugPrint('[NavigationState] Set route start: $_routeStart');
} else {
// "Route To" - this location is the END, we need to pick START
_routeEnd = _provisionalPinLocation;
_routeEndAddress = _provisionalPinAddress;
debugPrint('[NavigationState] Set route end: $_routeEnd');
}
_mode = AppNavigationMode.routeSetup;
@@ -156,16 +183,25 @@ class NavigationState extends ChangeNotifier {
/// Lock in second route location
void selectRouteLocation() {
if (_mode != AppNavigationMode.routeSetup || _provisionalPinLocation == null) return;
debugPrint('[NavigationState] selectRouteLocation called - mode: $_mode, provisional: $_provisionalPinLocation');
if (_mode != AppNavigationMode.routeSetup || _provisionalPinLocation == null) {
debugPrint('[NavigationState] selectRouteLocation - early return (mode: $_mode, location: $_provisionalPinLocation)');
return;
}
if (_settingRouteStart) {
_routeStart = _provisionalPinLocation;
_routeStartAddress = _provisionalPinAddress;
debugPrint('[NavigationState] Set route start: $_routeStart');
} else {
_routeEnd = _provisionalPinLocation;
_routeEndAddress = _provisionalPinAddress;
debugPrint('[NavigationState] Set route end: $_routeEnd');
}
debugPrint('[NavigationState] Route points - start: $_routeStart, end: $_routeEnd');
// Start route calculation
_calculateRoute();
}

View File

@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:provider/provider.dart';
import '../../app_state.dart';
import '../../dev_config.dart';
@@ -13,6 +14,7 @@ class MapOverlays extends StatelessWidget {
final AddNodeSession? session;
final EditNodeSession? editSession;
final String? attribution; // Attribution for current tile provider
final VoidCallback? onSearchPressed; // Callback for search button
const MapOverlays({
super.key,
@@ -21,6 +23,7 @@ class MapOverlays extends StatelessWidget {
this.session,
this.editSession,
this.attribution,
this.onSearchPressed,
});
@override
@@ -113,45 +116,58 @@ class MapOverlays extends StatelessWidget {
Positioned(
bottom: bottomPositionFromButtonBar(kZoomControlsSpacingAboveButtonBar, MediaQuery.of(context).padding.bottom),
right: 16,
child: Column(
children: [
// Layer selector button
const LayerSelectorButton(),
const SizedBox(height: 8),
// Zoom in button
FloatingActionButton(
mini: true,
heroTag: "zoom_in",
onPressed: () {
try {
final zoom = mapController.camera.zoom;
mapController.move(mapController.camera.center, zoom + 1);
} catch (_) {
// Map controller not ready yet
}
},
child: const Icon(Icons.add),
),
const SizedBox(height: 8),
// Zoom out button
FloatingActionButton(
mini: true,
heroTag: "zoom_out",
onPressed: () {
try {
final zoom = mapController.camera.zoom;
mapController.move(mapController.camera.center, zoom - 1);
} catch (_) {
// Map controller not ready yet
}
},
child: const Icon(Icons.remove),
),
],
child: Consumer<AppState>(
builder: (context, appState, child) {
return Column(
children: [
// Search/Route button (top of controls)
if (onSearchPressed != null)
FloatingActionButton(
mini: true,
heroTag: "search_nav",
onPressed: onSearchPressed,
tooltip: appState.hasActiveRoute ? 'Route Overview' : 'Search Location',
child: Icon(appState.hasActiveRoute ? Icons.route : Icons.search),
),
if (onSearchPressed != null) const SizedBox(height: 8),
// Layer selector button
const LayerSelectorButton(),
const SizedBox(height: 8),
// Zoom in button
FloatingActionButton(
mini: true,
heroTag: "zoom_in",
onPressed: () {
try {
final zoom = mapController.camera.zoom;
mapController.move(mapController.camera.center, zoom + 1);
} catch (_) {
// Map controller not ready yet
}
},
child: const Icon(Icons.add),
),
const SizedBox(height: 8),
// Zoom out button
FloatingActionButton(
mini: true,
heroTag: "zoom_out",
onPressed: () {
try {
final zoom = mapController.camera.zoom;
mapController.move(mapController.camera.center, zoom - 1);
} catch (_) {
// Map controller not ready yet
}
},
child: const Icon(Icons.remove),
),
],
);
},
),
),
],
);
}

View File

@@ -38,6 +38,7 @@ class MapView extends StatefulWidget {
this.sheetHeight = 0.0,
this.selectedNodeId,
this.onNodeTap,
this.onSearchPressed,
});
final FollowMeMode followMeMode;
@@ -45,6 +46,7 @@ class MapView extends StatefulWidget {
final double sheetHeight;
final int? selectedNodeId;
final void Function(OsmNode)? onNodeTap;
final VoidCallback? onSearchPressed;
@override
State<MapView> createState() => MapViewState();
@@ -497,6 +499,7 @@ class MapViewState extends State<MapView> {
session: session,
editSession: editSession,
attribution: appState.selectedTileType?.attribution,
onSearchPressed: widget.onSearchPressed,
),
// Network status indicator (top-left) - conditionally shown

View File

@@ -180,22 +180,25 @@ class _LocationSearchBarState extends State<LocationSearchBar> {
focusNode: _focusNode,
decoration: InputDecoration(
hintText: 'Search places or coordinates...',
prefixIcon: const Icon(Icons.search),
suffixIcon: Row(
prefixIcon: Row(
mainAxisSize: MainAxisSize.min,
children: [
if (_controller.text.isNotEmpty)
IconButton(
icon: const Icon(Icons.clear),
onPressed: _onClear,
),
IconButton(
icon: const Icon(Icons.close),
onPressed: _onCancel,
tooltip: 'Cancel search',
),
const Icon(Icons.search),
],
),
prefixIconConstraints: const BoxConstraints(minWidth: 80),
suffixIcon: _controller.text.isNotEmpty
? IconButton(
icon: const Icon(Icons.clear),
onPressed: _onClear,
tooltip: 'Clear text',
)
: null,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide.none,