first commit

This commit is contained in:
2025-11-13 14:07:15 +01:00
parent 8be7c1305a
commit 40d35f8b48
31 changed files with 1432 additions and 0 deletions
Vendored
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+31
View File
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<employees>
<employee>
<emp_id>1</emp_id>
<firstname>Sue</firstname>
<lastname>Hove</lastname>
<email>shove@cafetownsend.com</email>
<startdate>2006-01-07</startdate>
</employee>
<employee>
<emp_id>2</emp_id>
<firstname>Matt</firstname>
<lastname>Boles</lastname>
<email>mboles@cafetownsend.com</email>
<startdate>2006-02-17</startdate>
</employee>
<employee>
<emp_id>3</emp_id>
<firstname>Mike</firstname>
<lastname>Kollen</lastname>
<email>mkollen@cafetownsend.com</email>
<startdate>2006-03-01</startdate>
</employee>
<employee>
<emp_id>4</emp_id>
<firstname>Jennifer</firstname>
<lastname>Jaegel</lastname>
<email>jjaegel@cafetownsend.com</email>
<startdate>2006-04-01</startdate>
</employee>
</employees>
+9
View File
@@ -0,0 +1,9 @@
<svg id="feathersui-icon" xmlns="http://www.w3.org/2000/svg" width="1024" height="1024">
<rect class="cls-1" width="1024" height="1024" rx="170" ry="170" style="fill: #ff8b26;"/>
<circle class="cls-2" cx="512" cy="512" r="444.156" style="fill: #f2eae4;"/>
<g id="Wings">
<path id="Rectangle_3_copy_3" data-name="Rectangle 3 copy 3" class="cls-3" d="M532.228,620.778H762.353v114.9H532.228v-114.9Z" style="fill: #ffc28c;fill-rule: evenodd;"/>
<path id="Rectangle_3_copy_4" data-name="Rectangle 3 copy 4" class="cls-4" d="M379.028,486.553H762.353V601.6H379.028V486.553Z" style="fill: #ffa759;fill-rule: evenodd;"/>
<path id="Rectangle_3_copy_5" data-name="Rectangle 3 copy 5" class="cls-5" d="M225.678,352.353H762.353V467.4H225.678V352.353Z" style="fill: #ff8b26;fill-rule: evenodd;"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 815 B

+22
View File
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<project>
<meta title="CafeTownsend" package="com.feathersui.samples.cairngorm.CafeTownsend" version="1.0.0" company="Bowler Hat LLC"/>
<meta title="Cafe Townsend Cairngorm — Feathers UI Samples" if="html5"/>
<app main="com.feathersui.cafetownsend.Main" file="CafeTownsend"/>
<window allow-high-dpi="true"/>
<window fps="60"/>
<window fps="0" if="html5"/>
<source path="src"/>
<haxelib name="openfl"/>
<haxelib name="actuate"/>
<haxelib name="feathersui"/>
<haxelib name="feathersui-cairngorm"/>
<icon path="assets/icons/feathersui-icon.svg"/>
<!-- copies data/Employees.xml to output -->
<assets path="assets/data" rename="data" embed="false"/>
</project>
+85
View File
@@ -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);
}
}
}
@@ -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);
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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<Employee> = [];
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.";
}
}
@@ -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"]);
}
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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);
}
}
@@ -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);
}
}
@@ -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);
}
}
@@ -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);
}
}
@@ -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);
}
}
@@ -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;
}
}
@@ -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);
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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<Employee>;
private function set_employeeListDP(value:ArrayCollection<Employee>):ArrayCollection<Employee> {
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;
}
}
@@ -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();
}
});
}
}
@@ -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();
}
}
@@ -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();
}
}
@@ -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;
}
}
@@ -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;
}
}