View Javadoc
1   /*
2    * Copyright (c) 2011-2024 PrimeFaces Extensions
3    *
4    *  Permission is hereby granted, free of charge, to any person obtaining a copy
5    *  of this software and associated documentation files (the "Software"), to deal
6    *  in the Software without restriction, including without limitation the rights
7    *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    *  copies of the Software, and to permit persons to whom the Software is
9    *  furnished to do so, subject to the following conditions:
10   *
11   *  The above copyright notice and this permission notice shall be included in
12   *  all copies or substantial portions of the Software.
13   *
14   *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20   *  THE SOFTWARE.
21   */
22  package org.primefaces.extensions.component.keynote;
23  
24  import java.io.IOException;
25  import java.util.Collection;
26  import java.util.List;
27  
28  import javax.faces.FacesException;
29  import javax.faces.application.Resource;
30  import javax.faces.component.UIComponent;
31  import javax.faces.context.ExternalContext;
32  import javax.faces.context.FacesContext;
33  import javax.faces.context.ResponseWriter;
34  
35  import org.primefaces.extensions.model.keynote.KeynoteItem;
36  import org.primefaces.extensions.util.Attrs;
37  import org.primefaces.renderkit.CoreRenderer;
38  import org.primefaces.util.WidgetBuilder;
39  
40  public class KeynoteRenderer extends CoreRenderer {
41  
42      public static final String CONTAINER_CLASS = "ui-keynote reveal";
43      public static final String SLIDES_CLASS = "slides";
44  
45      /**
46       * {@inheritDoc}
47       */
48      @Override
49      public void decode(final FacesContext context, final UIComponent component) {
50          decodeBehaviors(context, component);
51      }
52  
53      /**
54       * {@inheritDoc}
55       */
56      @Override
57      public void encodeBegin(final FacesContext context, final UIComponent component) throws IOException {
58          final Keynote keynote = (Keynote) component;
59  
60          if (!"none".equals(keynote.getTheme())) {
61              encodeCSS(context, keynote.getLibrary(), keynote.getTheme());
62          }
63      }
64  
65      /**
66       * {@inheritDoc}
67       */
68      @Override
69      public void encodeEnd(final FacesContext context, final UIComponent component) throws IOException {
70          final Keynote keynote = (Keynote) component;
71  
72          encodeMarkup(context, keynote);
73          encodeScript(context, keynote);
74      }
75  
76      /**
77       * Create the HTML markup for the DOM.
78       */
79      private void encodeMarkup(final FacesContext context, final Keynote keynote) throws IOException {
80          final ResponseWriter writer = context.getResponseWriter();
81          final String clientId = keynote.getClientId(context);
82          final String styleClass = getStyleClassBuilder(context)
83                      .add(CONTAINER_CLASS)
84                      .add(keynote.getStyleClass())
85                      .build();
86  
87          writer.startElement("div", keynote);
88          writer.writeAttribute("id", clientId, null);
89          writer.writeAttribute(Attrs.CLASS, styleClass, "styleClass");
90          if (keynote.getStyle() != null) {
91              writer.writeAttribute(Attrs.STYLE, keynote.getStyle(), Attrs.STYLE);
92          }
93  
94          writer.startElement("div", null);
95          writer.writeAttribute(Attrs.CLASS, SLIDES_CLASS, "class");
96  
97          if (keynote.getVar() != null) {
98              // dynamic items
99              final Object value = keynote.getValue();
100             if (value != null) {
101                 if (!(value instanceof Collection)) {
102                     throw new FacesException("Value in Keynote must be of type Collection / List");
103                 }
104 
105                 final List<UIComponent> children = keynote.getChildren();
106                 for (int i = 0; i < children.size(); i++) {
107                     final UIComponent kid = children.get(i);
108                     if (kid.isRendered() && !(kid instanceof UIKeynoteItem)) {
109                         // first render children like stamped elements, etc.
110                         renderChild(context, kid);
111                     }
112                 }
113 
114                 final Collection<KeynoteItem> col = (Collection) value;
115                 for (int i = 0; i < col.size(); i++) {
116                     final KeynoteItem keynoteItem = (KeynoteItem) col.toArray()[i];
117                     // find ui item by type
118                     final UIKeynoteItem uiItem = keynote.getItem(keynoteItem.getType());
119 
120                     if (uiItem.isRendered()) {
121                         // set data in request scope
122                         keynote.setData(keynoteItem);
123 
124                         // render item
125                         renderChild(context, uiItem);
126                     }
127                 }
128             }
129         }
130         else {
131             // static items
132             final List<UIComponent> children = keynote.getChildren();
133             for (int i = 0; i < children.size(); i++) {
134                 final UIComponent kid = children.get(i);
135                 if (kid.isRendered()) {
136                     renderChild(context, kid);
137                 }
138             }
139         }
140 
141         writer.endElement("div");
142 
143         writer.endElement("div");
144     }
145 
146     /**
147      * Create the Javascript.
148      */
149     private void encodeScript(final FacesContext context, final Keynote keynote) throws IOException {
150         final WidgetBuilder wb = getWidgetBuilder(context);
151 
152         wb.init("ExtKeynote", keynote)
153                     .attr("width", keynote.getWidth(), 960)
154                     .attr("height", keynote.getHeight(), 700)
155                     .attr("margin", keynote.getMargin(), 0.04)
156                     .attr("minScale", keynote.getMinScale(), 0.2)
157                     .attr("maxScale", keynote.getMaxScale(), 2.0)
158                     .attr("autoSlide", keynote.getAutoSlide(), 0)
159                     .attr("center", keynote.isCenter(), true)
160                     .attr("controls", keynote.isControls(), true)
161                     .attr("disableLayout", keynote.isDisableLayout(), false)
162                     .attr("embedded", keynote.isEmbedded(), false)
163                     .attr("loop", keynote.isLoop(), false)
164                     .attr("navigationMode", keynote.getNavigationMode(), "default")
165                     .attr("progress", keynote.isProgress(), true)
166                     .attr("showNotes", keynote.isShowNotes(), false)
167                     .attr("slideNumber", keynote.getSlideNumber(), "false")
168                     .attr("touch", keynote.isTouch(), true)
169                     .attr("transition", keynote.getTransition(), "slide")
170                     .attr("transitionSpeed", keynote.getTransitionSpeed(), "default")
171                     .attr("backgroundTransition", keynote.getBackgroundTransition(), "fade")
172                     .attr("theme", keynote.getTheme(), "none");
173 
174         encodeClientBehaviors(context, keynote);
175 
176         wb.finish();
177     }
178 
179     private void encodeCSS(final FacesContext context, final String library, final String theme) throws IOException {
180         final ResponseWriter writer = context.getResponseWriter();
181         final ExternalContext externalContext = context.getExternalContext();
182 
183         final Resource cssResource = context.getApplication()
184                     .getResourceHandler()
185                     .createResource("keynote/theme/" + theme + ".css", library);
186         if (cssResource == null) {
187             throw new FacesException(
188                         "Error loading CSS, cannot find \"" + theme + "\" resource of \"" + library + "\" library");
189         }
190         else {
191             writer.startElement("link", null);
192             writer.writeAttribute("type", "text/css", null);
193             writer.writeAttribute("rel", "stylesheet", null);
194             writer.writeAttribute("href", externalContext.encodeResourceURL(cssResource.getRequestPath()), null);
195             writer.endElement("link");
196         }
197     }
198 
199     /**
200      * {@inheritDoc}
201      */
202     @Override
203     public void encodeChildren(final FacesContext context, final UIComponent component) {
204         // Do nothing
205     }
206 
207     /**
208      * {@inheritDoc}
209      */
210     @Override
211     public boolean getRendersChildren() {
212         return true;
213     }
214 
215 }