import * as React from 'react'; import Srl from "../data/Srl"; import SrlVisualizer from "./SrlVisualizer"; import TokensSelection from "./Selection/TokensSelection"; import RoleSelection from "./Selection/RoleSelection"; import DragingSelection from "./Selection/DragingSelection"; import {Selection} from "./SrlVisualizer"; import {blue, grey, red} from '@material-ui/core/colors'; import UndoIcon from '@material-ui/icons/Undo'; import EditHistory from './EditHistory'; import MenuList from "@material-ui/core/MenuList/MenuList"; import MenuItem from "@material-ui/core/MenuItem/MenuItem"; import Popover from "@material-ui/core/Popover/Popover"; import {FrameLabelSet} from "../data/FrameLabelSet"; import IconButton from "@material-ui/core/IconButton"; import Typography from "@material-ui/core/Typography"; type Anchor = {left:number, top:number}; type Props = { srl: Srl, noArrow?: boolean, onRequestSrlChange?: (srl:Srl)=>void, width?: number, frameLabelSets: FrameLabelSet[] }; type Inks = string[]; type State = { srl?: Srl, selectedFrame: null|number, selection: Selection, menuAnchor: null|Anchor, } const menuItemProps = { dense: true, style: { fontSize: 12, lineHeight: 1, paddingTop: 4, paddingBottom: 4, } }; class SrlEditable extends React.Component{ currMousePos: Anchor = {left:0, top:0}; state:State = {selectedFrame: null, selection: null, menuAnchor:null}; history:EditHistory = new EditHistory(); getInksThatHighlightFrame(frameIndex: null|number):Inks { if (frameIndex == null) return [grey[500]]; const numFrames = this.getSrl().frames.length; const ret:Inks = Array(numFrames).fill(grey[500]); if(frameIndex { if(selection instanceof DragingSelection) { this.setState({selection:selection, menuAnchor:null}); return; } let candidate:Partial = {selection:selection, menuAnchor:this.currMousePos}; if(selection instanceof RoleSelection) candidate = {selectedFrame:selection.frameIndex, ...candidate}; else if(selection == null) candidate = {selection: null, menuAnchor:null}; this.setState(candidate as Pick); }; handleSrlChange = (srl:Srl) => { this.setState({menuAnchor:null}); if(typeof this.props.onRequestSrlChange === "function") this.props.onRequestSrlChange(srl); else this.setState({srl}) }; handleMenuClose = () => { this.setState({menuAnchor: null}) }; pushHistory() { this.history.push(this.getSrl(), this.state.selection, this.state.selectedFrame); } popHistory = () => { if(this.history.isEmpty()) return; const {srl, selection, selectedFrame} = this.history.pop()!; this.setState({selection, selectedFrame}); setTimeout(()=>this.handleSrlChange(srl)); }; addFrame(predLabel: string) { const {selection} = this.state; if(selection instanceof TokensSelection) { const srl = Srl.addFrame(this.getSrl(), selection.beginIndex, selection.endIndex, predLabel); this.pushHistory(); this.handleSrlChange(srl); this.handleSelectionChange(new RoleSelection(srl.frames.length-1, 0)); this.setState({menuAnchor: null}); } } addRole(name:string) { const {selectedFrame, selection} = this.state; if(selectedFrame != null && selection instanceof TokensSelection) { const srl = Srl.addRole(this.getSrl(), selectedFrame, selection.beginIndex, selection.endIndex,name); this.pushHistory(); this.handleSrlChange(srl) } } removeFrame() { const {selectedFrame} = this.state; if(selectedFrame != null) { this.handleSelectionChange(null); const srl = Srl.removeFrame(this.getSrl(),selectedFrame); this.pushHistory(); this.handleSrlChange(srl); this.setState({selectedFrame: null}); } } removeRole() { const {selectedFrame, selection} = this.state; if(selectedFrame != null && selection instanceof RoleSelection) { this.handleSelectionChange(null); const srl = Srl.removeRole(this.getSrl(),selectedFrame, selection.roleIndex); this.pushHistory(); this.handleSrlChange(srl); } } changeRole(name:string) { const {selectedFrame, selection} = this.state; if(selectedFrame != null && selection instanceof RoleSelection) { const srl = Srl.changeRole(this.getSrl(),selectedFrame, selection.roleIndex, name); this.pushHistory(); this.handleSrlChange(srl); } } static findFrameLabelSet(frameLabelSets:FrameLabelSet[], srl:Srl):FrameLabelSet|null { const name = srl.frameLabelSetName; if(name == null) return null; for(const frameLabelSet of frameLabelSets) { if(frameLabelSet.name === name) return frameLabelSet; } return null; } renderMenuList() { const {frameLabelSets, srl} = this.props; const frameLabelSet = SrlEditable.findFrameLabelSet(frameLabelSets, srl) || frameLabelSets[0]; if(frameLabelSet == null) { return no frame configuration defined } const {selectedFrame, selection} = this.state; if(selectedFrame == null && selection instanceof TokensSelection) { return {frameLabelSet.targets.map(x=>this.addFrame(x)} {...menuItemProps}> create frame {x} )} } if(selectedFrame != null && selection instanceof TokensSelection) { return {frameLabelSet.targets.map(x=>this.addFrame(x)} {...menuItemProps}> create frame {x} )} {frameLabelSet.args.map(x=>this.addRole(x)} {...menuItemProps}> mark as {x} )} } if(selection instanceof RoleSelection) { const srl = this.getSrl(); if(srl.frames.length<=selection.frameIndex) return null; const frame = srl.frames[selection.frameIndex]; if(frame.roles.length<=selection.roleIndex) return null; if(frame.roles[selection.roleIndex].isPredicate) { return this.removeFrame()} {...menuItemProps}>remove frame } return this.removeRole()} {...menuItemProps}>remove role {frameLabelSet.args.map(x=>this.changeRole(x)} {...menuItemProps}> change to {x} )} } return null; } render() { const srl = this.getSrl(); const {selection,menuAnchor,selectedFrame} = this.state; return
this.currMousePos = {left:e.clientX, top:e.clientY}}> {!this.history.isEmpty() && } {this.renderMenuList()}
} } export default SrlEditable;