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.
Files changed (67) hide show
  1. package/babel/babel.config.js +33 -0
  2. package/babel/trace-babel-plugin.js +243 -0
  3. package/babel/trace-log-babel-plugin.js +164 -0
  4. package/common/core.ts +2 -0
  5. package/common/log.ts +57 -0
  6. package/common/trace.ts +26 -0
  7. package/core/action-decorator.ts +16 -0
  8. package/dialog/basic-dialog.ts +32 -0
  9. package/dialog/builders/button-builder.ts +53 -0
  10. package/dialog/builders/checkbox-builder.ts +30 -0
  11. package/dialog/builders/combo-box-builder.ts +36 -0
  12. package/dialog/builders/combo-edit-builder.ts +36 -0
  13. package/dialog/builders/dialog-builder.ts +49 -0
  14. package/dialog/builders/groupbox-builder.ts +73 -0
  15. package/dialog/builders/label-builder.ts +18 -0
  16. package/dialog/builders/layout-builder.ts +46 -0
  17. package/dialog/builders/line-edit-builder.ts +118 -0
  18. package/dialog/builders/list-view-builder.ts +327 -0
  19. package/dialog/builders/node-selection-builder.ts +44 -0
  20. package/dialog/builders/popup-menu-builder.ts +47 -0
  21. package/dialog/builders/radio-builder.ts +43 -0
  22. package/dialog/builders/splitter-builder.ts +90 -0
  23. package/dialog/builders/tab-builder.ts +106 -0
  24. package/dialog/builders/widget-builder.ts +109 -0
  25. package/dialog/builders/widgets-builder.ts +119 -0
  26. package/dialog/input-dialog.ts +28 -0
  27. package/dialog/input-validator.ts +9 -0
  28. package/dialog/shared.ts +8 -0
  29. package/helpers/action-helper.ts +81 -0
  30. package/helpers/array-helper.ts +145 -0
  31. package/helpers/camera-helper.ts +14 -0
  32. package/helpers/custom-action-helper.ts +176 -0
  33. package/helpers/file-helper.ts +90 -0
  34. package/helpers/input-helper.ts +19 -0
  35. package/helpers/list-view-helper.ts +89 -0
  36. package/helpers/menu-helper.ts +29 -0
  37. package/helpers/message-box-helper.ts +16 -0
  38. package/helpers/node-helper.ts +216 -0
  39. package/helpers/number-helper.ts +11 -0
  40. package/helpers/numeric-property-helper.ts +92 -0
  41. package/helpers/object-helper.ts +3 -0
  42. package/helpers/pane-helper.ts +21 -0
  43. package/helpers/progress-helper.ts +34 -0
  44. package/helpers/property-helper.ts +53 -0
  45. package/helpers/record-helper.ts +16 -0
  46. package/helpers/scene-helper.ts +96 -0
  47. package/helpers/script-helper.ts +16 -0
  48. package/helpers/skeleton-helper.ts +27 -0
  49. package/helpers/splitter-helper.ts +9 -0
  50. package/helpers/string-helper.ts +28 -0
  51. package/helpers/surface-helper.ts +6 -0
  52. package/helpers/undo-helper.ts +7 -0
  53. package/helpers/viewport-helper.ts +9 -0
  54. package/lib/delayed.ts +39 -0
  55. package/lib/dz-dump.ts +121 -0
  56. package/lib/global.ts +5 -0
  57. package/lib/guid.ts +3 -0
  58. package/lib/observable.ts +94 -0
  59. package/lib/set.ts +25 -0
  60. package/lib/settings.ts +104 -0
  61. package/models/custom-action.ts +12 -0
  62. package/models/frame-keys.ts +68 -0
  63. package/package.json +48 -0
  64. package/shared/base-script.ts +30 -0
  65. package/shared/install-generator.js +185 -0
  66. package/shared/set-keyboard-shortcut.ts +103 -0
  67. package/webpack.config.js +48 -0
