Java tutorial
/* * Copyright 2010 Richard Nichols. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * under the License. */ package com.visural.wicket.component.fancybox; import com.visural.wicket.util.images.ImageReference; import com.visural.common.Function; import com.visural.common.StringUtil; import com.visural.wicket.security.IPrivilege; import com.visural.wicket.security.ISecureEnableInstance; import com.visural.wicket.security.ISecureRenderInstance; import java.util.HashMap; import java.util.Map; import net.fancybox.FancyBoxCSSRef; import net.fancybox.FancyBoxJavascriptRef; import net.fancybox.JQueryMouseWheelJSRef; import org.apache.wicket.behavior.HeaderContributor; import org.apache.wicket.markup.ComponentTag; import org.apache.wicket.markup.html.CSSPackageResource; import org.apache.wicket.markup.html.IHeaderContributor; import org.apache.wicket.markup.html.IHeaderResponse; import org.apache.wicket.markup.html.JavascriptPackageResource; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.model.AbstractReadOnlyModel; import org.apache.wicket.model.IModel; /** * A wicket-integration of the Fancybox component from http://fancybox.net/ * * Apply to a `<a href="">...</a>` anchor tag. * * Used in the following way: `<a href="#" wicket:id="myBox">...</a>` * * Fancybox can display an image, another markup container (e.g. div) or an iframe * with a URL as a pop-up model box. * * Typically it would be used as a "lightbox" image viewer component, but videos * or other embedded media may also be used. * * Fancyboxes can be added to groups, however only the first element added to the * group's settings will take effect. i.e. the first element in the group's settings * will apply to the whole group. This is a limitation of the underlying plugin. * * When applying fancybox to another WebMarkupContainer, you should enclose the * container in a hidden div, e.g. * `<div style="display: none;"><div wicket:id="myContentToShow">....</div></div>` * This is less optimal but has changed due to Fancybox changes in the latest version. * * @version $Id: Fancybox.java 239 2010-11-23 00:35:45Z tibes80@gmail.com $ * @author Richard Nichols */ public class Fancybox extends WebMarkupContainer implements ISecureEnableInstance, ISecureRenderInstance { private static final long serialVersionUID = 1L; /** * Use this javascript to close an iframe fancybox from the child iframe code. */ public static final String IFRAME_PARENT_CLOSE_JS = "parent.$.fancybox.close();"; private FancyboxGroup group; private final ImageReference image; private final IModel iframeURL; private final WebMarkupContainer container; private String boxTitle; public Fancybox(String id, ImageReference image) { super(id); this.image = image; this.iframeURL = null; this.container = null; initAll(); } /** * Create a fancy box link to an iframe URL. * @param id * @param linkText * @param iframeURL */ public Fancybox(String id, IModel iframeURL) { super(id); this.image = null; this.iframeURL = iframeURL; this.container = null; initAll(); } /** * Create a fancy box link to an iframe URL. * @param id * @param linkText * @param iframeURL */ public Fancybox(String id, final String iframeURL) { super(id); this.image = null; this.iframeURL = new AbstractReadOnlyModel() { @Override public Object getObject() { return iframeURL; } }; this.container = null; initAll(); } /** * Create a fancy box link to another DOM element * @param id * @param linkText * @param iframeURL */ public Fancybox(String id, WebMarkupContainer container) { super(id); this.image = null; this.iframeURL = null; this.container = container; initAll(); } /** * Override and return false to suppress static Javascript and CSS contributions. * (May be desired if you are concatenating / compressing resources as part of build process) * @return */ protected boolean autoAddToHeader() { return true; } @Override protected void onComponentTag(ComponentTag tag) { checkComponentTag(tag, "a"); super.onComponentTag(tag); if (boxTitle != null) { tag.put("title", boxTitle); } if (group != null) { tag.put("rel", group.getName()); } if (isImage()) { tag.put("href", image.getURL()); } else if (isIframe()) { tag.put("href", Function.nvl(this.iframeURL.getObject(), "").toString()); } else if (isDiv()) { if (!container.getOutputMarkupId()) { throw new IllegalStateException( "The container component " + container.getId() + " is not getOutputMarkupId() == true."); } tag.put("href", "#" + container.getMarkupId()); } } private boolean isImage() { return (this.image != null); } private boolean isIframe() { return (this.iframeURL != null); } private boolean isDiv() { return (this.container != null); } private void initAll() { this.setOutputMarkupId(true); // we default the "hide on content click" to false if this isn't an image being displayed. if (!this.isImage()) { this.setHideOnContentClick(false); } if (autoAddToHeader()) { add(JavascriptPackageResource.getHeaderContribution(new FancyBoxJavascriptRef())); if (isMouseWheelEnabled()) { add(JavascriptPackageResource.getHeaderContribution(new JQueryMouseWheelJSRef())); } add(CSSPackageResource.getHeaderContribution(new FancyBoxCSSRef())); } add(new HeaderContributor(new IHeaderContributor() { public void renderHead(IHeaderResponse response) { String js = getFancyBoxJS(); if (js != null) { response.renderOnDomReadyJavascript(js); } } })); } private String getFancyBoxJS() { if (group != null && group.getMain() != this) { return null; } String selector = (group != null ? group.getGroupSelector() : "#" + getMarkupId()); String options = getBoxOptionsAsString(); if (StringUtil.isBlankStr(options)) { return "jQuery('" + selector + "').fancybox();"; } else { return "jQuery('" + selector + "').fancybox({" + options + "});"; } } public FancyboxGroup getGroup() { return group; } public Fancybox setGroup(FancyboxGroup group) { if (this.group != null) { this.group.removeFancybox(this); } this.group = group; group.addFancybox(this); return this; } public String getBoxTitle() { return boxTitle; } public Fancybox setBoxTitle(String boxTitle) { this.boxTitle = boxTitle; return this; } /** * Return whether to enable mouse wheel scroll on fancybox groups. * * By default mouse wheel functionality is disabled as it increases the * amount of Javascript required and only applies to box groups. * * Override and return true to enable. * * @return */ public boolean isMouseWheelEnabled() { return false; } private String getBoxOptionsAsString() { StringBuilder result = new StringBuilder(); Map<String, String> options = getBoxOptions(); if (isIframe()) { // force iframe, otherwise have to use element class, which creates styling issues options.put("type", "'iframe'"); } if (isImage()) { options.put("type", "'image'"); } boolean addBreak = false; for (String option : options.keySet()) { if (addBreak) { result.append(",\n"); } result.append("'"); result.append(option); result.append("': "); result.append(options.get(option)); addBreak = true; } return result.toString(); } private Map<String, String> getBoxOptions() { HashMap<String, String> result = new HashMap<String, String>(); if (padding != null) { result.put("padding", padding.toString()); } if (margin != null) { result.put("margin", margin.toString()); } if (opacity != null) { result.put("opacity", opacity.toString()); } if (modal != null) { result.put("modal", modal.toString()); } if (cyclic != null) { result.put("cyclic", cyclic.toString()); } if (scrolling != null) { result.put("scrolling", scrolling.toString()); } if (width != null) { result.put("width", width.toString()); } if (height != null) { result.put("height", height.toString()); } if (autoScale != null) { result.put("autoScale", autoScale.toString()); } if (autoDimensions != null) { result.put("autoDimensions", autoDimensions.toString()); } if (centerOnScroll != null) { result.put("centerOnScroll", centerOnScroll.toString()); } if (hideOnOverlayClick != null) { result.put("hideOnOverlayClick", hideOnOverlayClick.toString()); } if (hideOnContentClick != null) { result.put("hideOnContentClick", hideOnContentClick.toString()); } if (overlayShow != null) { result.put("overlayShow", overlayShow.toString()); } if (overlayOpacity != null) { result.put("overlayOpacity", overlayOpacity.toString()); } if (titleShow != null) { result.put("titleShow", titleShow.toString()); } if (speedIn != null) { result.put("speedIn", speedIn.toString()); } if (speedOut != null) { result.put("speedOut", speedOut.toString()); } if (changeSpeed != null) { result.put("changeSpeed", changeSpeed.toString()); } if (showCloseButton != null) { result.put("showCloseButton", showCloseButton.toString()); } if (showNavArrows != null) { result.put("showNavArrows", showNavArrows.toString()); } if (enableEscapeButton != null) { result.put("enableEscapeButton", enableEscapeButton.toString()); } if (overlayColor != null) { result.put("overlayColor", "'" + overlayColor + "'"); } if (titlePosition != null) { result.put("titlePosition", "'" + titlePosition.getValue() + "'"); } if (transitionIn != null) { result.put("transitionIn", "'" + transitionIn + "'"); } if (transitionOut != null) { result.put("transitionOut", "'" + transitionOut + "'"); } if (changeFade != null) { result.put("changeFade", "'" + changeFade + "'"); } if (easingIn != null) { result.put("easingIn", "'" + easingIn + "'"); } if (easingOut != null) { result.put("easingOut", "'" + easingOut + "'"); } if (onStart != null) { result.put("onStart", "function() {" + onStart + "}"); } if (onCancel != null) { result.put("onCancel", "function() {" + onCancel + "}"); } if (onComplete != null) { result.put("onComplete", "function() {" + onComplete + "}"); } if (onCleanup != null) { result.put("onCleanup", "function() {" + onCleanup + "}"); } if (onClosed != null) { result.put("onClosed", "function() {" + onClosed + "}"); } return result; } // fancybox properties follow //ajax { } Ajax options (error, success will be overwritten) //swf {wmode: 'transparent'} Flashvars to put on the swf object //titleFormat null Callback to customize title area. You can set any html - custom image counter or even custom navigation private Integer padding; // 10 Space between FancyBox wrapper and content private Integer margin; // 20 Space between viewport and FancyBox wrapper private Boolean opacity; // false When true, transparency of content is changed for elastic transitions private Boolean modal; // false When true, 'overlayShow' is set to 'true' and 'hideOnOverlayClick', 'hideOnContentClick', 'enableEscapeButton', 'showCloseButton' are set to 'false' private Boolean cyclic; // false When true, galleries will be cyclic, allowing you to keep pressing next/back. private Boolean scrolling; // 'auto' Set the overflow CSS property to create or hide scrollbars. Can be set to 'auto', 'yes', or 'no' private Integer width; // 560 Width for content types 'iframe' and 'swf'. Also set for inline content if 'autoDimensions' is set to 'false' private Integer height; // 340 Height for content types 'iframe' and 'swf'. Also set for inline content if 'autoDimensions' is set to 'false' private Boolean autoScale; // true If true, FancyBox is scaled to fit in viewport private Boolean autoDimensions; // true For inline and ajax views, resizes the view to the element recieves. Make sure it has dimensions otherwise this will give unexpected results private Boolean centerOnScroll; // false When true, FancyBox is centered while scrolling page private Boolean hideOnOverlayClick; // true Toggle if clicking the overlay should close FancyBox private Boolean hideOnContentClick; // false Toggle if clicking the content should close FancyBox private Boolean overlayShow; // true Toggle overlay private Float overlayOpacity; // 0.3 Opacity of the overlay (from 0 to 1; default - 0.3) private Boolean titleShow; // true Toggle title private String overlayColor; // '#666' Color of the overlay private TitlePosition titlePosition; // 'outside' The position of title. Can be set to 'outside', 'inside' or 'over' private String transitionIn; // private String transitionOut; // 'fade' The transition type. Can be set to 'elastic', 'fade' or 'none' private String changeFade; // 'fast' Speed of the content fading while changing gallery items private String easingIn; // private String easingOut; // 'swing' Easing used for elastic animations private String onStart; // null Will be called right before attempting to load the content private String onCancel; // null Will be called after loading is canceled private String onComplete; // null Will be called once the content is displayed private String onCleanup; // null Will be called just before closing private String onClosed; // null Will be called once FancyBox is closed private Integer speedIn; // private Integer speedOut; // 300 Speed of the fade and elastic transitions, in milliseconds private Integer changeSpeed; // 300 Speed of resizing when changing gallery items, in milliseconds private Boolean showCloseButton; // true Toggle close button private Boolean showNavArrows; // true Toggle navigation arrows private Boolean enableEscapeButton; // true Toggle if pressing Esc button closes FancyBox public Integer getPadding() { return padding; } /** * Space between FancyBox wrapper and content * @param padding * @return */ public Fancybox setPadding(Integer padding) { this.padding = padding; return this; } public Integer getMargin() { return margin; } /** * Space between viewport and FancyBox wrapper * @param margin * @return */ public Fancybox setMargin(Integer margin) { this.margin = margin; return this; } public Boolean getOpacity() { return opacity; } /** * When true, transparency of content is changed for elastic transitions * @param opacity * @return */ public Fancybox setOpacity(Boolean opacity) { this.opacity = opacity; return this; } public Boolean getModal() { return modal; } /** * When true, 'overlayShow' is set to 'true' and 'hideOnOverlayClick', * 'hideOnContentClick', 'enableEscapeButton', 'showCloseButton' are set * to 'false' * @param modal * @return */ public Fancybox setModal(Boolean modal) { this.modal = modal; return this; } public Boolean getCyclic() { return cyclic; } /** * When true, galleries will be cyclic, allowing you to keep pressing next/back. * @param cyclic * @return */ public Fancybox setCyclic(Boolean cyclic) { this.cyclic = cyclic; return this; } public Boolean getScrolling() { return scrolling; } /** * Set the overflow CSS property to create or hide scrollbars. Can be set to 'auto', 'yes', or 'no' * @param scrolling * @return */ public Fancybox setScrolling(Boolean scrolling) { this.scrolling = scrolling; return this; } public Integer getWidth() { return width; } /** * Width for content types 'iframe' and 'swf'. Also set for inline content if 'autoDimensions' is set to 'false' * @param width * @return */ public Fancybox setWidth(Integer width) { this.width = width; return this; } public Integer getHeight() { return height; } /** * Height for content types 'iframe' and 'swf'. Also set for inline content if 'autoDimensions' is set to 'false' * @param height * @return */ public Fancybox setHeight(Integer height) { this.height = height; return this; } public Boolean getAutoScale() { return autoScale; } /** * If true, FancyBox is scaled to fit in viewport * @param autoScale * @return */ public Fancybox setAutoScale(Boolean autoScale) { this.autoScale = autoScale; return this; } public Boolean getAutoDimensions() { return autoDimensions; } /** * For inline and ajax views, resizes the view to the element recieves. * Make sure it has dimensions otherwise this will give unexpected results * @param autoDimensions * @return */ public Fancybox setAutoDimensions(Boolean autoDimensions) { this.autoDimensions = autoDimensions; return this; } public Boolean getCenterOnScroll() { return centerOnScroll; } /** * When true, FancyBox is centered while scrolling page * @param centerOnScroll * @return */ public Fancybox setCenterOnScroll(Boolean centerOnScroll) { this.centerOnScroll = centerOnScroll; return this; } public Boolean getHideOnOverlayClick() { return hideOnOverlayClick; } /** * Toggle if clicking the overlay should close FancyBox * @param hideOnOverlayClick * @return */ public Fancybox setHideOnOverlayClick(Boolean hideOnOverlayClick) { this.hideOnOverlayClick = hideOnOverlayClick; return this; } public Boolean getHideOnContentClick() { return hideOnContentClick; } /** * Toggle if clicking the content should close FancyBox * @param hideOnContentClick * @return */ public Fancybox setHideOnContentClick(Boolean hideOnContentClick) { this.hideOnContentClick = hideOnContentClick; return this; } public Boolean getOverlayShow() { return overlayShow; } /** * Toggle overlay * @param overlayShow * @return */ public Fancybox setOverlayShow(Boolean overlayShow) { this.overlayShow = overlayShow; return this; } public Float getOverlayOpacity() { return overlayOpacity; } /** * Opacity of the overlay (from 0 to 1; default - 0.3) * @param overlayOpacity * @return */ public Fancybox setOverlayOpacity(Float overlayOpacity) { this.overlayOpacity = overlayOpacity; return this; } public String getOverlayColor() { return overlayColor; } /** * Color of the overlay * @param overlayColor * @return */ public Fancybox setOverlayColor(String overlayColor) { this.overlayColor = overlayColor; return this; } public Boolean getTitleShow() { return titleShow; } /** * Toggle title * @param titleShow * @return */ public Fancybox setTitleShow(Boolean titleShow) { this.titleShow = titleShow; return this; } public TitlePosition getTitlePosition() { return titlePosition; } /** * The position of title. Can be set to 'outside', 'inside' or 'over' * @param titlePosition * @return */ public Fancybox setTitlePosition(TitlePosition titlePosition) { this.titlePosition = titlePosition; return this; } public FancyboxTransition getTransitionIn() { return transitionIn == null ? null : FancyboxTransition.valueOf(transitionIn); } /** * The transition type. Can be set to 'elastic', 'fade' or 'none' * @param transitionIn * @return */ public Fancybox setTransitionIn(FancyboxTransition transitionIn) { this.transitionIn = transitionIn.name(); return this; } public FancyboxTransition getTransitionOut() { return transitionOut == null ? null : FancyboxTransition.valueOf(transitionOut); } /** * The transition type. Can be set to 'elastic', 'fade' or 'none' * @param transitionOut * @return */ public Fancybox setTransitionOut(FancyboxTransition transitionOut) { this.transitionOut = transitionOut.name(); return this; } public Integer getSpeedIn() { return speedIn; } /** * Speed of the fade and elastic transitions, in milliseconds * @param speedIn * @return */ public Fancybox setSpeedIn(Integer speedIn) { this.speedIn = speedIn; return this; } public Integer getSpeedOut() { return speedOut; } /** * Speed of the fade and elastic transitions, in milliseconds * @return */ public Fancybox setSpeedOut(Integer speedOut) { this.speedOut = speedOut; return this; } public Integer getChangeSpeed() { return changeSpeed; } /** * Speed of resizing when changing gallery items, in milliseconds * @return */ public Fancybox setChangeSpeed(Integer changeSpeed) { this.changeSpeed = changeSpeed; return this; } public String getChangeFade() { return changeFade; } /** * Speed of the content fading while changing gallery items * @param changeFade * @return */ public Fancybox setChangeFade(String changeFade) { this.changeFade = changeFade; return this; } public String getEasingIn() { return easingIn; } /** * Easing used for elastic animations * @param easingIn * @return */ public Fancybox setEasingIn(String easingIn) { this.easingIn = easingIn; return this; } public String getEasingOut() { return easingOut; } /** * Easing used for elastic animations * @param easingIn * @return */ public Fancybox setEasingOut(String easingOut) { this.easingOut = easingOut; return this; } public Boolean getShowCloseButton() { return showCloseButton; } /** * Toggle close button * @param showCloseButton * @return */ public Fancybox setShowCloseButton(Boolean showCloseButton) { this.showCloseButton = showCloseButton; return this; } public Boolean getShowNavArrows() { return showNavArrows; } /** * Toggle navigation arrows * @param showNavArrows * @return */ public Fancybox setShowNavArrows(Boolean showNavArrows) { this.showNavArrows = showNavArrows; return this; } public Boolean getEnableEscapeButton() { return enableEscapeButton; } /** * Toggle if pressing Esc button closes FancyBox * @param enableEscapeButton * @return */ public Fancybox setEnableEscapeButton(Boolean enableEscapeButton) { this.enableEscapeButton = enableEscapeButton; return this; } public String getOnStart() { return onStart; } /** * Will be called right before attempting to load the content * @param onStart * @return */ public Fancybox setOnStart(String onStart) { this.onStart = onStart; return this; } public String getOnCancel() { return onCancel; } /** * Will be called after loading is canceled * @param onCancel * @return */ public Fancybox setOnCancel(String onCancel) { this.onCancel = onCancel; return this; } public String getOnComplete() { return onComplete; } /** * Will be called once the content is displayed * @param onComplete * @return */ public Fancybox setOnComplete(String onComplete) { this.onComplete = onComplete; return this; } public String getOnCleanup() { return onCleanup; } /** * Will be called just before closing * @param onCleanup * @return */ public Fancybox setOnCleanup(String onCleanup) { this.onCleanup = onCleanup; return this; } public String getOnClosed() { return onClosed; } /** * Will be called once FancyBox is closed * @param onClosed * @return */ public Fancybox setOnClosed(String onClosed) { this.onClosed = onClosed; return this; } public IPrivilege getRenderPrivilege() { return IPrivilege.NULL; } public IPrivilege getEnablePrivilege() { return IPrivilege.NULL; } }