DIRECTORY Ascii, Rope, Xl, XlAscii, XTk, XTkButtons, XTkCredentialsWidget, XTkInputFocus, XTkLabels; XTkCredentialsWidgetImpl: CEDAR MONITOR IMPORTS Rope, Xl, XlAscii, XTk, XTkButtons, XTkInputFocus, XTkLabels EXPORTS XTkCredentialsWidget = BEGIN Widget: TYPE = XTk.Widget; WidgetSpec: TYPE = XTk.WidgetSpec; clearText: Rope.ROPE ~ "xxxxxxxx"; fullText: Rope.ROPE ~ "*******"; events: Xl.EventFilter ~ Xl.CreateEventFilter[keyPress]; Create: PUBLIC PROC [widgetSpec: XTk.WidgetSpec ¬ []] RETURNS [w: XTk.Widget] = { w ¬ XTkButtons.CreateButton[widgetSpec: widgetSpec, text: clearText, hitProc: Hit]; XTk.AddPermanentMatch[w, [proc: EventProc, handles: events, tq: Xl.CreateTQ[], data: w], [keyPress: TRUE]]; }; Contents: PUBLIC PROC [w: XTk.Widget] RETURNS [Rope.ROPE] = { WITH XTk.GetWidgetProp[w, clearText] SELECT FROM r: Rope.ROPE => RETURN [r]; ENDCASE => RETURN [NIL]; }; Put: PROC [w: XTk.Widget, contents: Rope.ROPE] = { old: Rope.ROPE ¬ Contents[w]; XTk.PutWidgetProp[w, clearText, contents]; IF ~Rope.Equal[old, contents] THEN { IF Rope.IsEmpty[contents] THEN XTkLabels.SetText[w, clearText] ELSE XTkLabels.SetText[w, fullText] }; }; Clear: PUBLIC PROC [w: XTk.Widget] = { Put[w, NIL]; }; Hit: XTk.WidgetNotifyProc ~ { WITH event SELECT FROM br: Xl.ButtonReleaseEvent => { pm: Xl.PointerMapping ~ Xl.GetPointerMapping[widget.connection]; SELECT pm[br.button] FROM 1 => Put[widget, NIL]; ENDCASE => {}; XTkInputFocus.SetFocus[widget, br.timeStamp]; }; ENDCASE => {}; }; EventProc: Xl.EventProcType = { ENABLE { Xl.XError => GOTO oops; }; widget: XTk.Widget ~ NARROW[clientData]; WITH event SELECT FROM keyPress: Xl.KeyPressEvent => { char: CHAR; keysym: Xl.KeySym; matched: Xl.KeySym; isModifier: BOOL; [char: char, keysym: keysym, matched: matched, isModifier: isModifier] ¬ XlAscii.Convert[event.connection, keyPress.keyCode, keyPress.state]; IF isModifier THEN RETURN; PushChar[widget, char]; }; ENDCASE => {}; EXITS oops => {}; }; PushChar: PROC [widget: XTk.Widget, ch: CHAR] = { text: Rope.ROPE ¬ Contents[widget]; SELECT ch FROM 4c, Ascii.LF, Ascii.CR, Ascii.DEL => {text ¬ NIL}; Ascii.BS => { leng: INT ¬ Rope.Length[text]; IF leng>0 THEN text ¬ Rope.Substr[text, 0, leng-1]; } ENDCASE => { text ¬ Rope.Concat[text, Rope.FromChar[ch]]; }; Put[widget, text]; }; END. BXTkCredentialsWidgetImpl.mesa Copyright Σ 1992 by Xerox Corporation. All rights reserved. Created by Christian Jacobi, January 31, 1992 Christian Jacobi, February 21, 1992 5:19 pm PST This module could benefit from code sharing with fields. But maybe it is as well to not make fields more complex as they are. ΚΌ–(cedarcode) style•NewlineDelimiter ˜codešœ™Kšœ Οeœ1™