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    @Override
45    public void prepareRender(FacesContext facesContext, UIComponent component) throws IOException {
46      super.prepareRender(facesContext, component);
47      HtmlRendererUtils.renderDojoDndSource(facesContext, component);
48    }
49  
50    /*
51    
52  with shadow
53    
54  <div class="tobago-box" style="width: 100px; height: 100px">
55    <div class="tobago-box-shadow" style="width: 99px; height: 99px">
56      <div class="tobago-box-border" style="width: 97px; height: 97px">
57        <div class="tobago-box-header">Label</div>
58      </div>
59    </div>
60  
61    <div style="position: absolute; top: 26px; left: 6px; width: 87px; height: 67px; background-color: blue;">
62      Content
63    </div>
64  </div>
65  
66  without shadow
67  
68  <div class="tobago-box" style="width: 100px; height: 100px">
69    <span class="tobago-box-header">Label</span>
70  
71    <div style="position: absolute; top: 26px; left: 6px; width: 87px; height: 67px; background-color: blue;">
72      Content
73    </div>
74  </div>
75  
76     */
77    @Override
78    public void encodeBegin(FacesContext facesContext, UIComponent component) throws IOException {
79  
80      TobagoResponseWriter writer = HtmlRendererUtils.getTobagoResponseWriter(facesContext);
81      UIBox box = (UIBox) component;
82  
83      String clientId = box.getClientId(facesContext);
84      writer.startElement(HtmlElements.DIV, box);
85      HtmlRendererUtils.renderDojoDndItem(box, writer, true);
86      writer.writeClassAttribute(Classes.create(box));
87      writer.writeIdAttribute(clientId);
88      String title = HtmlRendererUtils.getTitleFromTipAndMessages(facesContext, box);
89      if (title != null) {
90        writer.writeAttribute(HtmlAttributes.TITLE, title, true);
91      }
92      HtmlRendererUtils.writeDataAttributes(facesContext, writer, box);
93      writer.writeStyleAttribute(new Style(facesContext, box));
94      encodeBox(facesContext, writer, box);
95    }
96  
97    private void encodeBox(FacesContext facesContext, TobagoResponseWriter writer, UIBox box) throws IOException {
98  
99      // todo: shadow = 0px means, that shadow is disabled, but it may be better, if we can set a boolean in the config.
100     // todo: this is possible after fixing 
101     Measure measure = getResourceManager().getThemeMeasure(facesContext, box, "shadow");
102     boolean hasShadow = measure.greaterThan(Measure.ZERO);
103 
104     if (hasShadow) {
105       // shadow begin
106       writer.startElement(HtmlElements.DIV, box);
107       writer.writeClassAttribute(Classes.create(box, "shadow"));
108 
109       Style shadow = new Style();
110       shadow.setWidth(box.getCurrentWidth().subtract(1));
111       shadow.setHeight(box.getCurrentHeight().subtract(1));
112       writer.writeStyleAttribute(shadow);
113 
114       // border begin
115       writer.startElement(HtmlElements.DIV, box);
116       writer.writeClassAttribute(Classes.create(box, "border"));
117 
118       Style border = new Style();
119       border.setWidth(box.getCurrentWidth().subtract(3));
120       border.setHeight(box.getCurrentHeight().subtract(3));
121       writer.writeStyleAttribute(border);
122     }
123 
124     UIComponent label = box.getFacet(Facets.LABEL);
125     writer.startElement(HtmlElements.DIV, null);
126     writer.writeClassAttribute(Classes.create(box, "header"));
127     String labelString = (String) box.getAttributes().get(Attributes.LABEL);
128     if (label != null) {
129       RenderUtils.encode(facesContext, label);
130     } else if (labelString != null) {
131       writer.writeText(labelString);
132     }
133     writer.endElement(HtmlElements.DIV);
134 
135     final UIMenuBar menuBar = getMenuBarFacet(box);
136     if (menuBar != null) {
137       RenderUtils.encode(facesContext, menuBar);
138     }
139 
140     UIPanel toolbar = (UIPanel) box.getFacet(Facets.TOOL_BAR);
141     if (toolbar != null) {
142       renderToolbar(facesContext, writer, box, toolbar);
143     }
144     
145     if (hasShadow) {
146       // border end
147       writer.endElement(HtmlElements.DIV);
148       // shadow end
149       writer.endElement(HtmlElements.DIV);
150     }
151 
152     writer.startElement(HtmlElements.DIV, null);
153     writer.writeClassAttribute(Classes.create(box, "content")); // needed to be scrollable inside of the box
154     final Style style = new Style(facesContext, box);
155     final Measure borderLeft = box.getBorderLeft();
156     final Measure borderRight = box.getBorderRight();
157     final Measure borderTop = box.getBorderTop();
158     final Measure borderBottom = box.getBorderBottom();
159     style.setWidth(style.getWidth().subtract(borderLeft).subtract(borderRight));
160     style.setHeight(style.getHeight().subtract(borderTop).subtract(borderBottom));
161     style.setLeft(borderLeft);
162     style.setTop(borderTop);
163     writer.writeStyleAttribute(style);
164   }
165 
166   @Override
167   public void encodeEnd(FacesContext facesContext, UIComponent component) throws IOException {
168     TobagoResponseWriter writer = HtmlRendererUtils.getTobagoResponseWriter(facesContext);
169     writer.endElement(HtmlElements.DIV);
170     writer.endElement(HtmlElements.DIV);
171   }
172 
173   protected void renderToolbar(
174       FacesContext facesContext, TobagoResponseWriter writer, UIBox box, UIPanel toolbar) throws IOException {
175     writer.startElement(HtmlElements.DIV, null);
176     writer.writeClassAttribute(Classes.create(box, "headerToolBar"));
177     toolbar.setRendererType(RendererTypes.BOX_TOOL_BAR);
178     RenderUtils.encode(facesContext, toolbar);
179     writer.endElement(HtmlElements.DIV);
180   }
181 }