func CreateLoginDialog(title, userName string) *LoginDialog {
	dlg := new(LoginDialog)

	dlg.View = AddWindow(15, 8, 10, 4, title)
	WindowManager().BeginUpdate()
	defer WindowManager().EndUpdate()

	dlg.View.SetModal(true)
	dlg.View.SetPack(Vertical)

	userfrm := CreateFrame(dlg.View, 1, 1, BorderNone, Fixed)
	userfrm.SetPaddings(1, 1)
	userfrm.SetPack(Horizontal)
	userfrm.SetGaps(1, 0)
	CreateLabel(userfrm, AutoSize, AutoSize, "User name", Fixed)
	edUser := CreateEditField(userfrm, 20, userName, 1)

	passfrm := CreateFrame(dlg.View, 1, 1, BorderNone, 1)
	passfrm.SetPaddings(1, 1)
	passfrm.SetPack(Horizontal)
	passfrm.SetGaps(1, 0)
	CreateLabel(passfrm, AutoSize, AutoSize, "Password", Fixed)
	edPass := CreateEditField(passfrm, 20, "", 1)
	edPass.SetPasswordMode(true)

	filler := CreateFrame(dlg.View, 1, 1, BorderNone, 1)
	filler.SetPack(Horizontal)
	lbRes := CreateLabel(filler, AutoSize, AutoSize, "", 1)

	blist := CreateFrame(dlg.View, 1, 1, BorderNone, Fixed)
	blist.SetPack(Horizontal)
	blist.SetPaddings(1, 1)
	btnOk := CreateButton(blist, 10, 4, "OK", Fixed)
	btnCancel := CreateButton(blist, 10, 4, "Cancel", Fixed)

	btnCancel.OnClick(func(ev Event) {
		WindowManager().DestroyWindow(dlg.View)
		WindowManager().BeginUpdate()
		dlg.Action = LoginCanceled
		closeFunc := dlg.onClose
		WindowManager().EndUpdate()
		if closeFunc != nil {
			closeFunc()
		}
	})

	btnOk.OnClick(func(ev Event) {
		if dlg.onCheck != nil && !dlg.onCheck(edUser.Title(), edPass.Title()) {
			lbRes.SetTitle("Invalid username or password")
			dlg.Action = LoginInvalid
			return
		}

		dlg.Action = LoginOk
		if dlg.onCheck == nil {
			dlg.Username = edUser.Title()
			dlg.Password = edPass.Title()
		}

		WindowManager().DestroyWindow(dlg.View)
		WindowManager().BeginUpdate()

		closeFunc := dlg.onClose
		WindowManager().EndUpdate()
		if closeFunc != nil {
			closeFunc()
		}
	})

	dlg.View.OnClose(func(ev Event) bool {
		if dlg.result == DialogAlive {
			dlg.result = DialogClosed
			if ev.X != 1 {
				WindowManager().DestroyWindow(dlg.View)
			}
			if dlg.onClose != nil {
				dlg.onClose()
			}
		}
		return true
	})

	edUser.OnChange(func(ev Event) {
		lbRes.SetTitle("")
	})
	edPass.OnChange(func(ev Event) {
		lbRes.SetTitle("")
	})

	if userName == "" {
		ActivateControl(dlg.View, edUser)
	} else {
		ActivateControl(dlg.View, edPass)
	}
	return dlg
}
func CreateLoginDialog(title, userName string) *LoginDialog {
	dlg := new(LoginDialog)

	dlg.View = AddWindow(15, 8, 10, 4, title)
	WindowManager().BeginUpdate()
	defer WindowManager().EndUpdate()

	dlg.View.SetModal(true)
	dlg.View.SetPack(Vertical)

	userfrm := CreateFrame(dlg.View, 1, 1, BorderNone, Fixed)
	userfrm.SetPaddings(1, 1)
	userfrm.SetPack(Horizontal)
	userfrm.SetGaps(1, 0)
	CreateLabel(userfrm, AutoSize, AutoSize, "User name", Fixed)
	edUser := CreateEditField(userfrm, 20, userName, 1)

	passfrm := CreateFrame(dlg.View, 1, 1, BorderNone, 1)
	passfrm.SetPaddings(1, 1)
	passfrm.SetPack(Horizontal)
	passfrm.SetGaps(1, 0)
	CreateLabel(passfrm, AutoSize, AutoSize, "Password", Fixed)
	edPass := CreateEditField(passfrm, 20, "", 1)
	edPass.SetPasswordMode(true)

	filler := CreateFrame(dlg.View, 1, 1, BorderNone, 1)
	filler.SetPack(Horizontal)
	lbRes := CreateLabel(filler, AutoSize, AutoSize, "", 1)

	blist := CreateFrame(dlg.View, 1, 1, BorderNone, Fixed)
	blist.SetPack(Horizontal)
	blist.SetPaddings(1, 1)
	btnOk := CreateButton(blist, 10, 4, "OK", Fixed)
	btnCancel := CreateButton(blist, 10, 4, "Cancel", Fixed)

	btnCancel.OnClick(func(ev Event) {
		WindowManager().DestroyWindow(dlg.View)
		WindowManager().BeginUpdate()
		dlg.Action = LoginCanceled
		closeFunc := dlg.onClose
		WindowManager().EndUpdate()
		if closeFunc != nil {
			closeFunc()
		}
	})

	btnOk.OnClick(func(ev Event) {
		if dlg.onCheck != nil && !dlg.onCheck(edUser.Title(), edPass.Title()) {
			lbRes.SetTitle("Invalid username or password")
			dlg.Action = LoginInvalid
			return
		}

		dlg.Action = LoginOk
		if dlg.onCheck == nil {
			dlg.Username = edUser.Title()
			dlg.Password = edPass.Title()
		}

		WindowManager().DestroyWindow(dlg.View)
		WindowManager().BeginUpdate()

		closeFunc := dlg.onClose
		WindowManager().EndUpdate()
		if closeFunc != nil {
			closeFunc()
		}
	})

	dlg.View.OnClose(func(ev Event) bool {
		if dlg.result == DialogAlive {
			dlg.result = DialogClosed
			if ev.X != 1 {
				WindowManager().DestroyWindow(dlg.View)
			}
			if dlg.onClose != nil {
				dlg.onClose()
			}
		}
		return true
	})

	edUser.OnChange(func(ev Event) {
		lbRes.SetTitle("")
	})
	edPass.OnChange(func(ev Event) {
		lbRes.SetTitle("")
	})

	if userName == "" {
		ActivateControl(dlg.View, edUser)
	} else {
		ActivateControl(dlg.View, edPass)
	}
	return dlg
}
// LoginDialog creates a new login dialog
//  * title - custom dialog title
//  * userName - initial username. Maybe useful if you want to implement
//     a feature "remember me"
// The active control depends on userName: if it is empty then the cursor is
//  in Username field, and in Password field otherwise.
// By default the dialog is closed when button "OK" is clicked. But if you set
//  OnCheck callback the dialog closes only if callback returns true or
//  button "Cancel" is clicked. This is helpful if you do not want to recreate
//  the dialog after every incorrect credentials. So, you define a callback
//  that checks whether pair of Usename and Password is correct and then the
//  button "OK" closed the dialog only if the callback returns true. If the
//  credentials are not valid, then the dialog shows a warning. The warning
//  automatically disappears when a user starts typing in Password or Username
//  field.