@nebularstreams/libmui 2.0.13 → 2.0.15
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/dist/libui.css +1 -1
- package/dist/libui.esm.js +1 -1
- package/dist/libui.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/index.js +66 -5
- package/src/meta/Emojis.js +32136 -0
- package/src/meta/FontAwesome.js +8012 -0
- package/src/meta/InputTemplates.js +3 -0
- package/src/util/colorjoe.js +1371 -0
- package/src/util/tainter.js +31 -0
- package/src/util/util.tokenizer.js +34 -1
- package/src/widgets/ButtonChoiceWidget.js +72 -0
- package/src/widgets/ColorJoeWidget.js +144 -0
- package/src/widgets/ComboWidget.js +155 -0
- package/src/widgets/CoolContentTicker.js +239 -0
- package/src/widgets/EmptyButton.js +39 -0
- package/src/widgets/FontSelectorButton.js +36 -0
- package/src/widgets/PlusMinusWidget.js +55 -0
- package/src/widgets/SelectFileMiniButton.js +194 -0
- package/src/widgets/SmileysButton.js +18 -0
- package/src/widgets/SmileysPanel.js +20 -0
- package/src/widgets/SmileysWidget.js +199 -0
- package/src/widgets/TemplatedInputWidget.js +1219 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import m from "mithril";
|
|
2
|
+
|
|
3
|
+
let
|
|
4
|
+
gTainted = false;
|
|
5
|
+
|
|
6
|
+
function taint() {
|
|
7
|
+
gTainted = true;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function taintRedraw() {
|
|
11
|
+
const r = gTainted;
|
|
12
|
+
gTainted = true;
|
|
13
|
+
// eslint-disable-next-line no-unused-expressions
|
|
14
|
+
r && m.redraw();
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function isTainted() {
|
|
18
|
+
return gTainted;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function untaint() {
|
|
22
|
+
gTainted = false;
|
|
23
|
+
m.redraw();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export {
|
|
27
|
+
taint,
|
|
28
|
+
taintRedraw,
|
|
29
|
+
isTainted,
|
|
30
|
+
untaint
|
|
31
|
+
};
|
|
@@ -216,6 +216,37 @@ function tokenizeUrl(tokenizedUrl, parameters, options) {
|
|
|
216
216
|
}
|
|
217
217
|
}
|
|
218
218
|
|
|
219
|
+
function sanitizeFilename(filename) {
|
|
220
|
+
return filename ? filename.trim()
|
|
221
|
+
.toLowerCase()
|
|
222
|
+
.replace(/[^0-9A-Z.-]+/gi, "") : null;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
const generateFilename = (url, prefix = undefined) => {
|
|
227
|
+
|
|
228
|
+
const
|
|
229
|
+
dateCode = parseInt(md5(url)
|
|
230
|
+
.substring(24), 16)
|
|
231
|
+
.toString(32);
|
|
232
|
+
|
|
233
|
+
return (prefix ? sanitizeFilename(prefix) + "-" : "") + dateCode;
|
|
234
|
+
|
|
235
|
+
}; // 2025 --- 24 years layer i'm 50 ! I wonder about my past self ...
|
|
236
|
+
|
|
237
|
+
const Tokenizer = {
|
|
238
|
+
tokenize,
|
|
239
|
+
tokenizeStrict,
|
|
240
|
+
tokenizeObject,
|
|
241
|
+
tokenizeKeep,
|
|
242
|
+
tokenizeWithDefault,
|
|
243
|
+
tokenizeUrl,
|
|
244
|
+
getPointedData,
|
|
245
|
+
sanitizeFilename,
|
|
246
|
+
generateFilename
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
export default Tokenizer;
|
|
219
250
|
export {
|
|
220
251
|
tokenize,
|
|
221
252
|
tokenizeStrict,
|
|
@@ -223,5 +254,7 @@ export {
|
|
|
223
254
|
tokenizeKeep,
|
|
224
255
|
tokenizeWithDefault,
|
|
225
256
|
tokenizeUrl,
|
|
226
|
-
getPointedData
|
|
257
|
+
getPointedData,
|
|
258
|
+
sanitizeFilename,
|
|
259
|
+
generateFilename
|
|
227
260
|
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import m from "mithril";
|
|
2
|
+
import {ButtonNew, defineWidget} from "./Basic";
|
|
3
|
+
import Separator from "./Separator"
|
|
4
|
+
|
|
5
|
+
const
|
|
6
|
+
|
|
7
|
+
/*
|
|
8
|
+
SizeChoices = {
|
|
9
|
+
"1080p": {width: 1920, height: 1080, value: "1080p"},
|
|
10
|
+
"720p": {width: 1280, height: 720, value: "720p"},
|
|
11
|
+
"Fluid": {width: null, height: null, value: "Fluid"},
|
|
12
|
+
"Custom": {value: ""}
|
|
13
|
+
}
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
ButtonChoiceWidget = defineWidget(
|
|
17
|
+
({attrs}) => {
|
|
18
|
+
|
|
19
|
+
const
|
|
20
|
+
{value, field, toggle, element, emptyMessage, chooseKey, chooseDict} = attrs,
|
|
21
|
+
choose = (!attrs.choose && chooseKey && chooseDict) ? chooseDict[chooseKey] : attrs.choose,
|
|
22
|
+
choices = choose
|
|
23
|
+
? choose.map((choice) => ({value: choice, caption: choice}))
|
|
24
|
+
: attrs.choices || {};
|
|
25
|
+
|
|
26
|
+
const
|
|
27
|
+
keys = Object.keys(choices),
|
|
28
|
+
has = keys.length,
|
|
29
|
+
clase = (attrs.class || "") + (attrs.subclass ? " " + attrs.subclass : " scaff scaff-b1");
|
|
30
|
+
|
|
31
|
+
return has || emptyMessage
|
|
32
|
+
? [
|
|
33
|
+
...attrs.label ? [m(Separator, {text: attrs.label, class: attrs.labelClass || ""})] : [],
|
|
34
|
+
m(
|
|
35
|
+
(element || "div") + ".buttonchoice.flexrow.ohidden",
|
|
36
|
+
{
|
|
37
|
+
class: clase + (attrs.icon ? " withicon fa-" + attrs.icon : ""),
|
|
38
|
+
title: attrs.title
|
|
39
|
+
},
|
|
40
|
+
m(
|
|
41
|
+
".flexrow.grows.ohidden.wrap" + (attrs.icon ? " scaff-left" : ""),
|
|
42
|
+
keys.length
|
|
43
|
+
? keys.map((choicekey) => {
|
|
44
|
+
|
|
45
|
+
const
|
|
46
|
+
choice = choices[choicekey],
|
|
47
|
+
choicevalue = attrs.raw && field ? choice : choice.value,
|
|
48
|
+
finalchoicevalue = field ? choicevalue[field] : choicevalue,
|
|
49
|
+
current = finalchoicevalue === value;
|
|
50
|
+
|
|
51
|
+
// noinspection EqualityComparisonWithCoercionJS
|
|
52
|
+
return m(ButtonNew, {
|
|
53
|
+
|
|
54
|
+
icon: choice.icon || undefined,
|
|
55
|
+
class: "grows scaff-b0 " + (attrs.buttonClass ? attrs.buttonClass + " " : "rectbutton unitheightsmall ") + (choice.class ? choice.class + " " : "") + (current ? "accent" : ""),
|
|
56
|
+
title: choice.current ? choice.titleOn || choice.title : choice.titleOff || choice.title,
|
|
57
|
+
onClick: (e) => {
|
|
58
|
+
attrs.onchange(toggle ? current ? undefined : choice : choice, choicekey, e);
|
|
59
|
+
m.redraw();
|
|
60
|
+
}
|
|
61
|
+
}, attrs.render ? attrs.render(choice) : choice.caption || choicekey);
|
|
62
|
+
})
|
|
63
|
+
: [m(".emptychoice.grows.al-center.align-self-center.unitheightsmall", attrs.emptyMessage)]
|
|
64
|
+
)
|
|
65
|
+
)
|
|
66
|
+
]
|
|
67
|
+
: [];
|
|
68
|
+
}
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
export default ButtonChoiceWidget;
|
|
72
|
+
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import m from "mithril";
|
|
2
|
+
import defineWidget from "../util/widgets.utils";
|
|
3
|
+
import {popupMessage} from "../util/widgets"
|
|
4
|
+
|
|
5
|
+
const
|
|
6
|
+
colorjoe = require("colorjoe");
|
|
7
|
+
// TODO
|
|
8
|
+
// ColorProbeButton = require("ColorProbeButton");
|
|
9
|
+
|
|
10
|
+
const
|
|
11
|
+
ColorJoe = defineWidget(
|
|
12
|
+
() => m(".colorjoe-frame.absolute"),
|
|
13
|
+
null,
|
|
14
|
+
({attrs, dom}) => {
|
|
15
|
+
|
|
16
|
+
window.SCALE = 1;
|
|
17
|
+
|
|
18
|
+
attrs.state.joe = (attrs.hsl ? colorjoe.hsl : colorjoe.rgb)(
|
|
19
|
+
dom,
|
|
20
|
+
attrs.color,
|
|
21
|
+
attrs.noalpha
|
|
22
|
+
? []
|
|
23
|
+
: [
|
|
24
|
+
// "currentColor",
|
|
25
|
+
"alpha"
|
|
26
|
+
]
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
attrs.state.joe.on("change", (c) => {
|
|
30
|
+
attrs.onColor(attrs.noalpha ? c.css() : c.cssa(), c);
|
|
31
|
+
})
|
|
32
|
+
.update();
|
|
33
|
+
}
|
|
34
|
+
),
|
|
35
|
+
FAVORITES = [],
|
|
36
|
+
ColorJoeWrapper = defineWidget(
|
|
37
|
+
({attrs, state, children}) => m(".colorjoe-popper.flexcol", {
|
|
38
|
+
class: attrs.noalpha ? "no-alpha" : ""
|
|
39
|
+
}, [
|
|
40
|
+
m(ColorJoe, {...attrs, state}),
|
|
41
|
+
...children,
|
|
42
|
+
m(".flexrow.extended.w-100.scaff-top.pad-2.wrap", [
|
|
43
|
+
|
|
44
|
+
[0, 1, 2, 3, 4, 5, 6, 7, 8].map((i) => m("button.scaff.scaff-b1.marg-1.unitheightsmall.grows", {
|
|
45
|
+
class: FAVORITES[i] ? "" : "chequered",
|
|
46
|
+
style: {
|
|
47
|
+
...FAVORITES[i] && {backgroundColor: FAVORITES[i]}
|
|
48
|
+
},
|
|
49
|
+
onclick: (e) => {
|
|
50
|
+
if (e.shiftKey) {
|
|
51
|
+
FAVORITES[i] = state.joe.get()
|
|
52
|
+
.css();
|
|
53
|
+
} else {
|
|
54
|
+
if (FAVORITES[i]) state.joe.set(FAVORITES[i]);
|
|
55
|
+
}
|
|
56
|
+
if (attrs.onRedraw) attrs.onRedraw(); else m.redraw();
|
|
57
|
+
}
|
|
58
|
+
})),
|
|
59
|
+
m(".flexbreak"),
|
|
60
|
+
/* TODO ELECTRON
|
|
61
|
+
m(ColorProbeButton, {
|
|
62
|
+
class: "grows marg-1 scaff scaff-b1 unitheightsmall",
|
|
63
|
+
icon: "magic",
|
|
64
|
+
title: "Pick a color from the scene",
|
|
65
|
+
onColor: (color) => state.joe.set(color)
|
|
66
|
+
}),
|
|
67
|
+
*/
|
|
68
|
+
...attrs.onRemove ? [m("button.scaff.scaff-b1.unitheightsmall.marg-1.pad-2.pad-h.grows.fabf.transp.bg-accent.fa-trash", {
|
|
69
|
+
onclick: () => attrs.onRemove(state.joe.get())
|
|
70
|
+
})] : []
|
|
71
|
+
])
|
|
72
|
+
])
|
|
73
|
+
),
|
|
74
|
+
popupColor = (vnode) => popupMessage(
|
|
75
|
+
() => m(ColorJoeWrapper, {
|
|
76
|
+
noalpha: vnode.attrs.noalpha,
|
|
77
|
+
color: vnode.state.color,
|
|
78
|
+
hsl: vnode.attrs.hsl,
|
|
79
|
+
onColor: (parsedColor, colorObject) => {
|
|
80
|
+
vnode.state.color = parsedColor;
|
|
81
|
+
if (vnode.attrs.onchange) vnode.attrs.onchange(parsedColor, colorObject);
|
|
82
|
+
m.redraw();
|
|
83
|
+
},
|
|
84
|
+
onRemove: () => {
|
|
85
|
+
if (vnode.attrs.onchange) vnode.attrs.onchange(null, null);
|
|
86
|
+
popupMessage(null);
|
|
87
|
+
},
|
|
88
|
+
onRedraw: () => {
|
|
89
|
+
popupMessage.redraw();
|
|
90
|
+
m.redraw();
|
|
91
|
+
}
|
|
92
|
+
}, vnode.children),
|
|
93
|
+
|
|
94
|
+
() => {
|
|
95
|
+
},
|
|
96
|
+
|
|
97
|
+
".modal-content-popper"
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
const ColorJoeWidget = defineWidget(
|
|
101
|
+
(vnode) => {
|
|
102
|
+
const {attrs, state} = vnode;
|
|
103
|
+
return [
|
|
104
|
+
m(
|
|
105
|
+
".colorjoe-cell.chequered",
|
|
106
|
+
{
|
|
107
|
+
class: (attrs.class || "") + (state.shown ? " open" : ""),
|
|
108
|
+
title: attrs.title,
|
|
109
|
+
...attrs.style && {style: attrs.style}
|
|
110
|
+
},
|
|
111
|
+
[
|
|
112
|
+
m(".inset", {
|
|
113
|
+
style: {
|
|
114
|
+
backgroundColor: state.color
|
|
115
|
+
},
|
|
116
|
+
...attrs.caption && {"data-caption": attrs.caption, class: "titled"},
|
|
117
|
+
onclick: (e) => {
|
|
118
|
+
if (attrs.onshiftclick && (e.shiftKey || e.ctrlKey)) {
|
|
119
|
+
attrs.onshiftclick();
|
|
120
|
+
} else {
|
|
121
|
+
popupColor(vnode);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
})
|
|
125
|
+
])
|
|
126
|
+
];
|
|
127
|
+
},
|
|
128
|
+
({attrs, state}) => {
|
|
129
|
+
state.original = attrs.color;
|
|
130
|
+
state.color = state.original || "rgba(0,0,0,0)";
|
|
131
|
+
},
|
|
132
|
+
null,
|
|
133
|
+
null,
|
|
134
|
+
({attrs, state}) => {
|
|
135
|
+
if (state.original !== attrs.color) {
|
|
136
|
+
state.original = attrs.color;
|
|
137
|
+
state.color = state.original || "rgba(0,0,0,0)";
|
|
138
|
+
m.redraw();
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
export default ColorJoeWidget;
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import m from "mithril";
|
|
2
|
+
|
|
3
|
+
const
|
|
4
|
+
PropGroup = {
|
|
5
|
+
view: ({attrs}) => attrs.items.map(({name}, index) => m(
|
|
6
|
+
"option",
|
|
7
|
+
{
|
|
8
|
+
...(attrs.state.index === index + (attrs.offset || 0)) && {selected: true}
|
|
9
|
+
},
|
|
10
|
+
name
|
|
11
|
+
))
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
let
|
|
15
|
+
__timer;
|
|
16
|
+
|
|
17
|
+
function parseGroups(attrs, state) {
|
|
18
|
+
|
|
19
|
+
if (attrs.groups) {
|
|
20
|
+
|
|
21
|
+
state.groups = {};
|
|
22
|
+
state.allItems = [];
|
|
23
|
+
|
|
24
|
+
attrs.parsed = true;
|
|
25
|
+
|
|
26
|
+
const
|
|
27
|
+
groupKeys = Object.keys(attrs.groups);
|
|
28
|
+
|
|
29
|
+
groupKeys.forEach((groupKey) => {
|
|
30
|
+
state.groups[groupKey] = {
|
|
31
|
+
label: groupKey,
|
|
32
|
+
len: attrs.groups[groupKey].length,
|
|
33
|
+
items: attrs.groups[groupKey]
|
|
34
|
+
};
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const
|
|
38
|
+
groupValues = Object.values(state.groups);
|
|
39
|
+
|
|
40
|
+
groupValues
|
|
41
|
+
.forEach((group, index) => {
|
|
42
|
+
|
|
43
|
+
if (attrs.value) {
|
|
44
|
+
state.index = 0;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
group.offset = index ? groupValues[index - 1].offset + groupValues[index - 1].len : 0;
|
|
48
|
+
state.allItems = state.allItems.concat(group.items);
|
|
49
|
+
if (attrs.value) {
|
|
50
|
+
|
|
51
|
+
group.items.forEach((item, itemIndex) => {
|
|
52
|
+
const
|
|
53
|
+
itemValue = item.value,
|
|
54
|
+
parsedValue = attrs.parser ? attrs.parser(itemValue) : itemValue;
|
|
55
|
+
if (parsedValue === attrs.value) {
|
|
56
|
+
state.index = itemIndex + group.offset;
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
} else if (attrs.items) {
|
|
62
|
+
state.index = 0;
|
|
63
|
+
for (let i = 0, l = attrs.items.length; i < l; i++) {
|
|
64
|
+
const
|
|
65
|
+
itemValue = attrs.items[i].value,
|
|
66
|
+
parsedValue = attrs.parser ? attrs.parser(itemValue) : itemValue;
|
|
67
|
+
if (parsedValue === attrs.value) {
|
|
68
|
+
state.index = i;
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
state.allItems = attrs.items;
|
|
73
|
+
} else {
|
|
74
|
+
state.allItems = [];
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const ComboWidget = {
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Creates the Widget View
|
|
83
|
+
* @param vnode
|
|
84
|
+
* @param {SelectAttrs} vnode.attrs
|
|
85
|
+
* @param {Object} vnode.state
|
|
86
|
+
* @return {*}
|
|
87
|
+
* @private
|
|
88
|
+
*/
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
view: ({attrs, state}) => {
|
|
92
|
+
const {groups} = state;
|
|
93
|
+
return m(
|
|
94
|
+
"select",
|
|
95
|
+
{
|
|
96
|
+
"aria-label": attrs.caption,
|
|
97
|
+
class: attrs.class,
|
|
98
|
+
oninput: (ev) => {
|
|
99
|
+
|
|
100
|
+
// el desincronismo es si se camian los items y el state no se entera
|
|
101
|
+
// esto asegura que estan synchro
|
|
102
|
+
parseGroups(attrs, state);
|
|
103
|
+
|
|
104
|
+
const
|
|
105
|
+
index = state.index = ev.target.selectedIndex,
|
|
106
|
+
item = index >= 0 ? state.allItems[index] : null;
|
|
107
|
+
|
|
108
|
+
if (attrs.onchange && item) {
|
|
109
|
+
attrs.onchange(item.value, item, index);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
m.redraw();
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
groups
|
|
116
|
+
? Object.values(groups)
|
|
117
|
+
.map((group) => m("optgroup", {label: group.label}, m(PropGroup, {
|
|
118
|
+
items: group.items,
|
|
119
|
+
offset: group.offset,
|
|
120
|
+
state
|
|
121
|
+
})))
|
|
122
|
+
: m(PropGroup, {items: (attrs.items != null ? attrs.items : []), state}));
|
|
123
|
+
},
|
|
124
|
+
|
|
125
|
+
oninit: ({attrs, state}) => {
|
|
126
|
+
Object.assign(state, {
|
|
127
|
+
index: attrs.index || 0,
|
|
128
|
+
initial: attrs.value
|
|
129
|
+
});
|
|
130
|
+
parseGroups(attrs, state);
|
|
131
|
+
},
|
|
132
|
+
|
|
133
|
+
oncreate: () => {
|
|
134
|
+
},
|
|
135
|
+
|
|
136
|
+
onupdate: ({attrs, state}) => {
|
|
137
|
+
|
|
138
|
+
const refresh = (attrs.value !== undefined && state.initial !== attrs.value);
|
|
139
|
+
|
|
140
|
+
if (!state.groups && !state.allItems || refresh) {
|
|
141
|
+
|
|
142
|
+
// sets index from attrs.value
|
|
143
|
+
parseGroups(attrs, state);
|
|
144
|
+
|
|
145
|
+
if (refresh) {
|
|
146
|
+
state.initial = attrs.value;
|
|
147
|
+
clearTimeout(__timer);
|
|
148
|
+
__timer = setTimeout(() => m.redraw(), 50);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
export default ComboWidget;
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import {defineWidget, ButtonNew} from "./Basic.js"
|
|
2
|
+
import {promptName} from "./OverflowUtils"
|
|
3
|
+
import {confirmPromise} from "../util/fuckingconfirm"
|
|
4
|
+
|
|
5
|
+
const
|
|
6
|
+
ThematicWrapper = defineWidget(
|
|
7
|
+
({attrs, children}) => m(
|
|
8
|
+
".buttonchoice.withicon.flexrow.scaff.scaff-b1.fadein.ohidden.fa-" + (attrs.icon || "gear"),
|
|
9
|
+
{class: (attrs.containerClass || "col-11 grows marg-1"), title: attrs.title},
|
|
10
|
+
m(
|
|
11
|
+
".flexrow.wrap.grows.col-11.ohidden.scaff-left.bg-inputs",
|
|
12
|
+
{class: attrs.class},
|
|
13
|
+
children
|
|
14
|
+
)
|
|
15
|
+
)
|
|
16
|
+
),
|
|
17
|
+
optionsPrompt = (items, index, onAdd, onDelete, onEdit, allowUpdate) => {
|
|
18
|
+
|
|
19
|
+
const item = items[index];
|
|
20
|
+
|
|
21
|
+
confirmPromise(
|
|
22
|
+
null,
|
|
23
|
+
|
|
24
|
+
"Choose an action for this preset",
|
|
25
|
+
|
|
26
|
+
onAdd && allowUpdate
|
|
27
|
+
? ["DELETE", "RENAME", "UPDATE", "CANCEL"]
|
|
28
|
+
: ["DELETE", "RENAME", "CANCEL"]
|
|
29
|
+
)
|
|
30
|
+
.then(({idx}) => {
|
|
31
|
+
|
|
32
|
+
if (idx === 0) {
|
|
33
|
+
items.splice(index, 1);
|
|
34
|
+
if (onDelete) onDelete(index);
|
|
35
|
+
m.redraw();
|
|
36
|
+
} else if (idx === 1) {
|
|
37
|
+
setTimeout(() => promptName(
|
|
38
|
+
"Rename Preset",
|
|
39
|
+
item.title || "",
|
|
40
|
+
"type a name for this preset",
|
|
41
|
+
(newName) => {
|
|
42
|
+
if (newName) {
|
|
43
|
+
newName = newName.trim();
|
|
44
|
+
if (newName) {
|
|
45
|
+
item.title = newName.substring(0, 24);
|
|
46
|
+
m.redraw();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
), 10);
|
|
51
|
+
} else if (onAdd && idx === 2) {
|
|
52
|
+
onAdd(false, index);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
},
|
|
56
|
+
GenericButtonTicker = defineWidget(
|
|
57
|
+
({attrs, children}) => {
|
|
58
|
+
|
|
59
|
+
const
|
|
60
|
+
{
|
|
61
|
+
title, noUpdate, items = [], current, altIndex, onEdit, emptyText,
|
|
62
|
+
onAdd, onSelect, onDelete, addText = "Add New",
|
|
63
|
+
unconfirm, buttonClass, themeIcon, themeTitle
|
|
64
|
+
} = attrs,
|
|
65
|
+
|
|
66
|
+
allItems = [
|
|
67
|
+
|
|
68
|
+
...items.map(
|
|
69
|
+
(item, index) => m(
|
|
70
|
+
"button.grows.marg-1.ellipsis.ohidden.hasShift",
|
|
71
|
+
{
|
|
72
|
+
|
|
73
|
+
class: (buttonClass ? buttonClass : "unitheightsmall scaff-b1")
|
|
74
|
+
+ (index === current ? " accent" : "")
|
|
75
|
+
+ (index === altIndex ? " alt-accent" : ""),
|
|
76
|
+
|
|
77
|
+
title,
|
|
78
|
+
onclick: (e) => {
|
|
79
|
+
if (e.metaKey && onEdit) {
|
|
80
|
+
onEdit(item);
|
|
81
|
+
} else if (onAdd && e.shiftKey) {
|
|
82
|
+
if (unconfirm) {
|
|
83
|
+
items.splice(index, 1);
|
|
84
|
+
if (onDelete) onDelete(index);
|
|
85
|
+
m.redraw();
|
|
86
|
+
} else {
|
|
87
|
+
optionsPrompt(items, index, onAdd, onDelete, undefined, !noUpdate);
|
|
88
|
+
}
|
|
89
|
+
} else {
|
|
90
|
+
onSelect(item, index, e.metaKey, e.shiftKey);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
(item.title || item.name || item.text || String(1 + index)).substring(0, 32)
|
|
95
|
+
)
|
|
96
|
+
),
|
|
97
|
+
|
|
98
|
+
...!items.length && emptyText
|
|
99
|
+
? [
|
|
100
|
+
m(".grows.marg-1.ellipsis.ohidden.al-center", emptyText)
|
|
101
|
+
] : [],
|
|
102
|
+
|
|
103
|
+
...onAdd
|
|
104
|
+
? [
|
|
105
|
+
m(ButtonNew, {
|
|
106
|
+
tabIndex: -1,
|
|
107
|
+
icon: attrs.icon || "plus",
|
|
108
|
+
title: attrs.addTitle || "Add a new item",
|
|
109
|
+
class: "pad-2 pad-h al-center unitheightsmall transp addbut scaff-left bg-window-lo grows",
|
|
110
|
+
onClick: (e) => onAdd(e.ctrlKey || e.metaKey),
|
|
111
|
+
text: items?.length ? "" : addText
|
|
112
|
+
})
|
|
113
|
+
]
|
|
114
|
+
: [],
|
|
115
|
+
|
|
116
|
+
...!themeIcon && attrs.currentWidget && current >= 0 && items[current]
|
|
117
|
+
? attrs.currentWidget(items[current], current) || []
|
|
118
|
+
: [],
|
|
119
|
+
|
|
120
|
+
...children
|
|
121
|
+
];
|
|
122
|
+
|
|
123
|
+
return themeIcon
|
|
124
|
+
? [
|
|
125
|
+
m(ThematicWrapper, {
|
|
126
|
+
title: themeTitle,
|
|
127
|
+
containerClass: attrs.containerClass,
|
|
128
|
+
icon: themeIcon
|
|
129
|
+
}, allItems),
|
|
130
|
+
...attrs.currentWidget && current >= 0 && items[current] ? attrs.currentWidget(items[current], current) || [] : []
|
|
131
|
+
] : allItems;
|
|
132
|
+
}
|
|
133
|
+
),
|
|
134
|
+
CoolGenericTicker = defineWidget(
|
|
135
|
+
({attrs, children}) => {
|
|
136
|
+
|
|
137
|
+
const
|
|
138
|
+
{
|
|
139
|
+
nocontainer,
|
|
140
|
+
emptyText,
|
|
141
|
+
title,
|
|
142
|
+
addTitle,
|
|
143
|
+
items,
|
|
144
|
+
currentIndex,
|
|
145
|
+
altIndex,
|
|
146
|
+
onEdit,
|
|
147
|
+
onDelta,
|
|
148
|
+
onSelect,
|
|
149
|
+
onAdd,
|
|
150
|
+
addText,
|
|
151
|
+
icon,
|
|
152
|
+
buttonClass
|
|
153
|
+
} = attrs,
|
|
154
|
+
itemz = ((items && items.length <= (attrs.max || 15)) || !onDelta)
|
|
155
|
+
? m(GenericButtonTicker, {
|
|
156
|
+
addTitle,
|
|
157
|
+
emptyText,
|
|
158
|
+
title,
|
|
159
|
+
items,
|
|
160
|
+
current: currentIndex,
|
|
161
|
+
altIndex,
|
|
162
|
+
onSelect,
|
|
163
|
+
onAdd,
|
|
164
|
+
onEdit,
|
|
165
|
+
addText,
|
|
166
|
+
icon,
|
|
167
|
+
buttonClass
|
|
168
|
+
}, children)
|
|
169
|
+
: [
|
|
170
|
+
m(ButtonNew, {
|
|
171
|
+
tabIndex: -1,
|
|
172
|
+
icon: "caret-right",
|
|
173
|
+
class: "unitheightsmall grows marg-1 no-marg-left",
|
|
174
|
+
onClick: () => onDelta(-1)
|
|
175
|
+
}),
|
|
176
|
+
...items
|
|
177
|
+
? [
|
|
178
|
+
m(
|
|
179
|
+
".scaff.unitheightsmall.value.al-center.bg-window-lo.grows.marg-1.no-marg-left ",
|
|
180
|
+
(1 + currentIndex) + " / " + items.length
|
|
181
|
+
)
|
|
182
|
+
]
|
|
183
|
+
: [],
|
|
184
|
+
m(ButtonNew, {
|
|
185
|
+
tabIndex: -1,
|
|
186
|
+
icon: "caret-left",
|
|
187
|
+
class: "unitheightsmall grows marg-1 marg-v",
|
|
188
|
+
onClick: () => onDelta(1)
|
|
189
|
+
}),
|
|
190
|
+
...onAdd
|
|
191
|
+
? [
|
|
192
|
+
m(ButtonNew, {
|
|
193
|
+
tabIndex: -1,
|
|
194
|
+
icon: attrs.icon || "plus",
|
|
195
|
+
class: "unitheightsmall marg-1 marg-v",
|
|
196
|
+
onClick: () => onAdd()
|
|
197
|
+
})
|
|
198
|
+
] : []
|
|
199
|
+
];
|
|
200
|
+
|
|
201
|
+
return nocontainer
|
|
202
|
+
? itemz
|
|
203
|
+
: items.length || !onAdd ? m(
|
|
204
|
+
".flexrow.wrap.max.minusbar",
|
|
205
|
+
{class: (attrs.dynclass ? attrs.dynclass() + " " : "") + attrs.class},
|
|
206
|
+
itemz
|
|
207
|
+
) : [];
|
|
208
|
+
}
|
|
209
|
+
),
|
|
210
|
+
|
|
211
|
+
CoolContentTicker = defineWidget(
|
|
212
|
+
({attrs}) => {
|
|
213
|
+
|
|
214
|
+
if (!attrs.layer.items) return [];
|
|
215
|
+
|
|
216
|
+
const
|
|
217
|
+
{global, layer, remoteFirst: isRemote, isCue} = attrs,
|
|
218
|
+
{storyWrapper} = global,
|
|
219
|
+
{id, items} = layer,
|
|
220
|
+
|
|
221
|
+
currentIndex = storyWrapper.getTickerIndex(id, isRemote),
|
|
222
|
+
altIndex = isRemote ? storyWrapper.getTickerIndex(id, false) : undefined;
|
|
223
|
+
|
|
224
|
+
// noinspection JSUnusedGlobalSymbols
|
|
225
|
+
return m(CoolGenericTicker, {
|
|
226
|
+
title: attrs.title,
|
|
227
|
+
onAdd: attrs.onAdd,
|
|
228
|
+
class: "marg-1 marg-h grows",
|
|
229
|
+
items,
|
|
230
|
+
currentIndex,
|
|
231
|
+
altIndex,
|
|
232
|
+
current: items[currentIndex] || undefined,
|
|
233
|
+
onDelta: (direction) => storyWrapper.tickLayer(layer, direction, isRemote, isCue),
|
|
234
|
+
onSelect: (item, index, force) => storyWrapper.setTickerIndex(layer, index, force, isRemote, isCue)
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
);
|
|
238
|
+
|
|
239
|
+
export {CoolContentTicker, CoolGenericTicker, GenericButtonTicker, optionsPrompt};
|