/* * Copyright 2011 Vancouver Ywebb Consulting Ltd * * 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 next.i.controller; import next.i.view.IView; import next.i.view.MPanelBase; import next.i.view.XDragScrollView; import next.i.view.XHorizontalScrollView; import next.i.view.XNavigationBar; import next.i.view.XNavigationView; import next.i.view.XVerticalScrollView; import next.i.view.XView; import com.google.gwt.user.client.Command; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.ui.IsWidget; /** * This class allows view-management functionality for toolbars, navigation * bars, and application views. The XController class also animates on view * transitions. * * * <h3>Example:</h3> * * <pre> * class MyController extends XController { * * private Command action; * * public MyController() { * * setTitle("Transform"); * * getNavigationBar().setLeftTitle("Back", Type.BACK_BUTTON); * getNavigationBar().getButtonLeft().addClickHandler(new ClickHandler() { * public void onClick(ClickEvent event) { * getNavigationController().popController(true); * } * }); * * getNavigationBar().setRightTitle("Okay"); * getNavigationBar().getButtonRight().addClickHandler(new ClickHandler() { * public void onClick(ClickEvent event) { * Window.alert("You clicked Okay."); * } * }); * } * } * </pre> */ public abstract class XController implements IController { private XNavigationBar _navigationBar; private IView _view; private String _title; private int _id; private XNavigationView _navigation; private XNavigationController _navigationController; private IsWidget viewContent; public static enum Scroll { VERTICAL, // default HORIZONTAL, DRAGGABLE, NO_SCROLL } public XController() { XController_(); } abstract public Scroll getScrollOrientation(); void register(XNavigationController navigationController) { // if (view != null) { // view.removeFromParent(); // } // if (navigationBar != null) { // navigationBar.removeFromParent(); // } this._navigationController = navigationController; // this.navigationBar = navigationController.getNavigationBar(); // this.navigation = navigationController.getNavigation(); } public IView getView() { if (_view == null) { if (getScrollOrientation() == Scroll.VERTICAL) { _view = new XVerticalScrollView(); } else if (getScrollOrientation() == Scroll.HORIZONTAL) { _view = new XHorizontalScrollView(); } else if (getScrollOrientation() == Scroll.DRAGGABLE) { _view = new XDragScrollView(); } else if (getScrollOrientation() == Scroll.NO_SCROLL) { _view = new XView(); } else { _view = new XVerticalScrollView(); } } return _view; } public abstract IsWidget getViewContent(); public XNavigationView getNavigationView() { return _navigation; } public String getTitle() { return _title; } public void setTitle(String title) { this._title = title; _navigationBar.setTitle(this._title); } public XNavigationBar getNavigationBar() { return _navigationBar; } void doOnHideComplete() { onHideComplete(); } @Override public String toString() { return _title + "-" + hashCode(); } @Override public boolean equals(Object obj) { return equals_(obj); } @Override public int hashCode() { return _id; } public XNavigationController getNavigationController() { return _navigationController; } public void attach() { attach_(); } public void dettach() { getNavigationView().removeFromParent(); } /** * This method is invoked when on hide completion. */ public void onHideComplete() { // will be implemented by children } public void onAfterLoad() { // Utils.setStyle(this, Transition.BEFORE, Transition.start); } public static void animate(final Command afterCmd, final int delayBeforeStart, final int animeDuration, final Animator... animators) { animate_(afterCmd, delayBeforeStart, animeDuration, animators); } public void slideUpIn() { slideUpIn_(); } public void slideUpReverse() { slideUpReverse_(); } public void slideDownIn() { slideDownIn_(); } public void slideDownReverse() { slideDownReverse_(); } public void flipTo(final XController controller, final Command afterCommand) { flipTo_(controller, afterCommand); } public void swapTo(final XController controller, final Command afterCommand) { swapTo_(controller, afterCommand); } public void swapToReverse(final XController controller, final Command afterCommand) { swapToReverse_(controller, afterCommand); } public void popIn() { popIn_(); } public void popOut() { popOut_(); } public void fadeIn() { fadeIn_(); } public void fadeOut() { fadeOut_(); } /** * private */ private void XController_() { this._id = ControllerID.get(); _navigationBar = new XNavigationBar(); _navigation = new XNavigationView(); _navigation.setNavigationContent(getView()); _navigation.setNavigationBar(_navigationBar); // defer invocation after sub-class constructors Timer t = new Timer() { @Override public void run() { onAfterLoad(); if (XController.this.viewContent == null) { IsWidget w = getViewContent(); if (w != null) { XController.this.viewContent = w; // TODO casting doesn't seem right ((MPanelBase) getView()).add(w.asWidget()); } } getNavigationBar().repaint(); } }; t.schedule(1); } // private void XController_(/*IsWidget isWidget*/) { // XController_(); // // _view.setContent(isWidget); // _view.setContent(getViewContent()); // } private boolean equals_(Object obj) { if (obj == null) { return false; } if (obj instanceof XController) { XController objSC = (XController) obj; return objSC.hashCode() == this.hashCode(); } else { return false; } } private void attach_() { if (!getNavigationView().isAttached()) { getNavigationView().setSize("100%", "100%"); // RootLayoutPanel.get().add(this.getNavigation()); RootAttacher.attach(this); } } private static void animate_(final Command afterCmd, final int delayBeforeStart, final int animeDuration, final Animator... animators) { Anime.lock(); for (Animator a : animators) { a.getController().attach(); Element el = a.getController().getNavigationView().asWidget().getElement(); el.getStyle().setProperty("WebkitTransitionDuration", "0ms"); Utils .setStyle(a.getController(), a.getTransform().title(), a.getTransform().direction(), Transform.START.title()); } new Timer() { @Override public void run() { for (Animator a : animators) { Element el = a.getController().getNavigationView().asWidget().getElement(); el.getStyle().setProperty("WebkitTransitionDuration", a.getTransform().duration() + "ms"); } new Timer() { public void run() { for (Animator b : animators) { Utils.removeStyle(b.getController(), Transform.START.title()); } new Timer() { public void run() { // currCtrl.getView().asWidget().removeFromParent(); // Utils.setStyle(XController.this, Transition.slide); // Utils.setStyle(XController.this, Transition.BEFORE, // Transition.start); if (afterCmd != null) { afterCmd.execute(); } Anime.release(); } }.schedule(animeDuration); } }.schedule(delayBeforeStart); } }.schedule(1); } private void slideUpIn_() { Animator a0 = new Animator(Transform.SLIDE_SC, this); XController.animate(null, 300, Interval.DURATION_SLIDE, a0); } private void slideUpReverse_() { Animator a0 = new Animator(Transform.SLIDE_CS, this); XController.animate(new Command() { public void execute() { XController.this.dettach(); } }, 300, Interval.DURATION_SLIDE, a0); } private void slideDownIn_() { Animator a0 = new Animator(Transform.SLIDE_NC, this); XController.animate(null, 300, Interval.DURATION_SLIDE, a0); } private void slideDownReverse_() { Animator a0 = new Animator(Transform.SLIDE_CN, this); XController.animate(new Command() { public void execute() { XController.this.dettach(); } }, 300, Interval.DURATION_SLIDE, a0); } private void flipTo_(final XController controller, final Command afterCommand) { Animator a1 = new Animator(Transform.FLIP_OUT, this); XController.animate(null, 300, Interval.DURATION_FLIP, a1); new Timer() { public void run() { if (afterCommand != null) { afterCommand.execute(); } XController.this.dettach(); Animator a0 = new Animator(Transform.FLIP_IN, controller); XController.animate(null, 200, Interval.DURATION_FLIP, a0); } }.schedule(500); } private void swapTo_(final XController controller, final Command afterCommand) { Command cmdTwo = new Command() { public void execute() { Animator a0 = new Animator(Transform.SWAP_OUT_TWO, XController.this); Animator a1 = new Animator(Transform.SWAP_IN_TWO, controller); XController.animate(new Command() { public void execute() { XController.this.dettach(); } }, 10, Interval.DURATION_SWAP, a0, a1); } }; Animator a0 = new Animator(Transform.SWAP_OUT_ONE, this); Animator a1 = new Animator(Transform.SWAP_IN_ONE, controller); XController.animate(cmdTwo, 10, Interval.DURATION_SWAP, a0, a1); } private void swapToReverse_(final XController controller, final Command afterCommand) { Command cmdTwo = new Command() { public void execute() { Animator a0 = new Animator(Transform.SWAP_OUT_TWO_REVERSE, controller); Animator a1 = new Animator(Transform.SWAP_IN_TWO_REVERSE, XController.this); XController.animate(new Command() { public void execute() { XController.this.dettach(); } }, 10, Interval.DURATION_SWAP, a0, a1); } }; Animator a0 = new Animator(Transform.SWAP_OUT_ONE_REVERSE, controller); Animator a1 = new Animator(Transform.SWAP_IN_ONE_REVERSE, this); XController.animate(cmdTwo, 10, Interval.DURATION_SWAP, a0, a1); } private void popIn_() { Animator a0 = new Animator(Transform.POP_IN, this); XController.animate(null, 1, Interval.DURATION_POP, a0); } private void popOut_() { Animator a0 = new Animator(Transform.POP_OUT, this); XController.animate(new Command() { public void execute() { XController.this.dettach(); } }, 1, Interval.DURATION_POP, a0); } private void fadeIn_() { Animator a0 = new Animator(Transform.FADE_IN, this); XController.animate(null, 1, Interval.DURATION_FADE, a0); } private void fadeOut_() { Animator a0 = new Animator(Transform.FADE_OUT, this); XController.animate(new Command() { public void execute() { XController.this.dettach(); } }, 1, Interval.DURATION_FADE, a0); } }