| /* |
| * 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.tablet; |
| |
| import com.google.gwt.core.client.GWT; |
| import com.google.gwt.event.dom.client.ClickEvent; |
| import com.google.gwt.event.dom.client.ClickHandler; |
| import com.google.gwt.sample.mobilewebapp.client.ClientFactory; |
| import com.google.gwt.sample.mobilewebapp.client.MobileWebAppShell; |
| import com.google.gwt.sample.mobilewebapp.client.event.ActionEvent; |
| import com.google.gwt.sample.mobilewebapp.client.event.ActionNames; |
| import com.google.gwt.sample.mobilewebapp.presenter.tasklist.TaskListPresenter; |
| import com.google.gwt.sample.mobilewebapp.presenter.tasklist.TaskListView; |
| import com.google.gwt.sample.ui.client.OrientationHelper; |
| import com.google.gwt.uibinder.client.UiBinder; |
| import com.google.gwt.uibinder.client.UiField; |
| import com.google.gwt.user.client.Command; |
| import com.google.gwt.user.client.ui.Button; |
| import com.google.gwt.user.client.ui.DeckLayoutPanel; |
| import com.google.gwt.user.client.ui.DockLayoutPanel; |
| import com.google.gwt.user.client.ui.IsWidget; |
| import com.google.gwt.user.client.ui.Label; |
| import com.google.gwt.user.client.ui.ResizeComposite; |
| import com.google.gwt.user.client.ui.SimplePanel; |
| import com.google.gwt.user.client.ui.Widget; |
| import com.google.web.bindery.event.shared.EventBus; |
| |
| /** |
| * Tablet version of the UI shell. |
| * |
| * TODO(rjrjr): this thing needs a presenter or two. Also, too much copy paste |
| * btw. this and the desktop version. |
| */ |
| public class MobileWebAppShellTablet extends ResizeComposite implements MobileWebAppShell { |
| |
| interface MobileWebAppShellTabletUiBinder extends UiBinder<Widget, MobileWebAppShellTablet> { |
| } |
| |
| private static MobileWebAppShellTabletUiBinder uiBinder = GWT |
| .create(MobileWebAppShellTabletUiBinder.class); |
| |
| /** |
| * The width of the task list in landscape mode in PCT. |
| */ |
| private static final double LANDSCAPE_TASK_LIST_WIDTH_PCT = 30.0; |
| |
| private final ClientFactory clientFactory; |
| |
| /** |
| * The button used to add items. |
| */ |
| @UiField |
| Button addButton; |
| |
| /** |
| * The container that holds content. |
| */ |
| @UiField |
| DeckLayoutPanel contentContainer; |
| |
| /** |
| * The widget displayed when the user has not selected a task. |
| */ |
| @UiField |
| Widget contentEmptyMessage; |
| |
| /** |
| * The DockLayoutPanel that splits the task list and the task edit views. |
| */ |
| @UiField |
| DockLayoutPanel splitPanel; |
| |
| /** |
| * The container that holds the tast list. |
| */ |
| @UiField |
| SimplePanel taskListContainer; |
| |
| /** |
| * The label containing the application title. |
| */ |
| @UiField |
| Label titleLabel; |
| |
| /** |
| * A boolean indicating that we have not yet seen the first content widget. |
| */ |
| private boolean firstContentWidget = true; |
| |
| private final TaskListView taskListView; |
| |
| private boolean isShowingTaskList; |
| |
| private final EventBus eventBus; |
| |
| /** |
| * Construct a new {@link MobileWebAppShellTablet}. |
| */ |
| public MobileWebAppShellTablet(ClientFactory clientFactory, OrientationHelper orientationHelper, |
| TaskListView taskListView) { |
| this.clientFactory = clientFactory; |
| this.eventBus = clientFactory.getEventBus(); |
| this.taskListView = taskListView; |
| |
| // Inject the tablet specific styles. |
| TabletResources resources = GWT.create(TabletResources.class); |
| resources.tabletStyles().ensureInjected(); |
| |
| // Initialize this widget. |
| initWidget(uiBinder.createAndBindUi(this)); |
| |
| // Initialize the add button. |
| addButton.addClickHandler(new ClickHandler() { |
| @Override |
| public void onClick(ClickEvent event) { |
| ActionEvent.fire(eventBus, ActionNames.ADD_TASK); |
| } |
| }); |
| setAddButtonVisible(false); |
| |
| orientationHelper.setCommands(this, new Command() { |
| @Override |
| public void execute() { |
| onShiftToPortrait(); |
| } |
| }, new Command() { |
| @Override |
| public void execute() { |
| onShiftToLandscape(); |
| } |
| }); |
| |
| // Go to the task list place when the title is clicked. |
| titleLabel.addClickHandler(new ClickHandler() { |
| @Override |
| public void onClick(ClickEvent event) { |
| ActionEvent.fire(eventBus, ActionNames.GO_HOME); |
| } |
| }); |
| } |
| |
| @Override |
| public void setAddButtonVisible(boolean visible) { |
| addButton.setVisible(visible); |
| } |
| |
| /** |
| * Set the widget to display in content area. |
| * |
| * @param content the {@link Widget} to display |
| */ |
| public void setWidget(IsWidget content) { |
| contentContainer.setWidget((content == null) ? contentEmptyMessage : content); |
| |
| // If the content is null and we are in landscape mode, show the add button. |
| if (content == null && isShowingTaskList) { |
| setAddButtonVisible(true); |
| } |
| |
| // Do not animate the first time we show a widget. |
| if (firstContentWidget) { |
| firstContentWidget = false; |
| contentContainer.animate(0); |
| } |
| } |
| |
| private void onShiftToLandscape() { |
| // Show the static task list view. |
| splitPanel.setWidgetSize(taskListContainer, LANDSCAPE_TASK_LIST_WIDTH_PCT); |
| |
| if (!isShowingTaskList) { |
| taskListContainer.add(taskListView); |
| TaskListPresenter taskListPresenter = new TaskListPresenter(clientFactory, false); |
| |
| /* |
| * Sleaze alert: We know that TaskListPresenter doesn't add any event |
| * handlers to the bus If it did, we should have to give it a |
| * ResettableEventBus and clear it out on stop |
| */ |
| taskListPresenter.start(eventBus); |
| |
| // DeckLayoutPanel hides the view, so we need to show it. |
| taskListView.asWidget().setVisible(true); |
| isShowingTaskList = true; |
| } |
| |
| // Do not use animations when the task list is always visible. |
| contentContainer.setAnimationDuration(0); |
| |
| // Ensure that the task list view is not displayed as content. |
| if (contentContainer.getVisibleWidget() == null) { |
| contentContainer.setWidget(contentEmptyMessage); |
| } |
| } |
| |
| private void onShiftToPortrait() { |
| // Hide the static task list view. |
| if (isShowingTaskList) { |
| isShowingTaskList = false; |
| // We don't stop the presenter started in onShiftToLandscape, |
| // because we know TaskListView#setPresenter will do so for us. |
| } |
| splitPanel.setWidgetSize(taskListContainer, 0); |
| |
| /* |
| * Add both views to the DeckLayoutPanel so we can animate between them. |
| * Using a DeckLayoutPanel here works because we only have two views, and we |
| * always know that the edit view should animate in from the right side of |
| * the screen. A more complex app will require more complex logic to figure |
| * out which direction to animate. |
| */ |
| contentContainer.insert(taskListView, 0); |
| contentContainer.setAnimationDuration(500); |
| |
| // Ensure that something is displayed. |
| Widget curWidget = contentContainer.getVisibleWidget(); |
| if (curWidget == null || curWidget == contentEmptyMessage) { |
| ActionEvent.fire(eventBus, ActionNames.GO_HOME); |
| contentContainer.animate(0); |
| } |
| } |
| } |