diff --git a/lib/app_component.dart b/lib/app_component.dart index 8e726df..bfdd949 100644 --- a/lib/app_component.dart +++ b/lib/app_component.dart @@ -1,61 +1,17 @@ import 'package:angular/angular.dart'; - -import 'dart:html' as html; -import 'package:rules_of_living/src/Engine.dart'; +import 'package:angular_components/angular_components.dart'; +import 'package:rules_of_living/components/controls_component.dart'; +import 'package:rules_of_living/components/header_component.dart'; +import 'package:rules_of_living/components/simulation_component.dart'; +import 'package:rules_of_living/service/engine_service.dart'; @Component( selector: 'my-app', templateUrl: "app_component.html", - directives: [coreDirectives]) -class AppComponent implements OnInit { + directives: [coreDirectives, MaterialButtonComponent, MaterialIconComponent, MaterialSliderComponent, HeaderComponent, SimulationComponent, ControlsComponent], + providers: [materialProviders, ClassProvider(EngineService)], + styleUrls: const ['package:angular_components/app_layout/layout.scss.css'], +) +class AppComponent { var name = "World"; - - Engine engine; - - @ViewChild("caCanvas") - html.CanvasElement canvas; - - @override - void ngOnInit() { - canvas.context2D.setFillColorRgb(200, 0, 0); - canvas.context2D.fillRect(0, 0, canvas.width, canvas.height); - canvas.context2D.setFillColorRgb(0, 255, 0); - canvas.context2D.fillText(''' - If you see this - the app is broken :( - ''', canvas.width/2, canvas.height/2); - engine = new Engine(canvas); - - html.window.animationFrame.then(animFrame); - } - - void animFrame(num now) { - engine.process(now); - html.window.animationFrame.then(animFrame); - } - - void onStartClicked() { - engine.running = !engine.running; - } - - void onStepClicked() { - engine.step(); - } - - void onResetClicked() { - engine.reset(); - } - - void onRandomClicked() { - engine.running = false; - engine.addPattern(); - } - - void onEdgesClicked() { - engine.toggleEdgeRendering(); - } - - void onClearClicked() { - engine.clear(); - } } diff --git a/lib/app_component.html b/lib/app_component.html index 90606c7..f4dc816 100644 --- a/lib/app_component.html +++ b/lib/app_component.html @@ -1,22 +1,9 @@ -

Cellular Automata

