from pathlib import Path
import wx

class PasswordPanel(wx.Panel):
    def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition,
                 size=(200, 30), value="", style=wx.BORDER_THEME|wx.TRANSPARENT_WINDOW,
                 iconside='right', name="name"):
        wx.Panel.__init__(self, parent, id, pos, size=size, style=style, name=name)

        self.value = value
        self.iconside = iconside

        curdir = Path(__file__).parent
        self.bmp_hide = wx.Bitmap(Path(curdir, 'icon_hidden.png').as_posix())
        self.bmp_show = wx.Bitmap(Path(curdir, 'icon_visible.png').as_posix())

        self.font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT).Larger()

        self.pw_icon = wx.StaticBitmap(self, -1, self.bmp_show)
        self.pw_icon.Bind(wx.EVT_LEFT_UP, self.OnShowPassword)

        self.sizer = wx.BoxSizer(wx.HORIZONTAL)
        self.build_display()
        self.SetSizer(self.sizer)

    def build_display(self, hide=True):
        tstyle = wx.TE_PROCESS_ENTER | wx.BORDER_NONE
        bitmap = self.bmp_hide
        if hide:
            bitmap = self.bmp_show
            tstyle = tstyle | wx.TE_PASSWORD

        self.pw_icon.SetBitmap(bitmap)
        self.pw_ctrl = wx.TextCtrl(self, value=self.value,
                                     size=(150, -1), style=tstyle)
        self.pw_ctrl.SetFont(self.font)

        self.sizer.Clear()
        if self.iconside.startswith('r'):
            self.sizer.Add(self.pw_ctrl, 1, wx.EXPAND|wx.ALL, 2)
            self.sizer.Add(self.pw_icon, 0, wx.ALIGN_CENTER_VERTICAL, 2)
        else:
            self.sizer.Add(self.pw_icon, 0, wx.ALIGN_CENTER_VERTICAL, 2)
            self.sizer.Add(self.pw_ctrl, 1, wx.EXPAND|wx.ALL, 2)
        self.Layout()


    def OnShowPassword(self, event):
        hidden = self.pw_ctrl.GetWindowStyle() & wx.TE_PASSWORD
        self.build_display(hide=(hidden==0))

    def GetValue(self, event):
        return self.pw_ctrl.GetValue()

    def SetValue(self, value):
        self.value = value
        self.pw_ctrl.SetValue(value)


class Frame(wx.Frame):
    def __init__(self, *args, **kw):
        super(Frame, self).__init__(*args, **kw)

        self.SetTitle("Password control with show/hide icon")
        self.SetSize((300, 150))
        self.Centre()

        pnl = wx.Panel(self)

        self.textCtrl1 = PasswordPanel(pnl, value='Password_1')
        self.textCtrl2 = PasswordPanel(pnl, value='Awesome', iconside='left')

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.textCtrl1, 0, wx.ALL | wx.EXPAND, 10)
        sizer.Add(self.textCtrl2, 0, wx.ALL | wx.EXPAND, 10)

        pnl.SetSizer(sizer)


class App(wx.App):
    def OnInit(self):
        frame = Frame(None)
        frame.Show()
        return True

if __name__ == "__main__":
    app = App()
    app.MainLoop()
