StringGadget for passwords - toggle '*'?

Just starting out? Need help? Post your questions and find answers here.
wombats
Enthusiast
Enthusiast
Posts: 716
Joined: Thu Dec 29, 2011 5:03 pm

Re: StringGadget for passwords - toggle '*'?

Post by wombats »

For the sake of completion, here is how you do it on the Qt subsystem:

Code: Select all

CompilerCase #PB_OS_Linux
  CompilerIf Not Subsystem("qt")
    gtk_entry_set_visibility_(GadgetID(StringGadgetID),
                              gtk_entry_get_visibility_(GadgetID(StringGadgetID)) ! 1)
  CompilerElse
    If Val(QtScript("gadget(" + Str(StringGadgetID) + ").echoMode")) = 2
      QtScript("gadget(" + Str(StringGadgetID) + ").echoMode = 0")
    ElseIf Val(QtScript("gadget(" + Str(StringGadgetID) + ").echoMode")) = 0
      QtScript("gadget(" + Str(StringGadgetID) + ").echoMode = 2")
    EndIf
  CompilerEndIf
User avatar
Shardik
Addict
Addict
Posts: 2058
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: StringGadget for passwords - toggle '*'?

Post by Shardik »

Thank you wombats for the addition of the Qt code. I have integrated it into my last example code and tested it successfully in Xubuntu 18.04 x86 with subsystem qt.
Little John
Addict
Addict
Posts: 4777
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: StringGadget for passwords - toggle '*'?

Post by Little John »

Shardik wrote:I therefore adapted my code example and even added the MacOS part
Cool. 8)
I think you are our cross-platform master.
Thank you!
ozzie
Enthusiast
Enthusiast
Posts: 443
Joined: Sun Apr 06, 2008 12:54 pm
Location: Brisbane, Qld, Australia
Contact:

Re: StringGadget for passwords - toggle '*'?

Post by ozzie »

Here's a variation that uses an 'eye' password reveal icon instead of a regular button gadget:

Code: Select all

EnableExplicit

CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
  Define SecuredPasswordCell.I
  Define VisiblePasswordCell.I
CompilerEndIf

Procedure TogglePasswordVisibility(StringGadgetID.I)
  CompilerSelect #PB_Compiler_OS
    CompilerCase #PB_OS_Linux
      CompilerIf Subsystem("qt")
        If Val(QtScript("gadget(" + Str(StringGadgetID) + ").echoMode")) = 2
          QtScript("gadget(" + Str(StringGadgetID) + ").echoMode = 0")
        ElseIf Val(QtScript("gadget(" + Str(StringGadgetID) + ").echoMode")) = 0
          QtScript("gadget(" + Str(StringGadgetID) + ").echoMode = 2")
        EndIf
      CompilerElse
        gtk_entry_set_visibility_(GadgetID(StringGadgetID),
          gtk_entry_get_visibility_(GadgetID(StringGadgetID)) ! 1)
      CompilerEndIf
    CompilerCase #PB_OS_MacOS
      Shared SecuredPasswordCell.I
      Shared VisiblePasswordCell.I
      
      Protected Cell.I
      Protected Password.S

      Password = GetGadgetText(StringGadgetID)
      
      If PeekS(CocoaMessage(0, CocoaMessage(0, CocoaMessage(0,
        GadgetID(StringGadgetID), "cell"), "className"), "UTF8String"),
        -1, #PB_UTF8) = "NSSecureTextFieldCell"
        If VisiblePasswordCell = 0
          SecuredPasswordCell = CocoaMessage(0, GadgetID(StringGadgetID),
            "cell")
          CocoaMessage(0, SecuredPasswordCell, "retain")
          VisiblePasswordCell = CocoaMessage(0, CocoaMessage(0,
            CocoaMessage(0, 0, "NSTextField alloc"), "initWithFrame:", 0),
            "cell")
          CocoaMessage(0, VisiblePasswordCell, "retain")
        EndIf
        
        CocoaMessage(0, GadgetID(StringGadgetID),
          "setCell:", VisiblePasswordCell)
        CocoaMessage(0, VisiblePasswordCell, "setStringValue:$", @Password)
        CocoaMessage(0, GadgetID(StringGadgetID), "setNeedsDisplay:", #YES)
      Else
        If SecuredPasswordCell
          CocoaMessage(0, GadgetID(StringGadgetID),
            "setCell:", SecuredPasswordCell)
          CocoaMessage(0, SecuredPasswordCell, "setStringValue:$", @Password)
          CocoaMessage(0, GadgetID(StringGadgetID), "setNeedsDisplay:", #YES)
        EndIf
      EndIf
    CompilerCase #PB_OS_Windows
      Static PasswordChar
      Static PasswordCharIsKnown

      If PasswordCharIsKnown = #False
        PasswordChar = SendMessage_(GadgetID(StringGadgetID),
          #EM_GETPASSWORDCHAR, 0, 0)
        PasswordCharIsKnown = #True
      EndIf

      If GetWindowLongPtr_(GadgetID(StringGadgetID),
        #GWL_STYLE) & #ES_PASSWORD
        SendMessage_(GadgetID(StringGadgetID), #EM_SETPASSWORDCHAR, 0, 0)
      Else
        SendMessage_(GadgetID(StringGadgetID), #EM_SETPASSWORDCHAR,
          PasswordChar, 0)
      EndIf

      InvalidateRect_(GadgetID(StringGadgetID), 0, 1)
  CompilerEndSelect
EndProcedure

OpenWindow(0, 270, 100, 280, 90, "Toggle password visibility")
StringGadget(0, 40, 20, 180, 20, "Test", #PB_String_Password)
CanvasGadget(2, 222, 20, 20, 20)
If StartVectorDrawing(CanvasVectorOutput(2))
  AddPathCircle(10, 15, 10, 340, 200, #PB_Path_CounterClockwise)
  MovePathCursor(10, 15)
  ClosePath()
  StrokePath(1)
  AddPathCircle(10, 12, 2)
  VectorSourceColor(RGBA(0, 0, 0, 255))
  FillPath()
  StopVectorDrawing()
EndIf

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
        CocoaMessage(0, VisiblePasswordCell, "release")
      CompilerEndIf
      Break
      
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 2
          Select EventType()
            Case #PB_EventType_LeftButtonDown
              TogglePasswordVisibility(0)
          EndSelect
      EndSelect
      
  EndSelect
ForEver
Tested under Windows only. Could possibly be improved - this is the first time I've used Vector Drawing! Could also be easily modified to follow the convention used on a number of sites and products where the password is revealed only when the mouse is down on the 'eye' icon, and is again hidden when the mouse is released or moved away from the icon.
Post Reply