### Slideshow mechanism.

The slideshow feature in the Photo Album Demo can be enabled by clicking on "Start Slideshow" link from two different places in the application: 1) from user's album preview ( `/web/src/main/webapp/image/albumInfo.xhtml` ) and 2) from a particular photo preview ( `src/main/webapp/image/imageInfo.xhtml` ). Both of two mentioned XHTML files include slideshow with the help of Facelets <ui:include tag (for more information about <ui:include see Facelets Reference Guide " http://www.jsftoolbox.com/documentation/facelets/01-Introduction/index.jsf).

The components that implement the slideshow functionality are:

- <rich:popupPanel> located in `web/src/main/webapp/includes/image/slideshow.xhtml` that is hidden by default as the attribute `show="#{'#{'}slideshow.active}"` and the active property of SlideshowManager.java is set to "false" by default.

- <a4j:poll> located also in `web/src/main/webapp/includes/image/slideshow.xhtml` which is also inactive due to the mentioned active property ( `active="#{'#{'}slideshow.active}"` )

After activation, <a4j:poll> will send asynchronous requests to the server with some certain interval, as the result of these requests modal panel will display the next image in the row.

Now let's have a look at the details of the slideshow implementation.

The `startSlideshow()` method of `SlideshowManager.java` is invoked when no photo is selected in the current image list. The method iterates over all photos of a particular album starting from the selected image or the first one in the list if none was selected. Look at the `SlideshowManager.java` listing below:

            public void startSlideshow() {
                if (!this.active) {
                    initSlideshow();
                }
                if (model.getImages() == null || model.getImages().size() < 1) {
                    onError(true);
                    return;
                }
                if (this.selectedImage == null) {
                    this.selectedImage = model.getImages().get(this.slideshowIndex);
                }

                this.selectedImage.setVisited(true);

                checkIsFileRecentlyDeleted();
            }

            public void startSlideshow(Image selectedImage) {
                initSlideshow();
                this.slideshowIndex = model.getImages().indexOf(selectedImage);
                this.startSlideshowIndex = this.slideshowIndex;
                this.selectedImage = selectedImage;

                startSlideshow();
            }

Both variants of `startSlideshow()` method set the `active` property to "true" as a result the poller is activated and modal panel becomes visible.

The slideshow modal panel is kept in the `web/src/main/webapp/includes/image/slideshow.xhtml` file and referred from the corresponding pages with the help of <ui:include> Facelets tag:

            <ui:include src="/includes/image/slideshow.xhtml" />

Have a look at `web/src/main/webapp/includes/image/slideshow.xhtml` file:

            <ui:composition … >
              <a4j:region>
                <rich:popupPanel show="#{'#{'}slideshow.active}"
                    domElementAttachment="parent"
                    id="slideShowModalPanel"
                    autosized="true"
                    onshow="$(#{'#{'}rich:element('imgSlideShow')}).fadeIn(600);">
                  <f:facet name="header">Slideshow panel</f:facet>
                  <f:facet name="controls">
                    <h:panelGroup>
                      <h:graphicImage value="/resources/img/modal/close.png" style="cursor:pointer" id="hidelink">
                         <a4j:ajax event="click" listener="#{'#{'}slideshow.stopSlideshow()}"
                             render="mainArea, treePanel, slideShowModalPanel" execute="@region" />
                      </h:graphicImage>
                    </h:panelGroup>
                  </f:facet>
                  <h:panelGrid styleClass="slideshow-table" columnClasses="slideshow-table-col" rowClasses="slideshow-table-row">
                    <h:panelGroup id="slideshowImage">
                      <a4j:mediaOutput id="imgSlideShow" element="img" styleClass="main-image"
                          createContent="#{'#{'}imageLoader.paintImage}"
                          value="#{'#{'}slideshow.selectedImage != null ? fileManager.transformPath(slideshow.selectedImage.fullPath, '_medium') : null}"
                          mimeType="image/png" style="display:none">
                        <rich:tooltip followMouse="true" direction="topRight" showDelay="500" styleClass="tooltip">
                          <span style="white-space: nowrap"> #{'#{'}slideshow.selectedImage.description} </span>
                        </rich:tooltip>
                      </a4j:mediaOutput>
                    </h:panelGroup>
                  </h:panelGrid>
                  <a4j:poll id="slideShowPoll"
                      data="#{'#{'}slideshow.errorDetected}"
                      render="slideshowImage"
                      interval="#{'#{'}slideshow.interval}"
                      enabled="#{'#{'}slideshow.active}"
                      oncomplete="if(event.data)#{'#{'}rich:component('slideShowModalPanel')}.hide(); $(#{'#{'}rich:element('imgSlideShow')}).fadeIn(600);"
                      actionListener="#{'#{'}slideshow.showNextImage()}" />
                </rich:popupPanel>
              </a4j:region>
            </ui:composition>

The slideshow poller sends the request for the next image ( `showNextImage()` method) each four seconds. The interval is defined in the interval property of the `SlideshowManager.java` and refers to a `INITIAL.DELAY` constant ( `constants.java` ).

The described above example implements a modal panel with photos that rotate them in the order they are stored in an album.

Image size control

To stop the slide-show user clicks Close window button on the slide-show panel and `stopSlideshow()` method is invoked.

            public void stopSlideshow(@Observes @EventType(Events.STOP_SLIDESHOW_EVENT) SimpleEvent se) {
                active = false;
                errorDetected = false;
                this.selectedImage = null;
                this.slideshowIndex = 0;
                this.startSlideshowIndex = 0;
            }

The `active` field is set to "false" again, consequently the poller becomes inactive and the modal panel becomes invisible too.

Visit following pages at RichFaces Showcase for more information, examples and sources on the components used in the application and described in this chapter:

- PopupPanel page for the <rich:popupPanel> component;

- MediaOutput for the <a4j:mediaOutput> component;

- Ajax for the <a4j:ajax> component;

- CommandLink for the <a4j:commandLink> component;

- Poll for the <a4j:poll> component.