blob: b1673b9bc7ffada22d15cf616b932abfb9ca92ca [file] [log] [blame]
/*
* Copyright 2010 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.sample.showcase.client;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.dom.client.TableCellElement;
import com.google.gwt.dom.client.TableElement;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.http.client.UrlBuilder;
import com.google.gwt.i18n.client.HasDirection.Direction;
import com.google.gwt.i18n.client.LocaleInfo;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.cellview.client.CellTree;
import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy;
import com.google.gwt.user.client.Cookies;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.Window.Location;
import com.google.gwt.user.client.ui.AbstractImagePrototype;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.ResizeComposite;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.SimpleLayoutPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.TreeViewModel;
import java.util.Date;
import java.util.List;
/**
* Application shell for Showcase sample.
*/
public class ShowcaseShell extends ResizeComposite {
interface ShowcaseShellUiBinder extends UiBinder<Widget, ShowcaseShell> {
}
/**
* The callback used when retrieving source code.
*/
private class CustomCallback implements ContentWidget.Callback<String> {
private int id;
public CustomCallback() {
id = ++nextCallbackId;
}
public void onError() {
if (id == nextCallbackId) {
contentSource.setHTML("Cannot find resource", Direction.LTR);
}
}
public void onSuccess(String value) {
if (id == nextCallbackId) {
contentSource.setHTML(value, Direction.LTR);
}
}
}
/**
* The text color of the selected tab.
*/
private static final String SELECTED_TAB_COLOR = "#333333";
/**
* The unique ID assigned to the next callback.
*/
private static int nextCallbackId = 0;
private static ShowcaseShellUiBinder uiBinder = GWT.create(
ShowcaseShellUiBinder.class);
/**
* The panel that holds the content.
*/
@UiField
SimpleLayoutPanel contentPanel;
/**
* The container around the links at the top of the app.
*/
@UiField
TableElement linkCell;
/**
* A drop box used to change the locale.
*/
@UiField
ListBox localeBox;
/**
* The container around locale selection.
*/
@UiField
TableCellElement localeSelectionCell;
/**
* The main menu used to navigate to examples.
*/
@UiField(provided = true)
CellTree mainMenu;
/**
* The button used to show the example.
*/
@UiField
Anchor tabExample;
/**
* The button used to show the source CSS style.
*/
@UiField
Anchor tabStyle;
/**
* The button used to show the source code.
*/
@UiField
Anchor tabSource;
/**
* The list of available source code.
*/
@UiField
ListBox tabSourceList;
/**
* The current {@link ContentWidget} being displayed.
*/
private ContentWidget content;
/**
* The handler used to handle user requests to view raw source.
*/
private HandlerRegistration contentSourceHandler;
/**
* The widget that holds CSS or source code for an example.
*/
private HTML contentSource = new HTML();
/**
* The html used to show a loading icon.
*/
private final String loadingHtml;
/**
* Construct the {@link ShowcaseShell}.
*
* @param treeModel the treeModel that backs the main menu
*/
public ShowcaseShell(TreeViewModel treeModel) {
AbstractImagePrototype proto = AbstractImagePrototype.create(
Showcase.images.loading());
loadingHtml = proto.getHTML();
// Create the cell tree.
mainMenu = new CellTree(treeModel, null);
mainMenu.setAnimationEnabled(true);
mainMenu.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.DISABLED);
mainMenu.ensureDebugId("mainMenu");
// Initialize the ui binder.
initWidget(uiBinder.createAndBindUi(this));
initializeLocaleBox();
contentSource.getElement().getStyle().setBackgroundColor("#eee");
contentSource.getElement().getStyle().setMargin(10.0, Unit.PX);
contentSource.getElement().getStyle().setProperty(
"border", "1px solid #c3c3c3");
contentSource.getElement().getStyle().setProperty("padding", "10px 2px");
// In RTL mode, we need to set some attributes.
if (LocaleInfo.getCurrentLocale().isRTL()) {
localeSelectionCell.setAlign("left");
linkCell.setPropertyString("align", "left");
}
// Handle events from the tabs.
tabExample.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
showExample();
}
});
tabStyle.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
showSourceStyles();
}
});
tabSource.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
showSourceFile();
}
});
tabSourceList.addChangeHandler(new ChangeHandler() {
public void onChange(ChangeEvent event) {
showSourceFile();
}
});
// Default to no content.
contentPanel.ensureDebugId("contentPanel");
setContent(null);
}
/**
* Returns the currently displayed content. (Used by tests.)
*/
public ContentWidget getContent() {
return content;
}
/**
* Get the main menu used to select examples.
*
* @return the main menu
*/
public CellTree getMainMenu() {
return mainMenu;
}
/**
* Set the content to display.
*
* @param content the content
*/
public void setContent(final ContentWidget content) {
// Clear the old handler.
if (contentSourceHandler != null) {
contentSourceHandler.removeHandler();
contentSourceHandler = null;
}
this.content = content;
if (content == null) {
tabExample.setVisible(false);
tabStyle.setVisible(false);
tabSource.setVisible(false);
tabSourceList.setVisible(false);
contentPanel.setWidget(null);
return;
}
// Setup the options bar.
tabExample.setVisible(true);
tabStyle.setVisible(content.hasStyle());
tabSource.setVisible(true);
/*
* Show the list of raw source files if there are any. We need to add at
* least one option to the list for crawlability. If we do not, HtmlUnit
* innerHtml will close the select tag in the open tag (ie, use a forward
* slash instead of a separate close tag) which most browsers parse
* incorrectly.
*/
tabSourceList.clear();
tabSourceList.addItem("Example");
List<String> rawFilenames = content.getRawSourceFilenames();
if (rawFilenames.size() > 0) {
String text = tabSource.getText();
if (!text.endsWith(":")) {
tabSource.setText(text + ":");
}
tabSourceList.setVisible(true);
for (String filename : rawFilenames) {
tabSourceList.addItem(filename);
}
tabSourceList.setSelectedIndex(0);
} else {
String text = tabSource.getText();
if (text.endsWith(":")) {
tabSource.setText(text.substring(0, text.length() - 1));
}
tabSourceList.setVisible(false);
}
// Handle user requests for raw source.
contentSourceHandler = content.addValueChangeHandler(
new ValueChangeHandler<String>() {
public void onValueChange(ValueChangeEvent<String> event) {
// Select the file in the list box.
String filename = event.getValue();
int index = content.getRawSourceFilenames().indexOf(filename);
tabSourceList.setSelectedIndex(index + 1);
// Show the file.
showSourceFile();
}
});
// Show the widget.
showExample();
}
/**
* Initialize the {@link ListBox} used for locale selection.
*/
private void initializeLocaleBox() {
final String cookieName = LocaleInfo.getLocaleCookieName();
final String queryParam = LocaleInfo.getLocaleQueryParam();
if (cookieName == null && queryParam == null) {
// if there is no way for us to affect the locale, don't show the selector
localeSelectionCell.getStyle().setDisplay(Display.NONE);
return;
}
String currentLocale = LocaleInfo.getCurrentLocale().getLocaleName();
if (currentLocale.equals("default")) {
currentLocale = "en";
}
String[] localeNames = LocaleInfo.getAvailableLocaleNames();
for (String localeName : localeNames) {
if (!localeName.equals("default")) {
String nativeName = LocaleInfo.getLocaleNativeDisplayName(localeName);
localeBox.addItem(nativeName, localeName);
if (localeName.equals(currentLocale)) {
localeBox.setSelectedIndex(localeBox.getItemCount() - 1);
}
}
}
localeBox.addChangeHandler(new ChangeHandler() {
@SuppressWarnings("deprecation")
public void onChange(ChangeEvent event) {
String localeName = localeBox.getValue(localeBox.getSelectedIndex());
if (cookieName != null) {
// expire in one year
Date expires = new Date();
expires.setYear(expires.getYear() + 1);
Cookies.setCookie(cookieName, localeName, expires);
}
if (queryParam != null) {
UrlBuilder builder = Location.createUrlBuilder().setParameter(
queryParam, localeName);
Window.Location.replace(builder.buildString());
} else {
// If we are using only cookies, just reload
Window.Location.reload();
}
}
});
}
/**
* Show a example.
*/
private void showExample() {
if (content == null) {
return;
}
// Set the highlighted tab.
tabExample.getElement().getStyle().setColor(SELECTED_TAB_COLOR);
tabStyle.getElement().getStyle().clearColor();
tabSource.getElement().getStyle().clearColor();
contentPanel.setWidget(content);
}
/**
* Show a source file based on the selection in the source list.
*/
private void showSourceFile() {
if (content == null) {
return;
}
// Set the highlighted tab.
tabExample.getElement().getStyle().clearColor();
tabStyle.getElement().getStyle().clearColor();
tabSource.getElement().getStyle().setColor(SELECTED_TAB_COLOR);
contentSource.setHTML(loadingHtml, Direction.LTR);
contentPanel.setWidget(new ScrollPanel(contentSource));
if (!tabSourceList.isVisible() || tabSourceList.getSelectedIndex() == 0) {
// If the source list isn't visible or the first item is selected, load
// the source for the example.
content.getSource(new CustomCallback());
} else {
// Load a raw file.
String filename = tabSourceList.getItemText(
tabSourceList.getSelectedIndex());
content.getRawSource(filename, new CustomCallback());
}
}
/**
* Show the source CSS style.
*/
private void showSourceStyles() {
if (content == null) {
return;
}
// Set the highlighted tab.
tabExample.getElement().getStyle().clearColor();
tabStyle.getElement().getStyle().setColor(SELECTED_TAB_COLOR);
tabSource.getElement().getStyle().clearColor();
contentSource.setHTML(loadingHtml, Direction.LTR);
contentPanel.setWidget(new ScrollPanel(contentSource));
content.getStyle(new CustomCallback());
}
}