<> <> <> <> <> <> <<>> DIRECTORY GGBasicTypes, GGBoundBox, GGInterfaceTypes, GGModelTypes, GGScene, GGOutline, GGSceneType, GGSegmentTypes, GGSelect, GGSequence, GGSlice, GGTraj, GGUtility, List; GGSelectImpl: CEDAR PROGRAM IMPORTS GGBoundBox, GGScene, GGOutline, GGSequence, GGSlice, GGTraj, GGUtility, List EXPORTS GGModelTypes, GGSelect = BEGIN BoundBox: TYPE = GGBasicTypes.BoundBox; Caret: TYPE = GGInterfaceTypes.Caret; EntityGenerator: TYPE = REF EntityGeneratorObj; EntityGeneratorObj: TYPE = GGModelTypes.EntityGeneratorObj; Joint: TYPE = GGModelTypes.Joint; JointGenerator: TYPE = GGModelTypes.JointGenerator; Outline: TYPE = GGModelTypes.Outline; OutlineDescriptor: TYPE = REF OutlineDescriptorObj; OutlineDescriptorObj: TYPE = GGModelTypes.OutlineDescriptorObj; SceneRef: TYPE = REF SceneObj; SceneObj: PUBLIC TYPE = GGSceneType.SceneObj; SegAndIndex: TYPE = GGSequence.SegAndIndex; Segment: TYPE = GGSegmentTypes.Segment; SegmentGenerator: TYPE = GGModelTypes.SegmentGenerator; SelectionClass: TYPE = GGInterfaceTypes.SelectionClass; Sequence: TYPE = REF SequenceObj; SequenceGenerator: TYPE = REF SequenceGeneratorObj; SequenceGeneratorObj: TYPE = GGModelTypes.SequenceGeneratorObj; SequenceObj: TYPE = GGModelTypes.SequenceObj; Slice: TYPE = GGModelTypes.Slice; SliceDescriptor: TYPE = GGModelTypes.SliceDescriptor; SliceDescriptorGenerator: TYPE = GGModelTypes.SliceDescriptorGenerator; SliceDescriptorGeneratorObj: TYPE = GGModelTypes.SliceDescriptorGeneratorObj; SliceDescriptorObj: TYPE = GGModelTypes.SliceDescriptorObj; SliceGenerator: TYPE = REF SliceGeneratorObj; SliceGeneratorObj: TYPE = GGModelTypes.SliceGeneratorObj; SliceParts: TYPE = GGModelTypes.SliceParts; Traj: TYPE = GGModelTypes.Traj; TrajEnd: TYPE = GGModelTypes.TrajEnd; TrajGenerator: TYPE = REF TrajGeneratorObj; TrajGeneratorObj: TYPE = GGModelTypes.TrajGeneratorObj; NotYetImplemented: PUBLIC SIGNAL = CODE; OutlineSequenceGenerator: TYPE = REF OutlineSequenceGeneratorObj; OutlineSequenceGeneratorObj: TYPE = GGSelect.OutlineSequenceGeneratorObj; OutlineSequence: TYPE = REF OutlineSequenceObj; OutlineSequenceObj: TYPE = GGSelect.OutlineSequenceObj; <> <> <> <> <> <<1) If an OutlineDescriptor is on the selected list, all of the selectedInFull fields of its joints, segments, and control points should be TRUE. The selected fields are maintained for efficiency only. The information they represent is always obtainable from the selected list as well.>> <> <<2) Only one sequence per trajectory may appear on the selected list.>> <> <<3) A non-gargoyle slice may only appear once on the selected list.>> <<4) Iff a sequence representing a trajectory is on the selected list, the "selectedInPart" field of the trajectory will TRUE.>> <<5) Iff a non-Gargoyle slice is on the selected list, the "selectedInFull" field of that slice will be true.>> <> <<>> <> <> < {>> <> <<};>> < {>> <> <<};>> < { -- this case needed for ReselectTraj>> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<};>> < ERROR;>> <<};>> <<>> <> <<>> ChangeDonkeyTail: PROC [sliceD: SliceDescriptor, selectClass: SelectionClass] = { SELECT selectClass FROM normal => sliceD.slice.normalSelectedParts _ sliceD; hot => sliceD.slice.hotSelectedParts _ sliceD; active => sliceD.slice.activeSelectedParts _ sliceD; ENDCASE; }; ChangeDonkeyTailOutline: PROC [sliceD: OutlineDescriptor, selectClass: SelectionClass] = { SELECT selectClass FROM normal => sliceD.slice.normalSelectedParts _ sliceD; hot => sliceD.slice.hotSelectedParts _ sliceD; active => sliceD.slice.activeSelectedParts _ sliceD; ENDCASE; }; NoDonkeyTail: PROC [slice: Slice, selectClass: SelectionClass] = { SELECT selectClass FROM normal => slice.normalSelectedParts _ NIL; hot => slice.hotSelectedParts _ NIL; active => slice.activeSelectedParts _ NIL; ENDCASE; }; NoDonkeyTailOutline: PROC [slice: Outline, selectClass: SelectionClass] = { SELECT selectClass FROM normal => slice.normalSelectedParts _ NIL; hot => slice.hotSelectedParts _ NIL; active => slice.activeSelectedParts _ NIL; ENDCASE; }; SelectAll: PUBLIC PROC [scene: SceneRef, selectClass: SelectionClass] = { entityGen: EntityGenerator; entityGen _ GGScene.TopLevelEntitiesInScene[scene]; FOR entity: REF ANY _ GGScene.NextEntity[entityGen], GGScene.NextEntity[entityGen] UNTIL entity = NIL DO WITH entity SELECT FROM slice: Slice => { SelectEntireSlice[slice, scene, selectClass]; }; outline: Outline => { SelectEntireOutline[outline, scene, selectClass]; }; ENDCASE => ERROR; ENDLOOP; }; SelectSlice: PUBLIC PROC [sliceD: SliceDescriptor, scene: SceneRef, selectClass: SelectionClass] = { oldSliceD, union: SliceDescriptor; slice: Slice _ sliceD.slice; IF slice.class.emptyParts[sliceD] THEN RETURN; oldSliceD _ FindSelectedSlice[slice, scene, selectClass]; IF oldSliceD#NIL THEN { union _ slice.class.unionParts[oldSliceD, sliceD]; DeselectSlice[slice, oldSliceD.parts, scene, selectClass]; -- throw away old selection } ELSE union _ sliceD; IF selectClass = normal THEN union _ slice.class.augmentParts[union, selectClass]; AppendSelection[scene, union, selectClass]; ChangeDonkeyTail[union, selectClass]; }; -- end SelectSlice SelectOutline: PUBLIC PROC [sliceD: OutlineDescriptor, scene: SceneRef, selectClass: SelectionClass] = { oldD, union: OutlineDescriptor; slice: Outline _ sliceD.slice; IF slice.class.emptyParts[sliceD] THEN RETURN; oldD _ FindSelectedOutline[slice, scene, selectClass]; IF oldD # NIL THEN { union _ slice.class.unionParts[oldD, sliceD]; DeselectOutline[slice, oldD.parts, scene, selectClass]; -- throw away old selection } ELSE union _ sliceD; IF selectClass = normal THEN union _ slice.class.augmentParts[union, selectClass]; AppendSelection[scene, union, selectClass]; ChangeDonkeyTailOutline[union, selectClass]; }; -- end SelectOutline SelectEntireOutline: PUBLIC PROC [outline: Outline, scene: SceneRef, selectClass: SelectionClass] = { allParts: OutlineDescriptor _ outline.class.newParts[outline, NIL, slice]; SelectOutline[allParts, scene, selectClass]; }; SelectEntireSlice: PUBLIC PROC [slice: Slice, scene: SceneRef, selectClass: SelectionClass] = { allParts: SliceDescriptor _ slice.class.newParts[slice, NIL, slice]; SelectSlice[allParts, scene, selectClass]; }; <<>> SelectSequence: PUBLIC PROC [seq: Sequence, scene: SceneRef, selectClass: SelectionClass] = { outline: Outline _ GGOutline.OutlineOfTraj[seq.traj]; parts: SliceParts; seqD: OutlineDescriptor; IF GGSequence.IsEmpty[seq] THEN RETURN; parts _ GGOutline.PartsFromSequence[outline, seq]; seqD _ GGOutline.DescriptorFromParts[outline, parts]; SelectOutline[seqD, scene, selectClass]; }; SelectTraj: PUBLIC PROC [traj: Traj, scene: SceneRef, selectClass: SelectionClass] = { <> wholeSeq: Sequence; wholeSeq _ GGSequence.CreateComplete[traj]; SelectSequence[wholeSeq, scene, selectClass]; }; <<>> DuplicateSelections: PROC [scene: SceneRef, fromClass: SelectionClass, toClass: SelectionClass] = { sliceDescGen: GGSelect.SliceDescriptorGenerator; seqGen: SequenceGenerator; sliceDescGen _ SelectedSlices[scene, fromClass]; FOR sliceD: SliceDescriptor _ NextSliceDescriptor[sliceDescGen], NextSliceDescriptor[sliceDescGen] UNTIL sliceD = NIL DO SelectSlice[sliceD, scene, toClass]; ENDLOOP; seqGen _ SelectedSequences[scene, fromClass]; FOR seq: Sequence _ GGSequence.NextSequence[seqGen], GGSequence.NextSequence[seqGen] UNTIL seq = NIL DO SelectSequence[seq, scene, toClass]; ENDLOOP; }; DeselectAll: PUBLIC PROC [scene: SceneRef, selectClass: SelectionClass] = { <> FOR selected: LIST OF REF ANY _ ListSelected[scene, selectClass], selected.rest UNTIL selected = NIL DO <> WITH selected.first SELECT FROM sliceD: SliceDescriptor => NoDonkeyTail[sliceD.slice, selectClass]; outlineD: OutlineDescriptor => NoDonkeyTailOutline[outlineD.slice, selectClass]; ENDCASE => ERROR; ENDLOOP; SetSelectedList[scene, NIL, selectClass]; }; DeselectEntity: PUBLIC PROC [entity: REF ANY, scene: SceneRef, selectClass: SelectionClass] = { WITH entity SELECT FROM seq: Sequence => DeselectSequence[seq, scene, selectClass]; traj: Traj => DeselectTraj[traj, scene, selectClass]; outline: Outline => DeselectEntireOutline[outline, scene, selectClass]; outlineD: OutlineDescriptor => DeselectOutline[outlineD.slice, outlineD.parts, scene, selectClass]; slice: Slice => DeselectEntireSlice[slice, scene, selectClass]; sliceD: SliceDescriptor => DeselectSlice[sliceD.slice, sliceD.parts, scene, selectClass]; ENDCASE => ERROR; }; DeselectEntityAllClasses: PUBLIC PROC [entity: REF ANY, scene: SceneRef] = { DeselectEntity[entity, scene, normal]; DeselectEntity[entity, scene, active]; DeselectEntity[entity, scene, hot]; }; DeselectAllAllClasses: PUBLIC PROC [scene: SceneRef] = { DeselectAll[scene, normal]; DeselectAll[scene, active]; DeselectAll[scene, hot]; }; DeselectEntireSlice: PUBLIC PROC [slice: Slice, scene: SceneRef, selectClass: SelectionClass] = { <> selSliceD: SliceDescriptor _ FindSelectedSlice[slice, scene, selectClass]; IF selSliceD#NIL THEN { IF selSliceD.slice.class.type = $Outline THEN ERROR NotYetImplemented; DeleteSelection[scene, selSliceD, selectClass]; NoDonkeyTail[selSliceD.slice, selectClass]; <> }; }; <> <> <> <> <> <<};>> <<};>> <<>> DeselectSlice: PUBLIC PROC [slice: Slice, parts: SliceParts, scene: SceneRef, selectClass: SelectionClass] = { oldD, newD, tempD: SliceDescriptor; oldD _ FindSelectedSlice[slice, scene, selectClass]; IF oldD # NIL THEN { tempD _ GGSlice.DescriptorFromParts[slice, parts]; newD _ slice.class.differenceParts[oldD, tempD]; DeleteSelection[scene, oldD, selectClass]; NoDonkeyTail[oldD.slice, selectClass]; IF NOT slice.class.emptyParts[newD] THEN { IF selectClass = normal THEN newD _ slice.class.augmentParts[newD, selectClass]; AppendSelection[scene, newD, selectClass]; ChangeDonkeyTail[newD, selectClass]; }; }; }; DeselectOutline: PUBLIC PROC [outline: Outline, parts: SliceParts, scene: SceneRef, selectClass: SelectionClass] = { <> oldD, newD, tempD: OutlineDescriptor; oldD _ FindSelectedOutline[outline, scene, selectClass]; IF oldD # NIL THEN { tempD _ GGOutline.DescriptorFromParts[outline, parts]; newD _ outline.class.differenceParts[oldD, tempD]; DeleteSelection[scene, oldD, selectClass]; NoDonkeyTailOutline[outline, selectClass]; IF NOT outline.class.emptyParts[newD] THEN { IF selectClass = normal THEN newD _ outline.class.augmentParts[newD, selectClass]; AppendSelection[scene, newD, selectClass]; ChangeDonkeyTailOutline[newD, selectClass]; }; }; }; DeselectSequence: PUBLIC PROC [seq: Sequence, scene: SceneRef, selectClass: SelectionClass] = { outline: Outline _ GGOutline.OutlineOfTraj[seq.traj]; seqParts: SliceParts _ GGOutline.PartsFromSequence[outline, seq]; DeselectOutline[outline, seqParts, scene, selectClass]; }; DeselectEntireOutline: PUBLIC PROC [outline: Outline, scene: SceneRef, selectClass: SelectionClass] = { <> outlineD: OutlineDescriptor _ FindSelectedOutline[outline, scene, selectClass]; IF outlineD # NIL THEN { DeleteSelection[scene, outlineD, selectClass]; NoDonkeyTailOutline[outlineD.slice, selectClass]; }; }; DeselectTraj: PUBLIC PROC [traj: Traj, scene: SceneRef, selectClass: SelectionClass] = { <> outline: Outline _ GGOutline.OutlineOfTraj[traj]; oldD, newD: OutlineDescriptor; oldD _ FindSelectedOutline[outline, scene, selectClass]; IF oldD # NIL THEN { newD _ GGOutline.RemoveTraj[oldD, traj]; DeleteSelection[scene, oldD, selectClass]; NoDonkeyTailOutline[outline, selectClass]; IF NOT outline.class.emptyParts[newD] THEN { AppendSelection[scene, newD, selectClass]; ChangeDonkeyTailOutline[newD, selectClass]; }; }; }; <<>> <> <<>> ReselectTraj: PUBLIC PROC [traj: Traj, trajEnd: TrajEnd, scene: SceneRef, extend: BOOL] RETURNS [newHot: Sequence] = { selSeq, newSeq: Sequence; selSeq _ FindSelectedSequence[traj, scene, normal]; <> IF selSeq # NIL THEN { newSeq _ GGSequence.Augment[selSeq, trajEnd, extend]; DeselectTraj[selSeq.traj, scene, normal]; SelectSequence[newSeq, scene, normal]; }; <> selSeq _ FindSelectedSequence[traj, scene, hot]; IF selSeq # NIL THEN { newHot _ newSeq _ GGSequence.Augment[selSeq, trajEnd, extend]; DeselectTraj[selSeq.traj, scene, hot]; SelectSequence[newSeq, scene, hot]; }; <> selSeq _ FindSelectedSequence[traj, scene, active]; IF selSeq # NIL THEN { ERROR; -- I don't think ReselectTraj should be used for active }; }; <> <<>> DeleteSelection: PROC [scene: SceneRef, entity: REF ANY, selectClass: SelectionClass] = { <> SetSelectedList[scene, List.DRemove[entity, ListSelected[scene, selectClass]], selectClass]; }; ListSelected: PUBLIC PROC [scene: SceneRef, selectClass: SelectionClass] RETURNS [selectedList: LIST OF REF ANY] = { SELECT selectClass FROM normal => selectedList _ scene.selected.normal; hot => selectedList _ scene.selected.hot; active => selectedList _ scene.selected.active; ENDCASE => ERROR; }; ListSelectedSequences: PUBLIC PROC [scene: SceneRef, selectClass: SelectionClass] RETURNS [selectedList: LIST OF Sequence] = { <> seq: Sequence; selectedList _ NIL; FOR entityList: LIST OF REF ANY _ ListSelected[scene, selectClass], entityList.rest UNTIL entityList = NIL DO IF ISTYPE[entityList.first, Sequence] THEN { seq _ NARROW[entityList.first]; selectedList _ CONS[seq, selectedList]; }; ENDLOOP; }; <> <<>> <> <