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

953 remove strand in batch #954

Merged
merged 4 commits into from
Nov 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 54 additions & 25 deletions lib/src/view/design_main_strand.dart
Original file line number Diff line number Diff line change
Expand Up @@ -273,16 +273,19 @@ class DesignMainStrandComponent extends UiComponent2<DesignMainStrandProps>

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<Domain> 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<Domain> domains) {
return app.disable_keyboard_shortcuts_while(
() => ask_for_label(props.strand, substrand, get_selected_domains()));
}

ReactElement _insertions() {
List<ReactElement> paths = [];
Expand Down Expand Up @@ -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',
Expand All @@ -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',
Expand All @@ -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',
Expand Down Expand Up @@ -901,7 +916,7 @@ PAGEHPLC : Dual PAGE & HPLC
app.dispatch(batch_action);
}

Future<void> ask_for_strand_name() async {
Future<void> ask_for_strand_name(Strand strand, BuiltSet<Strand> selected_strands) async {
int name_idx = 0;
var items = List<DialogItem>.filled(1, null);
items[name_idx] = DialogText(label: 'name', value: props.strand.name ?? '');
Expand All @@ -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<void> ask_for_substrand_name(Substrand substrand) async {
Future<void> ask_for_domain_names(BuiltSet<Domain> domains) async {
int name_idx = 0;
var items = List<DialogItem>.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);
Expand All @@ -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<void> ask_for_label(Strand strand, Substrand substrand, BuiltSet<Strand> selected_strands) async {
Future<void> ask_for_label<T extends SelectableMixin>(
Strand strand, Substrand substrand, BuiltSet<T> selected_strands) async {
String part_name = 'strand';
if (substrand != null) {
part_name = substrand.type_description();
Expand Down Expand Up @@ -972,12 +988,12 @@ Future<void> ask_for_label(Strand strand, Substrand substrand, BuiltSet<Strand>

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<Strand>, "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);
Expand All @@ -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<Domain> get_selected_domains() {
return BuiltSet<Domain>(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) =>
Expand All @@ -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));

Expand Down
18 changes: 13 additions & 5 deletions lib/src/view/design_main_strand_extension.dart
Original file line number Diff line number Diff line change
Expand Up @@ -173,15 +173,21 @@ class DesignMainExtensionComponent extends UiComponent2<DesignMainExtensionProps
if (props.ext.name != null)
ContextMenuItem(
title: 'remove extension name',
on_click: () => 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,
),
if (props.ext.label != null)
ContextMenuItem(
title: 'remove extension label',
on_click: () => 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
Expand Down Expand Up @@ -217,7 +223,7 @@ class DesignMainExtensionComponent extends UiComponent2<DesignMainExtensionProps
set_extension_label() => 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<void> ask_for_extension_name() async {
Expand All @@ -230,8 +236,10 @@ class DesignMainExtensionComponent extends UiComponent2<DesignMainExtensionProps
if (results == null) return;

String name = (results[name_idx] as DialogText).value;
actions.UndoableAction action = actions.SubstrandNameSet(name: name, substrand: props.ext);
app.dispatch(action);
app.dispatch(actions.BatchAction(
app.state.ui_state.selectables_store.selected_extensions
.map((e) => actions.SubstrandNameSet(name: name, substrand: e)),
"set extension names"));
}

extension_display_length_and_angle_change() =>
Expand Down
18 changes: 13 additions & 5 deletions lib/src/view/design_main_strand_loopout.dart
Original file line number Diff line number Diff line change
Expand Up @@ -166,15 +166,21 @@ class DesignMainLoopoutComponent extends UiStatefulComponent2<DesignMainLoopoutP
if (props.loopout.name != null)
ContextMenuItem(
title: 'remove loopout name',
on_click: () => 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,
),
if (props.loopout.label != null)
ContextMenuItem(
title: 'remove loopout label',
on_click: () => 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(
Expand Down Expand Up @@ -224,7 +230,7 @@ class DesignMainLoopoutComponent extends UiStatefulComponent2<DesignMainLoopoutP
set_loopout_label() => 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<void> ask_for_loopout_name() async {
Expand All @@ -237,8 +243,10 @@ class DesignMainLoopoutComponent extends UiStatefulComponent2<DesignMainLoopoutP
if (results == null) return;

String name = (results[name_idx] as DialogText).value;
actions.UndoableAction action = actions.SubstrandNameSet(name: name, substrand: props.loopout);
app.dispatch(action);
app.dispatch(actions.BatchAction(
app.state.ui_state.selectables_store.selected_loopouts
.map((l) => actions.SubstrandNameSet(name: name, substrand: l)),
"set loopout names"));
}

String loopout_path_description_between_groups() {
Expand Down