/*
* Copyright 2008 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.topspin.desktop.client;
import java.util.ArrayList;
import java.util.List;
import com.google.gwt.topspin.desktop.client.TabBar.Tab;
import com.google.gwt.topspin.desktop.client.TabBar.TabSelectedEvent;
import com.google.gwt.topspin.ui.client.Composite;
import com.google.gwt.topspin.ui.client.Container;
import com.google.gwt.topspin.ui.client.HasContainer;
import com.google.gwt.topspin.ui.client.Panel;
import com.google.gwt.topspin.ui.client.Widget;
import com.google.gwt.topspin.ui.client.WrapperContainer;
/**
* A panel that represents a tabbed set of pages, each of which contains another
* widget. Its child widgets are shown as the user selects the various tabs
* associated with them.
*
* TODO(jgw): This widget doesn't yet perform any styling, and the API still
* needs to be changed a bit.
*/
public class TabPanel extends Composite implements HasContainer {
private Panel panel;
private TabBar tabBar;
private DeckPanel deckPanel;
private List<Widget> widgets = new ArrayList<Widget>();
private List<TabBar.Tab> tabs = new ArrayList<TabBar.Tab>();
private Container deckContainer;
/**
* Creates an new TabPanel in the given container.
*
* @param container the container in which the widget will be created
*/
public TabPanel(Container container) {
super(container);
panel = new Panel(getCompositeContainer());
tabBar = new TabBar(panel.getContainer());
tabBar.addTabSelectedListener(new TabBar.TabSelectedListener() {
public void onTabSelected(TabSelectedEvent event) {
Tab tab = event.getTab();
int index = tabs.indexOf(tab);
selectTab(index);
}
});
deckPanel = new DeckPanel(panel.getContainer());
deckContainer = new WrapperContainer(deckPanel.getContainer()) {
public void add(Widget widget) {
super.add(widget);
widgets.add(widget);
tabs.add(new TabBar.Tab(tabBar));
}
public void remove(Widget widget) {
super.remove(widget);
int tabIndex = getTabIndexForWidget(widget);
assert (tabIndex != -1);
Tab tab = tabs.get(tabIndex);
tab.destroy();
// TODO(jgw): Deal with the selected widget being removed.
widgets.remove(tabIndex);
tabs.remove(tabIndex);
}
};
}
/**
* Gets a container that appends child widgets to this panel. The
* {@link TabBar.Tab} associated with an added widget can be retrieved using
* {@link #getTabForWidget(Widget)}.
*
* @return a container
*/
public Container getContainer() {
return deckContainer;
}
/**
* Gets the {@link TabBar.Tab} associated with the given widget.
*
* @param widget the widget
* @return the widget's tab
*/
public TabBar.Tab getTabForWidget(Widget widget) {
int tabIndex = getTabIndexForWidget(widget);
assert (tabIndex != -1);
return tabs.get(tabIndex);
}
/**
* Selects the tab at the given index.
*
* TODO(jgw): I'm not certain it's a good idea to mix index-based and
* widget-based referencing of tabs. We should probably change this to use a
* widget.
*
* @param index the tab index
*/
public void selectTab(int index) {
assert ((index >= 0) && (index < widgets.size()));
deckPanel.showWidget(widgets.get(index));
}
private int getTabIndexForWidget(Widget widget) {
for (int i = 0; i < widgets.size(); ++i) {
if (widgets.get(i) == widget) {
return i;
}
}
return -1;
}
}