@qtoggle/qui 1.20.1 → 1.20.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/js/icons/multi-state-sprites-icon.js +59 -41
- package/js/utils/array.js +42 -6
- package/js/utils/css.js +15 -0
- package/js/utils/gestures.js +13 -11
- package/js/views/common-views/icon-label-view.js +22 -11
- package/js/widgets/common-widgets/combo.js +3 -2
- package/js/widgets/common-widgets/progress-disk.js +29 -17
- package/js/widgets/common-widgets/slider.js +6 -3
- package/package.json +1 -1
- package/pyproject.toml +1 -1
|
@@ -138,31 +138,40 @@ class MultiStateSpritesIcon extends Icon {
|
|
|
138
138
|
let bgWidth = params.bgWidth
|
|
139
139
|
let bgHeight = params.bgHeight
|
|
140
140
|
|
|
141
|
+
let iconElement = element[0]
|
|
142
|
+
|
|
141
143
|
/* Find and remove existing icon state elements */
|
|
142
|
-
let existingStateElements =
|
|
143
|
-
|
|
144
|
-
|
|
144
|
+
let existingStateElements = []
|
|
145
|
+
for (let i = 0; i < iconElement.children.length; i++) {
|
|
146
|
+
let child = iconElement.children[i]
|
|
147
|
+
let isState = child.className.split(' ').some(function (c) {
|
|
148
|
+
return c !== 'qui-icon-decoration' && c.startsWith('qui-icon-') && c.length > 'qui-icon-'.length
|
|
145
149
|
})
|
|
146
|
-
|
|
150
|
+
if (isState) {
|
|
151
|
+
existingStateElements.push(child)
|
|
152
|
+
}
|
|
153
|
+
}
|
|
147
154
|
|
|
148
|
-
|
|
149
|
-
|
|
155
|
+
if (iconElement.isConnected) {
|
|
156
|
+
/* Only this branch fades the old elements out, and only it needs them as a jQuery object */
|
|
157
|
+
let oldElements = $(existingStateElements)
|
|
150
158
|
asap(function () {
|
|
151
|
-
|
|
159
|
+
oldElements.addClass('qui-icon-hidden')
|
|
152
160
|
})
|
|
153
161
|
Theme.afterTransition(function () {
|
|
154
|
-
|
|
155
|
-
},
|
|
162
|
+
oldElements.remove()
|
|
163
|
+
}, oldElements)
|
|
156
164
|
}
|
|
157
165
|
else {
|
|
158
|
-
existingStateElements.remove()
|
|
166
|
+
existingStateElements.forEach(e => e.remove())
|
|
159
167
|
existingStateElements = []
|
|
160
168
|
}
|
|
161
169
|
|
|
162
|
-
|
|
170
|
+
iconElement.classList.add('qui-icon')
|
|
163
171
|
|
|
164
|
-
/* Add new icon state elements
|
|
165
|
-
|
|
172
|
+
/* Add new icon state elements. Built with plain DOM calls because this runs for every icon on screen, and
|
|
173
|
+
* jQuery's element, style and append helpers were about half of what renderTo cost on a 448-row list. */
|
|
174
|
+
let newElements = []
|
|
166
175
|
ObjectUtils.forEach(this._states, function (state, details) {
|
|
167
176
|
|
|
168
177
|
let offsetX = details.offsetX
|
|
@@ -173,35 +182,33 @@ class MultiStateSpritesIcon extends Icon {
|
|
|
173
182
|
return
|
|
174
183
|
}
|
|
175
184
|
|
|
176
|
-
let stateDiv =
|
|
185
|
+
let stateDiv = document.createElement('div')
|
|
186
|
+
stateDiv.className = `qui-icon-${state}`
|
|
177
187
|
/* If no existing elements, display the new element directly, w/o any effect; otherwise start hidden and
|
|
178
188
|
* do a transition to visible */
|
|
179
189
|
if (existingStateElements.length) {
|
|
180
|
-
stateDiv.
|
|
190
|
+
stateDiv.classList.add('qui-icon-hidden')
|
|
181
191
|
}
|
|
182
192
|
|
|
183
|
-
let
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
}
|
|
193
|
+
let style = stateDiv.style
|
|
194
|
+
style.backgroundImage = `url("${this._url}")`
|
|
195
|
+
style.backgroundPosition = `${(-offsetX * size)}${this._unit} ${(-offsetY * size)}${this._unit}`
|
|
187
196
|
if (bgWidth && bgHeight) {
|
|
188
|
-
|
|
197
|
+
style.backgroundSize = `${bgWidth} ${bgHeight}`
|
|
189
198
|
}
|
|
190
199
|
|
|
191
200
|
if (details.filter) {
|
|
192
|
-
|
|
201
|
+
style.filter = details.filter
|
|
193
202
|
}
|
|
194
203
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
element.append(stateDiv)
|
|
198
|
-
newElements = newElements.add(stateDiv)
|
|
204
|
+
iconElement.appendChild(stateDiv)
|
|
205
|
+
newElements.push(stateDiv)
|
|
199
206
|
|
|
200
207
|
}, this)
|
|
201
208
|
|
|
202
209
|
if (existingStateElements.length) {
|
|
203
210
|
asap(function () {
|
|
204
|
-
newElements.
|
|
211
|
+
newElements.forEach(e => e.classList.remove('qui-icon-hidden'))
|
|
205
212
|
})
|
|
206
213
|
}
|
|
207
214
|
|
|
@@ -212,19 +219,23 @@ class MultiStateSpritesIcon extends Icon {
|
|
|
212
219
|
}
|
|
213
220
|
}, this)
|
|
214
221
|
|
|
215
|
-
|
|
216
|
-
|
|
222
|
+
iconElement.classList.remove(...this.constructor.KNOWN_STATES.map(s => `top-${s}`))
|
|
223
|
+
iconElement.classList.add(`top-${topState}`)
|
|
217
224
|
|
|
218
225
|
/* Decoration */
|
|
219
226
|
|
|
220
|
-
let decorationDiv =
|
|
221
|
-
|
|
222
|
-
|
|
227
|
+
let decorationDiv = null
|
|
228
|
+
for (let i = 0; i < iconElement.children.length; i++) {
|
|
229
|
+
if (iconElement.children[i].classList.contains('qui-icon-decoration')) {
|
|
230
|
+
decorationDiv = iconElement.children[i]
|
|
231
|
+
break
|
|
232
|
+
}
|
|
223
233
|
}
|
|
224
234
|
|
|
225
235
|
if (!decorationDiv && this._decoration) {
|
|
226
|
-
decorationDiv =
|
|
227
|
-
|
|
236
|
+
decorationDiv = document.createElement('div')
|
|
237
|
+
decorationDiv.className = 'qui-icon-decoration'
|
|
238
|
+
iconElement.insertBefore(decorationDiv, iconElement.firstChild)
|
|
228
239
|
}
|
|
229
240
|
else if (decorationDiv && !this._decoration) {
|
|
230
241
|
decorationDiv.remove()
|
|
@@ -232,35 +243,42 @@ class MultiStateSpritesIcon extends Icon {
|
|
|
232
243
|
}
|
|
233
244
|
|
|
234
245
|
if (decorationDiv) {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
246
|
+
decorationDiv.style.background = this._decoration
|
|
247
|
+
|
|
248
|
+
/* The decoration element outlives a render, so a colour lookup can resolve after another icon has been
|
|
249
|
+
* applied to the same element. Each render stamps the element, and only the latest one may write. */
|
|
250
|
+
let renderToken = (decorationDiv._quiRenderToken = (decorationDiv._quiRenderToken || 0) + 1)
|
|
238
251
|
|
|
239
252
|
let bgColor = this._findBgColor(element)
|
|
240
253
|
let bgRGB = Colors.str2rgba(bgColor)
|
|
241
254
|
let decoRGB = Colors.str2rgba(this._decoration)
|
|
242
255
|
if (Colors.contrast(bgRGB, decoRGB) > 1.5) {
|
|
243
|
-
|
|
256
|
+
decorationDiv.style.borderColor = bgColor
|
|
244
257
|
}
|
|
245
258
|
else {
|
|
246
259
|
this._findIconColor(element).then(function (color) {
|
|
247
|
-
|
|
260
|
+
if (decorationDiv._quiRenderToken === renderToken) {
|
|
261
|
+
decorationDiv.style.borderColor = color
|
|
262
|
+
}
|
|
248
263
|
})
|
|
249
264
|
}
|
|
250
|
-
|
|
251
|
-
decorationDiv.css(css)
|
|
252
265
|
}
|
|
253
266
|
}
|
|
254
267
|
|
|
255
268
|
_findBgColor(elem) {
|
|
256
269
|
/* Find the background color behind the icon */
|
|
257
270
|
|
|
271
|
+
/* Icons are usually rendered before their row is attached, and a detached element has no computed style, so
|
|
272
|
+
* up such a chain css() only ever reports the inline one. Reading that directly skips a getComputedStyle call
|
|
273
|
+
* per element, worth about 130 ms across a 448-row list. */
|
|
274
|
+
let attached = elem.length > 0 && elem[0].isConnected
|
|
275
|
+
|
|
258
276
|
let e = elem
|
|
259
277
|
let bgColor = null
|
|
260
278
|
while (e.length && e[0].tagName && (!bgColor || bgColor === 'rgba(0, 0, 0, 0)' ||
|
|
261
279
|
bgColor === 'transparent')) {
|
|
262
280
|
|
|
263
|
-
bgColor = e.css('background-color')
|
|
281
|
+
bgColor = attached ? e.css('background-color') : e[0].style.backgroundColor
|
|
264
282
|
e = e.parent()
|
|
265
283
|
}
|
|
266
284
|
|
package/js/utils/array.js
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
* @namespace qui.utils.array
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
function
|
|
6
|
-
return function (
|
|
7
|
-
let k1 =
|
|
8
|
-
let k2 =
|
|
5
|
+
function makeKeySortFunc(desc) {
|
|
6
|
+
return function (p1, p2) {
|
|
7
|
+
let k1 = p1.key
|
|
8
|
+
let k2 = p2.key
|
|
9
9
|
|
|
10
10
|
if ((desc && k1 > k2) || (!desc && k1 < k2)) {
|
|
11
11
|
return -1
|
|
@@ -19,6 +19,36 @@ function makeSortFunc(extractFunc, desc, thisArg) {
|
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
/* The sort runs over element-key pairs, so the key function runs once per element instead of twice for every
|
|
23
|
+
* comparison the sort makes. Sorting 448 items in random order took 6408 key extractions; this brings it to 448. */
|
|
24
|
+
function sortPairs(array, func, desc, thisArg, sortFunc) {
|
|
25
|
+
/* Each element carries its own key instead of the two being matched up in a Map, which would file 0 and -0 under
|
|
26
|
+
* one entry. Undefined entries and holes are held back and restored at the end, as Array#sort leaves them. */
|
|
27
|
+
let length = array.length
|
|
28
|
+
let pairs = []
|
|
29
|
+
let undefinedCount = 0
|
|
30
|
+
|
|
31
|
+
array.forEach(function (e) {
|
|
32
|
+
if (e === undefined) {
|
|
33
|
+
undefinedCount++
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
pairs.push({element: e, key: func.call(thisArg, e)})
|
|
37
|
+
}
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
sortFunc(pairs, makeKeySortFunc(desc))
|
|
41
|
+
|
|
42
|
+
array.length = 0
|
|
43
|
+
pairs.forEach(p => array.push(p.element))
|
|
44
|
+
while (undefinedCount--) {
|
|
45
|
+
array.push(undefined)
|
|
46
|
+
}
|
|
47
|
+
array.length = length
|
|
48
|
+
|
|
49
|
+
return array
|
|
50
|
+
}
|
|
51
|
+
|
|
22
52
|
function merge(left, right, compareFunc) {
|
|
23
53
|
let result = []
|
|
24
54
|
|
|
@@ -94,6 +124,9 @@ export function stableSort(array, compareFunc) {
|
|
|
94
124
|
|
|
95
125
|
/**
|
|
96
126
|
* Perform a sort on an array, *in place*, using a key extraction function.
|
|
127
|
+
*
|
|
128
|
+
* As with `Array#sort`, `undefined` entries and holes end up at the end of the array, in that order, and the key
|
|
129
|
+
* extraction function is not called for them. It is called once per remaining element.
|
|
97
130
|
* @alias qui.utils.array.sortKey
|
|
98
131
|
* @param {Array} array
|
|
99
132
|
* @param {Function} func key extraction function; will be called with each element as parameter and is expected to
|
|
@@ -103,11 +136,14 @@ export function stableSort(array, compareFunc) {
|
|
|
103
136
|
* @returns {Array} the array
|
|
104
137
|
*/
|
|
105
138
|
export function sortKey(array, func, desc = false, thisArg = null) {
|
|
106
|
-
return array
|
|
139
|
+
return sortPairs(array, func, desc, thisArg, (pairs, compareFunc) => pairs.sort(compareFunc))
|
|
107
140
|
}
|
|
108
141
|
|
|
109
142
|
/**
|
|
110
143
|
* Perform a stable sort on an array, *in place*, using a key extraction function.
|
|
144
|
+
*
|
|
145
|
+
* As with `Array#sort`, `undefined` entries and holes end up at the end of the array, in that order, and the key
|
|
146
|
+
* extraction function is not called for them. It is called once per remaining element.
|
|
111
147
|
* @alias qui.utils.array.stableSortKey
|
|
112
148
|
* @param {Array} array
|
|
113
149
|
* @param {Function} func key extraction function; will be called with each element as parameter and is expected to
|
|
@@ -117,7 +153,7 @@ export function sortKey(array, func, desc = false, thisArg = null) {
|
|
|
117
153
|
* @returns {Array} the array
|
|
118
154
|
*/
|
|
119
155
|
export function stableSortKey(array, func, desc = false, thisArg = null) {
|
|
120
|
-
return
|
|
156
|
+
return sortPairs(array, func, desc, thisArg, stableSort)
|
|
121
157
|
}
|
|
122
158
|
|
|
123
159
|
/**
|
package/js/utils/css.js
CHANGED
|
@@ -238,3 +238,18 @@ export function px2em(px, elem = Window.$body) {
|
|
|
238
238
|
|
|
239
239
|
return width
|
|
240
240
|
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Convert a length from visual pixels to CSS pixels.
|
|
244
|
+
*
|
|
245
|
+
* Pointer event coordinates and `getBoundingClientRect()` values (so also jQuery's `offset()` and `position()`) are
|
|
246
|
+
* visual pixels -- they include the scaling factor applied to the body. CSS lengths, *em* units, `offsetWidth` and
|
|
247
|
+
* jQuery's `width()` are CSS pixels. Mixing the two is only safe when the scaling factor is `1`.
|
|
248
|
+
*
|
|
249
|
+
* @alias qui.utils.css.unscalePx
|
|
250
|
+
* @param {Number} px
|
|
251
|
+
* @returns {Number}
|
|
252
|
+
*/
|
|
253
|
+
export function unscalePx(px) {
|
|
254
|
+
return px / Window.getScalingFactor()
|
|
255
|
+
}
|
package/js/utils/gestures.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import $ from '$qui/lib/jquery.module.js'
|
|
6
6
|
|
|
7
|
+
import * as CSS from '$qui/utils/css.js'
|
|
7
8
|
import * as Window from '$qui/window.js'
|
|
8
9
|
|
|
9
10
|
|
|
@@ -44,6 +45,10 @@ const LONG_PRESS_DATA_KEY = 'qui.utils.gestures.longPress'
|
|
|
44
45
|
|
|
45
46
|
/**
|
|
46
47
|
* Setup an HTML element for dragging.
|
|
48
|
+
*
|
|
49
|
+
* All coordinates passed to the callbacks are CSS pixels, so they can be compared or combined with *em* units and CSS
|
|
50
|
+
* lengths directly. Use {@link qui.utils.css.unscalePx} on any `offset()` or `position()` value measured against them.
|
|
51
|
+
*
|
|
47
52
|
* @alias qui.utils.gestures.enableDragging
|
|
48
53
|
* @param {jQuery} element the dragged element
|
|
49
54
|
* @param {qui.utils.gestures.DragMoveCallback} onMove
|
|
@@ -81,12 +86,11 @@ export function enableDragging(element, onMove, onBegin, onEnd, direction) {
|
|
|
81
86
|
|
|
82
87
|
function pointerDown(e) {
|
|
83
88
|
let elemOffset = element.offset()
|
|
84
|
-
beginElemX = elemOffset.left
|
|
85
|
-
beginElemY = elemOffset.top
|
|
89
|
+
beginElemX = CSS.unscalePx(elemOffset.left)
|
|
90
|
+
beginElemY = CSS.unscalePx(elemOffset.top)
|
|
86
91
|
|
|
87
|
-
|
|
88
|
-
e.
|
|
89
|
-
e.pageY /= scalingFactor
|
|
92
|
+
e.pageX = CSS.unscalePx(e.pageX)
|
|
93
|
+
e.pageY = CSS.unscalePx(e.pageY)
|
|
90
94
|
|
|
91
95
|
beginPageX = e.pageX
|
|
92
96
|
beginPageY = e.pageY
|
|
@@ -109,9 +113,8 @@ export function enableDragging(element, onMove, onBegin, onEnd, direction) {
|
|
|
109
113
|
* where the pointer actually was, before it is told the drag is over */
|
|
110
114
|
flushMove()
|
|
111
115
|
|
|
112
|
-
|
|
113
|
-
e.
|
|
114
|
-
e.pageY /= scalingFactor
|
|
116
|
+
e.pageX = CSS.unscalePx(e.pageX)
|
|
117
|
+
e.pageY = CSS.unscalePx(e.pageY)
|
|
115
118
|
|
|
116
119
|
if (direction === 'x') { /* Constrain moving to horizontal axis */
|
|
117
120
|
e.pageY = beginPageY
|
|
@@ -135,9 +138,8 @@ export function enableDragging(element, onMove, onBegin, onEnd, direction) {
|
|
|
135
138
|
}
|
|
136
139
|
|
|
137
140
|
function pointerMove(e) {
|
|
138
|
-
|
|
139
|
-
e.
|
|
140
|
-
e.pageY /= scalingFactor
|
|
141
|
+
e.pageX = CSS.unscalePx(e.pageX)
|
|
142
|
+
e.pageY = CSS.unscalePx(e.pageY)
|
|
141
143
|
|
|
142
144
|
if (direction === 'x') { /* Constrain moving to horizontal axis */
|
|
143
145
|
e.pageY = beginPageY
|
|
@@ -40,28 +40,39 @@ const IconLabelViewMixin = Mixin((superclass = Object) => {
|
|
|
40
40
|
* @returns {jQuery}
|
|
41
41
|
*/
|
|
42
42
|
makeIconLabelContainer() {
|
|
43
|
-
|
|
43
|
+
/* Built with plain DOM calls: five elements per view, and jQuery's element and append helpers were about
|
|
44
|
+
* a fifth of what the hub's 448-row port list cost to build. The three elements kept as fields stay
|
|
45
|
+
* jQuery objects, because the icon and label setters work on them. */
|
|
46
|
+
let container = document.createElement('div')
|
|
47
|
+
container.className = 'qui-icon-label-view'
|
|
44
48
|
|
|
45
49
|
if (this._clickable) {
|
|
46
|
-
container.
|
|
50
|
+
container.classList.add('qui-base-button')
|
|
47
51
|
}
|
|
48
52
|
|
|
49
|
-
|
|
53
|
+
let iconElement = document.createElement('div')
|
|
54
|
+
iconElement.className = 'qui-icon'
|
|
55
|
+
this._iconElement = $(iconElement)
|
|
50
56
|
this._applyIcon(this._icon, this._iconElement)
|
|
51
|
-
container.
|
|
57
|
+
container.appendChild(iconElement)
|
|
52
58
|
|
|
53
|
-
let labelsContainer =
|
|
54
|
-
|
|
59
|
+
let labelsContainer = document.createElement('div')
|
|
60
|
+
labelsContainer.className = 'labels'
|
|
61
|
+
container.appendChild(labelsContainer)
|
|
55
62
|
|
|
56
|
-
|
|
63
|
+
let labelElement = document.createElement('div')
|
|
64
|
+
labelElement.className = 'label'
|
|
65
|
+
this._labelElement = $(labelElement)
|
|
57
66
|
this.setLabel(this._label)
|
|
58
|
-
labelsContainer.
|
|
67
|
+
labelsContainer.appendChild(labelElement)
|
|
59
68
|
|
|
60
|
-
|
|
69
|
+
let subLabelElement = document.createElement('div')
|
|
70
|
+
subLabelElement.className = 'sub-label'
|
|
71
|
+
this._subLabelElement = $(subLabelElement)
|
|
61
72
|
this.setSubLabel(this._subLabel)
|
|
62
|
-
labelsContainer.
|
|
73
|
+
labelsContainer.appendChild(subLabelElement)
|
|
63
74
|
|
|
64
|
-
return container
|
|
75
|
+
return $(container)
|
|
65
76
|
}
|
|
66
77
|
|
|
67
78
|
/**
|
|
@@ -3,6 +3,7 @@ import $ from '$qui/lib/jquery.module.js'
|
|
|
3
3
|
|
|
4
4
|
import {gettext} from '$qui/base/i18n.js'
|
|
5
5
|
import * as Theme from '$qui/theme.js'
|
|
6
|
+
import * as CSS from '$qui/utils/css.js'
|
|
6
7
|
import {asap} from '$qui/utils/misc.js'
|
|
7
8
|
import * as ObjectUtils from '$qui/utils/object.js'
|
|
8
9
|
import * as PromiseUtils from '$qui/utils/promise.js'
|
|
@@ -370,7 +371,7 @@ $.widget('qui.combo', $.qui.basewidget, {
|
|
|
370
371
|
this._prevItemDiv = this._itemContainer.children('div.qui-combo-item.selected')
|
|
371
372
|
|
|
372
373
|
if (this._prevItemDiv.length) {
|
|
373
|
-
let scrollTop = this._prevItemDiv.offset().top - this._itemContainer.offset().top +
|
|
374
|
+
let scrollTop = CSS.unscalePx(this._prevItemDiv.offset().top - this._itemContainer.offset().top) +
|
|
374
375
|
this._itemContainer.scrollTop()
|
|
375
376
|
this._itemContainer.scrollTop(scrollTop)
|
|
376
377
|
}
|
|
@@ -534,7 +535,7 @@ $.widget('qui.combo', $.qui.basewidget, {
|
|
|
534
535
|
if (itemDiv) {
|
|
535
536
|
itemDiv.addClass('selected')
|
|
536
537
|
if (scroll) {
|
|
537
|
-
let scrollTop = itemDiv.offset().top - this._itemContainer.offset().top +
|
|
538
|
+
let scrollTop = CSS.unscalePx(itemDiv.offset().top - this._itemContainer.offset().top) +
|
|
538
539
|
this._itemContainer.scrollTop()
|
|
539
540
|
this._itemContainer.scrollTop(scrollTop)
|
|
540
541
|
}
|
|
@@ -113,23 +113,35 @@ $.widget('qui.progressdisk', $.qui.basewidget, {
|
|
|
113
113
|
let iRadius = oRadius - thickness / 2
|
|
114
114
|
let color = Theme.getColor(this.options.color)
|
|
115
115
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
this.
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
116
|
+
/* This runs on every value change, but the size only follows the radius option. jQuery's width() and height()
|
|
117
|
+
* each read the computed style, which came to about 400 ms while a 448-row list was being built. */
|
|
118
|
+
if (this._appliedWidth !== width) {
|
|
119
|
+
this._appliedWidth = width
|
|
120
|
+
|
|
121
|
+
this.element.width(width)
|
|
122
|
+
this.element.height(width)
|
|
123
|
+
this.element.css('line-height', width)
|
|
124
|
+
|
|
125
|
+
this._svg.setAttribute('width', width)
|
|
126
|
+
this._svg.setAttribute('height', width)
|
|
127
|
+
this._svg.setAttribute('viewBox', `0 0 ${fWidth} ${fWidth}`)
|
|
128
|
+
|
|
129
|
+
this._ring.setAttribute('cx', oRadius.toString())
|
|
130
|
+
this._ring.setAttribute('cy', oRadius.toString())
|
|
131
|
+
this._ring.setAttribute('rx', iRadius.toString())
|
|
132
|
+
this._ring.setAttribute('ry', iRadius.toString())
|
|
133
|
+
this._ring.setAttribute('stroke-width', thickness.toString())
|
|
134
|
+
|
|
135
|
+
this._cursor.setAttribute('stroke-width', thickness.toString())
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/* The colour is still looked up every time, so a theme change lands on the next value. */
|
|
139
|
+
if (this._appliedColor !== color) {
|
|
140
|
+
this._appliedColor = color
|
|
141
|
+
|
|
142
|
+
this._ring.setAttribute('stroke', color)
|
|
143
|
+
this._cursor.setAttribute('stroke', color)
|
|
144
|
+
}
|
|
133
145
|
|
|
134
146
|
if (this._curVal >= 0) {
|
|
135
147
|
this._updateSVGPercent(iRadius, oRadius)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
|
|
2
2
|
import $ from '$qui/lib/jquery.module.js'
|
|
3
3
|
|
|
4
|
+
import * as CSS from '$qui/utils/css.js'
|
|
4
5
|
import * as Gestures from '$qui/utils/gestures.js'
|
|
5
6
|
|
|
6
7
|
import * as BaseWidget from '../base-widget.js' /* Needed */
|
|
@@ -68,8 +69,8 @@ $.widget('qui.slider', $.qui.basewidget, {
|
|
|
68
69
|
return
|
|
69
70
|
}
|
|
70
71
|
|
|
71
|
-
let
|
|
72
|
-
let pos = pageX -
|
|
72
|
+
let barLeft = CSS.unscalePx(widget._bar.offset().left)
|
|
73
|
+
let pos = pageX - barLeft
|
|
73
74
|
pos = pos / widget._getWidth()
|
|
74
75
|
pos = widget._bestPos(pos)
|
|
75
76
|
|
|
@@ -233,7 +234,9 @@ $.widget('qui.slider', $.qui.basewidget, {
|
|
|
233
234
|
},
|
|
234
235
|
|
|
235
236
|
_getPos: function () {
|
|
236
|
-
|
|
237
|
+
/* Deduced from the current value, rather than measured: the cursor is placed with a percentage and a negative
|
|
238
|
+
* margin, which no measurement reads back cleanly under a scaling factor */
|
|
239
|
+
return this._valToPos(this._curVal)
|
|
237
240
|
},
|
|
238
241
|
|
|
239
242
|
_setPos: function (pos) {
|
package/package.json
CHANGED