Skip to content

Commit 147928c

Browse files
committed
puremvc-haxe-demo-feathersui-todomvc
1 parent 67c79bf commit 147928c

File tree

18 files changed

+1301
-0
lines changed

18 files changed

+1301
-0
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
- PureMVC TodoMVC Demo for Haxe and Feathers UI - Copyright © 2022 Bowler Hat LLC
2+
- Original TodoMVC Project - Copyright © Addy Osmani, Sindre Sorhus
3+
- PureMVC - Copyright © 2006-2012 Futurescale, Inc.
4+
- All rights reserved.
5+
6+
- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7+
8+
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9+
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
10+
- Neither the name of Futurescale, Inc., PureMVC.org, nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
11+
12+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# PureMVC Haxe Feathers UI TodoMVC
2+
3+
This example app demonstrates how to create [TodoMVC](https://todomvc.com) using [PureMVC](http://puremvc.org/) and [Feathers UI](https://feathersui.com/).
4+
5+
## Live demo
6+
7+
A build of the [_puremvc-haxe-demo-feathersui-todomvc_ sample](https://feathersui.com/samples/haxe-openfl/puremvc/puremvc-haxe-demo-feathersui-todomvc/) is hosted on the Feathers UI website, and it may be viewed in any modern web browser.
8+
9+
## Run locally
10+
11+
This project includes an [_project.xml_](https://lime.software/docs/project-files/xml-format/) file that configures all options for [OpenFL](https://openfl.org/). This file makes it easy to build from the command line, and many IDEs can parse this file to configure a Haxe project to use OpenFL.
12+
13+
### Prerequisites
14+
15+
- [Install Haxe 4.0.0 or newer](https://haxe.org/download/)
16+
- [Install Feathers UI from Haxelib](https://feathersui.com/learn/haxe-openfl/installation/)
17+
18+
### Command Line
19+
20+
Run the [**openfl**](https://www.openfl.org/learn/haxelib/docs/tools/) tool in your terminal:
21+
22+
```sh
23+
haxelib run openfl test html5
24+
```
25+
26+
In addition to `html5`, other supported targets include `windows`, `mac`, `linux`, `android`, and `ios`. See [Lime Command Line Tools: Basic Commands](https://lime.software/docs/command-line-tools/basic-commands/) for complete details about the available commands.
27+
28+
### Editors and IDEs
29+
30+
Check out the following tutorials for creating Feathers UI projects in popular development environments:
31+
32+
- [HaxeDevelop](https://feathersui.com/learn/haxe-openfl/haxedevelop/)
33+
- [Moonshine IDE](https://feathersui.com/learn/haxe-openfl/moonshine-ide/)
34+
- [Visual Studio Code](https://feathersui.com/learn/haxe-openfl/visual-studio-code/)
Lines changed: 9 additions & 0 deletions
Loading
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<project>
3+
<meta title="TodoMVC" package="com.feathersui.samples.puremvc.TodoMVC" version="1.0.0" company="Bowler Hat LLC"/>
4+
<meta title="PureMVC Haxe Feathers UI TodoMVC Demo — Feathers UI Samples" if="html5"/>
5+
<app main="TodoMVC" file="TodoMVC"/>
6+
7+
<window allow-high-dpi="true"/>
8+
<window fps="60"/>
9+
<window fps="0" if="html5"/>
10+
11+
<source path="src"/>
12+
13+
<haxelib name="openfl"/>
14+
<haxelib name="actuate"/>
15+
<haxelib name="feathersui"/>
16+
<haxelib name="puremvc-standard"/>
17+
18+
<icon path="assets/icons/feathersui-icon.svg"/>
19+
</project>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
PureMVC Haxe Demo - Feathers UI TodoMVC
3+
Copyright (c) 2022 Bowler Hat LLC
4+
*/
5+
6+
import feathers.controls.Application;
7+
import feathers.events.FeathersEvent;
8+
import feathers.style.Theme;
9+
import org.puremvc.haxe.demos.feathersui.todomvc.ApplicationFacade;
10+
import org.puremvc.haxe.demos.feathersui.todomvc.theme.TodoTheme;
11+
import org.puremvc.haxe.demos.feathersui.todomvc.view.components.MainView;
12+
13+
class TodoMVC extends Application {
14+
public function new() {
15+
Theme.setTheme(new TodoTheme());
16+
super();
17+
this.addEventListener(FeathersEvent.CREATION_COMPLETE, event -> facade.startup(this));
18+
}
19+
20+
public var mainView:MainView;
21+
22+
private var facade = ApplicationFacade.getInstance();
23+
24+
override private function initialize():Void {
25+
super.initialize();
26+
this.mainView = new MainView();
27+
this.addChild(this.mainView);
28+
}
29+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
PureMVC Haxe Demo - Feathers UI TodoMVC
3+
Copyright (c) 2022 Bowler Hat LLC
4+
*/
5+
6+
package org.puremvc.haxe.demos.feathersui.todomvc;
7+
8+
import org.puremvc.haxe.demos.feathersui.todomvc.controller.ApplicationStartupCommand;
9+
import org.puremvc.haxe.patterns.facade.Facade;
10+
11+
/**
12+
A concrete `Facade` for the `TodoMVC` application.
13+
14+
The main job of the `ApplicationFacade` is to act as a single
15+
place for mediators, proxies and commands to access and communicate
16+
with each other without having to interact with the Model, View, and
17+
Controller classes directly. All this capability it inherits from
18+
the PureMVC Facade class.
19+
20+
This concrete Facade subclass is also a central place to define
21+
notification constants which will be shared among commands, proxies and
22+
mediators, as well as initializing the controller with Command to
23+
Notification mappings.
24+
**/
25+
class ApplicationFacade extends Facade {
26+
// Notification name constants
27+
public static final STARTUP = "startup";
28+
29+
public function new() {
30+
super();
31+
}
32+
33+
/**
34+
Singleton ApplicationFacade Factory Method
35+
**/
36+
public static function getInstance():ApplicationFacade {
37+
if (Facade.instance == null) {
38+
Facade.instance = new ApplicationFacade();
39+
}
40+
return cast(Facade.instance, ApplicationFacade);
41+
}
42+
43+
/**
44+
Register Commands with the Controller
45+
**/
46+
override private function initializeController():Void {
47+
super.initializeController();
48+
registerCommand(STARTUP, ApplicationStartupCommand);
49+
}
50+
51+
/**
52+
Start the application
53+
**/
54+
public function startup(app:TodoMVC):Void {
55+
sendNotification(STARTUP, app);
56+
}
57+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
PureMVC Haxe Demo - Feathers UI TodoMVC
3+
Copyright (c) 2022 Bowler Hat LLC
4+
*/
5+
6+
package org.puremvc.haxe.demos.feathersui.todomvc.controller;
7+
8+
import org.puremvc.haxe.patterns.command.MacroCommand;
9+
10+
/**
11+
A MacroCommand executed when the application starts.
12+
13+
@see org.puremvc.demos.feathersui.appskeleton.controller.ModelPrepCommand
14+
@see org.puremvc.demos.feathersui.appskeleton.controller.ViewPrepCommand
15+
*/
16+
class ApplicationStartupCommand extends MacroCommand {
17+
/**
18+
Initialize the MacroCommand by adding its SubCommands.
19+
20+
Since we built the UI using an MXML `Application` tag, those
21+
components are created first. The top level `Application`
22+
then initialized the `ApplicationFacade`, which in turn initialized
23+
the `Controller`, registering Commands. Then the
24+
`Application` sent the `APP_STARTUP`
25+
Notification, leading to this `MacroCommand`'s execution.
26+
27+
It is important for us to create and register Proxys with the Model
28+
prior to creating and registering Mediators with the View, since
29+
availability of Model data is often essential to the proper
30+
initialization of the View.
31+
32+
So, `ApplicationStartupCommand` first executes
33+
`ModelPrepCommand` followed by `ViewPrepCommand`
34+
**/
35+
override private function initializeMacroCommand():Void {
36+
addSubCommand(ModelPrepCommand);
37+
addSubCommand(ViewPrepCommand);
38+
}
39+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*
2+
PureMVC Haxe Demo - Feathers UI TodoMVC
3+
Copyright (c) 2022 Bowler Hat LLC
4+
*/
5+
6+
package org.puremvc.haxe.demos.feathersui.todomvc.controller;
7+
8+
import org.puremvc.haxe.demos.feathersui.todomvc.model.TodosProxy;
9+
import org.puremvc.haxe.interfaces.INotification;
10+
import org.puremvc.haxe.patterns.command.SimpleCommand;
11+
12+
/**
13+
Create and register `Proxy`s with the `Model`.
14+
**/
15+
class ModelPrepCommand extends SimpleCommand {
16+
override public function execute(note:INotification):Void {
17+
facade.registerProxy(new TodosProxy());
18+
}
19+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
PureMVC Haxe Demo - Feathers UI TodoMVC
3+
Copyright (c) 2022 Bowler Hat LLC
4+
*/
5+
6+
package org.puremvc.haxe.demos.feathersui.todomvc.controller;
7+
8+
import org.puremvc.haxe.demos.feathersui.todomvc.view.ApplicationMediator;
9+
import org.puremvc.haxe.interfaces.INotification;
10+
import org.puremvc.haxe.patterns.command.SimpleCommand;
11+
12+
/**
13+
Prepare the View for use.
14+
15+
The `Notification` was sent by the `Application`,
16+
and a reference to that view component was passed on the note body.
17+
The `ApplicationMediator` will be created and registered using this
18+
reference. The `ApplicationMediator` will then register
19+
all the `Mediator`s for the components it created.
20+
**/
21+
class ViewPrepCommand extends SimpleCommand {
22+
override public function execute(note:INotification):Void {
23+
// Register the ApplicationMediator
24+
facade.registerMediator(new ApplicationMediator(cast(note.getBody(), TodoMVC)));
25+
}
26+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/*
2+
PureMVC Haxe Demo - Feathers UI TodoMVC
3+
Copyright (c) 2022 Bowler Hat LLC
4+
*/
5+
6+
package org.puremvc.haxe.demos.feathersui.todomvc.model;
7+
8+
import feathers.data.ArrayCollection;
9+
import org.puremvc.haxe.demos.feathersui.todomvc.model.vo.TodoItem;
10+
import org.puremvc.haxe.interfaces.IProxy;
11+
import org.puremvc.haxe.patterns.proxy.Proxy;
12+
13+
class TodosProxy extends Proxy implements IProxy {
14+
public static final NAME = "TodosProxy"; // Proxy name
15+
16+
public function new(data:Any = null) {
17+
super(NAME);
18+
}
19+
20+
public var todosCollection = new ArrayCollection<TodoItem>();
21+
22+
public function addTodoItem(item:TodoItem):Void {
23+
this.todosCollection.add(item);
24+
}
25+
26+
public function removeTodoItem(item:TodoItem):Void {
27+
this.todosCollection.remove(item);
28+
}
29+
30+
public function editTodoItem(item:TodoItem, newText:String):Void {
31+
item.text = newText;
32+
this.todosCollection.updateAt(this.todosCollection.indexOf(item));
33+
}
34+
35+
public function toggleCompleted(item:TodoItem):Void {
36+
item.completed = !item.completed;
37+
this.todosCollection.updateAt(this.todosCollection.indexOf(item));
38+
}
39+
40+
public function clearCompleted():Void {
41+
var savedFilterFunction = this.todosCollection.filterFunction;
42+
this.todosCollection.filterFunction = null;
43+
var i = this.todosCollection.length - 1;
44+
while (i >= 0) {
45+
var todoItem = this.todosCollection.get(i);
46+
if (todoItem.completed) {
47+
this.todosCollection.removeAt(i);
48+
}
49+
i--;
50+
}
51+
this.todosCollection.filterFunction = savedFilterFunction;
52+
}
53+
54+
public function refreshSelectAll(select:Bool):Void {
55+
for (todoItem in this.todosCollection.array) {
56+
todoItem.completed = select;
57+
}
58+
this.todosCollection.updateAll();
59+
}
60+
61+
public function filterAll():Void {
62+
this.todosCollection.filterFunction = null;
63+
}
64+
65+
public function filterActive():Void {
66+
this.todosCollection.filterFunction = activeFilterFunction;
67+
}
68+
69+
public function filterCompleted():Void {
70+
this.todosCollection.filterFunction = completedFilterFunction;
71+
}
72+
73+
private function activeFilterFunction(item:TodoItem):Bool {
74+
return !item.completed;
75+
}
76+
77+
private function completedFilterFunction(item:TodoItem):Bool {
78+
return item.completed;
79+
}
80+
}

0 commit comments

Comments
 (0)