@qooxdoo/framework
Version:
The JS Framework for Coders
345 lines (285 loc) • 8.08 kB
JavaScript
/* ************************************************************************
qooxdoo - the new era of web development
http://qooxdoo.org
Copyright:
2004-2008 1&1 Internet AG, Germany, http://www.1und1.de
License:
MIT: https://opensource.org/licenses/MIT
See the LICENSE file in the project's top-level directory for details.
Authors:
* Martin Wittemann (martinwittemann)
************************************************************************ */
/**
* A toggle Button widget
*
* If the user presses the button by tapping on it pressing the enter or
* space key, the button toggles between the pressed an not pressed states.
*/
qx.Class.define("qx.ui.form.ToggleButton",
{
extend : qx.ui.basic.Atom,
include : [
qx.ui.core.MExecutable
],
implement : [
qx.ui.form.IBooleanForm,
qx.ui.form.IExecutable,
qx.ui.form.IRadioItem
],
/*
*****************************************************************************
CONSTRUCTOR
*****************************************************************************
*/
/**
* Creates a ToggleButton.
*
* @param label {String} The text on the button.
* @param icon {String} An URI to the icon of the button.
*/
construct : function(label, icon)
{
this.base(arguments, label, icon);
// register pointer events
this.addListener("pointerover", this._onPointerOver);
this.addListener("pointerout", this._onPointerOut);
this.addListener("pointerdown", this._onPointerDown);
this.addListener("pointerup", this._onPointerUp);
// register keyboard events
this.addListener("keydown", this._onKeyDown);
this.addListener("keyup", this._onKeyUp);
// register execute event
this.addListener("execute", this._onExecute, this);
},
/*
*****************************************************************************
PROPERTIES
*****************************************************************************
*/
properties:
{
// overridden
appearance:
{
refine: true,
init: "button"
},
// overridden
focusable :
{
refine : true,
init : true
},
/** The value of the widget. True, if the widget is checked. */
value :
{
check : "Boolean",
nullable : true,
event : "changeValue",
apply : "_applyValue",
init : false
},
/** The assigned qx.ui.form.RadioGroup which handles the switching between registered buttons. */
group :
{
check : "qx.ui.form.RadioGroup",
nullable : true,
apply : "_applyGroup"
},
/**
* Whether the button has a third state. Use this for tri-state checkboxes.
*
* When enabled, the value null of the property value stands for "undetermined",
* while true is mapped to "enabled" and false to "disabled" as usual. Note
* that the value property is set to false initially.
*
*/
triState :
{
check : "Boolean",
apply : "_applyTriState",
nullable : true,
init : null
}
},
/*
*****************************************************************************
MEMBERS
*****************************************************************************
*/
members :
{
/** The assigned {@link qx.ui.form.RadioGroup} which handles the switching between registered buttons */
_applyGroup : function(value, old)
{
if (old) {
old.remove(this);
}
if (value) {
value.add(this);
}
},
/**
* Changes the state of the button dependent on the checked value.
*
* @param value {Boolean} Current value
* @param old {Boolean} Previous value
*/
_applyValue : function(value, old) {
value ? this.addState("checked") : this.removeState("checked");
if (this.isTriState()) {
if (value === null) {
this.addState("undetermined");
} else if (old === null) {
this.removeState("undetermined");
}
}
},
/**
* Apply value property when triState property is modified.
*
* @param value {Boolean} Current value
* @param old {Boolean} Previous value
*/
_applyTriState : function(value, old) {
this._applyValue(this.getValue());
},
/**
* Handler for the execute event.
*
* @param e {qx.event.type.Event} The execute event.
*/
_onExecute : function(e) {
this.toggleValue();
},
/**
* Listener method for "pointerover" event.
* <ul>
* <li>Adds state "hovered"</li>
* <li>Removes "abandoned" and adds "pressed" state (if "abandoned" state is set)</li>
* </ul>
*
* @param e {qx.event.type.Pointer} Pointer event
*/
_onPointerOver : function(e)
{
if (e.getTarget() !== this) {
return;
}
this.addState("hovered");
if (this.hasState("abandoned"))
{
this.removeState("abandoned");
this.addState("pressed");
}
},
/**
* Listener method for "pointerout" event.
* <ul>
* <li>Removes "hovered" state</li>
* <li>Adds "abandoned" state (if "pressed" state is set)</li>
* <li>Removes "pressed" state (if "pressed" state is set and button is not checked)
* </ul>
*
* @param e {qx.event.type.Pointer} pointer event
*/
_onPointerOut : function(e)
{
if (e.getTarget() !== this) {
return;
}
this.removeState("hovered");
if (this.hasState("pressed"))
{
if (!this.getValue()) {
this.removeState("pressed");
}
this.addState("abandoned");
}
},
/**
* Listener method for "pointerdown" event.
* <ul>
* <li>Activates capturing</li>
* <li>Removes "abandoned" state</li>
* <li>Adds "pressed" state</li>
* </ul>
*
* @param e {qx.event.type.Pointer} pointer event
*/
_onPointerDown : function(e)
{
if (!e.isLeftPressed()) {
return;
}
// Activate capturing if the button get a pointerout while
// the button is pressed.
this.capture();
this.removeState("abandoned");
this.addState("pressed");
e.stopPropagation();
},
/**
* Listener method for "pointerup" event.
* <ul>
* <li>Releases capturing</li>
* <li>Removes "pressed" state (if not "abandoned" state is set and "pressed" state is set)</li>
* <li>Removes "abandoned" state (if set)</li>
* <li>Toggles {@link #value} (if state "abandoned" is not set and state "pressed" is set)</li>
* </ul>
*
* @param e {qx.event.type.Pointer} pointer event
*/
_onPointerUp : function(e)
{
this.releaseCapture();
if (this.hasState("abandoned")) {
this.removeState("abandoned");
} else if (this.hasState("pressed")) {
this.execute();
}
this.removeState("pressed");
e.stopPropagation();
},
/**
* Listener method for "keydown" event.<br/>
* Removes "abandoned" and adds "pressed" state
* for the keys "Enter" or "Space"
*
* @param e {Event} Key event
*/
_onKeyDown : function(e)
{
switch(e.getKeyIdentifier())
{
case "Enter":
case "Space":
this.removeState("abandoned");
this.addState("pressed");
e.stopPropagation();
}
},
/**
* Listener method for "keyup" event.<br/>
* Removes "abandoned" and "pressed" state (if "pressed" state is set)
* for the keys "Enter" or "Space". It also toggles the {@link #value} property.
*
* @param e {Event} Key event
*/
_onKeyUp : function(e)
{
if (!this.hasState("pressed")) {
return;
}
switch(e.getKeyIdentifier())
{
case "Enter":
case "Space":
this.removeState("abandoned");
this.execute();
this.removeState("pressed");
e.stopPropagation();
}
}
}
});