diff --git a/lib/src/view/design_main_strand.dart b/lib/src/view/design_main_strand.dart index 31a47e7ff..c7225853c 100644 --- a/lib/src/view/design_main_strand.dart +++ b/lib/src/view/design_main_strand.dart @@ -273,16 +273,19 @@ class DesignMainStrandComponent extends UiComponent2 assign_plate_well_fields() => app.disable_keyboard_shortcuts_while(ask_for_assign_plate_well_fields); - set_strand_name() => app.disable_keyboard_shortcuts_while(ask_for_strand_name); + set_strand_name() => app.disable_keyboard_shortcuts_while( + () => ask_for_strand_name(props.strand, app.state.ui_state.selectables_store.selected_strands)); set_strand_label() => app.disable_keyboard_shortcuts_while( () => ask_for_label(props.strand, null, app.state.ui_state.selectables_store.selected_strands)); - set_substrand_name(Substrand substrand) => - app.disable_keyboard_shortcuts_while(() => ask_for_substrand_name(substrand)); + set_domain_names(BuiltSet domains) => + app.disable_keyboard_shortcuts_while(() => ask_for_domain_names(domains)); - set_substrand_label(Substrand substrand) => app.disable_keyboard_shortcuts_while( - () => ask_for_label(props.strand, substrand, app.state.ui_state.selectables_store.selected_substrands)); + set_domain_labels(Substrand substrand, BuiltSet domains) { + return app.disable_keyboard_shortcuts_while( + () => ask_for_label(props.strand, substrand, get_selected_domains())); + } ReactElement _insertions() { List paths = []; @@ -474,10 +477,14 @@ assigned, assign the complementary DNA sequence to this strand. if (props.strand.name != null) ContextMenuItem( title: 'remove strand name', - on_click: () => app.dispatch(actions.StrandNameSet(name: null, strand: props.strand))), + on_click: () => app.dispatch(batch_if_multiple_selected( + (strand) => actions.StrandNameSet(name: null, strand: strand), + props.strand, + app.state.ui_state.selectables_store.selected_strands, + 'remove strand name'))), ContextMenuItem( title: 'set domain name', - on_click: () => set_substrand_name(substrand), + on_click: () => set_domain_names(get_selected_domains()), ), ContextMenuItem( title: 'assign domain name complement from bound strands', @@ -491,7 +498,9 @@ feature for individual domains, set select mode to domain. if (substrand.name != null) ContextMenuItem( title: 'remove domain name', - on_click: () => app.dispatch(actions.SubstrandNameSet(name: null, substrand: substrand))), + on_click: () => app.dispatch(actions.BatchAction( + get_selected_domains().map((d) => actions.SubstrandNameSet(name: null, substrand: d)), + 'remove domain names'))), ].build()), ContextMenuItem( title: 'edit label', @@ -503,15 +512,21 @@ feature for individual domains, set select mode to domain. if (props.strand.label != null) ContextMenuItem( title: 'remove strand label', - on_click: () => app.dispatch(actions.StrandLabelSet(label: null, strand: props.strand))), + on_click: () => app.dispatch(batch_if_multiple_selected( + (strand) => actions.StrandLabelSet(label: null, strand: strand), + props.strand, + app.state.ui_state.selectables_store.selected_strands, + 'remove strand label'))), ContextMenuItem( title: 'set domain label', - on_click: () => set_substrand_label(substrand), + on_click: () => set_domain_labels(substrand, get_selected_domains()), ), if (substrand.label != null) ContextMenuItem( title: 'remove domain label', - on_click: () => app.dispatch(actions.SubstrandLabelSet(label: null, substrand: substrand))), + on_click: () => app.dispatch(actions.BatchAction( + get_selected_domains().map((d) => actions.SubstrandLabelSet(label: null, substrand: d)), + 'remove domain labels'))), ].build()), ContextMenuItem( title: 'reflect', @@ -901,7 +916,7 @@ PAGEHPLC : Dual PAGE & HPLC app.dispatch(batch_action); } - Future ask_for_strand_name() async { + Future ask_for_strand_name(Strand strand, BuiltSet selected_strands) async { int name_idx = 0; var items = List.filled(1, null); items[name_idx] = DialogText(label: 'name', value: props.strand.name ?? ''); @@ -912,17 +927,17 @@ PAGEHPLC : Dual PAGE & HPLC if (results == null) return; String name = (results[name_idx] as DialogText).value; - actions.UndoableAction action = actions.StrandNameSet(name: name, strand: props.strand); + actions.UndoableAction action = batch_if_multiple_selected( + name_set_strand_action_creator(name), strand, selected_strands, "set strand names"); app.dispatch(action); } - Future ask_for_substrand_name(Substrand substrand) async { + Future ask_for_domain_names(BuiltSet domains) async { int name_idx = 0; var items = List.filled(1, null); - - items[name_idx] = DialogText(label: 'name', value: substrand.name ?? ''); + items[name_idx] = DialogText(label: 'name', value: ""); var dialog = Dialog( - title: 'set ${substrand.type_description()} name', + title: 'set ${domains.first.type_description()} name', items: items, type: DialogType.set_domain_name, use_saved_response: false); @@ -931,12 +946,13 @@ PAGEHPLC : Dual PAGE & HPLC if (results == null) return; String name = (results[name_idx] as DialogText).value; - actions.UndoableAction action = actions.SubstrandNameSet(name: name, substrand: substrand); - app.dispatch(action); + return app.dispatch(actions.BatchAction( + domains.map((d) => actions.SubstrandNameSet(name: name, substrand: d)), "set domain names")); } } -Future ask_for_label(Strand strand, Substrand substrand, BuiltSet selected_strands) async { +Future ask_for_label( + Strand strand, Substrand substrand, BuiltSet selected_strands) async { String part_name = 'strand'; if (substrand != null) { part_name = substrand.type_description(); @@ -972,12 +988,12 @@ Future ask_for_label(Strand strand, Substrand substrand, BuiltSet actions.UndoableAction action; if (substrand == null) { - action = batch_if_multiple_selected( - label_set_strand_action_creator(label), strand, selected_strands, "set strand label"); + action = batch_if_multiple_selected(label_set_strand_action_creator(label), strand, + selected_strands as BuiltSet, "set strand label"); } else { - action = actions.SubstrandLabelSet(label: label, substrand: substrand); - // action = batch_if_multiple_selected( - // label_set_strand_action_creator(label), props.strand, selected_strands, "set domain label"); + action = actions.BatchAction( + selected_strands.map((s) => actions.SubstrandLabelSet(label: label, substrand: (s as Substrand))), + "set substrand labels"); } app.dispatch(action); @@ -1000,6 +1016,16 @@ actions.UndoableAction batch_if_multiple_selected(StrandActionCreator action_cre return action; } +// this is so if user selects with the domain select tool, it still returns the selected domains +// as opposed to just using "selected_strands" +BuiltSet get_selected_domains() { + return BuiltSet(app.state.ui_state.selectables_store.selected_strands + .map((s) => s.substrands) + .expand((l) => l) + .toBuiltSet()) + .union(app.state.ui_state.selectables_store.selected_domains); +} + typedef StrandActionCreator = actions.UndoableAction Function(Strand strand); StrandActionCreator scaffold_set_strand_action_creator(bool is_scaffold) => @@ -1016,6 +1042,9 @@ StrandActionCreator color_set_substrand_action_creator(Substrand substrand, Stri ((Strand strand) => actions.StrandOrSubstrandColorSet(strand: strand, substrand: substrand, color: Color.hex(color_hex))); +StrandActionCreator name_set_strand_action_creator(String name) => + ((Strand strand) => actions.StrandNameSet(strand: strand, name: name)); + StrandActionCreator label_set_strand_action_creator(String label) => ((Strand strand) => actions.StrandLabelSet(strand: strand, label: label)); diff --git a/lib/src/view/design_main_strand_extension.dart b/lib/src/view/design_main_strand_extension.dart index 43437b758..c8fe49be6 100644 --- a/lib/src/view/design_main_strand_extension.dart +++ b/lib/src/view/design_main_strand_extension.dart @@ -173,7 +173,10 @@ class DesignMainExtensionComponent extends UiComponent2 app.dispatch(actions.SubstrandNameSet(name: null, substrand: props.ext))), + on_click: () => app.dispatch(actions.BatchAction( + app.state.ui_state.selectables_store.selected_extensions + .map((e) => actions.SubstrandNameSet(name: null, substrand: e)), + "remove extension names"))), ContextMenuItem( title: 'set extension label', on_click: set_extension_label, @@ -181,7 +184,10 @@ class DesignMainExtensionComponent extends UiComponent2 app.dispatch(actions.SubstrandLabelSet(label: null, substrand: props.ext))), + on_click: () => app.dispatch(actions.BatchAction( + app.state.ui_state.selectables_store.selected_extensions + .map((e) => actions.SubstrandLabelSet(label: null, substrand: e)), + "remove extension labels"))), ContextMenuItem( title: 'set extension color', on_click: () => app @@ -217,7 +223,7 @@ class DesignMainExtensionComponent extends UiComponent2 app.disable_keyboard_shortcuts_while(() => design_main_strand.ask_for_label( props.strand, props.ext, - app.state.ui_state.selectables_store.selected_substrands, + app.state.ui_state.selectables_store.selected_extensions, )); Future ask_for_extension_name() async { @@ -230,8 +236,10 @@ class DesignMainExtensionComponent extends UiComponent2 actions.SubstrandNameSet(name: name, substrand: e)), + "set extension names")); } extension_display_length_and_angle_change() => diff --git a/lib/src/view/design_main_strand_loopout.dart b/lib/src/view/design_main_strand_loopout.dart index 42ae99531..5b55b4c5b 100644 --- a/lib/src/view/design_main_strand_loopout.dart +++ b/lib/src/view/design_main_strand_loopout.dart @@ -166,7 +166,10 @@ class DesignMainLoopoutComponent extends UiStatefulComponent2 app.dispatch(actions.SubstrandNameSet(name: null, substrand: props.loopout))), + on_click: () => app.dispatch(actions.BatchAction( + app.state.ui_state.selectables_store.selected_loopouts + .map((l) => actions.SubstrandNameSet(name: null, substrand: l)), + "remove loopout names"))), ContextMenuItem( title: 'set loopout label', on_click: set_loopout_label, @@ -174,7 +177,10 @@ class DesignMainLoopoutComponent extends UiStatefulComponent2 app.dispatch(actions.SubstrandLabelSet(substrand: props.loopout, label: null))), + on_click: () => app.dispatch(actions.BatchAction( + app.state.ui_state.selectables_store.selected_loopouts + .map((l) => actions.SubstrandLabelSet(label: null, substrand: l)), + "remove loopout names"))), ContextMenuItem( title: 'set loopout color', on_click: () => app.dispatch( @@ -224,7 +230,7 @@ class DesignMainLoopoutComponent extends UiStatefulComponent2 app.disable_keyboard_shortcuts_while(() => design_main_strand.ask_for_label( props.strand, props.loopout, - app.state.ui_state.selectables_store.selected_substrands, + app.state.ui_state.selectables_store.selected_loopouts, )); Future ask_for_loopout_name() async { @@ -237,8 +243,10 @@ class DesignMainLoopoutComponent extends UiStatefulComponent2 actions.SubstrandNameSet(name: name, substrand: l)), + "set loopout names")); } String loopout_path_description_between_groups() {