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

nextapp.echo2.webcontainer.syncpeer.ButtonPeer Maven / Gradle / Ivy

Go to download

Echo2 bundled with Echo2_Extras, Echo2_FileTransfer and echopointing and various improvements/bugfixes

There is a newer version: 2.0.4
Show newest version
/* 
 * This file is part of the Echo Web Application Framework (hereinafter "Echo").
 * Copyright (C) 2002-2009 NextApp, Inc.
 *
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (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.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 */

package nextapp.echo2.webcontainer.syncpeer;

import nextapp.echo2.app.Alignment;
import nextapp.echo2.app.Border;
import nextapp.echo2.app.CheckBox;
import nextapp.echo2.app.Color;
import nextapp.echo2.app.Component;
import nextapp.echo2.app.Extent;
import nextapp.echo2.app.FillImage;
import nextapp.echo2.app.Font;
import nextapp.echo2.app.ImageReference;
import nextapp.echo2.app.Insets;
import nextapp.echo2.app.RadioButton;
import nextapp.echo2.app.ResourceImageReference;
import nextapp.echo2.app.button.AbstractButton;
import nextapp.echo2.app.button.ButtonGroup;
import nextapp.echo2.app.button.ToggleButton;
import nextapp.echo2.app.update.ServerComponentUpdate;
import nextapp.echo2.webcontainer.ActionProcessor;
import nextapp.echo2.webcontainer.ContainerInstance;
import nextapp.echo2.webcontainer.DomUpdateSupport;
import nextapp.echo2.webcontainer.PropertyUpdateProcessor;
import nextapp.echo2.webcontainer.RenderContext;
import nextapp.echo2.webcontainer.ComponentSynchronizePeer;
import nextapp.echo2.webcontainer.image.ImageRenderSupport;
import nextapp.echo2.webcontainer.image.ImageTools;
import nextapp.echo2.webcontainer.propertyrender.AlignmentRender;
import nextapp.echo2.webcontainer.propertyrender.BorderRender;
import nextapp.echo2.webcontainer.propertyrender.ColorRender;
import nextapp.echo2.webcontainer.propertyrender.ExtentRender;
import nextapp.echo2.webcontainer.propertyrender.FillImageRender;
import nextapp.echo2.webcontainer.propertyrender.FontRender;
import nextapp.echo2.webcontainer.propertyrender.ImageReferenceRender;
import nextapp.echo2.webcontainer.propertyrender.InsetsRender;
import nextapp.echo2.webcontainer.propertyrender.LayoutDirectionRender;
import nextapp.echo2.webrender.ServerMessage;
import nextapp.echo2.webrender.Service;
import nextapp.echo2.webrender.WebRenderServlet;
import nextapp.echo2.webrender.output.CssStyle;
import nextapp.echo2.webrender.servermessage.DomUpdate;
import nextapp.echo2.webrender.service.JavaScriptService;

import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.Text;

/**
 * Synchronization peer for 
 * nextapp.echo2.app.AbstractButton-derived components.
 * 

* This class should not be extended or used by classes outside of the * Echo framework. */ public class ButtonPeer implements ActionProcessor, DomUpdateSupport, ImageRenderSupport, PropertyUpdateProcessor, ComponentSynchronizePeer { private static final Alignment DEFAULT_TEXT_POSITION = new Alignment(Alignment.TRAILING, Alignment.DEFAULT); private static final Alignment DEFAULT_STATE_POSITION = new Alignment(Alignment.LEADING, Alignment.DEFAULT); private static final Extent DEFAULT_ICON_TEXT_MARGIN = new Extent(5); private static final ImageReference DEFAULT_CHECKBOX_ICON = new ResourceImageReference("/nextapp/echo2/webcontainer/resource/image/CheckBoxOff.gif"); private static final ImageReference DEFAULT_SELECTED_CHECKBOX_ICON = new ResourceImageReference("/nextapp/echo2/webcontainer/resource/image/CheckBoxOn.gif"); private static final ImageReference DEFAULT_RADIOBUTTON_ICON = new ResourceImageReference("/nextapp/echo2/webcontainer/resource/image/RadioButtonOff.gif"); private static final ImageReference DEFAULT_SELECTED_RADIOBUTTON_ICON = new ResourceImageReference("/nextapp/echo2/webcontainer/resource/image/RadioButtonOn.gif"); private static final String[] BUTTON_INIT_KEYS = new String[]{"default-style", "rollover-style", "pressed-style"}; private static final String IMAGE_ID_BACKGROUND = "background"; private static final String IMAGE_ID_ICON = "icon"; private static final String IMAGE_ID_ROLLOVER_BACKGROUND = "rolloverBackground"; private static final String IMAGE_ID_ROLLOVER_ICON = "rolloverIcon"; private static final String IMAGE_ID_ROLLOVER_STATE_ICON = "rolloverStateIcon"; private static final String IMAGE_ID_ROLLOVER_SELECTED_STATE_ICON = "rolloverSelectedStateIcon"; private static final String IMAGE_ID_PRESSED_BACKGROUND = "pressedBackground"; private static final String IMAGE_ID_PRESSED_ICON = "pressedIcon"; private static final String IMAGE_ID_PRESSED_STATE_ICON = "pressedStateIcon"; private static final String IMAGE_ID_PRESSED_SELECTED_STATE_ICON = "pressedSelectedStateIcon"; private static final String IMAGE_ID_STATE_ICON = "stateIcon"; private static final String IMAGE_ID_SELECTED_STATE_ICON = "selectedStateIcon"; private static final String CONTAINER_TABLE_CSS_TEXT_DEFAULT = "border:0px none;border-collapse:collapse;"; private static final String CONTAINER_TABLE_CSS_TEXT_LEFT = "border:0px none;border-collapse:collapse; margin: 0 auto 0 0"; private static final String CONTAINER_TABLE_CSS_TEXT_CENTER = "border:0px none;border-collapse:collapse; margin: 0 auto;"; private static final String CONTAINER_TABLE_CSS_TEXT_RIGHT = "border:0px none;border-collapse:collapse; margin: 0 0 0 auto;"; /** * Service to provide supporting JavaScript library. */ private static final Service BUTTON_SERVICE = JavaScriptService.forResource("Echo.Button", "/nextapp/echo2/webcontainer/resource/js/Button.js"); static { WebRenderServlet.getServiceRegistry().add(BUTTON_SERVICE); } /** * Determines the CSS text which should be placed in the 'style' attribute * of the button's container TABLE element. * * @param button the rendering AbstractButton * @return the CSS text */ private static String getContainerTableCssText(AbstractButton button) { Alignment alignment = (Alignment) button.getRenderProperty(AbstractButton.PROPERTY_ALIGNMENT); if (alignment != null) { int horizontal = AlignmentRender.getRenderedHorizontal(alignment, button); switch (horizontal) { case Alignment.LEFT: return CONTAINER_TABLE_CSS_TEXT_LEFT; case Alignment.CENTER: return CONTAINER_TABLE_CSS_TEXT_CENTER; case Alignment.RIGHT: return CONTAINER_TABLE_CSS_TEXT_RIGHT; } } return CONTAINER_TABLE_CSS_TEXT_DEFAULT; } /** * @see nextapp.echo2.webcontainer.ComponentSynchronizePeer#getContainerId(nextapp.echo2.app.Component) */ public String getContainerId(Component child) { throw new UnsupportedOperationException("Component does not support children."); } /** * Combines the properties of two Alignment objects together. * Properties of the secondary object will override default * properties of the primary. * * @param primary the first Alignment (may be null) * @param secondary the second Alignment (may be null) * @return a new Alignment combining the values of both (or * null if both input Alignments were null */ private Alignment combineAlignment(Alignment primary, Alignment secondary) { if (primary == null) { return secondary; } else if (secondary == null) { return primary; } int horizontal = primary.getHorizontal(); int vertical = primary.getVertical(); Alignment alignment = new Alignment(horizontal == Alignment.DEFAULT ? secondary.getHorizontal() : horizontal, vertical == Alignment.DEFAULT ? secondary.getVertical() : vertical); return alignment; } /** * @see nextapp.echo2.webcontainer.image.ImageRenderSupport#getImage(nextapp.echo2.app.Component, * java.lang.String) */ public ImageReference getImage(Component component, String imageId) { if (IMAGE_ID_ICON.equals(imageId)) { if (component.isRenderEnabled()) { return (ImageReference) component.getRenderProperty(AbstractButton.PROPERTY_ICON); } else { ImageReference icon = (ImageReference) component.getRenderProperty(AbstractButton.PROPERTY_DISABLED_ICON); if (icon == null) { icon = (ImageReference) component.getRenderProperty(AbstractButton.PROPERTY_ICON); } return icon; } } else if (IMAGE_ID_ROLLOVER_ICON.equals(imageId)) { return (ImageReference) component.getRenderProperty(AbstractButton.PROPERTY_ROLLOVER_ICON); } else if (IMAGE_ID_PRESSED_ICON.equals(imageId)) { return (ImageReference) component.getRenderProperty(AbstractButton.PROPERTY_PRESSED_ICON); } else if (IMAGE_ID_STATE_ICON.equals(imageId)) { return getStateIcon((ToggleButton) component); } else if (IMAGE_ID_SELECTED_STATE_ICON.equals(imageId)) { return getSelectedStateIcon((ToggleButton) component); } else if (IMAGE_ID_BACKGROUND.equals(imageId)) { FillImage backgroundImage; if (component.isRenderEnabled()) { backgroundImage = (FillImage) component.getRenderProperty(AbstractButton.PROPERTY_BACKGROUND_IMAGE); } else { backgroundImage = (FillImage) component.getRenderProperty(AbstractButton.PROPERTY_DISABLED_BACKGROUND_IMAGE); if (backgroundImage == null) { backgroundImage = (FillImage) component.getRenderProperty(AbstractButton.PROPERTY_BACKGROUND_IMAGE); } } if (backgroundImage == null) { return null; } else { return backgroundImage.getImage(); } } else if (IMAGE_ID_ROLLOVER_BACKGROUND.equals(imageId)) { FillImage backgroundImage = (FillImage) component.getRenderProperty(AbstractButton.PROPERTY_ROLLOVER_BACKGROUND_IMAGE); if (backgroundImage == null) { return null; } else { return backgroundImage.getImage(); } } else if (IMAGE_ID_PRESSED_BACKGROUND.equals(imageId)) { FillImage backgroundImage = (FillImage) component.getRenderProperty(AbstractButton.PROPERTY_PRESSED_BACKGROUND_IMAGE); if (backgroundImage == null) { return null; } else { return backgroundImage.getImage(); } } else if (IMAGE_ID_ROLLOVER_STATE_ICON.equals(imageId)) { ImageReference icon = (ImageReference) component.getRenderProperty(ToggleButton.PROPERTY_ROLLOVER_STATE_ICON); return icon == null ? getStateIcon((ToggleButton) component) : icon; } else if (IMAGE_ID_ROLLOVER_SELECTED_STATE_ICON.equals(imageId)) { ImageReference icon = (ImageReference) component.getRenderProperty(ToggleButton.PROPERTY_ROLLOVER_SELECTED_STATE_ICON); return icon == null ? getSelectedStateIcon((ToggleButton) component) : icon; } else if (IMAGE_ID_PRESSED_STATE_ICON.equals(imageId)) { ImageReference icon = (ImageReference) component.getRenderProperty(ToggleButton.PROPERTY_PRESSED_STATE_ICON); return icon == null ? getStateIcon((ToggleButton) component) : icon; } else if (IMAGE_ID_PRESSED_SELECTED_STATE_ICON.equals(imageId)) { ImageReference icon = (ImageReference) component.getRenderProperty(ToggleButton.PROPERTY_PRESSED_SELECTED_STATE_ICON); return icon == null ? getSelectedStateIcon((ToggleButton) component) : icon; } else { return null; } } /** * Determines the selected state icon of the specified * ToggleButton. * * @param toggleButton the ToggleButton * @return the selected state icon */ private ImageReference getSelectedStateIcon(ToggleButton toggleButton) { ImageReference selectedStateIcon = (ImageReference) toggleButton.getRenderProperty(ToggleButton.PROPERTY_SELECTED_STATE_ICON); if (selectedStateIcon == null) { if (toggleButton instanceof CheckBox) { selectedStateIcon = DEFAULT_SELECTED_CHECKBOX_ICON; } else if (toggleButton instanceof RadioButton) { selectedStateIcon = DEFAULT_SELECTED_RADIOBUTTON_ICON; } } return selectedStateIcon; } /** * Determines the default (non-selected) state icon of the specified * ToggleButton. * * @param toggleButton the ToggleButton * @return the state icon */ private ImageReference getStateIcon(ToggleButton toggleButton) { ImageReference stateIcon = (ImageReference) toggleButton.getRenderProperty(ToggleButton.PROPERTY_STATE_ICON); if (stateIcon == null) { if (toggleButton instanceof CheckBox) { stateIcon = DEFAULT_CHECKBOX_ICON; } else if (toggleButton instanceof RadioButton) { stateIcon = DEFAULT_RADIOBUTTON_ICON; } } return stateIcon; } /** * @see nextapp.echo2.webcontainer.ActionProcessor#processAction(nextapp.echo2.webcontainer.ContainerInstance, * nextapp.echo2.app.Component, org.w3c.dom.Element) */ public void processAction(ContainerInstance ci, Component component, Element actionElement) { ci.getUpdateManager().getClientUpdateManager().setComponentAction(component, AbstractButton.INPUT_CLICK, null); } /** * @see nextapp.echo2.webcontainer.PropertyUpdateProcessor#processPropertyUpdate( * nextapp.echo2.webcontainer.ContainerInstance, nextapp.echo2.app.Component, org.w3c.dom.Element) */ public void processPropertyUpdate(ContainerInstance ci, Component component, Element propertyElement) { String propertyName = propertyElement.getAttribute(PropertyUpdateProcessor.PROPERTY_NAME); if (ToggleButton.SELECTED_CHANGED_PROPERTY.equals(propertyName)) { Boolean propertyValue = new Boolean("true".equals(propertyElement.getAttribute("value"))); ci.getUpdateManager().getClientUpdateManager().setComponentProperty(component, ToggleButton.SELECTED_CHANGED_PROPERTY, propertyValue); } } /** * @see nextapp.echo2.webcontainer.ComponentSynchronizePeer#renderAdd(nextapp.echo2.webcontainer.RenderContext, * nextapp.echo2.app.update.ServerComponentUpdate, java.lang.String, nextapp.echo2.app.Component) */ public void renderAdd(RenderContext rc, ServerComponentUpdate update, String targetId, Component component) { Element domAddElement = DomUpdate.renderElementAdd(rc.getServerMessage()); DocumentFragment htmlFragment = rc.getServerMessage().getDocument().createDocumentFragment(); renderHtml(rc, update, htmlFragment, component); DomUpdate.renderElementAddContent(rc.getServerMessage(), domAddElement, targetId, htmlFragment); } /** * Renders the containing DIV element of a button. * * @param rc the relevant RenderContext * @param parentNode the parent node * @param button the AbstractButton being rendered * @return the rendered DIV element (note that this element will already * have been appended to the parent) */ private Element renderButtonContainer(RenderContext rc, Node parentNode, AbstractButton button) { Element divElement = parentNode.getOwnerDocument().createElement("div"); divElement.setAttribute("id", ContainerInstance.getElementId(button)); if (button.isFocusTraversalParticipant()) { divElement.setAttribute("tabindex", Integer.toString(button.getFocusTraversalIndex())); } else { divElement.setAttribute("tabindex", "-1"); } boolean renderEnabled = button.isRenderEnabled(); String toolTipText = (String) button.getRenderProperty(AbstractButton.PROPERTY_TOOL_TIP_TEXT); if (renderEnabled && toolTipText != null) { divElement.setAttribute("title", toolTipText); } divElement.setAttribute("style", "visibility:hidden;"); parentNode.appendChild(divElement); return divElement; } /** * Renders the content of the button, i.e., its text, icon, and/or state icon. * * @param rc the relevant RenderContext * @param buttonContainerElement the Element which will * contain the content * @param button the AbstractButton being rendered */ private void renderButtonContent(RenderContext rc, Element buttonContainerElement, AbstractButton button) { Node contentNode; Document document = rc.getServerMessage().getDocument(); ToggleButton toggleButton = button instanceof ToggleButton ? (ToggleButton) button : null; String elementId = ContainerInstance.getElementId(button); String text = (String) button.getRenderProperty(AbstractButton.PROPERTY_TEXT); ImageReference icon = (ImageReference) button.getRenderProperty(AbstractButton.PROPERTY_ICON); // Create entities. Text textNode = text == null ? null : rc.getServerMessage().getDocument().createTextNode( (String) button.getRenderProperty(AbstractButton.PROPERTY_TEXT)); Element iconElement; if (icon == null) { iconElement = null; } else { iconElement = ImageReferenceRender.renderImageReferenceElement(rc, ButtonPeer.this, button, IMAGE_ID_ICON); iconElement.setAttribute("id", elementId + "_icon"); } Element stateIconElement; if (toggleButton == null) { stateIconElement = null; } else { stateIconElement = ImageReferenceRender.renderImageReferenceElement(rc, ButtonPeer.this, button, toggleButton.isSelected() ? IMAGE_ID_SELECTED_STATE_ICON : IMAGE_ID_STATE_ICON); stateIconElement.setAttribute("id", elementId + "_stateicon"); } int entityCount = (textNode == null ? 0 : 1) + (iconElement == null ? 0 : 1) + (stateIconElement == null ? 0 : 1); Extent iconTextMargin; Alignment textPosition; Element tableElement; switch (entityCount) { case 1: if (textNode != null) { contentNode = textNode; } else if (iconElement != null) { contentNode = iconElement; } else { // stateIconElement must not be null. contentNode = stateIconElement; } break; case 2: iconTextMargin = (Extent) button.getRenderProperty(AbstractButton.PROPERTY_ICON_TEXT_MARGIN, DEFAULT_ICON_TEXT_MARGIN); TriCellTable tct; textPosition = (Alignment) button.getRenderProperty(AbstractButton.PROPERTY_TEXT_POSITION, DEFAULT_TEXT_POSITION); if (stateIconElement == null) { // Not rendering a ToggleButton. int orientation = TriCellTableConfigurator.convertIconTextPositionToOrientation(textPosition, button); tct = new TriCellTable(rc, document, elementId, orientation, iconTextMargin); renderCellText(tct, textNode, button); renderCellIcon(tct, iconElement, 1, button); } else { // Rendering a ToggleButton. Extent stateMargin = (Extent) button.getRenderProperty(ToggleButton.PROPERTY_STATE_MARGIN, DEFAULT_ICON_TEXT_MARGIN); Alignment statePosition = (Alignment) button.getRenderProperty(ToggleButton.PROPERTY_STATE_POSITION, DEFAULT_STATE_POSITION); int orientation = TriCellTableConfigurator.convertStatePositionToOrientation(statePosition, button); tct = new TriCellTable(rc, document, elementId, orientation, stateMargin); if (textNode == null) { renderCellIcon(tct, iconElement, 0, button); } else { renderCellText(tct, textNode, button); } renderCellState(tct, stateIconElement, 1, button); } tct.addCellCssText("padding:0px;"); tableElement = tct.getTableElement(); tableElement.setAttribute("id", elementId + "_table"); tableElement.setAttribute("style", getContainerTableCssText(button)); contentNode = tableElement; break; case 3: iconTextMargin = (Extent) button.getRenderProperty(AbstractButton.PROPERTY_ICON_TEXT_MARGIN, DEFAULT_ICON_TEXT_MARGIN); textPosition = (Alignment) button.getRenderProperty(AbstractButton.PROPERTY_TEXT_POSITION, DEFAULT_TEXT_POSITION); Extent stateMargin = (Extent) button.getRenderProperty(ToggleButton.PROPERTY_STATE_MARGIN, DEFAULT_ICON_TEXT_MARGIN); Alignment statePosition = (Alignment) button.getRenderProperty(ToggleButton.PROPERTY_STATE_POSITION, DEFAULT_STATE_POSITION); int stateOrientation = TriCellTableConfigurator.convertStatePositionToOrientation(statePosition, button); int orientation = TriCellTableConfigurator.convertIconTextPositionToOrientation(textPosition, button); tct = new TriCellTable(rc, document, elementId, orientation, iconTextMargin, stateOrientation, stateMargin); renderCellText(tct, textNode, button); renderCellIcon(tct, iconElement, 1, button); renderCellState(tct, stateIconElement, 2, button); tct.addCellCssText("padding:0px;"); tableElement = tct.getTableElement(); tableElement.setAttribute("id", elementId + "_table"); tableElement.setAttribute("style", getContainerTableCssText(button)); contentNode = tableElement; break; default: // 0 element button. contentNode = null; } if (contentNode != null) { buttonContainerElement.appendChild(contentNode); } } /** * Renders the content of the TriCellTable cell which * contains the button's icon. * * @param tct the TriCellTable to update * @param iconElement the icon element * @param cellIndex the index of the cell in the TriCellTable * that should contain the icon */ private void renderCellIcon(TriCellTable tct, Element iconElement, int cellIndex, AbstractButton button) { Element iconTdElement = tct.getTdElement(cellIndex); Alignment alignment = (Alignment) button.getRenderProperty(AbstractButton.PROPERTY_ALIGNMENT); if (alignment != null) { CssStyle style = new CssStyle(); AlignmentRender.renderToStyle(style, alignment, button); iconTdElement.setAttribute("style", style.renderInline()); } iconTdElement.appendChild(iconElement); } /** * Renders the content of the TriCellTable cell which * contains the button's state icon. * * @param tct the TriCellTable to update * @param stateIconElement the state icon element * @param cellIndex the index of the cell in the TriCellTable * that should contain the state icon * @param button the AbstractButton being rendered */ private void renderCellState(TriCellTable tct, Element stateIconElement, int cellIndex, AbstractButton button) { Element stateTdElement = tct.getTdElement(cellIndex); CssStyle stateTdCssStyle = new CssStyle(); AlignmentRender.renderToStyle(stateTdCssStyle, (Alignment) button.getRenderProperty(ToggleButton.PROPERTY_STATE_ALIGNMENT), button); stateTdElement.setAttribute("style", stateTdCssStyle.renderInline()); stateTdElement.appendChild(stateIconElement); } /** * Renders the content of the TriCellTable cell which * contains the button's text. * Text is always rendered in cell #0 of the table. * * @param tct the TriCellTable to update * @param textNode the text * @param button the AbstractButton being rendered */ private void renderCellText(TriCellTable tct, Text textNode, AbstractButton button) { Element textTdElement = tct.getTdElement(0); CssStyle textTdCssStyle = new CssStyle(); if (Boolean.FALSE.equals(button.getRenderProperty(AbstractButton.PROPERTY_LINE_WRAP))) { textTdCssStyle.setAttribute("white-space", "nowrap"); } Alignment alignment = combineAlignment((Alignment) button.getRenderProperty(AbstractButton.PROPERTY_TEXT_ALIGNMENT), (Alignment) button.getRenderProperty(AbstractButton.PROPERTY_ALIGNMENT)); AlignmentRender.renderToStyle(textTdCssStyle, alignment, button); boolean renderEnabled = button.isRenderEnabled(); Font font; if (renderEnabled) { font = (Font) button.getRenderProperty(AbstractButton.PROPERTY_FONT); } else { font = (Font) button.getRenderProperty(AbstractButton.PROPERTY_DISABLED_FONT); if (font == null) { font = (Font) button.getRenderProperty(AbstractButton.PROPERTY_FONT); } } FontRender.renderToStyle(textTdCssStyle, font); if (textTdCssStyle.hasAttributes()) { textTdElement.setAttribute("style", textTdCssStyle.renderInline()); } textTdElement.appendChild(textNode); } /** * Render default CSS style. */ private CssStyle renderDefaultStyle(RenderContext rc, AbstractButton button) { int entityCount = (button.getRenderProperty(AbstractButton.PROPERTY_TEXT) == null ? 1 : 0) + (button.getRenderProperty(AbstractButton.PROPERTY_ICON) == null ? 1 : 0) + (button instanceof ToggleButton ? 1 : 0); CssStyle cssStyle = new CssStyle(); LayoutDirectionRender.renderToStyle(cssStyle, button.getLayoutDirection(), button.getLocale()); ExtentRender.renderToStyle(cssStyle, "width", (Extent) button.getRenderProperty(AbstractButton.PROPERTY_WIDTH)); Extent height = (Extent) button.getRenderProperty(AbstractButton.PROPERTY_HEIGHT); if (height != null) { ExtentRender.renderToStyle(cssStyle, "height", height); cssStyle.setAttribute("overflow", "hidden"); } if (Boolean.FALSE.equals(button.getRenderProperty(AbstractButton.PROPERTY_LINE_WRAP))) { cssStyle.setAttribute("white-space", "nowrap"); } boolean renderEnabled = button.isRenderEnabled(); Border border; Color foreground, background; Font font = null; FillImage backgroundImage; if (!renderEnabled) { // Retrieve disabled style information. background = (Color) button.getRenderProperty(AbstractButton.PROPERTY_DISABLED_BACKGROUND); backgroundImage = (FillImage) button.getRenderProperty(AbstractButton.PROPERTY_DISABLED_BACKGROUND_IMAGE); border = (Border) button.getRenderProperty(AbstractButton.PROPERTY_DISABLED_BORDER); foreground = (Color) button.getRenderProperty(AbstractButton.PROPERTY_DISABLED_FOREGROUND); // Fallback to normal styles. if (background == null) { background = (Color) button.getRenderProperty(AbstractButton.PROPERTY_BACKGROUND); if (backgroundImage == null) { // Special case: // Disabled background without disabled background image will render disabled background instead of // normal background image. backgroundImage = (FillImage) button.getRenderProperty(AbstractButton.PROPERTY_BACKGROUND_IMAGE); } } if (border == null) { border = (Border) button.getRenderProperty(AbstractButton.PROPERTY_BORDER); } if (foreground == null) { foreground = (Color) button.getRenderProperty(AbstractButton.PROPERTY_FOREGROUND); } if (entityCount == 1) { font = (Font) button.getRenderProperty(AbstractButton.PROPERTY_DISABLED_FONT); if (font == null) { font = (Font) button.getRenderProperty(AbstractButton.PROPERTY_FONT); } } } else { border = (Border) button.getRenderProperty(AbstractButton.PROPERTY_BORDER); foreground = (Color) button.getRenderProperty(AbstractButton.PROPERTY_FOREGROUND); background = (Color) button.getRenderProperty(AbstractButton.PROPERTY_BACKGROUND); backgroundImage = (FillImage) button.getRenderProperty(AbstractButton.PROPERTY_BACKGROUND_IMAGE); if (entityCount == 1) { font = (Font) button.getRenderProperty(AbstractButton.PROPERTY_FONT); } } BorderRender.renderToStyle(cssStyle, border); ColorRender.renderToStyle(cssStyle, foreground, background); FillImageRender.renderToStyle(cssStyle, rc, this, button, IMAGE_ID_BACKGROUND, backgroundImage, FillImageRender.FLAG_DISABLE_FIXED_MODE); if (entityCount == 1) { FontRender.renderToStyle(cssStyle, font); } InsetsRender.renderToStyle(cssStyle, "padding", (Insets) button.getRenderProperty(AbstractButton.PROPERTY_INSETS)); AlignmentRender.renderToStyle(cssStyle, (Alignment) button.getRenderProperty(AbstractButton.PROPERTY_ALIGNMENT), button); return cssStyle; } /** * @see nextapp.echo2.webcontainer.ComponentSynchronizePeer#renderDispose(nextapp.echo2.webcontainer.RenderContext, * nextapp.echo2.app.update.ServerComponentUpdate, nextapp.echo2.app.Component) */ public void renderDispose(RenderContext rc, ServerComponentUpdate update, Component component) { rc.getServerMessage().addLibrary(BUTTON_SERVICE.getId()); renderDisposeDirective(rc, (AbstractButton) component); } /** * Renders a directive to the outgoing ServerMessage to * dispose the state of a button, performing tasks such as unregistering * event listeners on the client. * * @param rc the relevant RenderContext * @param button the button */ private void renderDisposeDirective(RenderContext rc, AbstractButton button) { ServerMessage serverMessage = rc.getServerMessage(); Element itemizedUpdateElement = serverMessage.getItemizedDirective(ServerMessage.GROUP_ID_PREREMOVE, "EchoButton.MessageProcessor", "dispose", new String[0], new String[0]); Element itemElement = serverMessage.getDocument().createElement("item"); itemElement.setAttribute("eid", ContainerInstance.getElementId(button)); itemizedUpdateElement.appendChild(itemElement); } /** * @see nextapp.echo2.webcontainer.DomUpdateSupport#renderHtml(nextapp.echo2.webcontainer.RenderContext, * nextapp.echo2.app.update.ServerComponentUpdate, org.w3c.dom.Node, nextapp.echo2.app.Component) */ public void renderHtml(RenderContext rc, ServerComponentUpdate update, Node parentNode, Component component) { ServerMessage serverMessage = rc.getServerMessage(); serverMessage.addLibrary(BUTTON_SERVICE.getId()); AbstractButton button = (AbstractButton) component; Element containerDivElement = renderButtonContainer(rc, parentNode, button); renderInitDirective(rc, button); renderButtonContent(rc, containerDivElement, button); } /** * Renders a directive to the outgoing ServerMessage to * initialize the state of a button, performing tasks such as registering * event listeners on the client. * * @param rc the relevant RenderContext * @param button the button */ private void renderInitDirective(RenderContext rc, AbstractButton button) { String elementId = ContainerInstance.getElementId(button); ServerMessage serverMessage = rc.getServerMessage(); FillImage backgroundImage = (FillImage) button.getRenderProperty(AbstractButton.PROPERTY_BACKGROUND_IMAGE); boolean rolloverEnabled = ((Boolean) button.getRenderProperty(AbstractButton.PROPERTY_ROLLOVER_ENABLED, Boolean.FALSE)).booleanValue(); boolean pressedEnabled = ((Boolean) button.getRenderProperty(AbstractButton.PROPERTY_PRESSED_ENABLED, Boolean.FALSE)).booleanValue(); String pressedStyle = ""; String rolloverStyle = ""; String defaultIconUri = null; String rolloverIconUri = null; String pressedIconUri = null; if (rolloverEnabled || pressedEnabled) { boolean hasIcon = button.getRenderProperty(AbstractButton.PROPERTY_ICON) != null; if (hasIcon) { defaultIconUri = ImageTools.getUri(rc, this, button, IMAGE_ID_ICON); } if (rolloverEnabled) { CssStyle rolloverCssStyle = new CssStyle(); BorderRender.renderToStyle(rolloverCssStyle, (Border) button.getRenderProperty(AbstractButton.PROPERTY_ROLLOVER_BORDER)); ColorRender.renderToStyle(rolloverCssStyle, (Color) button.getRenderProperty(AbstractButton.PROPERTY_ROLLOVER_FOREGROUND), (Color) button.getRenderProperty(AbstractButton.PROPERTY_ROLLOVER_BACKGROUND)); FontRender.renderToStyle(rolloverCssStyle, (Font) button.getRenderProperty(AbstractButton.PROPERTY_ROLLOVER_FONT)); if (backgroundImage != null) { FillImageRender.renderToStyle(rolloverCssStyle, rc, this, button, IMAGE_ID_ROLLOVER_BACKGROUND, (FillImage) button.getRenderProperty(AbstractButton.PROPERTY_ROLLOVER_BACKGROUND_IMAGE), FillImageRender.FLAG_DISABLE_FIXED_MODE); } if (rolloverCssStyle.hasAttributes()) { rolloverStyle = rolloverCssStyle.renderInline(); } if (hasIcon) { ImageReference rolloverIcon = (ImageReference) button.getRenderProperty(AbstractButton.PROPERTY_ROLLOVER_ICON); if (rolloverIcon != null) { rolloverIconUri = ImageTools.getUri(rc, this, button, IMAGE_ID_ROLLOVER_ICON); } } } if (pressedEnabled) { CssStyle pressedCssStyle = new CssStyle(); BorderRender.renderToStyle(pressedCssStyle, (Border) button.getRenderProperty(AbstractButton.PROPERTY_PRESSED_BORDER)); ColorRender.renderToStyle(pressedCssStyle, (Color) button.getRenderProperty(AbstractButton.PROPERTY_PRESSED_FOREGROUND), (Color) button.getRenderProperty(AbstractButton.PROPERTY_PRESSED_BACKGROUND)); FontRender.renderToStyle(pressedCssStyle, (Font) button.getRenderProperty(AbstractButton.PROPERTY_PRESSED_FONT)); if (backgroundImage != null) { FillImageRender.renderToStyle(pressedCssStyle, rc, this, button, IMAGE_ID_PRESSED_BACKGROUND, (FillImage) button.getRenderProperty(AbstractButton.PROPERTY_PRESSED_BACKGROUND_IMAGE), FillImageRender.FLAG_DISABLE_FIXED_MODE); } if (pressedCssStyle.hasAttributes()) { pressedStyle = pressedCssStyle.renderInline(); } if (hasIcon) { ImageReference pressedIcon = (ImageReference) button.getRenderProperty(AbstractButton.PROPERTY_PRESSED_ICON); if (pressedIcon != null) { pressedIconUri = ImageTools.getUri(rc, this, button, IMAGE_ID_PRESSED_ICON); } } } } CssStyle defaultCssStyle = renderDefaultStyle(rc, button); String defaultStyle = defaultCssStyle.renderInline(); Element itemizedUpdateElement = serverMessage.getItemizedDirective(ServerMessage.GROUP_ID_POSTUPDATE, "EchoButton.MessageProcessor", "init", BUTTON_INIT_KEYS, new String[]{defaultStyle, rolloverStyle, pressedStyle}); Element itemElement = serverMessage.getDocument().createElement("item"); itemElement.setAttribute("eid", elementId); if (defaultIconUri != null) { itemElement.setAttribute("default-icon", defaultIconUri); } if (rolloverIconUri != null) { itemElement.setAttribute("rollover-icon", rolloverIconUri); } if (pressedIconUri != null) { itemElement.setAttribute("pressed-icon", pressedIconUri); } if (!button.hasActionListeners()) { itemElement.setAttribute("server-notify", "false"); } if (!button.isRenderEnabled()) { itemElement.setAttribute("enabled", "false"); } if (button instanceof ToggleButton) { ToggleButton toggleButton = (ToggleButton) button; itemElement.setAttribute("toggle", "true"); itemElement.setAttribute("selected", toggleButton.isSelected() ? "true" : "false"); itemElement.setAttribute("state-icon", ImageTools.getUri(rc, this, toggleButton, IMAGE_ID_STATE_ICON)); itemElement.setAttribute("selected-state-icon", ImageTools.getUri(rc, this, toggleButton, IMAGE_ID_SELECTED_STATE_ICON)); if (rolloverEnabled && toggleButton.getRenderProperty(ToggleButton.PROPERTY_ROLLOVER_STATE_ICON) != null && toggleButton.getRenderProperty(ToggleButton.PROPERTY_ROLLOVER_SELECTED_STATE_ICON) != null) { itemElement.setAttribute("rollover-state-icon", ImageTools.getUri(rc, this, toggleButton, IMAGE_ID_ROLLOVER_STATE_ICON)); itemElement.setAttribute("rollover-selected-state-icon", ImageTools.getUri(rc, this, toggleButton, IMAGE_ID_ROLLOVER_SELECTED_STATE_ICON)); } if (pressedEnabled && toggleButton.getRenderProperty(ToggleButton.PROPERTY_PRESSED_STATE_ICON) != null && toggleButton.getRenderProperty(ToggleButton.PROPERTY_PRESSED_SELECTED_STATE_ICON) != null) { itemElement.setAttribute("pressed-state-icon", ImageTools.getUri(rc, this, toggleButton, IMAGE_ID_PRESSED_STATE_ICON)); itemElement.setAttribute("pressed-selected-state-icon", ImageTools.getUri(rc, this, toggleButton, IMAGE_ID_PRESSED_SELECTED_STATE_ICON)); } if (button instanceof RadioButton) { ButtonGroup buttonGroup = ((RadioButton) toggleButton).getGroup(); if (buttonGroup != null) { rc.getContainerInstance().getIdTable().register(buttonGroup); itemElement.setAttribute("group", buttonGroup.getRenderId()); } } } itemizedUpdateElement.appendChild(itemElement); } /** * @see nextapp.echo2.webcontainer.ComponentSynchronizePeer#renderUpdate(nextapp.echo2.webcontainer.RenderContext, * nextapp.echo2.app.update.ServerComponentUpdate, java.lang.String) */ public boolean renderUpdate(RenderContext rc, ServerComponentUpdate update, String targetId) { String parentId = ContainerInstance.getElementId(update.getParent()); DomUpdate.renderElementRemove(rc.getServerMessage(), parentId); renderAdd(rc, update, targetId, update.getParent()); return false; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy