jh-componentj 0.2.0
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/LICENSE.md +21 -0
- package/README.md +61 -0
- package/dist/tvjs-xp.js +2375 -0
- package/dist/tvjs-xp.min.js +5 -0
- package/dist/tvjs-xp.min.js.LICENSE.txt +6 -0
- package/package.json +69 -0
- package/src/Main.vue +170 -0
- package/src/apps/App1.vue +71 -0
- package/src/apps/App2.vue +155 -0
- package/src/components/AppTag.vue +48 -0
- package/src/components/Chartbox.vue +87 -0
- package/src/components/Codepane.vue +260 -0
- package/src/components/Multiselect.vue +106 -0
- package/src/components/MyVueComponent.vue +26 -0
- package/src/components/StdInput.vue +70 -0
- package/src/components/Window.vue +95 -0
- package/src/components/dragg.js +32 -0
- package/src/extensions/chart-link/main.js +299 -0
- package/src/extensions/chart-link/shared.js +10 -0
- package/src/extensions/chart-link/utils.js +17 -0
- package/src/extensions/chart-link/x.json +11 -0
- package/src/extensions/grid-resize/Splitter.vue +80 -0
- package/src/extensions/grid-resize/main.js +152 -0
- package/src/extensions/grid-resize/utils.js +25 -0
- package/src/extensions/grid-resize/x.json +11 -0
- package/src/extensions/legend-buttons/AddWin.vue +91 -0
- package/src/extensions/legend-buttons/main.js +156 -0
- package/src/extensions/legend-buttons/x.json +11 -0
- package/src/extensions/settings-win/SettingsWin.vue +76 -0
- package/src/extensions/settings-win/main.js +39 -0
- package/src/extensions/settings-win/utils.js +19 -0
- package/src/extensions/settings-win/x.json +11 -0
- package/src/index.html +19 -0
- package/src/index_dev.js +27 -0
- package/src/index_prod.js +28 -0
- package/src/main.js +14 -0
- package/src/stuff/utils.js +16 -0
@@ -0,0 +1,299 @@
|
|
1
|
+
|
2
|
+
/* Example:
|
3
|
+
|
4
|
+
rules: {
|
5
|
+
'* -> *': {}, // From each to each
|
6
|
+
'*': { // The same as ^
|
7
|
+
cursor: true, // bool, 'X', 'Y', 'XY'
|
8
|
+
position: 'X', // bool, 'X', 'Y', 'XY'
|
9
|
+
tools: true
|
10
|
+
},
|
11
|
+
'trading-vue-1 -> trading-vue-2': {
|
12
|
+
data: [
|
13
|
+
'onchart.SMA',
|
14
|
+
'RSI4H',
|
15
|
+
{
|
16
|
+
from: 'chart.data',
|
17
|
+
to: 'datasets',
|
18
|
+
obj: {
|
19
|
+
id: 'small-tf-data',
|
20
|
+
type: 'SourceData'
|
21
|
+
}
|
22
|
+
}
|
23
|
+
]
|
24
|
+
},
|
25
|
+
'none': {
|
26
|
+
range: 'X', // bool, 'X', 'Y', 'XY'
|
27
|
+
}
|
28
|
+
}
|
29
|
+
*/
|
30
|
+
|
31
|
+
import Shared from './shared.js'
|
32
|
+
import Utils from './utils.js'
|
33
|
+
|
34
|
+
export default class Main {
|
35
|
+
|
36
|
+
constructor(tv, dc, sett) {
|
37
|
+
|
38
|
+
if (sett.use_window) {
|
39
|
+
if (!window.xchartlink$) {
|
40
|
+
window.xchartlink$ = {}
|
41
|
+
}
|
42
|
+
this.shared = window.xchartlink$
|
43
|
+
} else {
|
44
|
+
this.shared = Shared
|
45
|
+
}
|
46
|
+
|
47
|
+
this.tv = tv
|
48
|
+
this.dc = dc
|
49
|
+
this.sett = sett
|
50
|
+
this.targets = {}
|
51
|
+
|
52
|
+
this.onsettings({'chart-link': sett})
|
53
|
+
}
|
54
|
+
|
55
|
+
onsettings(all) {
|
56
|
+
clearTimeout(this.reset_id)
|
57
|
+
this.sett = all['chart-link']
|
58
|
+
if (!this.shared.rules) {
|
59
|
+
this.shared.rules = {}
|
60
|
+
this.shared.refs = {}
|
61
|
+
this.shared.meta = {}
|
62
|
+
}
|
63
|
+
|
64
|
+
let el = document.getElementById(this.tv.id)
|
65
|
+
|
66
|
+
if (this.sett.rules && el) {
|
67
|
+
this.shared.rules[this.tv.id] = this.sett.rules
|
68
|
+
}
|
69
|
+
|
70
|
+
this.shared.refs[this.tv.id] = this.tv
|
71
|
+
|
72
|
+
this.combine()
|
73
|
+
this.reset_id = setTimeout(() => this.reset())
|
74
|
+
}
|
75
|
+
|
76
|
+
// Combine rules from different instances
|
77
|
+
combine() {
|
78
|
+
this.shared.combined = {}
|
79
|
+
for (var id in this.shared.rules) {
|
80
|
+
for (var r in this.shared.rules[id]) {
|
81
|
+
this.shared.combined[r] =
|
82
|
+
this.shared.rules[id][r]
|
83
|
+
}
|
84
|
+
}
|
85
|
+
}
|
86
|
+
|
87
|
+
// Compile rules for this instance
|
88
|
+
compile() {
|
89
|
+
|
90
|
+
let gebcn = 'getElementsByClassName'
|
91
|
+
let els = [...document[gebcn]('trading-vue')]
|
92
|
+
this.targets = {}
|
93
|
+
|
94
|
+
for (let el of els) {
|
95
|
+
if (el.id === this.tv.id) continue
|
96
|
+
this.targets[el.id] = {}
|
97
|
+
}
|
98
|
+
|
99
|
+
let rules = this.rank(this.shared.combined)
|
100
|
+
|
101
|
+
for (var r of rules) {
|
102
|
+
let dst = r.pair[1]
|
103
|
+
if (dst === '*') {
|
104
|
+
dst = Object.keys(this.targets)
|
105
|
+
}
|
106
|
+
if (Array.isArray(dst)) {
|
107
|
+
for (var d of dst) {
|
108
|
+
if (!(d in this.targets)) continue
|
109
|
+
Object.assign(this.targets[d], r.r)
|
110
|
+
}
|
111
|
+
} else {
|
112
|
+
if (!(dst in this.targets)) continue
|
113
|
+
Object.assign(this.targets[dst], r.r)
|
114
|
+
}
|
115
|
+
}
|
116
|
+
}
|
117
|
+
|
118
|
+
// Select, rank & sort the rules
|
119
|
+
rank(rules) {
|
120
|
+
let out = []
|
121
|
+
for (var r in rules) {
|
122
|
+
let pair = this.splitr(r)
|
123
|
+
if (!this.matches(pair[0])) continue
|
124
|
+
if (pair[0] === '*') {
|
125
|
+
var rank = 20
|
126
|
+
} else if (Array.isArray(pair[0]) ) {
|
127
|
+
rank = 10
|
128
|
+
} else {
|
129
|
+
rank = 0
|
130
|
+
}
|
131
|
+
if (pair[1] === '*') {
|
132
|
+
rank += 2
|
133
|
+
} else if (Array.isArray(pair[1]) ) {
|
134
|
+
rank += 1
|
135
|
+
} else {
|
136
|
+
rank += 0
|
137
|
+
}
|
138
|
+
out.push({pair, rank, r: rules[r]})
|
139
|
+
}
|
140
|
+
return out.sort((a, b) => b.rank - a.rank)
|
141
|
+
}
|
142
|
+
|
143
|
+
// Check if the source of a rule matches tv.id
|
144
|
+
matches(src) {
|
145
|
+
return src === '*' || src === this.tv.id ||
|
146
|
+
(Array.isArray(src) && src.includes(this.tv.id))
|
147
|
+
}
|
148
|
+
|
149
|
+
splitr(rule) {
|
150
|
+
if (rule.trim() === '*') return ['*', '*']
|
151
|
+
return rule.split('->').map(x => {
|
152
|
+
let tup = x.split(',')
|
153
|
+
if (tup.length > 1) {
|
154
|
+
return tup.map(y => y.trim())
|
155
|
+
}
|
156
|
+
return x.trim()
|
157
|
+
})
|
158
|
+
|
159
|
+
}
|
160
|
+
|
161
|
+
// Apply all rules for this instance
|
162
|
+
reset() {
|
163
|
+
this.compile()
|
164
|
+
|
165
|
+
// Enable some chart hook events
|
166
|
+
this.tv.$refs.chart.hooks('xchanged')
|
167
|
+
|
168
|
+
|
169
|
+
this.tv.$watch(x => this.dc.get('.')
|
170
|
+
.filter(x => x.settings.$state),
|
171
|
+
this.ontools.bind(this))
|
172
|
+
|
173
|
+
}
|
174
|
+
|
175
|
+
// Listening to the Chart.vue hooks &
|
176
|
+
// other events
|
177
|
+
update(e) {
|
178
|
+
switch (e.event) {
|
179
|
+
case '?x-changed':
|
180
|
+
let cursor = e.args[0]
|
181
|
+
if (cursor.preventDefault) return
|
182
|
+
let main = this.tv.$refs.chart._layout.grids[cursor.grid_id]
|
183
|
+
let mc = this.tv.$refs.chart.cursor
|
184
|
+
cursor.t = mc.t
|
185
|
+
cursor.$ = mc.y$
|
186
|
+
for (var id in this.targets) {
|
187
|
+
let r = this.targets[id].cursor
|
188
|
+
if (r) {
|
189
|
+
let tv = this.shared.refs[id]
|
190
|
+
let g = tv.$refs.chart._layout.grids[0]
|
191
|
+
let xx = this.isX(r)
|
192
|
+
let yy = g.id === main.id && this.isY(r)
|
193
|
+
let upd = {
|
194
|
+
preventDefault: true,
|
195
|
+
x: xx ? g.t2screen(cursor.t) : -10,
|
196
|
+
y: yy ? g.$2screen(cursor.$) : -10,
|
197
|
+
grid_id: 0
|
198
|
+
}
|
199
|
+
tv.$refs.chart.cursor_changed(upd)
|
200
|
+
tv.$refs.chart.cursor.t = xx ? cursor.t : -10
|
201
|
+
tv.$refs.chart.cursor.y$ = yy ? cursor.$ : -10
|
202
|
+
}
|
203
|
+
}
|
204
|
+
break
|
205
|
+
case 'range-changed':
|
206
|
+
let now = new Date().getTime()
|
207
|
+
let meta = this.shared.meta[this.tv.id]
|
208
|
+
if (meta && meta.position) {
|
209
|
+
if (meta.position.lock > now) return
|
210
|
+
}
|
211
|
+
let range = e.args[0]
|
212
|
+
for (var id in this.targets) {
|
213
|
+
let r = this.targets[id].position
|
214
|
+
let tv = this.shared.refs[id]
|
215
|
+
let xx = this.isX(r)
|
216
|
+
let yy = this.isY(r)
|
217
|
+
if (!this.shared.meta[id]) {
|
218
|
+
this.shared.meta[id] = {}
|
219
|
+
}
|
220
|
+
// Prevents an infinite loop
|
221
|
+
this.shared.meta[id].position = {
|
222
|
+
lock: now + 100
|
223
|
+
}
|
224
|
+
if (xx) tv.goto(range[1])
|
225
|
+
}
|
226
|
+
break
|
227
|
+
}
|
228
|
+
}
|
229
|
+
|
230
|
+
ontools(n, p) {
|
231
|
+
let rem = Utils.removed(
|
232
|
+
n.map(x => x.settings.$uuid),
|
233
|
+
p.map(x => x.settings.$uuid)
|
234
|
+
)
|
235
|
+
let now = new Date().getTime()
|
236
|
+
let meta = this.shared.meta[this.tv.id]
|
237
|
+
if (meta && meta.tools) {
|
238
|
+
if (meta.tools.lock > now) return
|
239
|
+
}
|
240
|
+
for (var id in this.targets) {
|
241
|
+
let r = this.targets[id].tools
|
242
|
+
let tv = this.shared.refs[id]
|
243
|
+
if (r) {
|
244
|
+
if (!this.shared.meta[id]) {
|
245
|
+
this.shared.meta[id] = {}
|
246
|
+
}
|
247
|
+
// Prevents an infinite loop
|
248
|
+
this.shared.meta[id].tools = {
|
249
|
+
lock: now + 100
|
250
|
+
}
|
251
|
+
this.copy_tools(n, tv)
|
252
|
+
rem.forEach(r => tv.data.del(`${r}`))
|
253
|
+
}
|
254
|
+
}
|
255
|
+
}
|
256
|
+
|
257
|
+
copy_tools(n, tv) {
|
258
|
+
for (var tool of n) {
|
259
|
+
if (tool.id.includes('offchart')) continue
|
260
|
+
let uuid = tool.settings.$uuid
|
261
|
+
let exi = tv.data.get_one(`${uuid}`)
|
262
|
+
if (exi) {
|
263
|
+
tv.$set(exi, 'settings', Utils.copy(
|
264
|
+
tool.settings,
|
265
|
+
{
|
266
|
+
$selected: false,
|
267
|
+
$state: 'finished'
|
268
|
+
})
|
269
|
+
)
|
270
|
+
// TODO: maybe add a proper method
|
271
|
+
// of accessing overlays
|
272
|
+
let ovs = tv.$refs.chart.$refs.sec[0]
|
273
|
+
.$refs.grid
|
274
|
+
.$children.filter(x => x.tool)
|
275
|
+
|
276
|
+
for (var ov of ovs) {
|
277
|
+
ov.pins.forEach(x => x.re_init())
|
278
|
+
}
|
279
|
+
|
280
|
+
} else {
|
281
|
+
let copy = Utils.copy(tool)
|
282
|
+
copy.settings.$selected = false
|
283
|
+
copy.settings.$state = 'finished'
|
284
|
+
tv.data.add('onchart', copy)
|
285
|
+
}
|
286
|
+
}
|
287
|
+
}
|
288
|
+
|
289
|
+
isX(rule) {
|
290
|
+
return rule === true ||
|
291
|
+
(typeof rule === 'string' && rule.includes('X'))
|
292
|
+
}
|
293
|
+
|
294
|
+
isY(rule) {
|
295
|
+
return rule === true ||
|
296
|
+
(typeof rule === 'string' && rule.includes('Y'))
|
297
|
+
}
|
298
|
+
|
299
|
+
}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
export default {
|
2
|
+
|
3
|
+
copy(obj, mod) {
|
4
|
+
let copy = JSON.parse(JSON.stringify(obj))
|
5
|
+
return Object.assign(copy, mod)
|
6
|
+
},
|
7
|
+
|
8
|
+
removed(ids, prev) {
|
9
|
+
let list = []
|
10
|
+
for (var id of prev) {
|
11
|
+
if (!ids.includes(id)) {
|
12
|
+
list.push(id)
|
13
|
+
}
|
14
|
+
}
|
15
|
+
return list
|
16
|
+
}
|
17
|
+
}
|
@@ -0,0 +1,80 @@
|
|
1
|
+
<template>
|
2
|
+
<span class="h-splitter"
|
3
|
+
@mousedown="hs_mousedown" :style="hs_style">
|
4
|
+
</span>
|
5
|
+
</template>
|
6
|
+
<script>
|
7
|
+
|
8
|
+
import Utils from './utils.js'
|
9
|
+
|
10
|
+
export default {
|
11
|
+
name: 'Splitter',
|
12
|
+
props: ['id', 'main', 'dc', 'tv', 'data'],
|
13
|
+
mounted() {
|
14
|
+
this.MIN_HEIGHT = this.data.sett.min_height || 20
|
15
|
+
},
|
16
|
+
methods: {
|
17
|
+
hs_mousedown(e) {
|
18
|
+
this.drag = {
|
19
|
+
type: 'hs',
|
20
|
+
y: e.clientY,
|
21
|
+
h1: this.data.grid1.height,
|
22
|
+
h2: this.data.grid2.height
|
23
|
+
}
|
24
|
+
Utils.add_style('disable-user-select', `body * {
|
25
|
+
user-select: none;
|
26
|
+
}
|
27
|
+
.trading-vue-chart {
|
28
|
+
pointer-events: none;
|
29
|
+
}`)
|
30
|
+
},
|
31
|
+
hs_mouseup(e) {
|
32
|
+
this.drag = null
|
33
|
+
Utils.rem_style('disable-user-select')
|
34
|
+
},
|
35
|
+
hs_mousemove(e) {
|
36
|
+
if (this.drag) {
|
37
|
+
let off = e.clientY - this.drag.y
|
38
|
+
let new_h1 = this.drag.h1 + off
|
39
|
+
let new_h2 = this.drag.h2 - off
|
40
|
+
if (new_h1 > this.MIN_HEIGHT &&
|
41
|
+
new_h2 > this.MIN_HEIGHT) {
|
42
|
+
this.data.grid1.height = new_h1
|
43
|
+
this.data.grid2.height = new_h2
|
44
|
+
}
|
45
|
+
this.main.calc_heights()
|
46
|
+
}
|
47
|
+
},
|
48
|
+
hs_mouseleave(e) {
|
49
|
+
this.drag = null
|
50
|
+
Utils.rem_style('disable-user-select')
|
51
|
+
}
|
52
|
+
},
|
53
|
+
computed: {
|
54
|
+
hs_style() {
|
55
|
+
return {
|
56
|
+
drag: null,
|
57
|
+
top: this.data.grid2.offset + 'px',
|
58
|
+
//backgroundColor: this.colors.splitter
|
59
|
+
}
|
60
|
+
},
|
61
|
+
}
|
62
|
+
}
|
63
|
+
</script>
|
64
|
+
<style scoped>
|
65
|
+
.h-splitter {
|
66
|
+
position: absolute;
|
67
|
+
left: 0;
|
68
|
+
height: 5px;
|
69
|
+
margin-top: -2px;
|
70
|
+
width: 100%;
|
71
|
+
z-index: 1;
|
72
|
+
background-color: #3ee4afb5;
|
73
|
+
opacity: 0;
|
74
|
+
pointer-events: all;
|
75
|
+
}
|
76
|
+
.h-splitter:hover {
|
77
|
+
cursor: row-resize;
|
78
|
+
opacity: 1;
|
79
|
+
}
|
80
|
+
</style>
|
@@ -0,0 +1,152 @@
|
|
1
|
+
|
2
|
+
// Extension's controller
|
3
|
+
|
4
|
+
import { Utils } from 'trading-vue-js'
|
5
|
+
import Vue from 'vue'
|
6
|
+
import Splitter from './Splitter.vue'
|
7
|
+
|
8
|
+
export default class Main {
|
9
|
+
|
10
|
+
constructor(tv, dc, sett) {
|
11
|
+
|
12
|
+
this.widgets = {}
|
13
|
+
this.tv = tv
|
14
|
+
this.dc = dc
|
15
|
+
this.sett = sett
|
16
|
+
|
17
|
+
setTimeout(() => {
|
18
|
+
|
19
|
+
this.tv.$el.addEventListener(
|
20
|
+
'mousemove', this.onmousemove.bind(this)
|
21
|
+
)
|
22
|
+
|
23
|
+
this.tv.$el.addEventListener(
|
24
|
+
'mouseup', this.onmouseup.bind(this)
|
25
|
+
)
|
26
|
+
|
27
|
+
this.tv.$el.addEventListener(
|
28
|
+
'mouseleave', this.onmouseleave.bind(this)
|
29
|
+
)
|
30
|
+
|
31
|
+
this.place_splitters()
|
32
|
+
this.calc_heights()
|
33
|
+
|
34
|
+
// Track changes of grids count
|
35
|
+
this.tv.$watch(x =>
|
36
|
+
this.dc.get('.').map(x => x.id),
|
37
|
+
this.ongrids.bind(this))
|
38
|
+
|
39
|
+
})
|
40
|
+
|
41
|
+
}
|
42
|
+
|
43
|
+
// Listens to all tvjs events, creates new widgets
|
44
|
+
update(e) {
|
45
|
+
switch(e.event) {
|
46
|
+
|
47
|
+
}
|
48
|
+
}
|
49
|
+
|
50
|
+
// Extension settings has changed
|
51
|
+
onsettings(sett) {}
|
52
|
+
|
53
|
+
ongrids() {
|
54
|
+
setTimeout(() => {
|
55
|
+
this.remove_widgets()
|
56
|
+
this.place_splitters()
|
57
|
+
})
|
58
|
+
}
|
59
|
+
|
60
|
+
onmousemove(e) {
|
61
|
+
// List of widgets created by this controller
|
62
|
+
let list = this.tv.$refs.widgets.$children
|
63
|
+
.filter(x => x.main === this)
|
64
|
+
|
65
|
+
for (var s of list) {
|
66
|
+
s.hs_mousemove(e)
|
67
|
+
}
|
68
|
+
}
|
69
|
+
|
70
|
+
onmouseup(e) {
|
71
|
+
// List of widgets created by this controller
|
72
|
+
let list = this.tv.$refs.widgets.$children
|
73
|
+
.filter(x => x.main === this)
|
74
|
+
|
75
|
+
for (var s of list) {
|
76
|
+
s.hs_mouseup(e)
|
77
|
+
}
|
78
|
+
}
|
79
|
+
|
80
|
+
onmouseleave(e) {
|
81
|
+
// List of widgets created by this controller
|
82
|
+
let list = this.tv.$refs.widgets.$children
|
83
|
+
.filter(x => x.main === this)
|
84
|
+
|
85
|
+
for (var s of list) {
|
86
|
+
s.hs_mouseleave(e)
|
87
|
+
}
|
88
|
+
}
|
89
|
+
|
90
|
+
place_splitters() {
|
91
|
+
let grids = this.tv.$refs.chart._layout.grids
|
92
|
+
for (var i = 1; i < grids.length; i++) {
|
93
|
+
let g1 = grids[i-1]
|
94
|
+
let g2 = grids[i]
|
95
|
+
let id = `Splitter-${g1.id}-${g2.id}-${Utils.uuid2()}`
|
96
|
+
Vue.set(this.widgets, id, {
|
97
|
+
id: id,
|
98
|
+
cls: Splitter,
|
99
|
+
data: {
|
100
|
+
grid1: g1,
|
101
|
+
grid2: g2,
|
102
|
+
sett: this.sett
|
103
|
+
}
|
104
|
+
})
|
105
|
+
}
|
106
|
+
}
|
107
|
+
|
108
|
+
calc_heights() {
|
109
|
+
let hs = []
|
110
|
+
for (var g of this.tv.$refs.chart._layout.grids) {
|
111
|
+
hs.push(g.height)
|
112
|
+
}
|
113
|
+
let sum = hs.reduce((a, b) => a + b, 0)
|
114
|
+
hs = hs.map(h => h / sum)
|
115
|
+
this.grid_ovs().forEach((ov, i) => {
|
116
|
+
if (!ov.grid) {
|
117
|
+
Vue.set(ov, 'grid', {})
|
118
|
+
}
|
119
|
+
Vue.set(ov.grid, 'height', hs[i] || 1)
|
120
|
+
})
|
121
|
+
}
|
122
|
+
|
123
|
+
// Grid defining overlays
|
124
|
+
grid_ovs() {
|
125
|
+
let list = [this.dc.data.chart]
|
126
|
+
for (var ov of this.dc.data.offchart) {
|
127
|
+
if (!ov.grid || ov.grid.id === undefined) {
|
128
|
+
list.push(ov)
|
129
|
+
}
|
130
|
+
}
|
131
|
+
return list
|
132
|
+
}
|
133
|
+
|
134
|
+
remove_widgets() {
|
135
|
+
for (var id in this.widgets) {
|
136
|
+
this.tv.$delete(this.widgets, id)
|
137
|
+
}
|
138
|
+
}
|
139
|
+
|
140
|
+
destroy() {
|
141
|
+
this.tv.$el.removeEventListener(
|
142
|
+
'mousemove', this.onmousemove
|
143
|
+
)
|
144
|
+
this.tv.$el.removeEventListener(
|
145
|
+
'mouseup', this.mouseup
|
146
|
+
)
|
147
|
+
this.tv.$el.removeEventListener(
|
148
|
+
'mouseleave', this.mouseleave
|
149
|
+
)
|
150
|
+
}
|
151
|
+
|
152
|
+
}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
export default {
|
2
|
+
|
3
|
+
add_style(id, style) {
|
4
|
+
|
5
|
+
var stbr = document.getElementById(id)
|
6
|
+
if (stbr) {
|
7
|
+
var sheetParent = stbr.parentNode
|
8
|
+
sheetParent.removeChild(stbr)
|
9
|
+
}
|
10
|
+
|
11
|
+
var sheet = document.createElement('style')
|
12
|
+
sheet.setAttribute("id", id)
|
13
|
+
sheet.innerHTML = style
|
14
|
+
document.body.appendChild(sheet)
|
15
|
+
},
|
16
|
+
|
17
|
+
rem_style(id, style) {
|
18
|
+
var stbr = document.getElementById(id)
|
19
|
+
if (stbr) {
|
20
|
+
var sheetParent = stbr.parentNode
|
21
|
+
sheetParent.removeChild(stbr)
|
22
|
+
}
|
23
|
+
}
|
24
|
+
|
25
|
+
}
|
@@ -0,0 +1,91 @@
|
|
1
|
+
<template>
|
2
|
+
<window title="Add Overlay" class="add-win"
|
3
|
+
@close="on_close" :tv='tv'>
|
4
|
+
<div class="add-win-list">
|
5
|
+
<div v-for="ov of ovs" class="add-win-item"
|
6
|
+
@click="on_click(ov.name)">
|
7
|
+
<span>{{ov.name}}</span>
|
8
|
+
<span class="add-win-item-desc">
|
9
|
+
{{ov.methods.meta_info().desc}}
|
10
|
+
</span>
|
11
|
+
</div>
|
12
|
+
</div>
|
13
|
+
</window>
|
14
|
+
</template>
|
15
|
+
<script>
|
16
|
+
|
17
|
+
import Window from '../../components/Window.vue'
|
18
|
+
|
19
|
+
export default {
|
20
|
+
name: 'AddWin',
|
21
|
+
props: ['id', 'main', 'dc', 'tv', 'data'],
|
22
|
+
components: { Window },
|
23
|
+
mounted() {
|
24
|
+
},
|
25
|
+
methods: {
|
26
|
+
on_close() {
|
27
|
+
this.$props.main.remove_widget(this.$props.id)
|
28
|
+
},
|
29
|
+
on_click(name) {
|
30
|
+
this.on_close()
|
31
|
+
this.main.add_overlay({
|
32
|
+
side: this.data.type,
|
33
|
+
index: this.data.index,
|
34
|
+
type: name
|
35
|
+
})
|
36
|
+
}
|
37
|
+
},
|
38
|
+
computed: {
|
39
|
+
sett() {
|
40
|
+
return this.$props.data.ov.settings
|
41
|
+
}
|
42
|
+
},
|
43
|
+
data() {
|
44
|
+
return {
|
45
|
+
ovs: this.tv.overlays.filter(x => x.methods.calc)
|
46
|
+
}
|
47
|
+
}
|
48
|
+
}
|
49
|
+
</script>
|
50
|
+
<style scoped>
|
51
|
+
.tvjs-x-window.add-win {
|
52
|
+
padding-bottom: 30px;
|
53
|
+
border: 1px solid #80808011;
|
54
|
+
}
|
55
|
+
.add-win-list {
|
56
|
+
height: 300px;
|
57
|
+
overflow-x: hidden;
|
58
|
+
overflow-y: auto;
|
59
|
+
user-select: none;
|
60
|
+
}
|
61
|
+
/* Hide scrollbar for Chrome, Safari and Opera */
|
62
|
+
.add-win-list::-webkit-scrollbar {
|
63
|
+
display: none;
|
64
|
+
}
|
65
|
+
|
66
|
+
/* Hide scrollbar for IE, Edge and Firefox */
|
67
|
+
.add-win-list {
|
68
|
+
-ms-overflow-style: none; /* IE and Edge */
|
69
|
+
scrollbar-width: none; /* Firefox */
|
70
|
+
}
|
71
|
+
.add-win-item {
|
72
|
+
color: #ffffff88;
|
73
|
+
width: 100%;
|
74
|
+
padding: 5px;
|
75
|
+
cursor: pointer;
|
76
|
+
}
|
77
|
+
.add-win-item:hover {
|
78
|
+
background: #88888822;
|
79
|
+
color: #ffffffff;
|
80
|
+
}
|
81
|
+
.add-win-item-desc {
|
82
|
+
color: #ffffff33;
|
83
|
+
margin-left: 3px;
|
84
|
+
}
|
85
|
+
.add-win-item:hover .add-win-item-desc {
|
86
|
+
color: #ffffff44;
|
87
|
+
}
|
88
|
+
.add-win-empty {
|
89
|
+
opacity: 0.5;
|
90
|
+
}
|
91
|
+
</style>
|