Browse Source

Added adding subcomponents

master
Kenneth Bruen 2 years ago
parent
commit
9e5cf4f92f
Signed by: kbruen
GPG Key ID: C1980A470C3EE5B1
  1. 6
      lib/components/visual_component.dart
  2. 71
      lib/pages/design_component.dart
  3. 34
      lib/state/component.dart
  4. 4
      lib/state/project.dart
  5. 3
      lib/state/projects.dart

6
lib/components/visual_component.dart

@ -140,7 +140,7 @@ class VisualComponent extends HookWidget {
} }
static double getHeightOfIO(BuildContext context, List<String> options, int index, [TextStyle? textStyle]) { static double getHeightOfIO(BuildContext context, List<String> options, int index, [TextStyle? textStyle]) {
assert(index < options.length); assert(index <= options.length);
getHeightOfText(String text) { getHeightOfText(String text) {
final textPainter = TextPainter( final textPainter = TextPainter(
text: TextSpan( text: TextSpan(
@ -163,7 +163,9 @@ class VisualComponent extends HookWidget {
for (var i = 0; i < index; i++) { for (var i = 0; i < index; i++) {
result += 5.0 + getHeightOfText(options[i]) + 5.0; result += 5.0 + getHeightOfText(options[i]) + 5.0;
} }
result += 5.0 + getHeightOfText(options[index]); if (index < options.length) {
result += 5.0 + getHeightOfText(options[index]);
}
return result; return result;
} }
} }

71
lib/pages/design_component.dart

@ -12,7 +12,9 @@ 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';
import 'package:logic_circuits_simulator/utils/stack_canvas_controller_hook.dart'; import 'package:logic_circuits_simulator/utils/stack_canvas_controller_hook.dart';
import 'package:provider/provider.dart';
import 'package:stack_canvas/stack_canvas.dart'; import 'package:stack_canvas/stack_canvas.dart';
import 'package:tuple/tuple.dart';
import 'package:uuid/uuid.dart'; import 'package:uuid/uuid.dart';
Key canvasKey = GlobalKey(); Key canvasKey = GlobalKey();
@ -56,6 +58,9 @@ class DesignComponentPage extends HookWidget {
final cs = componentState; final cs = componentState;
// First remove all connected wires // First remove all connected wires
if (w is DesignComponent) { if (w is DesignComponent) {
// Get project state to be able to remove dependency
final projectState = Provider.of<ProjectState>(context, listen: false);
final wires = cs.wiringDraft.wires final wires = cs.wiringDraft.wires
.where( .where(
(wire) => wire.input.startsWith('${w.instanceId}/') || wire.output.startsWith('${w.instanceId}/') (wire) => wire.input.startsWith('${w.instanceId}/') || wire.output.startsWith('${w.instanceId}/')
@ -63,6 +68,9 @@ class DesignComponentPage extends HookWidget {
.map((wire) => wire.wireId) .map((wire) => wire.wireId)
.toList(); .toList();
// Get component id before removing
final componentId = cs.wiringDraft.instances.where((inst) => inst.instanceId == w.instanceId).first.componentId;
await cs.updateDesign(cs.designDraft.copyWith( await cs.updateDesign(cs.designDraft.copyWith(
wires: cs.designDraft.wires wires: cs.designDraft.wires
.where((wire) => !wires.contains(wire.wireId)) .where((wire) => !wires.contains(wire.wireId))
@ -83,6 +91,12 @@ class DesignComponentPage extends HookWidget {
.where((comp) => comp.instanceId != w.instanceId) .where((comp) => comp.instanceId != w.instanceId)
.toList(), .toList(),
)); ));
// Remove dependency if it's the last of its kind
if (!cs.wiringDraft.instances.map((inst) => inst.componentId).contains(componentId)) {
componentState.removeDependency(componentId, modifyCurrentComponent: true);
await projectState.editComponent(componentState.currentComponent!);
}
} }
else if (w is DesignInput) { else if (w is DesignInput) {
final wires = cs.wiringDraft.wires final wires = cs.wiringDraft.wires
@ -534,7 +548,7 @@ class DesignComponentPage extends HookWidget {
hw(update.delta.dx, update.delta.dy); hw(update.delta.dx, update.delta.dy);
} }
}, },
onTapUp: (update) { onTapUp: (update) async {
final canvasCenterLocation = canvasController.canvasSize / 2; final canvasCenterLocation = canvasController.canvasSize / 2;
final canvasCenterLocationOffset = Offset(canvasCenterLocation.width, canvasCenterLocation.height); final canvasCenterLocationOffset = Offset(canvasCenterLocation.width, canvasCenterLocation.height);
final canvasLocation = update.localPosition - canvasCenterLocationOffset + canvasController.offset; final canvasLocation = update.localPosition - canvasCenterLocationOffset + canvasController.offset;
@ -603,7 +617,62 @@ class DesignComponentPage extends HookWidget {
designSelection.value = null; designSelection.value = null;
} }
else { else {
final currentProjectState = Provider.of<ProjectState>(context, listen: false);
// Add subcomponent // Add subcomponent
final splitted = ds.split('/');
var projectId = splitted[0];
final componentId = splitted[1];
if (Provider.of<ProjectState>(context, listen: false).currentProject!.projectId == projectId) {
projectId = 'self';
}
final depId = '$projectId/$componentId';
final project = projectId == 'self'
? Provider.of<ProjectState>(context, listen: false).currentProject!
: Provider.of<ProjectsState>(context, listen: false).index.projects.where((p) => p.projectId == projectId).first;
final projectState = ProjectState();
await projectState.setCurrentProject(project);
final component = projectState.index.components.where((c) => c.componentId == componentId).first;
// Add dependency
if (!componentState.hasDependency(depId)) {
componentState.addDependency(
depId,
Tuple2(
project,
component,
),
modifyCurrentComponent: true,
);
await currentProjectState.editComponent(componentState.currentComponent!);
}
// Create component instance
final instanceId = const Uuid().v4();
await componentState.updateWiring(componentState.wiringDraft.copyWith(
instances: componentState.wiringDraft.instances + [
WiringInstance(
componentId: depId,
instanceId: instanceId,
),
],
));
await componentState.updateDesign(componentState.designDraft.copyWith(
components: componentState.designDraft.components + [
DesignComponent(
instanceId: instanceId,
x: canvasLocation.dx,
y: canvasLocation.dy,
),
],
));
// Recreate simulation with new subcomponent
await componentState.recreatePartialSimulation();
designSelection.value = null;
} }
}, },
child: Stack( child: Stack(

34
lib/state/component.dart

@ -115,7 +115,7 @@ class ComponentState extends ChangeNotifier {
unsatisfiedDependencies.add(depId); unsatisfiedDependencies.add(depId);
} }
else { else {
_dependenciesMap[depId] = maybeDep; addDependency(depId, maybeDep);
} }
} }
if (unsatisfiedDependencies.isNotEmpty) { if (unsatisfiedDependencies.isNotEmpty) {
@ -124,10 +124,34 @@ class ComponentState extends ChangeNotifier {
await _loadComponentFiles(); await _loadComponentFiles();
if (component.visualDesigned) { await recreatePartialSimulation();
notifyListeners();
}
void addDependency(String depId, Tuple2<ProjectEntry, ComponentEntry> dependency, {bool modifyCurrentComponent = false}) {
_dependenciesMap[depId] = dependency;
if (modifyCurrentComponent && _currentComponent?.dependencies.contains(depId) == false) {
_currentComponent = _currentComponent?.copyWith(
dependencies: (_currentComponent?.dependencies ?? []) + [depId],
);
}
}
void removeDependency(String depId, {bool modifyCurrentComponent = false}) {
_dependenciesMap.remove(depId);
if (modifyCurrentComponent && _currentComponent?.dependencies.contains(depId) == true) {
_currentComponent = _currentComponent?.copyWith(
dependencies: _currentComponent?.dependencies.where((dep) => dep != depId).toList() ?? [],
);
}
}
Future<void> recreatePartialSimulation() async {
if (_currentComponent!.visualDesigned) {
_partialVisualSimulation = await PartialVisualSimulation.init( _partialVisualSimulation = await PartialVisualSimulation.init(
project: project, project: _currentProject!,
component: component, component: _currentComponent!,
state: this, state: this,
onRequiredDependency: _onRequiredDependency, onRequiredDependency: _onRequiredDependency,
); );
@ -136,6 +160,8 @@ class ComponentState extends ChangeNotifier {
notifyListeners(); notifyListeners();
} }
bool hasDependency(String depId) => _dependenciesMap.containsKey(depId);
void noComponent() { void noComponent() {
_dependenciesMap.clear(); _dependenciesMap.clear();
_currentProject = null; _currentProject = null;

4
lib/state/project.dart

@ -90,8 +90,8 @@ class ProjectState extends ChangeNotifier {
await _updateIndex( await _updateIndex(
index.copyWith( index.copyWith(
components: index.components components: index.components
.where((c) => c.componentId != component.componentId) .map((c) => c.componentId == component.componentId ? component : c)
.toList() + [component], .toList(),
) )
); );
} }

3
lib/state/projects.dart

@ -73,8 +73,7 @@ class ProjectsState extends ChangeNotifier {
await _updateIndex( await _updateIndex(
index.copyWith( index.copyWith(
projects: index.projects projects: index.projects
.where((p) => p.projectId != project.projectId) .map((p) => p.projectId == project.projectId ? project : p)
.followedBy([project])
.toList() .toList()
) )
); );

Loading…
Cancel
Save