diff --git a/src/graphics/slider-brackets.psd b/src/graphics/slider-brackets.psd index 705dc3277..3521aff12 100644 Binary files a/src/graphics/slider-brackets.psd and b/src/graphics/slider-brackets.psd differ diff --git a/src/main/java/com/metaweb/gridworks/browsing/facets/RangeFacet.java b/src/main/java/com/metaweb/gridworks/browsing/facets/RangeFacet.java index 24a42896b..c1c526242 100644 --- a/src/main/java/com/metaweb/gridworks/browsing/facets/RangeFacet.java +++ b/src/main/java/com/metaweb/gridworks/browsing/facets/RangeFacet.java @@ -23,7 +23,6 @@ public class RangeFacet implements Facet { protected String _name; // name of facet protected String _expression; // expression to compute numeric value(s) per row protected String _columnName; // column to base expression on, if any - protected String _mode; // "range", MIN, MAX protected double _from; // the numeric selection protected double _to; @@ -76,7 +75,6 @@ public class RangeFacet implements Facet { writer.key("name"); writer.value(_name); writer.key("expression"); writer.value(_expression); writer.key("columnName"); writer.value(_columnName); - writer.key("mode"); writer.value(_mode); if (_errorMessage != null) { writer.key("error"); writer.value(_errorMessage); @@ -98,14 +96,8 @@ public class RangeFacet implements Facet { } writer.endArray(); - if (MIN.equals(_mode)) { - writer.key(FROM); writer.value(_from); - } else if (MAX.equals(_mode)) { - writer.key(TO); writer.value(_to); - } else { - writer.key(FROM); writer.value(_from); - writer.key(TO); writer.value(_to); - } + writer.key(FROM); writer.value(_from); + writer.key(TO); writer.value(_to); } writer.key("baseNumericCount"); writer.value(_baseNumericCount); @@ -143,24 +135,9 @@ public class RangeFacet implements Facet { _errorMessage = e.getMessage(); } - _mode = o.getString("mode"); - if (MIN.equals(_mode)) { - if (o.has(FROM)) { - _from = o.getDouble(FROM); - _selected = true; - } - } else if (MAX.equals(_mode)) { - if (o.has(TO)) { - _to = o.getDouble(TO); - _selected = true; - } - } else { - if (o.has(FROM) && o.has(TO)) { - _from = o.getDouble(FROM); - _to = o.getDouble(TO); - _selected = true; - } - } + _from = o.getDouble(FROM); + _to = o.getDouble(TO); + _selected = true; _selectNumeric = JSONUtilities.getBoolean(o, "selectNumeric", true); _selectNonNumeric = JSONUtilities.getBoolean(o, "selectNonNumeric", true); @@ -174,31 +151,13 @@ public class RangeFacet implements Facet { public RowFilter getRowFilter() { if (_eval != null && _errorMessage == null && _selected) { - if (MIN.equals(_mode)) { - return new ExpressionNumberComparisonRowFilter( - _eval, _columnName, _cellIndex, _selectNumeric, _selectNonNumeric, _selectBlank, _selectError) { - - protected boolean checkValue(double d) { - return d >= _from; - }; + return new ExpressionNumberComparisonRowFilter( + _eval, _columnName, _cellIndex, _selectNumeric, _selectNonNumeric, _selectBlank, _selectError) { + + protected boolean checkValue(double d) { + return d >= _from && d < _to; }; - } else if (MAX.equals(_mode)) { - return new ExpressionNumberComparisonRowFilter( - _eval, _columnName, _cellIndex, _selectNumeric, _selectNonNumeric, _selectBlank, _selectError) { - - protected boolean checkValue(double d) { - return d < _to; - }; - }; - } else { - return new ExpressionNumberComparisonRowFilter( - _eval, _columnName, _cellIndex, _selectNumeric, _selectNonNumeric, _selectBlank, _selectError) { - - protected boolean checkValue(double d) { - return d >= _from && d < _to; - }; - }; - } + }; } else { return null; } diff --git a/src/main/webapp/images/slider-left-bracket.png b/src/main/webapp/images/slider-left-bracket.png index 50e896371..be02f6f01 100644 Binary files a/src/main/webapp/images/slider-left-bracket.png and b/src/main/webapp/images/slider-left-bracket.png differ diff --git a/src/main/webapp/images/slider-right-bracket.png b/src/main/webapp/images/slider-right-bracket.png index c4593c60e..ab956e9a2 100644 Binary files a/src/main/webapp/images/slider-right-bracket.png and b/src/main/webapp/images/slider-right-bracket.png differ diff --git a/src/main/webapp/project.html b/src/main/webapp/project.html index 38983e757..e07849d56 100644 --- a/src/main/webapp/project.html +++ b/src/main/webapp/project.html @@ -1 +1 @@ - Freebase Gridworks
starting up ...
\ No newline at end of file + Freebase Gridworks
starting up ...
\ No newline at end of file diff --git a/src/main/webapp/scripts/dialogs/clustering-dialog.js b/src/main/webapp/scripts/dialogs/clustering-dialog.js index 2a309f785..009ed95b5 100644 --- a/src/main/webapp/scripts/dialogs/clustering-dialog.js +++ b/src/main/webapp/scripts/dialogs/clustering-dialog.js @@ -476,31 +476,28 @@ ClusteringDialog.Facet = function(dialog, title, property, elmt, clusters) { elmt.addClass("clustering-dialog-facet"); var html = $( '
' + title + '
' + - '
' + - '
' + + '
' + + '
' + + '
' + '
' ).appendTo(elmt); this._elmts = DOM.bind(html); this._histogram = new HistogramWidget(this._elmts.histogramContainer, { binColors: [ "#ccccff", "#6666ff" ] }); - - this._elmts.slider.slider({ - min: this._min, - max: this._max, - values: [ this._from, this._to ], - slide: function(evt, ui) { - self._from = ui.values[0]; - self._to = ui.values[1]; - self._setRangeIndicators(); - }, - stop: function(evt, ui) { - self._from = ui.values[0]; - self._to = ui.values[1]; - self._setRangeIndicators(); - self._dialog._updateAll(); - } + this._sliderWidget = new SliderWidget(this._elmts.sliderWidgetDiv); + + this._elmts.sliderWidgetDiv.bind("slide", function(evt, data) { + self._from = data.from; + self._to = data.to; + self._setRangeIndicators(); + }).bind("stop", function(evt, data) { + self._from = data.from; + self._to = data.to; + self._setRangeIndicators(); + self._dialog._updateAll(); }); + this._setRangeIndicators(); } }; @@ -531,19 +528,23 @@ ClusteringDialog.Facet.prototype.update = function(clusters) { var bins = this._computeDistribution(clusters); + this._sliderWidget.update( + this._min, + this._max, + this._step, + this._from, + this._to + ); this._histogram.update( this._min, this._max, this._step, - [ this._baseBins, bins ], - this._from, - this._to + [ this._baseBins, bins ] ); }; ClusteringDialog.Facet.prototype._setRangeIndicators = function() { - this._histogram.highlight(this._from, this._to); - this._elmts.selectionContainer.text(this._from + " to " + this._to); + this._elmts.selectionContainer.html(this._from + " — " + this._to); }; ClusteringDialog.Facet.prototype._computeDistribution = function(clusters) { diff --git a/src/main/webapp/scripts/facets/range-facet.js b/src/main/webapp/scripts/facets/range-facet.js index d72630522..4288765cf 100644 --- a/src/main/webapp/scripts/facets/range-facet.js +++ b/src/main/webapp/scripts/facets/range-facet.js @@ -26,21 +26,16 @@ function RangeFacet(div, config, options) { } RangeFacet.prototype.reset = function() { - switch (this._config.mode) { - case "min": - this._from = this._config.min; - this._sliderDiv.slider("value", this._from); - break; - case "max": - this._to = this._config.max; - this._sliderDiv.slider("value", this._to); - break; - default: - this._from = this._config.min; - this._to = this._config.max; - this._sliderDiv.slider("values", 0, this._from); - this._sliderDiv.slider("values", 1, this._to); - } + this._from = this._config.min; + this._to = this._config.max; + this._sliderWidget.update( + this._config.min, + this._config.max, + this._config.step, + this._from, + this._to + ); + this._selectNumeric = true; this._selectNonNumeric = true; this._selectBlank = true; @@ -69,7 +64,6 @@ RangeFacet.prototype.getJSON = function() { var o = { type: "range", name: this._config.name, - mode: this._config.mode, expression: this._config.expression, columnName: this._config.columnName, selectNumeric: this._selectNumeric, @@ -78,15 +72,11 @@ RangeFacet.prototype.getJSON = function() { selectError: this._selectError }; - if (this._config.mode == "min" || this._config.mode == "range") { - if (this._from !== null) { - o.from = this._from; - } + if (this._from !== null) { + o.from = this._from; } - if (this._config.mode == "max" || this._config.mode == "range") { - if (this._to !== null) { - o.to = this._to; - } + if (this._to !== null) { + o.to = this._to; } return o; @@ -97,92 +87,59 @@ RangeFacet.prototype.hasSelection = function() { return true; } - switch (this._config.mode) { - case "min": - return this._from !== null && (!this._initializedUI || this._from > this._config.min); - case "max": - return this._to !== null && (!this._initializedUI || this._to < this._config.max); - default: - return (this._from !== null && (!this._initializedUI || this._from > this._config.min)) || - (this._to !== null && (!this._initializedUI || this._to < this._config.max)); - } + return (this._from !== null && (!this._initializedUI || this._from > this._config.min)) || + (this._to !== null && (!this._initializedUI || this._to < this._config.max)); }; RangeFacet.prototype._initializeUI = function() { var self = this; - var container = this._div.empty().show(); + this._div + .empty() + .show() + .html( + '
' + + '' + + 'reset' + + '' + + '
' + + '
' + + '
Loading...
' + + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + ); + this._elmts = DOM.bind(this._div); - var headerDiv = $('
').addClass("facet-title").appendTo(container); - $('').text(this._config.name).appendTo(headerDiv); - - var resetButton = $('').addClass("facet-choice-link").text("reset").click(function() { + this._elmts.facetTitle.text(this._config.name); + this._elmts.resetButton.click(function() { self.reset(); self._updateRest(); - }).prependTo(headerDiv); - - var removeButton = $('') - .attr("src", "images/close.png") - .attr("title", "Remove this facet") - .addClass("facet-choice-link") - .click(function() { + }); + this._elmts.removeButton.click(function() { self._remove(); - }).prependTo(headerDiv); + }); - var bodyDiv = $('
').addClass("facet-range-body").appendTo(container); + this._histogram = new HistogramWidget(this._elmts.histogramDiv, { binColors: [ "#ccccff", "#6666ff" ] }); + this._sliderWidget = new SliderWidget(this._elmts.sliderWidgetDiv); - this._messageDiv = $('
').text("Loading...").addClass("facet-range-message").appendTo(bodyDiv); - this._histogramDiv = $('
').addClass("facet-range-histogram").appendTo(bodyDiv); - this._sliderDiv = $('
').addClass("facet-range-slider").appendTo(bodyDiv); - this._statusDiv = $('
').addClass("facet-range-status").appendTo(bodyDiv); - this._otherChoicesDiv = $('
').addClass("facet-range-other-choices").appendTo(bodyDiv); - - this._histogram = new HistogramWidget(this._histogramDiv, { binColors: [ "#ccccff", "#6666ff" ] }); - - var onSlide = function(event, ui) { - switch (self._config.mode) { - case "min": - self._from = ui.value; - break; - case "max": - self._to = ui.value; - break; - default: - self._from = ui.values[0]; - self._to = ui.values[1]; - } + this._elmts.sliderWidgetDiv.bind("slide", function(evt, data) { + self._from = data.from; + self._to = data.to; self._setRangeIndicators(); - }; - var onStop = function() { + }).bind("stop", function(evt, data) { + self._from = data.from; + self._to = data.to; self._selectNumeric = true; self._updateRest(); - }; - var sliderConfig = { - min: this._config.min, - max: this._config.max, - stop: onStop, - slide: onSlide - }; - - switch (this._config.mode) { - case "min": - sliderConfig.range = "max"; - sliderConfig.value = this._config.min; - break; - case "max": - sliderConfig.range = "min"; - sliderConfig.value = this._config.max; - break; - default: - sliderConfig.range = true; - sliderConfig.values = [ this._config.min, this._config.max ]; - } - - this._sliderDiv.slider(sliderConfig); + }); }; RangeFacet.prototype._renderOtherChoices = function() { var self = this; - var container = this._otherChoicesDiv.empty(); + var container = this._elmts.otherChoicesDiv.empty(); if (this._baseNonNumericCount === 0 && this._baseBlankCount === 0 && this._baseErrorCount === 0) { return; @@ -274,20 +231,7 @@ RangeFacet.prototype._renderOtherChoices = function() { }; RangeFacet.prototype._setRangeIndicators = function() { - var text; - switch (this._config.mode) { - case "min": - text = "At least " + this._from; - break; - case "max": - text = "At most " + this._to; - break; - default: - text = this._from + " to " + this._to; - } - - this._statusDiv.text(text); - this._histogram.highlight(this._from, this._to); + this._elmts.statusDiv.html(this._from + " — " + this._to); }; RangeFacet.prototype.updateState = function(data) { @@ -340,31 +284,32 @@ RangeFacet.prototype.render = function() { } if (this._error) { - this._messageDiv.text(this._errorMessage).show(); - this._sliderDiv.hide(); - this._histogramDiv.hide(); - this._statusDiv.hide(); - this._otherChoicesDiv.hide(); + this._elmts.messageDiv.text(this._errorMessage).show(); + this._elmts.sliderWidgetDiv.hide(); + this._elmts.histogramDiv.hide(); + this._elmts.statusDiv.hide(); + this._elmts.otherChoicesDiv.hide(); return; } - this._messageDiv.hide(); - this._sliderDiv.show(); - this._histogramDiv.show(); - this._statusDiv.show(); - this._otherChoicesDiv.show(); - - this._sliderDiv.slider("option", "min", this._config.min); - this._sliderDiv.slider("option", "max", this._config.max); - this._sliderDiv.slider("option", "step", this._config.step); + this._elmts.messageDiv.hide(); + this._elmts.sliderWidgetDiv.show(); + this._elmts.histogramDiv.show(); + this._elmts.statusDiv.show(); + this._elmts.otherChoicesDiv.show(); + this._sliderWidget.update( + this._config.min, + this._config.max, + this._config.step, + this._from, + this._to + ); this._histogram.update( this._config.min, this._config.max, this._config.step, - [ this._baseBins, this._bins ], - this._from, - this._to + [ this._baseBins, this._bins ] ); this._setRangeIndicators(); diff --git a/src/main/webapp/scripts/widgets/histogram-widget.js b/src/main/webapp/scripts/widgets/histogram-widget.js index 5c08026e8..2713330a1 100644 --- a/src/main/webapp/scripts/widgets/histogram-widget.js +++ b/src/main/webapp/scripts/widgets/histogram-widget.js @@ -4,21 +4,18 @@ function HistogramWidget(elmt, options) { this._range = null; this._binMatrix = null; - this._highlight = null; this._initializeUI(); } -HistogramWidget.prototype.highlight = function(from, to) { - this._highlight = { from: from, to: to }; - this._update(); -}; - -HistogramWidget.prototype.update = function(min, max, step, binMatrix, from, to) { - if (typeof min == "undefined" || typeof binMatrix == "undefined" || binMatrix.length === 0 || binMatrix[0].length === 0) { +HistogramWidget.prototype.update = function(min, max, step, binMatrix) { + if (typeof min == "undefined" || + typeof binMatrix == "undefined" || + binMatrix.length === 0 || + binMatrix[0].length === 0) { + this._range = null; this._binMatrix = null; - this._highlight = null; this._elmt.hide(); } else { @@ -33,21 +30,12 @@ HistogramWidget.prototype.update = function(min, max, step, binMatrix, from, to) } } - if (typeof from != "undefined" && typeof to != "undefined") { - this._highlight = { from: from, to: to }; - } - this._update(); } }; HistogramWidget.prototype._update = function() { if (this._binMatrix !== null) { - if (this._highlight !== null) { - this._highlight.from = Math.max(this._highlight.from, this._range.min); - this._highlight.to = Math.min(this._highlight.to, this._range.max); - } - this._elmt.show(); this._resize(); this._render(); @@ -67,8 +55,11 @@ HistogramWidget.prototype._initializeUI = function() { }; HistogramWidget.prototype._resize = function() { - this._elmts.canvas.attr("height", "height" in this._options ? this._options.height : 50); + var height = "height" in this._options ? this._options.height : 50; + + this._elmts.canvas.attr("height", height); this._elmts.canvas.attr("width", this._elmts.canvas.width()); + this._elmt.height(height); }; HistogramWidget.prototype._render = function() { @@ -132,29 +123,5 @@ HistogramWidget.prototype._render = function() { ); } - /* - * Draw highlight - */ - if (this._highlight !== null) { - ctx.fillStyle = "rgba(192,192,192, 0.5)"; - ctx.globalCompositeOperation = "source-over"; - if (this._highlight.from > this._range.min) { - ctx.fillRect( - 0, - 0, - (this._highlight.from - this._range.min) * stepScale, - canvas.height - ); - } - if (this._highlight.to < this._range.max) { - ctx.fillRect( - (this._highlight.to - this._range.min) * stepScale, - 0, - canvas.width - (this._highlight.to - this._range.min) * stepScale, - canvas.height - ); - } - } - ctx.restore(); }; diff --git a/src/main/webapp/scripts/widgets/slider-widget.js b/src/main/webapp/scripts/widgets/slider-widget.js new file mode 100644 index 000000000..5717d0f74 --- /dev/null +++ b/src/main/webapp/scripts/widgets/slider-widget.js @@ -0,0 +1,180 @@ +function SliderWidget(elmt, options) { + this._elmt = elmt; + this._options = options || {}; + + this._range = { + min: 0, + max: 1, + step: 1, + from: 0, + to: 0 + }; + this._drag = null; + + this._initializeUI(); + this._update(); +} + +SliderWidget.prototype.update = function(min, max, step, from, to) { + if (step <= 0) { + step = 1; + } + max = Math.max(max, min + step); + from = Math.max(min, from); + to = Math.min(max, to); + + this._range = { + min: min, + max: max, + step: step, + from: from, + to: to + }; + this._update(); +} + +SliderWidget.prototype._initializeUI = function() { + this._elmt.addClass("slider-widget"); + + this._leftTintedRect = $("
").addClass("slider-widget-tint left").appendTo(this._elmt); + this._rightTintedRect = $("
").addClass("slider-widget-tint right").appendTo(this._elmt); + this._highlightRect = $("
").addClass("slider-widget-highlight slider-widget-draggable").attr("part", "highlight").appendTo(this._elmt); + this._leftBracket = $("
").addClass("slider-widget-bracket slider-widget-draggable left").attr("part", "left").appendTo(this._elmt); + this._rightBracket = $("
").addClass("slider-widget-bracket slider-widget-draggable right").attr("part", "right").appendTo(this._elmt); + + var self = this; + this._elmt.find(".slider-widget-draggable") + .mousedown(function(evt) { + return self._onMouseDown(evt, this.getAttribute("part")); + }); + + this._highlightRect.dblclick(function(evt) { + if (self._range.from > self._range.min || self._range.to < self._range.max) { + self._range.from = self._range.min; + self._range.to = self._range.max; + self._update(); + self._trigger("stop"); + } + }); + + this._elmt + .mousemove(function(evt) { + return self._onMouseMove(evt); + }) + .mouseup(function(evt) { + return self._onMouseUp(evt); + }); +}; + +SliderWidget.prototype._onMouseDown = function(evt, part) { + if (this._drag) { + return; + } + + this._drag = { + sureDrag: false + }; + if ("highlight" == part) { + this._drag.elmt = this._highlightRect; + this._drag.value = this._range.from; + } else if ("left" == part) { + this._drag.elmt = this._leftBracket; + } else if ("right" == part) { + this._drag.elmt = this._rightBracket; + } + this._drag.what = part; + this._drag.from = this._range.from; + this._drag.to = this._range.to; + this._drag.down = { + x: evt.pageX, + y: evt.pageY + }; +}; + +SliderWidget.prototype._onMouseUp = function(evt) { + if (!(this._drag)) { + return; + } + + if (this._drag.sureDrag) { + this._update(); + this._trigger("stop"); + } + this._drag = null; +}; + +SliderWidget.prototype._trigger = function(eventName) { + this._elmt.trigger(eventName, [{ from: this._range.from, to: this._range.to }]); +}; + +SliderWidget.prototype._onMouseMove = function(evt) { + if (!(this._drag)) { + return; + } + + var drag = this._drag; + var range = this._range; + + var offset = this._elmt.offset(); + var xDiff = evt.pageX - drag.down.x; + var yDiff = evt.pageX - drag.down.y; + + if (Math.abs(xDiff) >= 2) { + drag.sureDrag = true; + } + + var pixelWidth = this._elmt.width(); + var scale = pixelWidth / (range.max - range.min); + var vDiff = xDiff / scale; + + var adjustFrom = function() { + range.from = drag.from + Math.floor(vDiff / range.step) * range.step; + range.from = Math.max(Math.min(range.from, range.max), range.min); + }; + var adjustTo = function() { + range.to = drag.to + Math.floor(vDiff / range.step) * range.step; + range.to = Math.max(Math.min(range.to, range.max), range.min); + }; + + if (drag.what == "left") { + adjustFrom(); + range.to = Math.min(Math.max(range.to, range.from + range.step), range.max); + } else if (drag.what == "right") { + adjustTo(); + range.from = Math.max(Math.min(range.from, range.to - range.step), range.min); + } else { + adjustFrom(); + adjustTo(); + } + + this._update(); + this._trigger("slide"); + + evt.preventDefault(); + return false; +}; + +SliderWidget.prototype._update = function() { + var range = this._range; + + var pixelWidth = this._elmt.width(); + var scale = pixelWidth / (range.max - range.min); + var valueToPixel = function(x) { + return (x - range.min) * scale; + }; + + var fromPixel = Math.floor(valueToPixel(range.from)); + var toPixel = Math.floor(valueToPixel(range.to)); + + if (range.from == range.min && range.to == range.max) { + this._leftTintedRect.hide(); + this._rightTintedRect.hide(); + } else { + this._leftTintedRect.show().width(fromPixel); + this._rightTintedRect.show().width(pixelWidth - toPixel); + } + + this._highlightRect.css("left", (fromPixel - 1) + "px").width(toPixel - fromPixel); + this._leftBracket.css("left", fromPixel + "px"); + this._rightBracket.css("left", toPixel + "px"); +}; diff --git a/src/main/webapp/styles/dialogs/clustering-dialog.css b/src/main/webapp/styles/dialogs/clustering-dialog.css index a9230efd6..87c8cff95 100644 --- a/src/main/webapp/styles/dialogs/clustering-dialog.css +++ b/src/main/webapp/styles/dialogs/clustering-dialog.css @@ -64,11 +64,10 @@ table.clustering-dialog-entry-table a:hover { font-weight: bold; } .clustering-dialog-facet-histogram { - margin: 10px; overflow: hidden; } .clustering-dialog-facet-slider { - margin: 5px 10px; + margin: 5px; } .clustering-dialog-facet-selection { text-align: center; diff --git a/src/main/webapp/styles/project/browsing.css b/src/main/webapp/styles/project/browsing.css index 29e2a1457..0dd6585a2 100644 --- a/src/main/webapp/styles/project/browsing.css +++ b/src/main/webapp/styles/project/browsing.css @@ -143,21 +143,15 @@ img.facet-choice-link { color: #f88; } .facet-range-histogram { - margin: 10px 0px; overflow: hidden; } -.facet-range-slider.ui-corner-all { - border-bottom-left-radius: 0px 0px; - border-bottom-right-radius: 0px 0px; - border-top-left-radius: 0px 0px; - border-top-right-radius: 0px 0px; +.facet-range-slider { + margin: 0px; } - .facet-range-status { - margin: 10px 0; + margin: 5px 0; text-align: center; - color: #aaa; } .facet-text-body { diff --git a/src/main/webapp/styles/widgets/slider-widget.css b/src/main/webapp/styles/widgets/slider-widget.css new file mode 100644 index 000000000..c0a03ebeb --- /dev/null +++ b/src/main/webapp/styles/widgets/slider-widget.css @@ -0,0 +1,45 @@ +.slider-widget { + position: relative; + overflow: visible; + margin-left: 12px; + margin-right: 12px; +} + +.slider-widget-tint { + position: absolute; + top: 0px; + height: 100%; + background: black; + opacity: 0.4; + display: none; +} +.slider-widget-tint.left { + left: 0px; +} +.slider-widget-tint.right { + right: 0px; +} +.slider-widget-highlight { + position: absolute; + padding: 1px 0px; + border: 1px solid #faa; + top: -2px; + height: 100%; + cursor: move; +} +.slider-widget-bracket { + position: absolute; + width: 12px; + top: 0px; + height: 100%; +} +.slider-widget-bracket.left { + background: url(../../images/slider-left-bracket.png) no-repeat center right; + margin-left: -14px; + cursor: e-resize; +} +.slider-widget-bracket.right { + background: url(../../images/slider-right-bracket.png) no-repeat center left; + margin-left: 2px; + cursor: w-resize; +}