地图组件和ECS框架完成
This commit is contained in:
25
.vscode/launch.json
vendored
Normal file
25
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
// 使用 IntelliSense 了解相关属性。
|
||||||
|
// 悬停以查看现有属性的描述。
|
||||||
|
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "llm_chat",
|
||||||
|
"request": "launch",
|
||||||
|
"type": "dart"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "llm_chat (profile mode)",
|
||||||
|
"request": "launch",
|
||||||
|
"type": "dart",
|
||||||
|
"flutterMode": "profile"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "llm_chat (release mode)",
|
||||||
|
"request": "launch",
|
||||||
|
"type": "dart",
|
||||||
|
"flutterMode": "release"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"cmake.ignoreCMakeListsMissing": true
|
||||||
|
}
|
||||||
2066
assets/config/style - 副本.json
Normal file
2066
assets/config/style - 副本.json
Normal file
File diff suppressed because it is too large
Load Diff
2066
assets/config/style.json
Normal file
2066
assets/config/style.json
Normal file
File diff suppressed because it is too large
Load Diff
76
assets/osm_style.json
Normal file
76
assets/osm_style.json
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
{
|
||||||
|
"version": 8,
|
||||||
|
"projection": {
|
||||||
|
"type": "globe"
|
||||||
|
},
|
||||||
|
"name": "My Martin Map",
|
||||||
|
"sources": {
|
||||||
|
"worlddom_source": {
|
||||||
|
"type": "raster",
|
||||||
|
"tiles": [
|
||||||
|
"http://localhost:5656/dom_source/{z}/{x}/{y}"
|
||||||
|
],
|
||||||
|
"tileSize": 256,
|
||||||
|
"attribution": "Custom Satellite Data"
|
||||||
|
},
|
||||||
|
"hillshadeSource": {
|
||||||
|
"type": "raster-dem",
|
||||||
|
"url": "http://localhost:5656/dem_terrain/{z}/{x}/{y}",
|
||||||
|
"tileSize": 256
|
||||||
|
},
|
||||||
|
"elevation_source": {
|
||||||
|
"type": "raster-dem",
|
||||||
|
"tiles": [
|
||||||
|
"http://localhost:5656/dem_terrain/{z}/{x}/{y}"
|
||||||
|
],
|
||||||
|
"tileSize": 256,
|
||||||
|
"encoding": "terrarium"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"layers": [
|
||||||
|
{
|
||||||
|
"id": "hillshade_layer",
|
||||||
|
"type": "hillshade",
|
||||||
|
"source": "elevation_source",
|
||||||
|
"layout": {
|
||||||
|
"visibility": "visible"
|
||||||
|
},
|
||||||
|
"paint": {
|
||||||
|
"hillshade-shadow-color": "#473B24",
|
||||||
|
"hillshade-highlight-color": "#FFFFE0",
|
||||||
|
"hillshade-illumination-direction": 335,
|
||||||
|
"hillshade-exaggeration": 0.5
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"id": "satellite_layer",
|
||||||
|
"type": "raster",
|
||||||
|
"source": "worlddom_source",
|
||||||
|
"minzoom": 0,
|
||||||
|
"maxzoom": 11
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"terrain": {
|
||||||
|
"source": "elevation_source",
|
||||||
|
"exaggeration": 0.01
|
||||||
|
},
|
||||||
|
"sky": {
|
||||||
|
"atmosphere-blend": [
|
||||||
|
"interpolate",
|
||||||
|
["linear"],
|
||||||
|
["zoom"],
|
||||||
|
0, 1,
|
||||||
|
5, 1,
|
||||||
|
7, 0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"light": {
|
||||||
|
"anchor": "map",
|
||||||
|
"position": [1.5, 60, 45]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
10925
assets/pmtiles_style.json
Normal file
10925
assets/pmtiles_style.json
Normal file
File diff suppressed because it is too large
Load Diff
33
assets/style - 副本.json
Normal file
33
assets/style - 副本.json
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"version": 8,
|
||||||
|
"projection": {
|
||||||
|
"type": "globe"
|
||||||
|
},
|
||||||
|
"sources": {
|
||||||
|
"satellite": {
|
||||||
|
"tiles": ["https://tiles.maps.eox.at/wmts/1.0.0/s2cloudless-2020_3857/default/g/{z}/{y}/{x}.jpg"],
|
||||||
|
"type": "raster"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"layers": [
|
||||||
|
{
|
||||||
|
"id": "Satellite",
|
||||||
|
"type": "raster",
|
||||||
|
"source": "satellite"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"sky": {
|
||||||
|
"atmosphere-blend": [
|
||||||
|
"interpolate",
|
||||||
|
["linear"],
|
||||||
|
["zoom"],
|
||||||
|
0, 1,
|
||||||
|
5, 1,
|
||||||
|
7, 0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"light": {
|
||||||
|
"anchor": "map",
|
||||||
|
"position": [1.5, 60, 45]
|
||||||
|
}
|
||||||
|
}
|
||||||
26
assets/style.json
Normal file
26
assets/style.json
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"version": 8,
|
||||||
|
|
||||||
|
"sources": {
|
||||||
|
"my-mbtiles-source": {
|
||||||
|
"type": "vector",
|
||||||
|
"tiles": [
|
||||||
|
"http://localhost:5656/osm_vector/{z}/{x}/{y}.pbf"
|
||||||
|
],
|
||||||
|
"minzoom": 0,
|
||||||
|
"maxzoom": 14
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"layers": [
|
||||||
|
{
|
||||||
|
"id": "my-layer",
|
||||||
|
"type": "line",
|
||||||
|
"source": "my-mbtiles-source",
|
||||||
|
"source-layer": "your_layer_name_in_mbtiles",
|
||||||
|
"paint": {
|
||||||
|
"line-color": "#ff0000",
|
||||||
|
"line-width": 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
3
devtools_options.yaml
Normal file
3
devtools_options.yaml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
description: This file stores settings for Dart & Flutter DevTools.
|
||||||
|
documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
|
||||||
|
extensions:
|
||||||
90
lib/ecs/component.dart
Normal file
90
lib/ecs/component.dart
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:maplibre_gl/maplibre_gl.dart';
|
||||||
|
import 'entity.dart';
|
||||||
|
|
||||||
|
/// 组件基类 - 代表实体的属性
|
||||||
|
abstract class Component {
|
||||||
|
final String id;
|
||||||
|
Entity? entity;
|
||||||
|
|
||||||
|
Component({String? id}) : id = id ?? "${DateTime.now().millisecondsSinceEpoch}";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 标绘组件 - 用于在地图上绘制图形
|
||||||
|
class PlotComponent extends Component {
|
||||||
|
final String plotType;
|
||||||
|
final List<LatLng> coordinates;
|
||||||
|
final Color color;
|
||||||
|
final double strokeWidth;
|
||||||
|
|
||||||
|
PlotComponent({
|
||||||
|
super.id,
|
||||||
|
required this.plotType,
|
||||||
|
required this.coordinates,
|
||||||
|
this.color = Colors.red,
|
||||||
|
this.strokeWidth = 2.0,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 图标组件 - 用于在地图上显示图标
|
||||||
|
class IconComponent extends Component {
|
||||||
|
final String iconPath;
|
||||||
|
LatLng position;
|
||||||
|
final double size;
|
||||||
|
|
||||||
|
IconComponent({
|
||||||
|
super.id,
|
||||||
|
required this.iconPath,
|
||||||
|
required this.position,
|
||||||
|
this.size = 30.0,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 拖尾组件 - 用于显示移动实体的轨迹
|
||||||
|
class TrailComponent extends Component {
|
||||||
|
final List<LatLng> trailPoints;
|
||||||
|
final Color trailColor;
|
||||||
|
final double maxLength;
|
||||||
|
|
||||||
|
TrailComponent({
|
||||||
|
super.id,
|
||||||
|
List<LatLng>? trailPoints,
|
||||||
|
this.trailColor = Colors.blue,
|
||||||
|
this.maxLength = 20.0,
|
||||||
|
}) : trailPoints = trailPoints ?? [];
|
||||||
|
|
||||||
|
void addPoint(LatLng point) {
|
||||||
|
trailPoints.add(point);
|
||||||
|
if (trailPoints.length > maxLength) {
|
||||||
|
trailPoints.removeAt(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 音频组件 - 用于播放与实体相关的音频
|
||||||
|
class AudioComponent extends Component {
|
||||||
|
final String audioPath;
|
||||||
|
final bool loop;
|
||||||
|
final double volume;
|
||||||
|
|
||||||
|
AudioComponent({
|
||||||
|
super.id,
|
||||||
|
required this.audioPath,
|
||||||
|
this.loop = false,
|
||||||
|
this.volume = 1.0,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 移动组件 - 用于控制实体的移动
|
||||||
|
class MovementComponent extends Component {
|
||||||
|
LatLng position;
|
||||||
|
LatLng? target;
|
||||||
|
double speed;
|
||||||
|
|
||||||
|
MovementComponent({
|
||||||
|
super.id,
|
||||||
|
required this.position,
|
||||||
|
this.target,
|
||||||
|
this.speed = 1.0,
|
||||||
|
});
|
||||||
|
}
|
||||||
39
lib/ecs/entity.dart
Normal file
39
lib/ecs/entity.dart
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import 'component.dart';
|
||||||
|
/// 实体ID生成器
|
||||||
|
class EntityIdGenerator {
|
||||||
|
static int _id = 0;
|
||||||
|
static int nextId() => _id++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 实体类 - 代表地图上的一个对象
|
||||||
|
class Entity {
|
||||||
|
final int id;
|
||||||
|
final String name;
|
||||||
|
int entityType;
|
||||||
|
final Map<String, Component> _components = {};
|
||||||
|
|
||||||
|
Entity({int? id, required this.name, this.entityType = 0}) : id = id ?? EntityIdGenerator.nextId();
|
||||||
|
|
||||||
|
/// 添加组件
|
||||||
|
void addComponent<T extends Component>(T component) {
|
||||||
|
_components[T.toString()] = component;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 获取组件
|
||||||
|
T? getComponent<T extends Component>() {
|
||||||
|
return _components[T.toString()] as T?;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 检查是否有特定类型的组件
|
||||||
|
bool hasComponent<T extends Component>() {
|
||||||
|
return _components.containsKey(T.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 移除组件
|
||||||
|
void removeComponent<T extends Component>() {
|
||||||
|
_components.remove(T.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 获取所有组件
|
||||||
|
Map<String, Component> get components => _components;
|
||||||
|
}
|
||||||
389
lib/ecs/system.dart
Normal file
389
lib/ecs/system.dart
Normal file
@@ -0,0 +1,389 @@
|
|||||||
|
import 'dart:collection';
|
||||||
|
import 'dart:math';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:maplibre/maplibre.dart';
|
||||||
|
import 'package:maplibre_gl/maplibre_gl.dart' as gl;
|
||||||
|
import '../screens/map_screen.dart';
|
||||||
|
import 'entity.dart';
|
||||||
|
import 'component.dart';
|
||||||
|
|
||||||
|
/// 系统基类 - 用于处理特定类型的组件
|
||||||
|
abstract class System {
|
||||||
|
void update(List<Entity> entities, Duration deltaTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 地图系统 - 处理地图相关的实体和组件
|
||||||
|
class MapSystem implements System {
|
||||||
|
gl.MapLibreMapController? mapController;
|
||||||
|
MapUiBodyState? mapUiBodyState;
|
||||||
|
final List<String> _plotIds = [];
|
||||||
|
final List<String> _trailIds = [];
|
||||||
|
final List<String> _iconIds = [];
|
||||||
|
|
||||||
|
// 单例实例
|
||||||
|
static MapSystem? _instance;
|
||||||
|
|
||||||
|
// 工厂构造函数,实现单例
|
||||||
|
factory MapSystem({gl.MapLibreMapController? mapController, MapUiBodyState? mapUiBodyState}) {
|
||||||
|
_instance ??= MapSystem._internal(mapController: mapController, mapUiBodyState: mapUiBodyState);
|
||||||
|
if (mapController != null) _instance!.mapController = mapController;
|
||||||
|
if (mapUiBodyState != null) _instance!.mapUiBodyState = mapUiBodyState;
|
||||||
|
return _instance!;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 私有构造函数
|
||||||
|
MapSystem._internal({this.mapController, this.mapUiBodyState});
|
||||||
|
|
||||||
|
/// 获取单例实例
|
||||||
|
static MapSystem get instance {
|
||||||
|
_instance ??= MapSystem._internal();
|
||||||
|
return _instance!;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void update(List<Entity> entities, Duration deltaTime) {
|
||||||
|
// 更新地图上的标绘
|
||||||
|
for (var entity in entities) {
|
||||||
|
if (entity.hasComponent<PlotComponent>()) {
|
||||||
|
_updatePlot(entity.getComponent<PlotComponent>()!);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entity.hasComponent<IconComponent>()) {
|
||||||
|
_updateIcon(entity.getComponent<IconComponent>()!);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entity.hasComponent<TrailComponent>()) {
|
||||||
|
_updateTrail(entity.getComponent<TrailComponent>()!);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entity.hasComponent<MovementComponent>()) {
|
||||||
|
_updateMovement(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _updatePlot(PlotComponent plot) {
|
||||||
|
// 实现标绘更新逻辑
|
||||||
|
// 这里可以根据plotType绘制不同类型的图形
|
||||||
|
if (plot.coordinates.length >= 2) {
|
||||||
|
// 示例:绘制线段
|
||||||
|
// mapController?.addLine() // 这里需要根据实际API实现
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _updateIcon(IconComponent icon) {
|
||||||
|
// 实现图标更新逻辑
|
||||||
|
// mapController?.addMarker() // 这里需要根据实际API实现
|
||||||
|
}
|
||||||
|
|
||||||
|
void _updateTrail(TrailComponent trail) {
|
||||||
|
// 实现拖尾更新逻辑
|
||||||
|
// 绘制轨迹线
|
||||||
|
}
|
||||||
|
|
||||||
|
void _updateMovement(Entity entity) {
|
||||||
|
var movement = entity.getComponent<MovementComponent>();
|
||||||
|
var plot = entity.getComponent<PlotComponent>();
|
||||||
|
var icon = entity.getComponent<IconComponent>();
|
||||||
|
|
||||||
|
if (movement != null && (plot != null || icon != null)) {
|
||||||
|
if (movement.target != null) {
|
||||||
|
// 简单的移动逻辑 - 向目标点移动
|
||||||
|
double dx = movement.target!.longitude - movement.position.longitude;
|
||||||
|
double dy = movement.target!.latitude - movement.position.latitude;
|
||||||
|
double distance = sqrt(dx * dx + dy * dy);
|
||||||
|
|
||||||
|
if (distance > 0.0001) { // 如果距离目标足够近就停止
|
||||||
|
double ratio = movement.speed * 0.0001 / distance;
|
||||||
|
movement.position = gl.LatLng(
|
||||||
|
movement.position.latitude + dy * ratio,
|
||||||
|
movement.position.longitude + dx * ratio,
|
||||||
|
);
|
||||||
|
|
||||||
|
// 更新图标位置
|
||||||
|
if (icon != null) {
|
||||||
|
icon.position = movement.position;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果有拖尾组件,添加新点
|
||||||
|
var trail = entity.getComponent<TrailComponent>();
|
||||||
|
if (trail != null) {
|
||||||
|
trail.addPoint(movement.position);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
movement.target = null; // 到达目标
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 便捷方法:通过 mapUiBodyState 调用地图接口 ====================
|
||||||
|
|
||||||
|
/// 添加自定义图片标记
|
||||||
|
void addCustomMarker(Geographic position, {Map<String, dynamic>? properties}) {
|
||||||
|
mapUiBodyState?.addCustomMarker(position, properties: properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 添加圆形
|
||||||
|
void addCircle(
|
||||||
|
Geographic position, {
|
||||||
|
double radius = 20,
|
||||||
|
Color color = Colors.orange,
|
||||||
|
Color strokeColor = Colors.red,
|
||||||
|
double strokeWidth = 2,
|
||||||
|
}) {
|
||||||
|
mapUiBodyState?.addCircle(
|
||||||
|
position,
|
||||||
|
radius: radius,
|
||||||
|
color: color,
|
||||||
|
strokeWidth: strokeWidth,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 添加扇形
|
||||||
|
/// [center] 扇形中心的地理位置
|
||||||
|
/// [radius] 扇形的半径(单位:米)
|
||||||
|
/// [startAngle] 起始角度(单位:度,0度表示正东方向)
|
||||||
|
/// [endAngle] 结束角度(单位:度)
|
||||||
|
/// [segments] 扇形的分段数,值越大越平滑
|
||||||
|
/// [color] 填充颜色
|
||||||
|
/// [outlineColor] 边框颜色
|
||||||
|
void addSector(
|
||||||
|
Geographic center, {
|
||||||
|
required double radius,
|
||||||
|
required double startAngle,
|
||||||
|
required double endAngle,
|
||||||
|
int segments = 36,
|
||||||
|
Color color = Colors.lightBlueAccent,
|
||||||
|
Color outlineColor = Colors.blue,
|
||||||
|
}) {
|
||||||
|
mapUiBodyState?.addSector(
|
||||||
|
center,
|
||||||
|
radius: radius,
|
||||||
|
startAngle: startAngle,
|
||||||
|
endAngle: endAngle,
|
||||||
|
segments: segments,
|
||||||
|
color: color,
|
||||||
|
outlineColor: outlineColor,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 添加长方形
|
||||||
|
/// [center] 长方形中心的地理位置
|
||||||
|
/// [width] 长方形的宽度(单位:米)
|
||||||
|
/// [height] 长方形的高度(单位:米)
|
||||||
|
/// [color] 填充颜色
|
||||||
|
/// [outlineColor] 边框颜色
|
||||||
|
void addRectangle(
|
||||||
|
Geographic center, {
|
||||||
|
required double width,
|
||||||
|
required double height,
|
||||||
|
Color color = Colors.lightBlueAccent,
|
||||||
|
Color outlineColor = Colors.blue,
|
||||||
|
}) {
|
||||||
|
mapUiBodyState?.addRectangle(
|
||||||
|
center,
|
||||||
|
width: width,
|
||||||
|
height: height,
|
||||||
|
color: color,
|
||||||
|
outlineColor: outlineColor,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 清除所有自定义标记
|
||||||
|
void clearCustomMarkers() {
|
||||||
|
mapUiBodyState?.clearCustomMarkers();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 清除所有圆形
|
||||||
|
void clearCircles() {
|
||||||
|
mapUiBodyState?.clearCircles();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 清除所有多边形(包括扇形和长方形)
|
||||||
|
void clearPolygons() {
|
||||||
|
mapUiBodyState?.clearPolygons();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 清除所有自定义图层
|
||||||
|
void clearAllCustomLayers() {
|
||||||
|
mapUiBodyState?.clearAllCustomLayers();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 添加固定大小的圆形(不随地图缩放)
|
||||||
|
void addFixedCircle(
|
||||||
|
Geographic position, {
|
||||||
|
double radius = 20,
|
||||||
|
Color color = Colors.orange,
|
||||||
|
Color strokeColor = Colors.red,
|
||||||
|
double strokeWidth = 2,
|
||||||
|
}) {
|
||||||
|
mapUiBodyState?.addFixedCircle(
|
||||||
|
position,
|
||||||
|
radius: radius,
|
||||||
|
color: color,
|
||||||
|
outlineColor: strokeColor,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 音频系统 - 处理音频相关的实体和组件
|
||||||
|
class AudioSystem implements System {
|
||||||
|
@override
|
||||||
|
void update(List<Entity> entities, Duration deltaTime) {
|
||||||
|
for (var entity in entities) {
|
||||||
|
if (entity.hasComponent<AudioComponent>()) {
|
||||||
|
var audioComponent = entity.getComponent<AudioComponent>()!;
|
||||||
|
_playAudio(audioComponent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _playAudio(AudioComponent audio) {
|
||||||
|
// 实现音频播放逻辑
|
||||||
|
// 这里可以使用Flutter的音频插件如audioplayers
|
||||||
|
print("Playing audio: ${audio.audioPath}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 组件系统 - 管理各种组件的交互
|
||||||
|
class ComponentSystem implements System {
|
||||||
|
@override
|
||||||
|
void update(List<Entity> entities, Duration deltaTime) {
|
||||||
|
// 处理组件间的交互
|
||||||
|
for (var entity in entities) {
|
||||||
|
// 可以根据需要实现组件交互逻辑
|
||||||
|
if (entity.hasComponent<PlotComponent>() && entity.hasComponent<IconComponent>()) {
|
||||||
|
// 当一个实体同时有标绘和图标组件时的特殊处理
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ECS管理器 - 管理实体、系统和整个ECS框架
|
||||||
|
class ECSManager {
|
||||||
|
static ECSManager? _instance;
|
||||||
|
|
||||||
|
factory ECSManager() {
|
||||||
|
_instance ??= ECSManager._internal();
|
||||||
|
return _instance!;
|
||||||
|
}
|
||||||
|
|
||||||
|
ECSManager._internal();
|
||||||
|
|
||||||
|
/// 获取单例实例
|
||||||
|
static ECSManager get instance {
|
||||||
|
_instance ??= ECSManager._internal();
|
||||||
|
return _instance!;
|
||||||
|
}
|
||||||
|
|
||||||
|
final List<Entity> _entities = [];
|
||||||
|
final List<System> _systems = [];
|
||||||
|
final Queue<Entity> _entitiesToAdd = Queue<Entity>();
|
||||||
|
final Queue<Entity> _entitiesToRemove = Queue<Entity>();
|
||||||
|
|
||||||
|
void addEntity(Entity entity) {
|
||||||
|
_entitiesToAdd.add(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeEntity(Entity entity) {
|
||||||
|
_entitiesToRemove.add(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
void addSystem(System system) {
|
||||||
|
_systems.add(system);
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeSystem(System system) {
|
||||||
|
_systems.remove(system);
|
||||||
|
}
|
||||||
|
|
||||||
|
void update(Duration deltaTime) {
|
||||||
|
// 添加新实体
|
||||||
|
while (_entitiesToAdd.isNotEmpty) {
|
||||||
|
_entities.add(_entitiesToAdd.removeFirst());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新所有系统
|
||||||
|
for (var system in _systems) {
|
||||||
|
system.update(_entities, deltaTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 移除实体
|
||||||
|
while (_entitiesToRemove.isNotEmpty) {
|
||||||
|
var entity = _entitiesToRemove.removeFirst();
|
||||||
|
_entities.remove(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Entity> get entities => _entities;
|
||||||
|
|
||||||
|
/// 工厂方法:创建一个带位置的实体
|
||||||
|
Entity createEntityAtPosition({
|
||||||
|
required String name,
|
||||||
|
required gl.LatLng position,
|
||||||
|
String? plotType,
|
||||||
|
Color plotColor = Colors.red,
|
||||||
|
double strokeWidth = 2.0,
|
||||||
|
String? iconPath,
|
||||||
|
double iconSize = 30.0,
|
||||||
|
bool hasTrail = false,
|
||||||
|
Color trailColor = Colors.blue,
|
||||||
|
double trailMaxLength = 20.0,
|
||||||
|
bool hasMovement = false,
|
||||||
|
gl.LatLng? movementTarget,
|
||||||
|
double movementSpeed = 1.0,
|
||||||
|
String? audioPath,
|
||||||
|
bool audioLoop = false,
|
||||||
|
double audioVolume = 1.0,
|
||||||
|
}) {
|
||||||
|
// 创建实体
|
||||||
|
final entity = Entity(name: name);
|
||||||
|
|
||||||
|
// 添加位置相关的组件
|
||||||
|
if (plotType != null) {
|
||||||
|
entity.addComponent(PlotComponent(
|
||||||
|
plotType: plotType,
|
||||||
|
coordinates: [position],
|
||||||
|
color: plotColor,
|
||||||
|
strokeWidth: strokeWidth,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iconPath != null) {
|
||||||
|
entity.addComponent(IconComponent(
|
||||||
|
iconPath: iconPath,
|
||||||
|
position: position,
|
||||||
|
size: iconSize,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasTrail) {
|
||||||
|
entity.addComponent(TrailComponent(
|
||||||
|
trailColor: trailColor,
|
||||||
|
maxLength: trailMaxLength,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasMovement) {
|
||||||
|
entity.addComponent(MovementComponent(
|
||||||
|
position: position,
|
||||||
|
target: movementTarget,
|
||||||
|
speed: movementSpeed,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (audioPath != null) {
|
||||||
|
entity.addComponent(AudioComponent(
|
||||||
|
audioPath: audioPath,
|
||||||
|
loop: audioLoop,
|
||||||
|
volume: audioVolume,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加到管理器
|
||||||
|
addEntity(entity);
|
||||||
|
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,12 @@ import '../providers/chat_provider.dart';
|
|||||||
import '../widgets/message_bubble.dart';
|
import '../widgets/message_bubble.dart';
|
||||||
import '../widgets/typing_indicator.dart';
|
import '../widgets/typing_indicator.dart';
|
||||||
import '../widgets/chat_input.dart';
|
import '../widgets/chat_input.dart';
|
||||||
|
import 'map_screen.dart'; // 导入地图界面
|
||||||
|
|
||||||
|
|
||||||
|
// 定义一个 GlobalKey 来访问 _ChatScreenState
|
||||||
|
final GlobalKey<_ChatScreenState> chatScreenStateKey = GlobalKey<_ChatScreenState>();
|
||||||
|
|
||||||
|
|
||||||
class ChatScreen extends StatefulWidget {
|
class ChatScreen extends StatefulWidget {
|
||||||
const ChatScreen({super.key});
|
const ChatScreen({super.key});
|
||||||
@@ -16,6 +22,13 @@ class ChatScreen extends StatefulWidget {
|
|||||||
|
|
||||||
class _ChatScreenState extends State<ChatScreen> {
|
class _ChatScreenState extends State<ChatScreen> {
|
||||||
final ScrollController _scrollController = ScrollController();
|
final ScrollController _scrollController = ScrollController();
|
||||||
|
bool _mapViewOpen = false; // 控制地图界面是否展开
|
||||||
|
|
||||||
|
void _toggleMapView() {
|
||||||
|
setState(() {
|
||||||
|
_mapViewOpen = !_mapViewOpen;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void _scrollToBottom() {
|
void _scrollToBottom() {
|
||||||
if (_scrollController.hasClients) {
|
if (_scrollController.hasClients) {
|
||||||
@@ -62,18 +75,43 @@ class _ChatScreenState extends State<ChatScreen> {
|
|||||||
context.read<ChatProvider>().clearMessages();
|
context.read<ChatProvider>().clearMessages();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
// 添加地图按钮
|
||||||
|
CommandBarButton(
|
||||||
|
icon: const Icon(FluentIcons.map_layers),
|
||||||
|
label: const Text('Map'),
|
||||||
|
onPressed: _toggleMapView, // 切换地图视图
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
content: Column(
|
content: Row( // 修改为Row布局,实现左右分屏
|
||||||
children: [
|
children: [
|
||||||
Expanded(child: _buildMessageList()),
|
// 聊天界面部分,使用Expanded来正确分配空间
|
||||||
_buildInputArea(),
|
Expanded(
|
||||||
|
flex: 1,
|
||||||
|
child: _buildChatContent(),
|
||||||
|
),
|
||||||
|
|
||||||
|
// 地图界面部分,根据状态决定是否显示
|
||||||
|
if (_mapViewOpen)
|
||||||
|
Expanded(
|
||||||
|
child: const MapUiPage(), // 使用现有的地图页面
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 提取聊天内容部分到单独的方法
|
||||||
|
Widget _buildChatContent() {
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
Expanded(child: _buildMessageList()),
|
||||||
|
_buildInputArea(),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Widget _buildMessageList() {
|
Widget _buildMessageList() {
|
||||||
return Consumer<ChatProvider>(
|
return Consumer<ChatProvider>(
|
||||||
builder: (context, chatProvider, child) {
|
builder: (context, chatProvider, child) {
|
||||||
@@ -161,7 +199,7 @@ class _ChatScreenState extends State<ChatScreen> {
|
|||||||
color: theme.accentColor,
|
color: theme.accentColor,
|
||||||
borderRadius: BorderRadius.circular(20),
|
borderRadius: BorderRadius.circular(20),
|
||||||
),
|
),
|
||||||
child: const Icon(FluentIcons.robot, color: Colors.white, size: 40),
|
child: Icon(FluentIcons.robot, color: Colors.white, size: 40),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 24),
|
const SizedBox(height: 24),
|
||||||
Text('Hello! I\'m your AI Assistant', style: theme.typography.title),
|
Text('Hello! I\'m your AI Assistant', style: theme.typography.title),
|
||||||
@@ -220,4 +258,4 @@ class _ChatScreenState extends State<ChatScreen> {
|
|||||||
_scrollController.dispose();
|
_scrollController.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
613
lib/screens/map_screen.dart
Normal file
613
lib/screens/map_screen.dart
Normal file
@@ -0,0 +1,613 @@
|
|||||||
|
// Copyright 2018 The Chromium Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
import 'dart:math' as Math;
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:maplibre/maplibre.dart';
|
||||||
|
import 'package:maplibre_gl/maplibre_gl.dart' as gl;
|
||||||
|
import '../ecs/system.dart';
|
||||||
|
|
||||||
|
abstract class ExamplePage extends StatelessWidget {
|
||||||
|
const ExamplePage(
|
||||||
|
this.leading,
|
||||||
|
this.title, {
|
||||||
|
this.needsLocationPermission = true,
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
final Widget leading;
|
||||||
|
final String title;
|
||||||
|
final bool needsLocationPermission;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class MapUiPage extends ExamplePage {
|
||||||
|
const MapUiPage({super.key}) : super(const Icon(Icons.map), '态势');
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return const MapUiBody();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MapUiBody extends StatefulWidget {
|
||||||
|
const MapUiBody({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<MapUiBody> createState() => MapUiBodyState();
|
||||||
|
|
||||||
|
/// 静态方法,用于通过 GlobalKey 获取 MapUiBodyState 实例
|
||||||
|
static MapUiBodyState? of(BuildContext context) {
|
||||||
|
final mapUiBody = context.findAncestorWidgetOfExactType<MapUiBody>();
|
||||||
|
if (mapUiBody?.key is GlobalKey<MapUiBodyState>) {
|
||||||
|
final key = mapUiBody?.key as GlobalKey<MapUiBodyState>;
|
||||||
|
return key.currentState;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MapUiBodyState extends State<MapUiBody> with TickerProviderStateMixin {
|
||||||
|
late final MapController _controller;
|
||||||
|
final GlobalKey _mapKey = GlobalKey();
|
||||||
|
|
||||||
|
// MapSystem 实例,用于通过系统调用地图接口
|
||||||
|
late final MapSystem mapSystem;
|
||||||
|
|
||||||
|
final _markerPositions = [
|
||||||
|
const Geographic(lon: -10, lat: 0),
|
||||||
|
const Geographic(lon: -5, lat: 0),
|
||||||
|
const Geographic(lon: 0, lat: 0),
|
||||||
|
const Geographic(lon: 5, lat: 0),
|
||||||
|
];
|
||||||
|
|
||||||
|
// 自定义图片标记数据
|
||||||
|
final _customMarkers = <Feature<Point>>[];
|
||||||
|
bool _customMarkerImageLoaded = false;
|
||||||
|
|
||||||
|
// 圆形数据
|
||||||
|
final _circles = <Feature<Point>>[];
|
||||||
|
|
||||||
|
// 多边形数据(包括扇形和长方形)
|
||||||
|
final _polygons = <Feature<Polygon>>[];
|
||||||
|
|
||||||
|
Geographic? _originalPosition;
|
||||||
|
MapGestures _mapGestures = const MapGestures.all();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
// 初始化 MapSystem,并将 this 传递给它
|
||||||
|
mapSystem = MapSystem(mapUiBodyState: this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
//appBar: AppBar(title: const Text('Interactive Widget Layer')),
|
||||||
|
body: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
const Padding(
|
||||||
|
padding: EdgeInsets.only(left: 16, bottom: 8),
|
||||||
|
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: MapLibreMap(
|
||||||
|
key: _mapKey,
|
||||||
|
options: MapOptions(
|
||||||
|
initZoom: 3,
|
||||||
|
initCenter: const Geographic(lon: 0, lat: 0),
|
||||||
|
initStyle: "assets/osm_style.json",
|
||||||
|
gestures: _mapGestures,
|
||||||
|
),
|
||||||
|
onMapCreated: (controller) => _controller = controller,
|
||||||
|
onEvent: (event) async {
|
||||||
|
if (event is MapEventStyleLoaded) {
|
||||||
|
// 加载自定义标记图片
|
||||||
|
await event.style.addImageFromIconData(
|
||||||
|
id: 'custom-marker',
|
||||||
|
iconData: Icons.location_on,
|
||||||
|
color: Colors.blue,
|
||||||
|
);
|
||||||
|
setState(() {
|
||||||
|
_customMarkerImageLoaded = true;
|
||||||
|
});
|
||||||
|
} else if (event is MapEventLongClick) {
|
||||||
|
final position = event.point;
|
||||||
|
_markerPositions.add(position);
|
||||||
|
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
layers: [
|
||||||
|
// 自定义图片标记层
|
||||||
|
MarkerLayer(
|
||||||
|
points: _customMarkers.where((marker) =>
|
||||||
|
marker.properties['type'] != 'fixed_circle'
|
||||||
|
).toList(), // 过滤掉固定圆形
|
||||||
|
iconImage: _customMarkerImageLoaded ? 'custom-marker' : null,
|
||||||
|
iconSize: 0.15,
|
||||||
|
iconAnchor: IconAnchor.bottom,
|
||||||
|
),
|
||||||
|
// 圆形层
|
||||||
|
CircleLayer(
|
||||||
|
points: _circles,
|
||||||
|
color: Colors.orange.withValues(alpha: 0.5),
|
||||||
|
radius: 20,
|
||||||
|
strokeColor: Colors.red,
|
||||||
|
strokeWidth: 2,
|
||||||
|
),
|
||||||
|
// 多边形层(扇形、长方形和圆形)
|
||||||
|
PolygonLayer(
|
||||||
|
polygons: _polygons,
|
||||||
|
color: Colors.lightBlueAccent.withValues(alpha: 0.6),
|
||||||
|
outlineColor: Colors.blue,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
children: [
|
||||||
|
WidgetLayer(
|
||||||
|
allowInteraction: true,
|
||||||
|
markers: List.generate(
|
||||||
|
_markerPositions.length,
|
||||||
|
(index) => Marker(
|
||||||
|
size: const Size.square(50),
|
||||||
|
point: _markerPositions[index],
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () => _onTap(index),
|
||||||
|
onLongPressStart: (details) =>
|
||||||
|
_onLongPress(index, details),
|
||||||
|
onPanStart: (details) => _onLongPanStart(details, index),
|
||||||
|
onPanUpdate: (details) async =>
|
||||||
|
_onPanUpdate(details, index),
|
||||||
|
onPanEnd: (details) async => _onPanEnd(details, index),
|
||||||
|
child: const Icon(
|
||||||
|
Icons.location_on,
|
||||||
|
color: Colors.red,
|
||||||
|
size: 50,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
alignment: Alignment.bottomCenter,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// 添加固定圆形的Widget
|
||||||
|
WidgetLayer(
|
||||||
|
allowInteraction: false, // 固定圆形不需要交互
|
||||||
|
markers: _customMarkers
|
||||||
|
.where((marker) => marker.properties['type'] == 'fixed_circle')
|
||||||
|
.map((marker) {
|
||||||
|
final pointGeometry = marker.geometry as Point;
|
||||||
|
// 使用Point的position属性获取坐标
|
||||||
|
final geographic = Geographic(
|
||||||
|
lon: pointGeometry.position.x,
|
||||||
|
lat: pointGeometry.position.y,
|
||||||
|
);
|
||||||
|
return Marker(
|
||||||
|
size: Size.fromRadius(marker.properties['radius']?.toDouble() ?? 20.0),
|
||||||
|
point: geographic,
|
||||||
|
child: IgnorePointer( // 忽略指针事件,确保不会干扰地图手势
|
||||||
|
child: Container(
|
||||||
|
width: (marker.properties['radius']?.toDouble() ?? 20.0) * 2,
|
||||||
|
height: (marker.properties['radius']?.toDouble() ?? 20.0) * 2,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: marker.properties['color'] ?? Colors.orange,
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
border: Border.all(
|
||||||
|
color: marker.properties['strokeColor'] ?? Colors.red,
|
||||||
|
width: marker.properties['strokeWidth']?.toDouble() ?? 2.0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
alignment: Alignment.center,
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.toList(),
|
||||||
|
),
|
||||||
|
// display the UI widgets above the widget markers.
|
||||||
|
const MapScalebar(),
|
||||||
|
const SourceAttribution(),
|
||||||
|
const MapControlButtons(),
|
||||||
|
const MapCompass(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Geographic> _toLngLat(Offset eventOffset) async {
|
||||||
|
final mapRenderBox =
|
||||||
|
_mapKey.currentContext?.findRenderObject() as RenderBox?;
|
||||||
|
|
||||||
|
assert(mapRenderBox != null, 'RenderBox of Map should never be null');
|
||||||
|
|
||||||
|
final mapOffset = mapRenderBox!.localToGlobal(Offset.zero);
|
||||||
|
|
||||||
|
final offset = Offset(
|
||||||
|
eventOffset.dx - mapOffset.dx,
|
||||||
|
eventOffset.dy - mapOffset.dy,
|
||||||
|
);
|
||||||
|
|
||||||
|
return _controller.toLngLat(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onLongPress(int index, LongPressStartDetails details) {
|
||||||
|
final offset = details.globalPosition;
|
||||||
|
|
||||||
|
showMenu(
|
||||||
|
context: context,
|
||||||
|
position: RelativeRect.fromLTRB(
|
||||||
|
offset.dx,
|
||||||
|
offset.dy,
|
||||||
|
MediaQuery.of(context).size.width - offset.dx,
|
||||||
|
MediaQuery.of(context).size.height - offset.dy,
|
||||||
|
),
|
||||||
|
items: [
|
||||||
|
const PopupMenuItem<void>(child: Text('Edit')),
|
||||||
|
PopupMenuItem<void>(
|
||||||
|
onTap: () async {
|
||||||
|
final isConfirmed = await _showConfirmationDialogDelete(index);
|
||||||
|
|
||||||
|
if (isConfirmed) {
|
||||||
|
_markerPositions.removeAt(index);
|
||||||
|
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: const Text('Delete'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onPanEnd(DragEndDetails details, int index) async {
|
||||||
|
final isAccepted = await _showConfirmationDialogMove();
|
||||||
|
|
||||||
|
if (!isAccepted) {
|
||||||
|
_markerPositions[index] = _originalPosition!;
|
||||||
|
} else {
|
||||||
|
final newPosition = await _toLngLat(details.globalPosition);
|
||||||
|
_markerPositions[index] = newPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
_originalPosition = null;
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
_mapGestures = const MapGestures.all();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onLongPanStart(DragStartDetails details, int index) {
|
||||||
|
// Keep original position in case of discarded move
|
||||||
|
_originalPosition = Geographic.from(_markerPositions[index]);
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
// Disable camera panning while a marker gets moved.
|
||||||
|
_mapGestures = const MapGestures.all(pan: false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onPanUpdate(DragUpdateDetails details, int index) async {
|
||||||
|
final newPosition = await _toLngLat(details.globalPosition);
|
||||||
|
_markerPositions[index] = newPosition;
|
||||||
|
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onTap(int index) {
|
||||||
|
_showMarkerDetails(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> _showConfirmationDialogDelete(int index) async {
|
||||||
|
final isConfirmed = await showDialog<bool>(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => AlertDialog(
|
||||||
|
title: Text('Delete marker [$index]?'),
|
||||||
|
actions: <Widget>[
|
||||||
|
TextButton(
|
||||||
|
style: TextButton.styleFrom(
|
||||||
|
textStyle: Theme.of(context).textTheme.labelLarge,
|
||||||
|
),
|
||||||
|
child: const Text('Cancel'),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop(false);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
style: TextButton.styleFrom(
|
||||||
|
textStyle: Theme.of(context).textTheme.labelLarge,
|
||||||
|
),
|
||||||
|
child: const Text('Delete'),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop(true);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return isConfirmed ?? false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> _showConfirmationDialogMove() async {
|
||||||
|
final isConfirmed = await showDialog<bool>(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => AlertDialog(
|
||||||
|
title: const Text('Accept new position?'),
|
||||||
|
actions: <Widget>[
|
||||||
|
TextButton(
|
||||||
|
style: TextButton.styleFrom(
|
||||||
|
textStyle: Theme.of(context).textTheme.labelLarge,
|
||||||
|
),
|
||||||
|
child: const Text('Discard'),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop(false);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
style: TextButton.styleFrom(
|
||||||
|
textStyle: Theme.of(context).textTheme.labelLarge,
|
||||||
|
),
|
||||||
|
child: const Text('Accept'),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop(true);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return isConfirmed ?? false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _showMarkerDetails(int index) async {
|
||||||
|
await showDialog<void>(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => AlertDialog(
|
||||||
|
title: Text('Details marker with index: $index'),
|
||||||
|
content: Text('Show here the details of Marker with index $index'),
|
||||||
|
actions: <Widget>[
|
||||||
|
TextButton(
|
||||||
|
style: TextButton.styleFrom(
|
||||||
|
textStyle: Theme.of(context).textTheme.labelLarge,
|
||||||
|
),
|
||||||
|
child: const Text('Cancel'),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 公共接口方法 ====================
|
||||||
|
|
||||||
|
/// 添加自定义图片标记
|
||||||
|
///
|
||||||
|
/// [position] 标记的地理位置
|
||||||
|
/// [properties] 可选的属性数据
|
||||||
|
void addCustomMarker(Geographic position, {Map<String, dynamic>? properties}) {
|
||||||
|
setState(() {
|
||||||
|
_customMarkers.add(Feature(
|
||||||
|
geometry: Point(position),
|
||||||
|
properties: properties,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 添加圆形
|
||||||
|
///
|
||||||
|
/// [position] 圆心的地理位置
|
||||||
|
/// [radius] 圆的半径(单位:像素)
|
||||||
|
/// [color] 填充颜色
|
||||||
|
/// [strokeColor] 边框颜色
|
||||||
|
/// [strokeWidth] 边框宽度
|
||||||
|
void addCircle(
|
||||||
|
Geographic position, {
|
||||||
|
double radius = 20,
|
||||||
|
Color color = Colors.orange,
|
||||||
|
Color strokeColor = Colors.red,
|
||||||
|
double strokeWidth = 2,
|
||||||
|
}) {
|
||||||
|
setState(() {
|
||||||
|
_circles.add(Feature(
|
||||||
|
geometry: Point(position),
|
||||||
|
properties: {
|
||||||
|
'radius': radius,
|
||||||
|
'color': color,
|
||||||
|
'strokeColor': strokeColor,
|
||||||
|
'strokeWidth': strokeWidth,
|
||||||
|
},
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 添加固定大小的圆形(不随地图缩放)
|
||||||
|
///
|
||||||
|
/// [center] 圆心的地理位置
|
||||||
|
/// [radius] 圆的半径(单位:米)
|
||||||
|
/// [color] 填充颜色
|
||||||
|
/// [outlineColor] 边框颜色
|
||||||
|
void addFixedCircle(
|
||||||
|
Geographic center, {
|
||||||
|
required double radius,
|
||||||
|
Color color = Colors.orange,
|
||||||
|
Color outlineColor = Colors.blue,
|
||||||
|
}) {
|
||||||
|
// 将半径从米转换为经纬度(度)
|
||||||
|
final radiusInDegrees = _metersToDegrees(center, radius);
|
||||||
|
|
||||||
|
final points = <Geographic>[];
|
||||||
|
|
||||||
|
// 计算圆周上的点(360度)
|
||||||
|
for (int i = 0; i <= 36; i++) { // 使用36个点来构成圆形
|
||||||
|
final angle = (360 * i / 36) * 3.14159265359 / 180; // 角度转弧度
|
||||||
|
|
||||||
|
// 将角度转换为经纬度偏移
|
||||||
|
final latOffset = radiusInDegrees * Math.sin(angle);
|
||||||
|
final lonOffset = radiusInDegrees * Math.cos(angle);
|
||||||
|
|
||||||
|
points.add(Geographic(
|
||||||
|
lon: center.lon + lonOffset,
|
||||||
|
lat: center.lat + latOffset,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
_polygons.add(Feature(
|
||||||
|
geometry: Polygon.from([points]),
|
||||||
|
properties: {
|
||||||
|
'color': color,
|
||||||
|
'outlineColor': outlineColor,
|
||||||
|
'type': 'fixed_circle_geo', // 标记为地理圆形
|
||||||
|
},
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 添加扇形
|
||||||
|
///
|
||||||
|
/// [center] 扇形中心的地理位置
|
||||||
|
/// [radius] 扇形的半径(单位:米)
|
||||||
|
/// [startAngle] 起始角度(单位:度,0度表示正东方向)
|
||||||
|
/// [endAngle] 结束角度(单位:度)
|
||||||
|
/// [segments] 扇形的分段数,值越大越平滑
|
||||||
|
/// [color] 填充颜色
|
||||||
|
/// [outlineColor] 边框颜色
|
||||||
|
void addSector(
|
||||||
|
Geographic center, {
|
||||||
|
required double radius,
|
||||||
|
required double startAngle,
|
||||||
|
required double endAngle,
|
||||||
|
int segments = 36,
|
||||||
|
Color color = Colors.lightBlueAccent,
|
||||||
|
Color outlineColor = Colors.blue,
|
||||||
|
}) {
|
||||||
|
// 将半径从米转换为经纬度(度)
|
||||||
|
final radiusInDegrees = _metersToDegrees(center, radius);
|
||||||
|
|
||||||
|
final points = <Geographic>[];
|
||||||
|
|
||||||
|
// 添加中心点
|
||||||
|
points.add(center);
|
||||||
|
|
||||||
|
// 计算扇形的弧线上的点
|
||||||
|
for (int i = 0; i <= segments; i++) {
|
||||||
|
final angle = startAngle + (endAngle - startAngle) * i / segments;
|
||||||
|
final angleRad = angle * 3.14159265359 / 180;
|
||||||
|
|
||||||
|
// 将角度转换为经纬度偏移
|
||||||
|
final latOffset = radiusInDegrees * Math.sin(angleRad);
|
||||||
|
final lonOffset = radiusInDegrees * Math.cos(angleRad);
|
||||||
|
|
||||||
|
points.add(Geographic(
|
||||||
|
lon: center.lon + lonOffset,
|
||||||
|
lat: center.lat + latOffset,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
_polygons.add(Feature(
|
||||||
|
geometry: Polygon.from([points]),
|
||||||
|
properties: {
|
||||||
|
'color': color,
|
||||||
|
'outlineColor': outlineColor,
|
||||||
|
},
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 添加长方形
|
||||||
|
///
|
||||||
|
/// [center] 长方形中心的地理位置
|
||||||
|
/// [width] 长方形的宽度(单位:米)
|
||||||
|
/// [height] 长方形的高度(单位:米)
|
||||||
|
/// [color] 填充颜色
|
||||||
|
/// [outlineColor] 边框颜色
|
||||||
|
void addRectangle(
|
||||||
|
Geographic center, {
|
||||||
|
required double width,
|
||||||
|
required double height,
|
||||||
|
Color color = Colors.lightBlueAccent,
|
||||||
|
Color outlineColor = Colors.blue,
|
||||||
|
}) {
|
||||||
|
// 将宽高从米转换为经纬度(度)
|
||||||
|
final widthInDegrees = _metersToDegrees(center, width / 2);
|
||||||
|
final heightInDegrees = _metersToDegrees(center, height / 2);
|
||||||
|
|
||||||
|
final points = [
|
||||||
|
Geographic(lon: center.lon - widthInDegrees, lat: center.lat - heightInDegrees),
|
||||||
|
Geographic(lon: center.lon + widthInDegrees, lat: center.lat - heightInDegrees),
|
||||||
|
Geographic(lon: center.lon + widthInDegrees, lat: center.lat + heightInDegrees),
|
||||||
|
Geographic(lon: center.lon - widthInDegrees, lat: center.lat + heightInDegrees),
|
||||||
|
Geographic(lon: center.lon - widthInDegrees, lat: center.lat - heightInDegrees), // 闭合多边形
|
||||||
|
];
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
_polygons.add(Feature(
|
||||||
|
geometry: Polygon.from([points]),
|
||||||
|
properties: {
|
||||||
|
'color': color,
|
||||||
|
'outlineColor': outlineColor,
|
||||||
|
},
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 将距离(米)转换为经纬度(度)
|
||||||
|
/// 此方法使用近似计算,适用于小范围区域
|
||||||
|
double _metersToDegrees(Geographic center, double meters) {
|
||||||
|
// 地球半径,约为6378137米
|
||||||
|
const earthRadius = 6378137.0;
|
||||||
|
|
||||||
|
// 将米转换为度
|
||||||
|
// 1度大约等于111320米(在赤道附近)
|
||||||
|
// 但需要考虑纬度的影响,因为经度的距离会随纬度变化
|
||||||
|
final latCircumference = 2 * Math.pi * earthRadius; // 纬线周长
|
||||||
|
final latFactor = meters / latCircumference * 360; // 纬度方向转换因子
|
||||||
|
|
||||||
|
// 经度方向需要考虑纬度的影响
|
||||||
|
final lonCircumference = 2 * Math.pi * earthRadius * Math.cos(center.lat * Math.pi / 180); // 经线周长
|
||||||
|
final lonFactor = meters / lonCircumference * 360; // 经度方向转换因子
|
||||||
|
|
||||||
|
// 返回平均值,对于小范围区域,这个近似是足够的
|
||||||
|
return (latFactor + lonFactor) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 清除所有自定义标记
|
||||||
|
void clearCustomMarkers() {
|
||||||
|
setState(() {
|
||||||
|
_customMarkers.clear();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 清除所有圆形
|
||||||
|
void clearCircles() {
|
||||||
|
setState(() {
|
||||||
|
_circles.clear();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 清除所有多边形(包括扇形和长方形)
|
||||||
|
void clearPolygons() {
|
||||||
|
setState(() {
|
||||||
|
_polygons.clear();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 清除所有自定义图层
|
||||||
|
void clearAllCustomLayers() {
|
||||||
|
setState(() {
|
||||||
|
_customMarkers.clear();
|
||||||
|
_circles.clear();
|
||||||
|
_polygons.clear();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
174
lib/utils/map_styles.dart
Normal file
174
lib/utils/map_styles.dart
Normal file
@@ -0,0 +1,174 @@
|
|||||||
|
enum MapStyles {
|
||||||
|
openMapTilesLiberty(
|
||||||
|
name: 'OpenMapTiles Liberty',
|
||||||
|
uri: 'https://tiles.openfreemap.org/styles/liberty',
|
||||||
|
),
|
||||||
|
openMapTilesBright(
|
||||||
|
name: 'OpenMapTiles Bright',
|
||||||
|
uri: 'https://tiles.openfreemap.org/styles/bright',
|
||||||
|
),
|
||||||
|
openMapTilesPositron(
|
||||||
|
name: 'OpenMapTiles Positron',
|
||||||
|
uri: 'https://tiles.openfreemap.org/styles/positron',
|
||||||
|
),
|
||||||
|
openMapTilesStreets(
|
||||||
|
name: 'OpenMapTiles Streets',
|
||||||
|
uri:
|
||||||
|
'https://api.maptiler.com/maps/streets-v2/style.json?key=$_maptilerKey',
|
||||||
|
),
|
||||||
|
stadiaMapsAlidadeSmooth(
|
||||||
|
name: 'Alidade Smooth',
|
||||||
|
uri:
|
||||||
|
'https://tiles.stadiamaps.com/styles/alidade_smooth.json?api_key=$_stadiamapsKey',
|
||||||
|
),
|
||||||
|
stadiaMapsAlidadeSmoothDark(
|
||||||
|
name: 'Alidade Smooth Dark',
|
||||||
|
uri:
|
||||||
|
'https://tiles.stadiamaps.com/styles/alidade_smooth_dark.json?api_key=$_stadiamapsKey',
|
||||||
|
),
|
||||||
|
versaTilesColorful(
|
||||||
|
name: 'VersaTiles Colorful',
|
||||||
|
uri: 'https://tiles.versatiles.org/assets/styles/colorful/style.json',
|
||||||
|
),
|
||||||
|
versaTilesGraybeard(
|
||||||
|
name: 'VersaTiles Graybeard',
|
||||||
|
uri: 'https://tiles.versatiles.org/assets/styles/graybeard/style.json',
|
||||||
|
),
|
||||||
|
versaTilesEclipse(
|
||||||
|
name: 'VersaTiles Eclipse',
|
||||||
|
uri: 'https://tiles.versatiles.org/assets/styles/eclipse/style.json',
|
||||||
|
),
|
||||||
|
versaTilesNeutrino(
|
||||||
|
name: 'VersaTiles Neutrino',
|
||||||
|
uri: 'https://tiles.versatiles.org/assets/styles/neutrino/style.json',
|
||||||
|
),
|
||||||
|
protomapsLight(
|
||||||
|
name: 'Protomaps Light',
|
||||||
|
uri: 'https://api.protomaps.com/styles/v2/light.json?key=$_protomapsKey',
|
||||||
|
),
|
||||||
|
protomapsLightPmTiles(
|
||||||
|
name: 'Protomaps Light (PMTiles)',
|
||||||
|
uri: 'assets/styles/protomaps-light.json',
|
||||||
|
),
|
||||||
|
protomapsDark(
|
||||||
|
name: 'Protomaps Dark',
|
||||||
|
uri: 'https://api.protomaps.com/styles/v2/dark.json?key=$_protomapsKey',
|
||||||
|
),
|
||||||
|
protomapsWhite(
|
||||||
|
name: 'Protomaps White',
|
||||||
|
uri: 'https://api.protomaps.com/styles/v2/white.json?key=$_protomapsKey',
|
||||||
|
),
|
||||||
|
// mapboxStreets(
|
||||||
|
// name: 'Mapbox Streets (legacy)',
|
||||||
|
// uri: 'mapbox://styles/mapbox/streets-v12?access_token=$_mapboxKey',
|
||||||
|
// ),
|
||||||
|
// mapboxOutdoor(
|
||||||
|
// name: 'Mapbox Outdoors (legacy)',
|
||||||
|
// uri: 'mapbox://styles/mapbox/outdoors-v12?access_token=$_mapboxKey',
|
||||||
|
// ),
|
||||||
|
// mapboxLight(
|
||||||
|
// name: 'Mapbox Light (legacy)',
|
||||||
|
// uri: 'mapbox://styles/mapbox/light-v11?access_token=$_mapboxKey',
|
||||||
|
// ),
|
||||||
|
// mapboxDark(
|
||||||
|
// name: 'Mapbox Dark (legacy)',
|
||||||
|
// uri: 'mapbox://styles/mapbox/dark-v11?access_token=$_mapboxKey',
|
||||||
|
// ),
|
||||||
|
// mapboxSatellite(
|
||||||
|
// name: 'Mapbox Satellite (legacy)',
|
||||||
|
// uri: 'mapbox://styles/mapbox/satellite-v9?access_token=$_mapboxKey',
|
||||||
|
// ),
|
||||||
|
// mapboxSatelliteStreets(
|
||||||
|
// name: 'Mapbox Satellite Streets (legacy)',
|
||||||
|
// uri:
|
||||||
|
// 'mapbox://styles/mapbox/satellite-streets-v12?access_token=$_mapboxKey',
|
||||||
|
// ),
|
||||||
|
maplibreWorld(
|
||||||
|
name: 'MapLibre World',
|
||||||
|
uri: 'https://demotiles.maplibre.org/style.json',
|
||||||
|
),
|
||||||
|
maplibreDebug(
|
||||||
|
name: 'MapLibre Debug',
|
||||||
|
uri: 'https://demotiles.maplibre.org/debug-tiles/style.json',
|
||||||
|
),
|
||||||
|
translucent(name: 'Translucent', uri: 'assets/styles/translucent_style.json'),
|
||||||
|
countries(
|
||||||
|
name: 'Countries',
|
||||||
|
uri: '''
|
||||||
|
{
|
||||||
|
"version": 8,
|
||||||
|
"name": "MapLibre",
|
||||||
|
"center": [17.65431710431244, 32.954120326746775],
|
||||||
|
"zoom": 0.8619833357855968,
|
||||||
|
"bearing": 0,
|
||||||
|
"pitch": 0,
|
||||||
|
"sources": {
|
||||||
|
"maplibre": {
|
||||||
|
"url": "https://demotiles.maplibre.org/tiles/tiles.json",
|
||||||
|
"type": "vector"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"glyphs": "https://demotiles.maplibre.org/font/{fontstack}/{range}.pbf",
|
||||||
|
"layers": [
|
||||||
|
{
|
||||||
|
"id": "background",
|
||||||
|
"type": "background",
|
||||||
|
"maxzoom": 24,
|
||||||
|
"filter": ["all"],
|
||||||
|
"paint": {"background-color": "#D8F2FF"}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "countries-fill",
|
||||||
|
"type": "fill",
|
||||||
|
"source": "maplibre",
|
||||||
|
"source-layer": "countries",
|
||||||
|
"maxzoom": 24,
|
||||||
|
"filter": ["all"],
|
||||||
|
"paint": {"fill-color": "#FFFFFF"}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "countries-boundary",
|
||||||
|
"type": "line",
|
||||||
|
"source": "maplibre",
|
||||||
|
"source-layer": "countries",
|
||||||
|
"maxzoom": 24,
|
||||||
|
"layout": {
|
||||||
|
"line-cap": "round",
|
||||||
|
"line-join": "round",
|
||||||
|
"visibility": "visible"
|
||||||
|
},
|
||||||
|
"paint": {
|
||||||
|
"line-color": "#198EC8",
|
||||||
|
"line-width": {"stops": [[1, 1], [6, 2], [14, 6], [22, 12]]},
|
||||||
|
"line-opacity": {"stops": [[3, 0.5], [6, 1]]}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"id": "43f36e14-e3f5-43c1-84c0-50a9c80dc5c7"
|
||||||
|
}
|
||||||
|
''',
|
||||||
|
);
|
||||||
|
|
||||||
|
const MapStyles({required this.name, required this.uri});
|
||||||
|
|
||||||
|
final String name;
|
||||||
|
final String uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// **Use your own key for your project!**
|
||||||
|
/// This key will be rotated occasionally.
|
||||||
|
///
|
||||||
|
/// https://cloud.maptiler.com/account/keys/
|
||||||
|
const _maptilerKey = 'OPCgnZ51sHETbEQ4wnkd';
|
||||||
|
|
||||||
|
/// **Use your own key for your project!**
|
||||||
|
/// This key will be rotated occasionally.
|
||||||
|
///
|
||||||
|
/// https://protomaps.com/account
|
||||||
|
const _protomapsKey = 'a6f9aebb3965458c';
|
||||||
|
|
||||||
|
/// **Use your own key for your project!**
|
||||||
|
/// This key will be rotated occasionally.
|
||||||
|
///
|
||||||
|
/// https://client.stadiamaps.com/dashboard
|
||||||
|
const _stadiamapsKey = '0d5e614b-aaf7-4bfd-9bf3-1f7c3062248e';
|
||||||
35
lib/utils/style_dropdown.dart
Normal file
35
lib/utils/style_dropdown.dart
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import '/utils/map_styles.dart';
|
||||||
|
|
||||||
|
class StyleDropdown extends StatefulWidget {
|
||||||
|
const StyleDropdown({required this.onChanged, super.key});
|
||||||
|
|
||||||
|
final void Function(MapStyles style) onChanged;
|
||||||
|
|
||||||
|
static MapStyles get initStyle => MapStyles.openMapTilesLiberty;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<StyleDropdown> createState() => _StyleDropdownState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _StyleDropdownState extends State<StyleDropdown> {
|
||||||
|
late MapStyles _selectedStyle = StyleDropdown.initStyle;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||||
|
child: DropdownButton<MapStyles>(
|
||||||
|
value: _selectedStyle,
|
||||||
|
items: MapStyles.values
|
||||||
|
.map((e) => DropdownMenuItem(value: e, child: Text(e.name)))
|
||||||
|
.toList(growable: false),
|
||||||
|
onChanged: (value) {
|
||||||
|
if (value == null) return;
|
||||||
|
setState(() => _selectedStyle = value);
|
||||||
|
widget.onChanged(value);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,20 +7,28 @@
|
|||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
#include <flutter_acrylic/flutter_acrylic_plugin.h>
|
#include <flutter_acrylic/flutter_acrylic_plugin.h>
|
||||||
|
#include <maplibre/maplibre_plugin.h>
|
||||||
#include <screen_retriever_linux/screen_retriever_linux_plugin.h>
|
#include <screen_retriever_linux/screen_retriever_linux_plugin.h>
|
||||||
#include <system_theme/system_theme_plugin.h>
|
#include <system_theme/system_theme_plugin.h>
|
||||||
|
#include <url_launcher_linux/url_launcher_plugin.h>
|
||||||
#include <window_manager/window_manager_plugin.h>
|
#include <window_manager/window_manager_plugin.h>
|
||||||
|
|
||||||
void fl_register_plugins(FlPluginRegistry* registry) {
|
void fl_register_plugins(FlPluginRegistry* registry) {
|
||||||
g_autoptr(FlPluginRegistrar) flutter_acrylic_registrar =
|
g_autoptr(FlPluginRegistrar) flutter_acrylic_registrar =
|
||||||
fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterAcrylicPlugin");
|
fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterAcrylicPlugin");
|
||||||
flutter_acrylic_plugin_register_with_registrar(flutter_acrylic_registrar);
|
flutter_acrylic_plugin_register_with_registrar(flutter_acrylic_registrar);
|
||||||
|
g_autoptr(FlPluginRegistrar) maplibre_registrar =
|
||||||
|
fl_plugin_registry_get_registrar_for_plugin(registry, "MaplibrePlugin");
|
||||||
|
maplibre_plugin_register_with_registrar(maplibre_registrar);
|
||||||
g_autoptr(FlPluginRegistrar) screen_retriever_linux_registrar =
|
g_autoptr(FlPluginRegistrar) screen_retriever_linux_registrar =
|
||||||
fl_plugin_registry_get_registrar_for_plugin(registry, "ScreenRetrieverLinuxPlugin");
|
fl_plugin_registry_get_registrar_for_plugin(registry, "ScreenRetrieverLinuxPlugin");
|
||||||
screen_retriever_linux_plugin_register_with_registrar(screen_retriever_linux_registrar);
|
screen_retriever_linux_plugin_register_with_registrar(screen_retriever_linux_registrar);
|
||||||
g_autoptr(FlPluginRegistrar) system_theme_registrar =
|
g_autoptr(FlPluginRegistrar) system_theme_registrar =
|
||||||
fl_plugin_registry_get_registrar_for_plugin(registry, "SystemThemePlugin");
|
fl_plugin_registry_get_registrar_for_plugin(registry, "SystemThemePlugin");
|
||||||
system_theme_plugin_register_with_registrar(system_theme_registrar);
|
system_theme_plugin_register_with_registrar(system_theme_registrar);
|
||||||
|
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
|
||||||
|
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
|
||||||
|
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
|
||||||
g_autoptr(FlPluginRegistrar) window_manager_registrar =
|
g_autoptr(FlPluginRegistrar) window_manager_registrar =
|
||||||
fl_plugin_registry_get_registrar_for_plugin(registry, "WindowManagerPlugin");
|
fl_plugin_registry_get_registrar_for_plugin(registry, "WindowManagerPlugin");
|
||||||
window_manager_plugin_register_with_registrar(window_manager_registrar);
|
window_manager_plugin_register_with_registrar(window_manager_registrar);
|
||||||
|
|||||||
@@ -4,12 +4,15 @@
|
|||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
flutter_acrylic
|
flutter_acrylic
|
||||||
|
maplibre
|
||||||
screen_retriever_linux
|
screen_retriever_linux
|
||||||
system_theme
|
system_theme
|
||||||
|
url_launcher_linux
|
||||||
window_manager
|
window_manager
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||||
|
jni
|
||||||
)
|
)
|
||||||
|
|
||||||
set(PLUGIN_BUNDLED_LIBRARIES)
|
set(PLUGIN_BUNDLED_LIBRARIES)
|
||||||
|
|||||||
@@ -6,13 +6,17 @@ import FlutterMacOS
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
import macos_window_utils
|
import macos_window_utils
|
||||||
|
import maplibre
|
||||||
import screen_retriever_macos
|
import screen_retriever_macos
|
||||||
import system_theme
|
import system_theme
|
||||||
|
import url_launcher_macos
|
||||||
import window_manager
|
import window_manager
|
||||||
|
|
||||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
MacOSWindowUtilsPlugin.register(with: registry.registrar(forPlugin: "MacOSWindowUtilsPlugin"))
|
MacOSWindowUtilsPlugin.register(with: registry.registrar(forPlugin: "MacOSWindowUtilsPlugin"))
|
||||||
|
MaplibrePlugin.register(with: registry.registrar(forPlugin: "MaplibrePlugin"))
|
||||||
ScreenRetrieverMacosPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverMacosPlugin"))
|
ScreenRetrieverMacosPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverMacosPlugin"))
|
||||||
SystemThemePlugin.register(with: registry.registrar(forPlugin: "SystemThemePlugin"))
|
SystemThemePlugin.register(with: registry.registrar(forPlugin: "SystemThemePlugin"))
|
||||||
|
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
||||||
WindowManagerPlugin.register(with: registry.registrar(forPlugin: "WindowManagerPlugin"))
|
WindowManagerPlugin.register(with: registry.registrar(forPlugin: "WindowManagerPlugin"))
|
||||||
}
|
}
|
||||||
|
|||||||
474
pubspec.lock
474
pubspec.lock
@@ -1,12 +1,20 @@
|
|||||||
# Generated by pub
|
# Generated by pub
|
||||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||||
packages:
|
packages:
|
||||||
|
archive:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: archive
|
||||||
|
sha256: "2fde1607386ab523f7a36bb3e7edb43bd58e6edaf2ffb29d8a6d578b297fdbbd"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "4.0.7"
|
||||||
args:
|
args:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: args
|
name: args
|
||||||
sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04
|
sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.7.0"
|
version: "2.7.0"
|
||||||
async:
|
async:
|
||||||
@@ -14,7 +22,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: async
|
name: async
|
||||||
sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb"
|
sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.13.0"
|
version: "2.13.0"
|
||||||
boolean_selector:
|
boolean_selector:
|
||||||
@@ -22,7 +30,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: boolean_selector
|
name: boolean_selector
|
||||||
sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea"
|
sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.2"
|
version: "2.1.2"
|
||||||
characters:
|
characters:
|
||||||
@@ -30,7 +38,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: characters
|
name: characters
|
||||||
sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
|
sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.4.0"
|
version: "1.4.0"
|
||||||
clock:
|
clock:
|
||||||
@@ -38,7 +46,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: clock
|
name: clock
|
||||||
sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
|
sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.2"
|
version: "1.1.2"
|
||||||
collection:
|
collection:
|
||||||
@@ -46,23 +54,63 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: collection
|
name: collection
|
||||||
sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
|
sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.19.1"
|
version: "1.19.1"
|
||||||
|
crypto:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: crypto
|
||||||
|
sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.7"
|
||||||
|
csslib:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: csslib
|
||||||
|
sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.2"
|
||||||
fake_async:
|
fake_async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: fake_async
|
name: fake_async
|
||||||
sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44"
|
sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.3"
|
version: "1.3.3"
|
||||||
|
ffi:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: ffi
|
||||||
|
sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.4"
|
||||||
|
fixnum:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: fixnum
|
||||||
|
sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.1"
|
||||||
|
fl_nodes:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: fl_nodes
|
||||||
|
sha256: "4597284f72369885e8b6bfc5221835a3a6472d9c61769b45c6c64b8f242b2b28"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.5.0+1"
|
||||||
fluent_ui:
|
fluent_ui:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: fluent_ui
|
name: fluent_ui
|
||||||
sha256: "64223237a1d873b426d578d4d8b2703b8f7d9731608a5beb7b9745194568d484"
|
sha256: "64223237a1d873b426d578d4d8b2703b8f7d9731608a5beb7b9745194568d484"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.13.0"
|
version: "4.13.0"
|
||||||
flutter:
|
flutter:
|
||||||
@@ -75,15 +123,23 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: flutter_acrylic
|
name: flutter_acrylic
|
||||||
sha256: b3996dbde5abf5823cc9ead4cf2e5267c3181f15585fe47ce4dc4472e7ec827a
|
sha256: b3996dbde5abf5823cc9ead4cf2e5267c3181f15585fe47ce4dc4472e7ec827a
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.4"
|
version: "1.1.4"
|
||||||
|
flutter_context_menu:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_context_menu
|
||||||
|
sha256: "79fe00cd7e3ac3840a552cb3e653d8eb61d827b6c04c559e219973a1dc769165"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.3.0"
|
||||||
flutter_lints:
|
flutter_lints:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: flutter_lints
|
name: flutter_lints
|
||||||
sha256: "3105dc8492f6183fb076ccf1f351ac3d60564bff92e20bfc4af9cc1651f4e7e1"
|
sha256: "3105dc8492f6183fb076ccf1f351ac3d60564bff92e20bfc4af9cc1651f4e7e1"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.0.0"
|
version: "6.0.0"
|
||||||
flutter_localizations:
|
flutter_localizations:
|
||||||
@@ -96,33 +152,105 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: flutter_markdown
|
name: flutter_markdown
|
||||||
sha256: "08fb8315236099ff8e90cb87bb2b935e0a724a3af1623000a9cec930468e0f27"
|
sha256: "08fb8315236099ff8e90cb87bb2b935e0a724a3af1623000a9cec930468e0f27"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.7.7+1"
|
version: "0.7.7+1"
|
||||||
|
flutter_shaders:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_shaders
|
||||||
|
sha256: "34794acadd8275d971e02df03afee3dee0f98dbfb8c4837082ad0034f612a3e2"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.3"
|
||||||
flutter_test:
|
flutter_test:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
flutter_web_plugins:
|
flutter_web_plugins:
|
||||||
dependency: transitive
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
|
geobase:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: geobase
|
||||||
|
sha256: "3a4e2eb17a7ab452dda78fb45ee498a3ab02469ded749a5f4a9abea21fc95919"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.5.0"
|
||||||
|
go_router:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: go_router
|
||||||
|
sha256: eff94d2a6fc79fa8b811dde79c7549808c2346037ee107a1121b4a644c745f2a
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "17.0.1"
|
||||||
|
html:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: html
|
||||||
|
sha256: "6d1264f2dffa1b1101c25a91dff0dc2daee4c18e87cd8538729773c073dbf602"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.15.6"
|
||||||
|
http:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: http
|
||||||
|
sha256: "87721a4a50b19c7f1d49001e51409bddc46303966ce89a65af4f4e6004896412"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.6.0"
|
||||||
|
http_parser:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: http_parser
|
||||||
|
sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "4.1.2"
|
||||||
|
image:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: image
|
||||||
|
sha256: "492bd52f6c4fbb6ee41f781ff27765ce5f627910e1e0cbecfa3d9add5562604c"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "4.7.2"
|
||||||
intl:
|
intl:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: intl
|
name: intl
|
||||||
sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5"
|
sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.20.2"
|
version: "0.20.2"
|
||||||
|
jni:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: jni
|
||||||
|
sha256: "8706a77e94c76fe9ec9315e18949cc9479cc03af97085ca9c1077b61323ea12d"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.15.2"
|
||||||
|
js:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: js
|
||||||
|
sha256: "53385261521cc4a0c4658fd0ad07a7d14591cf8fc33abbceae306ddb974888dc"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.7.2"
|
||||||
json_annotation:
|
json_annotation:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: json_annotation
|
name: json_annotation
|
||||||
sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1"
|
sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.9.0"
|
version: "4.9.0"
|
||||||
leak_tracker:
|
leak_tracker:
|
||||||
@@ -130,7 +258,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: leak_tracker
|
name: leak_tracker
|
||||||
sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de"
|
sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "11.0.2"
|
version: "11.0.2"
|
||||||
leak_tracker_flutter_testing:
|
leak_tracker_flutter_testing:
|
||||||
@@ -138,7 +266,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: leak_tracker_flutter_testing
|
name: leak_tracker_flutter_testing
|
||||||
sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1"
|
sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.10"
|
version: "3.0.10"
|
||||||
leak_tracker_testing:
|
leak_tracker_testing:
|
||||||
@@ -146,7 +274,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: leak_tracker_testing
|
name: leak_tracker_testing
|
||||||
sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1"
|
sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.2"
|
version: "3.0.2"
|
||||||
lints:
|
lints:
|
||||||
@@ -154,23 +282,79 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: lints
|
name: lints
|
||||||
sha256: a5e2b223cb7c9c8efdc663ef484fdd95bb243bff242ef5b13e26883547fce9a0
|
sha256: a5e2b223cb7c9c8efdc663ef484fdd95bb243bff242ef5b13e26883547fce9a0
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.0.0"
|
version: "6.0.0"
|
||||||
|
lists:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: lists
|
||||||
|
sha256: "4ca5c19ae4350de036a7e996cdd1ee39c93ac0a2b840f4915459b7d0a7d4ab27"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.1"
|
||||||
|
logging:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: logging
|
||||||
|
sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.3.0"
|
||||||
macos_window_utils:
|
macos_window_utils:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: macos_window_utils
|
name: macos_window_utils
|
||||||
sha256: d4df3501fd32ac0d2d7590cb6a8e4758337d061c8fa0db816fdd636be63a8438
|
sha256: d4df3501fd32ac0d2d7590cb6a8e4758337d061c8fa0db816fdd636be63a8438
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.9.0"
|
version: "1.9.0"
|
||||||
|
maplibre:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: maplibre
|
||||||
|
sha256: d58260f7163baa05305a8700706325b9f8715a71887091370cab28fc327ef9d7
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.3.2"
|
||||||
|
maplibre_gl:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: maplibre_gl
|
||||||
|
sha256: "5c7b1008396b2a321bada7d986ed60f9423406fbc7bd16f7ce91b385dfa054cd"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.22.0"
|
||||||
|
maplibre_gl_platform_interface:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: maplibre_gl_platform_interface
|
||||||
|
sha256: "08ee0a2d0853ea945a0ab619d52c0c714f43144145cd67478fc6880b52f37509"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.22.0"
|
||||||
|
maplibre_gl_web:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: maplibre_gl_web
|
||||||
|
sha256: "2b13d4b1955a9a54e38a718f2324e56e4983c080fc6de316f6f4b5458baacb58"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.22.0"
|
||||||
|
maplibre_ios:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: maplibre_ios
|
||||||
|
sha256: "8c2c4ebba25039f7a4001f2d369fb187b0583c805b71b695e1d3c96ee3b7ba0a"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.3.2"
|
||||||
markdown:
|
markdown:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: markdown
|
name: markdown
|
||||||
sha256: "935e23e1ff3bc02d390bad4d4be001208ee92cc217cb5b5a6c19bc14aaa318c1"
|
sha256: "935e23e1ff3bc02d390bad4d4be001208ee92cc217cb5b5a6c19bc14aaa318c1"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.3.0"
|
version: "7.3.0"
|
||||||
matcher:
|
matcher:
|
||||||
@@ -178,7 +362,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: matcher
|
name: matcher
|
||||||
sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
|
sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.12.17"
|
version: "0.12.17"
|
||||||
material_color_utilities:
|
material_color_utilities:
|
||||||
@@ -186,7 +370,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: material_color_utilities
|
name: material_color_utilities
|
||||||
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
|
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.11.1"
|
version: "0.11.1"
|
||||||
math_expressions:
|
math_expressions:
|
||||||
@@ -194,7 +378,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: math_expressions
|
name: math_expressions
|
||||||
sha256: "218dc65bed4726562bb31c53d8daa3cc824664b26fb72d77bc592757edf74ba0"
|
sha256: "218dc65bed4726562bb31c53d8daa3cc824664b26fb72d77bc592757edf74ba0"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.7.0"
|
version: "2.7.0"
|
||||||
meta:
|
meta:
|
||||||
@@ -202,23 +386,47 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: meta
|
name: meta
|
||||||
sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394"
|
sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.17.0"
|
version: "1.17.0"
|
||||||
|
mgrs_dart:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: mgrs_dart
|
||||||
|
sha256: fb89ae62f05fa0bb90f70c31fc870bcbcfd516c843fb554452ab3396f78586f7
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.0"
|
||||||
nested:
|
nested:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: nested
|
name: nested
|
||||||
sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20"
|
sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.0"
|
version: "1.0.0"
|
||||||
|
objective_c:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: objective_c
|
||||||
|
sha256: "87103d96b19be76dc34b5ef859fecae78561d49779d5480b73c23b4dec8b9ec4"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "8.1.0"
|
||||||
|
package_config:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: package_config
|
||||||
|
sha256: f096c55ebb7deb7e384101542bfba8c52696c1b56fca2eb62827989ef2353bbc
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.2.0"
|
||||||
path:
|
path:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path
|
name: path
|
||||||
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
|
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.9.1"
|
version: "1.9.1"
|
||||||
petitparser:
|
petitparser:
|
||||||
@@ -226,7 +434,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: petitparser
|
name: petitparser
|
||||||
sha256: "07c8f0b1913bcde1ff0d26e57ace2f3012ccbf2b204e070290dad3bb22797646"
|
sha256: "07c8f0b1913bcde1ff0d26e57ace2f3012ccbf2b204e070290dad3bb22797646"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.1.0"
|
version: "6.1.0"
|
||||||
plugin_platform_interface:
|
plugin_platform_interface:
|
||||||
@@ -234,23 +442,79 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: plugin_platform_interface
|
name: plugin_platform_interface
|
||||||
sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
|
sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.8"
|
version: "2.1.8"
|
||||||
|
pointer_interceptor:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: pointer_interceptor
|
||||||
|
sha256: "57210410680379aea8b1b7ed6ae0c3ad349bfd56fe845b8ea934a53344b9d523"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.10.1+2"
|
||||||
|
pointer_interceptor_ios:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: pointer_interceptor_ios
|
||||||
|
sha256: "03c5fa5896080963ab4917eeffda8d28c90f22863a496fb5ba13bc10943e40e4"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.10.1+1"
|
||||||
|
pointer_interceptor_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: pointer_interceptor_platform_interface
|
||||||
|
sha256: "0597b0560e14354baeb23f8375cd612e8bd4841bf8306ecb71fcd0bb78552506"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.10.0+1"
|
||||||
|
pointer_interceptor_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: pointer_interceptor_web
|
||||||
|
sha256: "460b600e71de6fcea2b3d5f662c92293c049c4319e27f0829310e5a953b3ee2a"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.10.3"
|
||||||
|
posix:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: posix
|
||||||
|
sha256: "6323a5b0fa688b6a010df4905a56b00181479e6d10534cecfecede2aa55add61"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "6.0.3"
|
||||||
|
proj4dart:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: proj4dart
|
||||||
|
sha256: c8a659ac9b6864aa47c171e78d41bbe6f5e1d7bd790a5814249e6b68bc44324e
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.0"
|
||||||
provider:
|
provider:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: provider
|
name: provider
|
||||||
sha256: "4e82183fa20e5ca25703ead7e05de9e4cceed1fbd1eadc1ac3cb6f565a09f272"
|
sha256: "4e82183fa20e5ca25703ead7e05de9e4cceed1fbd1eadc1ac3cb6f565a09f272"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.1.5+1"
|
version: "6.1.5+1"
|
||||||
|
pub_semver:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: pub_semver
|
||||||
|
sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.2.0"
|
||||||
recase:
|
recase:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: recase
|
name: recase
|
||||||
sha256: e4eb4ec2dcdee52dcf99cb4ceabaffc631d7424ee55e56f280bc039737f89213
|
sha256: e4eb4ec2dcdee52dcf99cb4ceabaffc631d7424ee55e56f280bc039737f89213
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.1.0"
|
version: "4.1.0"
|
||||||
screen_retriever:
|
screen_retriever:
|
||||||
@@ -258,7 +522,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: screen_retriever
|
name: screen_retriever
|
||||||
sha256: "570dbc8e4f70bac451e0efc9c9bb19fa2d6799a11e6ef04f946d7886d2e23d0c"
|
sha256: "570dbc8e4f70bac451e0efc9c9bb19fa2d6799a11e6ef04f946d7886d2e23d0c"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.2.0"
|
version: "0.2.0"
|
||||||
screen_retriever_linux:
|
screen_retriever_linux:
|
||||||
@@ -266,7 +530,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: screen_retriever_linux
|
name: screen_retriever_linux
|
||||||
sha256: f7f8120c92ef0784e58491ab664d01efda79a922b025ff286e29aa123ea3dd18
|
sha256: f7f8120c92ef0784e58491ab664d01efda79a922b025ff286e29aa123ea3dd18
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.2.0"
|
version: "0.2.0"
|
||||||
screen_retriever_macos:
|
screen_retriever_macos:
|
||||||
@@ -274,7 +538,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: screen_retriever_macos
|
name: screen_retriever_macos
|
||||||
sha256: "71f956e65c97315dd661d71f828708bd97b6d358e776f1a30d5aa7d22d78a149"
|
sha256: "71f956e65c97315dd661d71f828708bd97b6d358e776f1a30d5aa7d22d78a149"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.2.0"
|
version: "0.2.0"
|
||||||
screen_retriever_platform_interface:
|
screen_retriever_platform_interface:
|
||||||
@@ -282,7 +546,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: screen_retriever_platform_interface
|
name: screen_retriever_platform_interface
|
||||||
sha256: ee197f4581ff0d5608587819af40490748e1e39e648d7680ecf95c05197240c0
|
sha256: ee197f4581ff0d5608587819af40490748e1e39e648d7680ecf95c05197240c0
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.2.0"
|
version: "0.2.0"
|
||||||
screen_retriever_windows:
|
screen_retriever_windows:
|
||||||
@@ -290,7 +554,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: screen_retriever_windows
|
name: screen_retriever_windows
|
||||||
sha256: "449ee257f03ca98a57288ee526a301a430a344a161f9202b4fcc38576716fe13"
|
sha256: "449ee257f03ca98a57288ee526a301a430a344a161f9202b4fcc38576716fe13"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.2.0"
|
version: "0.2.0"
|
||||||
scroll_pos:
|
scroll_pos:
|
||||||
@@ -298,7 +562,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: scroll_pos
|
name: scroll_pos
|
||||||
sha256: cebf602b2dd939de6832bb902ffefb574608d1b84f420b82b381a4007d3c1e1b
|
sha256: cebf602b2dd939de6832bb902ffefb574608d1b84f420b82b381a4007d3c1e1b
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.5.0"
|
version: "0.5.0"
|
||||||
sky_engine:
|
sky_engine:
|
||||||
@@ -311,7 +575,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: source_span
|
name: source_span
|
||||||
sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c"
|
sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.10.1"
|
version: "1.10.1"
|
||||||
stack_trace:
|
stack_trace:
|
||||||
@@ -319,7 +583,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: stack_trace
|
name: stack_trace
|
||||||
sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
|
sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.12.1"
|
version: "1.12.1"
|
||||||
stream_channel:
|
stream_channel:
|
||||||
@@ -327,7 +591,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: stream_channel
|
name: stream_channel
|
||||||
sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
|
sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.4"
|
version: "2.1.4"
|
||||||
string_scanner:
|
string_scanner:
|
||||||
@@ -335,31 +599,31 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: string_scanner
|
name: string_scanner
|
||||||
sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43"
|
sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.4.1"
|
version: "1.4.1"
|
||||||
system_theme:
|
system_theme:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: system_theme
|
name: system_theme
|
||||||
sha256: "5f93485401689601d4636a695f99f7c70a30873ee68c1d95025d908a3386be7e"
|
sha256: "827cc5f94a6c3097a4c08d4f9eb11d345322f9deea5be1cb73611ff24bdf45bb"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.2"
|
version: "3.2.0"
|
||||||
system_theme_web:
|
system_theme_web:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: system_theme_web
|
name: system_theme_web
|
||||||
sha256: "900c92c5c050ce58048f241ef9a17e5cd8629808325a05b473dc62a6e99bae77"
|
sha256: a354b25ff0788ed802b48b632187d344a841b2034f16e4f6cdaa295e4a41a8aa
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.0.3"
|
version: "0.0.4"
|
||||||
term_glyph:
|
term_glyph:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: term_glyph
|
name: term_glyph
|
||||||
sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e"
|
sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.2"
|
version: "1.2.2"
|
||||||
test_api:
|
test_api:
|
||||||
@@ -367,15 +631,103 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: test_api
|
name: test_api
|
||||||
sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55
|
sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.7.7"
|
version: "0.7.7"
|
||||||
|
typed_data:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: typed_data
|
||||||
|
sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.4.0"
|
||||||
|
unicode:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: unicode
|
||||||
|
sha256: "0f69e46593d65245774d4f17125c6084d2c20b4e473a983f6e21b7d7762218f1"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.3.1"
|
||||||
|
url_launcher:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: url_launcher
|
||||||
|
sha256: f6a7e5c4835bb4e3026a04793a4199ca2d14c739ec378fdfe23fc8075d0439f8
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "6.3.2"
|
||||||
|
url_launcher_android:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: url_launcher_android
|
||||||
|
sha256: "767344bf3063897b5cf0db830e94f904528e6dd50a6dfaf839f0abf509009611"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "6.3.28"
|
||||||
|
url_launcher_ios:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: url_launcher_ios
|
||||||
|
sha256: cfde38aa257dae62ffe79c87fab20165dfdf6988c1d31b58ebf59b9106062aad
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "6.3.6"
|
||||||
|
url_launcher_linux:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: url_launcher_linux
|
||||||
|
sha256: d5e14138b3bc193a0f63c10a53c94b91d399df0512b1f29b94a043db7482384a
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "3.2.2"
|
||||||
|
url_launcher_macos:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: url_launcher_macos
|
||||||
|
sha256: "368adf46f71ad3c21b8f06614adb38346f193f3a59ba8fe9a2fd74133070ba18"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "3.2.5"
|
||||||
|
url_launcher_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: url_launcher_platform_interface
|
||||||
|
sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.3.2"
|
||||||
|
url_launcher_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: url_launcher_web
|
||||||
|
sha256: "4bd2b7b4dc4d4d0b94e5babfffbca8eac1a126c7f3d6ecbc1a11013faa3abba2"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.4.1"
|
||||||
|
url_launcher_windows:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: url_launcher_windows
|
||||||
|
sha256: "712c70ab1b99744ff066053cbe3e80c73332b38d46e5e945c98689b2e66fc15f"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "3.1.5"
|
||||||
|
uuid:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: uuid
|
||||||
|
sha256: a11b666489b1954e01d992f3d601b1804a33937b5a8fe677bd26b8a9f96f96e8
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "4.5.2"
|
||||||
vector_math:
|
vector_math:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: vector_math
|
name: vector_math
|
||||||
sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
|
sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.0"
|
version: "2.2.0"
|
||||||
vm_service:
|
vm_service:
|
||||||
@@ -383,7 +735,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: vm_service
|
name: vm_service
|
||||||
sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60"
|
sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "15.0.2"
|
version: "15.0.2"
|
||||||
web:
|
web:
|
||||||
@@ -391,7 +743,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: web
|
name: web
|
||||||
sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
|
sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.1"
|
version: "1.1.1"
|
||||||
window_manager:
|
window_manager:
|
||||||
@@ -399,9 +751,25 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: window_manager
|
name: window_manager
|
||||||
sha256: "732896e1416297c63c9e3fb95aea72d0355f61390263982a47fd519169dc5059"
|
sha256: "732896e1416297c63c9e3fb95aea72d0355f61390263982a47fd519169dc5059"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.4.3"
|
version: "0.4.3"
|
||||||
|
wkt_parser:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: wkt_parser
|
||||||
|
sha256: "8a555fc60de3116c00aad67891bcab20f81a958e4219cc106e3c037aa3937f13"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.0"
|
||||||
|
xml:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: xml
|
||||||
|
sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "6.5.0"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.10.0 <4.0.0"
|
dart: ">=3.10.0 <4.0.0"
|
||||||
flutter: ">=3.32.0"
|
flutter: ">=3.35.6"
|
||||||
|
|||||||
24
pubspec.yaml
24
pubspec.yaml
@@ -30,17 +30,24 @@ environment:
|
|||||||
dependencies:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
flutter_web_plugins:
|
||||||
|
sdk: flutter
|
||||||
|
go_router: ^17.0.0
|
||||||
|
http: ^1.2.2
|
||||||
|
maplibre: ^0.3.2
|
||||||
# Fluent UI
|
# Fluent UI
|
||||||
fluent_ui: ^4.9.2
|
fluent_ui: ^4.9.2
|
||||||
system_theme: ^3.1.2
|
system_theme: ^3.1.2
|
||||||
window_manager: ^0.4.3
|
window_manager: ^0.4.3
|
||||||
flutter_acrylic: ^1.1.4
|
flutter_acrylic: ^1.1.4
|
||||||
|
maplibre_gl: ^0.22.0
|
||||||
|
maplibre_gl_web: ^0.22.0
|
||||||
|
maplibre_gl_platform_interface: ^0.22.0
|
||||||
# Utilities
|
# Utilities
|
||||||
flutter_markdown: ^0.7.4+3
|
flutter_markdown: ^0.7.4+3
|
||||||
provider: ^6.1.2
|
provider: ^6.1.2
|
||||||
|
fl_nodes: ^0.5.0+1
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
@@ -64,10 +71,11 @@ flutter:
|
|||||||
uses-material-design: true
|
uses-material-design: true
|
||||||
|
|
||||||
# To add assets to your application, add an assets section, like this:
|
# To add assets to your application, add an assets section, like this:
|
||||||
# assets:
|
assets:
|
||||||
# - images/a_dot_burr.jpeg
|
- assets/config/
|
||||||
# - images/a_dot_ham.jpeg
|
- assets/style.json
|
||||||
|
- assets/osm_style.json
|
||||||
|
- assets/pmtiles_style.json
|
||||||
# An image asset can refer to one or more resolution-specific "variants", see
|
# An image asset can refer to one or more resolution-specific "variants", see
|
||||||
# https://flutter.dev/to/resolution-aware-images
|
# https://flutter.dev/to/resolution-aware-images
|
||||||
|
|
||||||
@@ -88,7 +96,7 @@ flutter:
|
|||||||
# - family: Trajan Pro
|
# - family: Trajan Pro
|
||||||
# fonts:
|
# fonts:
|
||||||
# - asset: fonts/TrajanPro.ttf
|
# - asset: fonts/TrajanPro.ttf
|
||||||
# - asset: fonts/TrajanPro_Bold.ttf
|
# - fonts/TrajanPro_Bold.ttf
|
||||||
# weight: 700
|
# weight: 700
|
||||||
#
|
#
|
||||||
# For details regarding fonts from package dependencies,
|
# For details regarding fonts from package dependencies,
|
||||||
|
|||||||
@@ -31,6 +31,11 @@
|
|||||||
|
|
||||||
<title>llm_chat</title>
|
<title>llm_chat</title>
|
||||||
<link rel="manifest" href="manifest.json">
|
<link rel="manifest" href="manifest.json">
|
||||||
|
|
||||||
|
<!-- MapLibre -->
|
||||||
|
<script src='https://unpkg.com/maplibre-gl@^5.3.0/dist/maplibre-gl.js'></script>
|
||||||
|
<link href='https://unpkg.com/maplibre-gl@^5.3.0/dist/maplibre-gl.css' rel='stylesheet'/>
|
||||||
|
<script src="https://unpkg.com/pmtiles@3.2.0/dist/pmtiles.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<script src="flutter_bootstrap.js" async></script>
|
<script src="flutter_bootstrap.js" async></script>
|
||||||
|
|||||||
@@ -7,17 +7,23 @@
|
|||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
#include <flutter_acrylic/flutter_acrylic_plugin.h>
|
#include <flutter_acrylic/flutter_acrylic_plugin.h>
|
||||||
|
#include <maplibre/maplibre_plugin_c_api.h>
|
||||||
#include <screen_retriever_windows/screen_retriever_windows_plugin_c_api.h>
|
#include <screen_retriever_windows/screen_retriever_windows_plugin_c_api.h>
|
||||||
#include <system_theme/system_theme_plugin.h>
|
#include <system_theme/system_theme_plugin.h>
|
||||||
|
#include <url_launcher_windows/url_launcher_windows.h>
|
||||||
#include <window_manager/window_manager_plugin.h>
|
#include <window_manager/window_manager_plugin.h>
|
||||||
|
|
||||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||||
FlutterAcrylicPluginRegisterWithRegistrar(
|
FlutterAcrylicPluginRegisterWithRegistrar(
|
||||||
registry->GetRegistrarForPlugin("FlutterAcrylicPlugin"));
|
registry->GetRegistrarForPlugin("FlutterAcrylicPlugin"));
|
||||||
|
MaplibrePluginCApiRegisterWithRegistrar(
|
||||||
|
registry->GetRegistrarForPlugin("MaplibrePluginCApi"));
|
||||||
ScreenRetrieverWindowsPluginCApiRegisterWithRegistrar(
|
ScreenRetrieverWindowsPluginCApiRegisterWithRegistrar(
|
||||||
registry->GetRegistrarForPlugin("ScreenRetrieverWindowsPluginCApi"));
|
registry->GetRegistrarForPlugin("ScreenRetrieverWindowsPluginCApi"));
|
||||||
SystemThemePluginRegisterWithRegistrar(
|
SystemThemePluginRegisterWithRegistrar(
|
||||||
registry->GetRegistrarForPlugin("SystemThemePlugin"));
|
registry->GetRegistrarForPlugin("SystemThemePlugin"));
|
||||||
|
UrlLauncherWindowsRegisterWithRegistrar(
|
||||||
|
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
|
||||||
WindowManagerPluginRegisterWithRegistrar(
|
WindowManagerPluginRegisterWithRegistrar(
|
||||||
registry->GetRegistrarForPlugin("WindowManagerPlugin"));
|
registry->GetRegistrarForPlugin("WindowManagerPlugin"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,12 +4,15 @@
|
|||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
flutter_acrylic
|
flutter_acrylic
|
||||||
|
maplibre
|
||||||
screen_retriever_windows
|
screen_retriever_windows
|
||||||
system_theme
|
system_theme
|
||||||
|
url_launcher_windows
|
||||||
window_manager
|
window_manager
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||||
|
jni
|
||||||
)
|
)
|
||||||
|
|
||||||
set(PLUGIN_BUNDLED_LIBRARIES)
|
set(PLUGIN_BUNDLED_LIBRARIES)
|
||||||
|
|||||||
Reference in New Issue
Block a user