From aae2d245944ecf26ad9274280477fb9a17e53288 Mon Sep 17 00:00:00 2001 From: Dan Anglin Date: Wed, 10 Jan 2024 11:20:15 +0000 Subject: [PATCH] fix(ui): improve the creating cards input modal This commit improves the look, feel and functionality of the custom modal that creates new cards on the board. Changes: - (BREAKING) The 'c' key is now used to create new cards. - An extra field is added for adding the card's description. - Improvements made to the styling of the modal. - The fields are reset when the user finishes with the form. --- README.asciidoc | 4 +- internal/ui/modal_input.go | 86 --------------------------- internal/ui/modalinput.go | 116 +++++++++++++++++++++++++++++++++++++ internal/ui/ui.go | 8 +-- 4 files changed, 122 insertions(+), 92 deletions(-) delete mode 100644 internal/ui/modal_input.go create mode 100644 internal/ui/modalinput.go diff --git a/README.asciidoc b/README.asciidoc index 3948827..7618f94 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -77,8 +77,8 @@ and initialises the database with an empty project. |CTRL + q |Quit the application -|a -|Add card +|c +|Create a new card |CTRL + d |Delete card diff --git a/internal/ui/modal_input.go b/internal/ui/modal_input.go deleted file mode 100644 index 890d63e..0000000 --- a/internal/ui/modal_input.go +++ /dev/null @@ -1,86 +0,0 @@ -package ui - -import ( - "github.com/gdamore/tcell/v2" - "github.com/rivo/tview" -) - -type modalInput struct { - *tview.Form - frame *tview.Frame - text string - done func(string, bool) -} - -func NewModalInput() *modalInput { - form := tview.NewForm() - m := modalInput{ - Form: form, - frame: tview.NewFrame(form), - text: "", - done: nil, - } - - m.SetButtonsAlign(tview.AlignCenter). - SetButtonBackgroundColor(tview.Styles.PrimitiveBackgroundColor). - SetButtonTextColor(tview.Styles.PrimaryTextColor). - SetBackgroundColor(tview.Styles.ContrastBackgroundColor). - SetBorderPadding(0, 0, 0, 0) - - m.AddInputField("", "", 50, nil, func(text string) { - m.text = text - }) - - m.AddButton("OK", func() { - if m.done != nil { - m.done(m.text, true) - } - }) - - m.AddButton("Cancel", func() { - if m.done != nil { - m.done(m.text, false) - } - }) - - m.frame.SetBorders(0, 0, 1, 0, 0, 0). - SetBorder(true). - SetBackgroundColor(tview.Styles.ContrastBackgroundColor). - SetBorderPadding(1, 1, 1, 1) - - return &m -} - -func (m *modalInput) SetValue(text string) { - m.Clear(false) - m.AddInputField("", text, 50, nil, func(text string) { - m.text = text - }) -} - -func (m *modalInput) SetDoneFunc(handler func(string, bool)) *modalInput { - m.done = handler - return m -} - -func (m *modalInput) Draw(screen tcell.Screen) { - buttonsWidth := 50 - screenWidth, screenHeight := screen.Size() - width := screenWidth / 3 - - if width < buttonsWidth { - width = buttonsWidth - } - - height := 7 - width += 4 - - // Set the modal's position and size. - x := (screenWidth - width) / 2 - y := (screenHeight - height) / 2 - m.SetRect(x, y, width, height) - - // Draw the frame. - m.frame.SetRect(x, y, width, height) - m.frame.Draw(screen) -} diff --git a/internal/ui/modalinput.go b/internal/ui/modalinput.go new file mode 100644 index 0000000..2b2b91b --- /dev/null +++ b/internal/ui/modalinput.go @@ -0,0 +1,116 @@ +package ui + +import ( + "github.com/gdamore/tcell/v2" + "github.com/rivo/tview" +) + +type modalInput struct { + *tview.Form + frame *tview.Frame + title string + description string + done func(string, string, bool) +} + +func newModalInput() *modalInput { + var ( + background = tcell.ColorBlack.TrueColor() + buttonBackground = tcell.ColorBlueViolet.TrueColor() + textColour = tcell.ColorWhite.TrueColor() + fieldBackground = tcell.ColorGrey.TrueColor() + labelColour = tcell.ColorGreen.TrueColor() + + form = tview.NewForm() + ) + + modal := modalInput{ + Form: form, + frame: tview.NewFrame(form), + title: "", + description: "", + done: nil, + } + + // Stylise the buttons + modal.SetButtonsAlign(tview.AlignCenter). + SetButtonBackgroundColor(buttonBackground). + SetButtonTextColor(textColour). + SetBorderPadding(0, 0, 0, 0) + + // Stylise the form + modal.SetLabelColor(labelColour). + SetFieldBackgroundColor(fieldBackground). + SetFieldTextColor(textColour). + SetBackgroundColor(background) + + // Stylise the frame around the form + modal.frame.SetBorders(0, 0, 1, 0, 0, 0). + SetBorder(true). + SetBorderColor(tcell.ColorOrangeRed.TrueColor()). + SetBackgroundColor(background). + SetBorderPadding(1, 1, 1, 1) + + modal.AddButton("Create card", func() { + if modal.done != nil { + modal.done(modal.title, modal.description, true) + } + modal.reset() + }) + + modal.AddButton("Cancel", func() { + if modal.done != nil { + modal.done(modal.title, modal.description, false) + } + modal.reset() + }) + + modal.addInputFields() + + modal.frame.SetTitle(" New Card ") + + return &modal +} + +func (m *modalInput) reset() { + m.Clear(false) + m.addInputFields() +} + +func (m *modalInput) addInputFields() { + m.AddInputField("Title", "", 60, nil, func(text string) { + m.title = text + }) + + m.AddTextArea("Description", "", 60, 10, 0, func(text string) { + m.description = text + }) +} + +func (m *modalInput) SetDoneFunc(handler func(string, string, bool)) *modalInput { + m.done = handler + + return m +} + +func (m *modalInput) Draw(screen tcell.Screen) { + buttonsWidth := 20 + screenWidth, screenHeight := screen.Size() + width := screenWidth / 3 + + if width < buttonsWidth { + width = buttonsWidth + } + + height := 20 + width += 4 + + // Set the modal's position and size. + x := (screenWidth - width) / 2 + y := (screenHeight - height) / 2 + m.SetRect(x, y, width, height) + + // Draw the frame. + m.frame.SetRect(x, y, width, height) + m.frame.Draw(screen) +} diff --git a/internal/ui/ui.go b/internal/ui/ui.go index 1a33c91..bffd0ce 100644 --- a/internal/ui/ui.go +++ b/internal/ui/ui.go @@ -57,7 +57,7 @@ func NewUI(path string) (UI, error) { pages: tview.NewPages(), flex: tview.NewFlex(), quitModal: tview.NewModal(), - addModal: NewModalInput(), + addModal: newModalInput(), focusedColumn: 0, columns: nil, board: kanban, @@ -93,7 +93,7 @@ func (u *UI) init() error { u.shiftColumnFocus(previous) case letter == 'l' || key == tcell.KeyRight: u.shiftColumnFocus(next) - case letter == 'a': + case letter == 'c': if u.mode == normal { u.pages.ShowPage(addPage) u.SetFocus(u.addModal) @@ -156,9 +156,9 @@ func (u *UI) init() error { // initAddInputModal initialises the add input modal. func (u *UI) initAddInputModal() { - doneFunc := func(text string, success bool) { + doneFunc := func(text, description string, success bool) { if success { - _ = u.newCard(text, "") + _ = u.newCard(text, description) } u.pages.HidePage(addPage)