Skip to content

Commit ed56b79

Browse files
authored
feat: Use intermediate change events for HSV sliders. (#2173)
1 parent f89bb8b commit ed56b79

File tree

1 file changed

+58
-2
lines changed

1 file changed

+58
-2
lines changed

plugins/field-colour-hsv-sliders/src/field_colour_hsv_sliders.ts

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,13 @@ export class FieldColourHsvSliders extends FieldColour {
214214
/** Helper colour structures to support conversion to the RGB colour space. */
215215
private static readonly helperRgb: RgbColour = new RgbColour();
216216

217+
/**
218+
* The intial value of the field when the user opened an editor to change its
219+
* value. When the editor is disposed, an event will be fired that uses this
220+
* as the event's oldValue.
221+
*/
222+
protected valueWhenEditorWasOpened: string | null = null;
223+
217224
/** Array holding info needed to unbind events. Used for disposing. */
218225
private hsvBoundEvents: Blockly.browserEvents.Data[] = [];
219226

@@ -257,6 +264,8 @@ export class FieldColourHsvSliders extends FieldColour {
257264
this.dropdownDisposeSliders.bind(this),
258265
);
259266

267+
this.valueWhenEditorWasOpened = this.value_;
268+
260269
// Focus so we can start receiving keyboard events.
261270
this.hueSlider.focus({preventScroll: true});
262271
}
@@ -399,6 +408,28 @@ export class FieldColourHsvSliders extends FieldColour {
399408
this.brightnessReadout = null;
400409
this.brightnessSlider = null;
401410
this.dropdownContainer = null;
411+
412+
if (
413+
this.sourceBlock_ &&
414+
Blockly.Events.isEnabled() &&
415+
this.valueWhenEditorWasOpened !== null &&
416+
this.valueWhenEditorWasOpened !== this.value_
417+
) {
418+
// When closing a field input widget, fire an event indicating that the
419+
// user has completed a sequence of changes. The value may have changed
420+
// multiple times while the editor was open, but this will fire an event
421+
// containing the value when the editor was opened as well as the new one.
422+
Blockly.Events.fire(
423+
new (Blockly.Events.get(Blockly.Events.BLOCK_CHANGE))(
424+
this.sourceBlock_,
425+
'field',
426+
this.name || null,
427+
this.valueWhenEditorWasOpened,
428+
this.value_,
429+
),
430+
);
431+
this.valueWhenEditorWasOpened = null;
432+
}
402433
}
403434

404435
/**
@@ -441,7 +472,9 @@ export class FieldColourHsvSliders extends FieldColour {
441472
const brightness: number =
442473
parseFloat(this.brightnessSlider.value) /
443474
FieldColourHsvSliders.BRIGHTNESS_SLIDER_MAX;
444-
this.setValue(FieldColourHsvSliders.hsvToHex(hue, saturation, brightness));
475+
this.setIntermediateValue(
476+
FieldColourHsvSliders.hsvToHex(hue, saturation, brightness),
477+
);
445478
this.renderSliders();
446479
}
447480

@@ -454,12 +487,35 @@ export class FieldColourHsvSliders extends FieldColour {
454487
if (window.EyeDropper) {
455488
const eyeDropper: EyeDropper = new window.EyeDropper();
456489
eyeDropper.open().then((result) => {
457-
this.setValue(result.sRGBHex);
490+
this.setIntermediateValue(result.sRGBHex);
458491
this.updateSliderValues();
459492
});
460493
}
461494
}
462495

496+
private setIntermediateValue(value: string): void {
497+
// Intermediate value changes from user input are not confirmed until the
498+
// user closes the editor, and may be numerous. Inhibit reporting these as
499+
// normal block change events, and instead report them as special
500+
// intermediate changes that do not get recorded in undo history.
501+
const oldValue = this.value_;
502+
// Change the field's value without firing the normal change event.
503+
this.setValue(value, false);
504+
if (
505+
this.sourceBlock_ &&
506+
Blockly.Events.isEnabled() &&
507+
this.value_ !== oldValue
508+
) {
509+
// Fire a special event indicating that the value changed but the change
510+
// isn't complete yet and normal field change listeners can wait.
511+
Blockly.Events.fire(
512+
new (Blockly.Events.get(
513+
Blockly.Events.BLOCK_FIELD_INTERMEDIATE_CHANGE,
514+
))(this.sourceBlock_, this.name || null, oldValue, this.value_),
515+
);
516+
}
517+
}
518+
463519
/**
464520
* Updates the gradient backgrounds of the slider tracks and readouts based
465521
* on the slider values.

0 commit comments

Comments
 (0)