Skip to content

Commit

Permalink
Added baseComponent to ui to save boilerplate lines
Browse files Browse the repository at this point in the history
  • Loading branch information
lukewilson2002 committed Apr 8, 2021
1 parent 0918afc commit 8346c52
Show file tree
Hide file tree
Showing 9 changed files with 96 additions and 213 deletions.
31 changes: 5 additions & 26 deletions ui/button.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,14 @@ import (
type Button struct {
Text string
Callback func()

x, y int
width, height int
focused bool

Theme *Theme
baseComponent
}

func NewButton(text string, theme *Theme, callback func()) *Button {
return &Button{
Text: text,
Callback: callback,
Theme: theme,
text,
callback,
baseComponent{theme: theme},
}
}

Expand All @@ -32,23 +27,7 @@ func (b *Button) Draw(s tcell.Screen) {
} else {
str = fmt.Sprintf(" %s ", b.Text)
}
DrawStr(s, b.x, b.y, str, b.Theme.GetOrDefault("Button"))
}

func (b *Button) SetFocused(v bool) {
b.focused = v
}

func (b *Button) SetTheme(theme *Theme) {
b.Theme = theme
}

func (b *Button) GetPos() (int, int) {
return b.x, b.y
}

func (b *Button) SetPos(x, y int) {
b.x, b.y = x, y
DrawStr(s, b.x, b.y, str, b.theme.GetOrDefault("Button"))
}

func (b *Button) GetMinSize() (int, int) {
Expand Down
55 changes: 49 additions & 6 deletions ui/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,60 @@ type Component interface {
SetTheme(*Theme)

// Get position of the Component.
GetPos() (int, int)
GetPos() (x, y int)
// Set position of the Component.
SetPos(int, int)
SetPos(x, y int)

// Returns the smallest size the Component can be.
GetMinSize() (int, int)
GetMinSize() (w, h int)
// Get size of the Component.
GetSize() (int, int)
GetSize() (w, h int)
// Set size of the component. If size is smaller than minimum, minimum is
// used, instead.
SetSize(int, int)
SetSize(w, h int)

tcell.EventHandler // A Component can handle events
// HandleEvent tells the Component to handle the provided event. The Component
// should only handle events if it is focused. An event can optionally be
// handled. If an event is handled, the function should return true. If the
// event went unhandled, the function should return false.
HandleEvent(tcell.Event) bool
}

// baseComponent can be embedded in a Component's struct to hide a few of the
// boilerplate fields and functions. The baseComponent defines defaults for
// ...Pos(), ...Size(), SetFocused(), and SetTheme() functions that can be
// overriden.
type baseComponent struct {
focused bool
x, y int
width, height int
theme *Theme
}

func (c *baseComponent) SetFocused(v bool) {
c.focused = v
}

func (c *baseComponent) SetTheme(theme *Theme) {
c.theme = theme
}

func (c *baseComponent) GetPos() (int, int) {
return c.x, c.y
}

func (c *baseComponent) SetPos(x, y int) {
c.x, c.y = x, y
}

func (c *baseComponent) GetMinSize() (int, int) {
return 0, 0
}

func (c *baseComponent) GetSize() (int, int) {
return c.width, c.height
}

func (c *baseComponent) SetSize(width, height int) {
c.width, c.height = width, height
}
32 changes: 9 additions & 23 deletions ui/fileselectordialog.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,27 @@ import (
// A FileSelectorDialog is a WindowContainer with an input and buttons for selecting files.
// It can be used to open zero or more existing files, or select one non-existant file (for saving).
type FileSelectorDialog struct {
Title string
MustExist bool // Whether the dialog should have a user select an existing file.
FilesChosenCallback func([]string) // Returns slice of filenames selected. nil if user canceled.
Theme *Theme

title string
x, y int
width, height int
focused bool

tabOrder []Component
tabOrderIdx int

inputField *InputField
confirmButton *Button
cancelButton *Button

baseComponent
}

func NewFileSelectorDialog(screen *tcell.Screen, title string, mustExist bool, theme *Theme, filesChosenCallback func([]string), cancelCallback func()) *FileSelectorDialog {
dialog := &FileSelectorDialog{
Title: title,
MustExist: mustExist,
FilesChosenCallback: filesChosenCallback,
Theme: theme,
title: title,

baseComponent: baseComponent{theme: theme},
}

dialog.inputField = NewInputField(screen, []byte{}, theme.GetOrDefault("Window")) // Use window's theme for InputField
Expand All @@ -57,12 +55,8 @@ func (d *FileSelectorDialog) SetCancelCallback(callback func()) {
d.cancelButton.Callback = callback
}

func (d *FileSelectorDialog) SetTitle(title string) {
d.title = title
}

func (d *FileSelectorDialog) Draw(s tcell.Screen) {
DrawWindow(s, d.x, d.y, d.width, d.height, d.title, d.Theme)
DrawWindow(s, d.x, d.y, d.width, d.height, d.Title, d.theme)

// Update positions of child components (dependent on size information that may not be available at SetPos() )
btnWidth, _ := d.confirmButton.GetSize()
Expand All @@ -79,28 +73,20 @@ func (d *FileSelectorDialog) SetFocused(v bool) {
}

func (d *FileSelectorDialog) SetTheme(theme *Theme) {
d.Theme = theme
d.theme = theme
d.inputField.SetStyle(theme.GetOrDefault("Window"))
d.confirmButton.SetTheme(theme)
d.cancelButton.SetTheme(theme)
}

func (d *FileSelectorDialog) GetPos() (int, int) {
return d.x, d.y
}

func (d *FileSelectorDialog) SetPos(x, y int) {
d.x, d.y = x, y
d.inputField.SetPos(d.x+1, d.y+2) // Center input field
d.cancelButton.SetPos(d.x+1, d.y+4) // Place "Cancel" button on left, bottom
}

func (d *FileSelectorDialog) GetMinSize() (int, int) {
return Max(len(d.title), 8) + 2, 6
}

func (d *FileSelectorDialog) GetSize() (int, int) {
return d.width, d.height
return Max(len(d.Title), 8) + 2, 6
}

func (d *FileSelectorDialog) SetSize(width, height int) {
Expand Down
27 changes: 2 additions & 25 deletions ui/inputfield.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,10 @@ type InputField struct {

cursorPos int
scrollPos int
x, y int
width, height int
focused bool
screen *tcell.Screen
style tcell.Style

baseComponent
}

func NewInputField(screen *tcell.Screen, placeholder []byte, style tcell.Style) *InputField {
Expand Down Expand Up @@ -157,28 +156,6 @@ func (f *InputField) SetStyle(style tcell.Style) {
f.style = style
}

func (f *InputField) SetTheme(theme *Theme) {}

func (f *InputField) GetPos() (int, int) {
return f.x, f.y
}

func (f *InputField) SetPos(x, y int) {
f.x, f.y = x, y
}

func (f *InputField) GetMinSize() (int, int) {
return 0, 0
}

func (f *InputField) GetSize() (int, int) {
return f.width, f.height
}

func (f *InputField) SetSize(width, height int) {
f.width, f.height = width, height
}

func (f *InputField) HandleEvent(event tcell.Event) bool {
switch ev := event.(type) {
case *tcell.EventKey:
Expand Down
4 changes: 2 additions & 2 deletions ui/label.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const (
// bounding box and allows for left-align, right-align, and justify.
type Label struct {
Text string
x, y int
width, height int
Alignment Align

baseComponent
}
Loading

0 comments on commit 8346c52

Please sign in to comment.