mirror of
https://github.com/dancojocaru2000/logic-circuits-simulator.git
synced 2025-02-21 16:49:36 +02:00
Separate truth table to file, add column borders
This commit is contained in:
parent
ba6cc9489c
commit
c002e70616
2 changed files with 184 additions and 152 deletions
183
lib/components/truth_table.dart
Normal file
183
lib/components/truth_table.dart
Normal file
|
@ -0,0 +1,183 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:logic_circuits_simulator/utils/iterable_extension.dart';
|
||||||
|
|
||||||
|
class TruthTableHeaderText extends StatelessWidget {
|
||||||
|
final String text;
|
||||||
|
final BoxBorder? border;
|
||||||
|
|
||||||
|
const TruthTableHeaderText(this.text, {super.key, this.border});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: border,
|
||||||
|
),
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 8,
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
text,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: Theme.of(context).textTheme.bodyLarge!.copyWith(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontSize: 24,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TruthTableTrue extends StatelessWidget {
|
||||||
|
final BoxBorder? border;
|
||||||
|
final void Function()? onTap;
|
||||||
|
|
||||||
|
const TruthTableTrue({super.key, this.border, this.onTap});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: border,
|
||||||
|
),
|
||||||
|
child: InkWell(
|
||||||
|
onTap: onTap,
|
||||||
|
child: Text(
|
||||||
|
'T',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: Theme.of(context).textTheme.bodyLarge!.copyWith(
|
||||||
|
color: Colors.green,
|
||||||
|
fontSize: 20,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TruthTableFalse extends StatelessWidget {
|
||||||
|
final BoxBorder? border;
|
||||||
|
final void Function()? onTap;
|
||||||
|
|
||||||
|
const TruthTableFalse({super.key, this.border, this.onTap});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: border,
|
||||||
|
),
|
||||||
|
child: InkWell(
|
||||||
|
onTap: onTap,
|
||||||
|
child: Text(
|
||||||
|
'F',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: Theme.of(context).textTheme.bodyLarge!.copyWith(
|
||||||
|
color: Colors.red,
|
||||||
|
fontSize: 20,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TruthTableEditor extends StatelessWidget {
|
||||||
|
static const marginBorder = BorderSide(
|
||||||
|
color: Colors.black,
|
||||||
|
width: 2,
|
||||||
|
);
|
||||||
|
static const innerBorder = BorderSide(
|
||||||
|
color: Colors.black45,
|
||||||
|
width: 1,
|
||||||
|
);
|
||||||
|
|
||||||
|
final List<String> inputs;
|
||||||
|
final List<String> outputs;
|
||||||
|
final List<String> truthTable;
|
||||||
|
|
||||||
|
final void Function(int, String)? onUpdateTable;
|
||||||
|
|
||||||
|
const TruthTableEditor({Key? key, required this.inputs, required this.outputs, required this.truthTable, required this.onUpdateTable}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Table(
|
||||||
|
defaultColumnWidth: const IntrinsicColumnWidth(),
|
||||||
|
border: TableBorder.symmetric(outside: const BorderSide(width: 2)),
|
||||||
|
children: List.generate(
|
||||||
|
truthTable.length + 1,
|
||||||
|
(index) {
|
||||||
|
if (index == 0) {
|
||||||
|
return TableRow(
|
||||||
|
children: inputs
|
||||||
|
.indexedMap<Widget>(
|
||||||
|
(index, e) => TruthTableHeaderText(
|
||||||
|
e,
|
||||||
|
border: Border(
|
||||||
|
bottom: marginBorder,
|
||||||
|
right: index == inputs.length - 1
|
||||||
|
? marginBorder
|
||||||
|
: innerBorder,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.followedBy(
|
||||||
|
outputs
|
||||||
|
.indexedMap(
|
||||||
|
(index, e) => TruthTableHeaderText(
|
||||||
|
e,
|
||||||
|
border: Border(
|
||||||
|
bottom: const BorderSide(width: 2),
|
||||||
|
right: index == outputs.length - 1
|
||||||
|
? BorderSide.none
|
||||||
|
: innerBorder,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
final inputBinary = (index - 1).toRadixString(2).padLeft(inputs.length, '0');
|
||||||
|
final outputBinary = truthTable[index - 1];
|
||||||
|
|
||||||
|
Widget runeToWidget({required int rune, void Function()? onTap, BoxBorder? border}) {
|
||||||
|
return int.parse(String.fromCharCode(rune)) != 0
|
||||||
|
? TruthTableTrue(
|
||||||
|
border: border,
|
||||||
|
onTap: onTap,
|
||||||
|
)
|
||||||
|
: TruthTableFalse(
|
||||||
|
border: border,
|
||||||
|
onTap: onTap,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TableRow(
|
||||||
|
children: inputBinary.runes.indexedMap(
|
||||||
|
(i, r) => runeToWidget(
|
||||||
|
rune: r,
|
||||||
|
border: i == inputBinary.runes.length - 1
|
||||||
|
? const Border(right: marginBorder)
|
||||||
|
: const Border(right: innerBorder),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.followedBy(outputBinary.runes.indexedMap(
|
||||||
|
(i, r) => runeToWidget(
|
||||||
|
rune: r,
|
||||||
|
border: i == outputBinary.runes.length - 1
|
||||||
|
? null
|
||||||
|
: const Border(right: innerBorder),
|
||||||
|
onTap: onUpdateTable == null ? null : () {
|
||||||
|
onUpdateTable!(index - 1, outputBinary.replaceRange(i, i+1, (outputBinary[i] == "1") ? "0" : "1"));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
))
|
||||||
|
.toList(),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ import 'dart:math';
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
|
import 'package:logic_circuits_simulator/components/truth_table.dart';
|
||||||
import 'package:logic_circuits_simulator/dialogs/new_ask_for_name.dart';
|
import 'package:logic_circuits_simulator/dialogs/new_ask_for_name.dart';
|
||||||
import 'package:logic_circuits_simulator/models/project.dart';
|
import 'package:logic_circuits_simulator/models/project.dart';
|
||||||
import 'package:logic_circuits_simulator/state/project.dart';
|
import 'package:logic_circuits_simulator/state/project.dart';
|
||||||
|
@ -398,155 +399,3 @@ class EditComponentPage extends HookWidget {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TruthTableHeaderText extends StatelessWidget {
|
|
||||||
final String text;
|
|
||||||
final BoxBorder? border;
|
|
||||||
|
|
||||||
const TruthTableHeaderText(this.text, {super.key, this.border});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Container(
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
border: border,
|
|
||||||
),
|
|
||||||
child: Text(
|
|
||||||
text,
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: Theme.of(context).textTheme.bodyLarge!.copyWith(
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
fontSize: 24,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class TruthTableTrue extends StatelessWidget {
|
|
||||||
final BoxBorder? border;
|
|
||||||
final void Function()? onTap;
|
|
||||||
|
|
||||||
const TruthTableTrue({super.key, this.border, this.onTap});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Container(
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
border: border,
|
|
||||||
),
|
|
||||||
child: InkWell(
|
|
||||||
onTap: onTap,
|
|
||||||
child: Text(
|
|
||||||
'T',
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: Theme.of(context).textTheme.bodyLarge!.copyWith(
|
|
||||||
color: Colors.green,
|
|
||||||
fontSize: 20,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class TruthTableFalse extends StatelessWidget {
|
|
||||||
final BoxBorder? border;
|
|
||||||
final void Function()? onTap;
|
|
||||||
|
|
||||||
const TruthTableFalse({super.key, this.border, this.onTap});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Container(
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
border: border,
|
|
||||||
),
|
|
||||||
child: InkWell(
|
|
||||||
onTap: onTap,
|
|
||||||
child: Text(
|
|
||||||
'F',
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: Theme.of(context).textTheme.bodyLarge!.copyWith(
|
|
||||||
color: Colors.red,
|
|
||||||
fontSize: 20,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class TruthTableEditor extends StatelessWidget {
|
|
||||||
final List<String> inputs;
|
|
||||||
final List<String> outputs;
|
|
||||||
final List<String> truthTable;
|
|
||||||
|
|
||||||
final void Function(int, String) onUpdateTable;
|
|
||||||
|
|
||||||
const TruthTableEditor({Key? key, required this.inputs, required this.outputs, required this.truthTable, required this.onUpdateTable}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Table(
|
|
||||||
defaultColumnWidth: const IntrinsicColumnWidth(),
|
|
||||||
border: TableBorder.symmetric(outside: const BorderSide(width: 2)),
|
|
||||||
children: List.generate(
|
|
||||||
truthTable.length + 1,
|
|
||||||
(index) {
|
|
||||||
if (index == 0) {
|
|
||||||
return TableRow(
|
|
||||||
children: inputs
|
|
||||||
.indexedMap<Widget>(
|
|
||||||
(index, e) => TruthTableHeaderText(
|
|
||||||
e,
|
|
||||||
border: Border(
|
|
||||||
bottom: const BorderSide(width: 2),
|
|
||||||
right: index == inputs.length - 1 ? const BorderSide(width: 2) : BorderSide.none,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.followedBy(
|
|
||||||
outputs
|
|
||||||
.map((e) => TruthTableHeaderText(e, border: const Border(bottom: BorderSide(width: 2)),))
|
|
||||||
)
|
|
||||||
.toList(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
final inputBinary = (index - 1).toRadixString(2).padLeft(inputs.length, '0');
|
|
||||||
final outputBinary = truthTable[index - 1];
|
|
||||||
|
|
||||||
Widget runeToWidget({required int rune, void Function()? onTap, BoxBorder? border}) {
|
|
||||||
return int.parse(String.fromCharCode(rune)) != 0
|
|
||||||
? TruthTableTrue(
|
|
||||||
border: border,
|
|
||||||
onTap: onTap,
|
|
||||||
)
|
|
||||||
: TruthTableFalse(
|
|
||||||
border: border,
|
|
||||||
onTap: onTap,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return TableRow(
|
|
||||||
children: inputBinary.runes.indexedMap(
|
|
||||||
(i, r) => runeToWidget(
|
|
||||||
rune: r,
|
|
||||||
border: i == inputBinary.runes.length - 1 ? const Border(right: BorderSide(width: 2)) : null,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.followedBy(outputBinary.runes.indexedMap(
|
|
||||||
(i, r) => runeToWidget(
|
|
||||||
rune: r,
|
|
||||||
onTap: () {
|
|
||||||
onUpdateTable(index - 1, outputBinary.replaceRange(i, i+1, (outputBinary[i] == "1") ? "0" : "1"));
|
|
||||||
},
|
|
||||||
),
|
|
||||||
))
|
|
||||||
.toList(),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue