Commit e13886c0 authored by Pascal Hartig's avatar Pascal Hartig

Merge pull request #882 from dprotti/gwtcleanmodel

gwt - model objects agnostic of presenters
parents e8f8532b 72a52baf
......@@ -11,10 +11,14 @@ import com.google.gwt.dom.client.EventTarget;
import com.google.gwt.dom.client.InputElement;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.safehtml.client.SafeHtmlTemplates;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
import com.todo.client.events.ToDoEvent;
import com.todo.client.events.ToDoRemovedEvent;
import com.todo.client.events.ToDoUpdatedEvent;
/**
* A cell that renders {@link ToDoItem} instances. This cell is rendered in both view and edit modes
......@@ -69,8 +73,11 @@ public class ToDoCell extends AbstractCell<ToDoItem> {
*/
private boolean beginningEdit = false;
private EventBus eventBus;
public ToDoCell() {
super("click", "keyup", "blur", "dblclick");
eventBus = ToDoEvent.getGlobalEventBus();
}
@Override
......@@ -81,8 +88,8 @@ public class ToDoCell extends AbstractCell<ToDoItem> {
sb.append(rendered);
} else {
SafeHtml rendered =
templates.view(value.isDone() ? templates.inputChecked() : templates.inputClear(),
SafeHtmlUtils.fromString(value.getTitle()), value.isDone() ? "listItem view completed"
templates.view(value.isCompleted() ? templates.inputChecked() : templates.inputClear(),
SafeHtmlUtils.fromString(value.getTitle()), value.isCompleted() ? "listItem view completed"
: "listItem view",
// NOTE: The addition of a timestamp here is a bit of a HACK! The problem
// is that the CellList uses a HasDataPresenter for rendering. This class
......@@ -152,9 +159,10 @@ public class ToDoCell extends AbstractCell<ToDoItem> {
// check whether the checkbox was clicked
if (tagName.equals("INPUT")) {
// if so, synchronise the model state
// if so, synchronize the model state
InputElement input = clickedElement.cast();
value.setDone(input.isChecked());
value.setCompleted(input.isChecked());
eventBus.fireEvent(new ToDoUpdatedEvent(value));
// update the 'row' style
if (input.isChecked()) {
......@@ -165,7 +173,7 @@ public class ToDoCell extends AbstractCell<ToDoItem> {
} else if (tagName.equals("BUTTON")) {
// if the delete anchor was clicked - delete the item
value.delete();
eventBus.fireEvent(new ToDoRemovedEvent(value));
}
}
}
......@@ -178,6 +186,7 @@ public class ToDoCell extends AbstractCell<ToDoItem> {
private void commitEdit(Element parent, ToDoItem value) {
InputElement input = getInputElement(parent);
value.setTitle(input.getValue());
eventBus.fireEvent(new ToDoUpdatedEvent(value));
}
/**
......
......@@ -4,39 +4,30 @@ package com.todo.client;
* An individual ToDo item.
*
* @author ceberhardt
* @author dprotti
*
*/
public class ToDoItem {
private final ToDoPresenter presenter;
private String title;
private boolean done;
private boolean completed;
public ToDoItem(String text, ToDoPresenter presenter) {
this.title = text;
this.done = false;
this.presenter = presenter;
public ToDoItem(String title) {
this(title, false);
}
public ToDoItem(String title, boolean done, ToDoPresenter presenter) {
public ToDoItem(String title, boolean completed) {
this.title = title;
this.done = done;
this.presenter = presenter;
}
public boolean isDone() {
return done;
this.completed = completed;
}
public void setDone(boolean done) {
this.done = done;
presenter.itemStateChanged(this);
public boolean isCompleted() {
return completed;
}
public void delete() {
presenter.deleteTask(this);
public void setCompleted(boolean completed) {
this.completed = completed;
}
public String getTitle() {
......@@ -44,13 +35,7 @@ public class ToDoItem {
}
public void setTitle(String title) {
setTitle(title, true);
}
public void setTitle(String title, boolean notify) {
this.title = title;
if (notify) {
presenter.itemStateChanged(this);
}
}
}
......@@ -6,6 +6,7 @@ import java.util.List;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONBoolean;
import com.google.gwt.json.client.JSONObject;
......@@ -15,12 +16,18 @@ import com.google.gwt.storage.client.Storage;
import com.google.gwt.user.client.History;
import com.google.gwt.view.client.AbstractDataProvider;
import com.google.gwt.view.client.ListDataProvider;
import com.todo.client.ToDoItem;
import com.todo.client.ToDoRouting;
import com.todo.client.events.ToDoEvent;
import com.todo.client.events.ToDoRemovedEvent;
import com.todo.client.events.ToDoUpdatedEvent;
/**
* The presenter for the ToDo application. This class is responsible for the lifecycle of the
* {@link ToDoItem} instances.
*
* @author ceberhardt
* @author dprotti
*
*/
public class ToDoPresenter {
......@@ -111,7 +118,7 @@ public class ToDoPresenter {
private ToDoRouting routing = ToDoRouting.ALL;
private boolean suppressStateChanged = false;
private EventBus eventBus;
public ToDoPresenter(View view) {
this.view = view;
......@@ -127,6 +134,25 @@ public class ToDoPresenter {
updateTaskStatistics();
setupHistoryHandler();
eventBus = ToDoEvent.getGlobalEventBus();
// listen to edits on individual items
eventBus.addHandler(ToDoUpdatedEvent.TYPE, new ToDoUpdatedEvent.Handler() {
@Override
public void onEvent(ToDoUpdatedEvent event) {
itemStateChanged(event.getToDo());
}
});
// listen to removals
eventBus.addHandler(ToDoRemovedEvent.TYPE, new ToDoRemovedEvent.Handler() {
@Override
public void onEvent(ToDoRemovedEvent event) {
deleteTask(event.getToDo());
}
});
}
/**
......@@ -176,7 +202,7 @@ public class ToDoPresenter {
int completeTask = 0;
for (ToDoItem task : todos) {
if (task.isDone()) {
if (task.isCompleted()) {
completeTask++;
}
}
......@@ -197,12 +223,7 @@ public class ToDoPresenter {
*/
protected void itemStateChanged(ToDoItem toDoItem) {
if (suppressStateChanged) {
return;
}
boolean notify = false;
toDoItem.setTitle(toDoItem.getTitle().trim(), notify);
toDoItem.setTitle(toDoItem.getTitle().trim());
if (toDoItem.getTitle().isEmpty()) {
todos.remove(toDoItem);
......@@ -225,12 +246,9 @@ public class ToDoPresenter {
*/
private void markAllCompleted(boolean completed) {
// update the completed state of each item
suppressStateChanged = true;
for (ToDoItem task : todos) {
task.setDone(completed);
task.setCompleted(completed);
}
suppressStateChanged = false;
taskStateChanged();
}
......@@ -245,7 +263,7 @@ public class ToDoPresenter {
if (taskTitle.equals(""))
return;
ToDoItem toDoItem = new ToDoItem(taskTitle, this);
ToDoItem toDoItem = new ToDoItem(taskTitle);
view.clearTaskText();
todos.add(toDoItem);
......@@ -259,7 +277,7 @@ public class ToDoPresenter {
Iterator<ToDoItem> iterator = todos.iterator();
while (iterator.hasNext()) {
ToDoItem item = iterator.next();
if (item.isDone()) {
if (item.isCompleted()) {
iterator.remove();
}
}
......@@ -280,7 +298,7 @@ public class ToDoPresenter {
ToDoItem toDoItem = todos.get(i);
JSONObject jsonObject = new JSONObject();
jsonObject.put("task", new JSONString(toDoItem.getTitle()));
jsonObject.put("complete", JSONBoolean.getInstance(toDoItem.isDone()));
jsonObject.put("complete", JSONBoolean.getInstance(toDoItem.isCompleted()));
todoItems.set(i, jsonObject);
}
......@@ -304,7 +322,7 @@ public class ToDoPresenter {
String task = jsonObject.get("task").isString().stringValue();
boolean completed = jsonObject.get("complete").isBoolean().booleanValue();
// add a new item to our list
todos.add(new ToDoItem(task, completed, this));
todos.add(new ToDoItem(task, completed));
}
} catch (Exception e) {
......
......@@ -40,7 +40,7 @@ public enum ToDoRouting {
private static class MatchActive implements Matcher {
@Override
public boolean matches(ToDoItem item) {
return !item.isDone();
return !item.isCompleted();
}
}
......@@ -50,7 +50,7 @@ public enum ToDoRouting {
private static class MatchCompleted implements Matcher {
@Override
public boolean matches(ToDoItem item) {
return item.isDone();
return item.isCompleted();
}
}
......
package com.todo.client.events;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.event.shared.EventHandler;
import com.google.gwt.event.shared.GwtEvent;
import com.google.gwt.event.shared.SimpleEventBus;
import com.todo.client.ToDoItem;
public abstract class ToDoEvent<H extends EventHandler> extends GwtEvent<H> {
private final ToDoItem toDo;
public ToDoEvent(ToDoItem toDo) {
this.toDo = toDo;
}
public ToDoItem getToDo() {
return toDo;
}
/* This acts as a global event bus factory */
private static EventBus eventBus = new SimpleEventBus();
public static EventBus getGlobalEventBus() {
return eventBus;
}
}
package com.todo.client.events;
import com.google.gwt.event.shared.EventHandler;
import com.todo.client.ToDoItem;
public class ToDoRemovedEvent extends ToDoEvent<ToDoRemovedEvent.Handler> {
public static final Type<ToDoRemovedEvent.Handler> TYPE = new Type<ToDoRemovedEvent.Handler>();
public static interface Handler extends EventHandler {
void onEvent(ToDoRemovedEvent event);
}
public ToDoRemovedEvent(ToDoItem toDo) {
super(toDo);
}
@Override
public Type<ToDoRemovedEvent.Handler> getAssociatedType() {
return TYPE;
}
@Override
protected void dispatch(ToDoRemovedEvent.Handler handler) {
handler.onEvent(this);
}
}
\ No newline at end of file
package com.todo.client.events;
import com.google.gwt.event.shared.EventHandler;
import com.todo.client.ToDoItem;
public class ToDoUpdatedEvent extends ToDoEvent<ToDoUpdatedEvent.Handler> {
public static final Type<ToDoUpdatedEvent.Handler> TYPE = new Type<ToDoUpdatedEvent.Handler>();
public static interface Handler extends EventHandler {
void onEvent(ToDoUpdatedEvent event);
}
public ToDoUpdatedEvent(ToDoItem toDo) {
super(toDo);
}
@Override
public Type<ToDoUpdatedEvent.Handler> getAssociatedType() {
return TYPE;
}
@Override
protected void dispatch(ToDoUpdatedEvent.Handler handler) {
handler.onEvent(this);
}
}
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment