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