From 3bf442f00b472d46b76da015ffca9edf30bbf2a9 Mon Sep 17 00:00:00 2001 From: cocopon Date: Thu, 25 Mar 2021 03:59:03 +0900 Subject: [PATCH 01/10] Implement disabling views, #215 --- lib/api/button-test.ts | 65 +++++++++----- lib/api/button.ts | 12 ++- lib/api/folder-test.ts | 2 + lib/api/folder.ts | 14 +++- lib/api/input-binding-test.ts | 17 +++- lib/api/input-binding.ts | 12 ++- lib/api/monitor-binding-test.ts | 2 + lib/api/monitor-binding.ts | 4 +- lib/api/separator-test.ts | 29 +++++++ lib/api/separator.ts | 4 +- lib/api/types.ts | 6 +- lib/index.ts | 2 + lib/pane/button-test.ts | 43 ++++++++++ lib/pane/input-test.ts | 22 +++++ lib/pane/tweakpane-test.ts | 2 + lib/pane/ui-test.ts | 20 ----- .../blade/button/controller/button-test.ts | 2 + lib/plugin/blade/button/controller/button.ts | 5 ++ lib/plugin/blade/button/view.ts | 18 +++- .../blade/common/controller/blade-test.ts | 16 +--- lib/plugin/blade/common/controller/blade.ts | 9 +- .../blade/common/controller/container-util.ts | 4 +- .../common/controller/input-binding-test.ts | 2 + .../blade/common/controller/input-binding.ts | 6 ++ .../common/controller/monitor-binding-test.ts | 2 + .../common/controller/monitor-binding.ts | 6 ++ .../blade/common/model/blade-rack-test.ts | 8 +- lib/plugin/blade/common/model/blade-rack.ts | 11 ++- lib/plugin/blade/common/model/blade-test.ts | 28 +------ lib/plugin/blade/common/model/blade.ts | 31 +------ lib/plugin/blade/folder/controller-test.ts | 9 ++ lib/plugin/blade/folder/controller.ts | 6 ++ lib/plugin/blade/folder/root.ts | 6 +- lib/plugin/blade/folder/view.ts | 14 +++- lib/plugin/blade/labeled/controller.ts | 6 ++ lib/plugin/blade/labeled/view.ts | 4 +- lib/plugin/blade/separator/controller.ts | 9 +- lib/plugin/blade/separator/view.ts | 9 +- lib/plugin/common/controller/controller.ts | 4 +- lib/plugin/common/model/value-map-test.ts | 14 ++++ lib/plugin/common/model/value-map.ts | 22 +++-- lib/plugin/common/view/view-test.ts | 45 ++++++++++ lib/plugin/common/view/view.ts | 84 +++++++++++++++++++ lib/plugin/input-binding-test.ts | 3 +- lib/plugin/input-binding.ts | 5 ++ .../input-bindings/boolean/controller.ts | 5 ++ lib/plugin/input-bindings/boolean/plugin.ts | 35 ++++---- lib/plugin/input-bindings/boolean/view.ts | 10 ++- .../color/controller/a-palette.ts | 4 + .../color/controller/color-picker-test.ts | 3 + .../color/controller/color-picker.ts | 10 +++ .../color/controller/color-swatch-text.ts | 6 ++ .../color/controller/color-swatch.ts | 5 ++ .../color/controller/color-text-test.ts | 3 + .../color/controller/color-text.ts | 7 ++ .../color/controller/h-palette.ts | 4 + .../color/controller/sv-palette.ts | 4 + .../input-bindings/color/plugin-number.ts | 1 + .../input-bindings/color/plugin-object.ts | 1 + .../input-bindings/color/plugin-string.ts | 1 + .../common/controller/list-test.ts | 3 + .../input-bindings/common/controller/list.ts | 5 ++ .../common/controller/point-nd-text-test.ts | 2 + .../common/controller/point-nd-text.ts | 5 ++ .../common/controller/text-test.ts | 3 + .../input-bindings/common/controller/text.ts | 5 ++ .../input-bindings/common/view/text-test.ts | 6 +- lib/plugin/input-bindings/common/view/text.ts | 18 +++- .../number/controller/number-text-test.ts | 2 + .../number/controller/number-text.ts | 9 +- .../number/controller/slider-text.ts | 6 ++ .../number/controller/slider.ts | 7 +- lib/plugin/input-bindings/number/plugin.ts | 3 + .../input-bindings/number/view/number-text.ts | 10 ++- .../input-bindings/number/view/slider-test.ts | 4 + .../input-bindings/number/view/slider.ts | 4 +- .../point-2d/controller/point-2d-pad-text.ts | 6 ++ .../point-2d/controller/point-2d-pad.ts | 6 +- lib/plugin/input-bindings/point-2d/plugin.ts | 46 ++++------ lib/plugin/input-bindings/point-3d/plugin.ts | 37 ++++---- lib/plugin/input-bindings/point-4d/plugin.ts | 33 ++++---- lib/plugin/input-bindings/string/plugin.ts | 43 +++++----- lib/plugin/monitor-binding-test.ts | 3 +- lib/plugin/monitor-bindings/boolean/plugin.ts | 3 + .../common/controller/multi-log.ts | 4 + .../common/controller/single-log.ts | 4 + .../monitor-bindings/common/view/list.ts | 16 ++-- .../number/controller/graph-log.ts | 4 + lib/plugin/monitor-bindings/number/plugin.ts | 4 + lib/plugin/monitor-bindings/string/plugin.ts | 3 + lib/sass/view/_labeled.scss | 3 + lib/sass/view/_root.scss | 5 +- lib/sass/view/common/_button.scss | 3 + lib/sass/view/common/_input.scss | 3 + src/doc/template/misc.html | 31 ++++++- src/doc/ts/route/misc.ts | 28 +++++++ test-module/plugin/src/index.ts | 17 +++- 97 files changed, 851 insertions(+), 286 deletions(-) create mode 100644 lib/api/separator-test.ts create mode 100644 lib/pane/button-test.ts create mode 100644 lib/plugin/common/view/view-test.ts diff --git a/lib/api/button-test.ts b/lib/api/button-test.ts index d4a0d74f8..ce16362b4 100644 --- a/lib/api/button-test.ts +++ b/lib/api/button-test.ts @@ -5,50 +5,69 @@ import {TestUtil} from '../misc/test-util'; import {ButtonController} from '../plugin/blade/button/controller/button'; import {Blade} from '../plugin/blade/common/model/blade'; import {LabeledController} from '../plugin/blade/labeled/controller'; +import {defaultViewProps} from '../plugin/common/view/view'; import {ButtonApi} from './button'; +function createApi(doc: Document): ButtonApi { + const c = new LabeledController(doc, { + blade: new Blade(), + valueController: new ButtonController(doc, { + title: 'Button', + viewProps: defaultViewProps(), + }), + }); + return new ButtonApi(c); +} + describe(ButtonApi.name, () => { it('should listen click event', (done) => { const doc = TestUtil.createWindow().document; - const c = new LabeledController(doc, { - blade: new Blade(), - valueController: new ButtonController(doc, { - title: 'Button', - }), - }); - const api = new ButtonApi(c); + const api = createApi(doc); api.on('click', () => { done(); }); - c.valueController.button.click(); + api.controller.valueController.button.click(); + }); + + it('should be hidden', () => { + const doc = TestUtil.createWindow().document; + const api = createApi(doc); + assert.isFalse(api.hidden); + + api.hidden = true; + assert.isTrue( + api.controller.view.element.classList.contains('tp-v-hidden'), + ); + }); + + it('should be disabled', () => { + const doc = TestUtil.createWindow().document; + const api = createApi(doc); + const c = api.controller.valueController as ButtonController; + + assert.isFalse(api.disabled); + assert.isFalse(c.view.buttonElement.disabled); + + api.disabled = true; + + assert.isTrue(c.view.element.classList.contains('tp-v-disabled')); + assert.isTrue(c.view.buttonElement.disabled); }); it('should have chainable event handling', () => { const doc = TestUtil.createWindow().document; - const c = new LabeledController(doc, { - blade: new Blade(), - valueController: new ButtonController(doc, { - title: 'Button', - }), - }); - const api = new ButtonApi(c); + const api = createApi(doc); const retval = api.on('click', () => {}); assert.strictEqual(retval, api); }); it('should bind `this` within handler to API', (done) => { const doc = TestUtil.createWindow().document; - const c = new LabeledController(doc, { - blade: new Blade(), - valueController: new ButtonController(doc, { - title: 'Button', - }), - }); - const api = new ButtonApi(c); + const api = createApi(doc); api.on('click', function(this: any) { assert.strictEqual(this, api); done(); }); - c.valueController.button.click(); + api.controller.valueController.button.click(); }); }); diff --git a/lib/api/button.ts b/lib/api/button.ts index 74aa87ddd..96ddca947 100644 --- a/lib/api/button.ts +++ b/lib/api/button.ts @@ -20,12 +20,20 @@ export class ButtonApi implements BladeApi { this.controller = buttonController; } + get disabled(): boolean { + return this.controller.viewProps.get('disabled'); + } + + set disabled(disabled: boolean) { + this.controller.viewProps.set('disabled', disabled); + } + get hidden(): boolean { - return this.controller.blade.hidden; + return this.controller.viewProps.get('hidden'); } set hidden(hidden: boolean) { - this.controller.blade.hidden = hidden; + this.controller.viewProps.set('hidden', hidden); } public dispose(): void { diff --git a/lib/api/folder-test.ts b/lib/api/folder-test.ts index dbb6adda3..9cf6fd878 100644 --- a/lib/api/folder-test.ts +++ b/lib/api/folder-test.ts @@ -8,6 +8,7 @@ import {Blade} from '../plugin/blade/common/model/blade'; import {FolderController} from '../plugin/blade/folder/controller'; import {LabeledController} from '../plugin/blade/labeled/controller'; import {SeparatorController} from '../plugin/blade/separator/controller'; +import {defaultViewProps} from '../plugin/common/view/view'; import {Color} from '../plugin/input-bindings/color/model/color'; import {NumberTextController} from '../plugin/input-bindings/number/controller/number-text'; import {SingleLogMonitorController} from '../plugin/monitor-bindings/common/controller/single-log'; @@ -21,6 +22,7 @@ function createApi(): FolderApi { const c = new FolderController(doc, { blade: new Blade(), title: 'Folder', + viewProps: defaultViewProps(), }); return new FolderApi(c); } diff --git a/lib/api/folder.ts b/lib/api/folder.ts index e0bb74c57..54260b19d 100644 --- a/lib/api/folder.ts +++ b/lib/api/folder.ts @@ -9,6 +9,7 @@ import {LabeledController} from '../plugin/blade/labeled/controller'; import {SeparatorController} from '../plugin/blade/separator/controller'; import {Emitter} from '../plugin/common/model/emitter'; import {TpError} from '../plugin/common/tp-error'; +import {defaultViewProps} from '../plugin/common/view/view'; import {BladeApi} from './blade-api'; import {ButtonApi} from './button'; import {InputBindingApi} from './input-binding'; @@ -80,11 +81,11 @@ export class FolderApi implements BladeApi { } get hidden(): boolean { - return this.controller.blade.hidden; + return this.controller.viewProps.get('hidden'); } set hidden(hidden: boolean) { - this.controller.blade.hidden = hidden; + this.controller.viewProps.set('hidden', hidden); } public dispose(): void { @@ -131,6 +132,7 @@ export class FolderApi implements BladeApi { const bc = new FolderController(this.controller.document, { ...params, blade: new Blade(), + viewProps: defaultViewProps(), }); this.controller.bladeRack.add(bc, params.index); @@ -144,7 +146,12 @@ export class FolderApi implements BladeApi { const bc = new LabeledController(doc, { blade: new Blade(), label: params.label, - valueController: new ButtonController(doc, params), + valueController: new ButtonController(doc, { + ...params, + viewProps: defaultViewProps({ + disabled: params.disabled, + }), + }), }); this.controller.bladeRack.add(bc, params.index); @@ -157,6 +164,7 @@ export class FolderApi implements BladeApi { const params = opt_params || {}; const bc = new SeparatorController(this.controller.document, { blade: new Blade(), + viewProps: defaultViewProps(), }); this.controller.bladeRack.add(bc, params.index); diff --git a/lib/api/input-binding-test.ts b/lib/api/input-binding-test.ts index d0b9e3063..bef18159c 100644 --- a/lib/api/input-binding-test.ts +++ b/lib/api/input-binding-test.ts @@ -13,6 +13,7 @@ import { import {numberFromUnknown} from '../plugin/common/converter/number'; import {Value} from '../plugin/common/model/value'; import {writePrimitive} from '../plugin/common/primitive'; +import {defaultViewProps} from '../plugin/common/view/view'; import {NumberTextController} from '../plugin/input-bindings/number/controller/number-text'; import {InputBindingApi} from './input-binding'; import {TpChangeEvent} from './tp-event'; @@ -26,6 +27,7 @@ function createApi(target: BindingTarget) { formatter: createNumberFormatter(0), parser: parseNumber, value: value, + viewProps: defaultViewProps(), }); const bc = new InputBindingController(doc, { binding: new InputBinding({ @@ -81,7 +83,7 @@ describe(InputBindingApi.name, () => { assert.strictEqual(api.controller.binding.value.rawValue, 123); }); - it('should hide', () => { + it('should be hidden', () => { const PARAMS = { foo: 0, }; @@ -93,4 +95,17 @@ describe(InputBindingApi.name, () => { api.controller.view.element.classList.contains('tp-v-hidden'), ); }); + + it('should be disabled', () => { + const PARAMS = { + foo: 0, + }; + const api = createApi(new BindingTarget(PARAMS, 'foo')); + assert.strictEqual(api.disabled, false); + + api.disabled = true; + assert.isTrue( + api.controller.view.element.classList.contains('tp-v-disabled'), + ); + }); }); diff --git a/lib/api/input-binding.ts b/lib/api/input-binding.ts index 001554634..7abff14ae 100644 --- a/lib/api/input-binding.ts +++ b/lib/api/input-binding.ts @@ -35,12 +35,20 @@ export class InputBindingApi implements BladeApi { this.controller.binding.emitter.on('change', this.onBindingChange_); } + get disabled(): boolean { + return this.controller.viewProps.get('disabled'); + } + + set disabled(disabled: boolean) { + this.controller.viewProps.set('disabled', disabled); + } + get hidden(): boolean { - return this.controller.blade.hidden; + return this.controller.viewProps.get('hidden'); } set hidden(hidden: boolean) { - this.controller.blade.hidden = hidden; + this.controller.viewProps.set('hidden', hidden); } public dispose(): void { diff --git a/lib/api/monitor-binding-test.ts b/lib/api/monitor-binding-test.ts index f4516f55a..243676d49 100644 --- a/lib/api/monitor-binding-test.ts +++ b/lib/api/monitor-binding-test.ts @@ -11,6 +11,7 @@ import {createNumberFormatter} from '../plugin/common/converter/number'; import {numberFromUnknown} from '../plugin/common/converter/number'; import {Buffer} from '../plugin/common/model/buffered-value'; import {Value} from '../plugin/common/model/value'; +import {defaultViewProps} from '../plugin/common/view/view'; import {SingleLogMonitorController} from '../plugin/monitor-bindings/common/controller/single-log'; import {MonitorBindingApi} from './monitor-binding'; import {TpUpdateEvent} from './tp-event'; @@ -21,6 +22,7 @@ function createApi(target: BindingTarget) { const mc = new SingleLogMonitorController(doc, { formatter: createNumberFormatter(0), value: value, + viewProps: defaultViewProps(), }); const bc = new MonitorBindingController(doc, { binding: new MonitorBinding({ diff --git a/lib/api/monitor-binding.ts b/lib/api/monitor-binding.ts index 3fca51504..f016761e6 100644 --- a/lib/api/monitor-binding.ts +++ b/lib/api/monitor-binding.ts @@ -34,11 +34,11 @@ export class MonitorBindingApi implements BladeApi { } get hidden(): boolean { - return this.controller.blade.hidden; + return this.controller.viewProps.get('hidden'); } set hidden(hidden: boolean) { - this.controller.blade.hidden = hidden; + this.controller.viewProps.set('hidden', hidden); } public dispose(): void { diff --git a/lib/api/separator-test.ts b/lib/api/separator-test.ts new file mode 100644 index 000000000..dedecee69 --- /dev/null +++ b/lib/api/separator-test.ts @@ -0,0 +1,29 @@ +import {assert} from 'chai'; +import {describe, it} from 'mocha'; + +import {TestUtil} from '../misc/test-util'; +import {Blade} from '../plugin/blade/common/model/blade'; +import {SeparatorController} from '../plugin/blade/separator/controller'; +import {defaultViewProps} from '../plugin/common/view/view'; +import {SeparatorApi} from './separator'; + +function createApi(doc: Document): SeparatorApi { + const c = new SeparatorController(doc, { + blade: new Blade(), + viewProps: defaultViewProps(), + }); + return new SeparatorApi(c); +} + +describe(SeparatorApi.name, () => { + it('should hide', () => { + const doc = TestUtil.createWindow().document; + const api = createApi(doc); + assert.strictEqual(api.hidden, false); + + api.hidden = true; + assert.isTrue( + api.controller.view.element.classList.contains('tp-v-hidden'), + ); + }); +}); diff --git a/lib/api/separator.ts b/lib/api/separator.ts index e7f05c8ce..b24874bf3 100644 --- a/lib/api/separator.ts +++ b/lib/api/separator.ts @@ -15,11 +15,11 @@ export class SeparatorApi implements BladeApi { } get hidden(): boolean { - return this.controller.blade.hidden; + return this.controller.viewProps.get('hidden'); } set hidden(hidden: boolean) { - this.controller.blade.hidden = hidden; + this.controller.viewProps.set('hidden', hidden); } public dispose(): void { diff --git a/lib/api/types.ts b/lib/api/types.ts index 00bcfb8fa..c30768c5e 100644 --- a/lib/api/types.ts +++ b/lib/api/types.ts @@ -28,6 +28,7 @@ export interface Point2dYParams extends PointDimensionParams { } export interface BaseInputParams extends BaseParams, LabelableParams { + disabled?: boolean; presetKey?: string; view?: string; } @@ -108,11 +109,14 @@ export type MonitorParams = export interface ButtonParams extends BaseParams, LabelableParams { title: string; + + disabled?: boolean; } export interface FolderParams extends BaseParams { - expanded?: boolean; title: string; + + expanded?: boolean; } export type SeparatorParams = BaseParams; diff --git a/lib/index.ts b/lib/index.ts index 4e88e058a..ad0fe6b8f 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -7,6 +7,7 @@ import {RootController} from './plugin/blade/folder/root'; import {getWindowDocument} from './plugin/common/dom-util'; import {TpError} from './plugin/common/tp-error'; import {ClassName} from './plugin/common/view/class-name'; +import {defaultViewProps} from './plugin/common/view/view'; import {InputBindingPlugin} from './plugin/input-binding'; import {BooleanInputPlugin} from './plugin/input-bindings/boolean/plugin'; import {NumberColorInputPlugin} from './plugin/input-bindings/color/plugin-number'; @@ -65,6 +66,7 @@ export default class Tweakpane extends RootApi { expanded: config.expanded, blade: new Blade(), title: config.title, + viewProps: defaultViewProps(), }); super(rootController); diff --git a/lib/pane/button-test.ts b/lib/pane/button-test.ts new file mode 100644 index 000000000..b62176925 --- /dev/null +++ b/lib/pane/button-test.ts @@ -0,0 +1,43 @@ +import {assert} from 'chai'; +import {describe, it} from 'mocha'; + +import Tweakpane from '../index'; +import {TestUtil} from '../misc/test-util'; + +function createApi(title?: string): Tweakpane { + return new Tweakpane({ + document: TestUtil.createWindow().document, + title: title, + }); +} + +describe(Tweakpane.name, () => { + it('should add button', () => { + const pane = createApi(); + const b = pane.addButton({ + title: 'push', + }); + assert.strictEqual(b.controller.valueController.button.title, 'push'); + }); + + it('should add disabled button', () => { + const pane = createApi(); + const b = pane.addButton({ + disabled: true, + title: 'push', + }); + assert.isTrue(b.controller.viewProps.get('disabled')); + }); + + it('should add button with label', () => { + const pane = createApi(); + const b = pane.addButton({ + label: 'foobarlabel', + title: 'push', + }); + assert.strictEqual(b.controller.valueController.button.title, 'push'); + assert.isTrue( + b.controller.view.element.innerHTML.indexOf('foobarlabel') >= 0, + ); + }); +}); diff --git a/lib/pane/input-test.ts b/lib/pane/input-test.ts index 063d9d46b..7f91eff91 100644 --- a/lib/pane/input-test.ts +++ b/lib/pane/input-test.ts @@ -156,4 +156,26 @@ describe(Tweakpane.name, () => { }); bapi.controller.binding.value.rawValue = 2; }); + + it('should apply disabled of input binding params', () => { + const PARAMS = {foo: 1}; + const pane = createPane(); + const bapi = pane.addInput(PARAMS, 'foo', { + disabled: true, + }); + assert.isTrue(bapi.disabled); + assert.isTrue(bapi.controller.viewProps.get('disabled')); + }); + + it('should apply disabled of input binding', () => { + const PARAMS = {foo: 1}; + const pane = createPane(); + const bapi = pane.addInput(PARAMS, 'foo'); + + assert.isFalse(bapi.disabled); + assert.isFalse(bapi.controller.viewProps.get('disabled')); + bapi.disabled = true; + assert.isTrue(bapi.disabled); + assert.isTrue(bapi.controller.viewProps.get('disabled')); + }); }); diff --git a/lib/pane/tweakpane-test.ts b/lib/pane/tweakpane-test.ts index d84c86bc1..35ac64f83 100644 --- a/lib/pane/tweakpane-test.ts +++ b/lib/pane/tweakpane-test.ts @@ -10,6 +10,7 @@ import { import {ValueMap} from '../plugin/common/model/value-map'; import {equalsPrimitive, writePrimitive} from '../plugin/common/primitive'; import {TpError} from '../plugin/common/tp-error'; +import {defaultViewProps} from '../plugin/common/view/view'; import {TextController} from '../plugin/input-bindings/common/controller/text'; describe(Tweakpane.name, () => { @@ -103,6 +104,7 @@ describe(Tweakpane.name, () => { formatter: formatString, }), value: args.value, + viewProps: defaultViewProps(), }); }, }, diff --git a/lib/pane/ui-test.ts b/lib/pane/ui-test.ts index 236140eb9..84f0b4496 100644 --- a/lib/pane/ui-test.ts +++ b/lib/pane/ui-test.ts @@ -19,26 +19,6 @@ function createApi(title?: string): Tweakpane { } describe(Tweakpane.name, () => { - it('should add button', () => { - const pane = createApi(); - const b = pane.addButton({ - title: 'push', - }); - assert.strictEqual(b.controller.valueController.button.title, 'push'); - }); - - it('should add button with label', () => { - const pane = createApi(); - const b = pane.addButton({ - label: 'foobarlabel', - title: 'push', - }); - assert.strictEqual(b.controller.valueController.button.title, 'push'); - assert.isTrue( - b.controller.view.element.innerHTML.indexOf('foobarlabel') >= 0, - ); - }); - it('should add folder', () => { const pane = createApi(); const f = pane.addFolder({ diff --git a/lib/plugin/blade/button/controller/button-test.ts b/lib/plugin/blade/button/controller/button-test.ts index f6246bf72..d41fcca7e 100644 --- a/lib/plugin/blade/button/controller/button-test.ts +++ b/lib/plugin/blade/button/controller/button-test.ts @@ -2,6 +2,7 @@ import {assert} from 'chai'; import {describe, it} from 'mocha'; import {TestUtil} from '../../../../misc/test-util'; +import {defaultViewProps} from '../../../common/view/view'; import {ButtonController} from './button'; describe(ButtonController.name, () => { @@ -9,6 +10,7 @@ describe(ButtonController.name, () => { const doc = TestUtil.createWindow().document; const c = new ButtonController(doc, { title: 'Push', + viewProps: defaultViewProps(), }); c.button.emitter.on('click', () => { diff --git a/lib/plugin/blade/button/controller/button.ts b/lib/plugin/blade/button/controller/button.ts index 327650350..17d55ebf8 100644 --- a/lib/plugin/blade/button/controller/button.ts +++ b/lib/plugin/blade/button/controller/button.ts @@ -1,9 +1,11 @@ import {Controller} from '../../../common/controller/controller'; +import {ViewProps} from '../../../common/view/view'; import {Button} from '../model/button'; import {ButtonView} from '../view'; interface Config { title: string; + viewProps: ViewProps; } /** @@ -12,14 +14,17 @@ interface Config { export class ButtonController implements Controller { public readonly button: Button; public readonly view: ButtonView; + public readonly viewProps: ViewProps; constructor(doc: Document, config: Config) { this.onButtonClick_ = this.onButtonClick_.bind(this); this.button = new Button(config.title); + this.viewProps = config.viewProps; this.view = new ButtonView(doc, { button: this.button, + viewProps: this.viewProps, }); this.view.buttonElement.addEventListener('click', this.onButtonClick_); } diff --git a/lib/plugin/blade/button/view.ts b/lib/plugin/blade/button/view.ts index 9f60027eb..d10a0ad92 100644 --- a/lib/plugin/blade/button/view.ts +++ b/lib/plugin/blade/button/view.ts @@ -1,9 +1,15 @@ import {ClassName} from '../../common/view/class-name'; -import {View} from '../../common/view/view'; +import { + bindDisabled, + bindViewProps, + View, + ViewProps, +} from '../../common/view/view'; import {Button} from './model/button'; interface Config { button: Button; + viewProps: ViewProps; } const className = ClassName('btn'); @@ -13,18 +19,22 @@ const className = ClassName('btn'); */ export class ButtonView implements View { public readonly element: HTMLElement; - public readonly button: Button; public readonly buttonElement: HTMLButtonElement; + private readonly button_: Button; + private readonly viewProps_: ViewProps; constructor(doc: Document, config: Config) { - this.button = config.button; + this.button_ = config.button; + this.viewProps_ = config.viewProps; this.element = doc.createElement('div'); this.element.classList.add(className()); + bindViewProps(this.viewProps_, this.element); const buttonElem = doc.createElement('button'); buttonElem.classList.add(className('b')); - buttonElem.textContent = this.button.title; + buttonElem.textContent = this.button_.title; + bindDisabled(this.viewProps_, buttonElem); this.element.appendChild(buttonElem); this.buttonElement = buttonElem; } diff --git a/lib/plugin/blade/common/controller/blade-test.ts b/lib/plugin/blade/common/controller/blade-test.ts index d91403fe4..35c272ca9 100644 --- a/lib/plugin/blade/common/controller/blade-test.ts +++ b/lib/plugin/blade/common/controller/blade-test.ts @@ -2,7 +2,7 @@ import {assert} from 'chai'; import {describe, it} from 'mocha'; import {TestUtil} from '../../../../misc/test-util'; -import {View} from '../../../common/view/view'; +import {defaultViewProps, View} from '../../../common/view/view'; import {Blade} from '../model/blade'; import {BladeController, setUpBladeController} from './blade'; @@ -19,6 +19,7 @@ class TestView implements View { class TestController implements BladeController { public readonly blade: Blade; public readonly view: TestView; + public readonly viewProps = defaultViewProps(); constructor(doc: Document) { this.blade = new Blade(); @@ -27,18 +28,7 @@ class TestController implements BladeController { } } -describe('BladeController', () => { - it('should apply hidden', () => { - const doc = TestUtil.createWindow().document; - const c = new TestController(doc); - const [m, v] = [c.blade, c.view]; - assert.isNotTrue(v.element.classList.contains('tp-v-hidden')); - m.hidden = true; - assert.isTrue(v.element.classList.contains('tp-v-hidden')); - m.hidden = false; - assert.isNotTrue(v.element.classList.contains('tp-v-hidden')); - }); - +describe(setUpBladeController.name, () => { it('should apply view position', () => { const doc = TestUtil.createWindow().document; const c = new TestController(doc); diff --git a/lib/plugin/blade/common/controller/blade.ts b/lib/plugin/blade/common/controller/blade.ts index e83106d5c..0dd4464bc 100644 --- a/lib/plugin/blade/common/controller/blade.ts +++ b/lib/plugin/blade/common/controller/blade.ts @@ -15,14 +15,7 @@ export function setUpBladeController(c: BladeController) { const blade = c.blade; blade.emitter.on('change', (ev: BladeEvents['change']) => { - if (ev.propertyName === 'hidden') { - const hiddenClass = className(undefined, 'hidden'); - if (blade.hidden) { - elem.classList.add(hiddenClass); - } else { - elem.classList.remove(hiddenClass); - } - } else if (ev.propertyName === 'positions') { + if (ev.propertyName === 'positions') { getAllBladePositions().forEach((pos) => { elem.classList.remove(className(undefined, pos)); }); diff --git a/lib/plugin/blade/common/controller/container-util.ts b/lib/plugin/blade/common/controller/container-util.ts index 32e2e8428..eb4b6480f 100644 --- a/lib/plugin/blade/common/controller/container-util.ts +++ b/lib/plugin/blade/common/controller/container-util.ts @@ -7,7 +7,9 @@ import {BladePosition} from '../model/blade-positions'; import {BladeRack} from '../model/blade-rack'; export function updateAllItemsPositions(bladeRack: BladeRack): void { - const visibleItems = bladeRack.items.filter((bc) => !bc.blade.hidden); + const visibleItems = bladeRack.items.filter( + (bc) => !bc.viewProps.get('hidden'), + ); const firstVisibleItem = visibleItems[0]; const lastVisibleItem = visibleItems[visibleItems.length - 1]; diff --git a/lib/plugin/blade/common/controller/input-binding-test.ts b/lib/plugin/blade/common/controller/input-binding-test.ts index 70c6d8f45..dd4ffc47e 100644 --- a/lib/plugin/blade/common/controller/input-binding-test.ts +++ b/lib/plugin/blade/common/controller/input-binding-test.ts @@ -11,6 +11,7 @@ import { import {numberFromUnknown} from '../../../common/converter/number'; import {Value} from '../../../common/model/value'; import {ValueMap} from '../../../common/model/value-map'; +import {defaultViewProps} from '../../../common/view/view'; import {TextController} from '../../../input-bindings/common/controller/text'; import {Blade} from '../model/blade'; import {InputBindingController} from './input-binding'; @@ -34,6 +35,7 @@ describe(InputBindingController.name, () => { formatter: createNumberFormatter(0), }), value: value, + viewProps: defaultViewProps(), }); const bc = new InputBindingController(doc, { binding: binding, diff --git a/lib/plugin/blade/common/controller/input-binding.ts b/lib/plugin/blade/common/controller/input-binding.ts index 07a7b4b48..e34d67e09 100644 --- a/lib/plugin/blade/common/controller/input-binding.ts +++ b/lib/plugin/blade/common/controller/input-binding.ts @@ -1,5 +1,6 @@ import {InputBinding} from '../../../common/binding/input'; import {ValueController} from '../../../common/controller/value'; +import {ViewProps} from '../../../common/view/view'; import {LabeledView} from '../../labeled/view'; import {Blade} from '../model/blade'; import {BladeController, setUpBladeController} from './blade'; @@ -26,6 +27,7 @@ export class InputBindingController implements BladeController { this.view = new LabeledView(doc, { label: config.label, + viewProps: this.viewProps, }); this.view.valueElement.appendChild(this.controller.view.element); @@ -33,6 +35,10 @@ export class InputBindingController implements BladeController { setUpBladeController(this); } + get viewProps(): ViewProps { + return this.controller.viewProps; + } + public onDispose() { if (this.controller.onDispose) { this.controller.onDispose(); diff --git a/lib/plugin/blade/common/controller/monitor-binding-test.ts b/lib/plugin/blade/common/controller/monitor-binding-test.ts index 9f4ce3b0e..3c1e921f2 100644 --- a/lib/plugin/blade/common/controller/monitor-binding-test.ts +++ b/lib/plugin/blade/common/controller/monitor-binding-test.ts @@ -8,6 +8,7 @@ import {ManualTicker} from '../../../common/binding/ticker/manual'; import {createNumberFormatter} from '../../../common/converter/number'; import {numberFromUnknown} from '../../../common/converter/number'; import {Value} from '../../../common/model/value'; +import {defaultViewProps} from '../../../common/view/view'; import {SingleLogMonitorController} from '../../../monitor-bindings/common/controller/single-log'; import {Blade} from '../model/blade'; import {MonitorBindingController} from './monitor-binding'; @@ -28,6 +29,7 @@ describe(MonitorBindingController.name, () => { const controller = new SingleLogMonitorController(doc, { formatter: createNumberFormatter(0), value: value, + viewProps: defaultViewProps(), }); const bc = new MonitorBindingController(doc, { binding: binding, diff --git a/lib/plugin/blade/common/controller/monitor-binding.ts b/lib/plugin/blade/common/controller/monitor-binding.ts index e10e73a6e..0bcb3e3e3 100644 --- a/lib/plugin/blade/common/controller/monitor-binding.ts +++ b/lib/plugin/blade/common/controller/monitor-binding.ts @@ -1,6 +1,7 @@ import {MonitorBinding} from '../../../common/binding/monitor'; import {ValueController} from '../../../common/controller/value'; import {Buffer} from '../../../common/model/buffered-value'; +import {ViewProps} from '../../../common/view/view'; import {LabeledView} from '../../labeled/view'; import {Blade} from '../model/blade'; import {BladeController, setUpBladeController} from './blade'; @@ -27,6 +28,7 @@ export class MonitorBindingController implements BladeController { this.view = new LabeledView(doc, { label: config.label, + viewProps: this.viewProps, }); this.view.valueElement.appendChild(this.controller.view.element); @@ -37,6 +39,10 @@ export class MonitorBindingController implements BladeController { setUpBladeController(this); } + get viewProps(): ViewProps { + return this.controller.viewProps; + } + public onDispose() { if (this.controller.onDispose) { this.controller.onDispose(); diff --git a/lib/plugin/blade/common/model/blade-rack-test.ts b/lib/plugin/blade/common/model/blade-rack-test.ts index 7f9bf9bb8..9e92dd7c8 100644 --- a/lib/plugin/blade/common/model/blade-rack-test.ts +++ b/lib/plugin/blade/common/model/blade-rack-test.ts @@ -12,6 +12,7 @@ import {stringFromUnknown} from '../../../common/converter/string'; import {Buffer} from '../../../common/model/buffered-value'; import {Value} from '../../../common/model/value'; import {writePrimitive} from '../../../common/primitive'; +import {defaultViewProps} from '../../../common/view/view'; import {CheckboxController} from '../../../input-bindings/boolean/controller'; import {SingleLogMonitorController} from '../../../monitor-bindings/common/controller/single-log'; import {FolderController} from '../../folder/controller'; @@ -34,6 +35,7 @@ function createInputBindingController( binding: b, controller: new CheckboxController(doc, { value: b.value, + viewProps: defaultViewProps(), }), label: '', }); @@ -54,6 +56,7 @@ function createMonitorBindingController( controller: new SingleLogMonitorController(doc, { formatter: (v) => String(v), value: b.value, + viewProps: defaultViewProps(), }), label: '', }); @@ -63,6 +66,7 @@ function createFolderController(doc: Document): FolderController { return new FolderController(doc, { blade: new Blade(), title: 'folder', + viewProps: defaultViewProps(), }); } @@ -167,7 +171,7 @@ describe(BladeRack.name, () => { done(); }); - bc.blade.hidden = !bc.blade.hidden; + bc.viewProps.set('hidden', !bc.viewProps.get('hidden')); }); it('should handle folder fold', (done) => { @@ -242,7 +246,7 @@ describe(BladeRack.name, () => { rack.emitter.on('layout', () => { count += 1; }); - bc.blade.hidden = !bc.blade.hidden; + bc.viewProps.set('hidden', !bc.viewProps.get('hidden')); assert.isTrue(count > 0); }); diff --git a/lib/plugin/blade/common/model/blade-rack.ts b/lib/plugin/blade/common/model/blade-rack.ts index 80cc53f9f..89804d3ce 100644 --- a/lib/plugin/blade/common/model/blade-rack.ts +++ b/lib/plugin/blade/common/model/blade-rack.ts @@ -6,6 +6,7 @@ import { } from '../../../common/binding/monitor'; import {Emitter} from '../../../common/model/emitter'; import {TpError} from '../../../common/tp-error'; +import {ViewPropsEvents} from '../../../common/view/view'; import {FolderController} from '../../folder/controller'; import {Folder, FolderEvents} from '../../folder/model/folder'; import {BladeController} from '../controller/blade'; @@ -101,6 +102,7 @@ export class BladeRack { this.onItemFolderFold_ = this.onItemFolderFold_.bind(this); this.onItemInputChange_ = this.onItemInputChange_.bind(this); this.onItemMonitorUpdate_ = this.onItemMonitorUpdate_.bind(this); + this.onItemViewPropsChange_ = this.onItemViewPropsChange_.bind(this); this.onSubitemLayout_ = this.onSubitemLayout_.bind(this); this.onSubitemFolderFold_ = this.onSubitemFolderFold_.bind(this); @@ -147,6 +149,7 @@ export class BladeRack { const bc = ev.item; bc.blade.emitter.on('dispose', this.onItemDispose_); + bc.viewProps.emitter.on('change', this.onItemViewPropsChange_); bc.blade.emitter.on('change', this.onItemLayout_); if (bc instanceof InputBindingController) { @@ -192,13 +195,19 @@ export class BladeRack { } private onItemLayout_(ev: BladeEvents['change']) { - if (ev.propertyName === 'hidden' || ev.propertyName === 'positions') { + if (ev.propertyName === 'positions') { this.emitter.emit('layout', { sender: this, }); } } + private onItemViewPropsChange_(_ev: ViewPropsEvents['change']) { + this.emitter.emit('layout', { + sender: this, + }); + } + private onItemDispose_(_: BladeEvents['dispose']): void { const disposedUcs = this.bcList_.items.filter((bc) => { return bc.blade.disposed; diff --git a/lib/plugin/blade/common/model/blade-test.ts b/lib/plugin/blade/common/model/blade-test.ts index d995a0b3f..cd973d5ec 100644 --- a/lib/plugin/blade/common/model/blade-test.ts +++ b/lib/plugin/blade/common/model/blade-test.ts @@ -1,29 +1,3 @@ -import {assert} from 'chai'; -import {describe, it} from 'mocha'; - import {Blade} from './blade'; -describe(Blade.name, () => { - it('should be shown by default', () => { - const b = new Blade(); - assert.strictEqual(b.hidden, false); - }); - - it('should emit change event for hidden', (done) => { - const b = new Blade(); - b.emitter.on('change', (ev) => { - assert.strictEqual(ev.propertyName, 'hidden'); - assert.strictEqual(b.hidden, true); - done(); - }); - b.hidden = true; - }); - - it('should not emit change event by setting hidden to same value', () => { - const b = new Blade(); - b.emitter.on('change', () => { - throw new Error('should not be called'); - }); - b.hidden = false; - }); -}); +describe(Blade.name, () => {}); diff --git a/lib/plugin/blade/common/model/blade.ts b/lib/plugin/blade/common/model/blade.ts index c1edff421..c37360f60 100644 --- a/lib/plugin/blade/common/model/blade.ts +++ b/lib/plugin/blade/common/model/blade.ts @@ -8,7 +8,7 @@ import {BladePosition} from './blade-positions'; */ export interface BladeEvents { change: { - propertyName: 'hidden' | 'positions'; + propertyName: 'positions'; sender: Blade; }; dispose: { @@ -17,38 +17,15 @@ export interface BladeEvents { } export class Blade { - public readonly emitter: Emitter; - private disposable_: Disposable; - private positions_: BladePosition[]; - private hidden_: boolean; + public readonly emitter: Emitter = new Emitter(); + private disposable_ = new Disposable(); + private positions_: BladePosition[] = []; constructor() { this.onDispose_ = this.onDispose_.bind(this); - - this.emitter = new Emitter(); - this.positions_ = []; - this.hidden_ = false; - - this.disposable_ = new Disposable(); this.disposable_.emitter.on('dispose', this.onDispose_); } - get hidden(): boolean { - return this.hidden_; - } - - set hidden(hidden: boolean) { - if (this.hidden_ === hidden) { - return; - } - - this.hidden_ = hidden; - this.emitter.emit('change', { - propertyName: 'hidden', - sender: this, - }); - } - get positions(): BladePosition[] { return this.positions_; } diff --git a/lib/plugin/blade/folder/controller-test.ts b/lib/plugin/blade/folder/controller-test.ts index 705dbee1f..53ad620d2 100644 --- a/lib/plugin/blade/folder/controller-test.ts +++ b/lib/plugin/blade/folder/controller-test.ts @@ -2,6 +2,7 @@ import {assert} from 'chai'; import {describe, it} from 'mocha'; import {TestUtil} from '../../../misc/test-util'; +import {defaultViewProps} from '../../common/view/view'; import {ButtonController} from '../button/controller/button'; import {BladeController} from '../common/controller/blade'; import {Blade} from '../common/model/blade'; @@ -14,6 +15,7 @@ function createSomeBladeController(doc: Document): BladeController { blade: new Blade(), valueController: new ButtonController(doc, { title: 'Foobar', + viewProps: defaultViewProps(), }), }); } @@ -24,6 +26,7 @@ describe(FolderController.name, () => { const c = new FolderController(doc, { title: 'Push', blade: new Blade(), + viewProps: defaultViewProps(), }); assert.strictEqual(c.folder.expanded, true); @@ -44,6 +47,7 @@ describe(FolderController.name, () => { const c = new FolderController(doc, { title: 'Push', blade: new Blade(), + viewProps: defaultViewProps(), }); const bc = createSomeBladeController(doc); c.bladeRack.add(bc); @@ -58,11 +62,13 @@ describe(FolderController.name, () => { const c = new FolderController(doc, { title: 'Folder', blade: new Blade(), + viewProps: defaultViewProps(), }); const sc = new FolderController(doc, { title: 'Subfolder', blade: new Blade(), + viewProps: defaultViewProps(), }); c.bladeRack.add(sc); @@ -76,6 +82,7 @@ describe(FolderController.name, () => { const c = new FolderController(doc, { title: '', blade: new Blade(), + viewProps: defaultViewProps(), }); const bcs = [ @@ -98,10 +105,12 @@ describe(FolderController.name, () => { const c = new FolderController(doc, { title: '', blade: new Blade(), + viewProps: defaultViewProps(), }); const sc = new FolderController(doc, { title: '', blade: new Blade(), + viewProps: defaultViewProps(), }); c.bladeRack.add(sc); const bc = createSomeBladeController(doc); diff --git a/lib/plugin/blade/folder/controller.ts b/lib/plugin/blade/folder/controller.ts index 9bf3ee31a..746151f8d 100644 --- a/lib/plugin/blade/folder/controller.ts +++ b/lib/plugin/blade/folder/controller.ts @@ -1,5 +1,6 @@ import {isEmpty} from '../../../misc/type-util'; import {forceReflow, insertElementAt} from '../../common/dom-util'; +import {ViewProps} from '../../common/view/view'; import { BladeController, setUpBladeController, @@ -17,6 +18,7 @@ interface Config { expanded?: boolean; title: string; blade: Blade; + viewProps: ViewProps; hidesTitle?: boolean; viewName?: string; @@ -30,6 +32,7 @@ export class FolderController implements BladeController { public readonly bladeRack: BladeRack; public readonly folder: Folder; public readonly view: FolderView; + public readonly viewProps: ViewProps; constructor(doc: Document, config: Config) { this.onContainerTransitionEnd_ = this.onContainerTransitionEnd_.bind(this); @@ -40,6 +43,8 @@ export class FolderController implements BladeController { this.onRackRemove_ = this.onRackRemove_.bind(this); this.blade = config.blade; + this.viewProps = config.viewProps; + this.folder = new Folder(config.title, config.expanded ?? true); this.folder.emitter.on('beforechange', this.onFolderBeforeChange_); @@ -53,6 +58,7 @@ export class FolderController implements BladeController { folder: this.folder, hidesTitle: config.hidesTitle, viewName: config.viewName, + viewProps: this.viewProps, }); this.view.titleElement.addEventListener('click', this.onTitleClick_); this.view.containerElement.addEventListener( diff --git a/lib/plugin/blade/folder/root.ts b/lib/plugin/blade/folder/root.ts index 57a22449a..52b53db06 100644 --- a/lib/plugin/blade/folder/root.ts +++ b/lib/plugin/blade/folder/root.ts @@ -1,10 +1,13 @@ +import {ViewProps} from '../../common/view/view'; import {Blade} from '../common/model/blade'; import {FolderController} from './controller'; interface Config { + blade: Blade; + viewProps: ViewProps; + expanded?: boolean; title?: string; - blade: Blade; } export class RootController extends FolderController { @@ -13,6 +16,7 @@ export class RootController extends FolderController { expanded: config.expanded, title: config.title || '', blade: config.blade, + viewProps: config.viewProps, hidesTitle: config.title === undefined, viewName: 'rot', diff --git a/lib/plugin/blade/folder/view.ts b/lib/plugin/blade/folder/view.ts index e5aebafdb..8bf63e491 100644 --- a/lib/plugin/blade/folder/view.ts +++ b/lib/plugin/blade/folder/view.ts @@ -1,9 +1,15 @@ import {ClassName} from '../../common/view/class-name'; -import {View} from '../../common/view/view'; +import { + bindDisabled, + bindViewProps, + View, + ViewProps, +} from '../../common/view/view'; import {Folder} from './model/folder'; export interface Config { folder: Folder; + viewProps: ViewProps; hidesTitle?: boolean; viewName?: string; @@ -16,8 +22,8 @@ export class FolderView implements View { public readonly containerElement: HTMLDivElement; public readonly titleElement: HTMLButtonElement; public readonly element: HTMLElement; - private folder_: Folder; - private className_: ReturnType; + private readonly folder_: Folder; + private readonly className_: ReturnType; constructor(doc: Document, config: Config) { this.onFolderChange_ = this.onFolderChange_.bind(this); @@ -28,6 +34,7 @@ export class FolderView implements View { this.className_ = ClassName(config.viewName || 'fld'); this.element = doc.createElement('div'); this.element.classList.add(this.className_()); + bindViewProps(config.viewProps, this.element); const titleElem = doc.createElement('button'); titleElem.classList.add(this.className_('t')); @@ -35,6 +42,7 @@ export class FolderView implements View { if (config.hidesTitle) { titleElem.style.display = 'none'; } + bindDisabled(config.viewProps, titleElem); this.element.appendChild(titleElem); this.titleElement = titleElem; diff --git a/lib/plugin/blade/labeled/controller.ts b/lib/plugin/blade/labeled/controller.ts index 3375368ec..94f00cd82 100644 --- a/lib/plugin/blade/labeled/controller.ts +++ b/lib/plugin/blade/labeled/controller.ts @@ -1,4 +1,5 @@ import {Controller} from '../../common/controller/controller'; +import {ViewProps} from '../../common/view/view'; import { BladeController, setUpBladeController, @@ -24,9 +25,14 @@ export class LabeledController this.view = new LabeledView(doc, { label: config.label, + viewProps: this.viewProps, }); this.view.valueElement.appendChild(this.valueController.view.element); setUpBladeController(this); } + + get viewProps(): ViewProps { + return this.valueController.viewProps; + } } diff --git a/lib/plugin/blade/labeled/view.ts b/lib/plugin/blade/labeled/view.ts index 0db0d01df..73f7ed5d8 100644 --- a/lib/plugin/blade/labeled/view.ts +++ b/lib/plugin/blade/labeled/view.ts @@ -1,8 +1,9 @@ import {ClassName} from '../../common/view/class-name'; -import {View} from '../../common/view/view'; +import {bindViewProps, View, ViewProps} from '../../common/view/view'; interface Config { label?: string; + viewProps: ViewProps; } const className = ClassName('lbl'); @@ -36,6 +37,7 @@ export class LabeledView implements View { this.element = doc.createElement('div'); this.element.classList.add(className()); + bindViewProps(config.viewProps, this.element); if (this.label !== undefined) { const labelElem = doc.createElement('div'); diff --git a/lib/plugin/blade/separator/controller.ts b/lib/plugin/blade/separator/controller.ts index e9acc7dc9..50d3aa72f 100644 --- a/lib/plugin/blade/separator/controller.ts +++ b/lib/plugin/blade/separator/controller.ts @@ -1,3 +1,4 @@ +import {ViewProps} from '../../common/view/view'; import { BladeController, setUpBladeController, @@ -7,6 +8,7 @@ import {SeparatorView} from './view'; interface Config { blade: Blade; + viewProps: ViewProps; } /** @@ -15,10 +17,15 @@ interface Config { export class SeparatorController implements BladeController { public readonly blade: Blade; public readonly view: SeparatorView; + public readonly viewProps: ViewProps; constructor(doc: Document, config: Config) { this.blade = config.blade; - this.view = new SeparatorView(doc); + this.viewProps = config.viewProps; + + this.view = new SeparatorView(doc, { + viewProps: this.viewProps, + }); setUpBladeController(this); } } diff --git a/lib/plugin/blade/separator/view.ts b/lib/plugin/blade/separator/view.ts index a7bf3ec62..8c9874971 100644 --- a/lib/plugin/blade/separator/view.ts +++ b/lib/plugin/blade/separator/view.ts @@ -1,17 +1,22 @@ import {ClassName} from '../../common/view/class-name'; -import {View} from '../../common/view/view'; +import {bindViewProps, View, ViewProps} from '../../common/view/view'; const className = ClassName('spr'); +interface Config { + viewProps: ViewProps; +} + /** * @hidden */ export class SeparatorView implements View { public readonly element: HTMLElement; - constructor(doc: Document) { + constructor(doc: Document, config: Config) { this.element = doc.createElement('div'); this.element.classList.add(className()); + bindViewProps(config.viewProps, this.element); const hrElem = doc.createElement('hr'); hrElem.classList.add(className('r')); diff --git a/lib/plugin/common/controller/controller.ts b/lib/plugin/common/controller/controller.ts index 4b2e42373..935d9e55b 100644 --- a/lib/plugin/common/controller/controller.ts +++ b/lib/plugin/common/controller/controller.ts @@ -1,9 +1,11 @@ -import {View} from '../view/view'; +import {View, ViewProps} from '../view/view'; /** * A controller that has a view to control. */ export interface Controller { + readonly viewProps: ViewProps; + /** * The view to control. */ diff --git a/lib/plugin/common/model/value-map-test.ts b/lib/plugin/common/model/value-map-test.ts index c00274ba0..9fe599d81 100644 --- a/lib/plugin/common/model/value-map-test.ts +++ b/lib/plugin/common/model/value-map-test.ts @@ -48,4 +48,18 @@ describe(ValueMap.name, () => { m.set('foo', 'bar'); }); }); + + it('should return signle value emitter', (done) => { + const m = new ValueMap({ + foo: 'bar', + baz: 'qux', + }); + + m.valueEmitter('baz').on('change', (ev) => { + assert.strictEqual(ev.value, 'changed'); + assert.strictEqual(m.get('baz'), 'changed'); + done(); + }); + m.set('baz', 'changed'); + }); }); diff --git a/lib/plugin/common/model/value-map.ts b/lib/plugin/common/model/value-map.ts index 4c72af45a..8588125e8 100644 --- a/lib/plugin/common/model/value-map.ts +++ b/lib/plugin/common/model/value-map.ts @@ -1,14 +1,15 @@ import {Emitter} from './emitter'; -interface ValueEvents { +export interface SingleValueEvents { change: { - sender: Value; + sender: SingleValue; + value: T; }; } // TODO: Integrate it with `./value` -class Value { - public readonly emitter: Emitter>; +class SingleValue { + public readonly emitter: Emitter>; private value_: T; constructor(initialValue: T) { @@ -28,6 +29,7 @@ class Value { this.value_ = value; this.emitter.emit('change', { sender: this, + value: this.value_, }); } } @@ -41,13 +43,13 @@ export interface ValueMapEvents> { export class ValueMap> { public readonly emitter: Emitter>; - private valMap_: {[Key in keyof O]: Value}; + private valMap_: {[Key in keyof O]: SingleValue}; constructor(initialValue: O) { this.emitter = new Emitter(); const keys: (keyof O)[] = Object.keys(initialValue); - const props = keys.map((key) => new Value(initialValue[key])); + const props = keys.map((key) => new SingleValue(initialValue[key])); props.forEach((prop, index) => { prop.emitter.on('change', () => { this.emitter.emit('change', { @@ -62,7 +64,7 @@ export class ValueMap> { return Object.assign(o, { [key]: props[index], }); - }, {} as {[Key in keyof O]: Value}); + }, {} as {[Key in keyof O]: SingleValue}); } public get(key: Key): O[Key] { @@ -72,4 +74,10 @@ export class ValueMap> { public set(key: Key, value: O[Key]): void { this.valMap_[key].value = value; } + + public valueEmitter( + key: Key, + ): Emitter> { + return this.valMap_[key].emitter; + } } diff --git a/lib/plugin/common/view/view-test.ts b/lib/plugin/common/view/view-test.ts new file mode 100644 index 000000000..576ed3673 --- /dev/null +++ b/lib/plugin/common/view/view-test.ts @@ -0,0 +1,45 @@ +import {assert} from 'chai'; +import {describe, it as context, it} from 'mocha'; + +import {defaultViewProps} from './view'; + +describe(defaultViewProps.name, () => { + [ + { + params: undefined, + expected: { + disabled: false, + hidden: false, + }, + }, + { + params: {}, + expected: { + disabled: false, + hidden: false, + }, + }, + { + params: {disabled: true}, + expected: { + disabled: true, + hidden: false, + }, + }, + { + params: {hidden: true}, + expected: { + disabled: false, + hidden: true, + }, + }, + ].forEach(({params, expected}) => { + context(`when ${JSON.stringify(params)}`, () => { + it('should set initial value', () => { + const p = defaultViewProps(params); + assert.strictEqual(p.get('disabled'), expected.disabled); + assert.strictEqual(p.get('hidden'), expected.hidden); + }); + }); + }); +}); diff --git a/lib/plugin/common/view/view.ts b/lib/plugin/common/view/view.ts index 5e00017b5..f2c979cab 100644 --- a/lib/plugin/common/view/view.ts +++ b/lib/plugin/common/view/view.ts @@ -1,3 +1,14 @@ +import {SingleValueEvents, ValueMap, ValueMapEvents} from '../model/value-map'; +import {ClassName} from './class-name'; + +interface ViewPropsObject extends Record { + disabled: boolean; + hidden: boolean; +} + +export type ViewProps = ValueMap; +export type ViewPropsEvents = ValueMapEvents; + /** * A view interface. */ @@ -9,3 +20,76 @@ export interface View { onDispose?(): void; } + +export function defaultViewProps( + opt_initialValue?: Partial, +): ViewProps { + const initialValue: Partial = opt_initialValue ?? {}; + return new ValueMap({ + disabled: initialValue.disabled ?? false, + hidden: initialValue.hidden ?? false, + }); +} + +const className = ClassName(''); + +function applyClass(elem: HTMLElement, className: string, active: boolean) { + if (active) { + elem.classList.add(className); + } else { + elem.classList.remove(className); + } +} + +function extractValue(ev: SingleValueEvents['change']): T { + return ev.value; +} + +function pipe( + h1: (input: A) => B, + h2: (input: B) => C, +): (input: A) => C { + return (input) => h2(h1(input)); +} + +function applyHiddenClass(elem: HTMLElement): (value: boolean) => void { + return (value) => { + applyClass(elem, className(undefined, 'hidden'), value); + }; +} + +function applyDisabledClass(elem: HTMLElement): (value: boolean) => void { + return (value) => { + applyClass(elem, className(undefined, 'disabled'), value); + }; +} + +function applyDisabled( + elem: HTMLButtonElement | HTMLInputElement | HTMLSelectElement, +) { + return (value: boolean) => { + elem.disabled = value; + }; +} + +export function bindViewProps(viewProps: ViewProps, elem: HTMLElement) { + viewProps + .valueEmitter('disabled') + .on('change', pipe(extractValue, applyDisabledClass(elem))); + applyDisabledClass(elem)(viewProps.get('disabled')); + + viewProps + .valueEmitter('hidden') + .on('change', pipe(extractValue, applyHiddenClass(elem))); + applyHiddenClass(elem)(viewProps.get('hidden')); +} + +export function bindDisabled( + viewProps: ViewProps, + elem: HTMLButtonElement | HTMLInputElement | HTMLSelectElement, +) { + viewProps + .valueEmitter('disabled') + .on('change', pipe(extractValue, applyDisabled(elem))); + applyDisabled(elem)(viewProps.get('disabled')); +} diff --git a/lib/plugin/input-binding-test.ts b/lib/plugin/input-binding-test.ts index 0eae94b60..40c24ef2c 100644 --- a/lib/plugin/input-binding-test.ts +++ b/lib/plugin/input-binding-test.ts @@ -7,7 +7,7 @@ import {ValueController} from './common/controller/value'; import {stringFromUnknown} from './common/converter/string'; import {Value} from './common/model/value'; import {writePrimitive} from './common/primitive'; -import {View} from './common/view/view'; +import {defaultViewProps, View} from './common/view/view'; import {createController, InputBindingPlugin} from './input-binding'; class TestView implements View { @@ -25,6 +25,7 @@ class TestView implements View { class TestController implements ValueController { public readonly view: TestView; + public readonly viewProps = defaultViewProps(); public disposed = false; constructor(doc: Document, public readonly value: Value) { diff --git a/lib/plugin/input-binding.ts b/lib/plugin/input-binding.ts index a24878ae5..8296fe663 100644 --- a/lib/plugin/input-binding.ts +++ b/lib/plugin/input-binding.ts @@ -7,6 +7,7 @@ import {BindingTarget} from './common/binding/target'; import {Constraint} from './common/constraint/constraint'; import {ValueController} from './common/controller/value'; import {Value} from './common/model/value'; +import {defaultViewProps, ViewProps} from './common/view/view'; import {BasePlugin} from './plugin'; interface BindingArguments { @@ -20,6 +21,7 @@ interface ControllerArguments { initialValue: Ex; params: InputParams; value: Value; + viewProps: ViewProps; } /** @@ -141,6 +143,9 @@ export function createController( initialValue: initialValue, params: args.params, value: binding.value, + viewProps: defaultViewProps({ + disabled: args.params.disabled, + }), }); const blade = new Blade(); diff --git a/lib/plugin/input-bindings/boolean/controller.ts b/lib/plugin/input-bindings/boolean/controller.ts index ec219340c..e63a981a8 100644 --- a/lib/plugin/input-bindings/boolean/controller.ts +++ b/lib/plugin/input-bindings/boolean/controller.ts @@ -1,6 +1,7 @@ import {forceCast} from '../../../misc/type-util'; import {ValueController} from '../../common/controller/value'; import {Value} from '../../common/model/value'; +import {ViewProps} from '../../common/view/view'; import {CheckboxView} from './view'; /** @@ -8,6 +9,7 @@ import {CheckboxView} from './view'; */ export interface Config { value: Value; + viewProps: ViewProps; } /** @@ -16,14 +18,17 @@ export interface Config { export class CheckboxController implements ValueController { public readonly value: Value; public readonly view: CheckboxView; + public readonly viewProps: ViewProps; constructor(doc: Document, config: Config) { this.onInputChange_ = this.onInputChange_.bind(this); this.value = config.value; + this.viewProps = config.viewProps; this.view = new CheckboxView(doc, { value: this.value, + viewProps: this.viewProps, }); this.view.inputElement.addEventListener('change', this.onInputChange_); } diff --git a/lib/plugin/input-bindings/boolean/plugin.ts b/lib/plugin/input-bindings/boolean/plugin.ts index 561d6e4f5..69cec01a8 100644 --- a/lib/plugin/input-bindings/boolean/plugin.ts +++ b/lib/plugin/input-bindings/boolean/plugin.ts @@ -7,7 +7,6 @@ import {Constraint} from '../../common/constraint/constraint'; import {ListConstraint} from '../../common/constraint/list'; import {boolToString} from '../../common/converter/boolean'; import {boolFromUnknown} from '../../common/converter/boolean'; -import {Value} from '../../common/model/value'; import {equalsPrimitive, writePrimitive} from '../../common/primitive'; import {InputBindingPlugin} from '../../input-binding'; import {createListConstraint, findListItems} from '../../util'; @@ -25,22 +24,6 @@ function createConstraint(params: InputParams): Constraint { return new CompositeConstraint(constraints); } -function createController(doc: Document, value: Value) { - const c = value.constraint; - - if (c && findConstraint(c, ListConstraint)) { - return new ListController(doc, { - listItems: findListItems(c) ?? [], - stringifyValue: boolToString, - value: value, - }); - } - - return new CheckboxController(doc, { - value: value, - }); -} - /** * @hidden */ @@ -54,6 +37,22 @@ export const BooleanInputPlugin: InputBindingPlugin = { writer: (_args) => writePrimitive, }, controller: (args) => { - return createController(args.document, args.value); + const doc = args.document; + const value = args.value; + const c = value.constraint; + + if (c && findConstraint(c, ListConstraint)) { + return new ListController(doc, { + listItems: findListItems(c) ?? [], + stringifyValue: boolToString, + value: value, + viewProps: args.viewProps, + }); + } + + return new CheckboxController(doc, { + value: value, + viewProps: args.viewProps, + }); }, }; diff --git a/lib/plugin/input-bindings/boolean/view.ts b/lib/plugin/input-bindings/boolean/view.ts index 599c49e6d..a4f007268 100644 --- a/lib/plugin/input-bindings/boolean/view.ts +++ b/lib/plugin/input-bindings/boolean/view.ts @@ -1,10 +1,16 @@ import {createSvgIconElement} from '../../common/dom-util'; import {Value} from '../../common/model/value'; import {ClassName} from '../../common/view/class-name'; -import {View} from '../../common/view/view'; +import { + bindDisabled, + bindViewProps, + View, + ViewProps, +} from '../../common/view/view'; interface Config { value: Value; + viewProps: ViewProps; } const className = ClassName('ckb'); @@ -22,6 +28,7 @@ export class CheckboxView implements View { this.element = doc.createElement('div'); this.element.classList.add(className()); + bindViewProps(config.viewProps, this.element); const labelElem = doc.createElement('label'); labelElem.classList.add(className('l')); @@ -32,6 +39,7 @@ export class CheckboxView implements View { inputElem.type = 'checkbox'; labelElem.appendChild(inputElem); this.inputElement = inputElem; + bindDisabled(config.viewProps, this.inputElement); const wrapperElem = doc.createElement('div'); wrapperElem.classList.add(className('w')); diff --git a/lib/plugin/input-bindings/color/controller/a-palette.ts b/lib/plugin/input-bindings/color/controller/a-palette.ts index a86a2327f..b60474573 100644 --- a/lib/plugin/input-bindings/color/controller/a-palette.ts +++ b/lib/plugin/input-bindings/color/controller/a-palette.ts @@ -6,12 +6,14 @@ import { PointerHandler, PointerHandlerEvents, } from '../../../common/view/pointer-handler'; +import {ViewProps} from '../../../common/view/view'; import {Color} from '../model/color'; import {getBaseStepForColor} from '../util'; import {APaletteView} from '../view/a-palette'; interface Config { value: Value; + viewProps: ViewProps; } /** @@ -20,6 +22,7 @@ interface Config { export class APaletteController implements ValueController { public readonly value: Value; public readonly view: APaletteView; + public readonly viewProps: ViewProps; private ptHandler_: PointerHandler; constructor(doc: Document, config: Config) { @@ -29,6 +32,7 @@ export class APaletteController implements ValueController { this.onPointerUp_ = this.onPointerUp_.bind(this); this.value = config.value; + this.viewProps = config.viewProps; this.view = new APaletteView(doc, { value: this.value, diff --git a/lib/plugin/input-bindings/color/controller/color-picker-test.ts b/lib/plugin/input-bindings/color/controller/color-picker-test.ts index 6341d1a62..7291d7409 100644 --- a/lib/plugin/input-bindings/color/controller/color-picker-test.ts +++ b/lib/plugin/input-bindings/color/controller/color-picker-test.ts @@ -3,6 +3,7 @@ import {describe, it} from 'mocha'; import {TestUtil} from '../../../../misc/test-util'; import {Value} from '../../../common/model/value'; +import {defaultViewProps} from '../../../common/view/view'; import {Color} from '../model/color'; import {PickedColor} from '../model/picked-color'; import {ColorPickerController} from './color-picker'; @@ -15,6 +16,7 @@ describe(ColorPickerController.name, () => { const c = new ColorPickerController(doc, { pickedColor: pc, supportsAlpha: false, + viewProps: defaultViewProps(), }); assert.strictEqual(c.textController.view.modeSelectElement.value, 'hsv'); @@ -27,6 +29,7 @@ describe(ColorPickerController.name, () => { const c = new ColorPickerController(doc, { pickedColor: pc, supportsAlpha: false, + viewProps: defaultViewProps(), }); // Change color mode to HSL diff --git a/lib/plugin/input-bindings/color/controller/color-picker.ts b/lib/plugin/input-bindings/color/controller/color-picker.ts index 16bbf997d..516ef5745 100644 --- a/lib/plugin/input-bindings/color/controller/color-picker.ts +++ b/lib/plugin/input-bindings/color/controller/color-picker.ts @@ -8,6 +8,7 @@ import {findNextTarget, supportsTouch} from '../../../common/dom-util'; import {Foldable} from '../../../common/model/foldable'; import {Value} from '../../../common/model/value'; import {connectValues} from '../../../common/model/value-sync'; +import {ViewProps} from '../../../common/view/view'; import {NumberTextController} from '../../number/controller/number-text'; import {PickedColor} from '..//model/picked-color'; import {Color} from '../model/color'; @@ -20,6 +21,7 @@ import {SvPaletteController} from './sv-palette'; interface Config { pickedColor: PickedColor; supportsAlpha: boolean; + viewProps: ViewProps; } /** @@ -29,6 +31,7 @@ export class ColorPickerController implements ValueController { public readonly foldable: Foldable; public readonly pickedColor: PickedColor; public readonly view: ColorPickerView; + public readonly viewProps: ViewProps; public triggerElement: HTMLElement | null = null; private alphaIcs_: { palette: APaletteController; @@ -43,18 +46,23 @@ export class ColorPickerController implements ValueController { this.onKeyDown_ = this.onKeyDown_.bind(this); this.pickedColor = config.pickedColor; + this.viewProps = config.viewProps; + this.foldable = new Foldable(); this.hPaletteIc_ = new HPaletteController(doc, { value: this.pickedColor.value, + viewProps: this.viewProps, }); this.svPaletteIc_ = new SvPaletteController(doc, { value: this.pickedColor.value, + viewProps: this.viewProps, }); this.alphaIcs_ = config.supportsAlpha ? { palette: new APaletteController(doc, { value: this.pickedColor.value, + viewProps: this.viewProps, }), text: new NumberTextController(doc, { draggingScale: 0.01, @@ -64,6 +72,7 @@ export class ColorPickerController implements ValueController { value: new Value(0, { constraint: new RangeConstraint({min: 0, max: 1}), }), + viewProps: this.viewProps, }), } : null; @@ -84,6 +93,7 @@ export class ColorPickerController implements ValueController { this.tc_ = new ColorTextController(doc, { parser: parseNumber, pickedColor: this.pickedColor, + viewProps: this.viewProps, }); this.view = new ColorPickerView(doc, { diff --git a/lib/plugin/input-bindings/color/controller/color-swatch-text.ts b/lib/plugin/input-bindings/color/controller/color-swatch-text.ts index a610b52ce..461129fea 100644 --- a/lib/plugin/input-bindings/color/controller/color-swatch-text.ts +++ b/lib/plugin/input-bindings/color/controller/color-swatch-text.ts @@ -3,6 +3,7 @@ import {Formatter} from '../../../common/converter/formatter'; import {Parser} from '../../../common/converter/parser'; import {Value} from '../../../common/model/value'; import {ValueMap} from '../../../common/model/value-map'; +import {ViewProps} from '../../../common/view/view'; import {TextController} from '../../common/controller/text'; import {Color} from '../model/color'; import {ColorSwatchTextView} from '../view/color-swatch-text'; @@ -13,6 +14,7 @@ interface Config { parser: Parser; supportsAlpha: boolean; value: Value; + viewProps: ViewProps; } /** @@ -21,15 +23,18 @@ interface Config { export class ColorSwatchTextController implements ValueController { public readonly value: Value; public readonly view: ColorSwatchTextView; + public readonly viewProps: ViewProps; private swatchIc_: ColorSwatchController; private textIc_: TextController; constructor(doc: Document, config: Config) { this.value = config.value; + this.viewProps = config.viewProps; this.swatchIc_ = new ColorSwatchController(doc, { supportsAlpha: config.supportsAlpha, value: this.value, + viewProps: this.viewProps, }); this.textIc_ = new TextController(doc, { @@ -38,6 +43,7 @@ export class ColorSwatchTextController implements ValueController { formatter: config.formatter, }), value: this.value, + viewProps: this.viewProps, }); this.view = new ColorSwatchTextView(doc, { diff --git a/lib/plugin/input-bindings/color/controller/color-swatch.ts b/lib/plugin/input-bindings/color/controller/color-swatch.ts index 119ec5ea8..613288977 100644 --- a/lib/plugin/input-bindings/color/controller/color-swatch.ts +++ b/lib/plugin/input-bindings/color/controller/color-swatch.ts @@ -1,6 +1,7 @@ import {forceCast} from '../../../../misc/type-util'; import {ValueController} from '../../../common/controller/value'; import {Value} from '../../../common/model/value'; +import {ViewProps} from '../../../common/view/view'; import {Color} from '../model/color'; import {PickedColor} from '../model/picked-color'; import {ColorSwatchView} from '../view/color-swatch'; @@ -9,6 +10,7 @@ import {ColorPickerController} from './color-picker'; interface Config { supportsAlpha: boolean; value: Value; + viewProps: ViewProps; } /** @@ -17,6 +19,7 @@ interface Config { export class ColorSwatchController implements ValueController { public readonly value: Value; public readonly view: ColorSwatchView; + public readonly viewProps: ViewProps; private pickerIc_: ColorPickerController; constructor(doc: Document, config: Config) { @@ -24,10 +27,12 @@ export class ColorSwatchController implements ValueController { this.onButtonClick_ = this.onButtonClick_.bind(this); this.value = config.value; + this.viewProps = config.viewProps; this.pickerIc_ = new ColorPickerController(doc, { pickedColor: new PickedColor(this.value), supportsAlpha: config.supportsAlpha, + viewProps: this.viewProps, }); this.view = new ColorSwatchView(doc, { diff --git a/lib/plugin/input-bindings/color/controller/color-text-test.ts b/lib/plugin/input-bindings/color/controller/color-text-test.ts index 82110f33b..2856966e8 100644 --- a/lib/plugin/input-bindings/color/controller/color-text-test.ts +++ b/lib/plugin/input-bindings/color/controller/color-text-test.ts @@ -4,6 +4,7 @@ import {describe, it} from 'mocha'; import {TestUtil} from '../../../../misc/test-util'; import {parseNumber} from '../../../common/converter/number'; import {Value} from '../../../common/model/value'; +import {defaultViewProps} from '../../../common/view/view'; import {Color, RgbaColorObject} from '../model/color'; import {PickedColor} from '../model/picked-color'; import {ColorTextController} from './color-text'; @@ -74,6 +75,7 @@ describe(ColorTextController.name, () => { const c = new ColorTextController(doc, { parser: parseNumber, pickedColor: new PickedColor(value), + viewProps: defaultViewProps(), }); const inputElem = c.view.textViews[testCase.params.index].inputElement; @@ -136,6 +138,7 @@ describe(ColorTextController.name, () => { const c = new ColorTextController(doc, { parser: parseNumber, pickedColor: new PickedColor(value), + viewProps: defaultViewProps(), }); const inputElem = c.view.textViews[testCase.params.index].inputElement; diff --git a/lib/plugin/input-bindings/color/controller/color-text.ts b/lib/plugin/input-bindings/color/controller/color-text.ts index b5ca503d4..e900b5603 100644 --- a/lib/plugin/input-bindings/color/controller/color-text.ts +++ b/lib/plugin/input-bindings/color/controller/color-text.ts @@ -5,6 +5,7 @@ import {createNumberFormatter} from '../../../common/converter/number'; import {Parser} from '../../../common/converter/parser'; import {Value} from '../../../common/model/value'; import {connectValues} from '../../../common/model/value-sync'; +import {ViewProps} from '../../../common/view/view'; import {NumberTextController} from '../../number/controller/number-text'; import {Color} from '../model/color'; import { @@ -19,6 +20,7 @@ import {ColorTextView} from '../view/color-text'; interface Config { parser: Parser; pickedColor: PickedColor; + viewProps: ViewProps; } const FORMATTER = createNumberFormatter(0); @@ -46,6 +48,7 @@ function createComponentController( config: { colorMode: ColorMode; parser: Parser; + viewProps: ViewProps; }, index: number, ): NumberTextController { @@ -58,6 +61,7 @@ function createComponentController( value: new Value(0, { constraint: MODE_TO_CONSTRAINT_MAP[config.colorMode](index), }), + viewProps: config.viewProps, }); } @@ -67,6 +71,7 @@ function createComponentController( export class ColorTextController implements ValueController { public readonly pickedColor: PickedColor; public readonly view: ColorTextView; + public readonly viewProps: ViewProps; private parser_: Parser; private ccs_: [ NumberTextController, @@ -79,6 +84,7 @@ export class ColorTextController implements ValueController { this.parser_ = config.parser; this.pickedColor = config.pickedColor; + this.viewProps = config.viewProps; this.ccs_ = this.createComponentControllers_(doc); @@ -102,6 +108,7 @@ export class ColorTextController implements ValueController { const cc = { colorMode: this.pickedColor.mode, parser: this.parser_, + viewProps: this.viewProps, }; const ccs: [ NumberTextController, diff --git a/lib/plugin/input-bindings/color/controller/h-palette.ts b/lib/plugin/input-bindings/color/controller/h-palette.ts index d6f8f3850..3ca9ad909 100644 --- a/lib/plugin/input-bindings/color/controller/h-palette.ts +++ b/lib/plugin/input-bindings/color/controller/h-palette.ts @@ -7,12 +7,14 @@ import { PointerHandler, PointerHandlerEvents, } from '../../../common/view/pointer-handler'; +import {ViewProps} from '../../../common/view/view'; import {Color} from '../model/color'; import {getBaseStepForColor} from '../util'; import {HPaletteView} from '../view/h-palette'; interface Config { value: Value; + viewProps: ViewProps; } /** @@ -21,6 +23,7 @@ interface Config { export class HPaletteController implements ValueController { public readonly value: Value; public readonly view: HPaletteView; + public readonly viewProps: ViewProps; private ptHandler_: PointerHandler; constructor(doc: Document, config: Config) { @@ -30,6 +33,7 @@ export class HPaletteController implements ValueController { this.onPointerUp_ = this.onPointerUp_.bind(this); this.value = config.value; + this.viewProps = config.viewProps; this.view = new HPaletteView(doc, { value: this.value, diff --git a/lib/plugin/input-bindings/color/controller/sv-palette.ts b/lib/plugin/input-bindings/color/controller/sv-palette.ts index b9fb8b27e..6d3cbd868 100644 --- a/lib/plugin/input-bindings/color/controller/sv-palette.ts +++ b/lib/plugin/input-bindings/color/controller/sv-palette.ts @@ -12,12 +12,14 @@ import { PointerHandler, PointerHandlerEvents, } from '../../../common/view/pointer-handler'; +import {ViewProps} from '../../../common/view/view'; import {Color} from '../model/color'; import {getBaseStepForColor} from '../util'; import {SvPaletteView} from '../view/sv-palette'; interface Config { value: Value; + viewProps: ViewProps; } /** @@ -26,6 +28,7 @@ interface Config { export class SvPaletteController implements ValueController { public readonly value: Value; public readonly view: SvPaletteView; + public readonly viewProps: ViewProps; private ptHandler_: PointerHandler; constructor(doc: Document, config: Config) { @@ -35,6 +38,7 @@ export class SvPaletteController implements ValueController { this.onPointerUp_ = this.onPointerUp_.bind(this); this.value = config.value; + this.viewProps = config.viewProps; this.view = new SvPaletteView(doc, { value: this.value, diff --git a/lib/plugin/input-bindings/color/plugin-number.ts b/lib/plugin/input-bindings/color/plugin-number.ts index e098a4fdc..a20859a7a 100644 --- a/lib/plugin/input-bindings/color/plugin-number.ts +++ b/lib/plugin/input-bindings/color/plugin-number.ts @@ -61,6 +61,7 @@ export const NumberColorInputPlugin: InputBindingPlugin = { parser: CompositeColorParser, supportsAlpha: supportsAlpha, value: args.value, + viewProps: args.viewProps, }); }, }; diff --git a/lib/plugin/input-bindings/color/plugin-object.ts b/lib/plugin/input-bindings/color/plugin-object.ts index c5dde5bf7..d173e66fc 100644 --- a/lib/plugin/input-bindings/color/plugin-object.ts +++ b/lib/plugin/input-bindings/color/plugin-object.ts @@ -40,6 +40,7 @@ export const ObjectColorInputPlugin: InputBindingPlugin< parser: CompositeColorParser, supportsAlpha: supportsAlpha, value: args.value, + viewProps: args.viewProps, }); }, }; diff --git a/lib/plugin/input-bindings/color/plugin-string.ts b/lib/plugin/input-bindings/color/plugin-string.ts index 030b75170..8f0f8bd35 100644 --- a/lib/plugin/input-bindings/color/plugin-string.ts +++ b/lib/plugin/input-bindings/color/plugin-string.ts @@ -52,6 +52,7 @@ export const StringColorInputPlugin: InputBindingPlugin = { parser: CompositeColorParser, supportsAlpha: hasAlphaComponent(notation), value: args.value, + viewProps: args.viewProps, }); }, }; diff --git a/lib/plugin/input-bindings/common/controller/list-test.ts b/lib/plugin/input-bindings/common/controller/list-test.ts index 021e7cd81..aa1dfe40d 100644 --- a/lib/plugin/input-bindings/common/controller/list-test.ts +++ b/lib/plugin/input-bindings/common/controller/list-test.ts @@ -5,6 +5,7 @@ import {TestUtil} from '../../../../misc/test-util'; import {ListConstraint} from '../../../common/constraint/list'; import {numberToString} from '../../../common/converter/number'; import {Value} from '../../../common/model/value'; +import {defaultViewProps} from '../../../common/view/view'; import {findListItems} from '../../../util'; import {ListController} from './list'; @@ -22,6 +23,7 @@ describe(ListController.name, () => { listItems: findListItems(value.constraint) ?? [], stringifyValue: numberToString, value: value, + viewProps: defaultViewProps(), }); assert.strictEqual(c.value, value); @@ -41,6 +43,7 @@ describe(ListController.name, () => { listItems: findListItems(value.constraint) ?? [], stringifyValue: numberToString, value: value, + viewProps: defaultViewProps(), }); c.view.selectElement.value = '34'; diff --git a/lib/plugin/input-bindings/common/controller/list.ts b/lib/plugin/input-bindings/common/controller/list.ts index 6ab0bf437..1fca8c375 100644 --- a/lib/plugin/input-bindings/common/controller/list.ts +++ b/lib/plugin/input-bindings/common/controller/list.ts @@ -2,12 +2,14 @@ import {forceCast} from '../../../../misc/type-util'; import {ListItem} from '../../../common/constraint/list'; import {ValueController} from '../../../common/controller/value'; import {Value} from '../../../common/model/value'; +import {ViewProps} from '../../../common/view/view'; import {ListView} from '../../../monitor-bindings/common/view/list'; interface Config { listItems: ListItem[]; stringifyValue: (value: T) => string; value: Value; + viewProps: ViewProps; } /** @@ -16,18 +18,21 @@ interface Config { export class ListController implements ValueController { public readonly value: Value; public readonly view: ListView; + public readonly viewProps: ViewProps; private listItems_: ListItem[]; constructor(doc: Document, config: Config) { this.onSelectChange_ = this.onSelectChange_.bind(this); this.value = config.value; + this.viewProps = config.viewProps; this.listItems_ = config.listItems; this.view = new ListView(doc, { options: this.listItems_, stringifyValue: config.stringifyValue, value: this.value, + viewProps: this.viewProps, }); this.view.selectElement.addEventListener('change', this.onSelectChange_); } diff --git a/lib/plugin/input-bindings/common/controller/point-nd-text-test.ts b/lib/plugin/input-bindings/common/controller/point-nd-text-test.ts index dc71b81f4..d7474b3be 100644 --- a/lib/plugin/input-bindings/common/controller/point-nd-text-test.ts +++ b/lib/plugin/input-bindings/common/controller/point-nd-text-test.ts @@ -7,6 +7,7 @@ import { parseNumber, } from '../../../common/converter/number'; import {Value} from '../../../common/model/value'; +import {defaultViewProps} from '../../../common/view/view'; import {Point2d, Point2dAssembly} from '../../point-2d/model/point-2d'; import {PointNdTextController} from './point-nd-text'; @@ -30,6 +31,7 @@ describe(PointNdTextController.name, () => { ], parser: parseNumber, value: new Value(new Point2d(12, 34)), + viewProps: defaultViewProps(), }); c.view.textViews[0].inputElement.value = '3.14'; diff --git a/lib/plugin/input-bindings/common/controller/point-nd-text.ts b/lib/plugin/input-bindings/common/controller/point-nd-text.ts index c29f00559..b8bd69e70 100644 --- a/lib/plugin/input-bindings/common/controller/point-nd-text.ts +++ b/lib/plugin/input-bindings/common/controller/point-nd-text.ts @@ -4,6 +4,7 @@ import {Formatter} from '../../../common/converter/formatter'; import {Parser} from '../../../common/converter/parser'; import {Value} from '../../../common/model/value'; import {connectValues} from '../../../common/model/value-sync'; +import {ViewProps} from '../../../common/view/view'; import {NumberTextController} from '../../number/controller/number-text'; import {PointNdConstraint} from '../constraint/point-nd'; import {PointNdAssembly} from '../model/point-nd'; @@ -20,6 +21,7 @@ interface Config { axes: Axis[]; parser: Parser; value: Value; + viewProps: ViewProps; } function findAxisConstraint( @@ -48,6 +50,7 @@ function createAxisController( value: new Value(0, { constraint: findAxisConstraint(config, index), }), + viewProps: config.viewProps, }); } @@ -58,10 +61,12 @@ export class PointNdTextController implements ValueController { public readonly value: Value; public readonly view: PointNdTextView; + public readonly viewProps: ViewProps; private readonly acs_: NumberTextController[]; constructor(doc: Document, config: Config) { this.value = config.value; + this.viewProps = config.viewProps; this.acs_ = config.axes.map((_, index) => createAxisController(doc, config, index), diff --git a/lib/plugin/input-bindings/common/controller/text-test.ts b/lib/plugin/input-bindings/common/controller/text-test.ts index 53b7513e2..5b0579674 100644 --- a/lib/plugin/input-bindings/common/controller/text-test.ts +++ b/lib/plugin/input-bindings/common/controller/text-test.ts @@ -8,6 +8,7 @@ import { } from '../../../common/converter/number'; import {Value} from '../../../common/model/value'; import {ValueMap} from '../../../common/model/value-map'; +import {defaultViewProps} from '../../../common/view/view'; import {TextController} from './text'; describe(TextController.name, () => { @@ -20,6 +21,7 @@ describe(TextController.name, () => { formatter: createNumberFormatter(2), }), value: value, + viewProps: defaultViewProps(), }); assert.strictEqual(c.value, value); @@ -35,6 +37,7 @@ describe(TextController.name, () => { formatter: createNumberFormatter(2), }), value: value, + viewProps: defaultViewProps(), }); c.view.inputElement.value = '3.14'; diff --git a/lib/plugin/input-bindings/common/controller/text.ts b/lib/plugin/input-bindings/common/controller/text.ts index fe9d3e23d..ed5e2428d 100644 --- a/lib/plugin/input-bindings/common/controller/text.ts +++ b/lib/plugin/input-bindings/common/controller/text.ts @@ -2,6 +2,7 @@ import {forceCast, isEmpty} from '../../../../misc/type-util'; import {ValueController} from '../../../common/controller/value'; import {Parser} from '../../../common/converter/parser'; import {Value} from '../../../common/model/value'; +import {ViewProps} from '../../../common/view/view'; import {TextProps, TextView} from '../view/text'; /** @@ -11,6 +12,7 @@ export interface Config { props: TextProps; parser: Parser; value: Value; + viewProps: ViewProps; } /** @@ -19,6 +21,7 @@ export interface Config { export class TextController implements ValueController { public readonly value: Value; public readonly view: TextView; + public readonly viewProps: ViewProps; private parser_: Parser; constructor(doc: Document, config: Config) { @@ -26,10 +29,12 @@ export class TextController implements ValueController { this.parser_ = config.parser; this.value = config.value; + this.viewProps = config.viewProps; this.view = new TextView(doc, { props: config.props, value: this.value, + viewProps: this.viewProps, }); this.view.inputElement.addEventListener('change', this.onInputChange_); } diff --git a/lib/plugin/input-bindings/common/view/text-test.ts b/lib/plugin/input-bindings/common/view/text-test.ts index b9c51c9ec..8a0631f99 100644 --- a/lib/plugin/input-bindings/common/view/text-test.ts +++ b/lib/plugin/input-bindings/common/view/text-test.ts @@ -4,6 +4,7 @@ import {describe} from 'mocha'; import {TestUtil} from '../../../../misc/test-util'; import {Value} from '../../../common/model/value'; import {ValueMap} from '../../../common/model/value-map'; +import {defaultViewProps} from '../../../common/view/view'; import {TextView} from './text'; describe(TextView.name, () => { @@ -16,6 +17,7 @@ describe(TextView.name, () => { const view = new TextView(doc, { props: props, value: v, + viewProps: defaultViewProps(), }); assert.strictEqual(view.inputElement.value, 'hellofooworld'); @@ -30,6 +32,7 @@ describe(TextView.name, () => { const view = new TextView(doc, { props: props, value: v, + viewProps: defaultViewProps(), }); v.rawValue = 'bar'; @@ -46,10 +49,11 @@ describe(TextView.name, () => { const view = new TextView(doc, { props: props, value: v, + viewProps: defaultViewProps(), }); + assert.strictEqual(view.inputElement.value, 'hellofooworld'); props.set('formatter', (v: string) => v.toUpperCase()); - assert.strictEqual(view.inputElement.value, 'FOO'); }); }); diff --git a/lib/plugin/input-bindings/common/view/text.ts b/lib/plugin/input-bindings/common/view/text.ts index 5839c4d2e..0e0862a4d 100644 --- a/lib/plugin/input-bindings/common/view/text.ts +++ b/lib/plugin/input-bindings/common/view/text.ts @@ -2,16 +2,21 @@ import {Formatter} from '../../../common/converter/formatter'; import {Value} from '../../../common/model/value'; import {ValueMap} from '../../../common/model/value-map'; import {ClassName} from '../../../common/view/class-name'; -import {View} from '../../../common/view/view'; +import { + bindDisabled, + bindViewProps, + View, + ViewProps, +} from '../../../common/view/view'; export type TextProps = ValueMap<{ formatter: Formatter; - [key: string]: unknown; }>; interface Config { props: TextProps; value: Value; + viewProps: ViewProps; } const className = ClassName('txt'); @@ -24,19 +29,24 @@ export class TextView implements View { public readonly element: HTMLElement; private readonly props_: TextProps; private readonly value_: Value; + private readonly viewProps_: ViewProps; constructor(doc: Document, config: Config) { this.onChange_ = this.onChange_.bind(this); - this.props_ = config.props; - this.props_.emitter.on('change', this.onChange_); + this.viewProps_ = config.viewProps; this.element = doc.createElement('div'); this.element.classList.add(className()); + bindViewProps(this.viewProps_, this.element); + + this.props_ = config.props; + this.props_.emitter.on('change', this.onChange_); const inputElem = doc.createElement('input'); inputElem.classList.add(className('i')); inputElem.type = 'text'; + bindDisabled(this.viewProps_, inputElem); this.element.appendChild(inputElem); this.inputElement = inputElem; diff --git a/lib/plugin/input-bindings/number/controller/number-text-test.ts b/lib/plugin/input-bindings/number/controller/number-text-test.ts index f20e18267..c1185559c 100644 --- a/lib/plugin/input-bindings/number/controller/number-text-test.ts +++ b/lib/plugin/input-bindings/number/controller/number-text-test.ts @@ -7,6 +7,7 @@ import { parseNumber, } from '../../../common/converter/number'; import {Value} from '../../../common/model/value'; +import {defaultViewProps} from '../../../common/view/view'; import {NumberTextController} from './number-text'; describe(NumberTextController.name, () => { @@ -19,6 +20,7 @@ describe(NumberTextController.name, () => { formatter: createNumberFormatter(0), parser: parseNumber, value: new Value(123), + viewProps: defaultViewProps(), }); c.view.inputElement.dispatchEvent( diff --git a/lib/plugin/input-bindings/number/controller/number-text.ts b/lib/plugin/input-bindings/number/controller/number-text.ts index c46b34390..8f07c3636 100644 --- a/lib/plugin/input-bindings/number/controller/number-text.ts +++ b/lib/plugin/input-bindings/number/controller/number-text.ts @@ -9,6 +9,7 @@ import { PointerHandler, PointerHandlerEvent, } from '../../../common/view/pointer-handler'; +import {ViewProps} from '../../../common/view/view'; import {NumberTextView} from '../view/number-text'; interface Config { @@ -17,6 +18,7 @@ interface Config { formatter: Formatter; parser: Parser; value: Value; + viewProps: ViewProps; arrayPosition?: 'fst' | 'mid' | 'lst'; } @@ -27,6 +29,7 @@ interface Config { export class NumberTextController implements ValueController { public readonly value: Value; public readonly view: NumberTextView; + public readonly viewProps: ViewProps; private baseStep_: number; private parser_: Parser; private originRawValue_ = 0; @@ -40,10 +43,11 @@ export class NumberTextController implements ValueController { this.onPointerMove_ = this.onPointerMove_.bind(this); this.onPointerUp_ = this.onPointerUp_.bind(this); - this.parser_ = config.parser; - this.value = config.value; this.baseStep_ = config.baseStep; this.draggingScale_ = config.draggingScale; + this.parser_ = config.parser; + this.value = config.value; + this.viewProps = config.viewProps; this.dragging_ = new Value(null); this.view = new NumberTextView(doc, { @@ -54,6 +58,7 @@ export class NumberTextController implements ValueController { formatter: config.formatter, }), value: this.value, + viewProps: this.viewProps, }); this.view.inputElement.addEventListener('change', this.onInputChange_); this.view.inputElement.addEventListener('keydown', this.onInputKeyDown_); diff --git a/lib/plugin/input-bindings/number/controller/slider-text.ts b/lib/plugin/input-bindings/number/controller/slider-text.ts index 5ac9173d8..9a51fcec9 100644 --- a/lib/plugin/input-bindings/number/controller/slider-text.ts +++ b/lib/plugin/input-bindings/number/controller/slider-text.ts @@ -2,6 +2,7 @@ import {ValueController} from '../../../common/controller/value'; import {Formatter} from '../../../common/converter/formatter'; import {Parser} from '../../../common/converter/parser'; import {Value} from '../../../common/model/value'; +import {ViewProps} from '../../../common/view/view'; import {SliderProps} from '../view/slider'; import {SliderTextView} from '../view/slider-text'; import {NumberTextController} from './number-text'; @@ -14,6 +15,7 @@ interface Config { parser: Parser; sliderProps: SliderProps; value: Value; + viewProps: ViewProps; } /** @@ -22,16 +24,19 @@ interface Config { export class SliderTextController implements ValueController { public readonly value: Value; public readonly view: SliderTextView; + public readonly viewProps: ViewProps; private sliderIc_: SliderController; private textIc_: NumberTextController; constructor(doc: Document, config: Config) { this.value = config.value; + this.viewProps = config.viewProps; this.sliderIc_ = new SliderController(doc, { baseStep: config.baseStep, props: config.sliderProps, value: config.value, + viewProps: this.viewProps, }); this.textIc_ = new NumberTextController(doc, { baseStep: config.baseStep, @@ -39,6 +44,7 @@ export class SliderTextController implements ValueController { formatter: config.formatter, parser: config.parser, value: config.value, + viewProps: config.viewProps, }); this.view = new SliderTextView(doc, { diff --git a/lib/plugin/input-bindings/number/controller/slider.ts b/lib/plugin/input-bindings/number/controller/slider.ts index 4a6e72f33..c0bd5ecbb 100644 --- a/lib/plugin/input-bindings/number/controller/slider.ts +++ b/lib/plugin/input-bindings/number/controller/slider.ts @@ -7,12 +7,14 @@ import { PointerHandler, PointerHandlerEvent, } from '../../../common/view/pointer-handler'; +import {ViewProps} from '../../../common/view/view'; import {SliderProps, SliderView} from '../view/slider'; interface Config { baseStep: number; props: SliderProps; value: Value; + viewProps: ViewProps; } /** @@ -21,6 +23,7 @@ interface Config { export class SliderController implements ValueController { public readonly value: Value; public readonly view: SliderView; + public readonly viewProps: ViewProps; private props_: SliderProps; private ptHandler_: PointerHandler; private baseStep_: number; @@ -29,14 +32,16 @@ export class SliderController implements ValueController { this.onKeyDown_ = this.onKeyDown_.bind(this); this.onPoint_ = this.onPoint_.bind(this); - this.value = config.value; this.baseStep_ = config.baseStep; + this.value = config.value; + this.viewProps = config.viewProps; this.props_ = config.props; this.view = new SliderView(doc, { props: this.props_, value: this.value, + viewProps: this.viewProps, }); this.ptHandler_ = new PointerHandler(this.view.trackElement); diff --git a/lib/plugin/input-bindings/number/plugin.ts b/lib/plugin/input-bindings/number/plugin.ts index f9c0b6edb..e2e9d32f3 100644 --- a/lib/plugin/input-bindings/number/plugin.ts +++ b/lib/plugin/input-bindings/number/plugin.ts @@ -120,6 +120,7 @@ export const NumberInputPlugin: InputBindingPlugin = { listItems: findListItems(c) ?? [], stringifyValue: numberToString, value: value, + viewProps: args.viewProps, }); } @@ -144,6 +145,7 @@ export const NumberInputPlugin: InputBindingPlugin = { minValue: min, }), value: value, + viewProps: args.viewProps, }); } @@ -153,6 +155,7 @@ export const NumberInputPlugin: InputBindingPlugin = { formatter: formatter, parser: parseNumber, value: value, + viewProps: args.viewProps, }); }, }; diff --git a/lib/plugin/input-bindings/number/view/number-text.ts b/lib/plugin/input-bindings/number/view/number-text.ts index bc2d19531..e4947258d 100644 --- a/lib/plugin/input-bindings/number/view/number-text.ts +++ b/lib/plugin/input-bindings/number/view/number-text.ts @@ -4,7 +4,12 @@ import {Value, ValueEvents} from '../../../common/model/value'; import {ValueMap} from '../../../common/model/value-map'; import {constrainRange} from '../../../common/number-util'; import {ClassName} from '../../../common/view/class-name'; -import {View} from '../../../common/view/view'; +import { + bindDisabled, + bindViewProps, + View, + ViewProps, +} from '../../../common/view/view'; export type NumberTextProps = ValueMap<{ draggingScale: number; @@ -15,6 +20,7 @@ interface NumberConfig { dragging: Value; props: NumberTextProps; value: Value; + viewProps: ViewProps; arrayPosition?: 'fst' | 'mid' | 'lst'; } @@ -43,10 +49,12 @@ export class NumberTextView implements View { if (config.arrayPosition) { this.element.classList.add(className(undefined, config.arrayPosition)); } + bindViewProps(config.viewProps, this.element); const inputElem = doc.createElement('input'); inputElem.classList.add(className('i')); inputElem.type = 'text'; + bindDisabled(config.viewProps, inputElem); this.element.appendChild(inputElem); this.inputElement = inputElem; diff --git a/lib/plugin/input-bindings/number/view/slider-test.ts b/lib/plugin/input-bindings/number/view/slider-test.ts index 3ec7a183a..9374f8bc9 100644 --- a/lib/plugin/input-bindings/number/view/slider-test.ts +++ b/lib/plugin/input-bindings/number/view/slider-test.ts @@ -4,6 +4,7 @@ import {describe} from 'mocha'; import {TestUtil} from '../../../../misc/test-util'; import {Value} from '../../../common/model/value'; import {ValueMap} from '../../../common/model/value-map'; +import {defaultViewProps} from '../../../common/view/view'; import {SliderView} from './slider'; describe(SliderView.name, () => { @@ -17,6 +18,7 @@ describe(SliderView.name, () => { const view = new SliderView(doc, { props: props, value: v, + viewProps: defaultViewProps(), }); assert.strictEqual(view.knobElement.style.width, '50%'); @@ -32,6 +34,7 @@ describe(SliderView.name, () => { const view = new SliderView(doc, { props: props, value: v, + viewProps: defaultViewProps(), }); v.rawValue = 0; @@ -49,6 +52,7 @@ describe(SliderView.name, () => { const view = new SliderView(doc, { props: props, value: v, + viewProps: defaultViewProps(), }); props.set('maxValue', 100); diff --git a/lib/plugin/input-bindings/number/view/slider.ts b/lib/plugin/input-bindings/number/view/slider.ts index 5017fc019..175613efb 100644 --- a/lib/plugin/input-bindings/number/view/slider.ts +++ b/lib/plugin/input-bindings/number/view/slider.ts @@ -2,7 +2,7 @@ import {Value} from '../../../common/model/value'; import {ValueMap} from '../../../common/model/value-map'; import {constrainRange, mapRange} from '../../../common/number-util'; import {ClassName} from '../../../common/view/class-name'; -import {View} from '../../../common/view/view'; +import {bindViewProps, View, ViewProps} from '../../../common/view/view'; export type SliderProps = ValueMap<{ maxValue: number; @@ -12,6 +12,7 @@ export type SliderProps = ValueMap<{ interface Config { props: SliderProps; value: Value; + viewProps: ViewProps; } const className = ClassName('sld'); @@ -34,6 +35,7 @@ export class SliderView implements View { this.element = doc.createElement('div'); this.element.classList.add(className()); + bindViewProps(config.viewProps, this.element); const trackElem = doc.createElement('div'); trackElem.classList.add(className('t')); diff --git a/lib/plugin/input-bindings/point-2d/controller/point-2d-pad-text.ts b/lib/plugin/input-bindings/point-2d/controller/point-2d-pad-text.ts index dc44d2c47..f10e38261 100644 --- a/lib/plugin/input-bindings/point-2d/controller/point-2d-pad-text.ts +++ b/lib/plugin/input-bindings/point-2d/controller/point-2d-pad-text.ts @@ -3,6 +3,7 @@ import {ValueController} from '../../../common/controller/value'; import {Formatter} from '../../../common/converter/formatter'; import {Parser} from '../../../common/converter/parser'; import {Value} from '../../../common/model/value'; +import {ViewProps} from '../../../common/view/view'; import {PointNdTextController} from '../../common/controller/point-nd-text'; import {Point2d, Point2dAssembly} from '../model/point-2d'; import {Point2dPadTextView} from '../view/point-2d-pad-text'; @@ -20,6 +21,7 @@ interface Config { maxValue: number; parser: Parser; value: Value; + viewProps: ViewProps; } /** @@ -28,6 +30,7 @@ interface Config { export class Point2dPadTextController implements ValueController { public readonly value: Value; public readonly view: Point2dPadTextView; + public readonly viewProps: ViewProps; private readonly padIc_: Point2dPadController; private readonly textIc_: PointNdTextController; @@ -36,12 +39,14 @@ export class Point2dPadTextController implements ValueController { this.onPadButtonClick_ = this.onPadButtonClick_.bind(this); this.value = config.value; + this.viewProps = config.viewProps; this.padIc_ = new Point2dPadController(doc, { baseSteps: [config.axes[0].baseStep, config.axes[1].baseStep], invertsY: config.invertsY, maxValue: config.maxValue, value: this.value, + viewProps: this.viewProps, }); this.textIc_ = new PointNdTextController(doc, { @@ -49,6 +54,7 @@ export class Point2dPadTextController implements ValueController { axes: config.axes, parser: config.parser, value: this.value, + viewProps: this.viewProps, }); this.view = new Point2dPadTextView(doc, { diff --git a/lib/plugin/input-bindings/point-2d/controller/point-2d-pad.ts b/lib/plugin/input-bindings/point-2d/controller/point-2d-pad.ts index b79060a7f..c7d377ce7 100644 --- a/lib/plugin/input-bindings/point-2d/controller/point-2d-pad.ts +++ b/lib/plugin/input-bindings/point-2d/controller/point-2d-pad.ts @@ -14,6 +14,7 @@ import { PointerHandler, PointerHandlerEvents, } from '../../../common/view/pointer-handler'; +import {ViewProps} from '../../../common/view/view'; import {Point2d} from '../model/point-2d'; import {Point2dPadView} from '../view/point-2d-pad'; @@ -22,6 +23,7 @@ interface Config { invertsY: boolean; maxValue: number; value: Value; + viewProps: ViewProps; } /** @@ -31,6 +33,7 @@ export class Point2dPadController implements ValueController { public readonly foldable: Foldable; public readonly value: Value; public readonly view: Point2dPadView; + public readonly viewProps: ViewProps; public triggerElement: HTMLElement | null = null; private readonly baseSteps_: [number, number]; private readonly ptHandler_: PointerHandler; @@ -45,8 +48,9 @@ export class Point2dPadController implements ValueController { this.onPointerMove_ = this.onPointerMove_.bind(this); this.onPointerUp_ = this.onPointerUp_.bind(this); - this.value = config.value; this.foldable = new Foldable(); + this.value = config.value; + this.viewProps = config.viewProps; this.baseSteps_ = config.baseSteps; this.maxValue_ = config.maxValue; diff --git a/lib/plugin/input-bindings/point-2d/plugin.ts b/lib/plugin/input-bindings/point-2d/plugin.ts index 43f7fc72f..b315462c1 100644 --- a/lib/plugin/input-bindings/point-2d/plugin.ts +++ b/lib/plugin/input-bindings/point-2d/plugin.ts @@ -11,7 +11,6 @@ import { createNumberFormatter, parseNumber, } from '../../common/converter/number'; -import {Value} from '../../common/model/value'; import {TpError} from '../../common/tp-error'; import {InputBindingPlugin} from '../../input-binding'; import { @@ -103,28 +102,6 @@ function createAxis( }; } -function createController( - document: Document, - value: Value, - invertsY: boolean, -) { - const c = value.constraint; - if (!(c instanceof PointNdConstraint)) { - throw TpError.shouldNeverHappen(); - } - - return new Point2dPadTextController(document, { - axes: [ - createAxis(value.rawValue.x, c.components[0]), - createAxis(value.rawValue.y, c.components[1]), - ], - invertsY: invertsY, - maxValue: getSuitableMaxValue(value.rawValue, value.constraint), - parser: parseNumber, - value: value, - }); -} - function shouldInvertY(params: InputParams): boolean { if (!('y' in params)) { return false; @@ -151,10 +128,23 @@ export const Point2dInputPlugin: InputBindingPlugin = { writer: (_args) => writePoint2d, }, controller: (args) => { - return createController( - args.document, - args.value, - shouldInvertY(args.params), - ); + const doc = args.document; + const value = args.value; + const c = value.constraint; + if (!(c instanceof PointNdConstraint)) { + throw TpError.shouldNeverHappen(); + } + + return new Point2dPadTextController(doc, { + axes: [ + createAxis(value.rawValue.x, c.components[0]), + createAxis(value.rawValue.y, c.components[1]), + ], + invertsY: shouldInvertY(args.params), + maxValue: getSuitableMaxValue(value.rawValue, value.constraint), + parser: parseNumber, + value: value, + viewProps: args.viewProps, + }); }, }; diff --git a/lib/plugin/input-bindings/point-3d/plugin.ts b/lib/plugin/input-bindings/point-3d/plugin.ts index 6adb6e072..124264c3e 100644 --- a/lib/plugin/input-bindings/point-3d/plugin.ts +++ b/lib/plugin/input-bindings/point-3d/plugin.ts @@ -8,7 +8,6 @@ import { createNumberFormatter, parseNumber, } from '../../common/converter/number'; -import {Value} from '../../common/model/value'; import {TpError} from '../../common/tp-error'; import {InputBindingPlugin} from '../../input-binding'; import { @@ -68,24 +67,6 @@ function createAxis( }; } -function createController(document: Document, value: Value) { - const c = value.constraint; - if (!(c instanceof PointNdConstraint)) { - throw TpError.shouldNeverHappen(); - } - - return new PointNdTextController(document, { - assembly: Point3dAssembly, - axes: [ - createAxis(value.rawValue.x, c.components[0]), - createAxis(value.rawValue.y, c.components[1]), - createAxis(value.rawValue.z, c.components[2]), - ], - parser: parseNumber, - value: value, - }); -} - /** * @hidden */ @@ -99,6 +80,22 @@ export const Point3dInputPlugin: InputBindingPlugin = { writer: (_args) => writePoint3d, }, controller: (args) => { - return createController(args.document, args.value); + const value = args.value; + const c = value.constraint; + if (!(c instanceof PointNdConstraint)) { + throw TpError.shouldNeverHappen(); + } + + return new PointNdTextController(args.document, { + assembly: Point3dAssembly, + axes: [ + createAxis(value.rawValue.x, c.components[0]), + createAxis(value.rawValue.y, c.components[1]), + createAxis(value.rawValue.z, c.components[2]), + ], + parser: parseNumber, + value: value, + viewProps: args.viewProps, + }); }, }; diff --git a/lib/plugin/input-bindings/point-4d/plugin.ts b/lib/plugin/input-bindings/point-4d/plugin.ts index f7dc9fef2..a87ec6b4a 100644 --- a/lib/plugin/input-bindings/point-4d/plugin.ts +++ b/lib/plugin/input-bindings/point-4d/plugin.ts @@ -8,7 +8,6 @@ import { createNumberFormatter, parseNumber, } from '../../common/converter/number'; -import {Value} from '../../common/model/value'; import {TpError} from '../../common/tp-error'; import {InputBindingPlugin} from '../../input-binding'; import { @@ -69,22 +68,6 @@ function createAxis( }; } -function createController(document: Document, value: Value) { - const c = value.constraint; - if (!(c instanceof PointNdConstraint)) { - throw TpError.shouldNeverHappen(); - } - - return new PointNdTextController(document, { - assembly: Point4dAssembly, - axes: value.rawValue - .getComponents() - .map((comp, index) => createAxis(comp, c.components[index])), - parser: parseNumber, - value: value, - }); -} - /** * @hidden */ @@ -98,6 +81,20 @@ export const Point4dInputPlugin: InputBindingPlugin = { writer: (_args) => writePoint4d, }, controller: (args) => { - return createController(args.document, args.value); + const value = args.value; + const c = value.constraint; + if (!(c instanceof PointNdConstraint)) { + throw TpError.shouldNeverHappen(); + } + + return new PointNdTextController(args.document, { + assembly: Point4dAssembly, + axes: value.rawValue + .getComponents() + .map((comp, index) => createAxis(comp, c.components[index])), + parser: parseNumber, + value: value, + viewProps: args.viewProps, + }); }, }; diff --git a/lib/plugin/input-bindings/string/plugin.ts b/lib/plugin/input-bindings/string/plugin.ts index 8069fe30a..9df04c765 100644 --- a/lib/plugin/input-bindings/string/plugin.ts +++ b/lib/plugin/input-bindings/string/plugin.ts @@ -6,7 +6,6 @@ import { import {Constraint} from '../../common/constraint/constraint'; import {ListConstraint} from '../../common/constraint/list'; import {formatString, stringFromUnknown} from '../../common/converter/string'; -import {Value} from '../../common/model/value'; import {ValueMap} from '../../common/model/value-map'; import {equalsPrimitive, writePrimitive} from '../../common/primitive'; import {InputBindingPlugin} from '../../input-binding'; @@ -25,26 +24,6 @@ function createConstraint(params: InputParams): Constraint { return new CompositeConstraint(constraints); } -function createController(doc: Document, value: Value) { - const c = value.constraint; - - if (c && findConstraint(c, ListConstraint)) { - return new ListController(doc, { - listItems: findListItems(c) ?? [], - stringifyValue: (v) => v, - value: value, - }); - } - - return new TextController(doc, { - parser: (v) => v, - props: new ValueMap({ - formatter: formatString, - }), - value: value, - }); -} - /** * @hidden */ @@ -58,6 +37,26 @@ export const StringInputPlugin: InputBindingPlugin = { writer: (_args) => writePrimitive, }, controller: (params) => { - return createController(params.document, params.value); + const doc = params.document; + const value = params.value; + const c = value.constraint; + + if (c && findConstraint(c, ListConstraint)) { + return new ListController(doc, { + listItems: findListItems(c) ?? [], + stringifyValue: (v) => v, + value: value, + viewProps: params.viewProps, + }); + } + + return new TextController(doc, { + parser: (v) => v, + props: new ValueMap({ + formatter: formatString, + }), + value: value, + viewProps: params.viewProps, + }); }, }; diff --git a/lib/plugin/monitor-binding-test.ts b/lib/plugin/monitor-binding-test.ts index 58ed7cbee..136b49948 100644 --- a/lib/plugin/monitor-binding-test.ts +++ b/lib/plugin/monitor-binding-test.ts @@ -6,7 +6,7 @@ import {BindingTarget} from './common/binding/target'; import {ValueController} from './common/controller/value'; import {stringFromUnknown} from './common/converter/string'; import {Buffer, BufferedValue} from './common/model/buffered-value'; -import {View} from './common/view/view'; +import {defaultViewProps, View, ViewProps} from './common/view/view'; import {createController, MonitorBindingPlugin} from './monitor-binding'; class TestView implements View { @@ -24,6 +24,7 @@ class TestView implements View { class TestController implements ValueController> { public readonly view: TestView; + public readonly viewProps: ViewProps = defaultViewProps(); public disposed = false; constructor(doc: Document, public readonly value: BufferedValue) { diff --git a/lib/plugin/monitor-bindings/boolean/plugin.ts b/lib/plugin/monitor-bindings/boolean/plugin.ts index 0550dd507..9935b2c7f 100644 --- a/lib/plugin/monitor-bindings/boolean/plugin.ts +++ b/lib/plugin/monitor-bindings/boolean/plugin.ts @@ -3,6 +3,7 @@ import { BooleanFormatter, boolFromUnknown, } from '../../common/converter/boolean'; +import {defaultViewProps} from '../../common/view/view'; import {MonitorBindingPlugin} from '../../monitor-binding'; import {MultiLogController} from '../common/controller/multi-log'; import {SingleLogMonitorController} from '../common/controller/single-log'; @@ -21,6 +22,7 @@ export const BooleanMonitorPlugin: MonitorBindingPlugin = { return new SingleLogMonitorController(args.document, { formatter: BooleanFormatter, value: args.value, + viewProps: defaultViewProps(), }); } @@ -28,6 +30,7 @@ export const BooleanMonitorPlugin: MonitorBindingPlugin = { formatter: BooleanFormatter, lineCount: args.params.lineCount ?? Constants.monitor.defaultLineCount, value: args.value, + viewProps: defaultViewProps(), }); }, }; diff --git a/lib/plugin/monitor-bindings/common/controller/multi-log.ts b/lib/plugin/monitor-bindings/common/controller/multi-log.ts index 8a162907b..df6ac260a 100644 --- a/lib/plugin/monitor-bindings/common/controller/multi-log.ts +++ b/lib/plugin/monitor-bindings/common/controller/multi-log.ts @@ -1,12 +1,14 @@ import {ValueController} from '../../../common/controller/value'; import {Formatter} from '../../../common/converter/formatter'; import {Buffer, BufferedValue} from '../../../common/model/buffered-value'; +import {ViewProps} from '../../../common/view/view'; import {MultiLogView} from '../view/multi-log'; interface Config { formatter: Formatter; lineCount: number; value: BufferedValue; + viewProps: ViewProps; } /** @@ -15,9 +17,11 @@ interface Config { export class MultiLogController implements ValueController> { public readonly value: BufferedValue; public readonly view: MultiLogView; + public readonly viewProps: ViewProps; constructor(doc: Document, config: Config) { this.value = config.value; + this.viewProps = config.viewProps; this.view = new MultiLogView(doc, { formatter: config.formatter, diff --git a/lib/plugin/monitor-bindings/common/controller/single-log.ts b/lib/plugin/monitor-bindings/common/controller/single-log.ts index 0467bfa81..49fcccfb9 100644 --- a/lib/plugin/monitor-bindings/common/controller/single-log.ts +++ b/lib/plugin/monitor-bindings/common/controller/single-log.ts @@ -1,11 +1,13 @@ import {ValueController} from '../../../common/controller/value'; import {Formatter} from '../../../common/converter/formatter'; import {Buffer, BufferedValue} from '../../../common/model/buffered-value'; +import {ViewProps} from '../../../common/view/view'; import {SingleLogView} from '../view/single-log'; interface Config { formatter: Formatter; value: BufferedValue; + viewProps: ViewProps; } /** @@ -15,9 +17,11 @@ export class SingleLogMonitorController implements ValueController> { public readonly value: BufferedValue; public readonly view: SingleLogView; + public readonly viewProps: ViewProps; constructor(doc: Document, config: Config) { this.value = config.value; + this.viewProps = config.viewProps; this.view = new SingleLogView(doc, { formatter: config.formatter, diff --git a/lib/plugin/monitor-bindings/common/view/list.ts b/lib/plugin/monitor-bindings/common/view/list.ts index 739b2ffae..93d90cc98 100644 --- a/lib/plugin/monitor-bindings/common/view/list.ts +++ b/lib/plugin/monitor-bindings/common/view/list.ts @@ -2,12 +2,13 @@ import {ListItem} from '../../../common/constraint/list'; import {createSvgIconElement} from '../../../common/dom-util'; import {Value} from '../../../common/model/value'; import {ClassName} from '../../../common/view/class-name'; -import {View} from '../../../common/view/view'; +import {bindViewProps, View, ViewProps} from '../../../common/view/view'; interface Config { options: ListItem[]; stringifyValue: (value: T) => string; value: Value; + viewProps: ViewProps; } const className = ClassName('lst'); @@ -18,16 +19,19 @@ const className = ClassName('lst'); export class ListView implements View { public readonly selectElement: HTMLSelectElement; public readonly element: HTMLElement; - public readonly value: Value; + private readonly value_: Value; + private readonly viewProps_: ViewProps; private stringifyValue_: (value: T) => string; constructor(doc: Document, config: Config) { this.onValueChange_ = this.onValueChange_.bind(this); + this.stringifyValue_ = config.stringifyValue; + this.viewProps_ = config.viewProps; + this.element = doc.createElement('div'); this.element.classList.add(className()); - - this.stringifyValue_ = config.stringifyValue; + bindViewProps(this.viewProps_, this.element); const selectElem = doc.createElement('select'); selectElem.classList.add(className('s')); @@ -47,13 +51,13 @@ export class ListView implements View { this.element.appendChild(markElem); config.value.emitter.on('change', this.onValueChange_); - this.value = config.value; + this.value_ = config.value; this.update(); } public update(): void { - this.selectElement.value = this.stringifyValue_(this.value.rawValue); + this.selectElement.value = this.stringifyValue_(this.value_.rawValue); } private onValueChange_(): void { diff --git a/lib/plugin/monitor-bindings/number/controller/graph-log.ts b/lib/plugin/monitor-bindings/number/controller/graph-log.ts index 2a9880067..9f1c86243 100644 --- a/lib/plugin/monitor-bindings/number/controller/graph-log.ts +++ b/lib/plugin/monitor-bindings/number/controller/graph-log.ts @@ -7,6 +7,7 @@ import { PointerHandler, PointerHandlerEvent, } from '../../../common/view/pointer-handler'; +import {ViewProps} from '../../../common/view/view'; import {GraphCursor} from '../model/graph-cursor'; import {GraphLogView} from '../view/graph-log'; @@ -16,6 +17,7 @@ interface Config { maxValue: number; minValue: number; value: BufferedValue; + viewProps: ViewProps; } /** @@ -24,6 +26,7 @@ interface Config { export class GraphLogController implements ValueController> { public readonly value: BufferedValue; public readonly view: GraphLogView; + public readonly viewProps: ViewProps; private cursor_: GraphCursor; constructor(doc: Document, config: Config) { @@ -34,6 +37,7 @@ export class GraphLogController implements ValueController> { this.onGraphPointerUp_ = this.onGraphPointerUp_.bind(this); this.value = config.value; + this.viewProps = config.viewProps; this.cursor_ = new GraphCursor(); this.view = new GraphLogView(doc, { diff --git a/lib/plugin/monitor-bindings/number/plugin.ts b/lib/plugin/monitor-bindings/number/plugin.ts index 169c2de02..560d1a5a9 100644 --- a/lib/plugin/monitor-bindings/number/plugin.ts +++ b/lib/plugin/monitor-bindings/number/plugin.ts @@ -7,6 +7,7 @@ import { numberFromUnknown, } from '../../common/converter/number'; import {Buffer, BufferedValue} from '../../common/model/buffered-value'; +import {defaultViewProps} from '../../common/view/view'; import {MonitorBindingPlugin} from '../../monitor-binding'; import {MultiLogController} from '../common/controller/multi-log'; import {SingleLogMonitorController} from '../common/controller/single-log'; @@ -30,6 +31,7 @@ function createTextMonitor({ return new SingleLogMonitorController(document, { formatter: createFormatter(), value: value, + viewProps: defaultViewProps(), }); } @@ -37,6 +39,7 @@ function createTextMonitor({ formatter: createFormatter(), lineCount: params.lineCount ?? Constants.monitor.defaultLineCount, value: value, + viewProps: defaultViewProps(), }); } @@ -55,6 +58,7 @@ function createGraphMonitor({ maxValue: ('max' in params ? params.max : null) ?? 100, minValue: ('min' in params ? params.min : null) ?? 0, value: value, + viewProps: defaultViewProps(), }); } diff --git a/lib/plugin/monitor-bindings/string/plugin.ts b/lib/plugin/monitor-bindings/string/plugin.ts index c81cdfdd8..355e77cd8 100644 --- a/lib/plugin/monitor-bindings/string/plugin.ts +++ b/lib/plugin/monitor-bindings/string/plugin.ts @@ -1,5 +1,6 @@ import {Constants} from '../../../misc/constants'; import {formatString, stringFromUnknown} from '../../common/converter/string'; +import {defaultViewProps} from '../../common/view/view'; import {MonitorBindingPlugin} from '../../monitor-binding'; import {MultiLogController} from '../common/controller/multi-log'; import {SingleLogMonitorController} from '../common/controller/single-log'; @@ -23,12 +24,14 @@ export const StringMonitorPlugin: MonitorBindingPlugin = { formatter: formatString, lineCount: args.params.lineCount ?? Constants.monitor.defaultLineCount, value: value, + viewProps: defaultViewProps(), }); } return new SingleLogMonitorController(args.document, { formatter: formatString, value: value, + viewProps: defaultViewProps(), }); }, }; diff --git a/lib/sass/view/_labeled.scss b/lib/sass/view/_labeled.scss index 4b6101ae9..ecfe640a3 100644 --- a/lib/sass/view/_labeled.scss +++ b/lib/sass/view/_labeled.scss @@ -17,6 +17,9 @@ padding-left: 4px; padding-right: 16px; } + &.#{$prefix}-v-disabled &_l { + opacity: 0.5; + } &_v { align-self: flex-start; flex-grow: 0; diff --git a/lib/sass/view/_root.scss b/lib/sass/view/_root.scss index 55a4935eb..77975d4dc 100644 --- a/lib/sass/view/_root.scss +++ b/lib/sass/view/_root.scss @@ -193,7 +193,10 @@ @extend %folder_container-expanded; } - // BladeView.hidden + &.#{$prefix}-v-disabled, + .#{$prefix}-v-disabled { + pointer-events: none; + } &.#{$prefix}-v-hidden, .#{$prefix}-v-hidden { display: none; diff --git a/lib/sass/view/common/_button.scss b/lib/sass/view/common/_button.scss index 01f0b9572..e9f112c0d 100644 --- a/lib/sass/view/common/_button.scss +++ b/lib/sass/view/common/_button.scss @@ -22,4 +22,7 @@ &:active { background-color: var(--btn-bg-a); } + &:disabled { + opacity: 0.5; + } } diff --git a/lib/sass/view/common/_input.scss b/lib/sass/view/common/_input.scss index 45e4350fa..f1ce4ec20 100644 --- a/lib/sass/view/common/_input.scss +++ b/lib/sass/view/common/_input.scss @@ -20,4 +20,7 @@ &:active { background-color: var(--in-bg-a); } + &:disabled { + opacity: 0.5; + } } diff --git a/src/doc/template/misc.html b/src/doc/template/misc.html index 0114c3cc9..fa90883a7 100644 --- a/src/doc/template/misc.html +++ b/src/doc/template/misc.html @@ -176,7 +176,7 @@

