baseslider.lzx
<library>
<include href="base/basevaluecomponent.lzx"/>
<include href="lz/button.lzx"/>
<include href="utils/states/dragstate.lzx"/>
<class name="baseslider" extends="basevaluecomponent" width="200">
<attribute name="track"/>
<attribute name="trackheight" value="8
" type="number"/>
<attribute name="thumbwidth" value="10
" type="number"/>
<attribute name="thumbheight" value="18
" type="number"/>
<attribute name="minvalue" value="0
" type="number" setter="setMinValue(minvalue)"/>
<attribute name="maxvalue" value="100
" type="number" setter="setMaxValue(maxvalue)"/>
<attribute name="showfill" value="true
"/>
<attribute name="showvalue" value="true
" type="boolean"/>
<attribute name="showrange" value="true
" type="boolean"/>
<attribute name="keystep" value="1
" type="number"/>
<attribute name="bordersize" value="1
" type="number"/>
<attribute name="value" value="0
" setter="setValue(value)"/>
<event name="onvalue"/>
<event name="onmaxvalue"/>
<event name="onminvalue"/>
<method name="init">
super.init();
// Since we didn't handle inconsistent values in the setters in the pre-init case,
// do it now.
// Choose init() because of oninit() for this because we get predictable
// order of execution with init().
if (this.maxvalue < this.minvalue) this.maxvalue = this.minvalue;
if (this.value < this.minvalue) this.value = this.minvalue;
if (this.value > this.maxvalue) this.value = this.maxvalue;
// and since we didn't send events in the pre-init case, do those now too
if (this['onvalue']) this.onvalue.sendEvent();
if (this['onminvalue']) this.onminvalue.sendEvent();
if (this['onmaxvalue']) this.onmaxvalue.sendEvent();
// since we didn't handle view consistency in the pre-init case, do it now
this._adjustThumb();
</method>
<method name="getMinValue">
//TODO: [20080412 anba] deprecate?
if ($debug) {
Debug.info("%w.%s() is deprecated. Use %w[%#w] instead.", this, arguments.callee, this, "minvalue");
}
return this.minvalue;
</method>
<method name="getMaxValue">
//TODO: [20080412 anba] deprecate?
if ($debug) {
Debug.info("%w.%s() is deprecated. Use %w[%#w] instead.", this, arguments.callee, this, "maxvalue");
}
return this.maxvalue;
</method>
<method name="setMinValue" args="v">
v = v * 1;
if (isNaN(v)) {
if ($debug) {
Debug.warn("%w.%s must not be set to %s", this, "minvalue", v);
}
v = 0;
}
if (!this._initcomplete) {
// bounds check and sendEvent are done in init() override in this case
this.minvalue = v;
} else {
if (this.minvalue == v) return;
// ensure no crossover
if (this.maxvalue < v) v = this.maxvalue;
// doing this before setting the attribute means we assume consistency
// on function entry and try to send events only when in a consistent state.
if (v > this.value) this.setAttribute("value", v);
this.minvalue = v;
if (this['onminvalue']) this.onminvalue.sendEvent();
this._adjustThumb();
}
</method>
<method name="setMaxValue" args="v">
v = v * 1;
if (isNaN(v)) {
if ($debug) {
Debug.warn("%w.%s must not be set to %s", this, "maxvalue", v);
}
v = 0;
}
if (!this._initcomplete) {
// bounds check and sendEvent are done in init() override in this case
this.maxvalue = v;
} else {
if (this.maxvalue == v) return;
// ensure no crossover
if (this.minvalue > v) v = this.minvalue;
// doing this before setting the attribute means we assume consistency
// on function entry and try to send events only when in a consistent state.
if (this.value > v) this.setAttribute("value", v);
this.maxvalue = v;
if (this['onmaxvalue']) this.onmaxvalue.sendEvent();
this._adjustThumb();
}
</method>
<method name="setValue" args="v">
v = v * 1;
if (isNaN(v)) {
if ($debug) {
Debug.warn("%w.%s must not be set to %s", this, "value", v);
}
v = 0;
}
if (!this._initcomplete) {
// bounds check and sendEvent are done in init() override in this case
this.value = v;
} else {
if (this.value == v) return;
// ensure in bounds
if (v < this.minvalue) v = this.minvalue;
if (v > this.maxvalue) v = this.maxvalue;
this.value = v;
if (this['onvalue']) this.onvalue.sendEvent(v);
this._adjustThumb();
}
</method>
<method name="setPercentage" args="p">
var diff = this.minvalue - this.maxvalue;
this.setAttribute("value", diff * p + this.minvalue);
</method>
<method name="getPercentage">
if ($debug) {
if (this.maxvalue - this.minvalue == 0) {
Debug.error("%s.%s can not be computed, range is empty", this, arguments.callee);
}
}
return (this.value - this.minvalue) / (this.maxvalue - this.minvalue);
</method>
<method name="_adjustThumb">
var track = this.track;
if (track) {
var thumb = track.thumb;
thumb.setAttribute("x", thumb._thumbFromValue());
}
</method>
<handler name="onkeydown" args="k">
var track = this.track;
if (track) {
if (k == 37) {
//left arrow
this.setValue(this.value - this.keystep);
} else if (k == 39) {
//right arrow
this.setValue(this.value + this.keystep);
}
}
</handler>
<method name="getFocusRect">
var fx = this.getAttributeRelative('x', canvas);
var fy = this.getAttributeRelative('y', canvas) - 4;
var fw = this.getAttributeRelative('width', canvas) + 2;
var fh = this.getAttributeRelative('height', canvas) + 6;
return [fx, fy, fw, fh];
</method>
<doc>
<tag name="shortdesc"><text>A non-visual base class for implementing sliders.</text></tag>
<text>
<p>
Baseslider is a non-visual representation of a slider.
</p>
</text>
</doc>
</class>
<class name="baseslidertrack" width="100%" height="${this.classroot.trackheight}" bgcolor="0x333333">
<method name="init">
super.init();
this.classroot.track = this;
</method>
</class>
<class name="basesliderthumb" extends="button" width="${this.parent.classroot.thumbwidth}" height="${this.parent.classroot.thumbheight}" onmousedown="this.thedragstate.setAttribute('applied', true);" onmouseup="this.thedragstate.setAttribute('applied', false);" focusable="false" x="0" y="${(this.parent.height - this.height) / 2}">
<attribute name="showvalue" value="${this.parent.parent.showvalue}"/>
<dragstate name="thedragstate" drag_axis="x">
<text name="t" resize="true" x="${(this.classroot.width / 2) - (this.width / 2)}" y="-14" text="${this.parent.parent.parent.presentValue()}" visible="${this.classroot.showvalue}" fgcolor="${this.classroot.style.textcolor}"/>
</dragstate>
<method name="_thumbFromValue">
var slider = this.parent.parent;
var delta = slider.maxvalue - slider.minvalue;
var perc = (delta == 0) ? 0 : (slider.value - slider.minvalue) / delta;
var pos = (slider.width - this.width) * perc;
return pos;
</method>
<method name="_valueFromThumb">
var slider = this.parent.parent;
var delta = slider.width - this.width;
var perc = (delta == 0) ? 0 : (this.x / (slider.width - this.width));
var val = Math.round((perc * (slider.maxvalue - slider.minvalue)) + slider.minvalue);
return val;
</method>
<setter name="x" args="x">
var boundedx = x;
var w = this.width;
var pwidth = this.parent.width;
if ( x > pwidth - w ) {
var constrainX = pwidth - w;
boundedx = constrainX;
} else {
var px = this.parent.x;
if (px > x) {
boundedx = px;
}
}
super.setAttribute('x', boundedx);
//update slider value
var slider = this.parent.parent;
if (slider.isinited) {
//set after slider is inited, see LPP-5710
var thumbVal = this._valueFromThumb();
if (thumbVal != slider.value) {
slider.setAttribute("value", thumbVal);
}
}
</setter>
</class>
</library>
Cross References
Includes
Classes