/* * 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.sample.showcase.client; import com.google.gwt.core.client.EntryPoint; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.HeadElement; import com.google.gwt.dom.client.Node; import com.google.gwt.dom.client.NodeList; import com.google.gwt.i18n.client.LocaleInfo; import com.google.gwt.sample.showcase.client.Application.ApplicationListener; import com.google.gwt.sample.showcase.client.content.i18n.CwConstantsExample; import com.google.gwt.sample.showcase.client.content.i18n.CwConstantsWithLookupExample; import com.google.gwt.sample.showcase.client.content.i18n.CwDateTimeFormat; import com.google.gwt.sample.showcase.client.content.i18n.CwDictionaryExample; import com.google.gwt.sample.showcase.client.content.i18n.CwMessagesExample; import com.google.gwt.sample.showcase.client.content.i18n.CwNumberFormat; import com.google.gwt.sample.showcase.client.content.lists.CwListBox; import com.google.gwt.sample.showcase.client.content.lists.CwMenuBar; import com.google.gwt.sample.showcase.client.content.lists.CwStackPanel; import com.google.gwt.sample.showcase.client.content.lists.CwSuggestBox; import com.google.gwt.sample.showcase.client.content.lists.CwTree; import com.google.gwt.sample.showcase.client.content.other.CwAnimation; import com.google.gwt.sample.showcase.client.content.other.CwCookies; import com.google.gwt.sample.showcase.client.content.panels.CwAbsolutePanel; import com.google.gwt.sample.showcase.client.content.panels.CwDecoratorPanel; import com.google.gwt.sample.showcase.client.content.panels.CwDisclosurePanel; import com.google.gwt.sample.showcase.client.content.panels.CwDockPanel; import com.google.gwt.sample.showcase.client.content.panels.CwFlowPanel; import com.google.gwt.sample.showcase.client.content.panels.CwHorizontalPanel; import com.google.gwt.sample.showcase.client.content.panels.CwHorizontalSplitPanel; import com.google.gwt.sample.showcase.client.content.panels.CwTabPanel; import com.google.gwt.sample.showcase.client.content.panels.CwVerticalPanel; import com.google.gwt.sample.showcase.client.content.panels.CwVerticalSplitPanel; import com.google.gwt.sample.showcase.client.content.popups.CwBasicPopup; import com.google.gwt.sample.showcase.client.content.popups.CwDialogBox; import com.google.gwt.sample.showcase.client.content.tables.CwFlexTable; import com.google.gwt.sample.showcase.client.content.tables.CwGrid; import com.google.gwt.sample.showcase.client.content.text.CwBasicText; import com.google.gwt.sample.showcase.client.content.text.CwRichText; import com.google.gwt.sample.showcase.client.content.widgets.CwBasicButton; import com.google.gwt.sample.showcase.client.content.widgets.CwCheckBox; import com.google.gwt.sample.showcase.client.content.widgets.CwCustomButton; import com.google.gwt.sample.showcase.client.content.widgets.CwFileUpload; import com.google.gwt.sample.showcase.client.content.widgets.CwHyperlink; import com.google.gwt.sample.showcase.client.content.widgets.CwRadioButton; import com.google.gwt.user.client.Command; import com.google.gwt.user.client.History; import com.google.gwt.user.client.HistoryListener; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.AbstractImagePrototype; import com.google.gwt.user.client.ui.ChangeListener; import com.google.gwt.user.client.ui.ClickListener; import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.HasHorizontalAlignment; import com.google.gwt.user.client.ui.HasVerticalAlignment; import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.ListBox; import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.user.client.ui.TabBar; import com.google.gwt.user.client.ui.ToggleButton; import com.google.gwt.user.client.ui.Tree; import com.google.gwt.user.client.ui.TreeItem; import com.google.gwt.user.client.ui.VerticalPanel; import com.google.gwt.user.client.ui.Widget; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Entry point classes define <code>onModuleLoad()</code>. */ public class Showcase implements EntryPoint { /** * The type passed into the * {@link com.google.gwt.sample.showcase.generator.ShowcaseGenerator}. */ private static final class GeneratorInfo { } /** * A special version of the ToggleButton that cannot be clicked if down. If * one theme button is pressed, all of the others are depressed. */ private static class ThemeButton extends ToggleButton { private static List<ThemeButton> allButtons = null; private String theme; public ThemeButton(String theme) { super(); this.theme = theme; addStyleName("sc-ThemeButton-" + theme); // Add this button to the static list if (allButtons == null) { allButtons = new ArrayList<ThemeButton>(); setDown(true); } allButtons.add(this); } public String getTheme() { return theme; } @Override protected void onClick() { if (!isDown()) { // Raise all of the other buttons for (ThemeButton button : allButtons) { if (button != this) { button.setDown(false); } } // Fire the click listeners super.onClick(); } } } /** * The static images used throughout the Showcase. */ public static final ShowcaseImages images = (ShowcaseImages) GWT.create(ShowcaseImages.class); /** * The current style theme. */ public static String CUR_THEME = ShowcaseConstants.STYLE_THEMES[0]; /** * Get the URL of the page, without an hash of query string. * * @return the location of the page */ private static native String getHostPageLocation() /*-{ var s = $doc.location.href; // Pull off any hash. var i = s.indexOf('#'); if (i != -1) s = s.substring(0, i); // Pull off any query string. i = s.indexOf('?'); if (i != -1) s = s.substring(0, i); // Ensure a final slash if non-empty. return s; }-*/; /** * The {@link Application}. */ private Application app = new Application(); /** * A mapping of history tokens to their associated menu items. */ private Map<String, TreeItem> itemTokens = new HashMap<String, TreeItem>(); /** * A mapping of menu items to the widget display when the item is selected. */ private Map<TreeItem, ContentWidget> itemWidgets = new HashMap<TreeItem, ContentWidget>(); /** * This is the entry point method. */ public void onModuleLoad() { // Generate the source code and css for the examples GWT.create(GeneratorInfo.class); // Create the constants ShowcaseConstants constants = (ShowcaseConstants) GWT.create(ShowcaseConstants.class); // Swap out the style sheets for the RTL versions if needed. updateStyleSheets(); // Create the application setupTitlePanel(constants); setupMainLinks(constants); setupOptionsPanel(); setupMainMenu(constants); // Setup a history listener to reselect the associate menu item final HistoryListener historyListener = new HistoryListener() { public void onHistoryChanged(String historyToken) { TreeItem item = itemTokens.get(historyToken); if (item == null) { item = app.getMainMenu().getItem(0).getChild(0); } // Select the associated TreeItem app.getMainMenu().setSelectedItem(item, false); app.getMainMenu().ensureSelectedItemVisible(); // Show the associated ContentWidget displayContentWidget(itemWidgets.get(item)); } }; History.addHistoryListener(historyListener); // Add an listener that sets the content widget when a menu item is selected app.setListener(new ApplicationListener() { public void onMenuItemSelected(TreeItem item) { ContentWidget content = itemWidgets.get(item); if (content != null && !content.equals(app.getContent())) { History.newItem(getContentWidgetToken(content)); } } }); // Show the initial example String initToken = History.getToken(); if (initToken.length() > 0) { historyListener.onHistoryChanged(initToken); } else { // Use the first token available TreeItem firstItem = app.getMainMenu().getItem(0).getChild(0); app.getMainMenu().setSelectedItem(firstItem, false); app.getMainMenu().ensureSelectedItemVisible(); displayContentWidget(itemWidgets.get(firstItem)); } } /** * Set the content to the {@link ContentWidget}. * * @param content the {@link ContentWidget} to display */ private void displayContentWidget(ContentWidget content) { if (content != null) { app.setContent(content); app.setContentTitle(content.getTabBar()); } } /** * Get the token for a given content widget. * * @return the content widget token. */ private String getContentWidgetToken(ContentWidget content) { String className = content.getClass().getName(); className = className.substring(className.lastIndexOf('.') + 1); return className; } /** * Get the style name of the reference element defined in the current GWT * theme style sheet. * * @param prefix the prefix of the reference style name * @return the style name */ private String getCurrentReferenceStyleName(String prefix) { String gwtRef = prefix + "-Reference-" + CUR_THEME; if (LocaleInfo.getCurrentLocale().isRTL()) { gwtRef += "-rtl"; } return gwtRef; } /** * Create the main links at the top of the application. * * @param constants the constants with text */ private void setupMainLinks(ShowcaseConstants constants) { // Link to GWT Homepage app.addLink(new HTML("<a href=\"" + ShowcaseConstants.GWT_HOMEPAGE + "\">" + constants.mainLinkHomepage() + "</a>")); // Link to More Examples app.addLink(new HTML("<a href=\"" + ShowcaseConstants.GWT_EXAMPLES + "\">" + constants.mainLinkExamples() + "</a>")); } /** * Setup all of the options in the main menu. * * @param constants the constant values to use */ private void setupMainMenu(ShowcaseConstants constants) { Tree mainMenu = app.getMainMenu(); // Widgets TreeItem catWidgets = mainMenu.addItem(constants.categoryWidgets()); setupMainMenuOption(catWidgets, new CwCheckBox(constants), images.catWidgets()); setupMainMenuOption(catWidgets, new CwRadioButton(constants), images.catWidgets()); setupMainMenuOption(catWidgets, new CwBasicButton(constants), images.catWidgets()); setupMainMenuOption(catWidgets, new CwCustomButton(constants), images.catWidgets()); setupMainMenuOption(catWidgets, new CwFileUpload(constants), images.catWidgets()); setupMainMenuOption(catWidgets, new CwHyperlink(constants), images.catWidgets()); // Lists TreeItem catLists = mainMenu.addItem(constants.categoryLists()); setupMainMenuOption(catLists, new CwListBox(constants), images.catLists()); setupMainMenuOption(catLists, new CwSuggestBox(constants), images.catLists()); setupMainMenuOption(catLists, new CwTree(constants), images.catLists()); setupMainMenuOption(catLists, new CwMenuBar(constants), images.catLists()); setupMainMenuOption(catLists, new CwStackPanel(constants), images.catLists()); // Text TreeItem catText = mainMenu.addItem(constants.categoryTextInput()); setupMainMenuOption(catText, new CwBasicText(constants), images.catTextInput()); setupMainMenuOption(catText, new CwRichText(constants), images.catTextInput()); // Popups TreeItem catPopup = mainMenu.addItem(constants.categoryPopups()); setupMainMenuOption(catPopup, new CwBasicPopup(constants), images.catPopups()); setupMainMenuOption(catPopup, new CwDialogBox(constants), images.catPopups()); // Panels TreeItem catPanels = mainMenu.addItem(constants.categoryPanels()); setupMainMenuOption(catPanels, new CwDecoratorPanel(constants), images.catPanels()); setupMainMenuOption(catPanels, new CwFlowPanel(constants), images.catPanels()); setupMainMenuOption(catPanels, new CwHorizontalPanel(constants), images.catPanels()); setupMainMenuOption(catPanels, new CwVerticalPanel(constants), images.catPanels()); setupMainMenuOption(catPanels, new CwAbsolutePanel(constants), images.catPanels()); setupMainMenuOption(catPanels, new CwDockPanel(constants), images.catPanels()); setupMainMenuOption(catPanels, new CwDisclosurePanel(constants), images.catPanels()); setupMainMenuOption(catPanels, new CwTabPanel(constants), images.catPanels()); setupMainMenuOption(catPanels, new CwHorizontalSplitPanel(constants), images.catPanels()); setupMainMenuOption(catPanels, new CwVerticalSplitPanel(constants), images.catPanels()); // Tables TreeItem catTables = mainMenu.addItem(constants.categoryTables()); setupMainMenuOption(catTables, new CwGrid(constants), images.catTables()); setupMainMenuOption(catTables, new CwFlexTable(constants), images.catTables()); // Internationalization TreeItem catI18N = mainMenu.addItem(constants.categoryI18N()); setupMainMenuOption(catI18N, new CwNumberFormat(constants), images.catI18N()); setupMainMenuOption(catI18N, new CwDateTimeFormat(constants), images.catI18N()); setupMainMenuOption(catI18N, new CwMessagesExample(constants), images.catI18N()); setupMainMenuOption(catI18N, new CwConstantsExample(constants), images.catI18N()); setupMainMenuOption(catI18N, new CwConstantsWithLookupExample(constants), images.catI18N()); setupMainMenuOption(catI18N, new CwDictionaryExample(constants), images.catI18N()); // Other TreeItem catOther = mainMenu.addItem(constants.categoryOther()); setupMainMenuOption(catOther, new CwAnimation(constants), images.catOther()); setupMainMenuOption(catOther, new CwCookies(constants), images.catOther()); } /** * Add an option to the main menu. * * @param parent the {@link TreeItem} that is the option * @param content the {@link ContentWidget} to display when selected * @param image the icon to display next to the {@link TreeItem} */ private void setupMainMenuOption(TreeItem parent, ContentWidget content, AbstractImagePrototype image) { // Create the TreeItem TreeItem option = parent.addItem(image.getHTML() + " " + content.getName()); // Map the item to its history token and content widget itemWidgets.put(option, content); itemTokens.put(getContentWidgetToken(content), option); } /** * Create the options that appear next to the title. */ private void setupOptionsPanel() { VerticalPanel vPanel = new VerticalPanel(); vPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT); if (LocaleInfo.getCurrentLocale().isRTL()) { vPanel.getElement().setAttribute("align", "left"); } else { vPanel.getElement().setAttribute("align", "right"); } app.setOptionsWidget(vPanel); // Add the option to change the locale final ListBox localeBox = new ListBox(); 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.addChangeListener(new ChangeListener() { public void onChange(Widget sender) { String localeName = localeBox.getValue(localeBox.getSelectedIndex()); Window.open(getHostPageLocation() + "?locale=" + localeName, "_self", ""); } }); HorizontalPanel localeWrapper = new HorizontalPanel(); localeWrapper.add(images.locale().createImage()); localeWrapper.add(localeBox); vPanel.add(localeWrapper); // Add the option to change the style final HorizontalPanel styleWrapper = new HorizontalPanel(); vPanel.add(styleWrapper); for (int i = 0; i < ShowcaseConstants.STYLE_THEMES.length; i++) { final ThemeButton button = new ThemeButton( ShowcaseConstants.STYLE_THEMES[i]); styleWrapper.add(button); button.addClickListener(new ClickListener() { public void onClick(Widget sender) { // Update the current theme CUR_THEME = button.getTheme(); // Reload the current tab, loading the new theme if necessary TabBar bar = ((TabBar) app.getContentTitle()); bar.selectTab(bar.getSelectedTab()); // Load the new style sheets updateStyleSheets(); } }); } } /** * Create the title bar at the top of the application. * * @param constants the constant values to use */ private void setupTitlePanel(ShowcaseConstants constants) { // Get the title from the internationalized constants String pageTitle = "<h1>" + constants.mainTitle() + "</h1><h2>" + constants.mainSubTitle() + "</h2>"; // Add the title and some images to the title bar HorizontalPanel titlePanel = new HorizontalPanel(); titlePanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE); titlePanel.add(images.gwtLogo().createImage()); titlePanel.add(new HTML(pageTitle)); app.setTitleWidget(titlePanel); } /** * Update the style sheets to reflect the current theme and direction. */ private void updateStyleSheets() { // Generate the names of the style sheets to include String gwtStyleSheet = "gwt/" + CUR_THEME + "/" + CUR_THEME + ".css"; String showcaseStyleSheet = CUR_THEME + "/Showcase.css"; if (LocaleInfo.getCurrentLocale().isRTL()) { gwtStyleSheet = gwtStyleSheet.replace(".css", "_rtl.css"); showcaseStyleSheet = showcaseStyleSheet.replace(".css", "_rtl.css"); } // Find existing style sheets that need to be removed boolean styleSheetsFound = false; final HeadElement headElem = StyleSheetLoader.getHeadElement(); final List<Element> toRemove = new ArrayList<Element>(); NodeList<Node> children = headElem.getChildNodes(); for (int i = 0; i < children.getLength(); i++) { Node node = children.getItem(i); if (node.getNodeType() == Node.ELEMENT_NODE) { Element elem = Element.as(node); if (elem.getTagName().equalsIgnoreCase("link") && elem.getPropertyString("rel").equalsIgnoreCase("stylesheet")) { styleSheetsFound = true; String href = elem.getPropertyString("href"); // If the correct style sheets are already loaded, then we should have // nothing to remove. if (!href.contains(gwtStyleSheet) && !href.contains(showcaseStyleSheet)) { toRemove.add(elem); } } } } // Return if we already have the correct style sheets if (styleSheetsFound && toRemove.size() == 0) { return; } // Detach the app while we manipulate the styles to avoid rendering issues RootPanel.get().remove(app); // Remove the old style sheets for (Element elem : toRemove) { headElem.removeChild(elem); } // Load the GWT theme style sheet String modulePath = GWT.getModuleBaseURL(); Command callback = new Command() { /** * The number of style sheets that have been loaded and executed this * command. */ private int numStyleSheetsLoaded = 0; public void execute() { // Wait until all style sheets have loaded before re-attaching the app numStyleSheetsLoaded++; if (numStyleSheetsLoaded < 2) { return; } // Different themes use different background colors for the body // element, but IE only changes the background of the visible content // on the page instead of changing the background color of the entire // page. By changing the display style on the body element, we force // IE to redraw the background correctly. RootPanel.getBodyElement().getStyle().setProperty("display", "none"); RootPanel.getBodyElement().getStyle().setProperty("display", ""); RootPanel.get().add(app); } }; StyleSheetLoader.loadStyleSheet(modulePath + gwtStyleSheet, getCurrentReferenceStyleName("gwt"), callback); // Load the showcase specific style sheet after the GWT theme style sheet so // that custom styles supercede the theme styles. StyleSheetLoader.loadStyleSheet(modulePath + showcaseStyleSheet, getCurrentReferenceStyleName("Application"), callback); } }