View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  
20  package org.apache.myfaces.tobago.renderkit.html.speyside.standard.tag;
21  
22  import org.apache.myfaces.tobago.component.Attributes;
23  import org.apache.myfaces.tobago.component.Facets;
24  import org.apache.myfaces.tobago.component.RendererTypes;
25  import org.apache.myfaces.tobago.component.UIBox;
26  import org.apache.myfaces.tobago.component.UIMenuBar;
27  import org.apache.myfaces.tobago.layout.Measure;
28  import org.apache.myfaces.tobago.renderkit.BoxRendererBase;
29  import org.apache.myfaces.tobago.renderkit.css.Classes;
30  import org.apache.myfaces.tobago.renderkit.css.Style;
31  import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
32  import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
33  import org.apache.myfaces.tobago.renderkit.html.util.HtmlRendererUtils;
34  import org.apache.myfaces.tobago.renderkit.util.RenderUtils;
35  import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
36  
37  import javax.faces.component.UIComponent;
38  import javax.faces.component.UIPanel;
39  import javax.faces.context.FacesContext;
40  import java.io.IOException;
41  
42  public class BoxRenderer extends BoxRendererBase {
43  
44    /*
45    
46  with shadow
47    
48  <div class="tobago-box" style="width: 100px; height: 100px">
49    <div class="tobago-box-shadow" style="width: 99px; height: 99px">
50      <div class="tobago-box-border" style="width: 97px; height: 97px">
51        <div class="tobago-box-header">Label</div>
52      </div>
53    </div>
54  
55    <div style="position: absolute; top: 26px; left: 6px; width: 87px; height: 67px; background-color: blue;">
56      Content
57    </div>
58  </div>
59  
60  without shadow
61  
62  <div class="tobago-box" style="width: 100px; height: 100px">
63    <span class="tobago-box-header">Label</span>
64  
65    <div style="position: absolute; top: 26px; left: 6px; width: 87px; height: 67px; background-color: blue;">
66      Content
67    </div>
68  </div>
69  
70     */
71    @Override
72    public void encodeBegin(final FacesContext facesContext, final UIComponent component) throws IOException {
73  
74      final TobagoResponseWriter writer = HtmlRendererUtils.getTobagoResponseWriter(facesContext);
75      final UIBox box = (UIBox) component;
76  
77      final String clientId = box.getClientId(facesContext);
78      writer.startElement(HtmlElements.DIV, box);
79      writer.writeClassAttribute(Classes.create(box));
80      writer.writeIdAttribute(clientId);
81      final String title = HtmlRendererUtils.getTitleFromTipAndMessages(facesContext, box);
82      if (title != null) {
83        writer.writeAttribute(HtmlAttributes.TITLE, title, true);
84      }
85      HtmlRendererUtils.writeDataAttributes(facesContext, writer, box);
86      writer.writeStyleAttribute(new Style(facesContext, box));
87      encodeBox(facesContext, writer, box);
88    }
89  
90    private void encodeBox(final FacesContext facesContext, final TobagoResponseWriter writer, final UIBox box)
91        throws IOException {
92  
93      // todo: shadow = 0px means, that shadow is disabled, but it may be better, if we can set a boolean in the config.
94      // todo: this is possible after fixing 
95      final Measure measure = getResourceManager().getThemeMeasure(facesContext, box, "shadow");
96      final boolean hasShadow = measure.greaterThan(Measure.ZERO);
97  
98      if (hasShadow) {
99        // shadow begin
100       writer.startElement(HtmlElements.DIV, box);
101       writer.writeClassAttribute(Classes.create(box, "shadow"));
102 
103       final Style shadow = new Style();
104       shadow.setWidth(box.getCurrentWidth().subtract(1));
105       shadow.setHeight(box.getCurrentHeight().subtract(1));
106       writer.writeStyleAttribute(shadow);
107 
108       // border begin
109       writer.startElement(HtmlElements.DIV, box);
110       writer.writeClassAttribute(Classes.create(box, "border"));
111 
112       final Style border = new Style();
113       border.setWidth(box.getCurrentWidth().subtract(3));
114       border.setHeight(box.getCurrentHeight().subtract(3));
115       writer.writeStyleAttribute(border);
116     }
117 
118     final UIComponent label = box.getFacet(Facets.LABEL);
119     writer.startElement(HtmlElements.DIV, null);
120     writer.writeClassAttribute(Classes.create(box, "header"));
121     final String labelString = (String) box.getAttributes().get(Attributes.LABEL);
122     if (label != null) {
123       RenderUtils.encode(facesContext, label);
124     } else if (labelString != null) {
125       writer.writeText(labelString);
126     }
127     writer.endElement(HtmlElements.DIV);
128 
129     final UIMenuBar menuBar = getMenuBarFacet(box);
130     if (menuBar != null) {
131       RenderUtils.encode(facesContext, menuBar);
132     }
133 
134     final UIPanel toolbar = (UIPanel) box.getFacet(Facets.TOOL_BAR);
135     if (toolbar != null) {
136       renderToolbar(facesContext, writer, box, toolbar);
137     }
138     
139     if (hasShadow) {
140       // border end
141       writer.endElement(HtmlElements.DIV);
142       // shadow end
143       writer.endElement(HtmlElements.DIV);
144     }
145 
146     writer.startElement(HtmlElements.DIV, null);
147     writer.writeClassAttribute(Classes.create(box, "content")); // needed to be scrollable inside of the box
148     final Style style = new Style(facesContext, box);
149     final Measure borderLeft = box.getBorderLeft();
150     final Measure borderRight = box.getBorderRight();
151     final Measure borderTop = box.getBorderTop();
152     final Measure borderBottom = box.getBorderBottom();
153     style.setWidth(style.getWidth().subtract(borderLeft).subtract(borderRight));
154     style.setHeight(style.getHeight().subtract(borderTop).subtract(borderBottom));
155     style.setLeft(borderLeft);
156     style.setTop(borderTop);
157     writer.writeStyleAttribute(style);
158   }
159 
160   @Override
161   public void encodeEnd(final FacesContext facesContext, final UIComponent component) throws IOException {
162     final TobagoResponseWriter writer = HtmlRendererUtils.getTobagoResponseWriter(facesContext);
163     writer.endElement(HtmlElements.DIV);
164     writer.endElement(HtmlElements.DIV);
165   }
166 
167   protected void renderToolbar(
168       final FacesContext facesContext, final TobagoResponseWriter writer, final UIBox box, final UIPanel toolbar)
169       throws IOException {
170     writer.startElement(HtmlElements.DIV, null);
171     writer.writeClassAttribute(Classes.create(box, "headerToolBar"));
172     toolbar.setRendererType(RendererTypes.BOX_TOOL_BAR);
173     RenderUtils.encode(facesContext, toolbar);
174     writer.endElement(HtmlElements.DIV);
175   }
176 }