mirror of
https://github.com/dancojocaru2000/logic-circuits-simulator.git
synced 2025-02-22 17:19:36 +02:00
Implemented component picker
This commit is contained in:
parent
8abd6b3ca8
commit
e74c2f58ed
4 changed files with 348 additions and 83 deletions
|
@ -154,7 +154,9 @@ class IOComponent extends HookWidget {
|
||||||
onEnter: (event) => hovered.value = true,
|
onEnter: (event) => hovered.value = true,
|
||||||
onExit: (event) => hovered.value = false,
|
onExit: (event) => hovered.value = false,
|
||||||
hitTestBehavior: HitTestBehavior.translucent,
|
hitTestBehavior: HitTestBehavior.translucent,
|
||||||
|
opaque: false,
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
|
behavior: HitTestBehavior.translucent,
|
||||||
onTap: onTap,
|
onTap: onTap,
|
||||||
child: Builder(
|
child: Builder(
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
|
|
|
@ -6,6 +6,8 @@ import 'package:logic_circuits_simulator/components/visual_component.dart';
|
||||||
import 'package:logic_circuits_simulator/models.dart';
|
import 'package:logic_circuits_simulator/models.dart';
|
||||||
import 'package:logic_circuits_simulator/pages_arguments/design_component.dart';
|
import 'package:logic_circuits_simulator/pages_arguments/design_component.dart';
|
||||||
import 'package:logic_circuits_simulator/state/component.dart';
|
import 'package:logic_circuits_simulator/state/component.dart';
|
||||||
|
import 'package:logic_circuits_simulator/state/project.dart';
|
||||||
|
import 'package:logic_circuits_simulator/state/projects.dart';
|
||||||
import 'package:logic_circuits_simulator/utils/future_call_debounce.dart';
|
import 'package:logic_circuits_simulator/utils/future_call_debounce.dart';
|
||||||
import 'package:logic_circuits_simulator/utils/iterable_extension.dart';
|
import 'package:logic_circuits_simulator/utils/iterable_extension.dart';
|
||||||
import 'package:logic_circuits_simulator/utils/provider_hook.dart';
|
import 'package:logic_circuits_simulator/utils/provider_hook.dart';
|
||||||
|
@ -13,6 +15,7 @@ import 'package:logic_circuits_simulator/utils/stack_canvas_controller_hook.dart
|
||||||
import 'package:stack_canvas/stack_canvas.dart';
|
import 'package:stack_canvas/stack_canvas.dart';
|
||||||
|
|
||||||
Key canvasKey = GlobalKey();
|
Key canvasKey = GlobalKey();
|
||||||
|
Key pickerKey = GlobalKey();
|
||||||
|
|
||||||
class DesignComponentPage extends HookWidget {
|
class DesignComponentPage extends HookWidget {
|
||||||
final ComponentEntry component;
|
final ComponentEntry component;
|
||||||
|
@ -38,6 +41,10 @@ class DesignComponentPage extends HookWidget {
|
||||||
|
|
||||||
final movingWidgetUpdater = useState<void Function(double dx, double dy)?>(null);
|
final movingWidgetUpdater = useState<void Function(double dx, double dy)?>(null);
|
||||||
final movingWidget = useState<dynamic>(null);
|
final movingWidget = useState<dynamic>(null);
|
||||||
|
final deleteOnDrop = useState<bool>(false);
|
||||||
|
final designSelection = useState<String?>(null);
|
||||||
|
final wireToDelete = useState<String?>(null);
|
||||||
|
|
||||||
final widgets = useMemoized(() => [
|
final widgets = useMemoized(() => [
|
||||||
for (final subcomponent in componentState.designDraft.components)
|
for (final subcomponent in componentState.designDraft.components)
|
||||||
CanvasObject(
|
CanvasObject(
|
||||||
|
@ -90,6 +97,8 @@ class DesignComponentPage extends HookWidget {
|
||||||
movingWidget.value = null;
|
movingWidget.value = null;
|
||||||
},
|
},
|
||||||
child: MouseRegion(
|
child: MouseRegion(
|
||||||
|
opaque: false,
|
||||||
|
hitTestBehavior: HitTestBehavior.translucent,
|
||||||
cursor: movingWidget.value == subcomponent ? SystemMouseCursors.move : MouseCursor.defer,
|
cursor: movingWidget.value == subcomponent ? SystemMouseCursors.move : MouseCursor.defer,
|
||||||
child: VisualComponent(
|
child: VisualComponent(
|
||||||
name: componentState.getMetaByInstance(subcomponent.instanceId).item2.componentName,
|
name: componentState.getMetaByInstance(subcomponent.instanceId).item2.componentName,
|
||||||
|
@ -141,10 +150,12 @@ class DesignComponentPage extends HookWidget {
|
||||||
movingWidgetUpdater.value = (dx, dy) {
|
movingWidgetUpdater.value = (dx, dy) {
|
||||||
debouncer.call([dx, dy]);
|
debouncer.call([dx, dy]);
|
||||||
};
|
};
|
||||||
|
movingWidget.value = input;
|
||||||
},
|
},
|
||||||
onPointerUp: (event) {
|
onPointerUp: (event) {
|
||||||
componentState.updateDesign(componentState.designDraft);
|
componentState.updateDesign(componentState.designDraft);
|
||||||
movingWidgetUpdater.value = null;
|
movingWidgetUpdater.value = null;
|
||||||
|
movingWidget.value = null;
|
||||||
},
|
},
|
||||||
child: IOComponent(
|
child: IOComponent(
|
||||||
input: true,
|
input: true,
|
||||||
|
@ -190,10 +201,12 @@ class DesignComponentPage extends HookWidget {
|
||||||
movingWidgetUpdater.value = (dx, dy) {
|
movingWidgetUpdater.value = (dx, dy) {
|
||||||
debouncer.call([dx, dy]);
|
debouncer.call([dx, dy]);
|
||||||
};
|
};
|
||||||
|
movingWidget.value = output;
|
||||||
},
|
},
|
||||||
onPointerUp: (event) {
|
onPointerUp: (event) {
|
||||||
componentState.updateDesign(componentState.designDraft);
|
componentState.updateDesign(componentState.designDraft);
|
||||||
movingWidgetUpdater.value = null;
|
movingWidgetUpdater.value = null;
|
||||||
|
movingWidget.value = null;
|
||||||
},
|
},
|
||||||
child: IOComponent(
|
child: IOComponent(
|
||||||
input: false,
|
input: false,
|
||||||
|
@ -310,11 +323,41 @@ class DesignComponentPage extends HookWidget {
|
||||||
dy: min(from.dy, to.dy),
|
dy: min(from.dy, to.dy),
|
||||||
width: (to - from).dx.abs(),
|
width: (to - from).dx.abs(),
|
||||||
height: (to - from).dy.abs(),
|
height: (to - from).dy.abs(),
|
||||||
child: IgnorePointer(
|
child: MouseRegion(
|
||||||
child: WireWidget(
|
hitTestBehavior: HitTestBehavior.translucent,
|
||||||
from: from,
|
opaque: false,
|
||||||
to: to,
|
onEnter: (_) {
|
||||||
color: wireColor,
|
if (designSelection.value == 'wiring') {
|
||||||
|
wireToDelete.value = wire.wireId;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onExit: (_) {
|
||||||
|
wireToDelete.value = null;
|
||||||
|
},
|
||||||
|
child: GestureDetector(
|
||||||
|
behavior: HitTestBehavior.translucent,
|
||||||
|
onTap: () async {
|
||||||
|
if (designSelection.value == 'wiring') {
|
||||||
|
if (wireToDelete.value != wire.wireId) {
|
||||||
|
wireToDelete.value = wire.wireId;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Delete the wire
|
||||||
|
await componentState.updateDesign(componentState.designDraft.copyWith(
|
||||||
|
wires: componentState.designDraft.wires.where((w) => w.wireId != wireToDelete.value).toList(),
|
||||||
|
));
|
||||||
|
await componentState.updateWiring(componentState.wiringDraft.copyWith(
|
||||||
|
wires: componentState.wiringDraft.wires.where((w) => w.wireId != wireToDelete.value).toList(),
|
||||||
|
));
|
||||||
|
wireToDelete.value = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: WireWidget(
|
||||||
|
from: from,
|
||||||
|
to: to,
|
||||||
|
color: wireToDelete.value == wire.wireId ? Colors.red : wireColor,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -344,95 +387,136 @@ class DesignComponentPage extends HookWidget {
|
||||||
title: Text('${isSimulating.value ? 'Simulation' : 'Design'} - ${component.componentName}'),
|
title: Text('${isSimulating.value ? 'Simulation' : 'Design'} - ${component.componentName}'),
|
||||||
actions: [
|
actions: [
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: Icon(isSimulating.value ? Icons.stop : Icons.start),
|
icon: Icon(isSimulating.value ? Icons.stop : Icons.play_arrow),
|
||||||
tooltip: isSimulating.value ? 'Stop Simulation' : 'Start Simulation',
|
tooltip: isSimulating.value ? 'Stop Simulation' : 'Start Simulation',
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
isSimulating.value = !isSimulating.value;
|
isSimulating.value = !isSimulating.value;
|
||||||
|
designSelection.value = null;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
body: GestureDetector(
|
body: OrientationBuilder(
|
||||||
onPanUpdate: (update) {
|
builder: (context, orientation) {
|
||||||
final hw = movingWidgetUpdater.value;
|
final stackCanvas = GestureDetector(
|
||||||
if (hw == null || isSimulating.value) {
|
behavior: HitTestBehavior.translucent,
|
||||||
canvasController.offset = canvasController.offset.translate(update.delta.dx, update.delta.dy);
|
onPanUpdate: (update) {
|
||||||
|
final hw = movingWidgetUpdater.value;
|
||||||
|
if (hw == null || isSimulating.value) {
|
||||||
|
canvasController.offset = canvasController.offset.translate(update.delta.dx, update.delta.dy);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
hw(update.delta.dx, update.delta.dy);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
StackCanvas(
|
||||||
|
key: canvasKey,
|
||||||
|
canvasController: canvasController,
|
||||||
|
animationDuration: const Duration(milliseconds: 50),
|
||||||
|
// disposeController: false,
|
||||||
|
backgroundColor: Theme.of(context).colorScheme.background,
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
bottom: 0,
|
||||||
|
right: 0,
|
||||||
|
child: MouseRegion(
|
||||||
|
hitTestBehavior: HitTestBehavior.translucent,
|
||||||
|
opaque: false,
|
||||||
|
onEnter: (_) {
|
||||||
|
deleteOnDrop.value = true;
|
||||||
|
},
|
||||||
|
onExit: (_) {
|
||||||
|
deleteOnDrop.value = false;
|
||||||
|
},
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(16.0),
|
||||||
|
child: Icon(
|
||||||
|
Icons.delete,
|
||||||
|
color: movingWidget.value != null && deleteOnDrop.value ? Colors.red : null,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
final debuggingButtons = DebuggingButtons(
|
||||||
|
partialSimulation: simulatePartially.value,
|
||||||
|
onPartialSimulationToggle: () {
|
||||||
|
simulatePartially.value = !simulatePartially.value;
|
||||||
|
},
|
||||||
|
onReset: simulatePartially.value ? () {
|
||||||
|
componentState.partialVisualSimulation!.restart();
|
||||||
|
} : null,
|
||||||
|
onNextStep: simulatePartially.value && componentState.partialVisualSimulation!.nextToSimulate.isNotEmpty ? () {
|
||||||
|
componentState.partialVisualSimulation!.nextStep();
|
||||||
|
} : null,
|
||||||
|
);
|
||||||
|
|
||||||
|
final componentPicker = ComponentPicker(
|
||||||
|
key: pickerKey,
|
||||||
|
onSeletionUpdate: (selection) {
|
||||||
|
designSelection.value = selection;
|
||||||
|
if (selection != 'wiring') {
|
||||||
|
wireToDelete.value = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (orientation == Orientation.portrait) {
|
||||||
|
return Column(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
stackCanvas,
|
||||||
|
if (isSimulating.value)
|
||||||
|
Positioned(
|
||||||
|
top: 8,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
child: Center(
|
||||||
|
child: debuggingButtons,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (!isSimulating.value)
|
||||||
|
componentPicker,
|
||||||
|
],
|
||||||
|
);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
hw(update.delta.dx, update.delta.dy);
|
return Row(
|
||||||
}
|
mainAxisSize: MainAxisSize.max,
|
||||||
},
|
children: [
|
||||||
child: OrientationBuilder(
|
Expanded(
|
||||||
builder: (context, orientation) {
|
child: Stack(
|
||||||
final stackCanvas = StackCanvas(
|
children: [
|
||||||
key: canvasKey,
|
stackCanvas,
|
||||||
canvasController: canvasController,
|
if (isSimulating.value)
|
||||||
animationDuration: const Duration(milliseconds: 50),
|
Positioned(
|
||||||
// disposeController: false,
|
top: 8,
|
||||||
backgroundColor: Theme.of(context).colorScheme.background,
|
left: 0,
|
||||||
);
|
right: 0,
|
||||||
|
child: Center(
|
||||||
final debuggingButtons = DebuggingButtons(
|
child: debuggingButtons,
|
||||||
partialSimulation: simulatePartially.value,
|
|
||||||
onPartialSimulationToggle: () {
|
|
||||||
simulatePartially.value = !simulatePartially.value;
|
|
||||||
},
|
|
||||||
onReset: simulatePartially.value ? () {
|
|
||||||
componentState.partialVisualSimulation!.restart();
|
|
||||||
} : null,
|
|
||||||
onNextStep: simulatePartially.value && componentState.partialVisualSimulation!.nextToSimulate.isNotEmpty ? () {
|
|
||||||
componentState.partialVisualSimulation!.nextStep();
|
|
||||||
} : null,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (orientation == Orientation.portrait) {
|
|
||||||
return Column(
|
|
||||||
mainAxisSize: MainAxisSize.max,
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: Stack(
|
|
||||||
children: [
|
|
||||||
stackCanvas,
|
|
||||||
if (isSimulating.value)
|
|
||||||
Positioned(
|
|
||||||
top: 8,
|
|
||||||
left: 0,
|
|
||||||
right: 0,
|
|
||||||
child: Center(
|
|
||||||
child: debuggingButtons,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
],
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
);
|
if (!isSimulating.value)
|
||||||
}
|
componentPicker,
|
||||||
else {
|
],
|
||||||
return Row(
|
);
|
||||||
mainAxisSize: MainAxisSize.max,
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: Stack(
|
|
||||||
children: [
|
|
||||||
stackCanvas,
|
|
||||||
if (isSimulating.value)
|
|
||||||
Positioned(
|
|
||||||
top: 8,
|
|
||||||
left: 0,
|
|
||||||
right: 0,
|
|
||||||
child: Center(
|
|
||||||
child: debuggingButtons,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
),
|
}
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -478,3 +562,167 @@ class DebuggingButtons extends StatelessWidget {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ComponentPicker extends HookWidget {
|
||||||
|
const ComponentPicker({required this.onSeletionUpdate, super.key});
|
||||||
|
|
||||||
|
final void Function(String? selection) onSeletionUpdate;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final projectsState = useProvider<ProjectsState>();
|
||||||
|
final tickerProvider = useSingleTickerProvider();
|
||||||
|
final selection = useState<String?>(null);
|
||||||
|
final tabBarControllerState = useState<TabController?>(null );
|
||||||
|
useEffect(() {
|
||||||
|
selection.addListener(() {
|
||||||
|
onSeletionUpdate(selection.value);
|
||||||
|
});
|
||||||
|
|
||||||
|
tabBarControllerState.value = TabController(
|
||||||
|
length: 1 + projectsState.projects.length,
|
||||||
|
vsync: tickerProvider,
|
||||||
|
initialIndex: 1,
|
||||||
|
);
|
||||||
|
|
||||||
|
tabBarControllerState.value!.addListener(() {
|
||||||
|
if (tabBarControllerState.value!.index == 0) {
|
||||||
|
selection.value = 'wiring';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
selection.value = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return () {
|
||||||
|
tabBarControllerState.value?.dispose();
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
final tabBarController = tabBarControllerState.value!;
|
||||||
|
|
||||||
|
return OrientationBuilder(
|
||||||
|
builder: (context, orientation) {
|
||||||
|
return SizedBox(
|
||||||
|
height: orientation == Orientation.portrait ? 200 : null,
|
||||||
|
width: orientation == Orientation.landscape ? 300 : null,
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
TabBar(
|
||||||
|
controller: tabBarController,
|
||||||
|
tabs: [
|
||||||
|
const Tab(
|
||||||
|
text: 'Wiring',
|
||||||
|
),
|
||||||
|
for (final project in projectsState.projects)
|
||||||
|
Tab(
|
||||||
|
text: project.projectName,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
isScrollable: true,
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: TabBarView(
|
||||||
|
controller: tabBarController,
|
||||||
|
children: [
|
||||||
|
Center(
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: const [
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.all(8.0),
|
||||||
|
child: Text(
|
||||||
|
'To create wires, click a source and then click a sink to link them.',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.all(8.0),
|
||||||
|
child: Text(
|
||||||
|
'To remove wires, click them or tap them twice.',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
for (final project in projectsState.projects)
|
||||||
|
HookBuilder(
|
||||||
|
builder: (context) {
|
||||||
|
final scrollController = useScrollController();
|
||||||
|
|
||||||
|
final projectState = useFuture(() async {
|
||||||
|
final projectState = ProjectState();
|
||||||
|
await projectState.setCurrentProject(project);
|
||||||
|
return projectState;
|
||||||
|
}());
|
||||||
|
|
||||||
|
if (projectState.data == null) {
|
||||||
|
return Container();
|
||||||
|
}
|
||||||
|
final components = projectState.data!.index.components;
|
||||||
|
|
||||||
|
return Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
children: [
|
||||||
|
const Padding(
|
||||||
|
padding: EdgeInsets.all(8.0),
|
||||||
|
child: Text('To add a component, select it below and then click on the canvas to place it.'),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Scrollbar(
|
||||||
|
controller: scrollController,
|
||||||
|
scrollbarOrientation: orientation == Orientation.portrait ? ScrollbarOrientation.bottom : ScrollbarOrientation.right,
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
controller: scrollController,
|
||||||
|
scrollDirection: orientation == Orientation.portrait ? Axis.horizontal : Axis.vertical,
|
||||||
|
child: Wrap(
|
||||||
|
direction: orientation == Orientation.portrait ? Axis.vertical : Axis.horizontal,
|
||||||
|
crossAxisAlignment: WrapCrossAlignment.center,
|
||||||
|
children: [
|
||||||
|
for (final component in components)
|
||||||
|
IntrinsicWidth(
|
||||||
|
child: Card(
|
||||||
|
color: selection.value == '${project.projectId}/${component.componentId}' ? Theme.of(context).colorScheme.primaryContainer : null,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () {
|
||||||
|
if (selection.value != '${project.projectId}/${component.componentId}') {
|
||||||
|
selection.value = '${project.projectId}/${component.componentId}';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
selection.value = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: Text(
|
||||||
|
component.componentName,
|
||||||
|
style: selection.value == '${project.projectId}/${component.componentId}'
|
||||||
|
? TextStyle(
|
||||||
|
inherit: true,
|
||||||
|
color: Theme.of(context).colorScheme.onPrimaryContainer,
|
||||||
|
)
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
14
pubspec.lock
14
pubspec.lock
|
@ -275,6 +275,13 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.0"
|
version: "2.1.0"
|
||||||
|
hetu_script:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: hetu_script
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.3.12"
|
||||||
http_multi_server:
|
http_multi_server:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -492,6 +499,13 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.0"
|
version: "3.1.0"
|
||||||
|
recase:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: recase
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "4.0.0"
|
||||||
share_plus:
|
share_plus:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
|
@ -41,6 +41,7 @@ dependencies:
|
||||||
stack_canvas:
|
stack_canvas:
|
||||||
git: https://github.com/dancojocaru2000/stack_canvas.git
|
git: https://github.com/dancojocaru2000/stack_canvas.git
|
||||||
tuple: ^2.0.0
|
tuple: ^2.0.0
|
||||||
|
hetu_script: ^0.3.12
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|
Loading…
Add table
Reference in a new issue