/******************************************************************************* * Copyright (c) 2006-2010 eBay Inc. All Rights Reserved. * 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 *******************************************************************************/ package org.ebayopensource.turmeric.policy.adminui.client.view.common; import com.google.gwt.safehtml.shared.SafeHtml; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.ui.ComplexPanel; import com.google.gwt.user.client.ui.InsertPanel; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.UIObject; import com.google.gwt.user.client.ui.Widget; /** * The Class TurmericStackPanel. */ public class TurmericStackPanel extends ComplexPanel implements InsertPanel.ForIsWidget { private static final String DEFAULT_STYLENAME = "gwt-StackPanel"; private static final String DEFAULT_ITEM_STYLENAME = "gwt-StackPanelItem"; private Element body; private int visibleStack = -1; /** * Instantiates a new turmeric stack panel. */ public TurmericStackPanel() { Element table = DOM.createTable(); setElement(table); this.body = DOM.createTBody(); DOM.appendChild(table, this.body); DOM.setElementPropertyInt(table, "cellSpacing", 0); DOM.setElementPropertyInt(table, "cellPadding", 0); DOM.sinkEvents(table, 1); setStyleName("gwt-StackPanel"); } /* (non-Javadoc) * @see com.google.gwt.user.client.ui.Panel#add(com.google.gwt.user.client.ui.Widget) */ public void add(Widget w) { insert(w, getWidgetCount()); } /** * Adds the. * * @param w * the w * @param stackText * the stack text */ public void add(Widget w, String stackText) { add(w, stackText, false); } /** * Adds the. * * @param w * the w * @param stackHtml * the stack html */ public void add(Widget w, SafeHtml stackHtml) { add(w, stackHtml.asString(), true); } /** * Adds the. * * @param w * the w * @param stackText * the stack text * @param asHTML * the as html */ public void add(Widget w, String stackText, boolean asHTML) { add(w); setStackText(getWidgetCount() - 1, stackText, asHTML); } /** * Gets the selected index. * * @return the selected index */ public int getSelectedIndex() { return this.visibleStack; } /* (non-Javadoc) * @see com.google.gwt.user.client.ui.InsertPanel.ForIsWidget#insert(com.google.gwt.user.client.ui.IsWidget, int) */ public void insert(IsWidget w, int beforeIndex) { insert(asWidgetOrNull(w), beforeIndex); } /* (non-Javadoc) * @see com.google.gwt.user.client.ui.InsertPanel#insert(com.google.gwt.user.client.ui.Widget, int) */ public void insert(Widget w, int beforeIndex) { Element trh = DOM.createTR(); Element tdh = DOM.createTD(); DOM.appendChild(trh, tdh); DOM.appendChild(tdh, createHeaderElem()); Element trb = DOM.createTR(); Element tdb = DOM.createTD(); DOM.appendChild(trb, tdb); beforeIndex = adjustIndex(w, beforeIndex); int effectiveIndex = beforeIndex * 2; DOM.insertChild(this.body, trb, effectiveIndex); DOM.insertChild(this.body, trh, effectiveIndex); setStyleName(tdh, "gwt-StackPanelItem", true); DOM.setElementPropertyInt(tdh, "__owner", super.hashCode()); DOM.setElementProperty(tdh, "height", "1px"); setStyleName(tdb, "gwt-StackPanelContent", true); DOM.setElementProperty(tdb, "height", "100%"); DOM.setElementProperty(tdb, "vAlign", "top"); insert(w, tdb, beforeIndex, false); updateIndicesFrom(beforeIndex); if (this.visibleStack == -1) { showStack(0); } else { setStackVisible(beforeIndex, false); if (this.visibleStack >= beforeIndex) { this.visibleStack += 1; } setStackVisible(this.visibleStack, true); } } /* (non-Javadoc) * @see com.google.gwt.user.client.ui.Widget#onBrowserEvent(com.google.gwt.user.client.Event) */ public void onBrowserEvent(Event event) { if (DOM.eventGetType(event) == 1) { Element target = DOM.eventGetTarget(event); int index = findDividerIndex(target); if (index != -1) { showStack(index); } } super.onBrowserEvent(event); } /* (non-Javadoc) * @see com.google.gwt.user.client.ui.ComplexPanel#remove(int) */ public boolean remove(int index) { return remove(getWidget(index), index); } /* (non-Javadoc) * @see com.google.gwt.user.client.ui.ComplexPanel#remove(com.google.gwt.user.client.ui.Widget) */ public boolean remove(Widget child) { return remove(child, getWidgetIndex(child)); } /** * Sets the stack text. * * @param index * the index * @param text * the text */ public void setStackText(int index, String text) { setStackText(index, text, false); } /** * Sets the stack text. * * @param index * the index * @param html * the html */ public void setStackText(int index, SafeHtml html) { setStackText(index, html.asString(), true); } /** * Sets the stack text. * * @param index * the index * @param text * the text * @param asHTML * the as html */ public void setStackText(int index, String text, boolean asHTML) { if (index >= getWidgetCount()) { return; } Element tdWrapper = DOM.getChild(DOM.getChild(this.body, index * 2), 0); Element headerElem = DOM.getFirstChild(tdWrapper); if (asHTML) DOM.setInnerHTML(getHeaderTextElem(headerElem), text); else DOM.setInnerText(getHeaderTextElem(headerElem), text); } /** * Show stack. * * @param index * the index */ public void showStack(int index) { if ((index >= getWidgetCount()) || index < 1) { return; } visibleStack = index; setStackVisible(visibleStack, !getWidget(visibleStack).isVisible()); // replaced code in order to mantain all panels open // if ((index >= getwidgetcount()) || (index < 0) // || (index == this.visiblestack)) { // return; // } // // if (this.visiblestack >= 0) { // setstackvisible(this.visiblestack, false); // } // // this.visiblestack = index; // setstackvisible(this.visiblestack, true); } /* (non-Javadoc) * @see com.google.gwt.user.client.ui.UIObject#onEnsureDebugId(java.lang.String) */ protected void onEnsureDebugId(String baseID) { super.onEnsureDebugId(baseID); int numHeaders = DOM.getChildCount(this.body) >> 1; for (int i = 0; i < numHeaders; ++i) { Element tdWrapper = DOM.getFirstChild(DOM .getChild(this.body, 2 * i)); Element headerElem = DOM.getFirstChild(tdWrapper); Element bodyElem = DOM.getFirstChild(DOM.getChild(this.body, 2 * i + 1)); ensureDebugId(tdWrapper, baseID, "text-wrapper" + i); ensureDebugId(bodyElem, baseID, "content" + i); ensureDebugId(getHeaderTextElem(headerElem), baseID, "text" + i); } } Element createHeaderElem() { return DOM.createDiv(); } Element getHeaderTextElem(Element headerElem) { return headerElem; } private int findDividerIndex(Element elem) { while ((elem != null) && (elem != getElement())) { String expando = DOM.getElementProperty(elem, "__index"); if (expando != null) { int ownerHash = DOM.getElementPropertyInt(elem, "__owner"); if (ownerHash == super.hashCode()) { return Integer.parseInt(expando); } return -1; } elem = DOM.getParent(elem); } return -1; } private boolean remove(Widget child, int index) { boolean removed = super.remove(child); if (removed) { int rowIndex = 2 * index; Element tr = DOM.getChild(this.body, rowIndex); DOM.removeChild(this.body, tr); tr = DOM.getChild(this.body, rowIndex); DOM.removeChild(this.body, tr); if (this.visibleStack == index) this.visibleStack = -1; else if (this.visibleStack > index) { this.visibleStack -= 1; } updateIndicesFrom(index); } return removed; } private void setStackContentVisible(int index, boolean visible) { Element tr = DOM.getChild(this.body, index * 2 + 1); UIObject.setVisible(tr, visible); getWidget(index).setVisible(visible); } private void setStackVisible(int index, boolean visible) { Element tr = DOM.getChild(this.body, index * 2); if (tr == null) { return; } Element td = DOM.getFirstChild(tr); setStyleName(td, "gwt-StackPanelItem-selected", visible); setStackContentVisible(index, visible); Element trNext = DOM.getChild(this.body, (index + 1) * 2); if (trNext != null) { Element tdNext = DOM.getFirstChild(trNext); setStyleName(tdNext, "gwt-StackPanelItem-below-selected", visible); } } private void updateIndicesFrom(int beforeIndex) { int i = beforeIndex; for (int c = getWidgetCount(); i < c; ++i) { Element childTR = DOM.getChild(this.body, i * 2); Element childTD = DOM.getFirstChild(childTR); DOM.setElementPropertyInt(childTD, "__index", i); if (beforeIndex == 0) setStyleName(childTD, "gwt-StackPanelItem-first", true); else setStyleName(childTD, "gwt-StackPanelItem-first", false); } } }