blob: 81d6677f1fe035198b6de350776a4b03daa8018b [file] [log] [blame]
/*
* Copyright 2011 Google Inc.
*
* Licensed 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 com.google.gwt.sample.mobilewebapp.client.desktop;
import com.google.gwt.cell.client.AbstractCell;
import com.google.gwt.cell.client.ValueUpdater;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.DataTransfer;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.EventTarget;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.DragDropEventBase;
import com.google.gwt.event.dom.client.DragLeaveEvent;
import com.google.gwt.event.dom.client.DragLeaveHandler;
import com.google.gwt.event.dom.client.DragOverEvent;
import com.google.gwt.event.dom.client.DragOverHandler;
import com.google.gwt.event.dom.client.DropEvent;
import com.google.gwt.event.dom.client.DropHandler;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
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.sample.mobilewebapp.client.ui.DateButton;
import com.google.gwt.sample.mobilewebapp.client.ui.EditorDecorator;
import com.google.gwt.sample.mobilewebapp.presenter.task.TaskEditView;
import com.google.gwt.sample.mobilewebapp.shared.TaskProxy;
import com.google.gwt.sample.mobilewebapp.shared.TaskProxyImpl;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.cellview.client.CellList;
import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DecoratedPopupPanel;
import com.google.gwt.user.client.ui.DockLayoutPanel;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.TextBoxBase;
import com.google.gwt.user.client.ui.Widget;
import com.google.web.bindery.requestfactory.gwt.client.RequestFactoryEditorDriver;
import java.util.ArrayList;
import java.util.List;
/**
* View used to edit a task.
*/
public class DesktopTaskEditView extends Composite implements TaskEditView {
/**
* The UiBinder interface.
*/
interface DesktopTaskEditViewUiBinder extends UiBinder<Widget, DesktopTaskEditView> {
}
/**
* A ClientBundle that provides images for this widget.
*/
interface Resources extends ClientBundle {
@Source("DesktopTaskEditView.css")
Style style();
}
/**
* The styles used in this widget.
*/
interface Style extends CssResource {
/**
* Applies to the cells in the task template list.
*/
String taskTemplateCell();
}
/**
* The cell used to render task templates.
*/
static class TaskTemplateCell extends AbstractCell<TaskProxy> {
interface Template extends SafeHtmlTemplates {
@SafeHtmlTemplates.Template("<div class=\"{0}\" draggable=\"true\">"
+ "{1}<div style=\"font-size:80%;\">{2}</div></div>")
SafeHtml task(String className, String name, String notes);
}
private Template template = GWT.create(Template.class);
private final String className;
public TaskTemplateCell(String className) {
super("dragstart");
this.className = className;
}
@Override
public void onBrowserEvent(Context context, Element parent, TaskProxy value, NativeEvent event,
ValueUpdater<TaskProxy> valueUpdater) {
if ("dragstart".equals(event.getType())) {
// Save the ID of the TaskProxy.
DataTransfer dataTransfer = event.getDataTransfer();
dataTransfer.setData("text", String.valueOf(context.getIndex()));
// Set the image.
dataTransfer.setDragImage(parent, 25, 15);
}
}
@Override
public void render(Context context, TaskProxy value, SafeHtmlBuilder sb) {
if (value == null) {
return;
}
String notes = value.getNotes();
sb.append(template.task(className, value.getName(), (notes == null) ? "" : notes));
}
}
interface Driver extends RequestFactoryEditorDriver<TaskProxy, DesktopTaskEditView> {
}
/**
* The UiBinder used to generate the view.
*/
private static DesktopTaskEditViewUiBinder uiBinder = GWT
.create(DesktopTaskEditViewUiBinder.class);
/**
* The glass panel used to lock the UI.
*/
private static PopupPanel glassPanel;
/**
* Show or hide the glass panel used to lock the UI will the task loads.
*
* @param visible true to show, false to hide
*/
private static void setGlassPanelVisible(boolean visible) {
// Initialize the panel.
if (glassPanel == null) {
glassPanel = new DecoratedPopupPanel(false, true);
glassPanel.setWidget(new Label("Loading..."));
}
if (visible) {
// Show the loading panel.
glassPanel.center();
} else {
// Hide the loading panel.
glassPanel.hide();
}
}
@UiField
DockLayoutPanel dockLayoutPanel;
/**
* The panel that contains the edit form.
*/
@UiField
HTMLPanel editForm;
@UiField
Button deleteButton;
@UiField
DateButton dueDateEditor;
final EditorDecorator<String> nameEditor;
@UiField
@Ignore
TextBoxBase nameField;
@UiField
Element nameViolation;
@UiField
TextBoxBase notesEditor;
@UiField
Button saveButton;
@UiField(provided = true)
final CellList<TaskProxy> templateList;
@UiField
Widget templateListContainer;
private final Driver driver = GWT.create(Driver.class);
/**
* The {@link TaskEditView.Presenter} for this view.
*/
private Presenter presenter;
private final Resources resources;
/**
* Construct a new {@link DesktopTaskEditView}.
*/
public DesktopTaskEditView() {
// Initialize the styles.
resources = GWT.create(Resources.class);
resources.style().ensureInjected();
// Create the template list.
templateList = createTaskTemplateList();
initWidget(uiBinder.createAndBindUi(this));
nameEditor = EditorDecorator.create(nameField.asEditor(), nameViolation);
driver.initialize(this);
// Hide the template list if it isn't supported.
if (!DragDropEventBase.isSupported()) {
dockLayoutPanel.setWidgetSize(templateListContainer, 0);
}
// Create a new task or modify the current task when done is pressed.
saveButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
if (presenter != null) {
presenter.saveTask();
}
}
});
// Delete the current task or cancel when delete is pressed.
deleteButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
if (presenter != null) {
presenter.deleteTask();
}
}
});
// Add the form as a drop target.
editForm.addDomHandler(new DragOverHandler() {
public void onDragOver(DragOverEvent event) {
// Highlight the name and notes box.
nameField.getElement().getStyle().setBackgroundColor("#ffa");
notesEditor.getElement().getStyle().setBackgroundColor("#ffa");
}
}, DragOverEvent.getType());
editForm.addDomHandler(new DragLeaveHandler() {
public void onDragLeave(DragLeaveEvent event) {
EventTarget eventTarget = event.getNativeEvent().getEventTarget();
if (!Element.is(eventTarget)) {
return;
}
Element target = Element.as(eventTarget);
if (target == editForm.getElement()) {
// Un-highlight the name and notes box.
nameField.getElement().getStyle().clearBackgroundColor();
notesEditor.getElement().getStyle().clearBackgroundColor();
}
}
}, DragLeaveEvent.getType());
editForm.addDomHandler(new DropHandler() {
public void onDrop(DropEvent event) {
// Prevent the default text drop.
event.preventDefault();
// Un-highlight the name and notes box.
nameField.getElement().getStyle().clearBackgroundColor();
notesEditor.getElement().getStyle().clearBackgroundColor();
// Fill in the form.
try {
// Get the template the from the data transfer object.
DataTransfer dataTransfer = event.getNativeEvent().getDataTransfer();
int templateIndex = Integer.parseInt(dataTransfer.getData("text"));
TaskProxy template = templateList.getVisibleItem(templateIndex);
nameField.setValue(template.getName());
notesEditor.setValue(template.getNotes());
} catch (NumberFormatException e) {
// The user probably dragged something other than a template.
}
}
}, DropEvent.getType());
}
public RequestFactoryEditorDriver<TaskProxy, ?> getEditorDriver() {
return driver;
}
public void setEditing(boolean isEditing) {
if (isEditing) {
deleteButton.setText("Delete item");
} else {
deleteButton.setText("Cancel");
}
}
public void setLocked(boolean locked) {
setGlassPanelVisible(locked);
}
public void setNameViolation(String message) {
nameViolation.setInnerText(message);
}
public void setPresenter(Presenter presenter) {
this.presenter = presenter;
}
private CellList<TaskProxy> createTaskTemplateList() {
CellList<TaskProxy> list =
new CellList<TaskProxy>(new TaskTemplateCell(resources.style().taskTemplateCell()));
list.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.DISABLED);
// Create the templates.
List<TaskProxy> templates = new ArrayList<TaskProxy>();
templates.add(new TaskProxyImpl("Call mom", null));
templates.add(new TaskProxyImpl("Register to vote", "Where is my polling location again?"));
templates.add(new TaskProxyImpl("Replace air filter", "Size: 24x13x1"));
templates.add(new TaskProxyImpl("Take out the trash", null));
list.setRowData(templates);
return list;
}
}