diff --git a/src/apps/rednatco/api.ts b/src/apps/rednatco/api.ts index fce22576002dc8e6d4d53a21a22151b7fb9ebd14..b53d578014a28788e487d24c8ce0765e588e92fd 100644 --- a/src/apps/rednatco/api.ts +++ b/src/apps/rednatco/api.ts @@ -41,13 +41,21 @@ export namespace ReDNATCOMspApi { } export type Command = Commands.DeselectStep | + Commands.Filter | Commands.Redraw | Commands.SelectStep | Commands.SwitchModel; export namespace Events { - export type Type = 'ready'|'step-deselected'|'step-requested'|'step-selected'|'structure-loaded'; + export type Type = 'filter'|'ready'|'step-deselected'|'step-requested'|'step-selected'|'structure-loaded'; + export type Filter = { type: 'filter', success: boolean, message: string } + export function FilterApplied(): Filter { + return { type: 'filter', success: true, message: '' }; + } + export function FilterFailed(message: string): Filter { + return { type: 'filter', success: false, message }; + } export type Ready = { type: 'ready' } export function Ready(): Ready { return { type: 'ready' }; @@ -77,6 +85,7 @@ export namespace ReDNATCOMspApi { } } export type Event = + Events.Filter | Events.Ready | Events.StepDeselected | Events.StepRequested | @@ -84,14 +93,19 @@ export namespace ReDNATCOMspApi { Events.StructureLoaded; export namespace Queries { - export type Type = 'selected-step'; + export type Type = 'current-filter'|'selected-step'; + + export type CurrentFilter = { type: 'current-filter', filter: Filters.All } + export function CurrentFilter(filter: Filters.All): CurrentFilter { + return { type: 'current-filter', filter }; + } export type SelectedStep = { type: 'selected-step', name: string, rmsd?: number } export function SelectedStep(name: string, rmsd?: number): SelectedStep { return { type: 'selected-step', name, rmsd }; } } - export type Response = Queries.SelectedStep; + export type Response = Queries.CurrentFilter|Queries.SelectedStep; export interface Object { command: (cmd: Command) => void; diff --git a/src/apps/rednatco/index.tsx b/src/apps/rednatco/index.tsx index 9d2919cc3760895e8020cee6e0c93f7379f87b48..79264bae85994a445bbd5e33378c323910b58d90 100644 --- a/src/apps/rednatco/index.tsx +++ b/src/apps/rednatco/index.tsx @@ -2,6 +2,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { ReDNATCOMspApi as Api } from './api'; import { ReDNATCOMspApiImpl } from './api-impl'; +import { Filters } from './filters'; import { ReDNATCOMspViewer } from './viewer'; import { NtCColors } from './colors'; import { ColorPicker } from './color-picker'; @@ -73,6 +74,7 @@ interface State { showControls: boolean; } export class ReDNATCOMsp extends React.Component<ReDNATCOMsp.Props, State> { + private currentFilter: Filters.All = Filters.Empty(); private presentConformers: string[] = []; private viewer: ReDNATCOMspViewer|undefined = undefined; private selectedStep: { name: string, rmsd?: number }|undefined; @@ -147,7 +149,9 @@ export class ReDNATCOMsp extends React.Component<ReDNATCOMsp.Props, State> { } apiQuery(type: Api.Queries.Type): Api.Response { - if (type === 'selected-step') { + if (type === 'current-filter') { + return Api.Queries.CurrentFilter(this.currentFilter); + } else if (type === 'selected-step') { if (this.selectedStep) return Api.Queries.SelectedStep(this.selectedStep.name, this.selectedStep.rmsd); return Api.Queries.SelectedStep(''); @@ -165,6 +169,15 @@ export class ReDNATCOMsp extends React.Component<ReDNATCOMsp.Props, State> { window.dispatchEvent(new Event('resize')); else if (cmd.type === 'deselect-step') { await this.viewer.actionDeselectStep(this.state.display); + } else if (cmd.type === 'filter') { + const ret = await this.viewer.actionApplyFilter(cmd.filter); + if (!ret) { + ReDNATCOMspApi.event(Api.Events.FilterFailed('')); + return; + } + + this.currentFilter = cmd.filter; + ReDNATCOMspApi.event(Api.Events.FilterApplied()); } else if (cmd.type === 'select-step') { const ret = await this.viewer.actionSelectStep(cmd.stepName, cmd.prevStepName, cmd.nextStepName, cmd.referenceNtC, cmd.references, this.state.display); if (!ret) { diff --git a/src/apps/rednatco/viewer.ts b/src/apps/rednatco/viewer.ts index f7cf4ec3767ded4f2ac5470f5fc2601f391ec61f..a2fc2f7e85b963052214dcac149214326818e19b 100644 --- a/src/apps/rednatco/viewer.ts +++ b/src/apps/rednatco/viewer.ts @@ -966,6 +966,37 @@ export class ReDNATCOMspViewer { } } + async actionApplyFilter(filter: Filters.All) { + await this.plugin.state.data.build() + .to(IDs.ID('structure', 'nucleic', BaseRef)) + .update( + StateTransforms.Model.StructureSelectionFromExpression, + old => ({ + ...old, + expression: Filtering.toExpression(filter) + }) + ) + .to(IDs.ID('structure', 'protein', BaseRef)) + .update( + StateTransforms.Model.StructureSelectionFromExpression, + old => ({ + ...old, + expression: Filtering.toExpression(filter) + }) + ) + .to(IDs.ID('structure', 'protein', BaseRef)) + .update( + StateTransforms.Model.StructureSelectionFromExpression, + old => ({ + ...old, + expression: Filtering.toExpression(filter) + }) + ) + .commit(); + + return true; + } + async actionDeselectStep(display: Display) { await this.plugin.state.data.build() .delete(IDs.ID('superposition', '', NtCSupSel))