All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.swm.commons.mobile.client.widgets.tab.TabPanel Maven / Gradle / Ivy

/*
 * Copyright 2011 SWM Services GmbH.
 * 
 * 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 de.swm.commons.mobile.client.widgets.tab;

import com.google.gwt.dom.client.Element;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.Widget;
import de.swm.commons.mobile.client.SWMMobile;
import de.swm.commons.mobile.client.page.Transition;
import de.swm.commons.mobile.client.widgets.LoadingIndicatorPopup;
import de.swm.commons.mobile.client.widgets.SWMMobileWidgetBase;
import de.swm.commons.mobile.client.widgets.itf.ISpinnerStarted;

import java.util.Iterator;
import java.util.logging.Logger;


/**
 * A Tab panel containts several {@link Tab}s. Each Tab has a {@link TabHeader} and a {@link TabContent}.
 */
public class TabPanel extends SWMMobileWidgetBase implements HasWidgets, ClickHandler {

	private static final Logger LOGGER = Logger.getLogger(TabPanel.class.getName());


	public static final int SPINNER_DELAY_MILLIS = 500;
	private final FlowPanel myPanel = new FlowPanel();
	private final FlowPanel myTabHeaderPanel = new FlowPanel();
	private final FlowPanel myTabContentPanel = new FlowPanel();
	private int mySelectedTabIndex = -1;
	private Transition transition = Transition.SLIDE;
	/**
	 * True if every tab transition should have an spinner page.
	 */
	private boolean showSpinnerBetweenTransitions = false;
	private boolean isSpinnerStarted = false;
	private final LoadingIndicatorPopup spinner = new LoadingIndicatorPopup();


	/**
	 * Default constructor.
	 */
	public TabPanel() {
		initWidget(myPanel);
		setStyleName(SWMMobile.getTheme().getMGWTCssBundle().getTabPanelCss().tabPanel());
		myPanel.add(myTabHeaderPanel);
		myPanel.add(myTabContentPanel);
		myTabHeaderPanel.addDomHandler(this, ClickEvent.getType());
	}

	public Transition getTransition() {
		return transition;
	}


	/**
	 * Sets the transition effect shown when switching between the tabs. Default is Transition.SLIDE.
	 *
	 * @param transition transition effect; if set to {code}null{code}, no transition effect is shown.
	 */
	public void setTransition(Transition transition) {
		this.transition = transition;
	}


	@Override
	public void add(Widget w) {
		assert w instanceof Tab : "Can only place Tab widgets inside a Tab Panel.";
		myTabHeaderPanel.add(w);
	}


	@Override
	public void onInitialLoad() {
		if (myTabHeaderPanel.getWidgetCount() > 0) {
			// FIXME:allow a different default tab to be set?
			selectTab(0);
		}
	}


	/**
	 * Selects a tab by his index position.
	 *
	 * @param index the index
	 */
	public void selectTab(int index) {
		if (mySelectedTabIndex == index) {
			LOGGER.info("same tab");
			return;
		}
		Tab from = unselectCurrentTab();
		Tab to = (Tab) myTabHeaderPanel.getWidget(index);
		to.addStyleName(SWMMobile.getTheme().getMGWTCssBundle().getTabPanelCss().selected());

		if (from == null) {
			myTabContentPanel.add(to.getContent());
		} else if (transition == null) {
			myTabContentPanel.remove(from.getContent());
			myTabContentPanel.add(to.getContent());
		} else {
			transition.start(from.getContent(), to.getContent(), myTabContentPanel, index < mySelectedTabIndex);
		}
		mySelectedTabIndex = index;
	}


	public int getSelectedTabIndex() {
		return mySelectedTabIndex;
	}


	@Override
	public void onClick(ClickEvent event) {
		if (this.showSpinnerBetweenTransitions) {
			if (!isSpinnerStarted) {
				final int index = getClickedTabHeaderIndex(event);
				this.startPopup(new ISpinnerStarted() {
					@Override
					public void spinnerStarted() {
						isSpinnerStarted = true;
						if (index != -1) {
							selectTab(index);
						}

						Timer timer = new Timer(){
							@Override
							public void run() {
								stopSpinnerIfRunning();
							}
						};
						timer.schedule(SPINNER_DELAY_MILLIS);


					}
				});
			}
		} else {
			int index = getClickedTabHeaderIndex(event);
			if (index != -1) {
				selectTab(index);
			}
		}
	}

	/**
	 * True, if a spinner will be shown betreen transisitions.
	 * @param showSpinnerBetweenTransitions true if spinner wil be shown between transitions.
	 */
	public void setShowSpinnerBetweenTransitions(boolean showSpinnerBetweenTransitions) {
		this.showSpinnerBetweenTransitions = showSpinnerBetweenTransitions;
	}

	/**
	 * Will hide a loading indicator popup.
	 */
	private void stopSpinnerIfRunning() {
		if (showSpinnerBetweenTransitions && isSpinnerStarted) {
			isSpinnerStarted = false;
			this.spinner.setVisible(false);
		}
	}


	@Override
	public void clear() {
		myPanel.clear();
	}


	@Override
	public Iterator iterator() {
		return myPanel.iterator();
	}


	@Override
	public boolean remove(Widget w) {
		return myPanel.remove(w);
	}


	/**
	 * Un-selects the current Tab.
	 *
	 * @return the tab previously selected
	 */
	private Tab unselectCurrentTab() {
		if (mySelectedTabIndex == -1) {
			return null;
		}
		Tab tab = (Tab) myTabHeaderPanel.getWidget(mySelectedTabIndex);
		tab.removeStyleName(SWMMobile.getTheme().getMGWTCssBundle().getTabPanelCss().selected());
		return tab;
	}


	/**
	 * Returns the index of clicked tab panel.
	 *
	 * @param e the click event
	 * @return the index
	 */
	private int getClickedTabHeaderIndex(ClickEvent e) {
		Element div = Element.as(e.getNativeEvent().getEventTarget());
		if (div == myTabHeaderPanel.getElement()) {
			LOGGER.info("TabClicked: " + e.toString());
			return -1;
		}
		while (div.getParentElement() != myTabHeaderPanel.getElement()) {
			div = div.getParentElement();
		}
		return DOM.getChildIndex((com.google.gwt.user.client.Element) myTabHeaderPanel.getElement(),
				(com.google.gwt.user.client.Element) div);
	}

	/**
	 * Starts a propgress bar.
	 *
	 * @param spinnerStarted spinner is started
	 * @return the loading indicator.
	 */
	private LoadingIndicatorPopup startPopup(final ISpinnerStarted spinnerStarted) {
		this.spinner.showCentered(true);
		final Timer timer = new Timer() {

			@Override
			public void run() {
				isSpinnerStarted = true;
				spinnerStarted.spinnerStarted();
			}
		};
		timer.schedule(50);
		return this.spinner;
	}


}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy