Hi,
I've written up a patch which will enable the use of server generated
buttons in tr:commandButtons. It follows the documentation in that you
must supply AFButtonStartIcon:alias, AFButtonEndIcon:alias,
AFButtonTopBackgroundIcon:alias and AFButtonBottomBackgroundIcon:alias
in the skin definition file. If it can't find these definitions, it
reverts to normal client-side buttons.
Mark
Index:
trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/CommandButtonRenderer.java
===================================================================
---
trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/CommandButtonRenderer.java
(revision 482383)
+++
trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/CommandButtonRenderer.java
(working copy)
@@ -15,19 +15,53 @@
*/
package org.apache.myfaces.trinidadinternal.renderkit.core.xhtml;
+import java.awt.Color;
+import java.awt.Font;
+
+import java.io.File;
import java.io.IOException;
+import java.io.InputStream;
+
+import java.net.URI;
+import java.net.URL;
+
+import java.util.Collection;
import java.util.Collections;
+import java.util.Iterator;
import java.util.List;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
+import javax.faces.context.ExternalContext;
import javax.faces.context.ResponseWriter;
+import org.apache.myfaces.trinidadinternal.share.io.FileInputStreamProvider;
import org.apache.myfaces.trinidad.bean.FacesBean;
import org.apache.myfaces.trinidad.bean.PropertyKey;
import org.apache.myfaces.trinidad.component.core.nav.CoreCommandButton;
+import org.apache.myfaces.trinidad.context.LocaleContext;
import org.apache.myfaces.trinidad.context.RenderingContext;
+import org.apache.myfaces.trinidad.skin.Icon;
+import org.apache.myfaces.trinidad.skin.Skin;
+import org.apache.myfaces.trinidadinternal.agent.TrinidadAgent;
+import org.apache.myfaces.trinidadinternal.context.ExternalContextDecorator;
+import org.apache.myfaces.trinidadinternal.image.ImageConstants;
+import org.apache.myfaces.trinidadinternal.image.ImageProvider;
+import org.apache.myfaces.trinidadinternal.image.ImageProviderResponse;
+import org.apache.myfaces.trinidadinternal.image.cache.CompositeButtonKey;
+import org.apache.myfaces.trinidadinternal.share.config.Configuration;
+import org.apache.myfaces.trinidadinternal.share.io.InputStreamProvider;
+import org.apache.myfaces.trinidadinternal.share.io.NameResolver;
+import org.apache.myfaces.trinidadinternal.share.io.URLInputStreamProvider;
+import org.apache.myfaces.trinidadinternal.skin.StyleSheetNameResolver;
+import org.apache.myfaces.trinidadinternal.style.Style;
+import org.apache.myfaces.trinidadinternal.style.StyleMap;
+import org.apache.myfaces.trinidadinternal.style.util.FontProxy;
+import org.apache.myfaces.trinidadinternal.ui.UIXRenderingContext;
+import
org.apache.myfaces.trinidadinternal.ui.laf.simple.desktop.IconInputStreamProvider;
+import
org.apache.myfaces.trinidadinternal.ui.laf.simple.desktop.SimpleDesktopConstants;
+import org.apache.myfaces.trinidadinternal.uinode.FacesRenderingContext;
public class CommandButtonRenderer extends CommandLinkRenderer
{
@@ -54,7 +88,214 @@
{
return true;
}
+
+ private static boolean _isRightToLeft(UIXRenderingContext context)
+ {
+ LocaleContext lContext = context.getLocaleContext();
+ return lContext.isRightToLeft();
+ }
+
+ // Key for Boolean Skin property which we use
+ // to track whether buttons should be rendered as images.
+ private static Object _IMAGE_BUTTON_KEY = new Object();
+ private static Object _IMAGE_BUTTON_RTL_KEY = new Object();
+
+ // Tests whether button should be rendered as an image.
+ // SLAF buttons are rendered using images if all three
+ // button icons (start, end, background) specified.
+ // Otherwise the button is rendered using the base.desktop
+ // button implementation (browser buttons).
+ static public boolean doRenderImageButton(
+ UIXRenderingContext context
+ )
+ {
+ // First, check the _IMAGE_BUTTON_KEY (or _IMAGE_BUTTON_RTL_KEY if rtl)
+ // property on the Skin.
+ // This will be Boolean.TRUE if
+ // we have all three icons, Boolean.FALSE if we
+ // don't, or null if we haven't checked yet.
+ boolean rtl = _isRightToLeft(context);
+ Boolean value;
+ Skin skin = context.getSkin();
+ if (rtl)
+ value = (Boolean)skin.getProperty(_IMAGE_BUTTON_RTL_KEY);
+ else
+ value = (Boolean)skin.getProperty(_IMAGE_BUTTON_KEY);
+
+ if (value != null)
+ return (Boolean.TRUE == value);
+
+ // we fetch different icons if we are in the
+ // right-to-left reading direction. context.getIcon takes care of
+ // this, by adding the :rtl suffix to the icon name if the
+ // reading direction is rtl.
+ Icon startIcon = context.getIcon(
+
SimpleDesktopConstants.BUTTON_START_ICON_NAME);
+ Icon endIcon = context.getIcon(
+
SimpleDesktopConstants.BUTTON_END_ICON_NAME);
+ Icon topBackgroundIcon = context.getIcon(
+
SimpleDesktopConstants.BUTTON_TOP_BACKGROUND_ICON_NAME);
+ Icon bottomBackgroundIcon = context.getIcon(
+
SimpleDesktopConstants.BUTTON_BOTTOM_BACKGROUND_ICON_NAME);
+
+ // If we are missing any of the icons, we don't render
+ // the button image.
+ if (startIcon == null || endIcon == null || topBackgroundIcon == null ||
bottomBackgroundIcon == null)
+ {
+
+ if (rtl)
+ skin.setProperty(_IMAGE_BUTTON_RTL_KEY, Boolean.FALSE);
+ else
+ skin.setProperty(_IMAGE_BUTTON_KEY, Boolean.FALSE);
+
+ return false;
+ }
+ if (rtl)
+ skin.setProperty(_IMAGE_BUTTON_RTL_KEY, Boolean.TRUE);
+ else
+ skin.setProperty(_IMAGE_BUTTON_KEY, Boolean.TRUE);
+
+ return true;
+ }
+
+ protected Integer getFontSize(Style serverButtonStyle) {
+ Integer serverFontSize =
(Integer)serverButtonStyle.getParsedProperty(Style.FONT_SIZE_KEY);
+ if(serverFontSize == null) {
+ serverFontSize = new Integer(12);
+ }
+
+ return serverFontSize;
+ }
+
+ protected Integer getFontStyle(Style serverButtonStyle) {
+ Integer serverFontStyle =
(Integer)serverButtonStyle.getParsedProperty(Style.FONT_STYLE_KEY);
+ if(serverFontStyle == null) {
+ serverFontStyle = new Integer(0);
+ }
+
+ return serverFontStyle;
+ }
+
+ protected ImageProviderResponse getButtonImage(FacesContext context,
UIComponent component, FacesBean bean) {
+
+ ImageProviderResponse response = null;
+ try {
+ UIXRenderingContext facesRender =
FacesRenderingContext.getRenderingContext(context, component);
+ ImageProvider imageProvider =
(ImageProvider)facesRender.getProperty(ImageConstants.TECATE_NAMESPACE,
ImageConstants.IMAGE_PROVIDER_PROPERTY);
+
+ ExternalContext externalContext = context.getExternalContext();
+ String contextPath = externalContext.getRequestContextPath();
+
+ Icon startIcon = facesRender.getIcon(
+
SimpleDesktopConstants.BUTTON_START_ICON_NAME);
+ Icon endIcon = facesRender.getIcon(
+
SimpleDesktopConstants.BUTTON_END_ICON_NAME);
+ Icon topBackgroundIcon = facesRender.getIcon(
+
SimpleDesktopConstants.BUTTON_TOP_BACKGROUND_ICON_NAME);
+ Icon bottomBackgroundIcon = facesRender.getIcon(
+
SimpleDesktopConstants.BUTTON_BOTTOM_BACKGROUND_ICON_NAME);
+
+ Icon startDisabledIcon = facesRender.getIcon(
+
SimpleDesktopConstants.BUTTON_DISABLED_START_ICON_NAME);
+ Icon endDisabledIcon = facesRender.getIcon(
+
SimpleDesktopConstants.BUTTON_DISABLED_END_ICON_NAME);
+ Icon topDisabledBackgroundIcon = facesRender.getIcon(
+
SimpleDesktopConstants.BUTTON_DISABLED_TOP_BACKGROUND_ICON_NAME);
+ Icon bottomDisabledBackgroundIcon = facesRender.getIcon(
+
SimpleDesktopConstants.BUTTON_DISABLED_BOTTOM_BACKGROUND_ICON_NAME);
+
+ NameResolver nameResolver =
StyleSheetNameResolver.createResolver(facesRender.getStyleContext());
+
+ InputStreamProvider startIsp;
+ InputStreamProvider endIsp;
+ InputStreamProvider borderBottonIsp;
+ InputStreamProvider borderTopIsp;
+
+
+ // Load up the icons used to generate the image
+ if (getDisabled(bean)) {
+ startIsp =
nameResolver.getProvider(((String)startDisabledIcon.getImageURI(context,RenderingContext.getCurrentInstance())).replaceAll(contextPath,
""));
+ endIsp =
nameResolver.getProvider(((String)endDisabledIcon.getImageURI(context,RenderingContext.getCurrentInstance())).replaceAll(contextPath,
""));
+ borderBottonIsp =
nameResolver.getProvider(((String)topDisabledBackgroundIcon.getImageURI(context,RenderingContext.getCurrentInstance())).replaceAll(contextPath,
""));
+ borderTopIsp =
nameResolver.getProvider(((String)bottomDisabledBackgroundIcon.getImageURI(context,RenderingContext.getCurrentInstance())).replaceAll(contextPath,
""));
+ } else {
+ startIsp =
nameResolver.getProvider(((String)startIcon.getImageURI(context,RenderingContext.getCurrentInstance())).replaceAll(contextPath,
""));
+ endIsp =
nameResolver.getProvider(((String)endIcon.getImageURI(context,RenderingContext.getCurrentInstance())).replaceAll(contextPath,
""));
+ borderBottonIsp =
nameResolver.getProvider(((String)topBackgroundIcon.getImageURI(context,RenderingContext.getCurrentInstance())).replaceAll(contextPath,
""));
+ borderTopIsp =
nameResolver.getProvider(((String)bottomBackgroundIcon.getImageURI(context,RenderingContext.getCurrentInstance())).replaceAll(contextPath,
""));
+ }
+
+ StyleMap styleMap = facesRender.getStyleContext().getStyleMap();
+ Style serverButtonStyle = null;
+
+ if (getDisabled(bean)) {
+ serverButtonStyle =
styleMap.getStyleByName(facesRender.getStyleContext(),"AFButtonServerTextDisabled");
+ } else {
+ serverButtonStyle =
styleMap.getStyleByName(facesRender.getStyleContext(),"AFButtonServerText");
+ }
+
+ Integer serverFontSize = getFontSize(serverButtonStyle);
+ Integer serverFontStyle = getFontStyle(serverButtonStyle);
+
+ Collection serverFont =
(Collection)serverButtonStyle.getParsedProperty(Style.FONT_FAMILIES_KEY);
+ String fontName = null;
+ Font fontImpl = null;
+ if(serverFont == null){
+ fontName = "Dialog";
+ fontImpl = new Font(fontName, serverFontStyle, serverFontSize);
+ } else {
+ Iterator<String> fonts = serverFont.iterator();
+ while(fonts.hasNext()) {
+ fontName = fonts.next();
+ fontImpl = new Font(fontName, serverFontStyle,
serverFontSize);
+ if(fontImpl != null)
+ break;
+ }
+ }
+ FontProxy myFontProxy = new FontProxy(fontImpl);
+
+ String text = getText(bean);
+
+ char accessKey;
+ if (supportsAccessKeys(RenderingContext.getCurrentInstance()))
+ {
+ accessKey = getAccessKey(bean);
+ }
+ else
+ {
+ accessKey = CHAR_UNDEFINED;
+ }
+
+ Color textColor =
(Color)serverButtonStyle.getParsedProperty(Style.FOREGROUND_KEY);
+ Color bgColor =
(Color)serverButtonStyle.getParsedProperty(Style.BACKGROUND_KEY);
+
+ if(textColor == null) {
+ textColor = Color.black;
+ }
+
+ if(bgColor == null) {
+ bgColor = Color.WHITE;
+ }
+
+ Boolean useAntiAlias =
(Boolean)serverButtonStyle.getParsedProperty(Style.TEXT_ANTIALIAS_KEY);
+ if(useAntiAlias == null) {
+ useAntiAlias = new Boolean(true);
+ }
+
+ CompositeButtonKey button = new
CompositeButtonKey(facesRender.getImageContext(),
facesRender.getLookAndFeel().getId(), text, text, textColor, bgColor, new
Color(0,0,0,0), myFontProxy, getDisabled(bean), useAntiAlias, accessKey,
+ startIsp,
+ endIsp,
+ borderBottonIsp,
+ borderTopIsp);
+
+ response = imageProvider.getImage(facesRender.getImageContext(),
button);
+ } catch(Exception e) {
+ e.printStackTrace();
+ }
+ return response;
+ }
+
@Override
protected void encodeAll(
FacesContext context,
@@ -71,74 +312,118 @@
// Make sure we don't have anything to save
assert(arc.getCurrentClientId() == null);
arc.setCurrentClientId(clientId);
-
- boolean useButtonTag = useButtonTags(arc);
- String element = useButtonTag ? "button" : "input";
- ResponseWriter rw = context.getResponseWriter();
- rw.startElement(element, component);
- renderId(context, component);
+
+ if(doRenderImageButton(FacesRenderingContext.getRenderingContext(context,
component))) {
+ ////////////
+ ResponseWriter rw = context.getResponseWriter();
+ rw.startElement("a", component);
- // Write the text and access key
- String text = getText(bean);
- String icon = getIcon(bean);
+ if (getDisabled(bean) || !supportsNavigation(arc))
+ {
+ renderId(context, component);
+ renderStyleAttributes(context, arc, bean);
+ }
+ else
+ {
+ renderId(context, component);
+ renderAllAttributes(context, arc, bean);
- if (useButtonTag)
- rw.writeAttribute("type", getButtonType(), null);
- else if (icon != null)
- rw.writeAttribute("type", "image", null);
- else
- rw.writeAttribute("type", getInputType(), null);
+ // If we have an onclick handler, always provide a destination
+ String destination = getDestination(bean);
+ if ((destination == null) && hasOnclick(bean))
+ {
+ destination = "#";
+ }
- if (getDisabled(bean))
- {
- rw.writeAttribute("disabled", Boolean.TRUE, "disabled");
- // Skip over event attributes when disabled
- renderStyleAttributes(context, arc, bean);
- }
- else
- {
- renderAllAttributes(context, arc, bean);
- }
+ renderEncodedActionURI(context, "href", destination);
- char accessKey;
- if (supportsAccessKeys(arc))
- {
- accessKey = getAccessKey(bean);
- if (accessKey != CHAR_UNDEFINED)
- {
- rw.writeAttribute("accesskey",
- new Character(accessKey),
- "accessKey");
- }
+ if (!Boolean.FALSE.equals(
+
arc.getAgent().getCapabilities().get(TrinidadAgent.CAP_TARGET)))
+ {
+ rw.writeAttribute("target", getTargetFrame(bean), null);
+ }
+ }
+ ////
+ ImageProviderResponse buttonImage = getButtonImage(context, component,
bean);
+ String buttonImageURI = buttonImage.getImageURI();
+ // ResponseWriter rw = context.getResponseWriter();
+ rw.startElement("img", component);
+ String baseURL = "/mvcore-mvbuilder-context-root/adf/images/cache/";
+ rw.writeAttribute("src", baseURL+buttonImageURI, null);
+ rw.endElement("img");
+
+ rw.endElement("a");
+
+ // super.encodeEnd(context, arc, component, bean);
+ } else {
+ boolean useButtonTag = useButtonTags(arc);
+ String element = useButtonTag ? "button" : "input";
+ ResponseWriter rw = context.getResponseWriter();
+ rw.startElement(element, component);
+ renderId(context, component);
+
+ // Write the text and access key
+ String text = getText(bean);
+ String icon = getIcon(bean);
+
+ if (useButtonTag)
+ rw.writeAttribute("type", getButtonType(), null);
+ else if (icon != null)
+ rw.writeAttribute("type", "image", null);
+ else
+ rw.writeAttribute("type", getInputType(), null);
+
+ if (getDisabled(bean))
+ {
+ rw.writeAttribute("disabled", Boolean.TRUE, "disabled");
+ // Skip over event attributes when disabled
+ renderStyleAttributes(context, arc, bean);
+ }
+ else
+ {
+ renderAllAttributes(context, arc, bean);
+ }
+
+ char accessKey;
+ if (supportsAccessKeys(arc))
+ {
+ accessKey = getAccessKey(bean);
+ if (accessKey != CHAR_UNDEFINED)
+ {
+ rw.writeAttribute("accesskey",
+ new Character(accessKey),
+ "accessKey");
+ }
+ }
+ else
+ {
+ accessKey = CHAR_UNDEFINED;
+ }
+
+ if (useButtonTag)
+ {
+ AccessKeyUtils.renderAccessKeyText(context,
+ text,
+ accessKey,
+
SkinSelectors.AF_ACCESSKEY_STYLE_CLASS);
+ if (icon != null)
+ OutputUtils.renderImage(context, arc, icon, null, null, null,
+ getShortDesc(bean));
+ }
+ else
+ {
+ if (icon != null)
+ {
+ renderEncodedResourceURI(context, "src", icon);
+ }
+ else
+ {
+ rw.writeAttribute("value", text, "text");
+ }
+ }
+
+ rw.endElement(element);
}
- else
- {
- accessKey = CHAR_UNDEFINED;
- }
-
- if (useButtonTag)
- {
- AccessKeyUtils.renderAccessKeyText(context,
- text,
- accessKey,
-
SkinSelectors.AF_ACCESSKEY_STYLE_CLASS);
- if (icon != null)
- OutputUtils.renderImage(context, arc, icon, null, null, null,
- getShortDesc(bean));
- }
- else
- {
- if (icon != null)
- {
- renderEncodedResourceURI(context, "src", icon);
- }
- else
- {
- rw.writeAttribute("value", text, "text");
- }
- }
-
- rw.endElement(element);
}
protected String getButtonType()
Index:
trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/StyleSheetNameResolver.java
===================================================================
---
trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/StyleSheetNameResolver.java
(revision 482383)
+++
trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/StyleSheetNameResolver.java
(working copy)
@@ -47,7 +47,7 @@
* @version $Name: $ ($Revision:
adfrt/faces/adf-faces-impl/src/main/java/oracle/adfinternal/view/faces/skin/StyleSheetNameResolver.java#0
$) $Date: 10-nov-2005.18:59:02 $
* @author The Oracle ADF Faces Team
*/
-class StyleSheetNameResolver implements NameResolver
+public class StyleSheetNameResolver implements NameResolver
{
/**
* Creates a NameResolver which can locate style sheets