You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@royale.apache.org by ca...@apache.org on 2020/01/30 10:19:03 UTC
[royale-asjs] branch develop updated: todomvc-jewel-example:
refactor to separate pieces and make it more "mvc"
This is an automated email from the ASF dual-hosted git repository.
carlosrovira pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git
The following commit(s) were added to refs/heads/develop by this push:
new e67f344 todomvc-jewel-example: refactor to separate pieces and make it more "mvc"
e67f344 is described below
commit e67f3449023540d2ea7d471ce54b763e8269792b
Author: Carlos Rovira <ca...@apache.org>
AuthorDate: Thu Jan 30 11:18:40 2020 +0100
todomvc-jewel-example: refactor to separate pieces and make it more "mvc"
---
.../todomvc/src/main/resources/todomvc-styles.css | 21 +-
examples/jewel/todomvc/src/main/royale/App.mxml | 3 +-
.../jewel/todomvc/controllers/TodoController.as | 177 +++++++++++++++++
.../main/royale/jewel/todomvc/events/TodoEvent.as | 68 +++++++
.../main/royale/jewel/todomvc/models/TodoModel.as | 134 +++++++++++++
.../jewel/todomvc/renderers/TodoItemRenderer.mxml | 92 +++++----
.../royale/jewel/todomvc/views/MainContent.mxml | 218 ---------------------
.../royale/jewel/todomvc/views/TodoFooter.mxml | 99 ++++++++++
.../royale/jewel/todomvc/views/TodoHeader.mxml | 74 +++++++
.../jewel/todomvc/views/TodoListSection.mxml | 87 ++++++++
10 files changed, 711 insertions(+), 262 deletions(-)
diff --git a/examples/jewel/todomvc/src/main/resources/todomvc-styles.css b/examples/jewel/todomvc/src/main/resources/todomvc-styles.css
index 4b27e31..24264b3 100644
--- a/examples/jewel/todomvc/src/main/resources/todomvc-styles.css
+++ b/examples/jewel/todomvc/src/main/resources/todomvc-styles.css
@@ -21,6 +21,15 @@
@namespace "http://www.w3.org/1999/xhtml";
@namespace j "library://ns.apache.org/royale/jewel";
+@namespace todomvc "jewel.todomvc.views.*";
+
+/* Add Controller and Model beads to TodoListSectionComponent */
+todomvc|TodoListSection
+{
+ IBeadController: ClassReference("jewel.todomvc.controllers.TodoController");
+ IBeadModel: ClassReference("jewel.todomvc.models.TodoModel");
+}
+
/* Application */
.jewel.application {
@@ -65,7 +74,7 @@
margin: 3px;
padding: 3px 7px;
background: none;
- border: none;
+ border: 1px solid transparent;
box-shadow: none;
border-radius: 0.25rem;
color: #808080;
@@ -75,15 +84,17 @@
}
.jewel.button:hover, .jewel.button:hover:focus {
background: none;
- border: none;
+ border: 1px solid transparent;
+
+ text-decoration: underline;
}
.jewel.button:active, .jewel.button:active:focus {
background: none;
- border: none;
+ border: 1px solid transparent;
box-shadow: none;
}
.jewel.button:focus {
- border: none;
+ border: 1px solid transparent;
box-shadow: none;
}
@@ -105,7 +116,7 @@
}
.jewel.togglebutton:active, .jewel.togglebutton:active:focus {
background: none;
- border: 1px solid rgba(175,47,47,.2);;
+ border: 1px solid rgba(175,47,47,.2);
box-shadow: none;
}
.jewel.togglebutton:focus {
diff --git a/examples/jewel/todomvc/src/main/royale/App.mxml b/examples/jewel/todomvc/src/main/royale/App.mxml
index 6e0b7ac..546447b 100644
--- a/examples/jewel/todomvc/src/main/royale/App.mxml
+++ b/examples/jewel/todomvc/src/main/royale/App.mxml
@@ -28,6 +28,7 @@
</j:valuesImpl>
<j:initialView>
- <views:MainContent/>
+ <views:TodoListSection/>
</j:initialView>
+
</j:Application>
diff --git a/examples/jewel/todomvc/src/main/royale/jewel/todomvc/controllers/TodoController.as b/examples/jewel/todomvc/src/main/royale/jewel/todomvc/controllers/TodoController.as
new file mode 100644
index 0000000..62f05d7
--- /dev/null
+++ b/examples/jewel/todomvc/src/main/royale/jewel/todomvc/controllers/TodoController.as
@@ -0,0 +1,177 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package jewel.todomvc.controllers
+{
+ import jewel.todomvc.events.TodoEvent;
+ import jewel.todomvc.models.TodoModel;
+ import jewel.todomvc.vos.TodoVO;
+
+ import org.apache.royale.core.IBeadController;
+ import org.apache.royale.core.IBeadModel;
+ import org.apache.royale.core.IStrand;
+ import org.apache.royale.events.IEventDispatcher;
+
+ [Bindable]
+ /**
+ * The Todo Controller holds all the global actions. The views dispatch events that bubbles and
+ * this class register to these evens and updates the model, so views can update accordingly using
+ * binding most of the times.
+ */
+ public class TodoController implements IBeadController
+ {
+ /**
+ * constructor.
+ */
+ public function TodoController():void
+ {
+ }
+
+ private var _strand:IStrand;
+ /**
+ * @copy org.apache.royale.core.IBead#strand
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10.2
+ * @playerversion AIR 2.6
+ * @productversion Royale 0.9.7
+ */
+ public function set strand(value:IStrand):void {
+ _strand = value;
+ IEventDispatcher(_strand).addEventListener(TodoEvent.ADD_TODO_ITEM, addTodoItem);
+ IEventDispatcher(_strand).addEventListener(TodoEvent.MARK_ALL_COMPLETE, markAllComplete);
+ IEventDispatcher(_strand).addEventListener(TodoEvent.REMOVE_COMPLETED, removeCompleted);
+ IEventDispatcher(_strand).addEventListener(TodoEvent.REFRESH_LIST, refreshList);
+ IEventDispatcher(_strand).addEventListener(TodoEvent.ITEM_STATE_CHANGED, itemStateChangedHandler);
+ IEventDispatcher(_strand).addEventListener(TodoEvent.ITEM_LABEL_CHANGED, itemLabelChangedHandler);
+ IEventDispatcher(_strand).addEventListener(TodoEvent.ITEM_REMOVED, itemRemovedHandler);
+
+ model = _strand.getBeadByType(IBeadModel) as TodoModel;
+ model.listItems = model.allItems;
+ }
+
+ /**
+ * Common todo model
+ */
+ private var model:TodoModel;
+
+ /**
+ * Add the todo item to the list and refresh the list state
+ */
+ protected function addTodoItem(event:TodoEvent):void {
+ model.allItems.addItem(event.todo);
+ updateInterface();
+ }
+
+ /**
+ * Mark all todo items as completed and update items left and clear completed button visibility
+ */
+ protected function markAllComplete(event:TodoEvent):void {
+ var len:int = model.allItems.length
+ var item:TodoVO;
+ for(var i:int = 0; i < len; i++) {
+ item = TodoVO(model.allItems.getItemAt(i));
+ item.done = true;
+ }
+
+ updateInterface();
+ }
+
+ /**
+ * Remove all completed todo items, update footer and toggle all button visibility
+ */
+ protected function removeCompleted(event:TodoEvent):void {
+ var l:uint = model.allItems.length;
+ var item:TodoVO;
+ while(l--) {
+ item = TodoVO(model.allItems.getItemAt(l));
+ if(item.done){
+ model.allItems.removeItem(item);
+ }
+ }
+
+ model.footerVisibility = model.allItems.length != 0 ? true : false;
+ model.toogleAllVisibility = model.allItems.length != 0 ? true : false;
+ }
+
+ /**
+ * Refresh the todo list to the appropiate filter state (All, Active or Completed)
+ */
+ protected function refreshList(event:TodoEvent):void
+ {
+ model.filterState = event.label;
+ setListState();
+ }
+
+ /**
+ * Sets the new state filter and refresh list to match the filter
+ */
+ protected function setListState():void {
+ // setting to the same collection must cause refreshed too
+ model.listItems = null;
+
+ model.activeItems.refresh();
+ model.completedItems.refresh();
+
+ if(model.filterState == TodoModel.ALL_FILTER) {
+ model.listItems = model.allItems;
+ }
+ else if(model.filterState == TodoModel.ACTIVE_FILTER) {
+ model.listItems = model.activeItems;
+ }
+ else if(model.filterState == TodoModel.COMPLETED_FILTER) {
+ model.listItems = model.completedItems;
+ }
+ }
+
+ /**
+ * When some todo item change state (done/undone), we must update the interface accordingly
+ */
+ public function itemStateChangedHandler(event:TodoEvent = null):void {
+ event.todo.done = event.completion;
+ updateInterface();
+ }
+
+ /**
+ * Commit the label changes to the item
+ */
+ public function itemLabelChangedHandler(event:TodoEvent = null):void {
+ event.todo.label = event.label;
+ }
+
+ /**
+ * When the user click in the renderer destroy button we must remove the item and update the interface
+ */
+ public function itemRemovedHandler(event:TodoEvent):void {
+ model.allItems.removeItem(event.todo);
+ updateInterface();
+ }
+
+ /**
+ * Update the interface accordingly
+ */
+ public function updateInterface():void {
+ setListState();
+
+ model.itemsLeftLabel = model.activeItems.length + " item left";
+ model.clearCompletedVisibility = model.completedItems.length != 0 ? true : false;
+ model.footerVisibility = model.allItems.length != 0 ? true : false;
+ model.toogleAllVisibility = model.allItems.length != 0 ? true : false;
+ }
+ }
+}
diff --git a/examples/jewel/todomvc/src/main/royale/jewel/todomvc/events/TodoEvent.as b/examples/jewel/todomvc/src/main/royale/jewel/todomvc/events/TodoEvent.as
new file mode 100644
index 0000000..bdb2517
--- /dev/null
+++ b/examples/jewel/todomvc/src/main/royale/jewel/todomvc/events/TodoEvent.as
@@ -0,0 +1,68 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package jewel.todomvc.events
+{
+ import jewel.todomvc.vos.TodoVO;
+
+ import org.apache.royale.events.Event;
+
+ /**
+ * Todo Event
+ */
+ public class TodoEvent extends Event
+ {
+ /**
+ * Actions
+ */
+ public static const ADD_TODO_ITEM:String = "add_Todo_Item";
+ public static const MARK_ALL_COMPLETE:String = "mark_all_complete";
+ public static const REMOVE_COMPLETED:String = "remove_completed";
+ public static const REFRESH_LIST:String = "refresh_list";
+
+ public static const ITEM_STATE_CHANGED:String = "item_state_changed";
+ public static const ITEM_LABEL_CHANGED:String = "item_label_changed";
+ public static const ITEM_REMOVED:String = "item_removed";
+
+ /**
+ * The todo to pass between layers
+ */
+ public var todo:TodoVO;
+
+ /**
+ * Use to send the filter state label or the changes in a todo item label
+ */
+ public var label:String;
+
+ /**
+ * To send the state of the item (done/undone)
+ */
+ public var completion:Boolean;
+
+ /**
+ * constructor
+ */
+ public function TodoEvent(type:String, todo:TodoVO = null, label:String = null, completion:Boolean = false) {
+ super(type, true);
+
+ this.todo = todo;
+ this.label = label;
+ this.completion = completion
+ }
+ }
+}
\ No newline at end of file
diff --git a/examples/jewel/todomvc/src/main/royale/jewel/todomvc/models/TodoModel.as b/examples/jewel/todomvc/src/main/royale/jewel/todomvc/models/TodoModel.as
new file mode 100644
index 0000000..22dcdc5
--- /dev/null
+++ b/examples/jewel/todomvc/src/main/royale/jewel/todomvc/models/TodoModel.as
@@ -0,0 +1,134 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package jewel.todomvc.models
+{
+ import jewel.todomvc.vos.TodoVO;
+
+ import org.apache.royale.collections.ArrayList;
+ import org.apache.royale.collections.ArrayListView;
+ import org.apache.royale.core.IBeadModel;
+ import org.apache.royale.core.IStrand;
+ import org.apache.royale.events.EventDispatcher;
+
+ [Bindable]
+ /**
+ * Todo Model stores global model variables that are updated by controller
+ * and used in views to update visuals for the user
+ */
+ public class TodoModel extends EventDispatcher implements IBeadModel
+ {
+ /**
+ * We have three todo list states: All, Active and Completed
+ */
+ public static const ALL_FILTER:String = "All";
+ public static const ACTIVE_FILTER:String = "Active";
+ public static const COMPLETED_FILTER:String = "Completed";
+
+ /**
+ * constructor.
+ */
+ public function TodoModel():void
+ {
+ activeItems = filterItems(isActive);
+ completedItems = filterItems(isCompleted);
+ }
+
+ private var _strand:IStrand;
+ /**
+ * @copy org.apache.royale.core.IBead#strand
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10.2
+ * @playerversion AIR 2.6
+ * @productversion Royale 0.9.7
+ */
+ public function set strand(value:IStrand):void {
+ _strand = value;
+ }
+
+ /**
+ * the list of items binded to the todo list component
+ */
+ public var listItems:Object;
+
+ /**
+ * the real list with all items
+ */
+ public var allItems:ArrayList = new ArrayList();
+
+ /**
+ * the filtered list with active items
+ */
+ public var activeItems:ArrayListView;
+
+ /**
+ * the filtered list with completed items
+ */
+ public var completedItems:ArrayListView;
+
+ /**
+ * Filter the items in the list creating an ArrayListView with the right filter function
+ */
+ public function filterItems(filterFunction:Function = null):ArrayListView {
+ var alv:ArrayListView = new ArrayListView(allItems);
+ alv.filterFunction = filterFunction;
+ alv.refresh();
+ return alv;
+ }
+
+ /**
+ * filterFunction for the ArrayListView to get active items
+ */
+ public function isActive(item:TodoVO):Boolean {
+ return item && item.done == false;
+ }
+
+ /**
+ * filterFunction for the ArrayListView to get completed items
+ */
+ public function isCompleted(item:TodoVO):Boolean {
+ return item && item.done == true;
+ }
+
+ /**
+ * Stores the current filter for the list
+ */
+ public var filterState:String = TodoModel.ALL_FILTER;
+
+ /**
+ * how many items left to do
+ */
+ public var itemsLeftLabel:String = "0 items left";
+
+ /**
+ * footer bar visibility
+ */
+ public var footerVisibility:Boolean = false;
+
+ /**
+ * toggle all button visibility
+ */
+ public var toogleAllVisibility:Boolean = false;
+
+ /**
+ * clear completed button visibility
+ */
+ public var clearCompletedVisibility:Boolean = false;
+ }
+}
diff --git a/examples/jewel/todomvc/src/main/royale/jewel/todomvc/renderers/TodoItemRenderer.mxml b/examples/jewel/todomvc/src/main/royale/jewel/todomvc/renderers/TodoItemRenderer.mxml
index 3365ea3..55284af 100644
--- a/examples/jewel/todomvc/src/main/royale/jewel/todomvc/renderers/TodoItemRenderer.mxml
+++ b/examples/jewel/todomvc/src/main/royale/jewel/todomvc/renderers/TodoItemRenderer.mxml
@@ -20,70 +20,86 @@ limitations under the License.
<j:ListItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:j="library://ns.apache.org/royale/jewel"
xmlns:js="library://ns.apache.org/royale/basic"
- width="100%" hoverable="false" selectable="false"
+ hoverable="false" selectable="false" width="100%"
rollOver="rollOverHandler(event)"
rollOut="rollOutHandler(event)">
<fx:Script>
<![CDATA[
+ import jewel.todomvc.events.TodoEvent;
import jewel.todomvc.vos.TodoVO;
import org.apache.royale.events.Event;
import org.apache.royale.events.MouseEvent;
- import org.apache.royale.jewel.List;
- import org.apache.royale.jewel.beads.views.ListView;
-
- public var host:List;
-
+
+ /**
+ * Used to know if mouse is over this render in order to
+ * show destroy button when exit editing state
+ */
+ private var mouseIsOverRenderer:Boolean = false;
+
+ /**
+ * the item used in bindnigs for this renderer
+ */
[Bindable("dataChange")]
public function get item():TodoVO {
return data as TodoVO;
}
- override public function set data(value:Object):void
- {
- if (value != data)
- {
- super.data = value;
- dispatchEvent(new Event("dataChange"));
- trace(description)
- }
+ /**
+ * Change the item state between done/undone
+ */
+ public function changeItemState(event:Event):void {
+ dispatchEvent(new TodoEvent(TodoEvent.ITEM_STATE_CHANGED, item, null, event.target.selected));
}
- public function clickCloseButton(event:MouseEvent):void {
- var view:ListView = itemRendererParent as ListView;
- host = view.host as List;
- dispatchEvent(new Event("removeItem", true));
+ /**
+ * Destroy this todo item
+ */
+ public function removeItemClickHandler(event:MouseEvent):void {
+ dispatchEvent(new TodoEvent(TodoEvent.ITEM_REMOVED, item));
}
- public function edit(event:Event):void {
- item.label = event.target.text;
+ /**
+ * If user made changes to label, commit changes to the todo item and exit 'editing' state
+ */
+ public function updateLabelAndExit(event:Event):void {
+ if(item.label != event.target.text)
+ dispatchEvent(new TodoEvent(TodoEvent.ITEM_LABEL_CHANGED, item, event.target.text));
currentState = 'normal';
+ if(mouseIsOverRenderer)
+ destroy_btn.visible = true;
}
- public function changeItemState(event:Event):void {
- item.done = event.target.selected;
- dispatchEvent(new Event("itemStateChanged", true));
- }
-
+ /**
+ * Change renderer state to edit mode by double clicking in the todo item label
+ */
public function goToEditMode(event:MouseEvent):void
{
editfield.text = description.text;
currentState = "editing";
- closeBtn.visible = false;
+ destroy_btn.visible = false;
editfield.setFocus();
}
- public function rollOverHandler(event:Event):void
+ /**
+ * Show destroy button when user rolls over the renderer
+ */
+ public function rollOverHandler(event:MouseEvent):void
{
+ mouseIsOverRenderer = true;
if(currentState == "normal")
- closeBtn.visible = true;
+ destroy_btn.visible = true;
}
- public function rollOutHandler(event:Event):void
+ /**
+ * Hide destroy button when user rolls out the renderer
+ */
+ public function rollOutHandler(event:MouseEvent):void
{
+ mouseIsOverRenderer = false;
if(currentState == "normal")
- closeBtn.visible = false;
+ destroy_btn.visible = false;
}
]]>
</fx:Script>
@@ -98,22 +114,22 @@ limitations under the License.
<js:ItemRendererDataBinding />
</j:beads>
- <j:CheckBox
- selected="{item ? (item.done ? true : false) : false }"
- click="changeItemState(event);"
- visible.normal="true" visible.editing="false"/>
+ <j:CheckBox selected="{item ? (item.done ? true : false) : false }"
+ visible.normal="true" visible.editing="false"
+ click="changeItemState(event);"/>
<j:Label localId="description" width="100%"
text="{item ? item.label : ''}" multiline="true"
- doubleClick="goToEditMode(event)"
visible.normal="true" visible.editing="false"
- className="{item ? (item.done ? 'todolabel completed' : 'todolabel') : 'todolabel' }"/>
+ className="{item ? (item.done ? 'todolabel completed' : 'todolabel') : 'todolabel' }"
+ doubleClick="goToEditMode(event)"/>
<j:TextInput localId="editfield" width="100%"
visible.normal="false" visible.editing="true"
- enter="edit(event)"/>
+ enter="updateLabelAndExit(event)"/>
- <j:IconButton localId="closeBtn" click="clickCloseButton(event)" visible="false" className="destroy">
+ <j:IconButton localId="destroy_btn" visible="false" className="destroy"
+ click="removeItemClickHandler(event)">
<j:icon>
<js:FontIcon text="{MaterialIconType.CLOSE}" material="true"/>
</j:icon>
diff --git a/examples/jewel/todomvc/src/main/royale/jewel/todomvc/views/MainContent.mxml b/examples/jewel/todomvc/src/main/royale/jewel/todomvc/views/MainContent.mxml
deleted file mode 100644
index b5c4c6c..0000000
--- a/examples/jewel/todomvc/src/main/royale/jewel/todomvc/views/MainContent.mxml
+++ /dev/null
@@ -1,218 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-
-Licensed to the Apache Software Foundation (ASF) under one or more
-contributor license agreements. See the NOTICE file distributed with
-this work for additional information regarding copyright ownership.
-The ASF licenses this file to You under the Apache License, Version 2.0
-(the "License"); you may not use this file except in compliance with
-the License. You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
--->
-<j:View xmlns:fx="http://ns.adobe.com/mxml/2009"
- xmlns:j="library://ns.apache.org/royale/jewel"
- xmlns:js="library://ns.apache.org/royale/basic"
- xmlns:html="library://ns.apache.org/royale/html"
- initComplete="setUp()">
-
- <fx:Script>
- <![CDATA[
- import jewel.todomvc.vos.TodoVO;
-
- import org.apache.royale.collections.ArrayList;
- import org.apache.royale.collections.ArrayListView;
- import org.apache.royale.events.Event;
-
- [Bindable]
- public var items:ArrayList = new ArrayList();
-
- [Bindable]
- public var completedItems:ArrayListView;
-
- [Bindable]
- public var activeItems:ArrayListView;
-
- public function setUp():void {
- todolist.addEventListener("itemStateChanged", itemStateChangedHandler);
- todolist.addEventListener("removeItem", removeItemHandler);
-
- activeItems = itemsCompleted(items, isActive);
- completedItems = itemsCompleted(items, isCompleted);
- }
-
- private function addItem(event:Event):void {
- if(event.target.text == "") return;
- var newItem:TodoVO = new TodoVO(event.target.text);
- items.addItem(newItem);
- event.target.text = "";
- itemStateChangedHandler();
- }
-
- public function itemsCompleted(listOfItems:ArrayList, filterFunction:Function = null):ArrayListView {
- var alv:ArrayListView = new ArrayListView(listOfItems);
- alv.filterFunction = filterFunction;
- alv.refresh();
- return alv;
- }
-
- public function allItems(item:TodoVO):Boolean {
- return true;
- }
-
- public function isActive(item:TodoVO):Boolean {
- return item && item.done == false;
- }
-
- public function isCompleted(item:TodoVO):Boolean {
- return item && item.done == true;
- }
-
- //Mark all as complete
- public function markAllAsComplete():void {
- var len:int = items.length
- var item:TodoVO;
- for(var i:int = 0; i < len; i++)
- {
- item = TodoVO(items.getItemAt(i));
- item.done = true;
- }
- }
-
- public function removeCompleted():void {
- var l:uint = items.length;
- var item:TodoVO;
- while(l--) {
- item = TodoVO(items.getItemAt(l));
- if(item.done){
- items.removeItem(item);
- }
- }
- clearCompleted.visible = false;
- toogleAll.visible = footer.visible = itemsCompleted(items, null).length != 0 ? true : false;
-
- if(all_btn.selected)
- selectFilter(all_btn.text);
- else if(active_btn.selected)
- selectFilter(active_btn.text);
- else if(completed_btn.selected)
- selectFilter(completed_btn.text);
- }
-
- public function itemStateChangedHandler(event:Event = null):void {
- itemsLeft.text = itemsCompleted(items, isActive).length + " item left";
- clearCompleted.visible = itemsCompleted(items, isCompleted).length != 0 ? true : false;
- toogleAll.visible = footer.visible = itemsCompleted(items, null).length != 0 ? true : false;
- }
-
- public function removeItemHandler(event:Event):void {
- items.removeItem(event.target.data);
- itemStateChangedHandler();
- }
-
- public function toggleButtonClickHandler(event:Event):void {
- selectFilter(event.target.text);
- }
- public function selectFilter(label:String):void {
- if(label == "All")
- {
- active_btn.selected = false;
- completed_btn.selected = false;
-
- todolist.dataProvider = items;
- }
- else if(label == "Active")
- {
- all_btn.selected = false;
- completed_btn.selected = false;
-
- activeItems.refresh();
-
- todolist.dataProvider = activeItems;
- }
- else if(label == "Completed")
- {
- all_btn.selected = false;
- active_btn.selected = false;
-
- completedItems.refresh();
-
- todolist.dataProvider = completedItems;
- }
- }
- ]]>
- </fx:Script>
-
- <j:beads>
- <js:ContainerDataBinding/>
- </j:beads>
-
- <html:Section className="todoapp">
- <html:H1 text="todos"/>
-
- <html:Header localId="header">
- <j:Group>
- <j:TextInput localId="need" enter="addItem(event)" width="100%" className="new-todo">
- <j:beads>
- <j:TextPrompt prompt="What needs to be done?"/>
- </j:beads>
- </j:TextInput>
- <j:IconButton localId="toogleAll" click="markAllAsComplete()" visible="false"
- width="40" x="10" y="10" className="toggle-all">
- <j:icon>
- <js:FontIcon text="{MaterialIconType.KEYBOARD_ARROW_DOWN}" material="true"/>
- </j:icon>
- </j:IconButton>
- </j:Group>
- </html:Header>
-
- <html:Section localId="main">
- <j:List localId="todolist" width="100%" rowHeight="55"
- labelField="label" className="todo-list"
- initComplete="todolist.dataProvider = itemsCompleted(items, null)">
- <j:beads>
- <j:AddListItemRendererForArrayListData/>
- <j:RemoveListItemRendererForArrayListData/>
- <j:UpdateListItemRendererForArrayListData/>
- </j:beads>
- </j:List>
- </html:Section>
-
- <html:Footer localId="footer" className="footer" visible="false">
- <j:BarRow>
- <j:BarSection width="15%">
- <j:Label localId="itemsLeft" text="0 items left"/>
- </j:BarSection>
- <j:BarSection gap="3" itemsHorizontalAlign="itemsCenter">
- <j:ToggleButton localId="all_btn" text="All" click="toggleButtonClickHandler(event)" selected="true"/>
- <j:ToggleButton localId="active_btn" text="Active" click="toggleButtonClickHandler(event)"/>
- <j:ToggleButton localId="completed_btn" text="Completed" click="toggleButtonClickHandler(event)"/>
- </j:BarSection>
- <j:BarSection width="15%" itemsHorizontalAlign="itemsRight">
- <j:Button localId="clearCompleted" text="Clear Completed" click="removeCompleted()" visible="false"/>
- </j:BarSection>
- </j:BarRow>
-
- </html:Footer>
- </html:Section>
-
- <html:Footer className="info">
- <![CDATA[
- <p>Double-click to edit a todo</p>
- <p>
- Created by
- <a href="http://github.com/carlosrovira" target="_blank">Carlos Rovira</a>
- for
- <a href="http://royale.apache.org" target="_blank">Apache Royale</a>
- </p>
- <p>Inspired in <a href="http://todomvc.com" target="_blank">TodoMVC</a></p>
- ]]>
- </html:Footer>
-</j:View>
\ No newline at end of file
diff --git a/examples/jewel/todomvc/src/main/royale/jewel/todomvc/views/TodoFooter.mxml b/examples/jewel/todomvc/src/main/royale/jewel/todomvc/views/TodoFooter.mxml
new file mode 100644
index 0000000..0c76f78
--- /dev/null
+++ b/examples/jewel/todomvc/src/main/royale/jewel/todomvc/views/TodoFooter.mxml
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<j:BarRow xmlns:fx="http://ns.adobe.com/mxml/2009"
+ xmlns:j="library://ns.apache.org/royale/jewel"
+ xmlns:js="library://ns.apache.org/royale/basic">
+
+ <fx:Script>
+ <![CDATA[
+ import jewel.todomvc.models.TodoModel;
+ import jewel.todomvc.events.TodoEvent;
+
+ [Bindable]
+ public var todoModel:TodoModel;
+
+ /**
+ * All toggle buttons runs select filter
+ */
+ public function toggleButtonClickHandler(event:Event):void {
+ selectFilter(event.target.text);
+ }
+
+ /**
+ * Update buttons states and refresh the list updating the list model
+ */
+ public function selectFilter(label:String):void {
+ if(label == TodoModel.ALL_FILTER)
+ {
+ active_btn.selected = false;
+ completed_btn.selected = false;
+ }
+ else if(label == TodoModel.ACTIVE_FILTER)
+ {
+ all_btn.selected = false;
+ completed_btn.selected = false;
+
+ }
+ else if(label == TodoModel.COMPLETED_FILTER)
+ {
+ all_btn.selected = false;
+ active_btn.selected = false;
+ }
+
+ dispatchEvent(new TodoEvent(TodoEvent.REFRESH_LIST, null, label));
+ }
+
+ /**
+ * Remove all completed todo items and update the todo list with the right filter
+ */
+ public function removeCompleted():void {
+ dispatchEvent(new TodoEvent(TodoEvent.REMOVE_COMPLETED));
+
+ clearCompleted.visible = false;
+
+ if(all_btn.selected)
+ selectFilter(all_btn.text);
+ else if(active_btn.selected)
+ selectFilter(active_btn.text);
+ else if(completed_btn.selected)
+ selectFilter(completed_btn.text);
+ }
+ ]]>
+ </fx:Script>
+
+ <j:beads>
+ <js:ContainerDataBinding/>
+ </j:beads>
+
+ <j:BarSection width="15%">
+ <j:Label localId="itemsLeft" text="{todoModel.itemsLeftLabel}"/>
+ </j:BarSection>
+
+ <j:BarSection gap="3" itemsHorizontalAlign="itemsCenter">
+ <j:ToggleButton localId="all_btn" text="All" click="toggleButtonClickHandler(event)" selected="true"/>
+ <j:ToggleButton localId="active_btn" text="Active" click="toggleButtonClickHandler(event)"/>
+ <j:ToggleButton localId="completed_btn" text="Completed" click="toggleButtonClickHandler(event)"/>
+ </j:BarSection>
+
+ <j:BarSection width="15%" gap="3" itemsHorizontalAlign="itemsRight">
+ <j:Button localId="clearCompleted" text="Clear Completed" click="removeCompleted()" visible="{todoModel.clearCompletedVisibility}"/>
+ </j:BarSection>
+
+</j:BarRow>
\ No newline at end of file
diff --git a/examples/jewel/todomvc/src/main/royale/jewel/todomvc/views/TodoHeader.mxml b/examples/jewel/todomvc/src/main/royale/jewel/todomvc/views/TodoHeader.mxml
new file mode 100644
index 0000000..3487343
--- /dev/null
+++ b/examples/jewel/todomvc/src/main/royale/jewel/todomvc/views/TodoHeader.mxml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<j:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
+ xmlns:j="library://ns.apache.org/royale/jewel"
+ xmlns:js="library://ns.apache.org/royale/basic">
+
+ <fx:Script>
+ <![CDATA[
+ import jewel.todomvc.events.TodoEvent;
+ import jewel.todomvc.models.TodoModel;
+ import jewel.todomvc.vos.TodoVO;
+
+ import org.apache.royale.events.Event;
+
+ [Bindable]
+ public var todoModel:TodoModel;
+
+ /**
+ * Signal todo item addition from main text box
+ */
+ private function addItem(event:Event):void {
+ if(event.target.text == "") return;
+ var newTodo:TodoVO = new TodoVO(event.target.text);
+ event.target.text = "";
+
+ dispatchEvent(new TodoEvent(TodoEvent.ADD_TODO_ITEM, newTodo));
+ }
+
+ /**
+ * Mark all todo items complete
+ */
+ public function markAllComplete(event:Event):void {
+ dispatchEvent(new TodoEvent(TodoEvent.MARK_ALL_COMPLETE));
+ }
+ ]]>
+ </fx:Script>
+
+ <j:beads>
+ <js:ContainerDataBinding/>
+ </j:beads>
+
+ <j:TextInput localId="need" width="100%" className="new-todo"
+ enter="addItem(event)">
+ <j:beads>
+ <j:TextPrompt prompt="What needs to be done?"/>
+ </j:beads>
+ </j:TextInput>
+
+ <j:IconButton localId="toogleAll" visible="{todoModel.toogleAllVisibility}"
+ width="40" x="10" y="10" className="toggle-all"
+ click="markAllComplete(event)">
+ <j:icon>
+ <js:FontIcon text="{MaterialIconType.KEYBOARD_ARROW_DOWN}" material="true"/>
+ </j:icon>
+ </j:IconButton>
+
+</j:Group>
\ No newline at end of file
diff --git a/examples/jewel/todomvc/src/main/royale/jewel/todomvc/views/TodoListSection.mxml b/examples/jewel/todomvc/src/main/royale/jewel/todomvc/views/TodoListSection.mxml
new file mode 100644
index 0000000..d0b50f4
--- /dev/null
+++ b/examples/jewel/todomvc/src/main/royale/jewel/todomvc/views/TodoListSection.mxml
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<j:View xmlns:fx="http://ns.adobe.com/mxml/2009"
+ xmlns:j="library://ns.apache.org/royale/jewel"
+ xmlns:js="library://ns.apache.org/royale/basic"
+ xmlns:html="library://ns.apache.org/royale/html"
+ xmlns:views="jewel.todomvc.views.*"
+ initComplete="setUp()">
+
+ <fx:Script>
+ <![CDATA[
+ import jewel.todomvc.models.TodoModel;
+ import org.apache.royale.core.IBeadModel;
+
+ [Bindable]
+ public var todoModel:TodoModel;
+
+ /**
+ * setUp child views
+ */
+ public function setUp():void
+ {
+ todoModel = getBeadByType(IBeadModel) as TodoModel;
+ header.todoModel = todoModel;
+ footer.todoModel = todoModel;
+ }
+ ]]>
+ </fx:Script>
+
+ <j:beads>
+ <js:ContainerDataBinding/>
+ </j:beads>
+
+ <html:Section className="todoapp">
+ <html:H1 text="todos"/>
+
+ <html:Header>
+ <views:TodoHeader localId="header"/>
+ </html:Header>
+
+ <html:Section localId="main">
+ <j:List localId="todolist" width="100%" rowHeight="55"
+ labelField="label" className="todo-list"
+ dataProvider="{todoModel.listItems}">
+ <j:beads>
+ <j:AddListItemRendererForArrayListData/>
+ <j:RemoveListItemRendererForArrayListData/>
+ <j:UpdateListItemRendererForArrayListData/>
+ </j:beads>
+ </j:List>
+ </html:Section>
+
+ <html:Footer className="footer" visible="{todoModel.footerVisibility}">
+ <views:TodoFooter localId="footer"/>
+ </html:Footer>
+ </html:Section>
+
+ <html:Footer className="info">
+ <![CDATA[
+ <p>Double-click to edit a todo</p>
+ <p>
+ Created by
+ <a href="http://github.com/carlosrovira" target="_blank">Carlos Rovira</a>
+ for
+ <a href="http://royale.apache.org" target="_blank">Apache Royale</a>
+ </p>
+ <p>Inspired in <a href="http://todomvc.com" target="_blank">TodoMVC</a></p>
+ ]]>
+ </html:Footer>
+</j:View>
\ No newline at end of file