Major Change Inputs & Co
This commit is contained in:
@@ -1,18 +1,32 @@
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:latlong2/latlong.dart';
|
||||
import 'package:flutter_map/flutter_map.dart';
|
||||
import 'package:oc_front/core/services/specialized_services/datacenter_service.dart';
|
||||
import 'package:oc_front/main.dart';
|
||||
import 'package:oc_front/models/resources/compute.dart';
|
||||
import 'package:oc_front/models/resources/resources.dart';
|
||||
import 'package:oc_front/models/resources/storage.dart';
|
||||
import 'package:oc_front/pages/abstract_page.dart';
|
||||
import 'package:oc_front/widgets/items/item_row.dart';
|
||||
|
||||
|
||||
class MapFactory implements AbstractFactory {
|
||||
@override GlobalKey getKey() { return key; }
|
||||
@override String? getSearch() { return ""; }
|
||||
@override void back(BuildContext context) { }
|
||||
static GlobalKey<MapPageWidgetState> key = GlobalKey<MapPageWidgetState>();
|
||||
@override bool searchFill() { return false; }
|
||||
@override Widget factory(GoRouterState state, List<String> args) { return MapPageWidget(); }
|
||||
@override void search(BuildContext context, bool special) { }
|
||||
}
|
||||
|
||||
double menuSize = 0;
|
||||
class MapPageWidget extends StatefulWidget {
|
||||
bool isShowed = false;
|
||||
final DatacenterService _service = DatacenterService();
|
||||
MapPageWidget(): super(key: MapFactory.key);
|
||||
@override MapPageWidgetState createState() => MapPageWidgetState();
|
||||
static void search(BuildContext context) { }
|
||||
@@ -22,26 +36,193 @@ class MapPageWidgetState extends State<MapPageWidget> {
|
||||
double currentZoom = 2.0;
|
||||
LatLng currentCenter = const LatLng(51.5, -0.09);
|
||||
static final MapController _mapController = MapController();
|
||||
void _zoom() {
|
||||
currentZoom = currentZoom - 1;
|
||||
_mapController.move(currentCenter, currentZoom);
|
||||
}
|
||||
bool selected = true;
|
||||
|
||||
@override Widget build(BuildContext context) {
|
||||
return Expanded(
|
||||
child : FlutterMap(
|
||||
mapController: _mapController,
|
||||
options: MapOptions(
|
||||
initialCenter: currentCenter,
|
||||
initialZoom: currentZoom,
|
||||
return FutureBuilder(future: widget._service.all(context), builder: (BuildContext context, AsyncSnapshot snapshot) {
|
||||
Map<String, Map<AbstractItem, LatLng>> coordinates = {};
|
||||
List<Marker> markerCoordinates = [];
|
||||
if (snapshot.data != null&& snapshot.data!.data != null && snapshot.data!.data!.values.isNotEmpty) {
|
||||
for (var element in snapshot.data!.data!.values) {
|
||||
if (element["type"] == "storage") {
|
||||
StorageItem resource = StorageItem().deserialize(element);
|
||||
var instance = resource.getSelectedInstance();
|
||||
if (instance == null || instance.location == null) { continue; }
|
||||
if (coordinates[resource.topic] == null) { coordinates[resource.topic] = {}; }
|
||||
coordinates[resource.topic]![resource] = LatLng(instance.location!.latitude ?? 0, instance.location!.longitude ?? 0);
|
||||
} else if (element["type"] == "compute") {
|
||||
ComputeItem resource = ComputeItem().deserialize(element);
|
||||
var instance = resource.getSelectedInstance();
|
||||
if (instance == null || instance.location == null) { continue; }
|
||||
if (coordinates[resource.topic] == null) { coordinates[resource.topic] = {}; }
|
||||
var lr = Random().nextInt(max(1, 100)) / 10000;
|
||||
var lfr = Random().nextInt(max(1, 100)) / 10000;
|
||||
coordinates[resource.topic]![resource] = LatLng((instance.location!.latitude ?? 0) + lr, (instance.location!.longitude ?? 0) + lfr);
|
||||
}
|
||||
}
|
||||
for (var topic in coordinates.keys) {
|
||||
for (var coord in coordinates[topic]!.keys) {
|
||||
markerCoordinates.add(Marker(
|
||||
width: 25,
|
||||
height: 30,
|
||||
point: coordinates[topic]![coord]!,
|
||||
child: HoverMenu( width: 110, title: Container( alignment: Alignment.center,
|
||||
constraints: BoxConstraints( maxHeight: 100, maxWidth: 100 ),
|
||||
child: Icon(FontAwesomeIcons.locationDot,
|
||||
shadows: <Shadow>[Shadow(color: Color.fromRGBO(0, 0, 0, 1), blurRadius: 10.0)],
|
||||
color: getColor(topic)) ),
|
||||
items: [ Container(color: Colors.white,
|
||||
child: ItemRowWidget(low: true, contextWidth: 290, item: coord)) ]
|
||||
),
|
||||
));
|
||||
}
|
||||
}
|
||||
Rect rect = Rect.fromCenter( center: MediaQuery.of(context).size.center(Offset.zero),
|
||||
width: selected ? menuSize : 0, height: (getMainHeight(context) - 50) > 0 ? (getMainHeight(context) - 50) : 0);
|
||||
return Expanded(
|
||||
child : FlutterMap(
|
||||
mapController: _mapController,
|
||||
options: MapOptions(
|
||||
initialCenter: currentCenter,
|
||||
initialZoom: currentZoom,
|
||||
),
|
||||
children: [
|
||||
TileLayer(
|
||||
urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
|
||||
userAgentPackageName: 'dev.fleaflet.flutter_map.example',
|
||||
),
|
||||
MarkerLayer(
|
||||
markers: markerCoordinates,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return const CircularProgressIndicator();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class HoverMenuController {
|
||||
HoverMenuState? currentState;
|
||||
|
||||
void hideSubMenu() {
|
||||
currentState?.hideSubMenu();
|
||||
}
|
||||
}
|
||||
|
||||
class HoverMenu extends StatefulWidget {
|
||||
final Widget title;
|
||||
final double? width;
|
||||
final List<Widget> items;
|
||||
final HoverMenuController? controller;
|
||||
bool isHovered = false;
|
||||
|
||||
|
||||
HoverMenu({
|
||||
Key? key,
|
||||
required this.title,
|
||||
this.items = const [],
|
||||
this.width,
|
||||
this.controller,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
HoverMenuState createState() => HoverMenuState();
|
||||
}
|
||||
|
||||
class HoverMenuState extends State<HoverMenu> {
|
||||
OverlayEntry? _overlayEntry;
|
||||
final _focusNode = FocusNode();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_focusNode.addListener(_onFocusChanged);
|
||||
|
||||
if (widget.controller != null) {
|
||||
widget.controller?.currentState = this;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_focusNode.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _onFocusChanged() {
|
||||
if (_focusNode.hasFocus) {
|
||||
_overlayEntry = _createOverlayEntry();
|
||||
Overlay.of(context).insert(_overlayEntry!);
|
||||
} else {
|
||||
_overlayEntry?.remove();
|
||||
_removeOverlay();
|
||||
}
|
||||
}
|
||||
|
||||
void _removeOverlay() {
|
||||
widget.isHovered = false;
|
||||
}
|
||||
|
||||
void hideSubMenu() {
|
||||
_focusNode.unfocus();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return TextButton(
|
||||
style: TextButton.styleFrom(
|
||||
elevation: 0.0,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(0)),
|
||||
splashFactory: NoSplash.splashFactory,
|
||||
padding: EdgeInsets.zero,
|
||||
foregroundColor: Colors.transparent,
|
||||
surfaceTintColor: Colors.transparent,
|
||||
backgroundColor: Colors.transparent,
|
||||
shadowColor: Colors.transparent,
|
||||
),
|
||||
children: [
|
||||
TileLayer(
|
||||
urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
|
||||
userAgentPackageName: 'dev.fleaflet.flutter_map.example',
|
||||
)
|
||||
],
|
||||
)
|
||||
focusNode: _focusNode,
|
||||
onHover: (isHovered) {
|
||||
if (isHovered && !widget.isHovered) {
|
||||
_focusNode.requestFocus();
|
||||
isHovered = true;
|
||||
} else {
|
||||
_focusNode.unfocus();
|
||||
widget.isHovered = false;
|
||||
}
|
||||
},
|
||||
onPressed: () {},
|
||||
child: widget.title,
|
||||
);
|
||||
}
|
||||
|
||||
OverlayEntry _createOverlayEntry() {
|
||||
final renderBox = context.findRenderObject() as RenderBox;
|
||||
final size = renderBox.size;
|
||||
final offset = renderBox.localToGlobal(Offset.zero);
|
||||
|
||||
return OverlayEntry(
|
||||
maintainState: true,
|
||||
builder: (context) => Positioned(
|
||||
left: offset.dx - 300,
|
||||
top: offset.dy + size.height,
|
||||
width: 300,
|
||||
child: TextButton(
|
||||
style: TextButton.styleFrom(
|
||||
padding: EdgeInsets.zero,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(0)),
|
||||
splashFactory: NoSplash.splashFactory,
|
||||
backgroundColor: Colors.transparent,
|
||||
),
|
||||
onPressed: () {},
|
||||
child: ListView(
|
||||
padding: EdgeInsets.zero,
|
||||
shrinkWrap: true,
|
||||
children: widget.items)),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user