/** * Copyright (C) 2011 Brian Ferris <bdferris@onebusaway.org> * * 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 org.onebusaway.webapp.gwt.viewkit; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import org.onebusaway.webapp.gwt.common.widgets.SpanWidget; import org.onebusaway.webapp.gwt.viewkit.events.ViewControllerSelectedEvent; import org.onebusaway.webapp.gwt.viewkit.events.ViewControllerSelectedHandler; import org.onebusaway.webapp.gwt.viewkit.resources.ViewKitCssResource; import org.onebusaway.webapp.gwt.viewkit.resources.ViewKitResources; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.shared.HandlerManager; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.Grid; import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.Image; import com.google.gwt.user.client.ui.Widget; public class TabBarController extends ViewController { private static final ViewKitCssResource _css = ViewKitResources.INSTANCE.getCSS(); private List<ViewController> _viewControllers = new ArrayList<ViewController>(); private Grid _panel = new Grid(2, 1); private HorizontalPanel _tabPanel = new HorizontalPanel(); private int _selectedIndex = -1; private Widget _selectedView = null; private boolean _visible = false; private HandlerManager _handlerManager; public void addVieControllerSelectedHandler( ViewControllerSelectedHandler handler) { ensureHandlers().addHandler(ViewControllerSelectedEvent.TYPE, handler); } public void addViewController(ViewController viewController) { // Does this really make sense? viewController.setNavigationController(getNavigationController()); _viewControllers.add(viewController); addTabForViewController(viewController, _viewControllers.size() - 1); if (_selectedIndex == -1) setSelectedIndex(_viewControllers.size() - 1); } public List<ViewController> getViewControllers() { return Collections.unmodifiableList(_viewControllers); } public boolean hasSelectedViewController() { return _selectedIndex != -1; } public ViewController getSelectedViewController() { if (!hasSelectedViewController()) return null; return _viewControllers.get(_selectedIndex); } public void setSelectedViewController(ViewController controller) { int index = _viewControllers.indexOf(controller); if (index != -1) setSelectedIndex(index); } public void setSelectedIndex(int index) { if (index == _selectedIndex) return; if (_selectedIndex != -1) { ViewController vc = _viewControllers.get(_selectedIndex); if (_visible) vc.viewWillDisappear(); _panel.setText(0, 0, ""); _selectedView.removeStyleName(_css.TabBarControllerContent()); if (_visible) vc.viewDidDisappear(); } ViewController viewController = _viewControllers.get(index); _selectedIndex = index; _selectedView = viewController.getView(); if (_visible) viewController.viewWillAppear(); _panel.setWidget(0, 0, _selectedView); _selectedView.addStyleName(_css.TabBarControllerContent()); ensureHandlers().fireEvent( new ViewControllerSelectedEvent(viewController, _selectedIndex)); if (_visible) viewController.viewDidAppear(); fireContextChangedEvent(); } /**** * {@link ViewController} Methods ****/ @Override public void viewWillAppear() { super.viewWillAppear(); if (hasSelectedViewController()) getSelectedViewController().viewWillAppear(); } @Override public void viewDidAppear() { super.viewDidAppear(); _visible = true; if (hasSelectedViewController()) getSelectedViewController().viewDidAppear(); } @Override public void viewWillDisappear() { super.viewWillDisappear(); if (hasSelectedViewController()) getSelectedViewController().viewWillDisappear(); } @Override public void viewDidDisappear() { super.viewDidDisappear(); _visible = false; if (hasSelectedViewController()) getSelectedViewController().viewDidDisappear(); } @Override protected void loadView() { super.loadView(); _panel.addStyleName(_css.TabBarController()); _tabPanel.addStyleName(_css.TabBar()); _panel.setWidget(1, 0, _tabPanel); _panel.getCellFormatter().addStyleName(1, 0, _css.TabBarControllerTabBar()); _view = _panel; } @Override public void setNavigationController(NavigationController controller) { super.setNavigationController(controller); for( ViewController views : _viewControllers) views.setNavigationController(controller); } @Override public void handleContext(List<String> path, Map<String, String> context) { if( path.isEmpty() ) return; String itemId = path.remove(0); for (ViewController viewController : _viewControllers) { NavigationItem navItem = viewController.getNavigationItem(); if (itemId.equals(navItem.getId())) { setSelectedViewController(viewController); viewController.handleContext(path,context); break; } } } @Override public void retrieveContext(List<String> path, Map<String, String> context) { if( _selectedIndex != -1 ) { ViewController vc = _viewControllers.get(_selectedIndex); NavigationItem item = vc.getNavigationItem(); path.add(item.getId()); vc.retrieveContext(path, context); } } /**** * Private Methods ****/ private void addTabForViewController(ViewController viewController, final int index) { TabBarItem tabBarItem = viewController.getTabBarItem(); ClickableFlowPanel tab = new ClickableFlowPanel(); tab.addStyleName(_css.TabBarItem()); FlowPanel imagePart = new FlowPanel(); tab.add(imagePart); Image image = tabBarItem.getImage(); if (image != null) { imagePart.add(image); } else { imagePart.addStyleName(_css.TabBarItemNoImage()); } FlowPanel namePart = new FlowPanel(); tab.add(namePart); String name = tabBarItem.getName(); if (name != null) { namePart.add(new SpanWidget(name)); } else { namePart.addStyleName(_css.TabBarItemNoName()); } tab.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent arg0) { setSelectedIndex(index); } }); _tabPanel.add(tab); } private HandlerManager ensureHandlers() { return _handlerManager == null ? _handlerManager = new HandlerManager(this) : _handlerManager; } }