Refresh manually

-

Component visibility

+

Visibility

Toggle hidden property to show/hide components.

@@ -186,7 +186,8 @@

Component visibility

const f = pane.addFolder({ title: 'Advanced', }); -// f.addInput(PARAMS, ...); + +// ... btn.on('click', () => { f.hidden = !f.hidden; @@ -200,6 +201,32 @@

Component visibility

+

Disabled

+

Use disabled property to disable a view temporarily.

+ +
+
+
+
const pane = new Tweakpane();
+const i = pane.addInput(PARAMS, 'param', {
+  disabled: true,
+  title: 'Advanced',
+});
+
+// ...
+
+btn.on('click', () => {
+  i.disabled = !i.disabled;
+});
+
+
+
+
+
+
+
+ +

Disposing

If you want to dispose a pane manually, call dispose() of the pane. You can also dispose each component in the same way.

diff --git a/src/doc/ts/route/misc.ts b/src/doc/ts/route/misc.ts index fed0d57fb..2b61f9452 100644 --- a/src/doc/ts/route/misc.ts +++ b/src/doc/ts/route/misc.ts @@ -263,6 +263,34 @@ export function initMisc() { f.hidden = !f.hidden; }); }, + + disabled: (container) => { + const PARAMS = { + param: 1, + }; + const pane = new Tweakpane({ + container: container, + }); + + pane.addSeparator(); + const i = pane.addInput(PARAMS, 'param', { + disabled: true, + }); + const btn = pane.addButton({ + disabled: true, + title: 'Button', + }); + pane + .addButton({ + index: 0, + label: 'disabled', + title: 'Toggle', + }) + .on('click', () => { + i.disabled = !i.disabled; + btn.disabled = !btn.disabled; + }); + }, }; Object.keys(markerToFnMap).forEach((marker) => { const initFn = markerToFnMap[marker]; diff --git a/test-module/plugin/src/index.ts b/test-module/plugin/src/index.ts index 1a53dcc65..89219dd25 100644 --- a/test-module/plugin/src/index.ts +++ b/test-module/plugin/src/index.ts @@ -8,7 +8,11 @@ import { writePrimitive, } from 'tweakpane/lib/plugin/common/primitive'; import {ClassName} from 'tweakpane/lib/plugin/common/view/class-name'; -import {View} from 'tweakpane/lib/plugin/common/view/view'; +import { + defaultViewProps, + View, + ViewProps, +} from 'tweakpane/lib/plugin/common/view/view'; import {InputBindingPlugin} from 'tweakpane/lib/plugin/input-binding'; interface ViewConfig { @@ -41,9 +45,17 @@ class TestView implements View { class TestController implements ValueController { public readonly value: Value; public readonly view: TestView; + public readonly viewProps: ViewProps; - constructor(doc: Document, config: {value: Value}) { + constructor( + doc: Document, + config: { + value: Value; + viewProps: ViewProps; + }, + ) { this.value = config.value; + this.viewProps = config.viewProps; this.view = new TestView(doc, { value: config.value, @@ -70,6 +82,7 @@ class TestController implements ValueController { controller(args) { return new TestController(args.document, { value: args.value, + viewProps: defaultViewProps(), }); }, } as InputBindingPlugin, From 5fb8a53169429b92309676238eadff5ab6ec2f11 Mon Sep 17 00:00:00 2001 From: cocopon Date: Fri, 26 Mar 2021 06:26:08 +0900 Subject: [PATCH 02/10] Bump up package version --- .github/workflows/ci.yml | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 30012fd39..955855f0c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,7 +7,7 @@ on: branches: - main release: - types: [published] + types: [released] jobs: test: runs-on: ubuntu-latest diff --git a/package.json b/package.json index aee856f29..c68a96f10 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tweakpane", - "version": "2.1.6", + "version": "2.2.0-beta.0", "description": "A compact pane for fine-tuning parameters and monitoring value changes", "author": "cocopon", "license": "MIT", From 58baf370aba639b5b604d43ebda95dd82079d386 Mon Sep 17 00:00:00 2001 From: cocopon Date: Fri, 26 Mar 2021 08:40:34 +0900 Subject: [PATCH 03/10] Refactor view bindings --- lib/plugin/blade/button/view.ts | 8 +-- lib/plugin/blade/folder/view.ts | 8 +-- lib/plugin/blade/labeled/view.ts | 3 +- lib/plugin/blade/separator/view.ts | 3 +- lib/plugin/common/view/reactive.ts | 63 ++++++++++++++++++ lib/plugin/common/view/view.ts | 66 +------------------ lib/plugin/input-bindings/boolean/view.ts | 8 +-- lib/plugin/input-bindings/common/view/text.ts | 8 +-- .../input-bindings/number/view/number-text.ts | 8 +-- .../input-bindings/number/view/slider.ts | 3 +- .../monitor-bindings/common/view/list.ts | 3 +- 11 files changed, 82 insertions(+), 99 deletions(-) create mode 100644 lib/plugin/common/view/reactive.ts diff --git a/lib/plugin/blade/button/view.ts b/lib/plugin/blade/button/view.ts index d10a0ad92..517674335 100644 --- a/lib/plugin/blade/button/view.ts +++ b/lib/plugin/blade/button/view.ts @@ -1,10 +1,6 @@ import {ClassName} from '../../common/view/class-name'; -import { - bindDisabled, - bindViewProps, - View, - ViewProps, -} from '../../common/view/view'; +import {bindDisabled, bindViewProps} from '../../common/view/reactive'; +import {View, ViewProps} from '../../common/view/view'; import {Button} from './model/button'; interface Config { diff --git a/lib/plugin/blade/folder/view.ts b/lib/plugin/blade/folder/view.ts index 8bf63e491..fb8db5206 100644 --- a/lib/plugin/blade/folder/view.ts +++ b/lib/plugin/blade/folder/view.ts @@ -1,10 +1,6 @@ import {ClassName} from '../../common/view/class-name'; -import { - bindDisabled, - bindViewProps, - View, - ViewProps, -} from '../../common/view/view'; +import {bindDisabled, bindViewProps} from '../../common/view/reactive'; +import {View, ViewProps} from '../../common/view/view'; import {Folder} from './model/folder'; export interface Config { diff --git a/lib/plugin/blade/labeled/view.ts b/lib/plugin/blade/labeled/view.ts index 73f7ed5d8..d5f592515 100644 --- a/lib/plugin/blade/labeled/view.ts +++ b/lib/plugin/blade/labeled/view.ts @@ -1,5 +1,6 @@ import {ClassName} from '../../common/view/class-name'; -import {bindViewProps, View, ViewProps} from '../../common/view/view'; +import {bindViewProps} from '../../common/view/reactive'; +import {View, ViewProps} from '../../common/view/view'; interface Config { label?: string; diff --git a/lib/plugin/blade/separator/view.ts b/lib/plugin/blade/separator/view.ts index 8c9874971..6bbfcdbd7 100644 --- a/lib/plugin/blade/separator/view.ts +++ b/lib/plugin/blade/separator/view.ts @@ -1,5 +1,6 @@ import {ClassName} from '../../common/view/class-name'; -import {bindViewProps, View, ViewProps} from '../../common/view/view'; +import {bindViewProps} from '../../common/view/reactive'; +import {View, ViewProps} from '../../common/view/view'; const className = ClassName('spr'); diff --git a/lib/plugin/common/view/reactive.ts b/lib/plugin/common/view/reactive.ts new file mode 100644 index 000000000..0b2081ff0 --- /dev/null +++ b/lib/plugin/common/view/reactive.ts @@ -0,0 +1,63 @@ +import {SingleValueEvents} from '../model/value-map'; +import {ClassName} from './class-name'; +import {ViewProps} from './view'; + +function compose( + h1: (input: A) => B, + h2: (input: B) => C, +): (input: A) => C { + return (input) => h2(h1(input)); +} + +function extractValue(ev: SingleValueEvents['change']): T { + return ev.value; +} + +function applyClass(elem: HTMLElement, className: string, active: boolean) { + if (active) { + elem.classList.add(className); + } else { + elem.classList.remove(className); + } +} + +const className = ClassName(''); + +function updateModifier( + elem: HTMLElement, + modifier: string, +): (value: boolean) => void { + return (value) => { + applyClass(elem, className(undefined, modifier), value); + }; +} + +function updateDisabled( + elem: HTMLButtonElement | HTMLInputElement | HTMLSelectElement, +) { + return (value: boolean) => { + elem.disabled = value; + }; +} + +export function bindViewProps(viewProps: ViewProps, elem: HTMLElement) { + viewProps + .valueEmitter('disabled') + .on('change', compose(extractValue, updateModifier(elem, 'disabled'))); + updateModifier(elem, 'disabled')(viewProps.get('disabled')); + + viewProps + .valueEmitter('hidden') + .on('change', compose(extractValue, updateModifier(elem, 'hidden'))); + updateModifier(elem, 'hidden')(viewProps.get('hidden')); +} + +export function bindDisabled( + viewProps: ViewProps, + elem: HTMLButtonElement | HTMLInputElement | HTMLSelectElement, +) { + viewProps + .valueEmitter('disabled') + .on('change', compose(extractValue, updateDisabled(elem))); + updateDisabled(elem)(viewProps.get('disabled')); +} diff --git a/lib/plugin/common/view/view.ts b/lib/plugin/common/view/view.ts index f2c979cab..0dcbd1bd5 100644 --- a/lib/plugin/common/view/view.ts +++ b/lib/plugin/common/view/view.ts @@ -1,5 +1,4 @@ -import {SingleValueEvents, ValueMap, ValueMapEvents} from '../model/value-map'; -import {ClassName} from './class-name'; +import {ValueMap, ValueMapEvents} from '../model/value-map'; interface ViewPropsObject extends Record { disabled: boolean; @@ -30,66 +29,3 @@ export function defaultViewProps( hidden: initialValue.hidden ?? false, }); } - -const className = ClassName(''); - -function applyClass(elem: HTMLElement, className: string, active: boolean) { - if (active) { - elem.classList.add(className); - } else { - elem.classList.remove(className); - } -} - -function extractValue(ev: SingleValueEvents['change']): T { - return ev.value; -} - -function pipe( - h1: (input: A) => B, - h2: (input: B) => C, -): (input: A) => C { - return (input) => h2(h1(input)); -} - -function applyHiddenClass(elem: HTMLElement): (value: boolean) => void { - return (value) => { - applyClass(elem, className(undefined, 'hidden'), value); - }; -} - -function applyDisabledClass(elem: HTMLElement): (value: boolean) => void { - return (value) => { - applyClass(elem, className(undefined, 'disabled'), value); - }; -} - -function applyDisabled( - elem: HTMLButtonElement | HTMLInputElement | HTMLSelectElement, -) { - return (value: boolean) => { - elem.disabled = value; - }; -} - -export function bindViewProps(viewProps: ViewProps, elem: HTMLElement) { - viewProps - .valueEmitter('disabled') - .on('change', pipe(extractValue, applyDisabledClass(elem))); - applyDisabledClass(elem)(viewProps.get('disabled')); - - viewProps - .valueEmitter('hidden') - .on('change', pipe(extractValue, applyHiddenClass(elem))); - applyHiddenClass(elem)(viewProps.get('hidden')); -} - -export function bindDisabled( - viewProps: ViewProps, - elem: HTMLButtonElement | HTMLInputElement | HTMLSelectElement, -) { - viewProps - .valueEmitter('disabled') - .on('change', pipe(extractValue, applyDisabled(elem))); - applyDisabled(elem)(viewProps.get('disabled')); -} diff --git a/lib/plugin/input-bindings/boolean/view.ts b/lib/plugin/input-bindings/boolean/view.ts index a4f007268..52abca71e 100644 --- a/lib/plugin/input-bindings/boolean/view.ts +++ b/lib/plugin/input-bindings/boolean/view.ts @@ -1,12 +1,8 @@ import {createSvgIconElement} from '../../common/dom-util'; import {Value} from '../../common/model/value'; import {ClassName} from '../../common/view/class-name'; -import { - bindDisabled, - bindViewProps, - View, - ViewProps, -} from '../../common/view/view'; +import {bindDisabled, bindViewProps} from '../../common/view/reactive'; +import {View, ViewProps} from '../../common/view/view'; interface Config { value: Value; diff --git a/lib/plugin/input-bindings/common/view/text.ts b/lib/plugin/input-bindings/common/view/text.ts index 0e0862a4d..61d56ae17 100644 --- a/lib/plugin/input-bindings/common/view/text.ts +++ b/lib/plugin/input-bindings/common/view/text.ts @@ -2,12 +2,8 @@ import {Formatter} from '../../../common/converter/formatter'; import {Value} from '../../../common/model/value'; import {ValueMap} from '../../../common/model/value-map'; import {ClassName} from '../../../common/view/class-name'; -import { - bindDisabled, - bindViewProps, - View, - ViewProps, -} from '../../../common/view/view'; +import {bindDisabled, bindViewProps} from '../../../common/view/reactive'; +import {View, ViewProps} from '../../../common/view/view'; export type TextProps = ValueMap<{ formatter: Formatter; diff --git a/lib/plugin/input-bindings/number/view/number-text.ts b/lib/plugin/input-bindings/number/view/number-text.ts index e4947258d..ce09141e5 100644 --- a/lib/plugin/input-bindings/number/view/number-text.ts +++ b/lib/plugin/input-bindings/number/view/number-text.ts @@ -4,12 +4,8 @@ import {Value, ValueEvents} from '../../../common/model/value'; import {ValueMap} from '../../../common/model/value-map'; import {constrainRange} from '../../../common/number-util'; import {ClassName} from '../../../common/view/class-name'; -import { - bindDisabled, - bindViewProps, - View, - ViewProps, -} from '../../../common/view/view'; +import {bindDisabled, bindViewProps} from '../../../common/view/reactive'; +import {View, ViewProps} from '../../../common/view/view'; export type NumberTextProps = ValueMap<{ draggingScale: number; diff --git a/lib/plugin/input-bindings/number/view/slider.ts b/lib/plugin/input-bindings/number/view/slider.ts index 175613efb..4837d91e5 100644 --- a/lib/plugin/input-bindings/number/view/slider.ts +++ b/lib/plugin/input-bindings/number/view/slider.ts @@ -2,7 +2,8 @@ import {Value} from '../../../common/model/value'; import {ValueMap} from '../../../common/model/value-map'; import {constrainRange, mapRange} from '../../../common/number-util'; import {ClassName} from '../../../common/view/class-name'; -import {bindViewProps, View, ViewProps} from '../../../common/view/view'; +import {bindViewProps} from '../../../common/view/reactive'; +import {View, ViewProps} from '../../../common/view/view'; export type SliderProps = ValueMap<{ maxValue: number; diff --git a/lib/plugin/monitor-bindings/common/view/list.ts b/lib/plugin/monitor-bindings/common/view/list.ts index 93d90cc98..20b8c52be 100644 --- a/lib/plugin/monitor-bindings/common/view/list.ts +++ b/lib/plugin/monitor-bindings/common/view/list.ts @@ -2,7 +2,8 @@ import {ListItem} from '../../../common/constraint/list'; import {createSvgIconElement} from '../../../common/dom-util'; import {Value} from '../../../common/model/value'; import {ClassName} from '../../../common/view/class-name'; -import {bindViewProps, View, ViewProps} from '../../../common/view/view'; +import {bindViewProps} from '../../../common/view/reactive'; +import {View, ViewProps} from '../../../common/view/view'; interface Config { options: ListItem[]; From 06dc0ba2122fb96f0301e6d5737fe6a1579f0e18 Mon Sep 17 00:00:00 2001 From: cocopon Date: Sat, 27 Mar 2021 04:23:07 +0900 Subject: [PATCH 04/10] Refactor ViewProps --- lib/api/button-test.ts | 4 ++-- lib/api/folder-test.ts | 4 ++-- lib/api/folder.ts | 8 ++++---- lib/api/input-binding-test.ts | 4 ++-- lib/api/monitor-binding-test.ts | 4 ++-- lib/api/separator-test.ts | 4 ++-- lib/index.ts | 4 ++-- lib/pane/tweakpane-test.ts | 4 ++-- .../blade/button/controller/button-test.ts | 4 ++-- lib/plugin/blade/button/controller/button.ts | 2 +- lib/plugin/blade/button/view.ts | 3 ++- .../blade/common/controller/blade-test.ts | 5 +++-- .../common/controller/input-binding-test.ts | 4 ++-- .../blade/common/controller/input-binding.ts | 2 +- .../common/controller/monitor-binding-test.ts | 4 ++-- .../common/controller/monitor-binding.ts | 2 +- .../blade/common/model/blade-rack-test.ts | 8 ++++---- lib/plugin/blade/common/model/blade-rack.ts | 2 +- lib/plugin/blade/folder/controller-test.ts | 18 ++++++++--------- lib/plugin/blade/folder/controller.ts | 2 +- lib/plugin/blade/folder/root.ts | 2 +- lib/plugin/blade/folder/view.ts | 3 ++- lib/plugin/blade/labeled/controller.ts | 2 +- lib/plugin/blade/labeled/view.ts | 3 ++- lib/plugin/blade/separator/controller.ts | 2 +- lib/plugin/blade/separator/view.ts | 3 ++- lib/plugin/common/controller/controller.ts | 3 ++- .../view-test.ts => model/view-props-test.ts} | 6 +++--- lib/plugin/common/model/view-props.ts | 19 ++++++++++++++++++ lib/plugin/common/view/reactive.ts | 2 +- lib/plugin/common/view/view.ts | 20 ------------------- lib/plugin/input-binding-test.ts | 5 +++-- lib/plugin/input-binding.ts | 4 ++-- .../input-bindings/boolean/controller.ts | 2 +- lib/plugin/input-bindings/boolean/view.ts | 3 ++- .../color/controller/a-palette.ts | 2 +- .../color/controller/color-picker-test.ts | 6 +++--- .../color/controller/color-picker.ts | 2 +- .../color/controller/color-swatch-text.ts | 2 +- .../color/controller/color-swatch.ts | 2 +- .../color/controller/color-text-test.ts | 6 +++--- .../color/controller/color-text.ts | 2 +- .../color/controller/h-palette.ts | 2 +- .../color/controller/sv-palette.ts | 2 +- .../common/controller/list-test.ts | 6 +++--- .../input-bindings/common/controller/list.ts | 2 +- .../common/controller/point-nd-text-test.ts | 4 ++-- .../common/controller/point-nd-text.ts | 2 +- .../common/controller/text-test.ts | 6 +++--- .../input-bindings/common/controller/text.ts | 2 +- .../input-bindings/common/view/text-test.ts | 8 ++++---- lib/plugin/input-bindings/common/view/text.ts | 3 ++- .../number/controller/number-text-test.ts | 4 ++-- .../number/controller/number-text.ts | 2 +- .../number/controller/slider-text.ts | 2 +- .../number/controller/slider.ts | 2 +- .../input-bindings/number/view/number-text.ts | 3 ++- .../input-bindings/number/view/slider-test.ts | 8 ++++---- .../input-bindings/number/view/slider.ts | 3 ++- .../point-2d/controller/point-2d-pad-text.ts | 2 +- .../point-2d/controller/point-2d-pad.ts | 2 +- lib/plugin/monitor-binding-test.ts | 5 +++-- lib/plugin/monitor-bindings/boolean/plugin.ts | 6 +++--- .../common/controller/multi-log.ts | 2 +- .../common/controller/single-log.ts | 2 +- .../monitor-bindings/common/view/list.ts | 3 ++- .../number/controller/graph-log.ts | 2 +- lib/plugin/monitor-bindings/number/plugin.ts | 8 ++++---- lib/plugin/monitor-bindings/string/plugin.ts | 6 +++--- test-module/plugin/src/index.ts | 9 +++------ 70 files changed, 155 insertions(+), 146 deletions(-) rename lib/plugin/common/{view/view-test.ts => model/view-props-test.ts} (85%) create mode 100644 lib/plugin/common/model/view-props.ts diff --git a/lib/api/button-test.ts b/lib/api/button-test.ts index ce16362b4..a25ac26ba 100644 --- a/lib/api/button-test.ts +++ b/lib/api/button-test.ts @@ -5,7 +5,7 @@ import {TestUtil} from '../misc/test-util'; import {ButtonController} from '../plugin/blade/button/controller/button'; import {Blade} from '../plugin/blade/common/model/blade'; import {LabeledController} from '../plugin/blade/labeled/controller'; -import {defaultViewProps} from '../plugin/common/view/view'; +import {createViewProps} from '../plugin/common/model/view-props'; import {ButtonApi} from './button'; function createApi(doc: Document): ButtonApi { @@ -13,7 +13,7 @@ function createApi(doc: Document): ButtonApi { blade: new Blade(), valueController: new ButtonController(doc, { title: 'Button', - viewProps: defaultViewProps(), + viewProps: createViewProps(), }), }); return new ButtonApi(c); diff --git a/lib/api/folder-test.ts b/lib/api/folder-test.ts index 9cf6fd878..842f4b8fa 100644 --- a/lib/api/folder-test.ts +++ b/lib/api/folder-test.ts @@ -8,7 +8,7 @@ import {Blade} from '../plugin/blade/common/model/blade'; import {FolderController} from '../plugin/blade/folder/controller'; import {LabeledController} from '../plugin/blade/labeled/controller'; import {SeparatorController} from '../plugin/blade/separator/controller'; -import {defaultViewProps} from '../plugin/common/view/view'; +import {createViewProps} from '../plugin/common/model/view-props'; import {Color} from '../plugin/input-bindings/color/model/color'; import {NumberTextController} from '../plugin/input-bindings/number/controller/number-text'; import {SingleLogMonitorController} from '../plugin/monitor-bindings/common/controller/single-log'; @@ -22,7 +22,7 @@ function createApi(): FolderApi { const c = new FolderController(doc, { blade: new Blade(), title: 'Folder', - viewProps: defaultViewProps(), + viewProps: createViewProps(), }); return new FolderApi(c); } diff --git a/lib/api/folder.ts b/lib/api/folder.ts index 54260b19d..872fc7294 100644 --- a/lib/api/folder.ts +++ b/lib/api/folder.ts @@ -8,8 +8,8 @@ import {FolderEvents} from '../plugin/blade/folder/model/folder'; import {LabeledController} from '../plugin/blade/labeled/controller'; import {SeparatorController} from '../plugin/blade/separator/controller'; import {Emitter} from '../plugin/common/model/emitter'; +import {createViewProps} from '../plugin/common/model/view-props'; import {TpError} from '../plugin/common/tp-error'; -import {defaultViewProps} from '../plugin/common/view/view'; import {BladeApi} from './blade-api'; import {ButtonApi} from './button'; import {InputBindingApi} from './input-binding'; @@ -132,7 +132,7 @@ export class FolderApi implements BladeApi { const bc = new FolderController(this.controller.document, { ...params, blade: new Blade(), - viewProps: defaultViewProps(), + viewProps: createViewProps(), }); this.controller.bladeRack.add(bc, params.index); @@ -148,7 +148,7 @@ export class FolderApi implements BladeApi { label: params.label, valueController: new ButtonController(doc, { ...params, - viewProps: defaultViewProps({ + viewProps: createViewProps({ disabled: params.disabled, }), }), @@ -164,7 +164,7 @@ export class FolderApi implements BladeApi { const params = opt_params || {}; const bc = new SeparatorController(this.controller.document, { blade: new Blade(), - viewProps: defaultViewProps(), + viewProps: createViewProps(), }); this.controller.bladeRack.add(bc, params.index); diff --git a/lib/api/input-binding-test.ts b/lib/api/input-binding-test.ts index bef18159c..503741281 100644 --- a/lib/api/input-binding-test.ts +++ b/lib/api/input-binding-test.ts @@ -12,8 +12,8 @@ import { } from '../plugin/common/converter/number'; import {numberFromUnknown} from '../plugin/common/converter/number'; import {Value} from '../plugin/common/model/value'; +import {createViewProps} from '../plugin/common/model/view-props'; import {writePrimitive} from '../plugin/common/primitive'; -import {defaultViewProps} from '../plugin/common/view/view'; import {NumberTextController} from '../plugin/input-bindings/number/controller/number-text'; import {InputBindingApi} from './input-binding'; import {TpChangeEvent} from './tp-event'; @@ -27,7 +27,7 @@ function createApi(target: BindingTarget) { formatter: createNumberFormatter(0), parser: parseNumber, value: value, - viewProps: defaultViewProps(), + viewProps: createViewProps(), }); const bc = new InputBindingController(doc, { binding: new InputBinding({ diff --git a/lib/api/monitor-binding-test.ts b/lib/api/monitor-binding-test.ts index 243676d49..debbe05e5 100644 --- a/lib/api/monitor-binding-test.ts +++ b/lib/api/monitor-binding-test.ts @@ -11,7 +11,7 @@ import {createNumberFormatter} from '../plugin/common/converter/number'; import {numberFromUnknown} from '../plugin/common/converter/number'; import {Buffer} from '../plugin/common/model/buffered-value'; import {Value} from '../plugin/common/model/value'; -import {defaultViewProps} from '../plugin/common/view/view'; +import {createViewProps} from '../plugin/common/model/view-props'; import {SingleLogMonitorController} from '../plugin/monitor-bindings/common/controller/single-log'; import {MonitorBindingApi} from './monitor-binding'; import {TpUpdateEvent} from './tp-event'; @@ -22,7 +22,7 @@ function createApi(target: BindingTarget) { const mc = new SingleLogMonitorController(doc, { formatter: createNumberFormatter(0), value: value, - viewProps: defaultViewProps(), + viewProps: createViewProps(), }); const bc = new MonitorBindingController(doc, { binding: new MonitorBinding({ diff --git a/lib/api/separator-test.ts b/lib/api/separator-test.ts index dedecee69..6526dc04f 100644 --- a/lib/api/separator-test.ts +++ b/lib/api/separator-test.ts @@ -4,13 +4,13 @@ import {describe, it} from 'mocha'; import {TestUtil} from '../misc/test-util'; import {Blade} from '../plugin/blade/common/model/blade'; import {SeparatorController} from '../plugin/blade/separator/controller'; -import {defaultViewProps} from '../plugin/common/view/view'; +import {createViewProps} from '../plugin/common/model/view-props'; import {SeparatorApi} from './separator'; function createApi(doc: Document): SeparatorApi { const c = new SeparatorController(doc, { blade: new Blade(), - viewProps: defaultViewProps(), + viewProps: createViewProps(), }); return new SeparatorApi(c); } diff --git a/lib/index.ts b/lib/index.ts index ad0fe6b8f..b6385187c 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -5,9 +5,9 @@ import {TweakpaneConfig} from './pane/tweakpane-config'; import {Blade} from './plugin/blade/common/model/blade'; import {RootController} from './plugin/blade/folder/root'; import {getWindowDocument} from './plugin/common/dom-util'; +import {createViewProps} from './plugin/common/model/view-props'; import {TpError} from './plugin/common/tp-error'; import {ClassName} from './plugin/common/view/class-name'; -import {defaultViewProps} from './plugin/common/view/view'; import {InputBindingPlugin} from './plugin/input-binding'; import {BooleanInputPlugin} from './plugin/input-bindings/boolean/plugin'; import {NumberColorInputPlugin} from './plugin/input-bindings/color/plugin-number'; @@ -66,7 +66,7 @@ export default class Tweakpane extends RootApi { expanded: config.expanded, blade: new Blade(), title: config.title, - viewProps: defaultViewProps(), + viewProps: createViewProps(), }); super(rootController); diff --git a/lib/pane/tweakpane-test.ts b/lib/pane/tweakpane-test.ts index 35ac64f83..c66e70e78 100644 --- a/lib/pane/tweakpane-test.ts +++ b/lib/pane/tweakpane-test.ts @@ -8,9 +8,9 @@ import { stringFromUnknown, } from '../plugin/common/converter/string'; import {ValueMap} from '../plugin/common/model/value-map'; +import {createViewProps} from '../plugin/common/model/view-props'; import {equalsPrimitive, writePrimitive} from '../plugin/common/primitive'; import {TpError} from '../plugin/common/tp-error'; -import {defaultViewProps} from '../plugin/common/view/view'; import {TextController} from '../plugin/input-bindings/common/controller/text'; describe(Tweakpane.name, () => { @@ -104,7 +104,7 @@ describe(Tweakpane.name, () => { formatter: formatString, }), value: args.value, - viewProps: defaultViewProps(), + viewProps: createViewProps(), }); }, }, diff --git a/lib/plugin/blade/button/controller/button-test.ts b/lib/plugin/blade/button/controller/button-test.ts index d41fcca7e..1c299cff1 100644 --- a/lib/plugin/blade/button/controller/button-test.ts +++ b/lib/plugin/blade/button/controller/button-test.ts @@ -2,7 +2,7 @@ import {assert} from 'chai'; import {describe, it} from 'mocha'; import {TestUtil} from '../../../../misc/test-util'; -import {defaultViewProps} from '../../../common/view/view'; +import {createViewProps} from '../../../common/model/view-props'; import {ButtonController} from './button'; describe(ButtonController.name, () => { @@ -10,7 +10,7 @@ describe(ButtonController.name, () => { const doc = TestUtil.createWindow().document; const c = new ButtonController(doc, { title: 'Push', - viewProps: defaultViewProps(), + viewProps: createViewProps(), }); c.button.emitter.on('click', () => { diff --git a/lib/plugin/blade/button/controller/button.ts b/lib/plugin/blade/button/controller/button.ts index 17d55ebf8..ab1a51713 100644 --- a/lib/plugin/blade/button/controller/button.ts +++ b/lib/plugin/blade/button/controller/button.ts @@ -1,5 +1,5 @@ import {Controller} from '../../../common/controller/controller'; -import {ViewProps} from '../../../common/view/view'; +import {ViewProps} from '../../../common/model/view-props'; import {Button} from '../model/button'; import {ButtonView} from '../view'; diff --git a/lib/plugin/blade/button/view.ts b/lib/plugin/blade/button/view.ts index 517674335..add36f072 100644 --- a/lib/plugin/blade/button/view.ts +++ b/lib/plugin/blade/button/view.ts @@ -1,6 +1,7 @@ +import {ViewProps} from '../../common/model/view-props'; import {ClassName} from '../../common/view/class-name'; import {bindDisabled, bindViewProps} from '../../common/view/reactive'; -import {View, ViewProps} from '../../common/view/view'; +import {View} from '../../common/view/view'; import {Button} from './model/button'; interface Config { diff --git a/lib/plugin/blade/common/controller/blade-test.ts b/lib/plugin/blade/common/controller/blade-test.ts index 35c272ca9..3924d23f1 100644 --- a/lib/plugin/blade/common/controller/blade-test.ts +++ b/lib/plugin/blade/common/controller/blade-test.ts @@ -2,7 +2,8 @@ import {assert} from 'chai'; import {describe, it} from 'mocha'; import {TestUtil} from '../../../../misc/test-util'; -import {defaultViewProps, View} from '../../../common/view/view'; +import {createViewProps} from '../../../common/model/view-props'; +import {View} from '../../../common/view/view'; import {Blade} from '../model/blade'; import {BladeController, setUpBladeController} from './blade'; @@ -19,7 +20,7 @@ class TestView implements View { class TestController implements BladeController { public readonly blade: Blade; public readonly view: TestView; - public readonly viewProps = defaultViewProps(); + public readonly viewProps = createViewProps(); constructor(doc: Document) { this.blade = new Blade(); diff --git a/lib/plugin/blade/common/controller/input-binding-test.ts b/lib/plugin/blade/common/controller/input-binding-test.ts index dd4ffc47e..96a728101 100644 --- a/lib/plugin/blade/common/controller/input-binding-test.ts +++ b/lib/plugin/blade/common/controller/input-binding-test.ts @@ -11,7 +11,7 @@ import { import {numberFromUnknown} from '../../../common/converter/number'; import {Value} from '../../../common/model/value'; import {ValueMap} from '../../../common/model/value-map'; -import {defaultViewProps} from '../../../common/view/view'; +import {createViewProps} from '../../../common/model/view-props'; import {TextController} from '../../../input-bindings/common/controller/text'; import {Blade} from '../model/blade'; import {InputBindingController} from './input-binding'; @@ -35,7 +35,7 @@ describe(InputBindingController.name, () => { formatter: createNumberFormatter(0), }), value: value, - viewProps: defaultViewProps(), + viewProps: createViewProps(), }); const bc = new InputBindingController(doc, { binding: binding, diff --git a/lib/plugin/blade/common/controller/input-binding.ts b/lib/plugin/blade/common/controller/input-binding.ts index e34d67e09..db9af1822 100644 --- a/lib/plugin/blade/common/controller/input-binding.ts +++ b/lib/plugin/blade/common/controller/input-binding.ts @@ -1,6 +1,6 @@ import {InputBinding} from '../../../common/binding/input'; import {ValueController} from '../../../common/controller/value'; -import {ViewProps} from '../../../common/view/view'; +import {ViewProps} from '../../../common/model/view-props'; import {LabeledView} from '../../labeled/view'; import {Blade} from '../model/blade'; import {BladeController, setUpBladeController} from './blade'; diff --git a/lib/plugin/blade/common/controller/monitor-binding-test.ts b/lib/plugin/blade/common/controller/monitor-binding-test.ts index 3c1e921f2..79f681c9c 100644 --- a/lib/plugin/blade/common/controller/monitor-binding-test.ts +++ b/lib/plugin/blade/common/controller/monitor-binding-test.ts @@ -8,7 +8,7 @@ import {ManualTicker} from '../../../common/binding/ticker/manual'; import {createNumberFormatter} from '../../../common/converter/number'; import {numberFromUnknown} from '../../../common/converter/number'; import {Value} from '../../../common/model/value'; -import {defaultViewProps} from '../../../common/view/view'; +import {createViewProps} from '../../../common/model/view-props'; import {SingleLogMonitorController} from '../../../monitor-bindings/common/controller/single-log'; import {Blade} from '../model/blade'; import {MonitorBindingController} from './monitor-binding'; @@ -29,7 +29,7 @@ describe(MonitorBindingController.name, () => { const controller = new SingleLogMonitorController(doc, { formatter: createNumberFormatter(0), value: value, - viewProps: defaultViewProps(), + viewProps: createViewProps(), }); const bc = new MonitorBindingController(doc, { binding: binding, diff --git a/lib/plugin/blade/common/controller/monitor-binding.ts b/lib/plugin/blade/common/controller/monitor-binding.ts index 0bcb3e3e3..ceb61bff5 100644 --- a/lib/plugin/blade/common/controller/monitor-binding.ts +++ b/lib/plugin/blade/common/controller/monitor-binding.ts @@ -1,7 +1,7 @@ import {MonitorBinding} from '../../../common/binding/monitor'; import {ValueController} from '../../../common/controller/value'; import {Buffer} from '../../../common/model/buffered-value'; -import {ViewProps} from '../../../common/view/view'; +import {ViewProps} from '../../../common/model/view-props'; import {LabeledView} from '../../labeled/view'; import {Blade} from '../model/blade'; import {BladeController, setUpBladeController} from './blade'; diff --git a/lib/plugin/blade/common/model/blade-rack-test.ts b/lib/plugin/blade/common/model/blade-rack-test.ts index 9e92dd7c8..38c2f085e 100644 --- a/lib/plugin/blade/common/model/blade-rack-test.ts +++ b/lib/plugin/blade/common/model/blade-rack-test.ts @@ -11,8 +11,8 @@ import {boolFromUnknown} from '../../../common/converter/boolean'; import {stringFromUnknown} from '../../../common/converter/string'; import {Buffer} from '../../../common/model/buffered-value'; import {Value} from '../../../common/model/value'; +import {createViewProps} from '../../../common/model/view-props'; import {writePrimitive} from '../../../common/primitive'; -import {defaultViewProps} from '../../../common/view/view'; import {CheckboxController} from '../../../input-bindings/boolean/controller'; import {SingleLogMonitorController} from '../../../monitor-bindings/common/controller/single-log'; import {FolderController} from '../../folder/controller'; @@ -35,7 +35,7 @@ function createInputBindingController( binding: b, controller: new CheckboxController(doc, { value: b.value, - viewProps: defaultViewProps(), + viewProps: createViewProps(), }), label: '', }); @@ -56,7 +56,7 @@ function createMonitorBindingController( controller: new SingleLogMonitorController(doc, { formatter: (v) => String(v), value: b.value, - viewProps: defaultViewProps(), + viewProps: createViewProps(), }), label: '', }); @@ -66,7 +66,7 @@ function createFolderController(doc: Document): FolderController { return new FolderController(doc, { blade: new Blade(), title: 'folder', - viewProps: defaultViewProps(), + viewProps: createViewProps(), }); } diff --git a/lib/plugin/blade/common/model/blade-rack.ts b/lib/plugin/blade/common/model/blade-rack.ts index 89804d3ce..f4840d162 100644 --- a/lib/plugin/blade/common/model/blade-rack.ts +++ b/lib/plugin/blade/common/model/blade-rack.ts @@ -5,8 +5,8 @@ import { MonitorBindingEvents, } from '../../../common/binding/monitor'; import {Emitter} from '../../../common/model/emitter'; +import {ViewPropsEvents} from '../../../common/model/view-props'; import {TpError} from '../../../common/tp-error'; -import {ViewPropsEvents} from '../../../common/view/view'; import {FolderController} from '../../folder/controller'; import {Folder, FolderEvents} from '../../folder/model/folder'; import {BladeController} from '../controller/blade'; diff --git a/lib/plugin/blade/folder/controller-test.ts b/lib/plugin/blade/folder/controller-test.ts index 53ad620d2..b49085c15 100644 --- a/lib/plugin/blade/folder/controller-test.ts +++ b/lib/plugin/blade/folder/controller-test.ts @@ -2,7 +2,7 @@ import {assert} from 'chai'; import {describe, it} from 'mocha'; import {TestUtil} from '../../../misc/test-util'; -import {defaultViewProps} from '../../common/view/view'; +import {createViewProps} from '../../common/model/view-props'; import {ButtonController} from '../button/controller/button'; import {BladeController} from '../common/controller/blade'; import {Blade} from '../common/model/blade'; @@ -15,7 +15,7 @@ function createSomeBladeController(doc: Document): BladeController { blade: new Blade(), valueController: new ButtonController(doc, { title: 'Foobar', - viewProps: defaultViewProps(), + viewProps: createViewProps(), }), }); } @@ -26,7 +26,7 @@ describe(FolderController.name, () => { const c = new FolderController(doc, { title: 'Push', blade: new Blade(), - viewProps: defaultViewProps(), + viewProps: createViewProps(), }); assert.strictEqual(c.folder.expanded, true); @@ -47,7 +47,7 @@ describe(FolderController.name, () => { const c = new FolderController(doc, { title: 'Push', blade: new Blade(), - viewProps: defaultViewProps(), + viewProps: createViewProps(), }); const bc = createSomeBladeController(doc); c.bladeRack.add(bc); @@ -62,13 +62,13 @@ describe(FolderController.name, () => { const c = new FolderController(doc, { title: 'Folder', blade: new Blade(), - viewProps: defaultViewProps(), + viewProps: createViewProps(), }); const sc = new FolderController(doc, { title: 'Subfolder', blade: new Blade(), - viewProps: defaultViewProps(), + viewProps: createViewProps(), }); c.bladeRack.add(sc); @@ -82,7 +82,7 @@ describe(FolderController.name, () => { const c = new FolderController(doc, { title: '', blade: new Blade(), - viewProps: defaultViewProps(), + viewProps: createViewProps(), }); const bcs = [ @@ -105,12 +105,12 @@ describe(FolderController.name, () => { const c = new FolderController(doc, { title: '', blade: new Blade(), - viewProps: defaultViewProps(), + viewProps: createViewProps(), }); const sc = new FolderController(doc, { title: '', blade: new Blade(), - viewProps: defaultViewProps(), + viewProps: createViewProps(), }); c.bladeRack.add(sc); const bc = createSomeBladeController(doc); diff --git a/lib/plugin/blade/folder/controller.ts b/lib/plugin/blade/folder/controller.ts index 746151f8d..7ade02411 100644 --- a/lib/plugin/blade/folder/controller.ts +++ b/lib/plugin/blade/folder/controller.ts @@ -1,6 +1,6 @@ import {isEmpty} from '../../../misc/type-util'; import {forceReflow, insertElementAt} from '../../common/dom-util'; -import {ViewProps} from '../../common/view/view'; +import {ViewProps} from '../../common/model/view-props'; import { BladeController, setUpBladeController, diff --git a/lib/plugin/blade/folder/root.ts b/lib/plugin/blade/folder/root.ts index 52b53db06..bfeb60aec 100644 --- a/lib/plugin/blade/folder/root.ts +++ b/lib/plugin/blade/folder/root.ts @@ -1,4 +1,4 @@ -import {ViewProps} from '../../common/view/view'; +import {ViewProps} from '../../common/model/view-props'; import {Blade} from '../common/model/blade'; import {FolderController} from './controller'; diff --git a/lib/plugin/blade/folder/view.ts b/lib/plugin/blade/folder/view.ts index fb8db5206..857eaf57a 100644 --- a/lib/plugin/blade/folder/view.ts +++ b/lib/plugin/blade/folder/view.ts @@ -1,6 +1,7 @@ +import {ViewProps} from '../../common/model/view-props'; import {ClassName} from '../../common/view/class-name'; import {bindDisabled, bindViewProps} from '../../common/view/reactive'; -import {View, ViewProps} from '../../common/view/view'; +import {View} from '../../common/view/view'; import {Folder} from './model/folder'; export interface Config { diff --git a/lib/plugin/blade/labeled/controller.ts b/lib/plugin/blade/labeled/controller.ts index 94f00cd82..49acc9c9e 100644 --- a/lib/plugin/blade/labeled/controller.ts +++ b/lib/plugin/blade/labeled/controller.ts @@ -1,5 +1,5 @@ import {Controller} from '../../common/controller/controller'; -import {ViewProps} from '../../common/view/view'; +import {ViewProps} from '../../common/model/view-props'; import { BladeController, setUpBladeController, diff --git a/lib/plugin/blade/labeled/view.ts b/lib/plugin/blade/labeled/view.ts index d5f592515..530f99d1d 100644 --- a/lib/plugin/blade/labeled/view.ts +++ b/lib/plugin/blade/labeled/view.ts @@ -1,6 +1,7 @@ +import {ViewProps} from '../../common/model/view-props'; import {ClassName} from '../../common/view/class-name'; import {bindViewProps} from '../../common/view/reactive'; -import {View, ViewProps} from '../../common/view/view'; +import {View} from '../../common/view/view'; interface Config { label?: string; diff --git a/lib/plugin/blade/separator/controller.ts b/lib/plugin/blade/separator/controller.ts index 50d3aa72f..4f042a5ed 100644 --- a/lib/plugin/blade/separator/controller.ts +++ b/lib/plugin/blade/separator/controller.ts @@ -1,4 +1,4 @@ -import {ViewProps} from '../../common/view/view'; +import {ViewProps} from '../../common/model/view-props'; import { BladeController, setUpBladeController, diff --git a/lib/plugin/blade/separator/view.ts b/lib/plugin/blade/separator/view.ts index 6bbfcdbd7..4aa097f95 100644 --- a/lib/plugin/blade/separator/view.ts +++ b/lib/plugin/blade/separator/view.ts @@ -1,6 +1,7 @@ +import {ViewProps} from '../../common/model/view-props'; import {ClassName} from '../../common/view/class-name'; import {bindViewProps} from '../../common/view/reactive'; -import {View, ViewProps} from '../../common/view/view'; +import {View} from '../../common/view/view'; const className = ClassName('spr'); diff --git a/lib/plugin/common/controller/controller.ts b/lib/plugin/common/controller/controller.ts index 935d9e55b..7d34aa93c 100644 --- a/lib/plugin/common/controller/controller.ts +++ b/lib/plugin/common/controller/controller.ts @@ -1,4 +1,5 @@ -import {View, ViewProps} from '../view/view'; +import {ViewProps} from '../model/view-props'; +import {View} from '../view/view'; /** * A controller that has a view to control. diff --git a/lib/plugin/common/view/view-test.ts b/lib/plugin/common/model/view-props-test.ts similarity index 85% rename from lib/plugin/common/view/view-test.ts rename to lib/plugin/common/model/view-props-test.ts index 576ed3673..d2ebc2502 100644 --- a/lib/plugin/common/view/view-test.ts +++ b/lib/plugin/common/model/view-props-test.ts @@ -1,9 +1,9 @@ import {assert} from 'chai'; import {describe, it as context, it} from 'mocha'; -import {defaultViewProps} from './view'; +import {createViewProps} from './view-props'; -describe(defaultViewProps.name, () => { +describe(createViewProps.name, () => { [ { params: undefined, @@ -36,7 +36,7 @@ describe(defaultViewProps.name, () => { ].forEach(({params, expected}) => { context(`when ${JSON.stringify(params)}`, () => { it('should set initial value', () => { - const p = defaultViewProps(params); + const p = createViewProps(params); assert.strictEqual(p.get('disabled'), expected.disabled); assert.strictEqual(p.get('hidden'), expected.hidden); }); diff --git a/lib/plugin/common/model/view-props.ts b/lib/plugin/common/model/view-props.ts new file mode 100644 index 000000000..bdd4610cc --- /dev/null +++ b/lib/plugin/common/model/view-props.ts @@ -0,0 +1,19 @@ +import {ValueMap, ValueMapEvents} from './value-map'; + +interface ViewPropsObject extends Record { + disabled: boolean; + hidden: boolean; +} + +export type ViewProps = ValueMap; +export type ViewPropsEvents = ValueMapEvents; + +export function createViewProps( + opt_initialValue?: Partial, +): ViewProps { + const initialValue: Partial = opt_initialValue ?? {}; + return new ValueMap({ + disabled: initialValue.disabled ?? false, + hidden: initialValue.hidden ?? false, + }); +} diff --git a/lib/plugin/common/view/reactive.ts b/lib/plugin/common/view/reactive.ts index 0b2081ff0..f230eeb81 100644 --- a/lib/plugin/common/view/reactive.ts +++ b/lib/plugin/common/view/reactive.ts @@ -1,6 +1,6 @@ import {SingleValueEvents} from '../model/value-map'; +import {ViewProps} from '../model/view-props'; import {ClassName} from './class-name'; -import {ViewProps} from './view'; function compose( h1: (input: A) => B, diff --git a/lib/plugin/common/view/view.ts b/lib/plugin/common/view/view.ts index 0dcbd1bd5..5e00017b5 100644 --- a/lib/plugin/common/view/view.ts +++ b/lib/plugin/common/view/view.ts @@ -1,13 +1,3 @@ -import {ValueMap, ValueMapEvents} from '../model/value-map'; - -interface ViewPropsObject extends Record { - disabled: boolean; - hidden: boolean; -} - -export type ViewProps = ValueMap; -export type ViewPropsEvents = ValueMapEvents; - /** * A view interface. */ @@ -19,13 +9,3 @@ export interface View { onDispose?(): void; } - -export function defaultViewProps( - opt_initialValue?: Partial, -): ViewProps { - const initialValue: Partial = opt_initialValue ?? {}; - return new ValueMap({ - disabled: initialValue.disabled ?? false, - hidden: initialValue.hidden ?? false, - }); -} diff --git a/lib/plugin/input-binding-test.ts b/lib/plugin/input-binding-test.ts index 40c24ef2c..05b2cccff 100644 --- a/lib/plugin/input-binding-test.ts +++ b/lib/plugin/input-binding-test.ts @@ -6,8 +6,9 @@ import {BindingTarget} from './common/binding/target'; import {ValueController} from './common/controller/value'; import {stringFromUnknown} from './common/converter/string'; import {Value} from './common/model/value'; +import {createViewProps} from './common/model/view-props'; import {writePrimitive} from './common/primitive'; -import {defaultViewProps, View} from './common/view/view'; +import {View} from './common/view/view'; import {createController, InputBindingPlugin} from './input-binding'; class TestView implements View { @@ -25,7 +26,7 @@ class TestView implements View { class TestController implements ValueController { public readonly view: TestView; - public readonly viewProps = defaultViewProps(); + public readonly viewProps = createViewProps(); public disposed = false; constructor(doc: Document, public readonly value: Value) { diff --git a/lib/plugin/input-binding.ts b/lib/plugin/input-binding.ts index 8296fe663..91ccf13ea 100644 --- a/lib/plugin/input-binding.ts +++ b/lib/plugin/input-binding.ts @@ -7,7 +7,7 @@ import {BindingTarget} from './common/binding/target'; import {Constraint} from './common/constraint/constraint'; import {ValueController} from './common/controller/value'; import {Value} from './common/model/value'; -import {defaultViewProps, ViewProps} from './common/view/view'; +import {createViewProps, ViewProps} from './common/model/view-props'; import {BasePlugin} from './plugin'; interface BindingArguments { @@ -143,7 +143,7 @@ export function createController( initialValue: initialValue, params: args.params, value: binding.value, - viewProps: defaultViewProps({ + viewProps: createViewProps({ disabled: args.params.disabled, }), }); diff --git a/lib/plugin/input-bindings/boolean/controller.ts b/lib/plugin/input-bindings/boolean/controller.ts index e63a981a8..b2ca5efb0 100644 --- a/lib/plugin/input-bindings/boolean/controller.ts +++ b/lib/plugin/input-bindings/boolean/controller.ts @@ -1,7 +1,7 @@ import {forceCast} from '../../../misc/type-util'; import {ValueController} from '../../common/controller/value'; import {Value} from '../../common/model/value'; -import {ViewProps} from '../../common/view/view'; +import {ViewProps} from '../../common/model/view-props'; import {CheckboxView} from './view'; /** diff --git a/lib/plugin/input-bindings/boolean/view.ts b/lib/plugin/input-bindings/boolean/view.ts index 52abca71e..82ea60902 100644 --- a/lib/plugin/input-bindings/boolean/view.ts +++ b/lib/plugin/input-bindings/boolean/view.ts @@ -1,8 +1,9 @@ import {createSvgIconElement} from '../../common/dom-util'; import {Value} from '../../common/model/value'; +import {ViewProps} from '../../common/model/view-props'; import {ClassName} from '../../common/view/class-name'; import {bindDisabled, bindViewProps} from '../../common/view/reactive'; -import {View, ViewProps} from '../../common/view/view'; +import {View} from '../../common/view/view'; interface Config { value: Value; diff --git a/lib/plugin/input-bindings/color/controller/a-palette.ts b/lib/plugin/input-bindings/color/controller/a-palette.ts index b60474573..d9a4fcf14 100644 --- a/lib/plugin/input-bindings/color/controller/a-palette.ts +++ b/lib/plugin/input-bindings/color/controller/a-palette.ts @@ -1,12 +1,12 @@ import {ValueController} from '../../../common/controller/value'; import {Value} from '../../../common/model/value'; +import {ViewProps} from '../../../common/model/view-props'; import {getHorizontalStepKeys, getStepForKey} from '../../../common/ui'; import { PointerData, PointerHandler, PointerHandlerEvents, } from '../../../common/view/pointer-handler'; -import {ViewProps} from '../../../common/view/view'; import {Color} from '../model/color'; import {getBaseStepForColor} from '../util'; import {APaletteView} from '../view/a-palette'; diff --git a/lib/plugin/input-bindings/color/controller/color-picker-test.ts b/lib/plugin/input-bindings/color/controller/color-picker-test.ts index 7291d7409..5c53354b8 100644 --- a/lib/plugin/input-bindings/color/controller/color-picker-test.ts +++ b/lib/plugin/input-bindings/color/controller/color-picker-test.ts @@ -3,7 +3,7 @@ import {describe, it} from 'mocha'; import {TestUtil} from '../../../../misc/test-util'; import {Value} from '../../../common/model/value'; -import {defaultViewProps} from '../../../common/view/view'; +import {createViewProps} from '../../../common/model/view-props'; import {Color} from '../model/color'; import {PickedColor} from '../model/picked-color'; import {ColorPickerController} from './color-picker'; @@ -16,7 +16,7 @@ describe(ColorPickerController.name, () => { const c = new ColorPickerController(doc, { pickedColor: pc, supportsAlpha: false, - viewProps: defaultViewProps(), + viewProps: createViewProps(), }); assert.strictEqual(c.textController.view.modeSelectElement.value, 'hsv'); @@ -29,7 +29,7 @@ describe(ColorPickerController.name, () => { const c = new ColorPickerController(doc, { pickedColor: pc, supportsAlpha: false, - viewProps: defaultViewProps(), + viewProps: createViewProps(), }); // Change color mode to HSL diff --git a/lib/plugin/input-bindings/color/controller/color-picker.ts b/lib/plugin/input-bindings/color/controller/color-picker.ts index 516ef5745..aef55564d 100644 --- a/lib/plugin/input-bindings/color/controller/color-picker.ts +++ b/lib/plugin/input-bindings/color/controller/color-picker.ts @@ -8,7 +8,7 @@ import {findNextTarget, supportsTouch} from '../../../common/dom-util'; import {Foldable} from '../../../common/model/foldable'; import {Value} from '../../../common/model/value'; import {connectValues} from '../../../common/model/value-sync'; -import {ViewProps} from '../../../common/view/view'; +import {ViewProps} from '../../../common/model/view-props'; import {NumberTextController} from '../../number/controller/number-text'; import {PickedColor} from '..//model/picked-color'; import {Color} from '../model/color'; diff --git a/lib/plugin/input-bindings/color/controller/color-swatch-text.ts b/lib/plugin/input-bindings/color/controller/color-swatch-text.ts index 461129fea..25355e32a 100644 --- a/lib/plugin/input-bindings/color/controller/color-swatch-text.ts +++ b/lib/plugin/input-bindings/color/controller/color-swatch-text.ts @@ -3,7 +3,7 @@ import {Formatter} from '../../../common/converter/formatter'; import {Parser} from '../../../common/converter/parser'; import {Value} from '../../../common/model/value'; import {ValueMap} from '../../../common/model/value-map'; -import {ViewProps} from '../../../common/view/view'; +import {ViewProps} from '../../../common/model/view-props'; import {TextController} from '../../common/controller/text'; import {Color} from '../model/color'; import {ColorSwatchTextView} from '../view/color-swatch-text'; diff --git a/lib/plugin/input-bindings/color/controller/color-swatch.ts b/lib/plugin/input-bindings/color/controller/color-swatch.ts index 613288977..26ccf947b 100644 --- a/lib/plugin/input-bindings/color/controller/color-swatch.ts +++ b/lib/plugin/input-bindings/color/controller/color-swatch.ts @@ -1,7 +1,7 @@ import {forceCast} from '../../../../misc/type-util'; import {ValueController} from '../../../common/controller/value'; import {Value} from '../../../common/model/value'; -import {ViewProps} from '../../../common/view/view'; +import {ViewProps} from '../../../common/model/view-props'; import {Color} from '../model/color'; import {PickedColor} from '../model/picked-color'; import {ColorSwatchView} from '../view/color-swatch'; diff --git a/lib/plugin/input-bindings/color/controller/color-text-test.ts b/lib/plugin/input-bindings/color/controller/color-text-test.ts index 2856966e8..f8f5800d1 100644 --- a/lib/plugin/input-bindings/color/controller/color-text-test.ts +++ b/lib/plugin/input-bindings/color/controller/color-text-test.ts @@ -4,7 +4,7 @@ import {describe, it} from 'mocha'; import {TestUtil} from '../../../../misc/test-util'; import {parseNumber} from '../../../common/converter/number'; import {Value} from '../../../common/model/value'; -import {defaultViewProps} from '../../../common/view/view'; +import {createViewProps} from '../../../common/model/view-props'; import {Color, RgbaColorObject} from '../model/color'; import {PickedColor} from '../model/picked-color'; import {ColorTextController} from './color-text'; @@ -75,7 +75,7 @@ describe(ColorTextController.name, () => { const c = new ColorTextController(doc, { parser: parseNumber, pickedColor: new PickedColor(value), - viewProps: defaultViewProps(), + viewProps: createViewProps(), }); const inputElem = c.view.textViews[testCase.params.index].inputElement; @@ -138,7 +138,7 @@ describe(ColorTextController.name, () => { const c = new ColorTextController(doc, { parser: parseNumber, pickedColor: new PickedColor(value), - viewProps: defaultViewProps(), + viewProps: createViewProps(), }); const inputElem = c.view.textViews[testCase.params.index].inputElement; diff --git a/lib/plugin/input-bindings/color/controller/color-text.ts b/lib/plugin/input-bindings/color/controller/color-text.ts index e900b5603..734631bf2 100644 --- a/lib/plugin/input-bindings/color/controller/color-text.ts +++ b/lib/plugin/input-bindings/color/controller/color-text.ts @@ -5,7 +5,7 @@ import {createNumberFormatter} from '../../../common/converter/number'; import {Parser} from '../../../common/converter/parser'; import {Value} from '../../../common/model/value'; import {connectValues} from '../../../common/model/value-sync'; -import {ViewProps} from '../../../common/view/view'; +import {ViewProps} from '../../../common/model/view-props'; import {NumberTextController} from '../../number/controller/number-text'; import {Color} from '../model/color'; import { diff --git a/lib/plugin/input-bindings/color/controller/h-palette.ts b/lib/plugin/input-bindings/color/controller/h-palette.ts index 3ca9ad909..ef536b374 100644 --- a/lib/plugin/input-bindings/color/controller/h-palette.ts +++ b/lib/plugin/input-bindings/color/controller/h-palette.ts @@ -1,5 +1,6 @@ import {ValueController} from '../../../common/controller/value'; import {Value} from '../../../common/model/value'; +import {ViewProps} from '../../../common/model/view-props'; import {mapRange} from '../../../common/number-util'; import {getHorizontalStepKeys, getStepForKey} from '../../../common/ui'; import { @@ -7,7 +8,6 @@ import { PointerHandler, PointerHandlerEvents, } from '../../../common/view/pointer-handler'; -import {ViewProps} from '../../../common/view/view'; import {Color} from '../model/color'; import {getBaseStepForColor} from '../util'; import {HPaletteView} from '../view/h-palette'; diff --git a/lib/plugin/input-bindings/color/controller/sv-palette.ts b/lib/plugin/input-bindings/color/controller/sv-palette.ts index 6d3cbd868..7531c0c19 100644 --- a/lib/plugin/input-bindings/color/controller/sv-palette.ts +++ b/lib/plugin/input-bindings/color/controller/sv-palette.ts @@ -1,5 +1,6 @@ import {ValueController} from '../../../common/controller/value'; import {Value} from '../../../common/model/value'; +import {ViewProps} from '../../../common/model/view-props'; import {mapRange} from '../../../common/number-util'; import { getHorizontalStepKeys, @@ -12,7 +13,6 @@ import { PointerHandler, PointerHandlerEvents, } from '../../../common/view/pointer-handler'; -import {ViewProps} from '../../../common/view/view'; import {Color} from '../model/color'; import {getBaseStepForColor} from '../util'; import {SvPaletteView} from '../view/sv-palette'; diff --git a/lib/plugin/input-bindings/common/controller/list-test.ts b/lib/plugin/input-bindings/common/controller/list-test.ts index aa1dfe40d..d42b76f6e 100644 --- a/lib/plugin/input-bindings/common/controller/list-test.ts +++ b/lib/plugin/input-bindings/common/controller/list-test.ts @@ -5,7 +5,7 @@ import {TestUtil} from '../../../../misc/test-util'; import {ListConstraint} from '../../../common/constraint/list'; import {numberToString} from '../../../common/converter/number'; import {Value} from '../../../common/model/value'; -import {defaultViewProps} from '../../../common/view/view'; +import {createViewProps} from '../../../common/model/view-props'; import {findListItems} from '../../../util'; import {ListController} from './list'; @@ -23,7 +23,7 @@ describe(ListController.name, () => { listItems: findListItems(value.constraint) ?? [], stringifyValue: numberToString, value: value, - viewProps: defaultViewProps(), + viewProps: createViewProps(), }); assert.strictEqual(c.value, value); @@ -43,7 +43,7 @@ describe(ListController.name, () => { listItems: findListItems(value.constraint) ?? [], stringifyValue: numberToString, value: value, - viewProps: defaultViewProps(), + viewProps: createViewProps(), }); c.view.selectElement.value = '34'; diff --git a/lib/plugin/input-bindings/common/controller/list.ts b/lib/plugin/input-bindings/common/controller/list.ts index 1fca8c375..6265476b0 100644 --- a/lib/plugin/input-bindings/common/controller/list.ts +++ b/lib/plugin/input-bindings/common/controller/list.ts @@ -2,7 +2,7 @@ import {forceCast} from '../../../../misc/type-util'; import {ListItem} from '../../../common/constraint/list'; import {ValueController} from '../../../common/controller/value'; import {Value} from '../../../common/model/value'; -import {ViewProps} from '../../../common/view/view'; +import {ViewProps} from '../../../common/model/view-props'; import {ListView} from '../../../monitor-bindings/common/view/list'; interface Config { diff --git a/lib/plugin/input-bindings/common/controller/point-nd-text-test.ts b/lib/plugin/input-bindings/common/controller/point-nd-text-test.ts index d7474b3be..503e7bda3 100644 --- a/lib/plugin/input-bindings/common/controller/point-nd-text-test.ts +++ b/lib/plugin/input-bindings/common/controller/point-nd-text-test.ts @@ -7,7 +7,7 @@ import { parseNumber, } from '../../../common/converter/number'; import {Value} from '../../../common/model/value'; -import {defaultViewProps} from '../../../common/view/view'; +import {createViewProps} from '../../../common/model/view-props'; import {Point2d, Point2dAssembly} from '../../point-2d/model/point-2d'; import {PointNdTextController} from './point-nd-text'; @@ -31,7 +31,7 @@ describe(PointNdTextController.name, () => { ], parser: parseNumber, value: new Value(new Point2d(12, 34)), - viewProps: defaultViewProps(), + viewProps: createViewProps(), }); c.view.textViews[0].inputElement.value = '3.14'; diff --git a/lib/plugin/input-bindings/common/controller/point-nd-text.ts b/lib/plugin/input-bindings/common/controller/point-nd-text.ts index b8bd69e70..f0718fbd5 100644 --- a/lib/plugin/input-bindings/common/controller/point-nd-text.ts +++ b/lib/plugin/input-bindings/common/controller/point-nd-text.ts @@ -4,7 +4,7 @@ import {Formatter} from '../../../common/converter/formatter'; import {Parser} from '../../../common/converter/parser'; import {Value} from '../../../common/model/value'; import {connectValues} from '../../../common/model/value-sync'; -import {ViewProps} from '../../../common/view/view'; +import {ViewProps} from '../../../common/model/view-props'; import {NumberTextController} from '../../number/controller/number-text'; import {PointNdConstraint} from '../constraint/point-nd'; import {PointNdAssembly} from '../model/point-nd'; diff --git a/lib/plugin/input-bindings/common/controller/text-test.ts b/lib/plugin/input-bindings/common/controller/text-test.ts index 5b0579674..aecc489b5 100644 --- a/lib/plugin/input-bindings/common/controller/text-test.ts +++ b/lib/plugin/input-bindings/common/controller/text-test.ts @@ -8,7 +8,7 @@ import { } from '../../../common/converter/number'; import {Value} from '../../../common/model/value'; import {ValueMap} from '../../../common/model/value-map'; -import {defaultViewProps} from '../../../common/view/view'; +import {createViewProps} from '../../../common/model/view-props'; import {TextController} from './text'; describe(TextController.name, () => { @@ -21,7 +21,7 @@ describe(TextController.name, () => { formatter: createNumberFormatter(2), }), value: value, - viewProps: defaultViewProps(), + viewProps: createViewProps(), }); assert.strictEqual(c.value, value); @@ -37,7 +37,7 @@ describe(TextController.name, () => { formatter: createNumberFormatter(2), }), value: value, - viewProps: defaultViewProps(), + viewProps: createViewProps(), }); c.view.inputElement.value = '3.14'; diff --git a/lib/plugin/input-bindings/common/controller/text.ts b/lib/plugin/input-bindings/common/controller/text.ts index ed5e2428d..28825c1d0 100644 --- a/lib/plugin/input-bindings/common/controller/text.ts +++ b/lib/plugin/input-bindings/common/controller/text.ts @@ -2,7 +2,7 @@ import {forceCast, isEmpty} from '../../../../misc/type-util'; import {ValueController} from '../../../common/controller/value'; import {Parser} from '../../../common/converter/parser'; import {Value} from '../../../common/model/value'; -import {ViewProps} from '../../../common/view/view'; +import {ViewProps} from '../../../common/model/view-props'; import {TextProps, TextView} from '../view/text'; /** diff --git a/lib/plugin/input-bindings/common/view/text-test.ts b/lib/plugin/input-bindings/common/view/text-test.ts index 8a0631f99..d2191bda0 100644 --- a/lib/plugin/input-bindings/common/view/text-test.ts +++ b/lib/plugin/input-bindings/common/view/text-test.ts @@ -4,7 +4,7 @@ import {describe} from 'mocha'; import {TestUtil} from '../../../../misc/test-util'; import {Value} from '../../../common/model/value'; import {ValueMap} from '../../../common/model/value-map'; -import {defaultViewProps} from '../../../common/view/view'; +import {createViewProps} from '../../../common/model/view-props'; import {TextView} from './text'; describe(TextView.name, () => { @@ -17,7 +17,7 @@ describe(TextView.name, () => { const view = new TextView(doc, { props: props, value: v, - viewProps: defaultViewProps(), + viewProps: createViewProps(), }); assert.strictEqual(view.inputElement.value, 'hellofooworld'); @@ -32,7 +32,7 @@ describe(TextView.name, () => { const view = new TextView(doc, { props: props, value: v, - viewProps: defaultViewProps(), + viewProps: createViewProps(), }); v.rawValue = 'bar'; @@ -49,7 +49,7 @@ describe(TextView.name, () => { const view = new TextView(doc, { props: props, value: v, - viewProps: defaultViewProps(), + viewProps: createViewProps(), }); assert.strictEqual(view.inputElement.value, 'hellofooworld'); diff --git a/lib/plugin/input-bindings/common/view/text.ts b/lib/plugin/input-bindings/common/view/text.ts index 61d56ae17..b0df0e6a3 100644 --- a/lib/plugin/input-bindings/common/view/text.ts +++ b/lib/plugin/input-bindings/common/view/text.ts @@ -1,9 +1,10 @@ import {Formatter} from '../../../common/converter/formatter'; import {Value} from '../../../common/model/value'; import {ValueMap} from '../../../common/model/value-map'; +import {ViewProps} from '../../../common/model/view-props'; import {ClassName} from '../../../common/view/class-name'; import {bindDisabled, bindViewProps} from '../../../common/view/reactive'; -import {View, ViewProps} from '../../../common/view/view'; +import {View} from '../../../common/view/view'; export type TextProps = ValueMap<{ formatter: Formatter; diff --git a/lib/plugin/input-bindings/number/controller/number-text-test.ts b/lib/plugin/input-bindings/number/controller/number-text-test.ts index c1185559c..440037b43 100644 --- a/lib/plugin/input-bindings/number/controller/number-text-test.ts +++ b/lib/plugin/input-bindings/number/controller/number-text-test.ts @@ -7,7 +7,7 @@ import { parseNumber, } from '../../../common/converter/number'; import {Value} from '../../../common/model/value'; -import {defaultViewProps} from '../../../common/view/view'; +import {createViewProps} from '../../../common/model/view-props'; import {NumberTextController} from './number-text'; describe(NumberTextController.name, () => { @@ -20,7 +20,7 @@ describe(NumberTextController.name, () => { formatter: createNumberFormatter(0), parser: parseNumber, value: new Value(123), - viewProps: defaultViewProps(), + viewProps: createViewProps(), }); c.view.inputElement.dispatchEvent( diff --git a/lib/plugin/input-bindings/number/controller/number-text.ts b/lib/plugin/input-bindings/number/controller/number-text.ts index 8f07c3636..aa41b8166 100644 --- a/lib/plugin/input-bindings/number/controller/number-text.ts +++ b/lib/plugin/input-bindings/number/controller/number-text.ts @@ -4,12 +4,12 @@ import {Formatter} from '../../../common/converter/formatter'; import {Parser} from '../../../common/converter/parser'; import {Value} from '../../../common/model/value'; import {ValueMap} from '../../../common/model/value-map'; +import {ViewProps} from '../../../common/model/view-props'; import {getStepForKey, getVerticalStepKeys} from '../../../common/ui'; import { PointerHandler, PointerHandlerEvent, } from '../../../common/view/pointer-handler'; -import {ViewProps} from '../../../common/view/view'; import {NumberTextView} from '../view/number-text'; interface Config { diff --git a/lib/plugin/input-bindings/number/controller/slider-text.ts b/lib/plugin/input-bindings/number/controller/slider-text.ts index 9a51fcec9..e88ecb89c 100644 --- a/lib/plugin/input-bindings/number/controller/slider-text.ts +++ b/lib/plugin/input-bindings/number/controller/slider-text.ts @@ -2,7 +2,7 @@ import {ValueController} from '../../../common/controller/value'; import {Formatter} from '../../../common/converter/formatter'; import {Parser} from '../../../common/converter/parser'; import {Value} from '../../../common/model/value'; -import {ViewProps} from '../../../common/view/view'; +import {ViewProps} from '../../../common/model/view-props'; import {SliderProps} from '../view/slider'; import {SliderTextView} from '../view/slider-text'; import {NumberTextController} from './number-text'; diff --git a/lib/plugin/input-bindings/number/controller/slider.ts b/lib/plugin/input-bindings/number/controller/slider.ts index c0bd5ecbb..de577ca28 100644 --- a/lib/plugin/input-bindings/number/controller/slider.ts +++ b/lib/plugin/input-bindings/number/controller/slider.ts @@ -1,5 +1,6 @@ import {ValueController} from '../../../common/controller/value'; import {Value} from '../../../common/model/value'; +import {ViewProps} from '../../../common/model/view-props'; import {mapRange} from '../../../common/number-util'; import {getHorizontalStepKeys, getStepForKey} from '../../../common/ui'; import { @@ -7,7 +8,6 @@ import { PointerHandler, PointerHandlerEvent, } from '../../../common/view/pointer-handler'; -import {ViewProps} from '../../../common/view/view'; import {SliderProps, SliderView} from '../view/slider'; interface Config { diff --git a/lib/plugin/input-bindings/number/view/number-text.ts b/lib/plugin/input-bindings/number/view/number-text.ts index ce09141e5..c38f584c0 100644 --- a/lib/plugin/input-bindings/number/view/number-text.ts +++ b/lib/plugin/input-bindings/number/view/number-text.ts @@ -2,10 +2,11 @@ import {Formatter} from '../../../common/converter/formatter'; import {SVG_NS} from '../../../common/dom-util'; import {Value, ValueEvents} from '../../../common/model/value'; import {ValueMap} from '../../../common/model/value-map'; +import {ViewProps} from '../../../common/model/view-props'; import {constrainRange} from '../../../common/number-util'; import {ClassName} from '../../../common/view/class-name'; import {bindDisabled, bindViewProps} from '../../../common/view/reactive'; -import {View, ViewProps} from '../../../common/view/view'; +import {View} from '../../../common/view/view'; export type NumberTextProps = ValueMap<{ draggingScale: number; diff --git a/lib/plugin/input-bindings/number/view/slider-test.ts b/lib/plugin/input-bindings/number/view/slider-test.ts index 9374f8bc9..26f09d979 100644 --- a/lib/plugin/input-bindings/number/view/slider-test.ts +++ b/lib/plugin/input-bindings/number/view/slider-test.ts @@ -4,7 +4,7 @@ import {describe} from 'mocha'; import {TestUtil} from '../../../../misc/test-util'; import {Value} from '../../../common/model/value'; import {ValueMap} from '../../../common/model/value-map'; -import {defaultViewProps} from '../../../common/view/view'; +import {createViewProps} from '../../../common/model/view-props'; import {SliderView} from './slider'; describe(SliderView.name, () => { @@ -18,7 +18,7 @@ describe(SliderView.name, () => { const view = new SliderView(doc, { props: props, value: v, - viewProps: defaultViewProps(), + viewProps: createViewProps(), }); assert.strictEqual(view.knobElement.style.width, '50%'); @@ -34,7 +34,7 @@ describe(SliderView.name, () => { const view = new SliderView(doc, { props: props, value: v, - viewProps: defaultViewProps(), + viewProps: createViewProps(), }); v.rawValue = 0; @@ -52,7 +52,7 @@ describe(SliderView.name, () => { const view = new SliderView(doc, { props: props, value: v, - viewProps: defaultViewProps(), + viewProps: createViewProps(), }); props.set('maxValue', 100); diff --git a/lib/plugin/input-bindings/number/view/slider.ts b/lib/plugin/input-bindings/number/view/slider.ts index 4837d91e5..13d669266 100644 --- a/lib/plugin/input-bindings/number/view/slider.ts +++ b/lib/plugin/input-bindings/number/view/slider.ts @@ -1,9 +1,10 @@ import {Value} from '../../../common/model/value'; import {ValueMap} from '../../../common/model/value-map'; +import {ViewProps} from '../../../common/model/view-props'; import {constrainRange, mapRange} from '../../../common/number-util'; import {ClassName} from '../../../common/view/class-name'; import {bindViewProps} from '../../../common/view/reactive'; -import {View, ViewProps} from '../../../common/view/view'; +import {View} from '../../../common/view/view'; export type SliderProps = ValueMap<{ maxValue: number; diff --git a/lib/plugin/input-bindings/point-2d/controller/point-2d-pad-text.ts b/lib/plugin/input-bindings/point-2d/controller/point-2d-pad-text.ts index f10e38261..1842d8d1b 100644 --- a/lib/plugin/input-bindings/point-2d/controller/point-2d-pad-text.ts +++ b/lib/plugin/input-bindings/point-2d/controller/point-2d-pad-text.ts @@ -3,7 +3,7 @@ import {ValueController} from '../../../common/controller/value'; import {Formatter} from '../../../common/converter/formatter'; import {Parser} from '../../../common/converter/parser'; import {Value} from '../../../common/model/value'; -import {ViewProps} from '../../../common/view/view'; +import {ViewProps} from '../../../common/model/view-props'; import {PointNdTextController} from '../../common/controller/point-nd-text'; import {Point2d, Point2dAssembly} from '../model/point-2d'; import {Point2dPadTextView} from '../view/point-2d-pad-text'; diff --git a/lib/plugin/input-bindings/point-2d/controller/point-2d-pad.ts b/lib/plugin/input-bindings/point-2d/controller/point-2d-pad.ts index c7d377ce7..a428ef336 100644 --- a/lib/plugin/input-bindings/point-2d/controller/point-2d-pad.ts +++ b/lib/plugin/input-bindings/point-2d/controller/point-2d-pad.ts @@ -2,6 +2,7 @@ import {ValueController} from '../../../common/controller/value'; import {findNextTarget, supportsTouch} from '../../../common/dom-util'; import {Foldable} from '../../../common/model/foldable'; import {Value} from '../../../common/model/value'; +import {ViewProps} from '../../../common/model/view-props'; import {mapRange} from '../../../common/number-util'; import { getHorizontalStepKeys, @@ -14,7 +15,6 @@ import { PointerHandler, PointerHandlerEvents, } from '../../../common/view/pointer-handler'; -import {ViewProps} from '../../../common/view/view'; import {Point2d} from '../model/point-2d'; import {Point2dPadView} from '../view/point-2d-pad'; diff --git a/lib/plugin/monitor-binding-test.ts b/lib/plugin/monitor-binding-test.ts index 136b49948..26949acff 100644 --- a/lib/plugin/monitor-binding-test.ts +++ b/lib/plugin/monitor-binding-test.ts @@ -6,7 +6,8 @@ import {BindingTarget} from './common/binding/target'; import {ValueController} from './common/controller/value'; import {stringFromUnknown} from './common/converter/string'; import {Buffer, BufferedValue} from './common/model/buffered-value'; -import {defaultViewProps, View, ViewProps} from './common/view/view'; +import {createViewProps, ViewProps} from './common/model/view-props'; +import {View} from './common/view/view'; import {createController, MonitorBindingPlugin} from './monitor-binding'; class TestView implements View { @@ -24,7 +25,7 @@ class TestView implements View { class TestController implements ValueController> { public readonly view: TestView; - public readonly viewProps: ViewProps = defaultViewProps(); + public readonly viewProps: ViewProps = createViewProps(); public disposed = false; constructor(doc: Document, public readonly value: BufferedValue) { diff --git a/lib/plugin/monitor-bindings/boolean/plugin.ts b/lib/plugin/monitor-bindings/boolean/plugin.ts index 9935b2c7f..e63988157 100644 --- a/lib/plugin/monitor-bindings/boolean/plugin.ts +++ b/lib/plugin/monitor-bindings/boolean/plugin.ts @@ -3,7 +3,7 @@ import { BooleanFormatter, boolFromUnknown, } from '../../common/converter/boolean'; -import {defaultViewProps} from '../../common/view/view'; +import {createViewProps} from '../../common/model/view-props'; import {MonitorBindingPlugin} from '../../monitor-binding'; import {MultiLogController} from '../common/controller/multi-log'; import {SingleLogMonitorController} from '../common/controller/single-log'; @@ -22,7 +22,7 @@ export const BooleanMonitorPlugin: MonitorBindingPlugin = { return new SingleLogMonitorController(args.document, { formatter: BooleanFormatter, value: args.value, - viewProps: defaultViewProps(), + viewProps: createViewProps(), }); } @@ -30,7 +30,7 @@ export const BooleanMonitorPlugin: MonitorBindingPlugin = { formatter: BooleanFormatter, lineCount: args.params.lineCount ?? Constants.monitor.defaultLineCount, value: args.value, - viewProps: defaultViewProps(), + viewProps: createViewProps(), }); }, }; diff --git a/lib/plugin/monitor-bindings/common/controller/multi-log.ts b/lib/plugin/monitor-bindings/common/controller/multi-log.ts index df6ac260a..ef04eaf5e 100644 --- a/lib/plugin/monitor-bindings/common/controller/multi-log.ts +++ b/lib/plugin/monitor-bindings/common/controller/multi-log.ts @@ -1,7 +1,7 @@ import {ValueController} from '../../../common/controller/value'; import {Formatter} from '../../../common/converter/formatter'; import {Buffer, BufferedValue} from '../../../common/model/buffered-value'; -import {ViewProps} from '../../../common/view/view'; +import {ViewProps} from '../../../common/model/view-props'; import {MultiLogView} from '../view/multi-log'; interface Config { diff --git a/lib/plugin/monitor-bindings/common/controller/single-log.ts b/lib/plugin/monitor-bindings/common/controller/single-log.ts index 49fcccfb9..b3233e527 100644 --- a/lib/plugin/monitor-bindings/common/controller/single-log.ts +++ b/lib/plugin/monitor-bindings/common/controller/single-log.ts @@ -1,7 +1,7 @@ import {ValueController} from '../../../common/controller/value'; import {Formatter} from '../../../common/converter/formatter'; import {Buffer, BufferedValue} from '../../../common/model/buffered-value'; -import {ViewProps} from '../../../common/view/view'; +import {ViewProps} from '../../../common/model/view-props'; import {SingleLogView} from '../view/single-log'; interface Config { diff --git a/lib/plugin/monitor-bindings/common/view/list.ts b/lib/plugin/monitor-bindings/common/view/list.ts index 20b8c52be..cb81d42e8 100644 --- a/lib/plugin/monitor-bindings/common/view/list.ts +++ b/lib/plugin/monitor-bindings/common/view/list.ts @@ -1,9 +1,10 @@ import {ListItem} from '../../../common/constraint/list'; import {createSvgIconElement} from '../../../common/dom-util'; import {Value} from '../../../common/model/value'; +import {ViewProps} from '../../../common/model/view-props'; import {ClassName} from '../../../common/view/class-name'; import {bindViewProps} from '../../../common/view/reactive'; -import {View, ViewProps} from '../../../common/view/view'; +import {View} from '../../../common/view/view'; interface Config { options: ListItem[]; diff --git a/lib/plugin/monitor-bindings/number/controller/graph-log.ts b/lib/plugin/monitor-bindings/number/controller/graph-log.ts index 9f1c86243..d87ce2fea 100644 --- a/lib/plugin/monitor-bindings/number/controller/graph-log.ts +++ b/lib/plugin/monitor-bindings/number/controller/graph-log.ts @@ -2,12 +2,12 @@ import {ValueController} from '../../../common/controller/value'; import {Formatter} from '../../../common/converter/formatter'; import {supportsTouch} from '../../../common/dom-util'; import {Buffer, BufferedValue} from '../../../common/model/buffered-value'; +import {ViewProps} from '../../../common/model/view-props'; import {mapRange} from '../../../common/number-util'; import { PointerHandler, PointerHandlerEvent, } from '../../../common/view/pointer-handler'; -import {ViewProps} from '../../../common/view/view'; import {GraphCursor} from '../model/graph-cursor'; import {GraphLogView} from '../view/graph-log'; diff --git a/lib/plugin/monitor-bindings/number/plugin.ts b/lib/plugin/monitor-bindings/number/plugin.ts index 560d1a5a9..3a6b4abae 100644 --- a/lib/plugin/monitor-bindings/number/plugin.ts +++ b/lib/plugin/monitor-bindings/number/plugin.ts @@ -7,7 +7,7 @@ import { numberFromUnknown, } from '../../common/converter/number'; import {Buffer, BufferedValue} from '../../common/model/buffered-value'; -import {defaultViewProps} from '../../common/view/view'; +import {createViewProps} from '../../common/model/view-props'; import {MonitorBindingPlugin} from '../../monitor-binding'; import {MultiLogController} from '../common/controller/multi-log'; import {SingleLogMonitorController} from '../common/controller/single-log'; @@ -31,7 +31,7 @@ function createTextMonitor({ return new SingleLogMonitorController(document, { formatter: createFormatter(), value: value, - viewProps: defaultViewProps(), + viewProps: createViewProps(), }); } @@ -39,7 +39,7 @@ function createTextMonitor({ formatter: createFormatter(), lineCount: params.lineCount ?? Constants.monitor.defaultLineCount, value: value, - viewProps: defaultViewProps(), + viewProps: createViewProps(), }); } @@ -58,7 +58,7 @@ function createGraphMonitor({ maxValue: ('max' in params ? params.max : null) ?? 100, minValue: ('min' in params ? params.min : null) ?? 0, value: value, - viewProps: defaultViewProps(), + viewProps: createViewProps(), }); } diff --git a/lib/plugin/monitor-bindings/string/plugin.ts b/lib/plugin/monitor-bindings/string/plugin.ts index 355e77cd8..1e83b7881 100644 --- a/lib/plugin/monitor-bindings/string/plugin.ts +++ b/lib/plugin/monitor-bindings/string/plugin.ts @@ -1,6 +1,6 @@ import {Constants} from '../../../misc/constants'; import {formatString, stringFromUnknown} from '../../common/converter/string'; -import {defaultViewProps} from '../../common/view/view'; +import {createViewProps} from '../../common/model/view-props'; import {MonitorBindingPlugin} from '../../monitor-binding'; import {MultiLogController} from '../common/controller/multi-log'; import {SingleLogMonitorController} from '../common/controller/single-log'; @@ -24,14 +24,14 @@ export const StringMonitorPlugin: MonitorBindingPlugin = { formatter: formatString, lineCount: args.params.lineCount ?? Constants.monitor.defaultLineCount, value: value, - viewProps: defaultViewProps(), + viewProps: createViewProps(), }); } return new SingleLogMonitorController(args.document, { formatter: formatString, value: value, - viewProps: defaultViewProps(), + viewProps: createViewProps(), }); }, }; diff --git a/test-module/plugin/src/index.ts b/test-module/plugin/src/index.ts index 89219dd25..348e25f26 100644 --- a/test-module/plugin/src/index.ts +++ b/test-module/plugin/src/index.ts @@ -3,16 +3,13 @@ import Tweakpane from 'tweakpane'; import {ValueController} from 'tweakpane/lib/plugin/common/controller/value'; import {stringFromUnknown} from 'tweakpane/lib/plugin/common/converter/string'; import {Value} from 'tweakpane/lib/plugin/common/model/value'; +import {ViewProps} from 'tweakpane/lib/plugin/common/model/view-props'; import { equalsPrimitive, writePrimitive, } from 'tweakpane/lib/plugin/common/primitive'; import {ClassName} from 'tweakpane/lib/plugin/common/view/class-name'; -import { - defaultViewProps, - View, - ViewProps, -} from 'tweakpane/lib/plugin/common/view/view'; +import {View} from 'tweakpane/lib/plugin/common/view/view'; import {InputBindingPlugin} from 'tweakpane/lib/plugin/input-binding'; interface ViewConfig { @@ -82,7 +79,7 @@ class TestController implements ValueController { controller(args) { return new TestController(args.document, { value: args.value, - viewProps: defaultViewProps(), + viewProps: args.viewProps, }); }, } as InputBindingPlugin, From 0cd676d66a6b0608c71e5ecf30f4ea310fddb8a6 Mon Sep 17 00:00:00 2001 From: cocopon Date: Sat, 27 Mar 2021 06:17:13 +0900 Subject: [PATCH 05/10] Add support for disabled monitor --- lib/api/monitor-binding.ts | 8 +++ lib/api/types.ts | 1 + .../common/controller/monitor-binding-test.ts | 57 ++++++++------- .../common/controller/monitor-binding.ts | 7 +- .../common/binding/ticker/interval-test.ts | 29 ++++++++ lib/plugin/common/binding/ticker/interval.ts | 71 +++++++++++++------ .../common/binding/ticker/manual-test.ts | 35 +++++++++ lib/plugin/common/binding/ticker/manual.ts | 5 ++ lib/plugin/common/binding/ticker/ticker.ts | 1 + lib/plugin/common/view/reactive.ts | 19 +++-- .../input-bindings/common/controller/list.ts | 2 +- .../common/view/list.ts | 0 lib/plugin/monitor-binding.ts | 5 ++ lib/plugin/monitor-bindings/boolean/plugin.ts | 5 +- .../common/controller/multi-log.ts | 1 + .../common/controller/single-log.ts | 1 + .../monitor-bindings/common/view/multi-log.ts | 4 ++ .../common/view/single-log.ts | 4 ++ .../number/controller/graph-log.ts | 1 + lib/plugin/monitor-bindings/number/plugin.ts | 55 ++++++-------- .../monitor-bindings/number/view/graph-log.ts | 4 ++ lib/plugin/monitor-bindings/string/plugin.ts | 5 +- lib/sass/view/_graph-log.scss | 3 + lib/sass/view/_log.scss | 6 ++ src/doc/ts/route/misc.ts | 17 ++++- 25 files changed, 243 insertions(+), 103 deletions(-) create mode 100644 lib/plugin/common/binding/ticker/manual-test.ts rename lib/plugin/{monitor-bindings => input-bindings}/common/view/list.ts (100%) diff --git a/lib/api/monitor-binding.ts b/lib/api/monitor-binding.ts index f016761e6..23445858f 100644 --- a/lib/api/monitor-binding.ts +++ b/lib/api/monitor-binding.ts @@ -33,6 +33,14 @@ export class MonitorBindingApi implements BladeApi { this.controller.binding.emitter.on('update', this.onBindingUpdate_); } + get disabled(): boolean { + return this.controller.viewProps.get('disabled'); + } + + set disabled(disabled: boolean) { + this.controller.viewProps.set('disabled', disabled); + } + get hidden(): boolean { return this.controller.viewProps.get('hidden'); } diff --git a/lib/api/types.ts b/lib/api/types.ts index c30768c5e..6018746f8 100644 --- a/lib/api/types.ts +++ b/lib/api/types.ts @@ -83,6 +83,7 @@ export type InputParams = export interface BaseMonitorParams extends BaseParams, LabelableParams { bufferSize?: number; + disabled?: boolean; interval?: number; view?: string; } diff --git a/lib/plugin/blade/common/controller/monitor-binding-test.ts b/lib/plugin/blade/common/controller/monitor-binding-test.ts index 79f681c9c..aced1b96e 100644 --- a/lib/plugin/blade/common/controller/monitor-binding-test.ts +++ b/lib/plugin/blade/common/controller/monitor-binding-test.ts @@ -13,32 +13,41 @@ import {SingleLogMonitorController} from '../../../monitor-bindings/common/contr import {Blade} from '../model/blade'; import {MonitorBindingController} from './monitor-binding'; +function create(): MonitorBindingController { + const obj = { + foo: 123, + }; + const doc = TestUtil.createWindow().document; + const value = new Value(Array(10).fill(undefined)); + const binding = new MonitorBinding({ + reader: numberFromUnknown, + target: new BindingTarget(obj, 'foo'), + ticker: new ManualTicker(), + value: value, + }); + const controller = new SingleLogMonitorController(doc, { + formatter: createNumberFormatter(0), + value: value, + viewProps: createViewProps(), + }); + return new MonitorBindingController(doc, { + binding: binding, + controller: controller, + label: 'foo', + blade: new Blade(), + }); +} + describe(MonitorBindingController.name, () => { it('should get properties', () => { - const obj = { - foo: 123, - }; - const doc = TestUtil.createWindow().document; - const value = new Value(Array(10).fill(undefined)); - const binding = new MonitorBinding({ - reader: numberFromUnknown, - target: new BindingTarget(obj, 'foo'), - ticker: new ManualTicker(), - value: value, - }); - const controller = new SingleLogMonitorController(doc, { - formatter: createNumberFormatter(0), - value: value, - viewProps: createViewProps(), - }); - const bc = new MonitorBindingController(doc, { - binding: binding, - controller: controller, - label: 'foo', - blade: new Blade(), - }); - assert.strictEqual(bc.binding, binding); - assert.strictEqual(bc.controller, controller); + const bc = create(); assert.strictEqual(bc.view.label, 'foo'); }); + + it('should disable ticker', () => { + const bc = create(); + assert.isFalse(bc.binding.ticker.disabled); + bc.viewProps.set('disabled', true); + assert.isTrue(bc.binding.ticker.disabled); + }); }); diff --git a/lib/plugin/blade/common/controller/monitor-binding.ts b/lib/plugin/blade/common/controller/monitor-binding.ts index ceb61bff5..f76ee6e23 100644 --- a/lib/plugin/blade/common/controller/monitor-binding.ts +++ b/lib/plugin/blade/common/controller/monitor-binding.ts @@ -2,6 +2,7 @@ import {MonitorBinding} from '../../../common/binding/monitor'; import {ValueController} from '../../../common/controller/value'; import {Buffer} from '../../../common/model/buffered-value'; import {ViewProps} from '../../../common/model/view-props'; +import {bindDisabled} from '../../../common/view/reactive'; import {LabeledView} from '../../labeled/view'; import {Blade} from '../model/blade'; import {BladeController, setUpBladeController} from './blade'; @@ -25,6 +26,7 @@ export class MonitorBindingController implements BladeController { constructor(doc: Document, config: Config) { this.binding = config.binding; this.controller = config.controller; + bindDisabled(this.viewProps, this.binding.ticker); this.view = new LabeledView(doc, { label: config.label, @@ -33,9 +35,6 @@ export class MonitorBindingController implements BladeController { this.view.valueElement.appendChild(this.controller.view.element); this.blade = config.blade; - this.blade.emitter.on('dispose', () => { - this.binding.dispose(); - }); setUpBladeController(this); } @@ -44,6 +43,8 @@ export class MonitorBindingController implements BladeController { } public onDispose() { + this.binding.dispose(); + if (this.controller.onDispose) { this.controller.onDispose(); } diff --git a/lib/plugin/common/binding/ticker/interval-test.ts b/lib/plugin/common/binding/ticker/interval-test.ts index 949d4620d..ab9f0b23e 100644 --- a/lib/plugin/common/binding/ticker/interval-test.ts +++ b/lib/plugin/common/binding/ticker/interval-test.ts @@ -1,3 +1,4 @@ +import {assert} from 'chai'; import {describe, it} from 'mocha'; import {TestUtil} from '../../../../misc/test-util'; @@ -20,4 +21,32 @@ describe(IntervalTicker.name, () => { done(); }, 10); }); + + it('should tick', (done) => { + const doc = TestUtil.createWindow().document; + const t = new IntervalTicker(doc, 1); + + t.emitter.on('tick', () => { + t.disposable.dispose(); + done(); + }); + }); + + it('should be enabled by default', () => { + const doc = TestUtil.createWindow().document; + const t = new IntervalTicker(doc, 0); + + assert.isFalse(t.disabled); + }); + + it('should not tick if disabled', (done) => { + const doc = TestUtil.createWindow().document; + const t = new IntervalTicker(doc, 1); + t.disabled = true; + t.emitter.on('tick', () => { + throw new Error('should not called'); + }); + + setTimeout(done, 10); + }); }); diff --git a/lib/plugin/common/binding/ticker/interval.ts b/lib/plugin/common/binding/ticker/interval.ts index 4f239db6d..63b15b634 100644 --- a/lib/plugin/common/binding/ticker/interval.ts +++ b/lib/plugin/common/binding/ticker/interval.ts @@ -8,9 +8,10 @@ import {Ticker, TickerEvents} from './ticker'; export class IntervalTicker implements Ticker { public readonly disposable: Disposable; public readonly emitter: Emitter; - // private active_ = true; + private readonly interval_: number; + private disabled_ = false; private doc_: Document; - private id_: number | null = null; + private timerId_: number | null = null; constructor(doc: Document, interval: number) { this.onTick_ = this.onTick_.bind(this); @@ -19,15 +20,9 @@ export class IntervalTicker implements Ticker { this.doc_ = doc; this.emitter = new Emitter(); + this.interval_ = interval; - if (interval <= 0) { - this.id_ = null; - } else { - const win = this.doc_.defaultView; - if (win) { - this.id_ = win.setInterval(this.onTick_, interval); - } - } + this.setTimer_(); // TODO: Stop on blur? // const win = document.defaultView; @@ -38,20 +33,52 @@ export class IntervalTicker implements Ticker { this.disposable = new Disposable(); this.disposable.emitter.on('dispose', () => { - if (this.id_ !== null) { - const win = this.doc_.defaultView; - if (win) { - win.clearInterval(this.id_); - } - } - this.id_ = null; + this.clearTimer_(); }); } + get disabled() { + return this.disabled_; + } + + set disabled(inactive: boolean) { + this.disabled_ = inactive; + if (this.disabled_) { + this.clearTimer_(); + } else { + this.setTimer_(); + } + } + + private clearTimer_() { + if (this.timerId_ === null) { + return; + } + + const win = this.doc_.defaultView; + if (win) { + win.clearInterval(this.timerId_); + } + this.timerId_ = null; + } + + private setTimer_() { + this.clearTimer_(); + + if (this.interval_ <= 0) { + return; + } + + const win = this.doc_.defaultView; + if (win) { + this.timerId_ = win.setInterval(this.onTick_, this.interval_); + } + } + private onTick_(): void { - // if (!this.active_) { - // return; - // } + if (this.disabled_) { + return; + } this.emitter.emit('tick', { sender: this, @@ -59,10 +86,10 @@ export class IntervalTicker implements Ticker { } // private onWindowBlur_(): void { - // this.active_ = false; + // this.inactive = true; // } // private onWindowFocus_(): void { - // this.active_ = true; + // this.inactive = false; // } } diff --git a/lib/plugin/common/binding/ticker/manual-test.ts b/lib/plugin/common/binding/ticker/manual-test.ts new file mode 100644 index 000000000..b418dffda --- /dev/null +++ b/lib/plugin/common/binding/ticker/manual-test.ts @@ -0,0 +1,35 @@ +import {assert} from 'chai'; +import {describe, it} from 'mocha'; + +import {ManualTicker} from './manual'; + +describe(ManualTicker.name, () => { + it('should be enabled by default', () => { + const t = new ManualTicker(); + assert.isFalse(t.disabled); + }); + + it('should fire tick event', () => { + const t = new ManualTicker(); + let count = 0; + t.emitter.on('tick', () => { + count += 1; + }); + + assert.strictEqual(count, 0); + t.tick(); + assert.strictEqual(count, 1); + }); + + it('should not fire tick event from disabled ticker', () => { + const t = new ManualTicker(); + t.emitter.on('tick', () => { + throw new Error('should not be called'); + }); + + t.disabled = true; + assert.doesNotThrow(() => { + t.tick(); + }); + }); +}); diff --git a/lib/plugin/common/binding/ticker/manual.ts b/lib/plugin/common/binding/ticker/manual.ts index 43ddebd4b..16287056d 100644 --- a/lib/plugin/common/binding/ticker/manual.ts +++ b/lib/plugin/common/binding/ticker/manual.ts @@ -8,6 +8,7 @@ import {Ticker, TickerEvents} from './ticker'; export class ManualTicker implements Ticker { public readonly disposable: Disposable; public readonly emitter: Emitter; + public disabled = false; constructor() { this.disposable = new Disposable(); @@ -15,6 +16,10 @@ export class ManualTicker implements Ticker { } public tick(): void { + if (this.disabled) { + return; + } + this.emitter.emit('tick', { sender: this, }); diff --git a/lib/plugin/common/binding/ticker/ticker.ts b/lib/plugin/common/binding/ticker/ticker.ts index e9559040b..831e00f00 100644 --- a/lib/plugin/common/binding/ticker/ticker.ts +++ b/lib/plugin/common/binding/ticker/ticker.ts @@ -16,4 +16,5 @@ export interface TickerEvents { export interface Ticker { readonly disposable: Disposable; readonly emitter: Emitter; + disabled: boolean; } diff --git a/lib/plugin/common/view/reactive.ts b/lib/plugin/common/view/reactive.ts index f230eeb81..8e52a864d 100644 --- a/lib/plugin/common/view/reactive.ts +++ b/lib/plugin/common/view/reactive.ts @@ -32,11 +32,13 @@ function updateModifier( }; } -function updateDisabled( - elem: HTMLButtonElement | HTMLInputElement | HTMLSelectElement, -) { +interface Disableable { + disabled: boolean; +} + +function updateDisabled(target: Disableable) { return (value: boolean) => { - elem.disabled = value; + target.disabled = value; }; } @@ -52,12 +54,9 @@ export function bindViewProps(viewProps: ViewProps, elem: HTMLElement) { updateModifier(elem, 'hidden')(viewProps.get('hidden')); } -export function bindDisabled( - viewProps: ViewProps, - elem: HTMLButtonElement | HTMLInputElement | HTMLSelectElement, -) { +export function bindDisabled(viewProps: ViewProps, target: Disableable) { viewProps .valueEmitter('disabled') - .on('change', compose(extractValue, updateDisabled(elem))); - updateDisabled(elem)(viewProps.get('disabled')); + .on('change', compose(extractValue, updateDisabled(target))); + updateDisabled(target)(viewProps.get('disabled')); } diff --git a/lib/plugin/input-bindings/common/controller/list.ts b/lib/plugin/input-bindings/common/controller/list.ts index 6265476b0..ea43f4943 100644 --- a/lib/plugin/input-bindings/common/controller/list.ts +++ b/lib/plugin/input-bindings/common/controller/list.ts @@ -3,7 +3,7 @@ import {ListItem} from '../../../common/constraint/list'; import {ValueController} from '../../../common/controller/value'; import {Value} from '../../../common/model/value'; import {ViewProps} from '../../../common/model/view-props'; -import {ListView} from '../../../monitor-bindings/common/view/list'; +import {ListView} from '../view/list'; interface Config { listItems: ListItem[]; diff --git a/lib/plugin/monitor-bindings/common/view/list.ts b/lib/plugin/input-bindings/common/view/list.ts similarity index 100% rename from lib/plugin/monitor-bindings/common/view/list.ts rename to lib/plugin/input-bindings/common/view/list.ts diff --git a/lib/plugin/monitor-binding.ts b/lib/plugin/monitor-binding.ts index 43b365f28..8d4104fce 100644 --- a/lib/plugin/monitor-binding.ts +++ b/lib/plugin/monitor-binding.ts @@ -11,6 +11,7 @@ import {Ticker} from './common/binding/ticker/ticker'; import {ValueController} from './common/controller/value'; import {BufferedValue, initializeBuffer} from './common/model/buffered-value'; import {Buffer} from './common/model/buffered-value'; +import {createViewProps, ViewProps} from './common/model/view-props'; import {BasePlugin} from './plugin'; interface BindingArguments { @@ -23,6 +24,7 @@ interface ControllerArguments { document: Document; params: MonitorParams; value: BufferedValue; + viewProps: ViewProps; } /** @@ -129,6 +131,9 @@ export function createController( document: args.document, params: args.params, value: binding.value, + viewProps: createViewProps({ + disabled: args.params.disabled, + }), }), label: args.params.label || args.target.key, blade: blade, diff --git a/lib/plugin/monitor-bindings/boolean/plugin.ts b/lib/plugin/monitor-bindings/boolean/plugin.ts index e63988157..9d14655af 100644 --- a/lib/plugin/monitor-bindings/boolean/plugin.ts +++ b/lib/plugin/monitor-bindings/boolean/plugin.ts @@ -3,7 +3,6 @@ import { BooleanFormatter, boolFromUnknown, } from '../../common/converter/boolean'; -import {createViewProps} from '../../common/model/view-props'; import {MonitorBindingPlugin} from '../../monitor-binding'; import {MultiLogController} from '../common/controller/multi-log'; import {SingleLogMonitorController} from '../common/controller/single-log'; @@ -22,7 +21,7 @@ export const BooleanMonitorPlugin: MonitorBindingPlugin = { return new SingleLogMonitorController(args.document, { formatter: BooleanFormatter, value: args.value, - viewProps: createViewProps(), + viewProps: args.viewProps, }); } @@ -30,7 +29,7 @@ export const BooleanMonitorPlugin: MonitorBindingPlugin = { formatter: BooleanFormatter, lineCount: args.params.lineCount ?? Constants.monitor.defaultLineCount, value: args.value, - viewProps: createViewProps(), + viewProps: args.viewProps, }); }, }; diff --git a/lib/plugin/monitor-bindings/common/controller/multi-log.ts b/lib/plugin/monitor-bindings/common/controller/multi-log.ts index ef04eaf5e..f3940f4af 100644 --- a/lib/plugin/monitor-bindings/common/controller/multi-log.ts +++ b/lib/plugin/monitor-bindings/common/controller/multi-log.ts @@ -27,6 +27,7 @@ export class MultiLogController implements ValueController> { formatter: config.formatter, lineCount: config.lineCount, value: this.value, + viewProps: this.viewProps, }); } } diff --git a/lib/plugin/monitor-bindings/common/controller/single-log.ts b/lib/plugin/monitor-bindings/common/controller/single-log.ts index b3233e527..5e536b5e5 100644 --- a/lib/plugin/monitor-bindings/common/controller/single-log.ts +++ b/lib/plugin/monitor-bindings/common/controller/single-log.ts @@ -26,6 +26,7 @@ export class SingleLogMonitorController this.view = new SingleLogView(doc, { formatter: config.formatter, value: this.value, + viewProps: this.viewProps, }); } } diff --git a/lib/plugin/monitor-bindings/common/view/multi-log.ts b/lib/plugin/monitor-bindings/common/view/multi-log.ts index 6a701bfd2..49a0920d0 100644 --- a/lib/plugin/monitor-bindings/common/view/multi-log.ts +++ b/lib/plugin/monitor-bindings/common/view/multi-log.ts @@ -1,12 +1,15 @@ import {Formatter} from '../../../common/converter/formatter'; import {BufferedValue} from '../../../common/model/buffered-value'; +import {ViewProps} from '../../../common/model/view-props'; import {ClassName} from '../../../common/view/class-name'; +import {bindViewProps} from '../../../common/view/reactive'; import {View} from '../../../common/view/view'; interface Config { formatter: Formatter; lineCount: number; value: BufferedValue; + viewProps: ViewProps; } const className = ClassName('mll'); @@ -27,6 +30,7 @@ export class MultiLogView implements View { this.element = doc.createElement('div'); this.element.classList.add(className()); + bindViewProps(config.viewProps, this.element); const textareaElem = doc.createElement('textarea'); textareaElem.classList.add(className('i')); diff --git a/lib/plugin/monitor-bindings/common/view/single-log.ts b/lib/plugin/monitor-bindings/common/view/single-log.ts index f5e3fb527..d54c188e5 100644 --- a/lib/plugin/monitor-bindings/common/view/single-log.ts +++ b/lib/plugin/monitor-bindings/common/view/single-log.ts @@ -1,11 +1,14 @@ import {Formatter} from '../../../common/converter/formatter'; import {BufferedValue} from '../../../common/model/buffered-value'; +import {ViewProps} from '../../../common/model/view-props'; import {ClassName} from '../../../common/view/class-name'; +import {bindViewProps} from '../../../common/view/reactive'; import {View} from '../../../common/view/view'; interface Config { formatter: Formatter; value: BufferedValue; + viewProps: ViewProps; } const className = ClassName('sgl'); @@ -26,6 +29,7 @@ export class SingleLogView implements View { this.element = doc.createElement('div'); this.element.classList.add(className()); + bindViewProps(config.viewProps, this.element); const inputElem = doc.createElement('input'); inputElem.classList.add(className('i')); diff --git a/lib/plugin/monitor-bindings/number/controller/graph-log.ts b/lib/plugin/monitor-bindings/number/controller/graph-log.ts index d87ce2fea..17e49b191 100644 --- a/lib/plugin/monitor-bindings/number/controller/graph-log.ts +++ b/lib/plugin/monitor-bindings/number/controller/graph-log.ts @@ -47,6 +47,7 @@ export class GraphLogController implements ValueController> { maxValue: config.maxValue, minValue: config.minValue, value: this.value, + viewProps: this.viewProps, }); if (!supportsTouch(doc)) { diff --git a/lib/plugin/monitor-bindings/number/plugin.ts b/lib/plugin/monitor-bindings/number/plugin.ts index 3a6b4abae..4a70c4565 100644 --- a/lib/plugin/monitor-bindings/number/plugin.ts +++ b/lib/plugin/monitor-bindings/number/plugin.ts @@ -6,8 +6,7 @@ import { createNumberFormatter, numberFromUnknown, } from '../../common/converter/number'; -import {Buffer, BufferedValue} from '../../common/model/buffered-value'; -import {createViewProps} from '../../common/model/view-props'; +import {Buffer} from '../../common/model/buffered-value'; import {MonitorBindingPlugin} from '../../monitor-binding'; import {MultiLogController} from '../common/controller/multi-log'; import {SingleLogMonitorController} from '../common/controller/single-log'; @@ -18,47 +17,35 @@ function createFormatter(): Formatter { return createNumberFormatter(2); } -function createTextMonitor({ - document, - params, - value, -}: { - document: Document; - params: MonitorParams; - value: BufferedValue; -}): ValueController> { - if (value.rawValue.length === 1) { - return new SingleLogMonitorController(document, { +function createTextMonitor( + args: Parameters['controller']>[0], +) { + if (args.value.rawValue.length === 1) { + return new SingleLogMonitorController(args.document, { formatter: createFormatter(), - value: value, - viewProps: createViewProps(), + value: args.value, + viewProps: args.viewProps, }); } - return new MultiLogController(document, { + return new MultiLogController(args.document, { formatter: createFormatter(), - lineCount: params.lineCount ?? Constants.monitor.defaultLineCount, - value: value, - viewProps: createViewProps(), + lineCount: args.params.lineCount ?? Constants.monitor.defaultLineCount, + value: args.value, + viewProps: args.viewProps, }); } -function createGraphMonitor({ - document, - params, - value, -}: { - document: Document; - params: MonitorParams; - value: BufferedValue; -}): ValueController> { - return new GraphLogController(document, { +function createGraphMonitor( + args: Parameters['controller']>[0], +): ValueController> { + return new GraphLogController(args.document, { formatter: createFormatter(), - lineCount: params.lineCount ?? Constants.monitor.defaultLineCount, - maxValue: ('max' in params ? params.max : null) ?? 100, - minValue: ('min' in params ? params.min : null) ?? 0, - value: value, - viewProps: createViewProps(), + lineCount: args.params.lineCount ?? Constants.monitor.defaultLineCount, + maxValue: ('max' in args.params ? args.params.max : null) ?? 100, + minValue: ('min' in args.params ? args.params.min : null) ?? 0, + value: args.value, + viewProps: args.viewProps, }); } diff --git a/lib/plugin/monitor-bindings/number/view/graph-log.ts b/lib/plugin/monitor-bindings/number/view/graph-log.ts index 55360d2ee..fb4b7a85d 100644 --- a/lib/plugin/monitor-bindings/number/view/graph-log.ts +++ b/lib/plugin/monitor-bindings/number/view/graph-log.ts @@ -1,8 +1,10 @@ import {Formatter} from '../../../common/converter/formatter'; import {forceReflow, SVG_NS} from '../../../common/dom-util'; import {BufferedValue} from '../../../common/model/buffered-value'; +import {ViewProps} from '../../../common/model/view-props'; import {mapRange} from '../../../common/number-util'; import {ClassName} from '../../../common/view/class-name'; +import {bindViewProps} from '../../../common/view/reactive'; import {View} from '../../../common/view/view'; import {GraphCursor} from '../model/graph-cursor'; @@ -13,6 +15,7 @@ interface Config { maxValue: number; minValue: number; value: BufferedValue; + viewProps: ViewProps; } const className = ClassName('grl'); @@ -37,6 +40,7 @@ export class GraphLogView implements View { this.element = doc.createElement('div'); this.element.classList.add(className()); + bindViewProps(config.viewProps, this.element); this.formatter_ = config.formatter; this.minValue_ = config.minValue; diff --git a/lib/plugin/monitor-bindings/string/plugin.ts b/lib/plugin/monitor-bindings/string/plugin.ts index 1e83b7881..48499129f 100644 --- a/lib/plugin/monitor-bindings/string/plugin.ts +++ b/lib/plugin/monitor-bindings/string/plugin.ts @@ -1,6 +1,5 @@ import {Constants} from '../../../misc/constants'; import {formatString, stringFromUnknown} from '../../common/converter/string'; -import {createViewProps} from '../../common/model/view-props'; import {MonitorBindingPlugin} from '../../monitor-binding'; import {MultiLogController} from '../common/controller/multi-log'; import {SingleLogMonitorController} from '../common/controller/single-log'; @@ -24,14 +23,14 @@ export const StringMonitorPlugin: MonitorBindingPlugin = { formatter: formatString, lineCount: args.params.lineCount ?? Constants.monitor.defaultLineCount, value: value, - viewProps: createViewProps(), + viewProps: args.viewProps, }); } return new SingleLogMonitorController(args.document, { formatter: formatString, value: value, - viewProps: createViewProps(), + viewProps: args.viewProps, }); }, }; diff --git a/lib/sass/view/_graph-log.scss b/lib/sass/view/_graph-log.scss index 9990dfb86..df2ca6ccf 100644 --- a/lib/sass/view/_graph-log.scss +++ b/lib/sass/view/_graph-log.scss @@ -25,6 +25,9 @@ transition: none; } } + &.#{$prefix}-v-disabled &_g { + opacity: 0.5; + } .#{$prefix}-ttv { background-color: var(--mo-fg); diff --git a/lib/sass/view/_log.scss b/lib/sass/view/_log.scss index f35a325d9..789cda878 100644 --- a/lib/sass/view/_log.scss +++ b/lib/sass/view/_log.scss @@ -4,6 +4,9 @@ padding: 0 4px; } + &.#{$prefix}-v-disabled &_i { + opacity: 0.5; + } } .#{$prefix}-mllv { @@ -17,4 +20,7 @@ resize: none; white-space: pre; } + &.#{$prefix}-v-disabled &_i { + opacity: 0.5; + } } diff --git a/src/doc/ts/route/misc.ts b/src/doc/ts/route/misc.ts index 2b61f9452..b8d0ca11f 100644 --- a/src/doc/ts/route/misc.ts +++ b/src/doc/ts/route/misc.ts @@ -1,6 +1,6 @@ import Tweakpane from 'tweakpane'; -import {selectContainer} from '../util'; +import {selectContainer, wave} from '../util'; export function initMisc() { const IMEX_PARAMS = { @@ -265,15 +265,25 @@ export function initMisc() { }, disabled: (container) => { + let wavet = 0; const PARAMS = { - param: 1, + input: 1, + monitor: 0, }; + setInterval(() => { + PARAMS.monitor = wave(wavet); + wavet += 1; + }, 200); + const pane = new Tweakpane({ container: container, }); pane.addSeparator(); - const i = pane.addInput(PARAMS, 'param', { + const i = pane.addInput(PARAMS, 'input', { + disabled: true, + }); + const m = pane.addMonitor(PARAMS, 'monitor', { disabled: true, }); const btn = pane.addButton({ @@ -288,6 +298,7 @@ export function initMisc() { }) .on('click', () => { i.disabled = !i.disabled; + m.disabled = !m.disabled; btn.disabled = !btn.disabled; }); }, From c49cde5e988314833efc8c8bb532b37ffea30873 Mon Sep 17 00:00:00 2001 From: cocopon Date: Sat, 27 Mar 2021 06:21:57 +0900 Subject: [PATCH 06/10] Bump up package version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c68a96f10..01b5ffabc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tweakpane", - "version": "2.2.0-beta.0", + "version": "2.2.0-beta.1", "description": "A compact pane for fine-tuning parameters and monitoring value changes", "author": "cocopon", "license": "MIT", From ee0bd0198d7fe604c74952430b87dc17a8c97907 Mon Sep 17 00:00:00 2001 From: cocopon Date: Sat, 27 Mar 2021 08:18:40 +0900 Subject: [PATCH 07/10] Add `disabled` flag to catalog --- src/doc/ts/route/catalog.ts | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/src/doc/ts/route/catalog.ts b/src/doc/ts/route/catalog.ts index 3d90a40a3..94d7d42d9 100644 --- a/src/doc/ts/route/catalog.ts +++ b/src/doc/ts/route/catalog.ts @@ -3,6 +3,8 @@ import Tweakpane from 'tweakpane'; import {selectContainer, wave} from '../util'; export function initCatalog() { + const disabled = location.search.includes('disabled'); + const markerToFnMap: { [key: string]: (container: HTMLElement) => void; } = { @@ -15,14 +17,17 @@ export function initCatalog() { title: 'Number', }); pane.addInput(params, 'number', { + disabled: disabled, label: 'text', }); pane.addInput(params, 'number', { + disabled: disabled, label: 'slider', min: -100, max: 100, }); pane.addInput(params, 'number', { + disabled: disabled, label: 'list', options: { option: 0, @@ -38,9 +43,11 @@ export function initCatalog() { title: 'String', }); pane.addInput(params, 'string', { + disabled: disabled, label: 'text', }); pane.addInput(params, 'string', { + disabled: disabled, label: 'list', options: { option: 'text', @@ -56,6 +63,7 @@ export function initCatalog() { title: 'Boolean', }); pane.addInput(params, 'bool', { + disabled: disabled, label: 'checkbox', }); }, @@ -68,6 +76,7 @@ export function initCatalog() { title: 'Color', }); pane.addInput(params, 'color', { + disabled: disabled, label: 'picker', }); }, @@ -82,12 +91,15 @@ export function initCatalog() { title: 'Point', }); pane.addInput(params, 'p2d', { + disabled: disabled, label: 'picker', }); pane.addInput(params, 'p3d', { + disabled: disabled, label: 'text', }); pane.addInput(params, 'p4d', { + disabled: disabled, label: 'text', }); }, @@ -106,13 +118,16 @@ export function initCatalog() { title: 'Number', }); pane.addMonitor(params, 'number', { + disabled: disabled, label: 'text', }); pane.addMonitor(params, 'number', { bufferSize: 10, + disabled: disabled, label: 'multiline', }); pane.addMonitor(params, 'number', { + disabled: disabled, label: 'graph', max: +1, min: -1, @@ -132,11 +147,13 @@ export function initCatalog() { title: 'String', }); pane.addMonitor(params, 'string', { + disabled: disabled, interval: 1000, label: 'text', }); pane.addMonitor(params, 'string', { bufferSize: 10, + disabled: disabled, interval: 1000, label: 'multiline', }); @@ -154,11 +171,13 @@ export function initCatalog() { title: 'Boolean', }); pane.addMonitor(params, 'bool', { + disabled: disabled, interval: 1000, label: 'text', }); pane.addMonitor(params, 'bool', { bufferSize: 10, + disabled: disabled, interval: 1000, label: 'multiline', }); @@ -168,15 +187,15 @@ export function initCatalog() { container: container, title: 'Folder', }); - pane.addInput({param: 0}, 'param'); + pane.addInput({param: 0}, 'param', {disabled: disabled}); const f = pane.addFolder({ title: 'Folder', }); - f.addInput({param: 0}, 'param'); + f.addInput({param: 0}, 'param', {disabled: disabled}); const sf = f.addFolder({ title: 'Subfolder', }); - sf.addInput({param: 0}, 'param'); + sf.addInput({param: 0}, 'param', {disabled: disabled}); }, button: (container) => { const pane = new Tweakpane({ @@ -184,9 +203,11 @@ export function initCatalog() { title: 'Button', }); pane.addButton({ + disabled: disabled, title: 'Button', }); pane.addButton({ + disabled: disabled, label: 'label', title: 'Button', }); @@ -196,9 +217,9 @@ export function initCatalog() { container: container, title: 'Separator', }); - pane.addInput({param: 0}, 'param'); + pane.addInput({param: 0}, 'param', {disabled: disabled}); pane.addSeparator(); - pane.addInput({param: 0}, 'param'); + pane.addInput({param: 0}, 'param', {disabled: disabled}); }, }; Object.keys(markerToFnMap).forEach((marker) => { From 26ba2ce46a2109007d1ab5829d0b571c5bdf9618 Mon Sep 17 00:00:00 2001 From: cocopon Date: Sat, 27 Mar 2021 08:29:14 +0900 Subject: [PATCH 08/10] Add missing styles for disabled state --- lib/plugin/input-bindings/color/controller/color-swatch.ts | 1 + lib/plugin/input-bindings/color/view/color-swatch-text.ts | 5 ----- lib/plugin/input-bindings/color/view/color-swatch.ts | 4 ++++ .../input-bindings/point-2d/controller/point-2d-pad-text.ts | 1 + lib/plugin/input-bindings/point-2d/view/point-2d-pad-text.ts | 5 +++++ lib/sass/view/_checkbox.scss | 3 +++ lib/sass/view/_color-swatch.scss | 4 ++++ lib/sass/view/_list.scss | 3 +++ lib/sass/view/_slider.scss | 4 ++++ 9 files changed, 25 insertions(+), 5 deletions(-) diff --git a/lib/plugin/input-bindings/color/controller/color-swatch.ts b/lib/plugin/input-bindings/color/controller/color-swatch.ts index 26ccf947b..43678c588 100644 --- a/lib/plugin/input-bindings/color/controller/color-swatch.ts +++ b/lib/plugin/input-bindings/color/controller/color-swatch.ts @@ -38,6 +38,7 @@ export class ColorSwatchController implements ValueController { this.view = new ColorSwatchView(doc, { pickerView: this.pickerIc_.view, value: this.value, + viewProps: this.viewProps, }); this.view.buttonElement.addEventListener('blur', this.onButtonBlur_); this.view.buttonElement.addEventListener('click', this.onButtonClick_); diff --git a/lib/plugin/input-bindings/color/view/color-swatch-text.ts b/lib/plugin/input-bindings/color/view/color-swatch-text.ts index ca35f119e..d49fff869 100644 --- a/lib/plugin/input-bindings/color/view/color-swatch-text.ts +++ b/lib/plugin/input-bindings/color/view/color-swatch-text.ts @@ -35,9 +35,4 @@ export class ColorSwatchTextView implements View { textElem.appendChild(this.textView.element); this.element.appendChild(textElem); } - - public update(): void { - this.swatchView_.update(); - this.textView.update(); - } } diff --git a/lib/plugin/input-bindings/color/view/color-swatch.ts b/lib/plugin/input-bindings/color/view/color-swatch.ts index 70655e79f..ce729d008 100644 --- a/lib/plugin/input-bindings/color/view/color-swatch.ts +++ b/lib/plugin/input-bindings/color/view/color-swatch.ts @@ -1,5 +1,7 @@ import {Value} from '../../../common/model/value'; +import {ViewProps} from '../../../common/model/view-props'; import {ClassName} from '../../../common/view/class-name'; +import {bindViewProps} from '../../../common/view/reactive'; import {View} from '../../../common/view/view'; import {colorToHexRgbaString} from '../converter/color-string'; import {Color} from '../model/color'; @@ -8,6 +10,7 @@ import {ColorPickerView} from './color-picker'; interface Config { pickerView: ColorPickerView; value: Value; + viewProps: ViewProps; } const className = ClassName('clsw'); @@ -30,6 +33,7 @@ export class ColorSwatchView implements View { this.element = doc.createElement('div'); this.element.classList.add(className()); + bindViewProps(config.viewProps, this.element); const swatchElem = doc.createElement('div'); swatchElem.classList.add(className('sw')); diff --git a/lib/plugin/input-bindings/point-2d/controller/point-2d-pad-text.ts b/lib/plugin/input-bindings/point-2d/controller/point-2d-pad-text.ts index 1842d8d1b..432f966d7 100644 --- a/lib/plugin/input-bindings/point-2d/controller/point-2d-pad-text.ts +++ b/lib/plugin/input-bindings/point-2d/controller/point-2d-pad-text.ts @@ -60,6 +60,7 @@ export class Point2dPadTextController implements ValueController { this.view = new Point2dPadTextView(doc, { padView: this.padIc_.view, textView: this.textIc_.view, + viewProps: this.viewProps, }); this.view.padButtonElement.addEventListener('blur', this.onPadButtonBlur_); this.view.padButtonElement.addEventListener( diff --git a/lib/plugin/input-bindings/point-2d/view/point-2d-pad-text.ts b/lib/plugin/input-bindings/point-2d/view/point-2d-pad-text.ts index 2af65c7ca..54d092f6d 100644 --- a/lib/plugin/input-bindings/point-2d/view/point-2d-pad-text.ts +++ b/lib/plugin/input-bindings/point-2d/view/point-2d-pad-text.ts @@ -1,5 +1,7 @@ import {createSvgIconElement} from '../../../common/dom-util'; +import {ViewProps} from '../../../common/model/view-props'; import {ClassName} from '../../../common/view/class-name'; +import {bindDisabled, bindViewProps} from '../../../common/view/reactive'; import {View} from '../../../common/view/view'; import {PointNdTextView} from '../../common/view/point-nd-text'; import {Point2dPadView} from './point-2d-pad'; @@ -7,6 +9,7 @@ import {Point2dPadView} from './point-2d-pad'; interface Config { padView: Point2dPadView; textView: PointNdTextView; + viewProps: ViewProps; } const className = ClassName('p2dpadtxt'); @@ -23,6 +26,7 @@ export class Point2dPadTextView implements View { constructor(doc: Document, config: Config) { this.element = doc.createElement('div'); this.element.classList.add(className()); + bindViewProps(config.viewProps, this.element); const padWrapperElem = doc.createElement('div'); padWrapperElem.classList.add(className('w')); @@ -31,6 +35,7 @@ export class Point2dPadTextView implements View { const buttonElem = doc.createElement('button'); buttonElem.classList.add(className('b')); buttonElem.appendChild(createSvgIconElement(doc, 'p2dpad')); + bindDisabled(config.viewProps, buttonElem); padWrapperElem.appendChild(buttonElem); this.padButtonElem_ = buttonElem; diff --git a/lib/sass/view/_checkbox.scss b/lib/sass/view/_checkbox.scss index 63e0ebc91..ecef5dfaa 100644 --- a/lib/sass/view/_checkbox.scss +++ b/lib/sass/view/_checkbox.scss @@ -51,4 +51,7 @@ &_i:checked + &_w svg { opacity: 1; } + &.#{$prefix}-v-disabled &_w { + opacity: 0.5; + } } diff --git a/lib/sass/view/_color-swatch.scss b/lib/sass/view/_color-swatch.scss index 9cff677e8..dc2761713 100644 --- a/lib/sass/view/_color-swatch.scss +++ b/lib/sass/view/_color-swatch.scss @@ -3,6 +3,10 @@ border-radius: $inner-border-radius; + &.#{$prefix}-v-disabled { + opacity: 0.5; + } + &_sw { @extend %input; } diff --git a/lib/sass/view/_list.scss b/lib/sass/view/_list.scss index ad261ca2d..b243e54d9 100644 --- a/lib/sass/view/_list.scss +++ b/lib/sass/view/_list.scss @@ -7,6 +7,9 @@ padding: 0 (16px + 2px * 2) 0 4px; width: 100%; } + &.#{$prefix}-v-disabled &_s { + opacity: 0.5; + } &_m { @extend %list_arrow; diff --git a/lib/sass/view/_slider.scss b/lib/sass/view/_slider.scss index 77435d5f6..6a3726526 100644 --- a/lib/sass/view/_slider.scss +++ b/lib/sass/view/_slider.scss @@ -1,4 +1,8 @@ .#{$prefix}-sldv { + &.#{$prefix}-v-disabled { + opacity: 0.5; + } + &_t { box-sizing: border-box; cursor: pointer; From d7c89afc5f4c030c9be39ec6a425ff87170d33bb Mon Sep 17 00:00:00 2001 From: cocopon Date: Sat, 27 Mar 2021 09:18:38 +0900 Subject: [PATCH 09/10] Add polyfill for existing plugins --- lib/plugin/input-binding.ts | 2 ++ lib/plugin/monitor-binding.ts | 20 ++++++++++++-------- lib/plugin/util.ts | 15 +++++++++++++++ lib/sass/view/_root.scss | 2 +- 4 files changed, 30 insertions(+), 9 deletions(-) diff --git a/lib/plugin/input-binding.ts b/lib/plugin/input-binding.ts index 91ccf13ea..659a4fec9 100644 --- a/lib/plugin/input-binding.ts +++ b/lib/plugin/input-binding.ts @@ -9,6 +9,7 @@ import {ValueController} from './common/controller/value'; import {Value} from './common/model/value'; import {createViewProps, ViewProps} from './common/model/view-props'; import {BasePlugin} from './plugin'; +import {polyfillViewProps} from './util'; interface BindingArguments { initialValue: Ex; @@ -147,6 +148,7 @@ export function createController( disabled: args.params.disabled, }), }); + polyfillViewProps(controller, plugin.id); const blade = new Blade(); return new InputBindingController(args.document, { diff --git a/lib/plugin/monitor-binding.ts b/lib/plugin/monitor-binding.ts index 8d4104fce..5001e3c7e 100644 --- a/lib/plugin/monitor-binding.ts +++ b/lib/plugin/monitor-binding.ts @@ -13,6 +13,7 @@ import {BufferedValue, initializeBuffer} from './common/model/buffered-value'; import {Buffer} from './common/model/buffered-value'; import {createViewProps, ViewProps} from './common/model/view-props'; import {BasePlugin} from './plugin'; +import {polyfillViewProps} from './util'; interface BindingArguments { initialValue: T; @@ -124,17 +125,20 @@ export function createController( value: initializeBuffer(bufferSize), }); + const controller = plugin.controller({ + document: args.document, + params: args.params, + value: binding.value, + viewProps: createViewProps({ + disabled: args.params.disabled, + }), + }); + polyfillViewProps(controller, plugin.id); + const blade = new Blade(); return new MonitorBindingController(args.document, { binding: binding, - controller: plugin.controller({ - document: args.document, - params: args.params, - value: binding.value, - viewProps: createViewProps({ - disabled: args.params.disabled, - }), - }), + controller: controller, label: args.params.label || args.target.key, blade: blade, }); diff --git a/lib/plugin/util.ts b/lib/plugin/util.ts index 03bfa9e84..6f6bab2b0 100644 --- a/lib/plugin/util.ts +++ b/lib/plugin/util.ts @@ -7,6 +7,8 @@ import {findConstraint} from './common/constraint/composite'; import {Constraint} from './common/constraint/constraint'; import {ListConstraint, ListItem} from './common/constraint/list'; import {StepConstraint} from './common/constraint/step'; +import {ValueController} from './common/controller/value'; +import {createViewProps} from './common/model/view-props'; import {getDecimalDigits} from './common/number-util'; function normalizeInputParamsOptions( @@ -113,3 +115,16 @@ export function getSuitableDraggingScale( return base === 0 ? 0.1 : Math.pow(10, Math.floor(Math.log10(base)) - 1); } + +// TODO: Remove polyfill in the next major release +export function polyfillViewProps( + controller: ValueController, + pluginId: string, +) { + if (!controller.viewProps) { + (controller as any).viewProps = createViewProps(); + console.warn( + `Missing controller.viewProps (plugin: '${pluginId}')\nThis polyfill will be removed in the next major version.`, + ); + } +} diff --git a/lib/sass/view/_root.scss b/lib/sass/view/_root.scss index 77975d4dc..bf943d005 100644 --- a/lib/sass/view/_root.scss +++ b/lib/sass/view/_root.scss @@ -110,7 +110,7 @@ // Separator @include themeVariable('spr-fg', 'separator-color', rgba($color-exdark, 0.2)); - // TODO: Remove outdated variables + // TODO: Remove outdated variables in the next major update --button-background-color: var(--btn-bg); --button-background-color-active: var(--btn-bg-a); --button-background-color-focus: var(--btn-bg-f); From e0dc3812c288b953ebb1b8f901fdf5faf026dd8d Mon Sep 17 00:00:00 2001 From: cocopon Date: Sat, 27 Mar 2021 09:25:27 +0900 Subject: [PATCH 10/10] Bump up package version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 01b5ffabc..d30f28ea7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tweakpane", - "version": "2.2.0-beta.1", + "version": "2.2.0-beta.2", "description": "A compact pane for fine-tuning parameters and monitoring value changes", "author": "cocopon", "license": "MIT",