message: mol-plugin-ui: cache focus options in StructureFocusControls
diff: @@ -16,6 +16,8 @@ import { lociLabel } from '../../mol-theme/label';
  import { FocusLoci } from '../../mol-plugin/behavior/dynamic/representation';
  import { StateTransform } from '../../mol-state';
  import { Binding } from '../../mol-util/binding';
  +import { memoizeLatest } from '../../mol-util/memoize';
  +import { StructureRef } from '../../mol-plugin-state/manager/structure/hierarchy-state';
  interface StructureFocusControlsState {
  isBusy: boolean
  @@ -95,6 +97,8 @@ export class StructureFocusControls extends PluginUIComponent<{}, StructureFocus
  componentDidMount() {
  this.subscribe(this.plugin.managers.structure.focus.behaviors.current, c => {
  + // clear the memo cache
  + this.getSelectionItems([]);
  this.forceUpdate();
  });
  @@ -111,25 +115,8 @@ export class StructureFocusControls extends PluginUIComponent<{}, StructureFocus
  return this.state.isBusy || this.actionItems.length === 0
  }
  - get actionItems() {
  - const historyItems: ActionMenu.Items[] = []
  - const { history } = this.plugin.managers.structure.focus
  - if (history.length > 0) {
  - historyItems.push([
  - ActionMenu.Header('History', { description: 'Previously focused on items.' }),
  - ...ActionMenu.createItems(history, {
  - label: f => f.label,
  - description: f => {
  - return f.category && f.label !== f.category
  - ? `${f.category} | ${f.label}`
  - : f.label
  - }
  - })
  - ])
  - }
  -
  + getSelectionItems = memoizeLatest((structures: ReadonlyArray<StructureRef>) => {
  const presetItems: ActionMenu.Items[] = []
  - const { structures } = this.plugin.managers.structure.hierarchy.selection;
  for (const s of structures) {
  const d = s.cell.obj?.data
  if (d) {
  @@ -146,6 +133,27 @@ export class StructureFocusControls extends PluginUIComponent<{}, StructureFocus
  }
  }
  }
  + return presetItems;
  + });
  +
  + get actionItems() {
  + const historyItems: ActionMenu.Items[] = []
  + const { history } = this.plugin.managers.structure.focus
  + if (history.length > 0) {
  + historyItems.push([
  + ActionMenu.Header('History', { description: 'Previously focused on items.' }),
  + ...ActionMenu.createItems(history, {
  + label: f => f.label,
  + description: f => {
  + return f.category && f.label !== f.category
  + ? `${f.category} | ${f.label}`
  + : f.label
  + }
  + })
  + ])
  + }
  +
  + const presetItems: ActionMenu.Items[] = this.getSelectionItems(this.plugin.managers.structure.hierarchy.selection.structures);
  if (presetItems.length === 1) {
  const item = presetItems[0] as ActionMenu.Items[]
  const header = item[0] as ActionMenu.Header
  