All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.zkoss.zul.impl.XulElement Maven / Gradle / Ivy

There is a newer version: 10.0.0-jakarta
Show newest version
/* XulElement.java

	Purpose:
		
	Description:
		
	History:
		Mon Jun 20 16:01:40     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.impl;

import java.io.Serializable;
import java.util.HashMap;

import org.zkoss.lang.Objects;
import org.zkoss.zk.au.DeferredValue;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.HtmlBasedComponent;
import org.zkoss.zk.ui.UiException;
import org.zkoss.zk.ui.sys.ObjectPropertyAccess;
import org.zkoss.zk.ui.sys.PropertyAccess;
import org.zkoss.zk.ui.sys.StringPropertyAccess;
import org.zkoss.zul.Popup;

/**
 * The fundamental class for XUL elements.
 * 
 * @author tomyeh
 */
public abstract class XulElement extends HtmlBasedComponent {
	/** AuxInfo: use a class (rather than multiple member) to save footprint */
	private AuxInfo _auxinf;

	/** Returns what keystrokes to intercept.
	 * 

Default: null. * @since 3.0.6 */ public String getCtrlKeys() { return _auxinf != null ? _auxinf.ctrlKeys : null; } /** Sets what keystrokes to intercept. * *

The string could be a combination of the following: *

*
^k
*
A control key, i.e., Ctrl+k, where k could be a~z, 0~9, #n
*
@k
*
A alt key, i.e., Alt+k, where k could be a~z, 0~9, #n
*
$n
*
A shift key, i.e., Shift+n, where n could be #n. * Note: $a ~ $z are not supported.
*
#home
*
Home
*
#end
*
End
*
#ins
*
Insert
*
#del
*
Delete
*
#bak
*
Backspace
*
#left
*
Left arrow
*
#right
*
Right arrow
*
#up
*
Up arrow
*
#down
*
Down arrow
*
#pgup
*
PageUp
*
#pgdn
*
PageDn
*
#f1 #f2 ... #f12
*
Function keys representing F1, F2, ... F12
*
* *

For example, *

*
^a^d@c#f10#left#right
*
It means you want to intercept Ctrl+A, Ctrl+D, Alt+C, F10, * Left and Right.
*
^#left
*
It means Ctrl+Left.
*
^#f1
*
It means Ctrl+F1.
*
@#f3
*
It means Alt+F3.
*
* *

Note: it doesn't support Ctrl+Alt, Shift+Ctrl, Shift+Alt or Shift+Ctrl+Alt. * @since 3.0.6 */ public void setCtrlKeys(String ctrlKeys) throws UiException { if (ctrlKeys != null && ctrlKeys.length() == 0) ctrlKeys = null; if (!Objects.equals(_auxinf != null ? _auxinf.ctrlKeys : null, ctrlKeys)) { initAuxInfo().ctrlKeys = ctrlKeys; smartUpdate("ctrlKeys", getCtrlKeys()); } } /** Returns the ID of the popup ({@link Popup}) that should appear * when the user right-clicks on the element (a.k.a., context menu). * *

Default: null (no context menu). */ public String getContext() { return _auxinf != null && _auxinf.context != null ? (String) _auxinf.context.getValue() : null; } /** Sets the ID of the popup ({@link Popup}) that should appear * when the user right-clicks on the element (a.k.a., context menu). * *

An onOpen event is sent to the context menu if it is going to * appear. Therefore, developers can manipulate it dynamically * (perhaps based on OpenEvent.getReference) by listening to the onOpen * event. * *

Note: To simplify the use, it not only searches its ID space, * but also all ID spaces in the desktop. * It first searches its own ID space, and then the other Id spaces * in the same browser window (might have one or multiple desktops). * *

(since 3.0.2) If there are two components with the same ID (of course, in * different ID spaces), you can specify the UUID with the following * format:
* uuid(comp_uuid) * *

Example:
*


	 * <label context="some">
	 * <label context="uuid(${some.uuid})"/>
	 * 
* Both reference a component whose ID is "some". * But, if there are several components with the same ID, * the first one can reference to any of them. * And, the second one reference to the component in the same ID space * (of the label component). * * *

(since 3.6.3) the context menu can be shown by a position from {@link Popup#open(org.zkoss.zk.ui.Component, String)} * or the location of x and y, you can specify the following format:
*

    *
  • id, position
  • *
  • id, position=before_start
  • *
  • id, x=15, y=20
  • *
  • uuid(comp_uuid), position
  • *
  • uuid(comp_uuid), x=15, y=20
  • *
* For example, *
	 * <button label="show" context="id, start_before"/>
	 * 
*

(since 6.5.2) the context menu can also be shown on customized location of x and y by adding parentheses"()", for example, *

	 * <button label="show" context="id, x=(zk.currentPointer[0] + 10), y=(zk.currentPointer[1] - 10)"/>
	 * 
* @see #setContext(Popup) */ public void setContext(String context) { if (!Objects.equals(_auxinf != null ? _auxinf.context : null, context)) { initAuxInfo().context = new DeferedUuid(context); smartUpdate("context", _auxinf.context); } } /** Sets the UUID of the popup that should appear * when the user right-clicks on the element (a.k.a., context menu). * *

Note: it actually invokes * setContext("uuid(" + popup.getUuid() + ")") * @since 3.0.2 * @see #setContext(String) * @see Popup#open(org.zkoss.zk.ui.Component, String) */ public void setContext(Popup popup) { if (!Objects.equals(_auxinf != null ? _auxinf.context : null, popup)) { initAuxInfo().context = new DeferedUuid(popup); smartUpdate("context", _auxinf.context); } } /** * Sets the Attributes for the Context Popup * * Note that position will be ignored if coordinates are set. * * @param popup the Context popup component, can be null * @param position e.g. "after_start", can be null * @param x e.g. "50" or "(zk.currentPointer[0] + 10)", can be null * @param y e.g. "50" or "(zk.currentPointer[0] + 10)", can be null * @param type e.g. "toggle", can be null * * @since 8.5.0 */ public void setContextAttributes(Popup popup, String position, String x, String y, String type) { setContext(popup); if (_auxinf != null && _auxinf.context != null) { DeferedUuid pp = (DeferedUuid) _auxinf.context; pp.setPosition(position); pp.setCoordinates(x, y); pp.setType(type); smartUpdate("context", _auxinf.context); } } /** Returns the ID of the popup ({@link Popup}) that should appear * when the user clicks on the element. * *

Default: null (no popup). */ public String getPopup() { return _auxinf != null && _auxinf.popup != null ? (String) _auxinf.popup.getValue() : null; } /** Sets the ID of the popup ({@link Popup}) that should appear * when the user clicks on the element. * *

An onOpen event is sent to the popup menu if it is going to * appear. Therefore, developers can manipulate it dynamically * (perhaps based on OpenEvent.getReference) by listening to the onOpen * event. * *

Note: To simplify the use, it not only searches its ID space, * but also all ID spaces in the desktop. * It first searches its own ID space, and then the other Id spaces * in the same browser window (might have one or multiple desktops). * *

(since 3.0.2) If there are two components with the same ID (of course, in * different ID spaces), you can specify the UUID with the following * format:
* uuid(comp_uuid) * *

(since 3.6.3) the popup can be shown by a position from {@link Popup#open(org.zkoss.zk.ui.Component, String)} * or the location of x and y, you can specify the following format:
*

    *
  • id, position
  • *
  • id, position=before_start
  • *
  • id, x=15, y=20
  • *
  • uuid(comp_uuid), position
  • *
  • uuid(comp_uuid), x=15, y=20
  • *
* For example, *
	 * <button label="show" popup="id, start_before"/>
	 * 
*

(since 6.5.2) the popup can also be shown on customized location of x and y by adding parentheses"()", for example, *

	 * <button label="show" context="id, x=(zk.currentPointer[0] + 10), y=(zk.currentPointer[1] - 10)"/>
	 * 
* @see #setPopup(Popup) * @see Popup#open(org.zkoss.zk.ui.Component, String) */ public void setPopup(String popup) { if (!Objects.equals(_auxinf != null ? _auxinf.popup : null, popup)) { initAuxInfo().popup = new DeferedUuid(popup); smartUpdate("popup", _auxinf.popup); } } /** Sets the UUID of the popup that should appear * when the user clicks on the element. * *

Note: it actually invokes * setPopup("uuid(" + popup.getUuid() + ")") * @since 3.0.2 * @see #setPopup(String) */ public void setPopup(Popup popup) { if (!Objects.equals(_auxinf != null ? _auxinf.popup : null, popup)) { initAuxInfo().popup = new DeferedUuid(popup); smartUpdate("popup", _auxinf.popup); } } /** * Sets the Attributes for the Popup * * Note that position will be ignored if coordinates are set. * * @param popup the popup component, can be null * @param position e.g. "after_start", can be null * @param x e.g. "50" or "(zk.currentPointer[0] + 10)", can be null * @param y e.g. "50" or "(zk.currentPointer[0] + 10)", can be null * @param type e.g. "toggle", can be null * * @since 8.5.0 */ public void setPopupAttributes(Popup popup, String position, String x, String y, String type) { setPopup(popup); if (_auxinf != null && _auxinf.popup != null) { DeferedUuid pp = (DeferedUuid) _auxinf.popup; pp.setPosition(position); pp.setCoordinates(x, y); pp.setType(type); smartUpdate("popup", _auxinf.popup); } } /** Returns the ID of the popup ({@link Popup}) that should be used * as a tooltip window when the mouse hovers over the element for a moment. * The tooltip will automatically disappear when the mouse is moved away. * *

Default: null (no tooltip). */ public String getTooltip() { return _auxinf != null && _auxinf.tooltip != null ? (String) _auxinf.tooltip.getValue() : null; } /** Sets the ID of the popup ({@link Popup}) that should be used * as a tooltip window when the mouse hovers over the element for a moment. * *

An onOpen event is sent to the tooltip if it is going to * appear. Therefore, developers can manipulate it dynamically * (perhaps based on OpenEvent.getReference) by listening to the onOpen * event. * *

Note: To simplify the use, it not only searches its ID space, * but also all ID spaces in the desktop. * It first searches its own ID space, and then the other Id spaces * in the same browser window (might have one or multiple desktops). * *

(since 3.0.2) If there are two components with the same ID (of course, in * different ID spaces), you can specify the UUID with the following * format:
* uuid(comp_uuid) * *

(since 3.6.3) the tooltip can be shown by a position from * {@link Popup#open(org.zkoss.zk.ui.Component, String)} * or the location of x and y, and can be specified * with a delay time (in millisecond), you can specify the following format: *
*

    *
  • id, position
  • *
  • id, position=before_start, delay=500
  • *
  • id, x=15, y=20
  • *
  • uuid(comp_uuid2), position
  • *
  • uuid(comp_uuid), x=15, y=20
  • *
* For example, *
	 * <button label="show" tooltip="id, start_before"/>
	 * 
*

(since 6.5.2) the tooltip can also be shown on customized location of x and y by adding parentheses"()", for example, *

	 * <button label="show" context="id, x=(zk.currentPointer[0] + 10), y=(zk.currentPointer[1] - 10)"/>
	 * 
* * @see #setTooltip(Popup) * @see Popup#open(org.zkoss.zk.ui.Component, String) */ public void setTooltip(String tooltip) { // ZK-816 if (!Objects.equals(_auxinf != null ? _auxinf.tooltip : null, tooltip)) { initAuxInfo().tooltip = new DeferedUuid(tooltip); smartUpdate("tooltip", _auxinf.tooltip); } } /** Sets the UUID of the popup that should be used * as a tooltip window when the mouse hovers over the element for a moment. * *

Note: it actually invokes * setTooltip("uuid(" + popup.getUuid() + ")") * @since 3.0.2 * @see #setTooltip(String) */ public void setTooltip(Popup popup) { // ZK-816, component keep wrong tooltip reference if set tooltip before tooltip attached if (!Objects.equals(_auxinf != null ? _auxinf.tooltip : null, popup)) { initAuxInfo().tooltip = new DeferedUuid(popup); smartUpdate("tooltip", _auxinf.tooltip); } } /** * Sets the Attributes for the Tooltip Popup * * Note that position will be ignored if coordinates are set. * * @param popup the tooltip popup component, can be null * @param position e.g. "after_start", can be null * @param x e.g. "50" or "(zk.currentPointer[0] + 10)", can be null * @param y e.g. "50" or "(zk.currentPointer[0] + 10)", can be null * @param delay in milliseconds, can be null * * @since 8.5.0 */ public void setTooltipAttributes(Popup popup, String position, String x, String y, Integer delay) { setTooltip(popup); if (_auxinf != null && _auxinf.tooltip != null) { DeferedUuid pp = (DeferedUuid) _auxinf.tooltip; pp.setPosition(position); pp.setCoordinates(x, y); pp.setDelay(delay); smartUpdate("tooltip", _auxinf.tooltip); } } //super// protected void renderProperties(org.zkoss.zk.ui.sys.ContentRenderer renderer) throws java.io.IOException { super.renderProperties(renderer); render(renderer, "popup", getPopup()); render(renderer, "context", getContext()); // ZK-816 render(renderer, "tooltip", getTooltip()); render(renderer, "ctrlKeys", getCtrlKeys()); } //--ComponentCtrl--// private static HashMap _properties = new HashMap(5); static { _properties.put("context", new ObjectPropertyAccess() { public void setValue(Component cmp, Object context) { if (context instanceof Popup) ((XulElement) cmp).setContext((Popup) context); else if (context != null) ((XulElement) cmp).setContext(String.valueOf(context)); } public String getValue(Component cmp) { return ((XulElement) cmp).getContext(); } }); _properties.put("popup", new ObjectPropertyAccess() { public void setValue(Component cmp, Object popup) { if (popup instanceof Popup) ((XulElement) cmp).setPopup((Popup) popup); else if (popup != null) ((XulElement) cmp).setPopup(String.valueOf(popup)); } public String getValue(Component cmp) { return ((XulElement) cmp).getPopup(); } }); _properties.put("tooltip", new ObjectPropertyAccess() { public void setValue(Component cmp, Object tooltip) { if (tooltip instanceof Popup) ((XulElement) cmp).setTooltip((Popup) tooltip); else if (tooltip != null) ((XulElement) cmp).setTooltip(String.valueOf(tooltip)); } public String getValue(Component cmp) { return ((XulElement) cmp).getTooltip(); } }); _properties.put("ctrlKeys", new StringPropertyAccess() { public void setValue(Component cmp, String ctrlKeys) { ((XulElement) cmp).setCtrlKeys(ctrlKeys); } public String getValue(Component cmp) { return ((XulElement) cmp).getCtrlKeys(); } }); } public PropertyAccess getPropertyAccess(String prop) { PropertyAccess pa = _properties.get(prop); if (pa != null) return pa; return super.getPropertyAccess(prop); } //Cloneable// public Object clone() { final XulElement clone = (XulElement) super.clone(); if (_auxinf != null) clone._auxinf = (AuxInfo) _auxinf.clone(); return clone; } private final AuxInfo initAuxInfo() { if (_auxinf == null) _auxinf = new AuxInfo(); return _auxinf; } /** Merge multiple members into an single object (and create on demand) * to minimize the footprint * @since 5.0.4 */ private static class AuxInfo implements java.io.Serializable, Cloneable { /** The popup ID that will be shown when click. */ private DeferredValue popup; /** The context ID that will be shown when right-click. */ private DeferredValue context; /** The tooltip ID that will be shown when mouse-over. */ private DeferredValue tooltip; /** What control and function keys to intercepts. */ private String ctrlKeys; public Object clone() { try { return super.clone(); } catch (CloneNotSupportedException e) { throw new InternalError(); } } } private static class DeferedUuid implements DeferredValue, Serializable { private static final long serialVersionUID = -122378869909137783L; private Popup popup; private String popupString; private String position; private String[] coordinates; private Integer delay; private String type; public DeferedUuid(String popupString) { super(); this.popupString = popupString; } public DeferedUuid(Popup tooltip) { super(); this.popup = tooltip; } public void setPosition(String position) { this.position = position; } public void setCoordinates(String x, String y) { this.coordinates = new String[]{x, y}; } public void setDelay(Integer delay) { this.delay = delay; } public void setType(String type) { this.type = type; } public Object getValue() { if (popupString != null) { return popupString; } else if (popup != null) { String uuidString = "uuid(" + popup.getUuid() + ")"; if (position != null) { uuidString += ", " + position; } else if (coordinates != null) { if (coordinates[0] != null) uuidString += ", x=" + coordinates[0]; if (coordinates[1] != null) uuidString += ", y=" + coordinates[1]; } if (delay != null) { uuidString += ", delay=" + delay; } if (type != null) { uuidString += ", type=" + type; } return uuidString; } else { return null; } } public int hashCode() { if (popupString != null) { return popupString.hashCode(); } else if (popup != null) { return popup.hashCode(); } else { return super.hashCode(); } } public boolean equals(Object obj) { if (obj instanceof String) { return Objects.equals(popupString, obj); } else if (obj instanceof Popup) { return Objects.equals(popup, obj); } else if (obj == null) { return popup == null && popupString == null; } else { return false; } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy