dazscript-framework 0.1.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/babel/babel.config.js +33 -0
- package/babel/trace-babel-plugin.js +243 -0
- package/babel/trace-log-babel-plugin.js +164 -0
- package/common/core.ts +2 -0
- package/common/log.ts +57 -0
- package/common/trace.ts +26 -0
- package/core/action-decorator.ts +16 -0
- package/dialog/basic-dialog.ts +32 -0
- package/dialog/builders/button-builder.ts +53 -0
- package/dialog/builders/checkbox-builder.ts +30 -0
- package/dialog/builders/combo-box-builder.ts +36 -0
- package/dialog/builders/combo-edit-builder.ts +36 -0
- package/dialog/builders/dialog-builder.ts +49 -0
- package/dialog/builders/groupbox-builder.ts +73 -0
- package/dialog/builders/label-builder.ts +18 -0
- package/dialog/builders/layout-builder.ts +46 -0
- package/dialog/builders/line-edit-builder.ts +118 -0
- package/dialog/builders/list-view-builder.ts +327 -0
- package/dialog/builders/node-selection-builder.ts +44 -0
- package/dialog/builders/popup-menu-builder.ts +47 -0
- package/dialog/builders/radio-builder.ts +43 -0
- package/dialog/builders/splitter-builder.ts +90 -0
- package/dialog/builders/tab-builder.ts +106 -0
- package/dialog/builders/widget-builder.ts +109 -0
- package/dialog/builders/widgets-builder.ts +119 -0
- package/dialog/input-dialog.ts +28 -0
- package/dialog/input-validator.ts +9 -0
- package/dialog/shared.ts +8 -0
- package/helpers/action-helper.ts +81 -0
- package/helpers/array-helper.ts +145 -0
- package/helpers/camera-helper.ts +14 -0
- package/helpers/custom-action-helper.ts +176 -0
- package/helpers/file-helper.ts +90 -0
- package/helpers/input-helper.ts +19 -0
- package/helpers/list-view-helper.ts +89 -0
- package/helpers/menu-helper.ts +29 -0
- package/helpers/message-box-helper.ts +16 -0
- package/helpers/node-helper.ts +216 -0
- package/helpers/number-helper.ts +11 -0
- package/helpers/numeric-property-helper.ts +92 -0
- package/helpers/object-helper.ts +3 -0
- package/helpers/pane-helper.ts +21 -0
- package/helpers/progress-helper.ts +34 -0
- package/helpers/property-helper.ts +53 -0
- package/helpers/record-helper.ts +16 -0
- package/helpers/scene-helper.ts +96 -0
- package/helpers/script-helper.ts +16 -0
- package/helpers/skeleton-helper.ts +27 -0
- package/helpers/splitter-helper.ts +9 -0
- package/helpers/string-helper.ts +28 -0
- package/helpers/surface-helper.ts +6 -0
- package/helpers/undo-helper.ts +7 -0
- package/helpers/viewport-helper.ts +9 -0
- package/lib/delayed.ts +39 -0
- package/lib/dz-dump.ts +121 -0
- package/lib/global.ts +5 -0
- package/lib/guid.ts +3 -0
- package/lib/observable.ts +94 -0
- package/lib/set.ts +25 -0
- package/lib/settings.ts +104 -0
- package/models/custom-action.ts +12 -0
- package/models/frame-keys.ts +68 -0
- package/package.json +48 -0
- package/shared/base-script.ts +30 -0
- package/shared/install-generator.js +185 -0
- package/shared/set-keyboard-shortcut.ts +103 -0
- package/webpack.config.js +48 -0
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
const tsFileParser = require('ts-file-parser');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const glob = require('glob');
|
|
5
|
+
const { program } = require('commander');
|
|
6
|
+
|
|
7
|
+
program
|
|
8
|
+
.requiredOption(
|
|
9
|
+
'-p, --scriptsPath <path>',
|
|
10
|
+
'Specify the path to your scripts'
|
|
11
|
+
)
|
|
12
|
+
.option(
|
|
13
|
+
'-m, --defaultMenuPath [path]',
|
|
14
|
+
'Specify the default menu path',
|
|
15
|
+
'My Scripts'
|
|
16
|
+
)
|
|
17
|
+
.parse(process.argv);
|
|
18
|
+
let options = program.opts();
|
|
19
|
+
|
|
20
|
+
const nameofActionDecorator = 'action';
|
|
21
|
+
|
|
22
|
+
const scriptsPath = options.scriptsPath.endsWith('/')
|
|
23
|
+
? options.scriptsPath
|
|
24
|
+
: options.scriptsPath + '/';
|
|
25
|
+
const defaultMenuPath = options.defaultMenuPath.endsWith('/')
|
|
26
|
+
? options.defaultMenuPath
|
|
27
|
+
: options.defaultMenuPath + '/';
|
|
28
|
+
|
|
29
|
+
const container = { scripts: [] };
|
|
30
|
+
|
|
31
|
+
function getPartialPath(filePath) {
|
|
32
|
+
const fileInfo = path.parse(filePath);
|
|
33
|
+
const dir = fileInfo.dir.replace('/src', '').replace(/^\.\//, '');
|
|
34
|
+
return `${dir}/${fileInfo.name}`;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function compareStrings(a, b) {
|
|
38
|
+
return a.localeCompare(b, undefined, { sensitivity: 'base' });
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function stringOrDefault(str, defaultValue) {
|
|
42
|
+
return str !== undefined && str !== null && str !== '' ? str : defaultValue;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function generateInstallerTemplate(data) {
|
|
46
|
+
return `
|
|
47
|
+
import { installCustomActions as install } from '@dsf/helpers/custom-action-helper';
|
|
48
|
+
|
|
49
|
+
install(${data});
|
|
50
|
+
`;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function generateUninstallerTemplate(data) {
|
|
54
|
+
return `
|
|
55
|
+
import { uninstallCustomActions as uninstall } from '@dsf/helpers/custom-action-helper';
|
|
56
|
+
|
|
57
|
+
uninstall(${data});
|
|
58
|
+
`;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function processScript(filePath) {
|
|
62
|
+
const fileInfo = path.parse(filePath);
|
|
63
|
+
const content = fs.readFileSync(filePath, 'utf-8').toString();
|
|
64
|
+
const json = tsFileParser.parseStruct(content, {}, filePath);
|
|
65
|
+
|
|
66
|
+
json.classes.forEach((cls) => {
|
|
67
|
+
const actionDecorator = cls.decorators.find(
|
|
68
|
+
(d) => d.name === nameofActionDecorator
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
if (!actionDecorator) return;
|
|
72
|
+
|
|
73
|
+
const decorator = actionDecorator.arguments[0] ?? {};
|
|
74
|
+
|
|
75
|
+
const script = {
|
|
76
|
+
name: null,
|
|
77
|
+
text: fileInfo.name.replace('.dsa', ''),
|
|
78
|
+
filePath:
|
|
79
|
+
decorator.bundle === undefined
|
|
80
|
+
? getPartialPath(filePath)
|
|
81
|
+
: fileInfo.name.replace('.ts', ''),
|
|
82
|
+
menuPath: `${defaultMenuPath}${path.parse(getPartialPath(filePath)).dir}`,
|
|
83
|
+
description: fileInfo.name.replace('.dsa', ''),
|
|
84
|
+
group: stringOrDefault(decorator.group, undefined),
|
|
85
|
+
shortcut: stringOrDefault(decorator.shortcut),
|
|
86
|
+
toolbar: stringOrDefault(decorator.toolbar, undefined),
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const icon = filePath.replace('.ts', '.png');
|
|
90
|
+
if (fs.existsSync(icon)) {
|
|
91
|
+
script.icon =
|
|
92
|
+
decorator.bundle === undefined
|
|
93
|
+
? `${getPartialPath(filePath)}.png`
|
|
94
|
+
: fileInfo.name.replace('.dsa', '.dsa.png');
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (actionDecorator) {
|
|
98
|
+
script.text = stringOrDefault(decorator.text, script.text);
|
|
99
|
+
if (typeof decorator.menuPath === 'boolean') {
|
|
100
|
+
script.menuPath = decorator.menuPath === true ? script.menuPath : '';
|
|
101
|
+
} else {
|
|
102
|
+
script.menuPath = stringOrDefault(decorator.menuPath, script.menuPath);
|
|
103
|
+
}
|
|
104
|
+
script.menuPath = script.menuPath.replace(
|
|
105
|
+
'#{defaultMenuPath}',
|
|
106
|
+
defaultMenuPath
|
|
107
|
+
);
|
|
108
|
+
script.shortcut = decorator.shortcut;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
console.log(`Adding script: ${script.text}`, script);
|
|
112
|
+
container.scripts.push(script);
|
|
113
|
+
|
|
114
|
+
// Check if the decorator has a "bundle" property
|
|
115
|
+
if (decorator.bundle !== undefined) {
|
|
116
|
+
let packageInstallerFilePath = `Install.dsa.ts`;
|
|
117
|
+
let packageUninstallerFilePath = `Uninstall.dsa.ts`;
|
|
118
|
+
|
|
119
|
+
if (decorator.bundle !== true) {
|
|
120
|
+
// If decorator.bundle is a string, use it as the bundle file name
|
|
121
|
+
packageInstallerFilePath = `Install ${decorator.bundle}.dsa.ts`;
|
|
122
|
+
packageUninstallerFilePath = `Uninstall ${decorator.bundle}.dsa.ts`;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Generate a separate file with the specified or default name
|
|
126
|
+
let bundleScriptContent = generateInstallerTemplate(
|
|
127
|
+
JSON.stringify(container.scripts, null, 4)
|
|
128
|
+
);
|
|
129
|
+
let bundleScriptFilePath = path.join(
|
|
130
|
+
path.parse(filePath).dir,
|
|
131
|
+
packageInstallerFilePath
|
|
132
|
+
);
|
|
133
|
+
fs.writeFileSync(bundleScriptFilePath, bundleScriptContent);
|
|
134
|
+
|
|
135
|
+
bundleScriptContent = generateUninstallerTemplate(
|
|
136
|
+
JSON.stringify(container.scripts, null, 4)
|
|
137
|
+
);
|
|
138
|
+
bundleScriptFilePath = path.join(
|
|
139
|
+
path.parse(filePath).dir,
|
|
140
|
+
packageUninstallerFilePath
|
|
141
|
+
);
|
|
142
|
+
fs.writeFileSync(bundleScriptFilePath, bundleScriptContent);
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function processScripts(paths) {
|
|
148
|
+
paths.forEach((filePath) => {
|
|
149
|
+
console.log(`Processing ${filePath}`);
|
|
150
|
+
processScript(filePath);
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function generate() {
|
|
155
|
+
glob(`${scriptsPath}/**/*.dsa.ts`, function (err, paths) {
|
|
156
|
+
if (err) {
|
|
157
|
+
console.error('Error while globbing:', err);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
processScripts(paths);
|
|
162
|
+
|
|
163
|
+
container.scripts = container.scripts.sort((a, b) => {
|
|
164
|
+
const aKey = a.menuPath + a.filePath;
|
|
165
|
+
const bKey = b.menuPath + b.filePath;
|
|
166
|
+
return compareStrings(aKey, bKey);
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
// Generate the InstallerScript class and call install function
|
|
170
|
+
const installerScriptContent = generateInstallerTemplate(
|
|
171
|
+
JSON.stringify(container.scripts, null, 4)
|
|
172
|
+
);
|
|
173
|
+
let outputFilePath = './src/Install.dsa.ts';
|
|
174
|
+
fs.writeFileSync(outputFilePath, installerScriptContent);
|
|
175
|
+
|
|
176
|
+
const uninstallerScriptContent = generateUninstallerTemplate(
|
|
177
|
+
JSON.stringify(container.scripts, null, 4)
|
|
178
|
+
);
|
|
179
|
+
outputFilePath = './src/Uninstall.dsa.ts';
|
|
180
|
+
fs.writeFileSync(outputFilePath, uninstallerScriptContent);
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Call the generate function at the end of the script
|
|
185
|
+
generate();
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { BasicDialog } from '@dsf/dialog/basic-dialog';
|
|
2
|
+
import { setActionShortcut } from '@dsf/helpers/action-helper';
|
|
3
|
+
import { contains } from '@dsf/helpers/array-helper';
|
|
4
|
+
import { Observable } from '@dsf/lib/observable';
|
|
5
|
+
|
|
6
|
+
class KeyboardShortcutModel {
|
|
7
|
+
actionLabel: string
|
|
8
|
+
shortcut = new Observable('')
|
|
9
|
+
control = new Observable(false)
|
|
10
|
+
alt = new Observable(false)
|
|
11
|
+
shift = new Observable(false)
|
|
12
|
+
windows = new Observable(false)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const letters = [
|
|
16
|
+
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
|
|
17
|
+
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '-'
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
const keys = [
|
|
21
|
+
'SPACE', 'HOME', 'END', 'INS', 'PLUS', 'MINUS',
|
|
22
|
+
'RIGHT', 'LEFT', 'UP', 'DOWN', 'TAB', 'BACKSPACE', 'COMMA', 'PERIOD', 'PGUP', 'PGDOWN', '-',
|
|
23
|
+
'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10',
|
|
24
|
+
'F11', 'F12', 'F13', 'F14', 'F15', 'F16', 'F17', 'F18', 'F19',
|
|
25
|
+
'F20', 'F21', 'F22', 'F23', 'F24',
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class KeyboardShortcutDialog extends BasicDialog {
|
|
30
|
+
private key = new Observable('')
|
|
31
|
+
|
|
32
|
+
constructor(private model: KeyboardShortcutModel) {
|
|
33
|
+
super('Keyboard Shortcut');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
protected build(): void {
|
|
37
|
+
let add = this.add
|
|
38
|
+
let model = this.model
|
|
39
|
+
this.dialog.setAcceptButtonEnabled(false)
|
|
40
|
+
this.dialog.showHelpButton(false)
|
|
41
|
+
this.builder.context.layout.margin = 5
|
|
42
|
+
this.dialog.minWidth = 250
|
|
43
|
+
|
|
44
|
+
this.key.intercept((_, current) => {
|
|
45
|
+
let value = current
|
|
46
|
+
if (current.length > 1 && !contains(keys, current))
|
|
47
|
+
value = current[1]
|
|
48
|
+
if (value.length === 1)
|
|
49
|
+
value = value.toUpperCase()
|
|
50
|
+
return value
|
|
51
|
+
})
|
|
52
|
+
this.key.connect((text) => {
|
|
53
|
+
model.shortcut.value = this.getShortcut(text)
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
const metaKeys = [model.control, model.alt, model.shift, model.windows];
|
|
57
|
+
for (const observable of metaKeys) {
|
|
58
|
+
observable.connect(() => this.key.trigger());
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
this.key.connect((text) => {
|
|
62
|
+
this.dialog.setAcceptButtonEnabled(Boolean(text))
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
add.group('Assign Keyboard Shortcut').build((layout) => {
|
|
66
|
+
layout.spacing = 5
|
|
67
|
+
add.edit().text(model.actionLabel).readOnly(true)
|
|
68
|
+
add.comboEdit().focus().items([...letters, ...keys]).changed(this.key).edited(this.key)
|
|
69
|
+
add.checkbox('Control').value(model.control)
|
|
70
|
+
add.checkbox('Option / Alt').value(model.alt)
|
|
71
|
+
add.checkbox('Shift').value(model.shift)
|
|
72
|
+
add.checkbox('Command / Windows').value(model.windows)
|
|
73
|
+
add.group('Shortcut:').style({ flat: true }).build(() => {
|
|
74
|
+
add.edit().text(model.shortcut).readOnly(true)
|
|
75
|
+
})
|
|
76
|
+
})
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
getShortcut(key: string): string {
|
|
80
|
+
let keys: string[] = []
|
|
81
|
+
|
|
82
|
+
if (this.model.control.value) keys.push('CTRL')
|
|
83
|
+
if (this.model.alt.value) keys.push('ALT')
|
|
84
|
+
if (this.model.shift.value) keys.push('SHIFT')
|
|
85
|
+
if (this.model.windows.value) keys.push('WIN')
|
|
86
|
+
|
|
87
|
+
keys.push(key)
|
|
88
|
+
|
|
89
|
+
return keys.join('+')
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export const setKeyboardShortcut = (actionLabel: string, actionName: string) => {
|
|
94
|
+
let model = new KeyboardShortcutModel()
|
|
95
|
+
model.actionLabel = actionLabel
|
|
96
|
+
|
|
97
|
+
let dialog = new KeyboardShortcutDialog(model)
|
|
98
|
+
let result = dialog.run()
|
|
99
|
+
|
|
100
|
+
if (!result || !model.shortcut) return
|
|
101
|
+
|
|
102
|
+
setActionShortcut(actionName, model.shortcut.value)
|
|
103
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const glob = require('glob');
|
|
3
|
+
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
|
|
4
|
+
|
|
5
|
+
module.exports = (env, argv) => {
|
|
6
|
+
const isFileSpecified = env && env.file;
|
|
7
|
+
const entryFiles = isFileSpecified
|
|
8
|
+
? [`./src/${env.file}.dsa.ts`]
|
|
9
|
+
: glob.sync('./src/**/*.dsa.ts');
|
|
10
|
+
|
|
11
|
+
return {
|
|
12
|
+
mode: 'production',
|
|
13
|
+
optimization: {
|
|
14
|
+
usedExports: true,
|
|
15
|
+
},
|
|
16
|
+
entry: entryFiles.reduce((acc, filePath) => {
|
|
17
|
+
const entry = filePath.replace('.dsa.ts', '').replace('src/', ''); // Remove 'src/' from the path
|
|
18
|
+
acc[entry] = `./${filePath}`;
|
|
19
|
+
return acc;
|
|
20
|
+
}, {}),
|
|
21
|
+
module: {
|
|
22
|
+
rules: [
|
|
23
|
+
{
|
|
24
|
+
test: /\.ts$/,
|
|
25
|
+
use: ['babel-loader', 'ts-loader'],
|
|
26
|
+
exclude: /node_modules/,
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
},
|
|
30
|
+
resolve: {
|
|
31
|
+
extensions: ['.tsx', '.ts', '.js'],
|
|
32
|
+
plugins: [new TsconfigPathsPlugin()],
|
|
33
|
+
},
|
|
34
|
+
output: {
|
|
35
|
+
filename: '[name].dsa',
|
|
36
|
+
path: path.resolve(__dirname, 'dist'),
|
|
37
|
+
environment: {
|
|
38
|
+
arrowFunction: false,
|
|
39
|
+
bigIntLiteral: false,
|
|
40
|
+
const: false,
|
|
41
|
+
destructuring: false,
|
|
42
|
+
dynamicImport: false,
|
|
43
|
+
forOf: true,
|
|
44
|
+
module: false,
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
};
|