diff --git a/.DS_Store b/.DS_Store
new file mode 100644
index 0000000..3a72f73
Binary files /dev/null and b/.DS_Store differ
diff --git a/assets/.DS_Store b/assets/.DS_Store
new file mode 100644
index 0000000..8690890
Binary files /dev/null and b/assets/.DS_Store differ
diff --git a/assets/data/Employees.xml b/assets/data/Employees.xml
new file mode 100644
index 0000000..9617129
--- /dev/null
+++ b/assets/data/Employees.xml
@@ -0,0 +1,31 @@
+
+
+
+ 1
+ Sue
+ Hove
+ shove@cafetownsend.com
+ 2006-01-07
+
+
+ 2
+ Matt
+ Boles
+ mboles@cafetownsend.com
+ 2006-02-17
+
+
+ 3
+ Mike
+ Kollen
+ mkollen@cafetownsend.com
+ 2006-03-01
+
+
+ 4
+ Jennifer
+ Jaegel
+ jjaegel@cafetownsend.com
+ 2006-04-01
+
+
diff --git a/assets/icons/feathersui-icon.svg b/assets/icons/feathersui-icon.svg
new file mode 100644
index 0000000..71496d6
--- /dev/null
+++ b/assets/icons/feathersui-icon.svg
@@ -0,0 +1,9 @@
+
diff --git a/project.xml b/project.xml
new file mode 100644
index 0000000..d2e727a
--- /dev/null
+++ b/project.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/com/feathersui/cafetownsend/Main.hx b/src/com/feathersui/cafetownsend/Main.hx
new file mode 100644
index 0000000..d4c4105
--- /dev/null
+++ b/src/com/feathersui/cafetownsend/Main.hx
@@ -0,0 +1,85 @@
+/*
+ Cafe Townsend MVC Tutorial
+
+ Copyright 2006 Adobe
+
+ Converted to feathersui-cairngorm by Bowler Hat LLC
+ https://feathersui.com
+
+ Converted to Cairngorm 2 (Flex) by Darren Houle
+ http://www.digimmersion.com
+
+ This is released under a Creative Commons license.
+ http://creativecommons.org/licenses/by/2.5/
+
+ */
+
+package com.feathersui.cafetownsend;
+
+import com.adobe.cairngorm.control.CairngormEventDispatcher;
+import com.feathersui.cafetownsend.business.Services;
+import com.feathersui.cafetownsend.control.AppController;
+import com.feathersui.cafetownsend.control.LoadEmployeesEvent;
+import com.feathersui.cafetownsend.model.AppModelLocator;
+import com.feathersui.cafetownsend.view.EmployeeDetail;
+import com.feathersui.cafetownsend.view.EmployeeList;
+import com.feathersui.cafetownsend.view.EmployeeLogin;
+import feathers.controls.Application;
+import feathers.controls.navigators.StackItem;
+import feathers.controls.navigators.StackNavigator;
+import feathers.events.FeathersEvent;
+import feathers.motion.transitions.FadeTransitionBuilder;
+import openfl.events.Event;
+
+class Main extends Application {
+ private var model = AppModelLocator.getInstance();
+ private var services = new Services();
+ private var appController = new AppController();
+
+ private var navigator:StackNavigator;
+
+ public function new() {
+ super();
+
+ addEventListener(FeathersEvent.CREATION_COMPLETE, creationCompleteHandler);
+ }
+
+ override private function initialize():Void {
+ super.initialize();
+
+ navigator = new StackNavigator();
+ navigator.addItem(StackItem.withClass("login", EmployeeLogin));
+ navigator.addItem(StackItem.withClass("list", EmployeeList));
+ navigator.addItem(StackItem.withClass("detail", EmployeeDetail));
+ navigator.replaceTransition = new FadeTransitionBuilder().build();
+ addChild(navigator);
+
+ navigator.rootItemID = "login";
+
+ model.addEventListener(AppModelLocator.VIEWING_CHANGE, model_viewingChangeHandler);
+ }
+
+ private function loadEmployees():Void {
+ var cgEvent = new LoadEmployeesEvent();
+ CairngormEventDispatcher.getInstance().dispatchEvent(cgEvent);
+ }
+
+ private function creationCompleteHandler(event:FeathersEvent):Void {
+ loadEmployees();
+ }
+
+ private function model_viewingChangeHandler(event:Event):Void {
+ var newID = null;
+ switch (model.viewing) {
+ case AppModelLocator.EMPLOYEE_LOGIN:
+ newID = "login";
+ case AppModelLocator.EMPLOYEE_DETAIL:
+ newID = "detail";
+ case AppModelLocator.EMPLOYEE_LIST:
+ newID = "list";
+ }
+ if (navigator.activeItemID != newID) {
+ navigator.replaceItem(newID);
+ }
+ }
+}
diff --git a/src/com/feathersui/cafetownsend/business/LoadEmployeesDelegate.hx b/src/com/feathersui/cafetownsend/business/LoadEmployeesDelegate.hx
new file mode 100644
index 0000000..667b59f
--- /dev/null
+++ b/src/com/feathersui/cafetownsend/business/LoadEmployeesDelegate.hx
@@ -0,0 +1,40 @@
+/*
+ Cafe Townsend MVC Tutorial
+
+ Copyright 2006 Adobe
+
+ Converted to feathersui-cairngorm by Bowler Hat LLC
+ https://feathersui.com
+
+ Converted to Cairngorm 2 (Flex) by Darren Houle
+ http://www.digimmersion.com
+
+ This is released under a Creative Commons license.
+ http://creativecommons.org/licenses/by/2.5/
+
+ */
+
+package com.feathersui.cafetownsend.business;
+
+import com.adobe.cairngorm.business.ServiceLocator;
+import feathers.rpc.IResponder;
+import feathers.rpc.http.HTTPService;
+
+class LoadEmployeesDelegate {
+ private var command:IResponder;
+ private var service:HTTPService;
+
+ public function new(command:IResponder) {
+ // constructor will store a reference to the service we're going to call
+ service = ServiceLocator.getInstance().getHTTPService('loadEmployeesService');
+ // and store a reference to the command that created this delegate
+ this.command = command;
+ }
+
+ public function loadEmployeesService():Void {
+ // call the service
+ var token = service.send();
+ // notify this command when the service call completes
+ token.addResponder(command);
+ }
+}
diff --git a/src/com/feathersui/cafetownsend/business/Services.hx b/src/com/feathersui/cafetownsend/business/Services.hx
new file mode 100644
index 0000000..8d3daf4
--- /dev/null
+++ b/src/com/feathersui/cafetownsend/business/Services.hx
@@ -0,0 +1,31 @@
+/*
+ Cafe Townsend MVC Tutorial
+
+ Copyright 2006 Adobe
+
+ Converted to feathersui-cairngorm by Bowler Hat LLC
+ https://feathersui.com
+
+ Converted to Cairngorm 2 (Flex) by Darren Houle
+ http://www.digimmersion.com
+
+ This is released under a Creative Commons license.
+ http://creativecommons.org/licenses/by/2.5/
+
+ */
+
+package com.feathersui.cafetownsend.business;
+
+import com.adobe.cairngorm.business.ServiceLocator;
+import feathers.rpc.http.HTTPService;
+
+class Services extends ServiceLocator {
+ public var loadEmployeesService:HTTPService;
+
+ public function new() {
+ super();
+ loadEmployeesService = new HTTPService();
+ loadEmployeesService.url = "data/Employees.xml";
+ loadEmployeesService.resultFormat = HTTPService.RESULT_FORMAT_HAXE_XML;
+ }
+}
diff --git a/src/com/feathersui/cafetownsend/command/AddNewEmployeeCommand.hx b/src/com/feathersui/cafetownsend/command/AddNewEmployeeCommand.hx
new file mode 100644
index 0000000..a85c22f
--- /dev/null
+++ b/src/com/feathersui/cafetownsend/command/AddNewEmployeeCommand.hx
@@ -0,0 +1,36 @@
+/*
+ Cafe Townsend MVC Tutorial
+
+ Copyright 2006 Adobe
+
+ Converted to feathersui-cairngorm by Bowler Hat LLC
+ https://feathersui.com
+
+ Converted to Cairngorm 2 (Flex) by Darren Houle
+ http://www.digimmersion.com
+
+ This is released under a Creative Commons license.
+ http://creativecommons.org/licenses/by/2.5/
+
+ */
+
+package com.feathersui.cafetownsend.command;
+
+import com.adobe.cairngorm.commands.ICommand;
+import com.adobe.cairngorm.control.CairngormEvent;
+import com.feathersui.cafetownsend.model.AppModelLocator;
+import com.feathersui.cafetownsend.vo.Employee;
+
+class AddNewEmployeeCommand implements ICommand {
+ private var model = AppModelLocator.getInstance();
+
+ public function execute(cgEvent:CairngormEvent):Void {
+ // add new employee instantiates a new employee object, which has default blank values in the constructor
+ model.employeeTemp = new Employee();
+
+ // main viewstack selectedIndex is bound to this model locator value
+ // so this now switches the view from the employee list to the detail screen
+ // so we can populate the new blank employee values
+ model.viewing = AppModelLocator.EMPLOYEE_DETAIL;
+ }
+}
diff --git a/src/com/feathersui/cafetownsend/command/CancelEmployeeEditsCommand.hx b/src/com/feathersui/cafetownsend/command/CancelEmployeeEditsCommand.hx
new file mode 100644
index 0000000..8de903a
--- /dev/null
+++ b/src/com/feathersui/cafetownsend/command/CancelEmployeeEditsCommand.hx
@@ -0,0 +1,35 @@
+/*
+ Cafe Townsend MVC Tutorial
+
+ Copyright 2006 Adobe
+
+ Converted to feathersui-cairngorm by Bowler Hat LLC
+ https://feathersui.com
+
+ Converted to Cairngorm 2 (Flex) by Darren Houle
+ http://www.digimmersion.com
+
+ This is released under a Creative Commons license.
+ http://creativecommons.org/licenses/by/2.5/
+
+ */
+
+package com.feathersui.cafetownsend.command;
+
+import com.adobe.cairngorm.commands.ICommand;
+import com.adobe.cairngorm.control.CairngormEvent;
+import com.feathersui.cafetownsend.model.AppModelLocator;
+
+class CancelEmployeeEditsCommand implements ICommand {
+ private var model = AppModelLocator.getInstance();
+
+ public function execute(cgEvent:CairngormEvent):Void {
+ // decided we don't need to store the edited employee details,
+ // so null out the temp employee in the model locators
+ model.employeeTemp = null;
+
+ // main viewstack selectedIndex is bound to this model locator value
+ // so this now switches the view from the detail screen back to the employee list
+ model.viewing = AppModelLocator.EMPLOYEE_LIST;
+ }
+}
diff --git a/src/com/feathersui/cafetownsend/command/DeleteEmployeeCommand.hx b/src/com/feathersui/cafetownsend/command/DeleteEmployeeCommand.hx
new file mode 100644
index 0000000..7803a25
--- /dev/null
+++ b/src/com/feathersui/cafetownsend/command/DeleteEmployeeCommand.hx
@@ -0,0 +1,44 @@
+/*
+ Cafe Townsend MVC Tutorial
+
+ Copyright 2006 Adobe
+
+ Converted to feathersui-cairngorm by Bowler Hat LLC
+ https://feathersui.com
+
+ Converted to Cairngorm 2 (Flex) by Darren Houle
+ http://www.digimmersion.com
+
+ This is released under a Creative Commons license.
+ http://creativecommons.org/licenses/by/2.5/
+
+ */
+
+package com.feathersui.cafetownsend.command;
+
+import com.adobe.cairngorm.commands.ICommand;
+import com.adobe.cairngorm.control.CairngormEvent;
+import com.feathersui.cafetownsend.model.AppModelLocator;
+
+class DeleteEmployeeCommand implements ICommand {
+ private var model = AppModelLocator.getInstance();
+
+ public function execute(cgEvent:CairngormEvent):Void {
+ // loop thru the employee list in the model locator
+ for (employee in model.employeeListDP) {
+ // if the emp_id stored in the temp employee matches one of the emp_id's in the employee list
+ if (model.employeeTemp.emp_id == employee.emp_id) {
+ // remove that item from the ArrayCollection
+ model.employeeListDP.remove(employee);
+ }
+ }
+
+ // clear out the data stored in the temp employee
+ model.employeeTemp = null;
+
+ // main viewstack selectedIndex is bound to this model locator value
+ // so this now switches the view from the detail screen back to the employee list
+ // the list should be one array item shorter
+ model.viewing = AppModelLocator.EMPLOYEE_LIST;
+ }
+}
diff --git a/src/com/feathersui/cafetownsend/command/LoadEmployeesCommand.hx b/src/com/feathersui/cafetownsend/command/LoadEmployeesCommand.hx
new file mode 100644
index 0000000..a629c87
--- /dev/null
+++ b/src/com/feathersui/cafetownsend/command/LoadEmployeesCommand.hx
@@ -0,0 +1,62 @@
+/*
+ Cafe Townsend MVC Tutorial
+
+ Copyright 2006 Adobe
+
+ Converted to feathersui-cairngorm by Bowler Hat LLC
+ https://feathersui.com
+
+ Converted to Cairngorm 2 (Flex) by Darren Houle
+ http://www.digimmersion.com
+
+ This is released under a Creative Commons license.
+ http://creativecommons.org/licenses/by/2.5/
+
+ */
+
+package com.feathersui.cafetownsend.command;
+
+import com.adobe.cairngorm.commands.ICommand;
+import com.adobe.cairngorm.control.CairngormEvent;
+import com.feathersui.cafetownsend.business.LoadEmployeesDelegate;
+import com.feathersui.cafetownsend.model.AppModelLocator;
+import com.feathersui.cafetownsend.vo.Employee;
+import feathers.data.ArrayCollection;
+import feathers.rpc.IResponder;
+import feathers.rpc.events.ResultEvent;
+
+class LoadEmployeesCommand implements ICommand implements IResponder {
+ private var model = AppModelLocator.getInstance();
+
+ public function execute(cgEvent:CairngormEvent):Void {
+ // create a worker who will go get some data
+ // pass it a reference to this command so the delegate knows where to return the data
+ var delegate = new LoadEmployeesDelegate(this);
+ // make the delegate do some work
+ delegate.loadEmployeesService();
+ }
+
+ // this is called when the delegate receives a result from the service
+ public function result(rpcEvent:Dynamic):Void {
+ // populate the employee list in the model locator with the XML results from the service call
+ var xmlData:Xml = cast(rpcEvent, ResultEvent).result;
+ var employees:Array = [];
+ for (employeeXml in xmlData.firstElement().elementsNamed("employee")) {
+ var emp_id = Std.parseInt(employeeXml.elementsNamed("emp_id").next().firstChild().nodeValue);
+ var firstname = employeeXml.elementsNamed("firstname").next().firstChild().nodeValue;
+ var lastname = employeeXml.elementsNamed("lastname").next().firstChild().nodeValue;
+ var email = employeeXml.elementsNamed("email").next().firstChild().nodeValue;
+ var startdate = Date.fromString(employeeXml.elementsNamed("startdate").next().firstChild().nodeValue);
+ var employee = new Employee(emp_id, firstname, lastname, email, startdate);
+ employees.push(employee);
+ }
+ model.employeeListDP = new ArrayCollection(employees);
+ }
+
+ // this is called when the delegate receives a fault from the service
+ public function fault(rpcEvent:Dynamic):Void {
+ // store an error message in the model locator
+ // labels, alerts, etc can bind to this to notify the user of errors
+ model.errorStatus = "Fault occured in LoadEmployeesCommand.";
+ }
+}
diff --git a/src/com/feathersui/cafetownsend/command/LoginCommand.hx b/src/com/feathersui/cafetownsend/command/LoginCommand.hx
new file mode 100644
index 0000000..56ab22e
--- /dev/null
+++ b/src/com/feathersui/cafetownsend/command/LoginCommand.hx
@@ -0,0 +1,47 @@
+/*
+ Cafe Townsend MVC Tutorial
+
+ Copyright 2006 Adobe
+
+ Converted to feathersui-cairngorm by Bowler Hat LLC
+ https://feathersui.com
+
+ Converted to Cairngorm 2 (Flex) by Darren Houle
+ http://www.digimmersion.com
+
+ This is released under a Creative Commons license.
+ http://creativecommons.org/licenses/by/2.5/
+
+ */
+
+package com.feathersui.cafetownsend.command;
+
+import com.adobe.cairngorm.commands.ICommand;
+import com.adobe.cairngorm.control.CairngormEvent;
+import com.feathersui.cafetownsend.control.LoginEvent;
+import com.feathersui.cafetownsend.model.AppModelLocator;
+import com.feathersui.cafetownsend.vo.User;
+import feathers.controls.Alert;
+
+class LoginCommand implements ICommand {
+ private var model = AppModelLocator.getInstance();
+
+ public function execute(cgEvent:CairngormEvent):Void {
+ // after casting, retreive the username & password payload from the incoming event
+ var username = cast(cgEvent, LoginEvent).username;
+ var password = cast(cgEvent, LoginEvent).password;
+
+ // if the auth info is correct
+ if (username == "Feathers" && password == "Cairngorm") {
+ // store the user info in a new user object in the model locator
+ model.user = new User(username, password);
+
+ // main viewstack selectedIndex is bound to this model locator value
+ // so this now switches the view from the login screen to the employee list
+ model.viewing = AppModelLocator.EMPLOYEE_LIST;
+ } else {
+ // if the auth info was incorrect, prompt with an alert box and remain on the login screen
+ Alert.show("We couldn't validate your username & password. Please try again.", "Login Failed", ["OK"]);
+ }
+ }
+}
diff --git a/src/com/feathersui/cafetownsend/command/LogoutCommand.hx b/src/com/feathersui/cafetownsend/command/LogoutCommand.hx
new file mode 100644
index 0000000..ea6a79b
--- /dev/null
+++ b/src/com/feathersui/cafetownsend/command/LogoutCommand.hx
@@ -0,0 +1,34 @@
+/*
+ Cafe Townsend MVC Tutorial
+
+ Copyright 2006 Adobe
+
+ Converted to feathersui-cairngorm by Bowler Hat LLC
+ https://feathersui.com
+
+ Converted to Cairngorm 2 (Flex) by Darren Houle
+ http://www.digimmersion.com
+
+ This is released under a Creative Commons license.
+ http://creativecommons.org/licenses/by/2.5/
+
+ */
+
+package com.feathersui.cafetownsend.command;
+
+import com.adobe.cairngorm.commands.ICommand;
+import com.adobe.cairngorm.control.CairngormEvent;
+import com.feathersui.cafetownsend.model.AppModelLocator;
+
+class LogoutCommand implements ICommand {
+ private var model = AppModelLocator.getInstance();
+
+ public function execute(cgEvent:CairngormEvent):Void {
+ // null out the user object stored in the model locator
+ model.user = null;
+
+ // main viewstack selectedIndex is bound to this model locator value
+ // so this now switches the view from the employee list back to the initial login screen
+ model.viewing = AppModelLocator.EMPLOYEE_LOGIN;
+ }
+}
diff --git a/src/com/feathersui/cafetownsend/command/SaveEmployeeEditsCommand.hx b/src/com/feathersui/cafetownsend/command/SaveEmployeeEditsCommand.hx
new file mode 100644
index 0000000..98a40af
--- /dev/null
+++ b/src/com/feathersui/cafetownsend/command/SaveEmployeeEditsCommand.hx
@@ -0,0 +1,70 @@
+/*
+ Cafe Townsend MVC Tutorial
+
+ Copyright 2006 Adobe
+
+ Converted to feathersui-cairngorm by Bowler Hat LLC
+ https://feathersui.com
+
+ Converted to Cairngorm 2 (Flex) by Darren Houle
+ http://www.digimmersion.com
+
+ This is released under a Creative Commons license.
+ http://creativecommons.org/licenses/by/2.5/
+
+ */
+
+package com.feathersui.cafetownsend.command;
+
+import com.adobe.cairngorm.commands.ICommand;
+import com.adobe.cairngorm.control.CairngormEvent;
+import com.feathersui.cafetownsend.control.SaveEmployeeEditsEvent;
+import com.feathersui.cafetownsend.model.AppModelLocator;
+
+class SaveEmployeeEditsCommand implements ICommand {
+ private var model = AppModelLocator.getInstance();
+
+ public function execute(cgEvent:CairngormEvent):Void {
+ // cast the cairngorm event and extract the edited employee data fields
+ var editItems = cast(cgEvent, SaveEmployeeEditsEvent);
+ // store those values in the temp employee in the model locator
+ model.employeeTemp.emp_id = editItems.emp_id;
+ model.employeeTemp.firstname = editItems.firstname;
+ model.employeeTemp.lastname = editItems.lastname;
+ model.employeeTemp.startdate = editItems.startdate;
+ model.employeeTemp.email = editItems.email;
+
+ // assume the edited fields are not an existing employee, but a new employee
+ // and set the ArrayCollection index to -1, which means this employee is not in our existing
+ // employee list anywhere
+ var dpIndex = -1;
+
+ // loop thru the employee list
+ for (i in 0...model.employeeListDP.length) {
+ // if the emp_id of the incoming employee matches an employee already in the list
+ if (model.employeeListDP.get(i).emp_id == model.employeeTemp.emp_id) {
+ // set our ArrayCollection index to that employee position
+ dpIndex = i;
+ }
+ }
+
+ // if it was an existing employee already in the ArrayCollection
+ if (dpIndex >= 0) {
+ // update that employee's values
+ model.employeeListDP.set(dpIndex, model.employeeTemp);
+ }
+ // otherwise, if it didn't match any existing employees
+ else {
+ // add the temp employee to the ArrayCollection
+ model.employeeListDP.add(model.employeeTemp);
+ }
+
+ // now that we've trasferred the temp employee to the array we can clear out the temp employee
+ model.employeeTemp = null;
+
+ // main viewstack selectedIndex is bound to this model locator value
+ // so this now switches the view from the detail screen back to the employee list
+ // the employee list should now contain one more item
+ model.viewing = AppModelLocator.EMPLOYEE_LIST;
+ }
+}
diff --git a/src/com/feathersui/cafetownsend/command/UpdateEmployeeCommand.hx b/src/com/feathersui/cafetownsend/command/UpdateEmployeeCommand.hx
new file mode 100644
index 0000000..5dec726
--- /dev/null
+++ b/src/com/feathersui/cafetownsend/command/UpdateEmployeeCommand.hx
@@ -0,0 +1,41 @@
+/*
+ Cafe Townsend MVC Tutorial
+
+ Copyright 2006 Adobe
+
+ Converted to feathersui-cairngorm by Bowler Hat LLC
+ https://feathersui.com
+
+ Converted to Cairngorm 2 (Flex) by Darren Houle
+ http://www.digimmersion.com
+
+ This is released under a Creative Commons license.
+ http://creativecommons.org/licenses/by/2.5/
+
+ */
+
+package com.feathersui.cafetownsend.command;
+
+import com.adobe.cairngorm.commands.ICommand;
+import com.adobe.cairngorm.control.CairngormEvent;
+import com.feathersui.cafetownsend.control.UpdateEmployeeEvent;
+import com.feathersui.cafetownsend.model.AppModelLocator;
+import com.feathersui.cafetownsend.vo.Employee;
+
+class UpdateEmployeeCommand implements ICommand {
+ private var model = AppModelLocator.getInstance();
+
+ public function execute(cgEvent:CairngormEvent):Void {
+ // cast the caringorm event so we can get at the selectedItem values sent from the mx:List
+ var selectedItem = cast(cgEvent, UpdateEmployeeEvent).selectedItem;
+
+ // populate a temp employee in the model locator with the details from the selectedItem
+ var employeeTemp:Employee = new Employee(selectedItem.emp_id, selectedItem.firstname, selectedItem.lastname, selectedItem.email,
+ Date.fromTime(selectedItem.startdate.getTime()));
+
+ model.employeeTemp = employeeTemp;
+ // main viewstack selectedIndex is bound to this model locator value
+ // so this now switches the view from the employee list to the detail screen
+ model.viewing = AppModelLocator.EMPLOYEE_DETAIL;
+ }
+}
diff --git a/src/com/feathersui/cafetownsend/control/AddNewEmployeeEvent.hx b/src/com/feathersui/cafetownsend/control/AddNewEmployeeEvent.hx
new file mode 100644
index 0000000..457f5e9
--- /dev/null
+++ b/src/com/feathersui/cafetownsend/control/AddNewEmployeeEvent.hx
@@ -0,0 +1,25 @@
+/*
+ Cafe Townsend MVC Tutorial
+
+ Copyright 2006 Adobe
+
+ Converted to feathersui-cairngorm by Bowler Hat LLC
+ https://feathersui.com
+
+ Converted to Cairngorm 2 (Flex) by Darren Houle
+ http://www.digimmersion.com
+
+ This is released under a Creative Commons license.
+ http://creativecommons.org/licenses/by/2.5/
+
+ */
+
+package com.feathersui.cafetownsend.control;
+
+import com.adobe.cairngorm.control.CairngormEvent;
+
+class AddNewEmployeeEvent extends CairngormEvent {
+ public function new() {
+ super(AppController.ADD_NEW_EMPLOYEE_EVENT);
+ }
+}
diff --git a/src/com/feathersui/cafetownsend/control/AppController.hx b/src/com/feathersui/cafetownsend/control/AppController.hx
new file mode 100644
index 0000000..6c309cc
--- /dev/null
+++ b/src/com/feathersui/cafetownsend/control/AppController.hx
@@ -0,0 +1,50 @@
+/*
+ Cafe Townsend MVC Tutorial
+
+ Copyright 2006 Adobe
+
+ Converted to feathersui-cairngorm by Bowler Hat LLC
+ https://feathersui.com
+
+ Converted to Cairngorm 2 (Flex) by Darren Houle
+ http://www.digimmersion.com
+
+ This is released under a Creative Commons license.
+ http://creativecommons.org/licenses/by/2.5/
+
+ */
+
+package com.feathersui.cafetownsend.control;
+
+import com.adobe.cairngorm.control.FrontController;
+import com.feathersui.cafetownsend.command.AddNewEmployeeCommand;
+import com.feathersui.cafetownsend.command.CancelEmployeeEditsCommand;
+import com.feathersui.cafetownsend.command.DeleteEmployeeCommand;
+import com.feathersui.cafetownsend.command.LoadEmployeesCommand;
+import com.feathersui.cafetownsend.command.LoginCommand;
+import com.feathersui.cafetownsend.command.LogoutCommand;
+import com.feathersui.cafetownsend.command.SaveEmployeeEditsCommand;
+import com.feathersui.cafetownsend.command.UpdateEmployeeCommand;
+
+class AppController extends FrontController {
+ public static final LOGIN_EVENT = "LOGIN_EVENT";
+ public static final LOGOUT_EVENT = "LOGOUT_EVENT";
+ public static final LOAD_EMPLOYEES_EVENT = "LOAD_EMPLOYEES_EVENT";
+ public static final ADD_NEW_EMPLOYEE_EVENT = "ADD_NEW_EMPLOYEE_EVENT";
+ public static final UPDATE_EMPLOYEE_EVENT = "UPDATE_EMPLOYEE_EVENT";
+ public static final CANCEL_EMPLOYEE_EDITS_EVENT = "CANCEL_EMPLOYEE_EDITS_EVENT";
+ public static final DELETE_EMPLOYEE_EVENT = "DELETE_EMPLOYEE_EVENT";
+ public static final SAVE_EMPLOYEE_EDITS_EVENT = "SAVE_EMPLOYEE_EDITS_EVENT";
+
+ public function new() {
+ super();
+ addCommand(AppController.LOGIN_EVENT, LoginCommand);
+ addCommand(AppController.LOGOUT_EVENT, LogoutCommand);
+ addCommand(AppController.LOAD_EMPLOYEES_EVENT, LoadEmployeesCommand);
+ addCommand(AppController.ADD_NEW_EMPLOYEE_EVENT, AddNewEmployeeCommand);
+ addCommand(AppController.UPDATE_EMPLOYEE_EVENT, UpdateEmployeeCommand);
+ addCommand(AppController.CANCEL_EMPLOYEE_EDITS_EVENT, CancelEmployeeEditsCommand);
+ addCommand(AppController.DELETE_EMPLOYEE_EVENT, DeleteEmployeeCommand);
+ addCommand(AppController.SAVE_EMPLOYEE_EDITS_EVENT, SaveEmployeeEditsCommand);
+ }
+}
diff --git a/src/com/feathersui/cafetownsend/control/CancelEmployeeEditsEvent.hx b/src/com/feathersui/cafetownsend/control/CancelEmployeeEditsEvent.hx
new file mode 100644
index 0000000..91af5f4
--- /dev/null
+++ b/src/com/feathersui/cafetownsend/control/CancelEmployeeEditsEvent.hx
@@ -0,0 +1,25 @@
+/*
+ Cafe Townsend MVC Tutorial
+
+ Copyright 2006 Adobe
+
+ Converted to feathersui-cairngorm by Bowler Hat LLC
+ https://feathersui.com
+
+ Converted to Cairngorm 2 (Flex) by Darren Houle
+ http://www.digimmersion.com
+
+ This is released under a Creative Commons license.
+ http://creativecommons.org/licenses/by/2.5/
+
+ */
+
+package com.feathersui.cafetownsend.control;
+
+import com.adobe.cairngorm.control.CairngormEvent;
+
+class CancelEmployeeEditsEvent extends CairngormEvent {
+ public function new() {
+ super(AppController.CANCEL_EMPLOYEE_EDITS_EVENT);
+ }
+}
diff --git a/src/com/feathersui/cafetownsend/control/DeleteEmployeeEvent.hx b/src/com/feathersui/cafetownsend/control/DeleteEmployeeEvent.hx
new file mode 100644
index 0000000..6978fe1
--- /dev/null
+++ b/src/com/feathersui/cafetownsend/control/DeleteEmployeeEvent.hx
@@ -0,0 +1,25 @@
+/*
+ Cafe Townsend MVC Tutorial
+
+ Copyright 2006 Adobe
+
+ Converted to feathersui-cairngorm by Bowler Hat LLC
+ https://feathersui.com
+
+ Converted to Cairngorm 2 (Flex) by Darren Houle
+ http://www.digimmersion.com
+
+ This is released under a Creative Commons license.
+ http://creativecommons.org/licenses/by/2.5/
+
+ */
+
+package com.feathersui.cafetownsend.control;
+
+import com.adobe.cairngorm.control.CairngormEvent;
+
+class DeleteEmployeeEvent extends CairngormEvent {
+ public function new() {
+ super(AppController.DELETE_EMPLOYEE_EVENT);
+ }
+}
diff --git a/src/com/feathersui/cafetownsend/control/LoadEmployeesEvent.hx b/src/com/feathersui/cafetownsend/control/LoadEmployeesEvent.hx
new file mode 100644
index 0000000..54bdb29
--- /dev/null
+++ b/src/com/feathersui/cafetownsend/control/LoadEmployeesEvent.hx
@@ -0,0 +1,25 @@
+/*
+ Cafe Townsend MVC Tutorial
+
+ Copyright 2006 Adobe
+
+ Converted to feathersui-cairngorm by Bowler Hat LLC
+ https://feathersui.com
+
+ Converted to Cairngorm 2 (Flex) by Darren Houle
+ http://www.digimmersion.com
+
+ This is released under a Creative Commons license.
+ http://creativecommons.org/licenses/by/2.5/
+
+ */
+
+package com.feathersui.cafetownsend.control;
+
+import com.adobe.cairngorm.control.CairngormEvent;
+
+class LoadEmployeesEvent extends CairngormEvent {
+ public function new() {
+ super(AppController.LOAD_EMPLOYEES_EVENT);
+ }
+}
diff --git a/src/com/feathersui/cafetownsend/control/LoginEvent.hx b/src/com/feathersui/cafetownsend/control/LoginEvent.hx
new file mode 100644
index 0000000..ad67236
--- /dev/null
+++ b/src/com/feathersui/cafetownsend/control/LoginEvent.hx
@@ -0,0 +1,30 @@
+/*
+ Cafe Townsend MVC Tutorial
+
+ Copyright 2006 Adobe
+
+ Converted to feathersui-cairngorm by Bowler Hat LLC
+ https://feathersui.com
+
+ Converted to Cairngorm 2 (Flex) by Darren Houle
+ http://www.digimmersion.com
+
+ This is released under a Creative Commons license.
+ http://creativecommons.org/licenses/by/2.5/
+
+ */
+
+package com.feathersui.cafetownsend.control;
+
+import com.adobe.cairngorm.control.CairngormEvent;
+
+class LoginEvent extends CairngormEvent {
+ public var username:String;
+ public var password:String;
+
+ public function new(username:String, password:String) {
+ super(AppController.LOGIN_EVENT);
+ this.username = username;
+ this.password = password;
+ }
+}
diff --git a/src/com/feathersui/cafetownsend/control/LogoutEvent.hx b/src/com/feathersui/cafetownsend/control/LogoutEvent.hx
new file mode 100644
index 0000000..aac0341
--- /dev/null
+++ b/src/com/feathersui/cafetownsend/control/LogoutEvent.hx
@@ -0,0 +1,25 @@
+/*
+ Cafe Townsend MVC Tutorial
+
+ Copyright 2006 Adobe
+
+ Converted to feathersui-cairngorm by Bowler Hat LLC
+ https://feathersui.com
+
+ Converted to Cairngorm 2 (Flex) by Darren Houle
+ http://www.digimmersion.com
+
+ This is released under a Creative Commons license.
+ http://creativecommons.org/licenses/by/2.5/
+
+ */
+
+package com.feathersui.cafetownsend.control;
+
+import com.adobe.cairngorm.control.CairngormEvent;
+
+class LogoutEvent extends CairngormEvent {
+ public function new() {
+ super(AppController.LOGOUT_EVENT);
+ }
+}
diff --git a/src/com/feathersui/cafetownsend/control/SaveEmployeeEditsEvent.hx b/src/com/feathersui/cafetownsend/control/SaveEmployeeEditsEvent.hx
new file mode 100644
index 0000000..a1fc524
--- /dev/null
+++ b/src/com/feathersui/cafetownsend/control/SaveEmployeeEditsEvent.hx
@@ -0,0 +1,36 @@
+/*
+ Cafe Townsend MVC Tutorial
+
+ Copyright 2006 Adobe
+
+ Converted to feathersui-cairngorm by Bowler Hat LLC
+ https://feathersui.com
+
+ Converted to Cairngorm 2 (Flex) by Darren Houle
+ http://www.digimmersion.com
+
+ This is released under a Creative Commons license.
+ http://creativecommons.org/licenses/by/2.5/
+
+ */
+
+package com.feathersui.cafetownsend.control;
+
+import com.adobe.cairngorm.control.CairngormEvent;
+
+class SaveEmployeeEditsEvent extends CairngormEvent {
+ public var emp_id:Int;
+ public var firstname:String;
+ public var lastname:String;
+ public var startdate:Date;
+ public var email:String;
+
+ public function new(emp_id:Int, firstname:String, lastname:String, startdate:Date, email:String) {
+ super(AppController.SAVE_EMPLOYEE_EDITS_EVENT);
+ this.emp_id = emp_id;
+ this.firstname = firstname;
+ this.lastname = lastname;
+ this.startdate = startdate;
+ this.email = email;
+ }
+}
diff --git a/src/com/feathersui/cafetownsend/control/UpdateEmployeeEvent.hx b/src/com/feathersui/cafetownsend/control/UpdateEmployeeEvent.hx
new file mode 100644
index 0000000..e18fbde
--- /dev/null
+++ b/src/com/feathersui/cafetownsend/control/UpdateEmployeeEvent.hx
@@ -0,0 +1,29 @@
+/*
+ Cafe Townsend MVC Tutorial
+
+ Copyright 2006 Adobe
+
+ Converted to feathersui-cairngorm by Bowler Hat LLC
+ https://feathersui.com
+
+ Converted to Cairngorm 2 (Flex) by Darren Houle
+ http://www.digimmersion.com
+
+ This is released under a Creative Commons license.
+ http://creativecommons.org/licenses/by/2.5/
+
+ */
+
+package com.feathersui.cafetownsend.control;
+
+import com.adobe.cairngorm.control.CairngormEvent;
+import com.feathersui.cafetownsend.vo.Employee;
+
+class UpdateEmployeeEvent extends CairngormEvent {
+ public var selectedItem:Employee;
+
+ public function new(selectedItem:Employee) {
+ super(AppController.UPDATE_EMPLOYEE_EVENT);
+ this.selectedItem = selectedItem;
+ }
+}
diff --git a/src/com/feathersui/cafetownsend/model/AppModelLocator.hx b/src/com/feathersui/cafetownsend/model/AppModelLocator.hx
new file mode 100644
index 0000000..228ef72
--- /dev/null
+++ b/src/com/feathersui/cafetownsend/model/AppModelLocator.hx
@@ -0,0 +1,101 @@
+/*
+ Cafe Townsend MVC Tutorial
+
+ Copyright 2006 Adobe
+
+ Converted to feathersui-cairngorm by Bowler Hat LLC
+ https://feathersui.com
+
+ Converted to Cairngorm 2 (Flex) by Darren Houle
+ http://www.digimmersion.com
+
+ This is released under a Creative Commons license.
+ http://creativecommons.org/licenses/by/2.5/
+
+ */
+
+package com.feathersui.cafetownsend.model;
+
+import com.adobe.cairngorm.model.IModelLocator;
+import com.feathersui.cafetownsend.vo.Employee;
+import com.feathersui.cafetownsend.vo.User;
+import feathers.data.ArrayCollection;
+import openfl.errors.Error;
+import openfl.events.Event;
+import openfl.events.EventDispatcher;
+
+class AppModelLocator extends EventDispatcher implements IModelLocator {
+ public static final VIEWING_CHANGE = "viewingChange";
+ public static final EMPLOYEE_LIST_DP_CHANGE = "employeeListDPChange";
+ public static final EMPLOYEE_TEMP_CHANGE = "employeeTempChange";
+ public static final USER_CHANGE = "userChange";
+
+ // this instance stores a static reference to itself
+ private static var model:AppModelLocator;
+
+ // available values for the main viewstack
+ // defined as contants to help uncover errors at compile time instead of run time
+ public static final EMPLOYEE_LOGIN = 0;
+ public static final EMPLOYEE_LIST = 1;
+ public static final EMPLOYEE_DETAIL = 2;
+
+ // viewstack starts out on the login screen
+ public var viewing(default, set):Int = EMPLOYEE_LOGIN;
+
+ private function set_viewing(value:Int):Int {
+ viewing = value;
+ dispatchEvent(new Event(VIEWING_CHANGE));
+ return viewing;
+ }
+
+ // user object contains uid/passwd
+ // its value gets set at login and cleared at logout but nothing binds to it or uses it
+ // retained since it was used in the original Adobe CafeTownsend example app
+ public var user(default, set):User;
+
+ private function set_user(value:User):User {
+ user = value;
+ dispatchEvent(new Event(USER_CHANGE));
+ return user;
+ }
+
+ // variable to store error messages from the httpservice
+ // nothinng currently binds to it, but an Alert or the login box could to show startup errors
+ public var errorStatus:String;
+
+ // contains the main employee list which is populated on startup
+ // mx:application's creationComplete event is mutated into a cairngorm event
+ // that calls the httpservice for the data
+ public var employeeListDP(default, set):ArrayCollection;
+
+ private function set_employeeListDP(value:ArrayCollection):ArrayCollection {
+ employeeListDP = value;
+ dispatchEvent(new Event(EMPLOYEE_LIST_DP_CHANGE));
+ return employeeListDP;
+ }
+
+ // temp holding space for employees we're creating or editing
+ // this gets copied into or added onto the main employee list
+ public var employeeTemp(default, set):Employee;
+
+ private function set_employeeTemp(value:Employee):Employee {
+ employeeTemp = value;
+ dispatchEvent(new Event(EMPLOYEE_TEMP_CHANGE));
+ return employeeTemp;
+ }
+
+ // singleton: constructor only allows one model locator
+ public function new() {
+ super();
+ if (AppModelLocator.model != null) {
+ throw new Error("Only one ModelLocator instance should be instantiated");
+ }
+ }
+
+ // singleton: always returns the one existing static instance to itself
+ public static function getInstance():AppModelLocator {
+ if (model == null)
+ model = new AppModelLocator();
+ return model;
+ }
+}
diff --git a/src/com/feathersui/cafetownsend/view/EmployeeDetail.hx b/src/com/feathersui/cafetownsend/view/EmployeeDetail.hx
new file mode 100644
index 0000000..9253867
--- /dev/null
+++ b/src/com/feathersui/cafetownsend/view/EmployeeDetail.hx
@@ -0,0 +1,165 @@
+/*
+ Cafe Townsend MVC Tutorial
+
+ Copyright 2006 Adobe
+
+ Converted to feathersui-cairngorm by Bowler Hat LLC
+ https://feathersui.com
+
+ Converted to Cairngorm 2 (Flex) by Darren Houle
+ http://www.digimmersion.com
+
+ This is released under a Creative Commons license.
+ http://creativecommons.org/licenses/by/2.5/
+
+ */
+
+package com.feathersui.cafetownsend.view;
+
+import com.adobe.cairngorm.control.CairngormEventDispatcher;
+import com.feathersui.cafetownsend.control.CancelEmployeeEditsEvent;
+import com.feathersui.cafetownsend.control.DeleteEmployeeEvent;
+import com.feathersui.cafetownsend.control.SaveEmployeeEditsEvent;
+import com.feathersui.cafetownsend.model.AppModelLocator;
+import feathers.controls.Alert;
+import feathers.controls.Button;
+import feathers.controls.Form;
+import feathers.controls.FormItem;
+import feathers.controls.Header;
+import feathers.controls.LayoutGroup;
+import feathers.controls.Panel;
+import feathers.controls.PopUpDatePicker;
+import feathers.controls.ScrollContainer;
+import feathers.controls.TextInput;
+import feathers.core.FocusManager;
+import feathers.events.TriggerEvent;
+import feathers.layout.AnchorLayout;
+import feathers.layout.AnchorLayoutData;
+import feathers.layout.ResponsiveGridLayout;
+import feathers.layout.ResponsiveGridLayoutData;
+
+class EmployeeDetail extends ScrollContainer {
+ private var model = AppModelLocator.getInstance();
+ private var details_frm:Form;
+ private var firstname:TextInput;
+ private var lastname:TextInput;
+ private var startdate:PopUpDatePicker;
+ private var email:TextInput;
+ private var submit_btn:Button;
+ private var delete_btn:Button;
+ private var cancel_btn:Button;
+
+ public function new() {
+ super();
+ }
+
+ override private function initialize():Void {
+ super.initialize();
+
+ var viewLayout = new ResponsiveGridLayout();
+ viewLayout.setPadding(10.0);
+ layout = viewLayout;
+
+ var panel = new Panel();
+ panel.layoutData = new ResponsiveGridLayoutData(12, 0, 8, 2, 6, 3, 4, 4);
+ panel.layout = new AnchorLayout();
+ addChild(panel);
+
+ var header = new Header("Employee Details");
+ panel.header = header;
+
+ cancel_btn = new Button();
+ cancel_btn.text = "Cancel";
+ cancel_btn.addEventListener(TriggerEvent.TRIGGER, cancel_btn_triggerHandler);
+ header.leftView = cancel_btn;
+
+ details_frm = new Form();
+ details_frm.layoutData = AnchorLayoutData.fill(10.0);
+ panel.addChild(details_frm);
+
+ firstname = new TextInput();
+ firstname.text = model.employeeTemp.firstname;
+ var firstname_fi = new FormItem("First Name:", firstname);
+ firstname_fi.required = true;
+ firstname_fi.horizontalAlign = JUSTIFY;
+ details_frm.addChild(firstname_fi);
+
+ lastname = new TextInput();
+ lastname.text = model.employeeTemp.lastname;
+ var lastname_fi = new FormItem("Last Name:", lastname);
+ lastname_fi.required = true;
+ lastname_fi.horizontalAlign = JUSTIFY;
+ details_frm.addChild(lastname_fi);
+
+ startdate = new PopUpDatePicker();
+ startdate.selectedDate = model.employeeTemp.startdate;
+ var startdate_fi = new FormItem("Start Date:", startdate);
+ startdate_fi.horizontalAlign = JUSTIFY;
+ details_frm.addChild(startdate_fi);
+
+ email = new TextInput();
+ email.text = model.employeeTemp.email;
+ var email_fi = new FormItem("Email:", email);
+ email_fi.required = true;
+ email_fi.horizontalAlign = JUSTIFY;
+ details_frm.addChild(email_fi);
+
+ var footer = new LayoutGroup();
+ footer.variant = LayoutGroup.VARIANT_TOOL_BAR;
+ panel.footer = footer;
+
+ submit_btn = new Button();
+ submit_btn.text = "Submit";
+ submit_btn.addEventListener(TriggerEvent.TRIGGER, submit_btn_triggerHandler);
+ footer.addChild(submit_btn);
+
+ delete_btn = new Button();
+ delete_btn.text = "Delete";
+ delete_btn.addEventListener(TriggerEvent.TRIGGER, delete_btn_triggerHandler);
+ footer.addChild(delete_btn);
+ }
+
+ private function cancelEmployeeEdits():Void {
+ var cgEvent = new CancelEmployeeEditsEvent();
+ CairngormEventDispatcher.getInstance().dispatchEvent(cgEvent);
+ }
+
+ private function saveEmployeeEdits():Void {
+ // first, validate the fields
+ var noFirstName = firstname.text == null || firstname.text.length == 0;
+ var noLastName = lastname.text == null || lastname.text.length == 0;
+ var noEmail = email.text == null || email.text.length == 0;
+ // if any of the fields were not valid
+ if (noFirstName || noLastName || noEmail) {
+ // return focus to the firstname field and do nothing else
+ FocusManager.setFocus(firstname);
+ return;
+ }
+ // to make it here the fields must have been valid
+ // create and broadcast a new cairngorm event with a payload containing the edited fields
+ var cgEvent = new SaveEmployeeEditsEvent(model.employeeTemp.emp_id, firstname.text, lastname.text, startdate.selectedDate, email.text);
+ CairngormEventDispatcher.getInstance().dispatchEvent(cgEvent);
+ }
+
+ private function deleteEmployee():Void {
+ // broadcast the cairngorm event
+ var cgEvent = new DeleteEmployeeEvent();
+ CairngormEventDispatcher.getInstance().dispatchEvent(cgEvent);
+ }
+
+ private function cancel_btn_triggerHandler(event:TriggerEvent):Void {
+ cancelEmployeeEdits();
+ }
+
+ private function submit_btn_triggerHandler(event:TriggerEvent):Void {
+ saveEmployeeEdits();
+ }
+
+ private function delete_btn_triggerHandler(event:TriggerEvent):Void {
+ Alert.show("Are you sure you want to delete the following employee?", "Delete employee?", ["OK", "Cancel"], state -> {
+ if (state.text == "OK") {
+ deleteEmployee();
+ }
+ });
+ }
+}
diff --git a/src/com/feathersui/cafetownsend/view/EmployeeList.hx b/src/com/feathersui/cafetownsend/view/EmployeeList.hx
new file mode 100644
index 0000000..a2d3741
--- /dev/null
+++ b/src/com/feathersui/cafetownsend/view/EmployeeList.hx
@@ -0,0 +1,130 @@
+/*
+ Cafe Townsend MVC Tutorial
+
+ Copyright 2006 Adobe
+
+ Converted to feathersui-cairngorm by Bowler Hat LLC
+ https://feathersui.com
+
+ Converted to Cairngorm 2 (Flex) by Darren Houle
+ http://www.digimmersion.com
+
+ This is released under a Creative Commons license.
+ http://creativecommons.org/licenses/by/2.5/
+
+ */
+
+package com.feathersui.cafetownsend.view;
+
+import feathers.layout.VerticalListLayout;
+import com.adobe.cairngorm.control.CairngormEventDispatcher;
+import com.feathersui.cafetownsend.control.AddNewEmployeeEvent;
+import com.feathersui.cafetownsend.control.LogoutEvent;
+import com.feathersui.cafetownsend.control.UpdateEmployeeEvent;
+import com.feathersui.cafetownsend.model.AppModelLocator;
+import com.feathersui.cafetownsend.vo.Employee;
+import feathers.controls.Button;
+import feathers.controls.Header;
+import feathers.controls.LayoutGroup;
+import feathers.controls.ListView;
+import feathers.controls.Panel;
+import feathers.controls.ScrollContainer;
+import feathers.events.ListViewEvent;
+import feathers.events.TriggerEvent;
+import feathers.layout.ResponsiveGridLayout;
+import feathers.layout.ResponsiveGridLayoutData;
+import feathers.layout.VerticalLayout;
+import feathers.layout.VerticalLayoutData;
+
+class EmployeeList extends ScrollContainer {
+ private var model = AppModelLocator.getInstance();
+ private var addEmployee_btn:Button;
+ private var logout_btn:Button;
+ private var employees_li:ListView;
+
+ public function new() {
+ super();
+ }
+
+ override private function initialize():Void {
+ super.initialize();
+
+ var viewLayout = new ResponsiveGridLayout();
+ viewLayout.setPadding(10.0);
+ layout = viewLayout;
+
+ var panel = new Panel();
+ panel.layoutData = new ResponsiveGridLayoutData(12, 0, 8, 2, 6, 3, 4, 4);
+ panel.layout = new VerticalLayout();
+ addChild(panel);
+
+ panel.header = new Header("Employee List");
+
+ var toolBar = new LayoutGroup();
+ toolBar.variant = LayoutGroup.VARIANT_TOOL_BAR;
+ toolBar.layoutData = VerticalLayoutData.fillHorizontal();
+ panel.addChild(toolBar);
+
+ addEmployee_btn = new Button();
+ addEmployee_btn.text = "Add New Employee";
+ addEmployee_btn.addEventListener(TriggerEvent.TRIGGER, addEmployee_btn_triggerHandler);
+ toolBar.addChild(addEmployee_btn);
+
+ logout_btn = new Button();
+ logout_btn.text = "Logout";
+ logout_btn.addEventListener(TriggerEvent.TRIGGER, logout_btn_triggerHandler);
+ toolBar.addChild(logout_btn);
+
+ employees_li = new ListView();
+ employees_li.layoutData = VerticalLayoutData.fillHorizontal();
+ employees_li.dataProvider = model.employeeListDP;
+ employees_li.itemToText = (item:Employee) -> item.lastname + ", " + item.firstname;
+ var listLayout = new VerticalListLayout();
+ listLayout.requestedMinRowCount = 5.0;
+ employees_li.layout = listLayout;
+ employees_li.addEventListener(ListViewEvent.ITEM_TRIGGER, employees_li_itemTriggerHandler);
+ panel.addChild(employees_li);
+ }
+
+ // mutate the logout button's click event
+ private function logout():Void {
+ // broadcast a cairngorm event
+ var cgEvent = new LogoutEvent();
+ CairngormEventDispatcher.getInstance().dispatchEvent(cgEvent);
+ }
+
+ // mutate the add new employee button's click event
+ public function addNewEmployee():Void {
+ // broadcast a cairngorm event
+ var cgEvent = new AddNewEmployeeEvent();
+ CairngormEventDispatcher.getInstance().dispatchEvent(cgEvent);
+ // de-select the list item (it may not exist next time we're on this view)
+ clearSelectedEmployee();
+ }
+
+ // mutate the List's change event
+ public function updateEmployee(employee:Employee):Void {
+ // boardcast a cairngorm event that contains the selectedItem from the List
+ var cgEvent = new UpdateEmployeeEvent(employee);
+ CairngormEventDispatcher.getInstance().dispatchEvent(cgEvent);
+ // de-select the list item (it may not exist next time we're on this view)
+ clearSelectedEmployee();
+ }
+
+ // de-select any selected List items
+ private function clearSelectedEmployee():Void {
+ employees_li.selectedIndex = -1;
+ }
+
+ private function addEmployee_btn_triggerHandler(event:TriggerEvent):Void {
+ addNewEmployee();
+ }
+
+ private function employees_li_itemTriggerHandler(event:ListViewEvent):Void {
+ updateEmployee((event.state.data : Employee));
+ }
+
+ private function logout_btn_triggerHandler(event:TriggerEvent):Void {
+ logout();
+ }
+}
diff --git a/src/com/feathersui/cafetownsend/view/EmployeeLogin.hx b/src/com/feathersui/cafetownsend/view/EmployeeLogin.hx
new file mode 100644
index 0000000..d57095b
--- /dev/null
+++ b/src/com/feathersui/cafetownsend/view/EmployeeLogin.hx
@@ -0,0 +1,117 @@
+/*
+ Cafe Townsend MVC Tutorial
+
+ Copyright 2006 Adobe
+
+ Converted to feathersui-cairngorm by Bowler Hat LLC
+ https://feathersui.com
+
+ Converted to Cairngorm 2 (Flex) by Darren Houle
+ http://www.digimmersion.com
+
+ This is released under a Creative Commons license.
+ http://creativecommons.org/licenses/by/2.5/
+
+ */
+
+package com.feathersui.cafetownsend.view;
+
+import com.adobe.cairngorm.control.CairngormEventDispatcher;
+import com.feathersui.cafetownsend.control.LoginEvent;
+import com.feathersui.cafetownsend.model.AppModelLocator;
+import feathers.controls.Button;
+import feathers.controls.Form;
+import feathers.controls.FormItem;
+import feathers.controls.Header;
+import feathers.controls.Label;
+import feathers.controls.LayoutGroup;
+import feathers.controls.Panel;
+import feathers.controls.ScrollContainer;
+import feathers.controls.TextInput;
+import feathers.events.TriggerEvent;
+import feathers.layout.AnchorLayout;
+import feathers.layout.AnchorLayoutData;
+import feathers.layout.HorizontalLayoutData;
+import feathers.layout.ResponsiveGridLayout;
+import feathers.layout.ResponsiveGridLayoutData;
+
+class EmployeeLogin extends ScrollContainer {
+ private var model = AppModelLocator.getInstance();
+ private var login_frm:Form;
+ private var username:TextInput;
+ private var password:TextInput;
+ private var login_btn:Button;
+
+ public function new() {
+ super();
+ }
+
+ override private function initialize():Void {
+ super.initialize();
+
+ var viewLayout = new ResponsiveGridLayout();
+ viewLayout.setPadding(10.0);
+ layout = viewLayout;
+
+ var panel = new Panel();
+ panel.layoutData = new ResponsiveGridLayoutData(12, 0, 8, 2, 6, 3, 4, 4);
+ panel.layout = new AnchorLayout();
+ panel.header = new Header("Cafe Townsend Login");
+ addChild(panel);
+
+ login_frm = new Form();
+ login_frm.layoutData = AnchorLayoutData.fill(10.0);
+ panel.addChild(login_frm);
+
+ username = new TextInput();
+ var username_fi = new FormItem("Username:", username);
+ username_fi.required = true;
+ username_fi.horizontalAlign = JUSTIFY;
+ login_frm.addChild(username_fi);
+
+ password = new TextInput();
+ password.displayAsPassword = true;
+ var password_fi = new FormItem("Password:", password);
+ password_fi.required = true;
+ password_fi.horizontalAlign = JUSTIFY;
+ login_frm.addChild(password_fi);
+
+ login_btn = new Button();
+ login_btn.text = "Login";
+ login_btn.addEventListener(TriggerEvent.TRIGGER, login_btn_triggerHandler);
+ login_frm.addChild(login_btn);
+
+ var footer = new LayoutGroup();
+ footer.variant = LayoutGroup.VARIANT_TOOL_BAR;
+ var instructions = new Label();
+ instructions.text = "Username: Feathers Password: Cairngorm";
+ instructions.wordWrap = true;
+ instructions.layoutData = HorizontalLayoutData.fillHorizontal();
+ footer.addChild(instructions);
+ panel.footer = footer;
+ }
+
+ // mutate the loginBtn's click event into a cairngorm event
+ private function loginEmployee():Void {
+ // validate the fields
+ var noUsername = username.text == null || username.text.length == 0;
+ var noPassword = password.text == null || password.text.length == 0;
+ if (noUsername || noPassword) {
+ return;
+ } else {
+ // if everything validates, broadcast an event containing the username & password
+ var cgEvent = new LoginEvent(username.text, password.text);
+ CairngormEventDispatcher.getInstance().dispatchEvent(cgEvent);
+
+ // now that the fields are sent in the event, blank out the login form fields
+ // otherwise they'll still be populated whenever the user returns here
+ // (if the user does not get the uid/passwd correct or when the user logs out)
+ username.text = "";
+ password.text = "";
+ }
+ }
+
+ private function login_btn_triggerHandler(event:TriggerEvent):Void {
+ loginEmployee();
+ }
+}
diff --git a/src/com/feathersui/cafetownsend/vo/Employee.hx b/src/com/feathersui/cafetownsend/vo/Employee.hx
new file mode 100644
index 0000000..ff0fb17
--- /dev/null
+++ b/src/com/feathersui/cafetownsend/vo/Employee.hx
@@ -0,0 +1,35 @@
+/*
+ Cafe Townsend MVC Tutorial
+
+ Copyright 2006 Adobe
+
+ Converted to feathersui-cairngorm by Bowler Hat LLC
+ https://feathersui.com
+
+ Converted to Cairngorm 2 (Flex) by Darren Houle
+ http://www.digimmersion.com
+
+ This is released under a Creative Commons license.
+ http://creativecommons.org/licenses/by/2.5/
+
+ */
+
+package com.feathersui.cafetownsend.vo;
+
+class Employee {
+ private static var currentIndex = 1000;
+
+ public var emp_id:Int;
+ public var firstname:String;
+ public var lastname:String;
+ public var email:String;
+ public var startdate:Date;
+
+ public function new(emp_id:Int = 0, firstname:String = "", lastname:String = "", email = "", startdate:Date = null) {
+ this.emp_id = (emp_id == 0) ? currentIndex++ : emp_id;
+ this.firstname = firstname;
+ this.lastname = lastname;
+ this.email = email;
+ this.startdate = (startdate == null) ? Date.now() : startdate;
+ }
+}
diff --git a/src/com/feathersui/cafetownsend/vo/User.hx b/src/com/feathersui/cafetownsend/vo/User.hx
new file mode 100644
index 0000000..79b213e
--- /dev/null
+++ b/src/com/feathersui/cafetownsend/vo/User.hx
@@ -0,0 +1,27 @@
+/*
+ Cafe Townsend MVC Tutorial
+
+ Copyright 2006 Adobe
+
+ Converted to feathersui-cairngorm by Bowler Hat LLC
+ https://feathersui.com
+
+ Converted to Cairngorm 2 (Flex) by Darren Houle
+ http://www.digimmersion.com
+
+ This is released under a Creative Commons license.
+ http://creativecommons.org/licenses/by/2.5/
+
+ */
+
+package com.feathersui.cafetownsend.vo;
+
+class User {
+ public var username:String;
+ public var password:String;
+
+ public function new(username:String, password:String) {
+ this.username = username;
+ this.password = password;
+ }
+}