/* Audio.java
Purpose:
Description:
History:
Wed Nov 16 11:48:27 2005, Created by tomyeh
Copyright (C) 2005 Potix Corporation. All Rights Reserved.
{{IS_RIGHT
This program is distributed under LGPL Version 2.1 in the hope that
it will be useful, but WITHOUT ANY WARRANTY.
}}IS_RIGHT
*/
package org.zkoss.zul;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.zkoss.util.media.Media;
import org.zkoss.zk.au.out.AuInvoke;
import org.zkoss.zk.ui.Desktop;
import org.zkoss.zk.ui.ext.render.DynamicMedia;
import org.zkoss.zul.impl.Utils;
import org.zkoss.zul.impl.XulElement;
/**
* An audio clip.
*
* <p>An extension to XUL.
* Only works for browsers supporting HTML5 audio tag (since ZK 7.0.0).
*
* @author tomyeh
*/
public class Audio extends XulElement {
protected List<String> _src = new ArrayList<String>();
/** The audio. _src and _audio cannot be nonnull at the same time. */
private org.zkoss.sound.Audio _audio;
/** Count the version of {@link #_audio}. */
private byte _audver;
private boolean _autoplay, _controls, _loop, _muted;
private String _preload;
public Audio() {
}
public Audio(String src) {
setSrc(src);
}
/** Plays the audio at the client.
*/
public void play() {
response("ctrl", new AuInvoke(this, "play"));
}
/** Stops the audio at the client.
*/
public void stop() {
response("ctrl", new AuInvoke(this, "stop"));
}
/** Pauses the audio at the client.
*/
public void pause() {
response("ctrl", new AuInvoke(this, "pause"));
}
/** Returns the src.
* <p>Default: [].
*/
public List<String> getSrc() {
return _src;
}
/** Sets the src.
*
* <p>Calling this method implies setContent(null).
* In other words, the last invocation of {@link #setSrc} overrides
* the previous {@link #setContent}, if any.
* @see #setContent
*/
public void setSrc(String src) {
List<String> list = new ArrayList<String>();
if (src.contains(",")) {
list = new ArrayList<String>(Arrays.asList(src.split("\\s*,\\s*")));
} else {
list.add(src.trim());
}
if (_audio != null || !_src.equals(list)) {
_audio = null;
setSrc(list);
}
}
/** Sets the source list.
*
* @since 7.0.0
*/
public void setSrc(List<String> src) {
if (!src.equals(_src)) {
_src = src;
smartUpdate("src", new EncodedSrc());
}
}
/** Returns whether to auto start playing the audio.
*
* <p>Default: false;
* @deprecated As of release 7.0.0, use {@link #isAutoplay} instead.
*/
public boolean isAutostart() {
return isAutoplay();
}
/** Sets whether to auto start playing the audio.
*
* @deprecated As of release 7.0.0, use {@link #setAutoplay} instead.
*/
public void setAutostart(boolean autostart) {
setAutoplay(autostart);
}
/** Returns whether to auto start playing the audio.
*
* <p>Default: false.
* @since 7.0.0
*/
public boolean isAutoplay() {
return _autoplay;
}
/** Sets whether to auto start playing the audio.
*
* @since 7.0.0
*/
public void setAutoplay(boolean autoplay) {
if (_autoplay != autoplay) {
_autoplay = autoplay;
smartUpdate("autoplay", _autoplay);
}
}
/** Returns whether and how the audio should be loaded.
* "none" or "metadata" or "auto" or null
* <p>Default: null.
* @since 7.0.0
*/
public String getPreload() {
return _preload;
}
/** Sets whether and how the audio should be loaded.
* Refer to <a href="http://www.w3.org/TR/html5/embedded-content-0.html#attr-media-preload">Preload Attribute Description</a> for details.
* @param preload which could be one of "none", "metadata", "auto".
* @since 7.0.0
*/
public void setPreload(String preload) {
if ("none".equalsIgnoreCase(preload)) {
preload = "none";
} else if ("metadata".equalsIgnoreCase(preload)) {
preload = "metadata";
} else {
preload = "auto";
}
if (!preload.equals(_preload)) {
_preload = preload;
smartUpdate("preload", _preload);
}
}
/** Returns whether to display the audio controls.
*
* <p>Default: false.
* @since 7.0.0
*/
public boolean isControls() {
return _controls;
}
/** Sets whether to display the audio controls.
* @since 7.0.0
*/
public void setControls(boolean controls) {
if (_controls != controls) {
_controls = controls;
smartUpdate("controls", _controls);
}
}
/** Returns whether to play the audio repeatedly.
*
* <p>Default: false.
* @since 3.6.1
*/
public boolean isLoop() {
return _loop;
}
/** Sets whether to play the audio repeatedly.
*
* @since 3.6.1
*/
public void setLoop(boolean loop) {
if (_loop != loop) {
_loop = loop;
smartUpdate("loop", _loop);
}
}
/** Returns whether to mute the audio.
*
* <p>Default: false.
* @since 7.0.0
*/
public boolean isMuted() {
return _muted;
}
/** Sets whether to mute the audio.
*
* @since 7.0.0
*/
public void setMuted(boolean muted) {
if (_muted != muted) {
_muted = muted;
smartUpdate("muted", _muted);
}
}
/** Sets the content directly.
*
* <p>Default: null.
*
* <p>Calling this method implies setSrc(null).
* In other words, the last invocation of {@link #setContent} overrides
* the previous {@link #setSrc}, if any.
* Note: setContent doesn't support in Chrome.
* @param audio the audio to display.
* @see #setSrc
*/
public void setContent(org.zkoss.sound.Audio audio) {
if (_src != null || audio != _audio) {
_audio = audio;
_src = null;
if (_audio != null)
++_audver; //enforce browser to reload
smartUpdate("src", new EncodedSrc());
}
}
/** Returns the content set by {@link #setContent}.
* <p>Note: it won't fetch what is set thru by {@link #setSrc}.
* It simply returns what is passed to {@link #setContent}.
*/
public org.zkoss.sound.Audio getContent() {
return _audio;
}
private List<String> getEncodedSrc() {
final Desktop dt = getDesktop();
List<String> list = new ArrayList<String>();
if (_audio != null) {
list.add(getAudioSrc());
} else if (dt != null) {
for (String src : _src) {
list.add(dt.getExecution().encodeURL(src));
}
}
return list;
}
/** Returns the encoded URL for the current audio content.
* Don't call this method unless _audio is not null;
*/
private String getAudioSrc() {
return Utils.getDynamicMediaURI(this, _audver, _audio.getName(), _audio.getFormat());
}
// super
protected void renderProperties(org.zkoss.zk.ui.sys.ContentRenderer renderer) throws java.io.IOException {
super.renderProperties(renderer);
render(renderer, "src", getEncodedSrc());
render(renderer, "autoplay", _autoplay);
render(renderer, "preload", _preload);
render(renderer, "controls", _controls);
render(renderer, "loop", _loop);
render(renderer, "muted", _muted);
}
/** Default: not childable.
*/
protected boolean isChildable() {
return false;
}
// ComponentCtrl
public Object getExtraCtrl() {
return new ExtraCtrl();
}
/** A utility class to implement {@link #getExtraCtrl}.
* It is used only by component developers.
*/
protected class ExtraCtrl extends XulElement.ExtraCtrl implements DynamicMedia {
//-- DynamicMedia --//
public Media getMedia(String pathInfo) {
return _audio;
}
}
private class EncodedSrc implements org.zkoss.zk.au.DeferredValue {
public Object getValue() {
return getEncodedSrc();
}
}
}