Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Google Blockly] customize angle fields #57841

Merged
merged 7 commits into from Apr 9, 2024
Merged

Conversation

mikeharv
Copy link
Contributor

@mikeharv mikeharv commented Apr 5, 2024

Follow-up to:

In the PR linked above, I added a plugin that provides our Google Blockly labs with a field for angles. I also set things up so that this field, essentially unmodified, would be used for all angle fields in our (non-migrated) Artist lab. This branch begins to make customizations to the new child fields, CdoFieldAngleDropdown and CdoFieldAngleTextInput, to make them work closer to how they do in CDO Blockly.

CSS color overrides

I'm not sure yet how critical it will be to exactly match the current UI, so for now I've just updated the colors.

CDO Blockly Plugin Styles Custom Styles
image image image

Further customization is definitely possible, but I think it's worth syncing with curriculum, product and possibly design before investing more effort here.

Handling constructor properties

Here are some examples of creating instances of these field classes as found throughout the repo. You'll note that dropdown fields pass an options argument, while text input fields pass both a value and options.

new blockly.FieldAngleTextInput('90', { // This field has a default value of 90
  directionTitle: 'DIR', // This block has another field called 'DIR', which is used to set the turn direction.
})
new blockly.FieldAngleTextInput('0', {
  direction: 'turnRight', // This block doesn't have a separate field for turn direction so it's always clockwise.
})
 new blockly.FieldAngleDropdown({
  directionTitleName: 'DIR', // Same purpose as directionTitle above, but a different label
  menuGenerator: this.VALUE, // This field has a custom set of restricted values that are permitted.
})

On the other hand, the constructor for the plugin looks like this:

  constructor(
    value?: string | number | typeof Blockly.Field.SKIP_SETUP,
    validator?: FieldAngleValidator,
    config?: FieldAngleConfig,
  )

As mentioned in the previous PR, the options we provide are not compatible with the FieldAngleConfig that the plugin expects. Instead, we create the field instance and then modify and add properties as needed.

Text Input Angle fields

Users should be able to enter any integer value. The plugin's validator automatically remaps numbers outside the range of 0...359 (e.g. 540 remaps to 180; -90 remaps to 270). In addition to entering text, the user can click on the field editor to choose an angle. If the user selects that this is right turn (using the 'DIR' field), then the editor re-orients accordingly to show increasing values in a clockwise fashion. This can also be specified directly for blocks that don't have a separate turn field. These fields don't have a dropdown so there is no way to further customize the selectable options.

Dropdown Angle fields

These blocks have the same customization options as text input fields (albeit with a different label for one property), but with extra customization intended for dropdown menu options and value validation. (Note: at this time, there is still no dropdown menu.)
In CDO Blockly, these fields show a dropdown menu beside the angle picker. If a user clicks the angle picker, the value is constrained to the nearest value option in the dropdown menu. These options can be set either by a menu generator or in the field XML:

  • menuGenerator: Provided for a few specific fields in the block definition. These blocks will always have the same options Because they are part of the block definition, these values are available immediately upon construction.
  • field XML: Some blocks are configurable per-level, or in fact, per block instance by adding a string of comma-separated values to the field element's config attribute. This isn't supported by core Blockly (mutators are preferred), but we fortunately already solved for this ahead of the Dance lab migration. Because these are part of the block serialization, they are accessed (and saved) with fromXml and toXml. See: https://developers.google.com/blockly/guides/create-custom-blocks/fields/customizing-fields/creating#toxml_and_fromxml

In either case, once we have a set of custom values, we can apply them to the min and max settings of the field. This not only constrains the input but also adjusts the UI. Specifically, it will only show "tick marks" between the min and max (at 15 degree intervals).

Blockly also automatically runs doClassValidation_ on fields to ensure the input is valid. (https://developers.google.com/blockly/reference/js/blockly.fieldangle_class.doclassvalidation__1_method)
The plugin handles ensuring valid angle values, but we also want to constrain to the custom options (from the block definition or xml). When the user clicks the field, the plugin class will take their new value (e.g. -185), return a valid angle (e.g. 175), and then we'll find the nearest option in our custom list (e.g 180).

Examples

Here are some examples that demonstrate proper validation of a few different blocks. For each, the relevant source of custom values (block definition or xml) is shown.

Custom options CDO Blockly Feature branch
imageimage rightcdo rightg
imageimage
image

Links

Jira - https://codedotorg.atlassian.net/browse/CT-477

Testing story

Deployment strategy

Follow-up work

Additional follow-ups:

  • Add dropdown UI to dropdown fields
  • Override dropdownCreate() to customize the editor UI and/or CSS as desired.
  • Ensure field serializes correctly to JSON (for projects)
  • Ensure field works as expected in all supported contexts (?)

Privacy

Security

Caching

PR Checklist:

  • Tests provide adequate coverage
  • Privacy and Security impacts have been assessed
  • Code is well-commented
  • New features are translatable or updates will not break translations
  • Relevant documentation has been added or updated
  • User impact is well-understood and desirable
  • Pull Request is labeled appropriately
  • Follow-up work items (including potential tech debt) are tracked and linked

@mikeharv mikeharv marked this pull request as draft April 5, 2024 20:29
Base automatically changed from mike/field-angle-plugin to staging April 5, 2024 20:30
@mikeharv mikeharv marked this pull request as ready for review April 5, 2024 22:57
@mikeharv mikeharv requested a review from a team April 5, 2024 22:57
this.directionFieldName
);
}
if (this.direction === 'turnRight') {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we add a constant for turnRight?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, good call. Added.

@mikeharv mikeharv merged commit 1206714 into staging Apr 9, 2024
2 checks passed
@mikeharv mikeharv deleted the mike/customize-angle-fields branch April 9, 2024 15:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants