/*
* 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 java.util.List;
import java.util.Stack;
import next.i.view.IView;
import next.i.view.XNavigationBar;
import next.i.view.XNavigationView;
import com.google.gwt.user.client.Command;
/**
* This class manages a stack of XControllers, each of which holds
* information about a view, such as its title and the navigation item
* associated with the view. When view controllers are pushed onto and popped
* off the stack, the navigation controller updates the navigation bar and view
* appropriately.
*
* <p>
* <img src='../../../resources/XNavigationView.png'/>
* </p>
*
* <h3>Example:</h3>
*
* <pre>
* class MyController extends XTableController {
* public MyController() {
*
* setTitle("Slide Example");
*
* getNavigationBar().setRightTitle("Source");
* getNavigationBar().setLeftTitle("Back", Type.BACK_BUTTON);
*
* TableData tableDS = new TableData();
* tableDS.add("0 list item", "1 list item");
*
* initDataSource(tableDS);
* }
* }
* ..
* new XNavigationController(new MyController());
* </pre>
*/
public class XNavigationController implements IController {
private XController _rootController;
private XController _currentController;
private Stack<XController> _stack;
// private TabBarController tabBarController;
public XNavigationController(XController rootController) {
NavigationController_(rootController);
}
public XController getTopController() {
return _stack.peek();
}
public XController getVisibleController() {
return _currentController;
}
public List<XController> getControllers() {
return _stack;
}
public void pushController(final XController newController, boolean animated) {
pushController_(newController, animated);
}
public XController popController(boolean animated) {
return popController_(animated);
}
public XController popToRootController(boolean animated) {
return popToRootController_(animated);
}
public XController popToController(XController controller, boolean animated) {
return popToController_(controller, animated);
}
public XNavigationBar getNavigationBar() {
return _currentController.getNavigationBar();
}
public XNavigationView getNavigationView() {
return _currentController.getNavigationView();
}
public IView getView() {
return _currentController.getNavigationView();
}
/**
* private
*/
private XController popToRootController_(boolean animated) {
if (_stack.empty()) {
return _rootController;
} else {
_stack.clear();
return popController_(_currentController, _rootController, animated);
}
}
private XController popToController_(XController controller, boolean animated) {
while (!_stack.empty()) {
final XController sc = _stack.pop();
if (controller.equals(sc)) {
return popController_(_currentController, sc, animated);
}
}
return null;
}
private XController popController_(boolean animated) {
if (_stack.empty()) {
return null;
} else {
XController newController = _stack.pop();
return popController_(_currentController, newController, animated);
}
}
private void pushController_(final XController newController, boolean animated) {
newController.register(this);
boolean contains = _stack.contains(newController) || _currentController.equals(newController);
if (!contains) {
newController.attach();
Animator a0 = new Animator(Transform.SLIDE_CW, _currentController);
Animator a1 = new Animator(Transform.SLIDE_EC, newController);
XController.animate(new Command() {
public void execute() {
_stack.push(_currentController);
_currentController.doOnHideComplete();
newController.doOnHideComplete();
_currentController.getNavigationView().getElement().getStyle().setZIndex(-1);
newController.getNavigationView().getElement().getStyle().setZIndex(1);
_currentController = newController;
}
}, 300, Interval.DURATION_SLIDE, a0, a1);
}
}
private void NavigationController_(XController rootController) {
this._rootController = rootController;
this._currentController = rootController;
_stack = new Stack<XController>();
this._rootController.register(this);
this._rootController.attach();
}
private XController popController_(final XController oldController,
final XController newController, boolean animated) {
Animator a0 = new Animator(Transform.SLIDE_CE, oldController);
Animator a1 = new Animator(Transform.SLIDE_WC, newController);
XController.animate(new Command() {
public void execute() {
oldController.getNavigationView().getElement().getStyle().setZIndex(-1);
newController.getNavigationView().getElement().getStyle().setZIndex(1);
oldController.doOnHideComplete();
newController.doOnHideComplete();
_currentController = newController;
oldController.dettach();
}
}, 300, Interval.DURATION_SLIDE, a0, a1);
return newController;
}
// public void setNavigationBarVisible(boolean visible, boolean animated) {
// // TODO animated action
// // navigation.getNavigationUIBar().setVisible(visible);
// }
//
// public Toolbar getToolbar() {
// return navigation.getToolbar();
// }
//
// public void setToolbarVisible(boolean visible, boolean animated) {
// // TODO animated action
// navigation.getToolbar().setVisible(visible);
// }
// /**
// * -----------------------<br>
// * Private Methods <br>
// * -----------------------<br>
// */
//
// private void _pushNavBar(final SlideController newCtrl, final boolean
// animated) {
//
// final NavigationBar newBar = newCtrl.getNavigationBar();
// final NavigationBar currBar = currentController.getNavigationBar();
//
// newBar.setLeftTitle(currentController.getTitle(), true);
//
// BarItem leftBtn = newBar.getButtonLeft();
// if (!leftBtn.hasClickHandler()) {
// leftBtn.addClickHandler(new ClickHandler() {
// public void onClick(ClickEvent event) {
// _popController(animated, 0);
// }
// });
// }
// // navigation.getNavigationUIBar().addWidget(newBar);
//
// _animateBar(currBar, newBar, Direction.EAST_WEST, null);
// }
//
// private void _popNavBar(SlideController newCtrl, final boolean animated) {
//
// final NavigationBar newBar = newCtrl.getNavigationBar();
// final NavigationBar currBar = currentController.getNavigationBar();
//
// if (stack.size() > 0) {
// newBar.setLeftTitle(stack.peek().getTitle(), true);
//
// BarItem leftBtn = newBar.getButtonLeft();
// if (!leftBtn.hasClickHandler()) {
// leftBtn.addClickHandler(new ClickHandler() {
// public void onClick(ClickEvent event) {
// _popController(animated, 0);
// }
// });
// }
// }
// // navigation.getNavigationUIBar().addWidget(newBar);
//
// _animateBar(currBar, newBar, Direction.WEST_EAST, null);
// }
//
// private void _animateBar(final NavigationBar currBar, final NavigationBar
// newBar, Direction dir,
// final Command afterCmd) {
//
// if (dir == Direction.WEST_EAST) {
// Utils.setStyle(newBar, Transition.barSlide, dir.leftController(),
// Transition.start);
// Utils.setStyle(currBar, Transition.barSlide, dir.rightController(),
// Transition.start);
//
// } else {
// Utils.setStyle(currBar, Transition.barSlide, dir.leftController(),
// Transition.start);
// Utils.setStyle(newBar, Transition.barSlide, dir.rightController(),
// Transition.start);
// }
//
// new Timer() {
// @Override
// public void run() {
// Utils.removeStyle(currBar, Transition.start);
// Utils.removeStyle(newBar, Transition.start);
//
// new Timer() {
// public void run() {
// currBar.clearActive();
//
// currBar.removeFromParent();
// Utils.setStyle(newBar, Transition.barSlide);
// if (afterCmd != null) {
// afterCmd.execute();
// }
// // Anime.release();
// }
// }.schedule(DURATION_BAR_ANIME);
//
// }
// }.schedule(WAIT_BEFORE_START_ANIME);
// }
//
// private void _animate(final SlideController currCtrl, final SlideController
// newCtrl, Direction dir,
// int startSchedule, final Command afterCmd) {
//
// Anime.lock();
//
// if (dir == Direction.WEST_EAST) {
// Utils.setStyle(newCtrl, Transition.slide, dir.leftController(),
// Transition.start);
// Utils.setStyle(currCtrl, Transition.slide, dir.rightController(),
// Transition.start);
//
// } else {
// Utils.setStyle(currCtrl, Transition.slide, dir.leftController(),
// Transition.start);
// Utils.setStyle(newCtrl, Transition.slide, dir.rightController(),
// Transition.start);
// }
//
// //
// navigation.getNavigationContent().addWidget(newCtrl.getView().asWidget());
//
// new Timer() {
// @Override
// public void run() {
// Utils.removeStyle(currCtrl, Transition.start);
// Utils.removeStyle(newCtrl, Transition.start);
//
// new Timer() {
// public void run() {
// // currCtrl.getView().asWidget().removeFromParent();
// Utils.setStyle(newCtrl, Transition.slide);
// if (afterCmd != null) {
// afterCmd.execute();
// }
// Anime.release();
// }
// }.schedule(DURATION_SLIDER_ANIME);
//
// }
// }.schedule(startSchedule);
// }
private String dbg_() {
String d = ", size: " + _stack.size() + ", currentCtrl=" + _currentController;
d += ", [";
for (XController c : _stack) {
d += c + ", ";
}
d += "]";
return d;
}
}