<<>> <> <> <> <<>> DIRECTORY Atom, BiScrollers, GGInterfaceTypes, GGUserInput, GGProps, InputFocus, IO, PropRegistry, Rope, ViewerClasses; GGRegistryImpl: CEDAR PROGRAM IMPORTS Atom, BiScrollers, GGUserInput, InputFocus, PropRegistry, Rope = BEGIN Viewer: TYPE = ViewerClasses.Viewer; GGData: TYPE = GGInterfaceTypes.GGData; STREAM: TYPE = IO.STREAM; ROPE: TYPE = PropRegistry.ROPE; Doc: TYPE = PropRegistry.Doc; Key: TYPE = PropRegistry.Key; lf: ROPE = "\l"; noFocus: ROPE = "No input focus in any viewer"; noGGFocus: ROPE = "No input focus in Gargoyle viewer"; LFNewLine: PROC [in: ROPE] RETURNS [out: ROPE] = { IF in#NIL THEN { size: INT = Rope.Size[in]; out _ in; FOR index: INT _ Rope.SkipTo[s: in, pos: 0, skip: "\l\r"], Rope.SkipTo[s: in, pos: index+1, skip: "\l\r"] UNTIL index = size DO out _ Rope.Replace[base: out, start: index, len: 1, with: lf]; ENDLOOP; }; }; GGPropGet: PropRegistry.PropGetProc = { <> lor: LIST OF ROPE; extRef: GGUserInput.External; ggData: GGData; focus: InputFocus.Focus _ InputFocus.GetInputFocus[]; from: Viewer _ IF focus#NIL THEN focus.owner ELSE NIL; IF from=NIL THEN RETURN [NIL, noFocus]; ggData _ NARROW[BiScrollers.ClientDataOfViewer[from]]; IF ggData=NIL THEN RETURN [NIL, noGGFocus]; extRef _ NEW[GGUserInput.ExternalRec _ [FALSE, key] ]; -- pass in Key GGUserInput.EventNotify[ggData, LIST[$GetPropExternal, extRef] ]; UNTIL extRef.valid DO GGUserInput.WaitExternal[extRef] ENDLOOP; <> lor _ NARROW[extRef.results]; <> prop _ LFNewLine[lor.first]; error _ LFNewLine[lor.rest.first]; }; GGPropList: PropRegistry.PropListProc = { <> extRef: GGUserInput.External; ggData: GGData; focus: InputFocus.Focus _ InputFocus.GetInputFocus[]; from: Viewer _ IF focus#NIL THEN focus.owner ELSE NIL; IF from=NIL THEN RETURN [NIL]; ggData _ NARROW[BiScrollers.ClientDataOfViewer[from]]; IF ggData=NIL THEN RETURN [NIL]; extRef _ NEW[GGUserInput.ExternalRec _ [] ]; GGUserInput.EventNotify[ggData, LIST[$ListPropsExternal, extRef] ]; <> UNTIL extRef.valid DO GGUserInput.WaitExternal[extRef] ENDLOOP; <> props _ NARROW[extRef.results]; }; GGPropRem: PropRegistry.PropRemProc = { <> ggData: GGData; focus: InputFocus.Focus _ InputFocus.GetInputFocus[]; from: Viewer _ IF focus#NIL THEN focus.owner ELSE NIL; IF from=NIL THEN RETURN; ggData _ NARROW[BiScrollers.ClientDataOfViewer[from]]; IF ggData=NIL THEN RETURN; GGUserInput.EventNotify[ggData, LIST[$RemoveProp, Atom.GetPName[key]] ]; <> }; GGPropSet: PropRegistry.PropSetProc = { <> keyVal: Rope.ROPE; ggData: GGData; focus: InputFocus.Focus _ InputFocus.GetInputFocus[]; from: Viewer _ IF focus#NIL THEN focus.owner ELSE NIL; IF from=NIL THEN RETURN; ggData _ NARROW[BiScrollers.ClientDataOfViewer[from]]; IF ggData=NIL THEN RETURN; keyVal _ Rope.Cat[Atom.GetPName[key], " ", prop]; -- that's what GG wants GGUserInput.EventNotify[ggData, LIST[$SetProp, keyVal] ]; <> }; GGGetTarget: PropRegistry.GetTargetProc = { <> success _ TRUE; -- LIE FOR NOW <> }; GGSetTarget: PropRegistry.SetTargetProc = { <> success _ TRUE; -- LIE FOR NOW }; GGValidateTarget: PropRegistry.ValidateTargetProc = { <> success _ NOT (doc.destroyed OR doc.iconic); IF NOT success THEN error _ IF doc.destroyed THEN "target viewer destroyed" ELSE "target viewer iconic" }; RegisterGG: PROC = { class: PropRegistry.RegistryClass _ NEW[PropRegistry.RegistryClassObj]; class^_ [ name: $ActionArea, getProp: GGPropGet, setProp: GGPropSet, remProp: GGPropRem, listProps: GGPropList, getTarget: GGGetTarget, setTarget: GGSetTarget, validTarget: GGValidateTarget ]; PropRegistry.Register[class]; }; RegisterGG[]; END.