@@ -0,0 +1,33 @@
1
+ module.exports = {
2
+ presets: [
3
+ [
4
+ '@babel/preset-env',
5
+ {
6
+ targets: {
7
+ esmodules: true,
8
+ ie: '11',
9
+ },
10
+ include: ['@babel/plugin-transform-class-properties'],
11
+ },
12
+ ],
13
+ '@babel/preset-typescript',
14
+ ],
15
+ plugins: [
16
+ '@babel/plugin-transform-class-properties',
17
+ 'babel-plugin-transform-typescript-metadata',
18
+ ['@babel/plugin-proposal-decorators', { version: 'legacy' }],
19
+ ['@babel/plugin-transform-arrow-functions'],
20
+ '@babel/plugin-transform-block-scoping',
21
+ '@babel/plugin-proposal-class-properties',
22
+ '@babel/plugin-transform-private-property-in-object',
23
+ '@babel/plugin-transform-private-methods',
24
+ [
25
+ './src/framework/babel/trace-babel-plugin',
26
+ { default: false, retainLines: false },
27
+ ],
28
+ [
29
+ './src/framework/babel/trace-log-babel-plugin',
30
+ { default: false, retainLines: false },
31
+ ],
32
+ ],
33
+ };
@@ -0,0 +1,243 @@
1
+ const t = require('@babel/types');
2
+ const path = require('path');
3
+ let globalEnable = true;
4
+ let enabled = false;
5
+
6
+ function isTraceDecorator(node) {
7
+ return false; // Your existing isTraceDecorator logic
8
+ }
9
+
10
+ function isTraceComment(node) {
11
+ return false; // Your existing isTraceComment logic
12
+ }
13
+
14
+ function createConsoleLogStatement(
15
+ location,
16
+ filename,
17
+ lineNumber,
18
+ functionName,
19
+ parameters
20
+ ) {
21
+ const filenameWithoutPath = path.basename(filename);
22
+ let logMessage = `[TRACE] ${location}: ${filenameWithoutPath}(${lineNumber}): ${functionName}`;
23
+
24
+ if (parameters.length > 0) {
25
+ logMessage += `(${parameters.join(', ')})`;
26
+ } else {
27
+ logMessage += '()';
28
+ }
29
+
30
+ return t.blockStatement([
31
+ t.expressionStatement(
32
+ t.callExpression(
33
+ t.memberExpression(t.identifier('App'), t.identifier('debug')),
34
+ [t.stringLiteral(logMessage)]
35
+ )
36
+ ),
37
+ t.expressionStatement(
38
+ t.callExpression(
39
+ t.memberExpression(t.identifier('App'), t.identifier('flushLogBuffer')),
40
+ []
41
+ )
42
+ ),
43
+ ]);
44
+ }
45
+
46
+ function processFunction(enabled, path, state) {
47
+ const filename = state.file.opts.filename || 'unknown';
48
+ const lineNumber = path.node.loc?.start?.line || 'unknown';
49
+ const functionName = path.node.id ? path.node.id.name : 'anonymous';
50
+ const parameters = path.node.params.map((param) => param.name);
51
+
52
+ if (!enabled || functionName === 'anonymous' || lineNumber === 'unknown')
53
+ return;
54
+
55
+ const enteringLogStatement = createConsoleLogStatement(
56
+ 'Entering',
57
+ filename,
58
+ lineNumber,
59
+ functionName,
60
+ parameters
61
+ );
62
+ const exitingLogStatement = createConsoleLogStatement(
63
+ 'Exiting',
64
+ filename,
65
+ lineNumber,
66
+ functionName,
67
+ parameters
68
+ );
69
+
70
+ // Process the return statements within the function body
71
+ path.get('body').traverse({
72
+ ReturnStatement(returnPath) {
73
+ returnPath.insertBefore(exitingLogStatement);
74
+ },
75
+ });
76
+
77
+ if (enteringLogStatement) {
78
+ if (t.isBlockStatement(path.node.body)) {
79
+ path.node.body.body.unshift(enteringLogStatement);
80
+ } else {
81
+ path.node.body = t.blockStatement([enteringLogStatement, path.node.body]);
82
+ }
83
+ }
84
+ }
85
+
86
+ function processAssignmentExpression(path, state) {
87
+ const filename = state.file.opts.filename || 'unknown';
88
+ const lineNumber = path.node.loc?.start?.line || 'unknown';
89
+ let functionName = 'anonymous'; // Default value for function name
90
+ const parameters = [];
91
+
92
+ if (!enabled || lineNumber === 'unknown') return;
93
+
94
+ if (t.isMemberExpression(path.node.left)) {
95
+ functionName = path.node.left.property.name;
96
+ }
97
+
98
+ const enteringLogStatement = createConsoleLogStatement(
99
+ 'Entering',
100
+ filename,
101
+ lineNumber,
102
+ functionName,
103
+ parameters
104
+ );
105
+ const exitingLogStatement = createConsoleLogStatement(
106
+ 'Exiting',
107
+ filename,
108
+ lineNumber,
109
+ functionName,
110
+ parameters
111
+ );
112
+
113
+ // Process the return statements within the function body
114
+ path.get('right').traverse({
115
+ ReturnStatement(returnPath) {
116
+ returnPath.insertBefore(exitingLogStatement);
117
+ },
118
+ });
119
+
120
+ if (
121
+ t.isFunctionExpression(path.node.right) ||
122
+ t.isArrowFunctionExpression(path.node.right)
123
+ ) {
124
+ // Handle the case where the right-hand side is a function expression or arrow function expression
125
+ if (t.isBlockStatement(path.node.right.body)) {
126
+ path.node.right.body.body.unshift(enteringLogStatement);
127
+ path.node.right.body.body.push(exitingLogStatement);
128
+ } else {
129
+ path.node.right.body = t.blockStatement([
130
+ enteringLogStatement,
131
+ t.returnStatement(path.node.right.body),
132
+ exitingLogStatement,
133
+ ]);
134
+ }
135
+ }
136
+ }
137
+
138
+ function processVariableDeclaration(path, state) {
139
+ const filename = state.file.opts.filename || 'unknown';
140
+ const lineNumber = path.node.loc?.start?.line || 'unknown';
141
+
142
+ path.node.declarations.forEach((declarator) => {
143
+ if (
144
+ t.isFunctionExpression(declarator.init) ||
145
+ t.isArrowFunctionExpression(declarator.init)
146
+ ) {
147
+ const functionName = declarator.id.name;
148
+ const parameters = declarator.init.params.map((param) => param.name);
149
+
150
+ if (!enabled || lineNumber === 'unknown') return;
151
+
152
+ const enteringLogStatement = createConsoleLogStatement(
153
+ 'Entering',
154
+ filename,
155
+ lineNumber,
156
+ functionName,
157
+ parameters
158
+ );
159
+ const exitingLogStatement = createConsoleLogStatement(
160
+ 'Exiting',
161
+ filename,
162
+ lineNumber,
163
+ functionName,
164
+ parameters
165
+ );
166
+
167
+ // Ensure the Exiting statement is added to the end of the function body
168
+ if (t.isBlockStatement(declarator.init.body)) {
169
+ declarator.init.body.body.push(exitingLogStatement);
170
+ } else {
171
+ declarator.init.body = t.blockStatement([
172
+ declarator.init.body,
173
+ exitingLogStatement,
174
+ ]);
175
+ }
176
+
177
+ // Process the return statements within the function body
178
+ declarator.init.body.body.forEach((statement, index) => {
179
+ if (t.isReturnStatement(statement)) {
180
+ // Add Exiting statement before the return statement
181
+ declarator.init.body.body.splice(index, 0, exitingLogStatement);
182
+ }
183
+ });
184
+
185
+ // Add the Entering statement at the beginning of the function body
186
+ if (t.isBlockStatement(declarator.init.body)) {
187
+ declarator.init.body.body.unshift(enteringLogStatement);
188
+ } else {
189
+ declarator.init.body = t.blockStatement([
190
+ enteringLogStatement,
191
+ t.returnStatement(declarator.init.body),
192
+ ]);
193
+ }
194
+ }
195
+ });
196
+ }
197
+
198
+ module.exports = function () {
199
+ let declarationFound = false;
200
+
201
+ return {
202
+ pre() {
203
+ if (this.opts && typeof this.opts.default === 'boolean') {
204
+ enabled = globalEnable = this.opts.default;
205
+ }
206
+ enabled = globalEnable;
207
+ declarationFound = false;
208
+ },
209
+ visitor: {
210
+ VariableDeclaration(path, state) {
211
+ const declarations = path.node.declarations;
212
+ const traceDeclaration = declarations.find(
213
+ (declaration) => declaration.id.name === 'TRACE'
214
+ );
215
+
216
+ if (!declarationFound) {
217
+ if (traceDeclaration) {
218
+ enabled = traceDeclaration.init
219
+ ? traceDeclaration.init.value
220
+ : false;
221
+ declarationFound = true;
222
+ } else {
223
+ enabled = globalEnable;
224
+ }
225
+ }
226
+
227
+ processVariableDeclaration(path, state);
228
+ },
229
+ FunctionDeclaration(path, state) {
230
+ //processFunction(path, state);
231
+ },
232
+ FunctionExpression(path, state) {
233
+ processFunction(enabled, path, state);
234
+ },
235
+ ArrowFunctionExpression(path, state) {
236
+ //processFunction(path, state);
237
+ },
238
+ AssignmentExpression(path, state) {
239
+ processAssignmentExpression(path, state);
240
+ },
241
+ },
242
+ };
243
+ };
@@ -0,0 +1,164 @@
1
+ const t = require('@babel/types');
2
+ const pathModule = require('path');
3
+ let globalEnable = true;
4
+ let enabled = false;
5
+
6
+ function wrapWithLogMethod(t, logMethodName, expression) {
7
+ return t.callExpression(
8
+ t.memberExpression(t.identifier('log'), t.identifier(logMethodName)),
9
+ [t.stringLiteral(expression)]
10
+ );
11
+ }
12
+
13
+ function createLogMessage(path) {
14
+ // Ensure that the parent is a function before accessing its name
15
+ if (
16
+ t.isFunctionDeclaration(path.parent) ||
17
+ t.isFunctionExpression(path.parent)
18
+ ) {
19
+ const functionName = path.parent.id ? path.parent.id.name : 'anonymous';
20
+ const filename = path.hub.file.opts.filename || 'unknown';
21
+ const lineNumber = path.node.loc?.start?.line || 'unknown';
22
+ const filenameWithoutPath = pathModule.basename(filename);
23
+
24
+ return `${filenameWithoutPath}.${functionName}(${lineNumber + 2}): ${
25
+ path.node.arguments[0].value
26
+ }`;
27
+ } else {
28
+ // If the parent is not a function, use "anonymous"
29
+ const filename = path.hub.file.opts.filename || 'unknown';
30
+ const lineNumber = path.node.loc?.start?.line || 'unknown';
31
+ const filenameWithoutPath = pathModule.basename(filename);
32
+ const lineNumberStr = lineNumber === 'unknown' ? '' : `(${lineNumber + 2})`;
33
+
34
+ return `${filenameWithoutPath}${lineNumberStr}: ${path.node.arguments[0].value}`;
35
+ }
36
+ }
37
+
38
+ function isNonStringLiteralOrTemplateLiteral(node) {
39
+ // Check if the node is not a string literal or is a template literal
40
+ return !(t.isStringLiteral(node) || t.isTemplateLiteral(node));
41
+ }
42
+
43
+ function replaceLogStatements(path, logMethodName) {
44
+ if (!enabled) return;
45
+ if (t.isCallExpression(path.node) && !path.node.processed) {
46
+ const callee = path.node.callee;
47
+
48
+ if (
49
+ isNonStringLiteralOrTemplateLiteral(path.node.arguments[0]) &&
50
+ t.isIdentifier(callee) &&
51
+ callee.name === logMethodName
52
+ ) {
53
+ // Handle non-string literal or template literal here
54
+ const functionName = path.parent.id ? `.${path.parent.id.name}` : '';
55
+ const filename = path.hub.file.opts.filename || 'unknown';
56
+ const lineNumber = path.node.loc?.start?.line || 'unknown';
57
+ const filenameWithoutPath = pathModule.basename(filename);
58
+
59
+ let logMessage = `[TRACE] ${filenameWithoutPath}${functionName}(${
60
+ lineNumber + 2
61
+ })`;
62
+
63
+ const logLine = t.blockStatement([
64
+ t.expressionStatement(
65
+ t.callExpression(
66
+ t.memberExpression(t.identifier('App'), t.identifier('debug')),
67
+ [t.stringLiteral(logMessage)]
68
+ )
69
+ ),
70
+ t.expressionStatement(
71
+ t.callExpression(
72
+ t.memberExpression(
73
+ t.identifier('App'),
74
+ t.identifier('flushLogBuffer')
75
+ ),
76
+ []
77
+ )
78
+ ),
79
+ ]);
80
+
81
+ path.insertBefore(logLine);
82
+ path.node.processed = true;
83
+ } else if (
84
+ t.isMemberExpression(callee) &&
85
+ t.isIdentifier(callee.object, { name: 'log' })
86
+ ) {
87
+ // It's log.debug or similar, wrap it with wrapWithLogMethod
88
+ const logMessage = createLogMessage(path, logMethodName);
89
+ path.replaceWith(wrapWithLogMethod(t, logMethodName, logMessage));
90
+ path.node.processed = true;
91
+ } else if (t.isIdentifier(callee) && callee.name === logMethodName) {
92
+ // It's just the specified method, update the argument directly
93
+ path.node.arguments[0].value = createLogMessage(path, logMethodName);
94
+ path.node.processed = true;
95
+ }
96
+ }
97
+ }
98
+
99
+ module.exports = function () {
100
+ let declarationFound = false;
101
+
102
+ return {
103
+ pre() {
104
+ if (this.opts && typeof this.opts.default === 'boolean') {
105
+ enabled = globalEnable = this.opts.default;
106
+ }
107
+ enabled = globalEnable;
108
+ declarationFound = false;
109
+ },
110
+ visitor: {
111
+ VariableDeclaration(path, state) {
112
+ const declarations = path.node.declarations;
113
+ const traceDeclaration = declarations.find(
114
+ (declaration) => declaration.id.name === 'TRACE'
115
+ );
116
+
117
+ if (!declarationFound) {
118
+ if (traceDeclaration) {
119
+ enabled = traceDeclaration.init
120
+ ? traceDeclaration.init.value
121
+ : false;
122
+ declarationFound = true;
123
+ } else {
124
+ enabled = globalEnable;
125
+ }
126
+ }
127
+ },
128
+ FunctionDeclaration(path, state) {
129
+ path.traverse({
130
+ CallExpression(callPath) {
131
+ //replaceLogStatements(callPath, 'trace');
132
+ },
133
+ });
134
+ },
135
+ FunctionExpression(path, state) {
136
+ path.traverse({
137
+ CallExpression(callPath) {
138
+ replaceLogStatements(callPath, 'debug');
139
+ },
140
+ });
141
+ path.traverse({
142
+ CallExpression(callPath) {
143
+ replaceLogStatements(callPath, 'error');
144
+ },
145
+ });
146
+ path.traverse({
147
+ CallExpression(callPath) {
148
+ replaceLogStatements(callPath, 'info');
149
+ },
150
+ });
151
+ path.traverse({
152
+ CallExpression(callPath) {
153
+ replaceLogStatements(callPath, 'dump');
154
+ },
155
+ });
156
+ path.traverse({
157
+ CallExpression(callPath) {
158
+ replaceLogStatements(callPath, 'trace');
159
+ },
160
+ });
161
+ },
162
+ },
163
+ };
164
+ };
package/common/core.ts ADDED
@@ -0,0 +1,2 @@
1
+ // import '@dsf/polyfills/array-polyfill'
2
+ // export { Array } from '@dsf/polyfills/array-polyfill'
package/common/log.ts ADDED
@@ -0,0 +1,57 @@
1
+ import * as global from '@dsf/lib/global'
2
+
3
+ export const debug = (message: any) => {
4
+ App.debug(format(message))
5
+ App.flushLogBuffer()
6
+ }
7
+
8
+ export const info = (message: any) => {
9
+ global.app.log(format(message))
10
+ App.flushLogBuffer()
11
+ }
12
+
13
+ export const error = (message: any) => {
14
+ App.warning(format(message, "ERROR"))
15
+ App.flushLogBuffer()
16
+ }
17
+
18
+ export const warn = (message: any) => {
19
+ App.warning(message)
20
+ App.flushLogBuffer()
21
+ }
22
+
23
+ export const trace = (message: any) => {
24
+ App.debug(format(message, "TRACE"))
25
+ App.flushLogBuffer()
26
+ }
27
+
28
+ export const status = (message: any, log: boolean = true) => {
29
+ App.statusLine(message, log)
30
+ }
31
+
32
+ /**
33
+ * Log the error and raise an exception
34
+ * @param err
35
+ */
36
+ export const raise = (err: string) => {
37
+ error(err)
38
+ throw Error(err)
39
+ }
40
+
41
+ export const dump = (obj: any) => {
42
+ App.debug(`[DUMP]\r\n${JSON.stringify(obj, null, 2)}`)
43
+ App.flushLogBuffer()
44
+ }
45
+
46
+
47
+ const format = (message: string, level?: 'ERROR' | 'TRACE' | 'DUMP' | 'INFO') => {
48
+ if (message == null) {
49
+ return ''
50
+ }
51
+
52
+ let text = message
53
+
54
+ if (level) text = `[${level}] ${text}`
55
+ return text
56
+ }
57
+
@@ -0,0 +1,26 @@
1
+ import { app } from '@dsf/lib/global';
2
+
3
+ export function trace(enabled: boolean = true) {
4
+ return function (target: any, key?: string, descriptor?: PropertyDescriptor) {
5
+ if (key !== undefined && descriptor !== undefined) {
6
+ // Applied to a method
7
+ if (!enabled)
8
+ return descriptor
9
+
10
+ const originalMethod = descriptor.value;
11
+ descriptor.value = function (...args: any[]) {
12
+ app.debug(`[TRACE] Entering method: ${key}`);
13
+ app.flushLogBuffer()
14
+ const result = originalMethod.apply(this, args);
15
+ app.debug(`[TRACE] Exiting method: ${key}`);
16
+ app.flushLogBuffer()
17
+ return result;
18
+ };
19
+
20
+ return descriptor;
21
+ } else if (key === undefined && descriptor === undefined) {
22
+ // Applied to a class
23
+ return target;
24
+ }
25
+ }
26
+ }
@@ -0,0 +1,16 @@
1
+ class CustomActionDefinition {
2
+ text?: string
3
+ description?: string
4
+ icon?: string
5
+ menuPath?: string | boolean
6
+ toolbar?: string
7
+ sort?: number
8
+ group?: string
9
+ shortcut?: string
10
+ bundle?: string | boolean
11
+ }
12
+
13
+ export const action = (action?: CustomActionDefinition) => {
14
+ return (target: Function) => {
15
+ }
16
+ }
@@ -0,0 +1,32 @@
1
+ import { DialogBuilder } from '@dsf/dialog/builders/dialog-builder';
2
+
3
+ export abstract class BasicDialog {
4
+ protected dialog: DzBasicDialog
5
+ protected readonly builder: DialogBuilder
6
+
7
+ protected get add(): DialogBuilder {
8
+ return this.builder
9
+ }
10
+
11
+ constructor(name: string, id?: string) {
12
+ this.builder = new DialogBuilder(name, id)
13
+ }
14
+
15
+ protected abstract build(): void
16
+
17
+ protected init() {
18
+ this.builder.build(() => {
19
+ this.dialog = this.builder.context.dialog
20
+ this.build()
21
+ })
22
+ }
23
+
24
+ run(): boolean {
25
+ this.init()
26
+ return this.dialog.exec()
27
+ }
28
+
29
+ close() {
30
+ this.dialog.close()
31
+ }
32
+ }
@@ -0,0 +1,53 @@
1
+ import { Observable } from '@dsf/lib/observable';
2
+ import { WidgetBuilderBase, createWidget } from './widget-builder';
3
+ import { WidgetBuilderContext } from './widgets-builder';
4
+
5
+ export class ButtonBuilder extends WidgetBuilderBase<DzPushButton> {
6
+ constructor(context: WidgetBuilderContext) {
7
+ super(createWidget(context).build(DzPushButton))
8
+ }
9
+
10
+ text(text: string): this {
11
+ this.widget.text = text
12
+ return this
13
+ }
14
+
15
+ toggle(bind: Observable<boolean>): this {
16
+ this.widget.setCheckable(true)
17
+ this.widget.checked = bind.value
18
+ this.widget.toggled.scriptConnect((value) => {
19
+ bind.value = value
20
+ })
21
+ bind.connect((value) => {
22
+ this.widget.checked = value
23
+ })
24
+ return this
25
+ }
26
+
27
+ clicked(then: Observable<void> | ((button: DzPushButton) => void)): this {
28
+ if (then instanceof Observable) {
29
+ this.widget.clicked.scriptConnect(() => {
30
+ then.trigger()
31
+ })
32
+ }
33
+ else {
34
+ this.widget.clicked.scriptConnect(() => {
35
+ then?.(this.widget)
36
+ })
37
+ }
38
+ return this
39
+ }
40
+
41
+ icon(image: string | Pixmap): this {
42
+ this.widget.pixmap = typeof image === 'string'
43
+ ? new Pixmap(image)
44
+ : image
45
+ return this
46
+ }
47
+
48
+ build(then?: (button: DzPushButton) => void): DzPushButton {
49
+ if (!this.widget.text && this.widget.pixmap) this.widget.collapseEmptySpace = true
50
+ then?.(this.widget)
51
+ return this.widget
52
+ }
53
+ }
@@ -0,0 +1,30 @@
1
+ import { Observable } from '@dsf/lib/observable';
2
+ import { WidgetBuilderBase, createWidget } from './widget-builder';
3
+ import { WidgetBuilderContext } from './widgets-builder';
4
+
5
+ export default class CheckBoxBuilder extends WidgetBuilderBase<DzCheckBox> {
6
+ constructor(context: WidgetBuilderContext) {
7
+ super(createWidget(context).build(DzCheckBox))
8
+ }
9
+
10
+ label(text: string): this {
11
+ this.widget.text = text ?? ''
12
+ return this
13
+ }
14
+
15
+ value(property: Observable<boolean>): this {
16
+ this.widget.checked = property.value
17
+ property.connect((value) => {
18
+ this.widget.checked = value
19
+ })
20
+ this.widget.toggled.scriptConnect((value) => {
21
+ property.value = value
22
+ })
23
+ return this
24
+ }
25
+
26
+ build(): DzCheckBox {
27
+ return this.widget
28
+ }
29
+
30
+ }
@@ -0,0 +1,36 @@
1
+ import { Observable } from '@dsf/lib/observable';
2
+ import { WidgetBuilderBase, createWidget } from './widget-builder';
3
+ import { WidgetBuilderContext } from './widgets-builder';
4
+
5
+ export class ComboBoxBuilder extends WidgetBuilderBase<DzComboBox>{
6
+ items(items: string[]): this {
7
+ items.forEach((item, idx) => {
8
+ if (!item)
9
+ this.widget.insertSeparator(idx)
10
+ else
11
+ this.widget.insertItem(idx, item)
12
+ });
13
+ return this
14
+ }
15
+
16
+ selected(bind: Observable<string>): this {
17
+ this.widget.currentText = bind.value
18
+ bind.connect((text) => {
19
+ if (this.widget.findText(text) >= 0)
20
+ this.widget.currentText = text
21
+ })
22
+ this.widget.textChanged.scriptConnect((text) => {
23
+ bind.value = text
24
+ })
25
+ return this
26
+ }
27
+
28
+ constructor(context: WidgetBuilderContext) {
29
+ super(createWidget(context).build(DzComboBox))
30
+ }
31
+
32
+ build(then?: (comboBox: DzComboBox) => void) {
33
+ then?.(this.widget)
34
+ return this.widget
35
+ }
36
+ }