+
Ruleset:
-
- -
-
- - - - - - Speed: - +
+ +
\ No newline at end of file diff --git a/lib/components/controls_component.css b/lib/components/controls_component.css new file mode 100644 index 0000000..580e03c --- /dev/null +++ b/lib/components/controls_component.css @@ -0,0 +1,4 @@ +material-slider { + display: inline-block; + width: 50px; +} \ No newline at end of file diff --git a/lib/components/controls_component.dart b/lib/components/controls_component.dart new file mode 100644 index 0000000..cd18105 --- /dev/null +++ b/lib/components/controls_component.dart @@ -0,0 +1,44 @@ +import 'package:angular/angular.dart'; +import 'package:angular_components/angular_components.dart'; +import 'package:rules_of_living/service/engine_service.dart'; +import 'package:rules_of_living/src/Engine.dart'; + +@Component( + selector: 'sim-controls', + templateUrl: "controls_component.html", + directives: [coreDirectives, MaterialButtonComponent, MaterialIconComponent, MaterialSliderComponent], + providers: [], + styleUrls: const ["controls_component.css"], +) +class ControlsComponent { + final EngineService engineService; + int simSpeed = 5; + + Engine get engine => engineService.engine; + ControlsComponent(this.engineService); + + void onStartClicked() { + engine.running = !engine.running; + } + + void onStepClicked() { + engine.step(); + } + + void onResetClicked() { + engine.reset(); + } + + void onRandomClicked() { + engine.running = false; + engine.addPattern(); + } + + void onEdgesClicked() { + engine.toggleEdgeRendering(); + } + + void onClearClicked() { + engine.clear(); + } +} diff --git a/lib/components/controls_component.html b/lib/components/controls_component.html new file mode 100644 index 0000000..4d07357 --- /dev/null +++ b/lib/components/controls_component.html @@ -0,0 +1,14 @@ +
+ + + + + + + + + + + {{simSpeed}} + +
\ No newline at end of file diff --git a/lib/components/header_component.dart b/lib/components/header_component.dart new file mode 100644 index 0000000..94e9a9b --- /dev/null +++ b/lib/components/header_component.dart @@ -0,0 +1,13 @@ +import 'package:angular/angular.dart'; +import 'package:angular_components/angular_components.dart'; + +@Component( + selector: 'app_header', + templateUrl: "header_component.html", + directives: [coreDirectives, MaterialButtonComponent, MaterialIconComponent, MaterialSliderComponent], + providers: [], + styleUrls: const ['package:angular_components/app_layout/layout.scss.css'], +) +class HeaderComponent { + +} diff --git a/lib/components/header_component.html b/lib/components/header_component.html new file mode 100644 index 0000000..2f87a66 --- /dev/null +++ b/lib/components/header_component.html @@ -0,0 +1,12 @@ +
+
+ + + + Cellular Automata +
+ +
+
\ No newline at end of file diff --git a/lib/components/simulation_component.dart b/lib/components/simulation_component.dart new file mode 100644 index 0000000..47567d5 --- /dev/null +++ b/lib/components/simulation_component.dart @@ -0,0 +1,41 @@ +import 'dart:html' as html; + +import 'package:angular/angular.dart'; +import 'package:rules_of_living/service/engine_service.dart'; + +@Component( + selector: 'gol-simulation', + templateUrl: "simulation_component.html", + directives: [coreDirectives], + providers: [], +// styleUrls: const ['package:angular_components/app_layout/layout.scss.css'], +) +class SimulationComponent implements OnInit { + final EngineService engineService; + + SimulationComponent(this.engineService); + + @override + void ngOnInit() { + html.CanvasElement canvas = html.CanvasElement()..id = "simulation"; + html.querySelector("#simulation")..append(canvas); + canvas.width = 500; + canvas.height= 500; + + canvas.context2D.setFillColorRgb(200, 0, 0); + canvas.context2D.fillRect(0, 0, canvas.width, canvas.height); + canvas.context2D.setFillColorRgb(0, 255, 0); + canvas.context2D.fillText(''' + If you see this\n + the app is broken :( + ''', canvas.width/2-50, canvas.height/2); + engineService.create(canvas); + + html.window.animationFrame.then(animFrame); + } + + void animFrame(num now) { + engineService.engine.process(now); + html.window.animationFrame.then(animFrame); + } +} diff --git a/lib/components/simulation_component.html b/lib/components/simulation_component.html new file mode 100644 index 0000000..1e5f113 --- /dev/null +++ b/lib/components/simulation_component.html @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/lib/service/engine_service.dart b/lib/service/engine_service.dart new file mode 100644 index 0000000..5107f3c --- /dev/null +++ b/lib/service/engine_service.dart @@ -0,0 +1,11 @@ +import 'dart:html' as html; + +import 'package:rules_of_living/src/Engine.dart'; + +class EngineService { + Engine _engine; + + Engine get engine => _engine; + + void create(html.CanvasElement canvas) => _engine = Engine(canvas); +} diff --git a/pubspec.yaml b/pubspec.yaml index 9dc2faa..1e77191 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -9,6 +9,7 @@ environment: dependencies: angular: ^5.0.0-beta + angular_components: ^0.9.0-beta dev_dependencies: angular_test: ^2.0.0-beta diff --git a/web/index.html b/web/index.html index 35bd3cb..be2e05b 100644 --- a/web/index.html +++ b/web/index.html @@ -15,11 +15,15 @@ + + + + diff --git a/web/styles.css b/web/styles.css index ef7a186..e0b0d35 100644 --- a/web/styles.css +++ b/web/styles.css @@ -1,117 +1,126 @@ @import url(https://fonts.googleapis.com/css?family=Roboto); @import url(https://fonts.googleapis.com/css?family=Material+Icons); -/* Master Styles */ -h1 { - color: #369; - font-family: Arial, Helvetica, sans-serif; - font-size: 250%; -} -h2, h3 { - color: #444; - font-family: Arial, Helvetica, sans-serif; - font-weight: lighter; -} -body { - margin: 2em; -} -body, input[text], button { - color: #888; - font-family: Cambria, Georgia; -} -a { - cursor: pointer; - cursor: hand; -} -button { - font-family: Arial; - background-color: #eee; - border: none; - padding: 5px 10px; - border-radius: 4px; - cursor: pointer; - cursor: hand; -} -button:hover { - background-color: #cfd8dc; -} -button:disabled { - background-color: #eee; - color: #aaa; - cursor: auto; -} -label { - padding-right: 0.5em; -} -/* Navigation link styles */ -nav a { - padding: 5px 10px; - text-decoration: none; - margin-right: 10px; - margin-top: 10px; - display: inline-block; - background-color: #eee; - border-radius: 4px; -} -nav a:visited, a:link { - color: #607D8B; -} -nav a:hover { - color: #039be5; - background-color: #CFD8DC; -} -nav a.active { - color: #039be5; +html, body { + height: 100%; + margin: 0; + padding: 0; + width: 100%; + font-family: 'Roboto', sans-serif; + } -/* items class */ -.items { - margin: 0 0 2em 0; - list-style-type: none; - padding: 0; - width: 24em; -} -.items li { - cursor: pointer; - position: relative; - left: 0; - background-color: #EEE; - margin: .5em; - padding: .3em 0; - height: 1.6em; - border-radius: 4px; -} -.items li:hover { - color: #607D8B; - background-color: #DDD; - left: .1em; -} -.items li.selected { - background-color: #CFD8DC; - color: white; -} -.items li.selected:hover { - background-color: #BBD8DC; -} -.items .text { - position: relative; - top: -3px; -} -.items .badge { - display: inline-block; - font-size: small; - color: white; - padding: 0.8em 0.7em 0 0.7em; - background-color: #607D8B; - line-height: 1em; - position: relative; - left: -1px; - top: -4px; - height: 1.8em; - margin-right: .8em; - border-radius: 4px 0 0 4px; -} -/* everywhere else */ -* { - font-family: Arial, Helvetica, sans-serif; -} +/*!* Master Styles *!*/ +/*h1 {*/ + /*color: #369;*/ + /*font-family: Arial, Helvetica, sans-serif;*/ + /*font-size: 250%;*/ +/*}*/ +/*h2, h3 {*/ + /*color: #444;*/ + /*font-family: Arial, Helvetica, sans-serif;*/ + /*font-weight: lighter;*/ +/*}*/ +/*body {*/ + /*margin: 2em;*/ +/*}*/ +/*body, input[text], button {*/ + /*color: #888;*/ + /*font-family: Cambria, Georgia;*/ +/*}*/ +/*a {*/ + /*cursor: pointer;*/ + /*cursor: hand;*/ +/*}*/ +/*button {*/ + /*font-family: Arial;*/ + /*background-color: #eee;*/ + /*border: none;*/ + /*padding: 5px 10px;*/ + /*border-radius: 4px;*/ + /*cursor: pointer;*/ + /*cursor: hand;*/ +/*}*/ +/*button:hover {*/ + /*background-color: #cfd8dc;*/ +/*}*/ +/*button:disabled {*/ + /*background-color: #eee;*/ + /*color: #aaa;*/ + /*cursor: auto;*/ +/*}*/ +/*label {*/ + /*padding-right: 0.5em;*/ +/*}*/ +/*!* Navigation link styles *!*/ +/*nav a {*/ + /*padding: 5px 10px;*/ + /*text-decoration: none;*/ + /*margin-right: 10px;*/ + /*margin-top: 10px;*/ + /*display: inline-block;*/ + /*background-color: #eee;*/ + /*border-radius: 4px;*/ +/*}*/ +/*nav a:visited, a:link {*/ + /*color: #607D8B;*/ +/*}*/ +/*nav a:hover {*/ + /*color: #039be5;*/ + /*background-color: #CFD8DC;*/ +/*}*/ +/*nav a.active {*/ + /*color: #039be5;*/ +/*}*/ + +/*!* items class *!*/ +/*.items {*/ + /*margin: 0 0 2em 0;*/ + /*list-style-type: none;*/ + /*padding: 0;*/ + /*width: 24em;*/ +/*}*/ +/*.items li {*/ + /*cursor: pointer;*/ + /*position: relative;*/ + /*left: 0;*/ + /*background-color: #EEE;*/ + /*margin: .5em;*/ + /*padding: .3em 0;*/ + /*height: 1.6em;*/ + /*border-radius: 4px;*/ +/*}*/ +/*.items li:hover {*/ + /*color: #607D8B;*/ + /*background-color: #DDD;*/ + /*left: .1em;*/ +/*}*/ +/*.items li.selected {*/ + /*background-color: #CFD8DC;*/ + /*color: white;*/ +/*}*/ +/*.items li.selected:hover {*/ + /*background-color: #BBD8DC;*/ +/*}*/ +/*.items .text {*/ + /*position: relative;*/ + /*top: -3px;*/ +/*}*/ +/*.items .badge {*/ + /*display: inline-block;*/ + /*font-size: small;*/ + /*color: white;*/ + /*padding: 0.8em 0.7em 0 0.7em;*/ + /*background-color: #607D8B;*/ + /*line-height: 1em;*/ + /*position: relative;*/ + /*left: -1px;*/ + /*top: -4px;*/ + /*height: 1.8em;*/ + /*margin-right: .8em;*/ + /*border-radius: 4px 0 0 4px;*/ +/*}*/ +/*!* everywhere else *!*/ +/** {*/ + /*font-family: Arial, Helvetica, sans-serif;*/ +/*}*/