Added baseComponent to ui to save boilerplate lines
This commit is contained in:
parent
0918afc483
commit
8346c52167
31
ui/button.go
31
ui/button.go
@ -9,19 +9,14 @@ import (
|
|||||||
type Button struct {
|
type Button struct {
|
||||||
Text string
|
Text string
|
||||||
Callback func()
|
Callback func()
|
||||||
|
baseComponent
|
||||||
x, y int
|
|
||||||
width, height int
|
|
||||||
focused bool
|
|
||||||
|
|
||||||
Theme *Theme
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewButton(text string, theme *Theme, callback func()) *Button {
|
func NewButton(text string, theme *Theme, callback func()) *Button {
|
||||||
return &Button{
|
return &Button{
|
||||||
Text: text,
|
text,
|
||||||
Callback: callback,
|
callback,
|
||||||
Theme: theme,
|
baseComponent{theme: theme},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,23 +27,7 @@ func (b *Button) Draw(s tcell.Screen) {
|
|||||||
} else {
|
} else {
|
||||||
str = fmt.Sprintf(" %s ", b.Text)
|
str = fmt.Sprintf(" %s ", b.Text)
|
||||||
}
|
}
|
||||||
DrawStr(s, b.x, b.y, str, b.Theme.GetOrDefault("Button"))
|
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Button) GetMinSize() (int, int) {
|
func (b *Button) GetMinSize() (int, int) {
|
||||||
|
@ -23,17 +23,60 @@ type Component interface {
|
|||||||
SetTheme(*Theme)
|
SetTheme(*Theme)
|
||||||
|
|
||||||
// Get position of the Component.
|
// Get position of the Component.
|
||||||
GetPos() (int, int)
|
GetPos() (x, y int)
|
||||||
// Set position of the Component.
|
// Set position of the Component.
|
||||||
SetPos(int, int)
|
SetPos(x, y int)
|
||||||
|
|
||||||
// Returns the smallest size the Component can be.
|
// Returns the smallest size the Component can be.
|
||||||
GetMinSize() (int, int)
|
GetMinSize() (w, h int)
|
||||||
// Get size of the Component.
|
// 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
|
// Set size of the component. If size is smaller than minimum, minimum is
|
||||||
// used, instead.
|
// 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
|
||||||
}
|
}
|
||||||
|
@ -9,14 +9,9 @@ import (
|
|||||||
// A FileSelectorDialog is a WindowContainer with an input and buttons for selecting files.
|
// 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).
|
// It can be used to open zero or more existing files, or select one non-existant file (for saving).
|
||||||
type FileSelectorDialog struct {
|
type FileSelectorDialog struct {
|
||||||
|
Title string
|
||||||
MustExist bool // Whether the dialog should have a user select an existing file.
|
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.
|
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
|
tabOrder []Component
|
||||||
tabOrderIdx int
|
tabOrderIdx int
|
||||||
@ -24,14 +19,17 @@ type FileSelectorDialog struct {
|
|||||||
inputField *InputField
|
inputField *InputField
|
||||||
confirmButton *Button
|
confirmButton *Button
|
||||||
cancelButton *Button
|
cancelButton *Button
|
||||||
|
|
||||||
|
baseComponent
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFileSelectorDialog(screen *tcell.Screen, title string, mustExist bool, theme *Theme, filesChosenCallback func([]string), cancelCallback func()) *FileSelectorDialog {
|
func NewFileSelectorDialog(screen *tcell.Screen, title string, mustExist bool, theme *Theme, filesChosenCallback func([]string), cancelCallback func()) *FileSelectorDialog {
|
||||||
dialog := &FileSelectorDialog{
|
dialog := &FileSelectorDialog{
|
||||||
|
Title: title,
|
||||||
MustExist: mustExist,
|
MustExist: mustExist,
|
||||||
FilesChosenCallback: filesChosenCallback,
|
FilesChosenCallback: filesChosenCallback,
|
||||||
Theme: theme,
|
|
||||||
title: title,
|
baseComponent: baseComponent{theme: theme},
|
||||||
}
|
}
|
||||||
|
|
||||||
dialog.inputField = NewInputField(screen, []byte{}, theme.GetOrDefault("Window")) // Use window's theme for InputField
|
dialog.inputField = NewInputField(screen, []byte{}, theme.GetOrDefault("Window")) // Use window's theme for InputField
|
||||||
@ -57,12 +55,8 @@ func (d *FileSelectorDialog) SetCancelCallback(callback func()) {
|
|||||||
d.cancelButton.Callback = callback
|
d.cancelButton.Callback = callback
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *FileSelectorDialog) SetTitle(title string) {
|
|
||||||
d.title = title
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *FileSelectorDialog) Draw(s tcell.Screen) {
|
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() )
|
// Update positions of child components (dependent on size information that may not be available at SetPos() )
|
||||||
btnWidth, _ := d.confirmButton.GetSize()
|
btnWidth, _ := d.confirmButton.GetSize()
|
||||||
@ -79,16 +73,12 @@ func (d *FileSelectorDialog) SetFocused(v bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *FileSelectorDialog) SetTheme(theme *Theme) {
|
func (d *FileSelectorDialog) SetTheme(theme *Theme) {
|
||||||
d.Theme = theme
|
d.theme = theme
|
||||||
d.inputField.SetStyle(theme.GetOrDefault("Window"))
|
d.inputField.SetStyle(theme.GetOrDefault("Window"))
|
||||||
d.confirmButton.SetTheme(theme)
|
d.confirmButton.SetTheme(theme)
|
||||||
d.cancelButton.SetTheme(theme)
|
d.cancelButton.SetTheme(theme)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *FileSelectorDialog) GetPos() (int, int) {
|
|
||||||
return d.x, d.y
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *FileSelectorDialog) SetPos(x, y int) {
|
func (d *FileSelectorDialog) SetPos(x, y int) {
|
||||||
d.x, d.y = x, y
|
d.x, d.y = x, y
|
||||||
d.inputField.SetPos(d.x+1, d.y+2) // Center input field
|
d.inputField.SetPos(d.x+1, d.y+2) // Center input field
|
||||||
@ -96,11 +86,7 @@ func (d *FileSelectorDialog) SetPos(x, y int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *FileSelectorDialog) GetMinSize() (int, int) {
|
func (d *FileSelectorDialog) GetMinSize() (int, int) {
|
||||||
return Max(len(d.title), 8) + 2, 6
|
return Max(len(d.Title), 8) + 2, 6
|
||||||
}
|
|
||||||
|
|
||||||
func (d *FileSelectorDialog) GetSize() (int, int) {
|
|
||||||
return d.width, d.height
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *FileSelectorDialog) SetSize(width, height int) {
|
func (d *FileSelectorDialog) SetSize(width, height int) {
|
||||||
|
@ -12,11 +12,10 @@ type InputField struct {
|
|||||||
|
|
||||||
cursorPos int
|
cursorPos int
|
||||||
scrollPos int
|
scrollPos int
|
||||||
x, y int
|
|
||||||
width, height int
|
|
||||||
focused bool
|
|
||||||
screen *tcell.Screen
|
screen *tcell.Screen
|
||||||
style tcell.Style
|
style tcell.Style
|
||||||
|
|
||||||
|
baseComponent
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewInputField(screen *tcell.Screen, placeholder []byte, style tcell.Style) *InputField {
|
func NewInputField(screen *tcell.Screen, placeholder []byte, style tcell.Style) *InputField {
|
||||||
@ -157,28 +156,6 @@ func (f *InputField) SetStyle(style tcell.Style) {
|
|||||||
f.style = 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 {
|
func (f *InputField) HandleEvent(event tcell.Event) bool {
|
||||||
switch ev := event.(type) {
|
switch ev := event.(type) {
|
||||||
case *tcell.EventKey:
|
case *tcell.EventKey:
|
||||||
|
@ -19,7 +19,7 @@ const (
|
|||||||
// bounding box and allows for left-align, right-align, and justify.
|
// bounding box and allows for left-align, right-align, and justify.
|
||||||
type Label struct {
|
type Label struct {
|
||||||
Text string
|
Text string
|
||||||
x, y int
|
|
||||||
width, height int
|
|
||||||
Alignment Align
|
Alignment Align
|
||||||
|
|
||||||
|
baseComponent
|
||||||
}
|
}
|
||||||
|
68
ui/menu.go
68
ui/menu.go
@ -74,19 +74,15 @@ func (m *Menu) GetShortcut() string {
|
|||||||
// A MenuBar is a horizontal list of menus.
|
// A MenuBar is a horizontal list of menus.
|
||||||
type MenuBar struct {
|
type MenuBar struct {
|
||||||
menus []*Menu
|
menus []*Menu
|
||||||
x, y int
|
|
||||||
width, height int
|
|
||||||
focused bool
|
|
||||||
selected int // Index of selection in MenuBar
|
selected int // Index of selection in MenuBar
|
||||||
menusVisible bool // Whether to draw the selected menu
|
menusVisible bool // Whether to draw the selected menu
|
||||||
|
baseComponent
|
||||||
Theme *Theme
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMenuBar(theme *Theme) *MenuBar {
|
func NewMenuBar(theme *Theme) *MenuBar {
|
||||||
return &MenuBar{
|
return &MenuBar{
|
||||||
menus: make([]*Menu, 0, 6),
|
menus: make([]*Menu, 0, 6),
|
||||||
Theme: theme,
|
baseComponent: baseComponent{theme: theme},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,7 +148,7 @@ func (b *MenuBar) CursorRight() {
|
|||||||
|
|
||||||
// Draw renders the MenuBar and its sub-menus.
|
// Draw renders the MenuBar and its sub-menus.
|
||||||
func (b *MenuBar) Draw(s tcell.Screen) {
|
func (b *MenuBar) Draw(s tcell.Screen) {
|
||||||
normalStyle := b.Theme.GetOrDefault("MenuBar")
|
normalStyle := b.theme.GetOrDefault("MenuBar")
|
||||||
|
|
||||||
// Draw menus based on whether b.focused and which is selected
|
// Draw menus based on whether b.focused and which is selected
|
||||||
DrawRect(s, b.x, b.y, b.width, 1, ' ', normalStyle)
|
DrawRect(s, b.x, b.y, b.width, 1, ' ', normalStyle)
|
||||||
@ -160,7 +156,7 @@ func (b *MenuBar) Draw(s tcell.Screen) {
|
|||||||
for i, item := range b.menus {
|
for i, item := range b.menus {
|
||||||
sty := normalStyle
|
sty := normalStyle
|
||||||
if b.focused && b.selected == i {
|
if b.focused && b.selected == i {
|
||||||
sty = b.Theme.GetOrDefault("MenuBarSelected") // Use special style for selected item
|
sty = b.theme.GetOrDefault("MenuBarSelected") // Use special style for selected item
|
||||||
}
|
}
|
||||||
|
|
||||||
str := fmt.Sprintf(" %s ", item.Name)
|
str := fmt.Sprintf(" %s ", item.Name)
|
||||||
@ -187,34 +183,10 @@ func (b *MenuBar) SetFocused(v bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *MenuBar) SetTheme(theme *Theme) {
|
|
||||||
b.Theme = theme
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetPos returns the position of the MenuBar.
|
|
||||||
func (b *MenuBar) GetPos() (int, int) {
|
|
||||||
return b.x, b.y
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetPos sets the position of the MenuBar.
|
|
||||||
func (b *MenuBar) SetPos(x, y int) {
|
|
||||||
b.x, b.y = x, y
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *MenuBar) GetMinSize() (int, int) {
|
func (b *MenuBar) GetMinSize() (int, int) {
|
||||||
return 0, 1
|
return 0, 1
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSize returns the size of the MenuBar.
|
|
||||||
func (b *MenuBar) GetSize() (int, int) {
|
|
||||||
return b.width, b.height
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetSize sets the size of the MenuBar.
|
|
||||||
func (b *MenuBar) SetSize(width, height int) {
|
|
||||||
b.width, b.height = width, height
|
|
||||||
}
|
|
||||||
|
|
||||||
// HandleEvent will propogate events to sub-menus and returns true if
|
// HandleEvent will propogate events to sub-menus and returns true if
|
||||||
// any of them handled the event.
|
// any of them handled the event.
|
||||||
func (b *MenuBar) HandleEvent(event tcell.Event) bool {
|
func (b *MenuBar) HandleEvent(event tcell.Event) bool {
|
||||||
@ -288,12 +260,10 @@ type Menu struct {
|
|||||||
QuickChar int // Character/rune index of Name
|
QuickChar int // Character/rune index of Name
|
||||||
Items []Item
|
Items []Item
|
||||||
|
|
||||||
x, y int
|
|
||||||
width, height int // Size may not be settable
|
|
||||||
selected int // Index of selected Item
|
selected int // Index of selected Item
|
||||||
itemSelectedCallback func() // Used internally to hide menus on selection
|
itemSelectedCallback func() // Used internally to hide menus on selection
|
||||||
|
|
||||||
Theme *Theme
|
baseComponent
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new Menu. `items` can be `nil`.
|
// New creates a new Menu. `items` can be `nil`.
|
||||||
@ -302,7 +272,8 @@ func NewMenu(name string, quickChar int, theme *Theme) *Menu {
|
|||||||
Name: name,
|
Name: name,
|
||||||
QuickChar: quickChar,
|
QuickChar: quickChar,
|
||||||
Items: make([]Item, 0, 6),
|
Items: make([]Item, 0, 6),
|
||||||
Theme: theme,
|
|
||||||
|
baseComponent: baseComponent{theme: theme},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -360,7 +331,7 @@ func (m *Menu) CursorDown() {
|
|||||||
|
|
||||||
// Draw renders the Menu at its position.
|
// Draw renders the Menu at its position.
|
||||||
func (m *Menu) Draw(s tcell.Screen) {
|
func (m *Menu) Draw(s tcell.Screen) {
|
||||||
defaultStyle := m.Theme.GetOrDefault("Menu")
|
defaultStyle := m.theme.GetOrDefault("Menu")
|
||||||
|
|
||||||
m.GetSize() // Call this to update internal width and height
|
m.GetSize() // Call this to update internal width and height
|
||||||
DrawRect(s, m.x, m.y, m.width, m.height, ' ', defaultStyle) // Fill background
|
DrawRect(s, m.x, m.y, m.width, m.height, ' ', defaultStyle) // Fill background
|
||||||
@ -375,7 +346,7 @@ func (m *Menu) Draw(s tcell.Screen) {
|
|||||||
default: // Handle sub-menus and item entries the same
|
default: // Handle sub-menus and item entries the same
|
||||||
var sty tcell.Style
|
var sty tcell.Style
|
||||||
if m.selected == i {
|
if m.selected == i {
|
||||||
sty = m.Theme.GetOrDefault("MenuSelected")
|
sty = m.theme.GetOrDefault("MenuSelected")
|
||||||
} else {
|
} else {
|
||||||
sty = defaultStyle
|
sty = defaultStyle
|
||||||
}
|
}
|
||||||
@ -401,23 +372,7 @@ func (m *Menu) SetFocused(v bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPos returns the position of the Menu.
|
|
||||||
func (m *Menu) GetPos() (int, int) {
|
|
||||||
return m.x, m.y
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetPos sets the position of the Menu.
|
|
||||||
func (m *Menu) SetPos(x, y int) {
|
|
||||||
m.x, m.y = x, y
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Menu) GetMinSize() (int, int) {
|
func (m *Menu) GetMinSize() (int, int) {
|
||||||
return m.GetSize()
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetSize returns the size of the Menu.
|
|
||||||
func (m *Menu) GetSize() (int, int) {
|
|
||||||
// TODO: no, pls don't do this
|
|
||||||
maxNameLen := 0
|
maxNameLen := 0
|
||||||
var widestShortcut int = 0 // Will contribute to the width
|
var widestShortcut int = 0 // Will contribute to the width
|
||||||
for i := range m.Items {
|
for i := range m.Items {
|
||||||
@ -441,6 +396,11 @@ func (m *Menu) GetSize() (int, int) {
|
|||||||
return m.width, m.height
|
return m.width, m.height
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetSize returns the size of the Menu.
|
||||||
|
func (m *Menu) GetSize() (int, int) {
|
||||||
|
return m.GetMinSize()
|
||||||
|
}
|
||||||
|
|
||||||
// SetSize sets the size of the Menu.
|
// SetSize sets the size of the Menu.
|
||||||
func (m *Menu) SetSize(width, height int) {
|
func (m *Menu) SetSize(width, height int) {
|
||||||
// Cannot set the size of a Menu
|
// Cannot set the size of a Menu
|
||||||
|
@ -30,13 +30,10 @@ type MessageDialog struct {
|
|||||||
message string
|
message string
|
||||||
messageWrapped string
|
messageWrapped string
|
||||||
|
|
||||||
x, y int
|
|
||||||
width, height int
|
|
||||||
focused bool
|
|
||||||
theme *Theme
|
|
||||||
|
|
||||||
buttons []*Button
|
buttons []*Button
|
||||||
selectedIdx int
|
selectedIdx int
|
||||||
|
|
||||||
|
baseComponent
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMessageDialog(title string, message string, kind MessageDialogKind, options []string, theme *Theme, callback func(string)) *MessageDialog {
|
func NewMessageDialog(title string, message string, kind MessageDialogKind, options []string, theme *Theme, callback func(string)) *MessageDialog {
|
||||||
@ -53,7 +50,7 @@ func NewMessageDialog(title string, message string, kind MessageDialogKind, opti
|
|||||||
Kind: kind,
|
Kind: kind,
|
||||||
Callback: callback,
|
Callback: callback,
|
||||||
|
|
||||||
theme: theme,
|
baseComponent: baseComponent{theme: theme},
|
||||||
}
|
}
|
||||||
|
|
||||||
dialog.buttons = make([]*Button, len(options))
|
dialog.buttons = make([]*Button, len(options))
|
||||||
@ -107,24 +104,12 @@ func (d *MessageDialog) SetTheme(theme *Theme) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *MessageDialog) GetPos() (int, int) {
|
|
||||||
return d.x, d.y
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *MessageDialog) SetPos(x, y int) {
|
|
||||||
d.x, d.y = x, y
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *MessageDialog) GetMinSize() (int, int) {
|
func (d *MessageDialog) GetMinSize() (int, int) {
|
||||||
lines := strings.Count(d.messageWrapped, "\n") + 1
|
lines := strings.Count(d.messageWrapped, "\n") + 1
|
||||||
|
|
||||||
return Max(len(d.Title)+2, 30), 2 + lines + 2
|
return Max(len(d.Title)+2, 30), 2 + lines + 2
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *MessageDialog) GetSize() (int, int) {
|
|
||||||
return d.width, d.height
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *MessageDialog) SetSize(width, height int) {
|
func (d *MessageDialog) SetSize(width, height int) {
|
||||||
minWidth, minHeight := d.GetMinSize()
|
minWidth, minHeight := d.GetMinSize()
|
||||||
d.width, d.height = Max(width, minWidth), Max(height, minHeight)
|
d.width, d.height = Max(width, minWidth), Max(height, minHeight)
|
||||||
|
@ -15,18 +15,15 @@ type Tab struct {
|
|||||||
// A TabContainer organizes children by showing only one of them at a time.
|
// A TabContainer organizes children by showing only one of them at a time.
|
||||||
type TabContainer struct {
|
type TabContainer struct {
|
||||||
children []Tab
|
children []Tab
|
||||||
x, y int
|
|
||||||
width, height int
|
|
||||||
focused bool
|
|
||||||
selected int
|
selected int
|
||||||
|
|
||||||
Theme *Theme
|
baseComponent
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTabContainer(theme *Theme) *TabContainer {
|
func NewTabContainer(theme *Theme) *TabContainer {
|
||||||
return &TabContainer{
|
return &TabContainer{
|
||||||
children: make([]Tab, 0, 4),
|
children: make([]Tab, 0, 4),
|
||||||
Theme: theme,
|
baseComponent: baseComponent{theme: theme},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,7 +87,7 @@ func (c *TabContainer) GetTab(idx int) *Tab {
|
|||||||
// Draw will draws the border of the BoxContainer, then it draws its child component.
|
// Draw will draws the border of the BoxContainer, then it draws its child component.
|
||||||
func (c *TabContainer) Draw(s tcell.Screen) {
|
func (c *TabContainer) Draw(s tcell.Screen) {
|
||||||
// Draw outline
|
// Draw outline
|
||||||
DrawRectOutlineDefault(s, c.x, c.y, c.width, c.height, c.Theme.GetOrDefault("TabContainer"))
|
DrawRectOutlineDefault(s, c.x, c.y, c.width, c.height, c.theme.GetOrDefault("TabContainer"))
|
||||||
|
|
||||||
combinedTabLength := 0
|
combinedTabLength := 0
|
||||||
for _, tab := range c.children {
|
for _, tab := range c.children {
|
||||||
@ -103,9 +100,9 @@ func (c *TabContainer) Draw(s tcell.Screen) {
|
|||||||
for i, tab := range c.children {
|
for i, tab := range c.children {
|
||||||
var sty tcell.Style
|
var sty tcell.Style
|
||||||
if c.selected == i {
|
if c.selected == i {
|
||||||
sty = c.Theme.GetOrDefault("TabSelected")
|
sty = c.theme.GetOrDefault("TabSelected")
|
||||||
} else {
|
} else {
|
||||||
sty = c.Theme.GetOrDefault("Tab")
|
sty = c.theme.GetOrDefault("Tab")
|
||||||
}
|
}
|
||||||
|
|
||||||
var dirty bool
|
var dirty bool
|
||||||
@ -141,21 +138,12 @@ func (c *TabContainer) SetFocused(v bool) {
|
|||||||
|
|
||||||
// SetTheme sets the theme.
|
// SetTheme sets the theme.
|
||||||
func (c *TabContainer) SetTheme(theme *Theme) {
|
func (c *TabContainer) SetTheme(theme *Theme) {
|
||||||
c.Theme = theme
|
c.theme = theme
|
||||||
for _, tab := range c.children {
|
for _, tab := range c.children {
|
||||||
tab.Child.SetTheme(theme) // Update the theme for all children
|
tab.Child.SetTheme(theme) // Update the theme for all children
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *TabContainer) GetMinSize() (int, int) {
|
|
||||||
return 0, 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetPos returns the position of the container.
|
|
||||||
func (c *TabContainer) GetPos() (int, int) {
|
|
||||||
return c.x, c.y
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetPos sets the position of the container and updates the child Component.
|
// SetPos sets the position of the container and updates the child Component.
|
||||||
func (c *TabContainer) SetPos(x, y int) {
|
func (c *TabContainer) SetPos(x, y int) {
|
||||||
c.x, c.y = x, y
|
c.x, c.y = x, y
|
||||||
@ -164,11 +152,6 @@ func (c *TabContainer) SetPos(x, y int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSize gets the size of the container.
|
|
||||||
func (c *TabContainer) GetSize() (int, int) {
|
|
||||||
return c.width, c.height
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetSize sets the size of the container and updates the size of the child Component.
|
// SetSize sets the size of the container and updates the size of the child Component.
|
||||||
func (c *TabContainer) SetSize(width, height int) {
|
func (c *TabContainer) SetSize(width, height int) {
|
||||||
c.width, c.height = width, height
|
c.width, c.height = width, height
|
||||||
|
@ -39,9 +39,6 @@ type TextEdit struct {
|
|||||||
FilePath string // Will be empty if the file has not been saved yet
|
FilePath string // Will be empty if the file has not been saved yet
|
||||||
|
|
||||||
screen *tcell.Screen // We keep our own reference to the screen for cursor purposes.
|
screen *tcell.Screen // We keep our own reference to the screen for cursor purposes.
|
||||||
x, y int
|
|
||||||
width, height int
|
|
||||||
focused bool
|
|
||||||
curx, cury int // Zero-based: cursor points before the character at that position.
|
curx, cury int // Zero-based: cursor points before the character at that position.
|
||||||
prevCurCol int // Previous maximum column the cursor was at, when the user pressed left or right
|
prevCurCol int // Previous maximum column the cursor was at, when the user pressed left or right
|
||||||
scrollx, scrolly int // X and Y offset of view, known as scroll
|
scrollx, scrolly int // X and Y offset of view, known as scroll
|
||||||
@ -49,7 +46,7 @@ type TextEdit struct {
|
|||||||
selection Region // Selection: selectMode determines if it should be used
|
selection Region // Selection: selectMode determines if it should be used
|
||||||
selectMode bool // Whether the user is actively selecting text
|
selectMode bool // Whether the user is actively selecting text
|
||||||
|
|
||||||
Theme *Theme
|
baseComponent
|
||||||
}
|
}
|
||||||
|
|
||||||
// New will initialize the buffer using the given 'contents'. If the 'filePath' or 'FilePath' is empty,
|
// New will initialize the buffer using the given 'contents'. If the 'filePath' or 'FilePath' is empty,
|
||||||
@ -62,8 +59,9 @@ func NewTextEdit(screen *tcell.Screen, filePath string, contents []byte, theme *
|
|||||||
UseHardTabs: true,
|
UseHardTabs: true,
|
||||||
TabSize: 4,
|
TabSize: 4,
|
||||||
FilePath: filePath,
|
FilePath: filePath,
|
||||||
screen: screen,
|
|
||||||
Theme: theme,
|
screen: screen,
|
||||||
|
baseComponent: baseComponent{theme: theme},
|
||||||
}
|
}
|
||||||
te.SetContents(contents)
|
te.SetContents(contents)
|
||||||
return te
|
return te
|
||||||
@ -383,8 +381,8 @@ func (t *TextEdit) Draw(s tcell.Screen) {
|
|||||||
columnWidth := t.getColumnWidth()
|
columnWidth := t.getColumnWidth()
|
||||||
bufferLines := t.Buffer.Lines()
|
bufferLines := t.Buffer.Lines()
|
||||||
|
|
||||||
selectedStyle := t.Theme.GetOrDefault("TextEditSelected")
|
selectedStyle := t.theme.GetOrDefault("TextEditSelected")
|
||||||
columnStyle := t.Theme.GetOrDefault("TextEditColumn")
|
columnStyle := t.theme.GetOrDefault("TextEditColumn")
|
||||||
|
|
||||||
t.Highlighter.UpdateInvalidatedLines(t.scrolly, t.scrolly+(t.height-1))
|
t.Highlighter.UpdateInvalidatedLines(t.scrolly, t.scrolly+(t.height-1))
|
||||||
|
|
||||||
@ -565,34 +563,6 @@ func (t *TextEdit) SetFocused(v bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TextEdit) SetTheme(theme *Theme) {
|
|
||||||
t.Theme = theme
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetPos gets the position of the TextEdit.
|
|
||||||
func (t *TextEdit) GetPos() (int, int) {
|
|
||||||
return t.x, t.y
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetPos sets the position of the TextEdit.
|
|
||||||
func (t *TextEdit) SetPos(x, y int) {
|
|
||||||
t.x, t.y = x, y
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *TextEdit) GetMinSize() (int, int) {
|
|
||||||
return 0, 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetSize gets the size of the TextEdit.
|
|
||||||
func (t *TextEdit) GetSize() (int, int) {
|
|
||||||
return t.width, t.height
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetSize sets the size of the TextEdit.
|
|
||||||
func (t *TextEdit) SetSize(width, height int) {
|
|
||||||
t.width, t.height = width, height
|
|
||||||
}
|
|
||||||
|
|
||||||
// HandleEvent allows the TextEdit to handle `event` if it chooses, returns
|
// HandleEvent allows the TextEdit to handle `event` if it chooses, returns
|
||||||
// whether the TextEdit handled the event.
|
// whether the TextEdit handled the event.
|
||||||
func (t *TextEdit) HandleEvent(event tcell.Event) bool {
|
func (t *TextEdit) HandleEvent(event tcell.Event) bool {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user