<> <> <> <> DIRECTORY Commander, CommanderOps, IO, Rope, Xl, XTk, XTkMigration, XTkWidgets; X11SimpleChat: CEDAR PROGRAM IMPORTS Commander, CommanderOps, IO, Rope, XTk, XTkMigration, XTkWidgets ~ BEGIN Widget: TYPE = XTk.Widget; Inst: TYPE = RECORD [ stream: IO.STREAM, --output stream directed to all participants of conservation conversation: Rope.ROPE ¬ NIL, --id designating the conservation last: Rope.ROPE ¬ NIL, --last input for last command id: Widget _ NIL, --widget denoting id of participant in: Widget _ NIL --widget for input to conversation ]; Create: PROC [conversation: Rope.ROPE, widgetStream: IO.STREAM, connection: REF] ~ { i: REF Inst ~ NEW[Inst ¬ [stream: widgetStream, conversation: conversation]]; in: Widget ¬ i.in ¬ XTkWidgets.CreateField[text: ""]; send: Widget ¬ XTkWidgets.CreateButton[text: "send", hitProc: Send, registerData: i]; split: Widget ¬ XTkWidgets.CreateButton[text: "split", hitProc: Split, registerData: i]; last: Widget ¬ XTkWidgets.CreateButton[text: "last", hitProc: Last, registerData: i]; move: Widget ¬ XTkWidgets.CreateButton[text: "move", hitProc: Move, registerData: i]; id: Widget ¬ i.id ¬ XTkWidgets.CreateLabeledField[label: "id: ", init: ""]; menus: Widget ¬ XTkWidgets.CreateXStack[stack: LIST[send, XTkWidgets.VRule[], last, XTkWidgets.VRule[], split, XTkWidgets.VRule[], move, XTkWidgets.VRule[], id]]; out: Widget ¬ XTkWidgets.CreateStreamWidget[widgetSpec: [geometry: [size: [350, 200]]], widgetStream: widgetStream]; container: Widget ¬ XTkWidgets.CreateYStack[stack: LIST[menus, XTkWidgets.HRule[], in, XTkWidgets.HRule[], out]]; shell: Widget ¬ XTkWidgets.CreateShell[child: container, windowHeader: Rope.Concat["simple chat ", conversation]]; IF connection#NIL THEN XTkWidgets.BindScreenShell[shell, connection]; XTkWidgets.RealizeShell[shell]; }; Send: XTk.WidgetNotifyProc = { i: REF Inst ~ NARROW[registerData]; text: Rope.ROPE ¬ XTkWidgets.GetText[i.in]; id: Rope.ROPE ¬ XTkWidgets.GetText[i.id]; leng: INT ¬ Rope.Length[text]; IF leng>0 THEN { i.last ¬ text; IF Rope.Fetch[text, leng-1]#'\n THEN text _ Rope.Concat[text, "\n"]; text ¬ Rope.Cat[id, ">", text]; IO.PutRope[i.stream, text]; XTkWidgets.SetText[i.in, ""]; }; }; Split: XTk.WidgetNotifyProc = { i: REF Inst ~ NARROW[registerData]; Create[i.conversation, i.stream, widget.connection]; }; Last: XTk.WidgetNotifyProc = { i: REF Inst ~ NARROW[registerData]; XTkWidgets.SetText[i.in, i.last]; }; Move: XTk.WidgetNotifyProc = { i: REF Inst ~ NARROW[registerData]; dest: Rope.ROPE ¬ XTkWidgets.GetText[i.id]; msg: Rope.ROPE ¬ XTkMigration.Migrate[XTk.RootWidget[widget], dest]; IF msg#NIL THEN XTkWidgets.SetText[i.in, msg]; }; CreateConversationCommand: Commander.CommandProc ~ { conversation: Rope.ROPE ¬ CommanderOps.NextArgument[cmd]; widgetStream: IO.STREAM ¬ XTkWidgets.CreateStream[]; Create[conversation, widgetStream, NIL]; }; Commander.Register["X11SimpleChat", CreateConversationCommand, "Create a simple chat widget"]; END.