From 8d7474f23b43a035da5ca58cbeed66b433e0b4e1 Mon Sep 17 00:00:00 2001 From: Vladimir Markelov Date: Tue, 2 Jan 2018 11:15:05 -0800 Subject: [PATCH] #63 - added password mode for the edit field --- VERSION | 2 +- changelog | 11 +++++- demos/editfield/editfield.go | 45 +++++++++++++++++++++++ demos/maindemo/themes/acsii.theme | 2 +- demos/maindemo/themes/turbovision.theme | 2 +- edit.go | 49 +++++++++++++++++++++---- theme.go | 2 +- themes/turbovision.theme | 2 +- 8 files changed, 102 insertions(+), 13 deletions(-) create mode 100644 demos/editfield/editfield.go diff --git a/VERSION b/VERSION index 3b1fc8e..31450a2 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.6.2 \ No newline at end of file +0.6.3 diff --git a/changelog b/changelog index 8a6b6e5..b7f17ec 100644 --- a/changelog +++ b/changelog @@ -1,4 +1,13 @@ -2017-12-01 - version 0.6.2 +2018-01-02 - version 0.6.3 +[+] Add a new boolean property for EditField - PasswordMode. If PasswordMode is + true then the editfield text is hidden with 'stars'. + Please see demo demos/editfield for details +[+] Change a theme for object 'Edit' - added non-obligatory forth character + that is used as replacement for any character inside EditField when Password + mode is on. By default it is '*' in all included themes. Old themes that + miss forth character use '*' as well. + +2017-12-01 - version 0.6.2 [*] Fix selecting the next control with TAB key 2017-11-28 - version 0.6.2 diff --git a/demos/editfield/editfield.go b/demos/editfield/editfield.go new file mode 100644 index 0000000..06fcafb --- /dev/null +++ b/demos/editfield/editfield.go @@ -0,0 +1,45 @@ +package main + +import ( + ui "github.com/VladimirMarkelov/clui" +) + +func createView() { + view := ui.AddWindow(0, 0, 10, 7, "EditField Demo") + + frmChk := ui.CreateFrame(view, 8, 5, ui.BorderNone, ui.Fixed) + frmChk.SetPack(ui.Vertical) + frmChk.SetPaddings(1, 1) + frmChk.SetGaps(1, 1) + ui.CreateLabel(frmChk, ui.AutoSize, ui.AutoSize, "Enter password:", ui.Fixed) + edFld := ui.CreateEditField(frmChk, 20, "", ui.Fixed) + chkPass := ui.CreateCheckBox(frmChk, ui.AutoSize, "Show Password", ui.Fixed) + + ui.ActivateControl(view, edFld) + + chkPass.OnChange(func(state int) { + if state == 0 { + edFld.SetPasswordMode(false) + ui.PutEvent(ui.Event{Type: ui.EventRedraw}) + } else if state == 1 { + edFld.SetPasswordMode(true) + ui.PutEvent(ui.Event{Type: ui.EventRedraw}) + } + }) +} + +func mainLoop() { + // Every application must create a single Composer and + // call its intialize method + ui.InitLibrary() + defer ui.DeinitLibrary() + + createView() + + // start event processing loop - the main core of the library + ui.MainLoop() +} + +func main() { + mainLoop() +} diff --git a/demos/maindemo/themes/acsii.theme b/demos/maindemo/themes/acsii.theme index 82bc9e1..8e273e3 100644 --- a/demos/maindemo/themes/acsii.theme +++ b/demos/maindemo/themes/acsii.theme @@ -15,7 +15,7 @@ ProgressActiveText = white //----------------- Objects ----------------- SingleBorder=-|++++ DoubleBorder==|++++ -Edit=<>V +Edit=<>V* ScrollBar=|O^V<> ViewButtons=^_X[] CheckBox=[] X? diff --git a/demos/maindemo/themes/turbovision.theme b/demos/maindemo/themes/turbovision.theme index dd301ed..286a7ce 100644 --- a/demos/maindemo/themes/turbovision.theme +++ b/demos/maindemo/themes/turbovision.theme @@ -81,7 +81,7 @@ TableHeaderBack=black //----------------- Objects ----------------- SingleBorder=─│┌┐└┘ DoubleBorder=═║╔╗╚╝ -Edit=←→V +Edit=←→V* ScrollBar=░■▲▼◄► ViewButtons=^↓○[] CheckBox=[] X? diff --git a/edit.go b/edit.go index 9ce646f..38ea33f 100644 --- a/edit.go +++ b/edit.go @@ -4,6 +4,7 @@ import ( "github.com/atotto/clipboard" xs "github.com/huandu/xstrings" term "github.com/nsf/termbox-go" + "strings" ) /* @@ -20,9 +21,10 @@ type EditField struct { // cursor position in edit text cursorPos int // the number of the first displayed text character - it is used in case of text is longer than edit width - offset int - readonly bool - maxWidth int + offset int + readonly bool + maxWidth int + showStars bool onChange func(Event) onKeyPress func(term.Key) bool @@ -97,26 +99,46 @@ func (e *EditField) Draw() { parts := []rune(SysObject(ObjEdit)) chLeft, chRight := string(parts[0]), string(parts[1]) + chStar := "*" + if len(parts) > 3 { + chStar = string(parts[3]) + } var textOut string curOff := 0 if e.offset == 0 && xs.Len(e.title) < e.width { - textOut = e.title + if e.showStars { + textOut = strings.Repeat(chStar, xs.Len(e.title)) + } else { + textOut = e.title + } } else { fromIdx := 0 toIdx := 0 if e.offset == 0 { toIdx = e.width - 1 - textOut = xs.Slice(e.title, 0, toIdx) + chRight + if e.showStars { + textOut = strings.Repeat(chStar, toIdx) + chRight + } else { + textOut = xs.Slice(e.title, 0, toIdx) + chRight + } curOff = -e.offset } else { curOff = 1 - e.offset fromIdx = e.offset if e.width-1 <= xs.Len(e.title)-e.offset { toIdx = e.offset + e.width - 2 - textOut = chLeft + xs.Slice(e.title, fromIdx, toIdx) + chRight + if e.showStars { + textOut = chLeft + strings.Repeat(chStar, toIdx-fromIdx) + chRight + } else { + textOut = chLeft + xs.Slice(e.title, fromIdx, toIdx) + chRight + } } else { - textOut = chLeft + xs.Slice(e.title, fromIdx, -1) + if e.showStars { + textOut = chLeft + strings.Repeat(chStar, xs.Len(e.title)-fromIdx) + } else { + textOut = chLeft + xs.Slice(e.title, fromIdx, -1) + } } } } @@ -361,3 +383,16 @@ func (e *EditField) SetSize(width, height int) { e.height = 1 } + +// PasswordMode returns whether password mode is enabled for the control +func (e *EditField) PasswordMode() bool { + return e.showStars +} + +// SetPasswordMode changes the way an EditField displays it content. +// If PasswordMode is false then the EditField works as regular text entry +// control. If PasswordMode is true then the EditField shows its content hidden +// with star characters ('*' by default) +func (e *EditField) SetPasswordMode(pass bool) { + e.showStars = pass +} diff --git a/theme.go b/theme.go index a48cc73..995937d 100644 --- a/theme.go +++ b/theme.go @@ -136,7 +136,7 @@ func ThemeReset() { defTheme.objects[ObjSingleBorder] = "─│┌┐└┘" defTheme.objects[ObjDoubleBorder] = "═║╔╗╚╝" - defTheme.objects[ObjEdit] = "←→V" + defTheme.objects[ObjEdit] = "←→V*" defTheme.objects[ObjScrollBar] = "░■▲▼◄►" defTheme.objects[ObjViewButtons] = "^↓○[]" defTheme.objects[ObjCheckBox] = "[] X?" diff --git a/themes/turbovision.theme b/themes/turbovision.theme index dd301ed..286a7ce 100644 --- a/themes/turbovision.theme +++ b/themes/turbovision.theme @@ -81,7 +81,7 @@ TableHeaderBack=black //----------------- Objects ----------------- SingleBorder=─│┌┐└┘ DoubleBorder=═║╔╗╚╝ -Edit=←→V +Edit=←→V* ScrollBar=░■▲▼◄► ViewButtons=^↓○[] CheckBox=[] X?