forked from tslocum/cview
parent
cc7796c4ca
commit
cdeff20296
|
@ -3,6 +3,7 @@ v1.4.8 (WIP)
|
|||
- Add Modal.GetForm and Modal.GetFrame
|
||||
- Fix Form.Clear deadlock
|
||||
- Fill nil Flex space with default background color
|
||||
- Use sync.RWMutex in all widgets
|
||||
|
||||
v1.4.7 (2020-06-09)
|
||||
- Add Box.SetBackgroundTransparent
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
This document lists architectural details of cview.
|
||||
|
||||
# Widgets always use `sync.RWMutex`
|
||||
|
||||
See [#30](https://gitlab.com/tslocum/cview/-/issues/30).
|
|
@ -29,7 +29,7 @@ type Button struct {
|
|||
// key is provided indicating which key was pressed to leave (tab or backtab).
|
||||
blur func(tcell.Key)
|
||||
|
||||
sync.Mutex
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
// NewButton returns a new input field.
|
||||
|
@ -56,8 +56,8 @@ func (b *Button) SetLabel(label string) *Button {
|
|||
|
||||
// GetLabel returns the button text.
|
||||
func (b *Button) GetLabel() string {
|
||||
b.Lock()
|
||||
defer b.Unlock()
|
||||
b.RLock()
|
||||
defer b.RUnlock()
|
||||
|
||||
return b.label
|
||||
}
|
||||
|
|
18
checkbox.go
18
checkbox.go
|
@ -46,7 +46,7 @@ type CheckBox struct {
|
|||
// this form item.
|
||||
finished func(tcell.Key)
|
||||
|
||||
sync.Mutex
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
// NewCheckBox returns a new input field.
|
||||
|
@ -70,8 +70,8 @@ func (c *CheckBox) SetChecked(checked bool) *CheckBox {
|
|||
|
||||
// IsChecked returns whether or not the box is checked.
|
||||
func (c *CheckBox) IsChecked() bool {
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
c.RLock()
|
||||
defer c.RUnlock()
|
||||
|
||||
return c.checked
|
||||
}
|
||||
|
@ -87,8 +87,8 @@ func (c *CheckBox) SetLabel(label string) *CheckBox {
|
|||
|
||||
// GetLabel returns the text to be displayed before the input area.
|
||||
func (c *CheckBox) GetLabel() string {
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
c.RLock()
|
||||
defer c.RUnlock()
|
||||
|
||||
return c.label
|
||||
}
|
||||
|
@ -104,8 +104,8 @@ func (c *CheckBox) SetMessage(message string) *CheckBox {
|
|||
|
||||
// GetMessage returns the text to be displayed after the checkbox
|
||||
func (c *CheckBox) GetMessage() string {
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
c.RLock()
|
||||
defer c.RUnlock()
|
||||
|
||||
return c.message
|
||||
}
|
||||
|
@ -162,8 +162,8 @@ func (c *CheckBox) SetFormAttributes(labelWidth int, labelColor, bgColor, fieldT
|
|||
|
||||
// GetFieldWidth returns this primitive's field width.
|
||||
func (c *CheckBox) GetFieldWidth() int {
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
c.RLock()
|
||||
defer c.RUnlock()
|
||||
|
||||
if c.message == "" {
|
||||
return 1
|
||||
|
|
6
flex.go
6
flex.go
|
@ -37,7 +37,7 @@ type Flex struct {
|
|||
// instead its box dimensions.
|
||||
fullScreen bool
|
||||
|
||||
sync.Mutex
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
// NewFlex returns a new flexbox layout container with no primitives and its
|
||||
|
@ -217,8 +217,8 @@ func (f *Flex) Focus(delegate func(p Primitive)) {
|
|||
|
||||
// HasFocus returns whether or not this primitive has focus.
|
||||
func (f *Flex) HasFocus() bool {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.RLock()
|
||||
defer f.RUnlock()
|
||||
|
||||
for _, item := range f.items {
|
||||
if item.Item != nil && item.Item.GetFocusable().HasFocus() {
|
||||
|
|
34
form.go
34
form.go
|
@ -84,7 +84,7 @@ type Form struct {
|
|||
// An optional function which is called when the user hits Escape.
|
||||
cancel func()
|
||||
|
||||
sync.Mutex
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
// NewForm returns a new form.
|
||||
|
@ -285,8 +285,8 @@ func (f *Form) AddButton(label string, selected func()) *Form {
|
|||
// buttons have been specially prepared for this form and modifying some of
|
||||
// their attributes may have unintended side effects.
|
||||
func (f *Form) GetButton(index int) *Button {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.RLock()
|
||||
defer f.RUnlock()
|
||||
|
||||
return f.buttons[index]
|
||||
}
|
||||
|
@ -303,8 +303,8 @@ func (f *Form) RemoveButton(index int) *Form {
|
|||
|
||||
// GetButtonCount returns the number of buttons in this form.
|
||||
func (f *Form) GetButtonCount() int {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.RLock()
|
||||
defer f.RUnlock()
|
||||
|
||||
return len(f.buttons)
|
||||
}
|
||||
|
@ -313,8 +313,8 @@ func (f *Form) GetButtonCount() int {
|
|||
// with 0 for the button that was added first. If no such label was found, -1
|
||||
// is returned.
|
||||
func (f *Form) GetButtonIndex(label string) int {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.RLock()
|
||||
defer f.RUnlock()
|
||||
|
||||
for index, button := range f.buttons {
|
||||
if button.GetLabel() == label {
|
||||
|
@ -368,8 +368,8 @@ func (f *Form) AddFormItem(item FormItem) *Form {
|
|||
// GetFormItemCount returns the number of items in the form (not including the
|
||||
// buttons).
|
||||
func (f *Form) GetFormItemCount() int {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.RLock()
|
||||
defer f.RUnlock()
|
||||
|
||||
return len(f.items)
|
||||
}
|
||||
|
@ -378,8 +378,8 @@ func (f *Form) GetFormItemCount() int {
|
|||
// 0. Elements are referenced in the order they were added. Buttons are not
|
||||
// included.
|
||||
func (f *Form) GetFormItem(index int) FormItem {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.RLock()
|
||||
defer f.RUnlock()
|
||||
|
||||
return f.items[index]
|
||||
}
|
||||
|
@ -399,8 +399,8 @@ func (f *Form) RemoveFormItem(index int) *Form {
|
|||
// no such element is found, nil is returned. Buttons are not searched and will
|
||||
// therefore not be returned.
|
||||
func (f *Form) GetFormItemByLabel(label string) FormItem {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.RLock()
|
||||
defer f.RUnlock()
|
||||
|
||||
for _, item := range f.items {
|
||||
if item.GetLabel() == label {
|
||||
|
@ -414,8 +414,8 @@ func (f *Form) GetFormItemByLabel(label string) FormItem {
|
|||
// label. If no such element is found, -1 is returned. Buttons are not searched
|
||||
// and will therefore not be returned.
|
||||
func (f *Form) GetFormItemIndex(label string) int {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.RLock()
|
||||
defer f.RUnlock()
|
||||
|
||||
for index, item := range f.items {
|
||||
if item.GetLabel() == label {
|
||||
|
@ -428,8 +428,8 @@ func (f *Form) GetFormItemIndex(label string) int {
|
|||
// GetFocusedItemIndex returns the indices of the form element or button which
|
||||
// currently has focus. If they don't, -1 is returned resepectively.
|
||||
func (f *Form) GetFocusedItemIndex() (formItem, button int) {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.RLock()
|
||||
defer f.RUnlock()
|
||||
|
||||
index := f.focusIndex()
|
||||
if index < 0 {
|
||||
|
|
6
frame.go
6
frame.go
|
@ -28,7 +28,7 @@ type Frame struct {
|
|||
// Border spacing.
|
||||
top, bottom, header, footer, left, right int
|
||||
|
||||
sync.Mutex
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
// NewFrame returns a new frame around the given primitive. The primitive's
|
||||
|
@ -167,8 +167,8 @@ func (f *Frame) Focus(delegate func(p Primitive)) {
|
|||
|
||||
// HasFocus returns whether or not this primitive has focus.
|
||||
func (f *Frame) HasFocus() bool {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.RLock()
|
||||
defer f.RUnlock()
|
||||
|
||||
focusable, ok := f.primitive.(Focusable)
|
||||
if ok {
|
||||
|
|
3
go.mod
3
go.mod
|
@ -8,5 +8,6 @@ require (
|
|||
github.com/mattn/go-runewidth v0.0.9
|
||||
github.com/rivo/uniseg v0.1.0
|
||||
gitlab.com/tslocum/cbind v0.1.1
|
||||
golang.org/x/sys v0.0.0-20200610111108-226ff32320da // indirect
|
||||
golang.org/x/sys v0.0.0-20200802091954-4b90ce9b60b3 // indirect
|
||||
golang.org/x/text v0.3.3 // indirect
|
||||
)
|
||||
|
|
6
go.sum
6
go.sum
|
@ -23,11 +23,13 @@ gitlab.com/tslocum/cbind v0.1.1/go.mod h1:rX7vkl0pUSg/yy427MmD1FZAf99S7WwpUlxF/q
|
|||
golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756 h1:9nuHUbU8dRnRRfj9KjWUVrJeoexdbeMjttk6Oh1rD10=
|
||||
golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200610111108-226ff32320da h1:bGb80FudwxpeucJUjPYJXuJ8Hk91vNtfvrymzwiei38=
|
||||
golang.org/x/sys v0.0.0-20200610111108-226ff32320da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200802091954-4b90ce9b60b3 h1:qDJKu1y/1SjhWac4BQZjLljqvqiWUhjmDMnonmVGDAU=
|
||||
golang.org/x/sys v0.0.0-20200802091954-4b90ce9b60b3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e h1:FDhOuMEY4JVRztM/gsbk+IKUQ8kj74bxZrgw87eMMVc=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
|
|
10
grid.go
10
grid.go
|
@ -56,7 +56,7 @@ type Grid struct {
|
|||
// The color of the borders around grid items.
|
||||
bordersColor tcell.Color
|
||||
|
||||
sync.Mutex
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
// NewGrid returns a new grid-based layout container with no initial primitives.
|
||||
|
@ -272,8 +272,8 @@ func (g *Grid) SetOffset(rows, columns int) *Grid {
|
|||
// GetOffset returns the current row and column offset (see SetOffset() for
|
||||
// details).
|
||||
func (g *Grid) GetOffset() (rows, columns int) {
|
||||
g.Lock()
|
||||
defer g.Unlock()
|
||||
g.RLock()
|
||||
defer g.RUnlock()
|
||||
|
||||
return g.rowOffset, g.columnOffset
|
||||
}
|
||||
|
@ -306,8 +306,8 @@ func (g *Grid) Blur() {
|
|||
|
||||
// HasFocus returns whether or not this primitive has focus.
|
||||
func (g *Grid) HasFocus() bool {
|
||||
g.Lock()
|
||||
defer g.Unlock()
|
||||
g.RLock()
|
||||
defer g.RUnlock()
|
||||
|
||||
for _, item := range g.items {
|
||||
if item.visible && item.Item.GetFocusable().HasFocus() {
|
||||
|
|
15
modal.go
15
modal.go
|
@ -31,7 +31,7 @@ type Modal struct {
|
|||
// receives the index of the clicked button and the button's label.
|
||||
done func(buttonIndex int, buttonLabel string)
|
||||
|
||||
sync.Mutex
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
// NewModal returns a new centered message window.
|
||||
|
@ -121,16 +121,16 @@ func (m *Modal) SetText(text string) *Modal {
|
|||
// GetForm returns the Form embedded in the window. The returned Form may be
|
||||
// modified to include additional elements (e.g. AddInputField, AddFormItem).
|
||||
func (m *Modal) GetForm() *Form {
|
||||
m.Lock()
|
||||
defer m.Unlock()
|
||||
m.RLock()
|
||||
defer m.RUnlock()
|
||||
|
||||
return m.form
|
||||
}
|
||||
|
||||
// GetFrame returns the Frame embedded in the window.
|
||||
func (m *Modal) GetFrame() *Frame {
|
||||
m.Lock()
|
||||
defer m.Unlock()
|
||||
m.RLock()
|
||||
defer m.RUnlock()
|
||||
|
||||
return m.frame
|
||||
}
|
||||
|
@ -188,10 +188,7 @@ func (m *Modal) Focus(delegate func(p Primitive)) {
|
|||
|
||||
// HasFocus returns whether or not this primitive has focus.
|
||||
func (m *Modal) HasFocus() bool {
|
||||
m.Lock()
|
||||
defer m.Unlock()
|
||||
|
||||
return m.form.HasFocus()
|
||||
return m.GetForm().HasFocus()
|
||||
}
|
||||
|
||||
// Draw draws this primitive onto the screen.
|
||||
|
|
18
pages.go
18
pages.go
|
@ -31,7 +31,7 @@ type Pages struct {
|
|||
// pages changes.
|
||||
changed func()
|
||||
|
||||
sync.Mutex
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
// NewPages returns a new Pages object.
|
||||
|
@ -55,8 +55,8 @@ func (p *Pages) SetChangedFunc(handler func()) *Pages {
|
|||
|
||||
// GetPageCount returns the number of pages currently stored in this object.
|
||||
func (p *Pages) GetPageCount() int {
|
||||
p.Lock()
|
||||
defer p.Unlock()
|
||||
p.RLock()
|
||||
defer p.RUnlock()
|
||||
|
||||
return len(p.pages)
|
||||
}
|
||||
|
@ -146,8 +146,8 @@ func (p *Pages) RemovePage(name string) *Pages {
|
|||
|
||||
// HasPage returns true if a page with the given name exists in this object.
|
||||
func (p *Pages) HasPage(name string) bool {
|
||||
p.Lock()
|
||||
defer p.Unlock()
|
||||
p.RLock()
|
||||
defer p.RUnlock()
|
||||
|
||||
for _, page := range p.pages {
|
||||
if page.Name == name {
|
||||
|
@ -301,8 +301,8 @@ func (p *Pages) SendToBack(name string) *Pages {
|
|||
// GetFrontPage returns the front-most visible page. If there are no visible
|
||||
// pages, ("", nil) is returned.
|
||||
func (p *Pages) GetFrontPage() (name string, item Primitive) {
|
||||
p.Lock()
|
||||
defer p.Unlock()
|
||||
p.RLock()
|
||||
defer p.RUnlock()
|
||||
|
||||
for index := len(p.pages) - 1; index >= 0; index-- {
|
||||
if p.pages[index].Visible {
|
||||
|
@ -314,8 +314,8 @@ func (p *Pages) GetFrontPage() (name string, item Primitive) {
|
|||
|
||||
// HasFocus returns whether or not this primitive has focus.
|
||||
func (p *Pages) HasFocus() bool {
|
||||
p.Lock()
|
||||
defer p.Unlock()
|
||||
p.RLock()
|
||||
defer p.RUnlock()
|
||||
|
||||
for _, page := range p.pages {
|
||||
if page.Item.GetFocusable().HasFocus() {
|
||||
|
|
|
@ -33,7 +33,7 @@ type ProgressBar struct {
|
|||
// Progress required to fill the bar.
|
||||
max int
|
||||
|
||||
sync.Mutex
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
// NewProgressBar returns a new progress bar.
|
||||
|
@ -98,8 +98,8 @@ func (p *ProgressBar) SetMax(max int) {
|
|||
|
||||
// GetMax returns the progress required to fill the bar.
|
||||
func (p *ProgressBar) GetMax() int {
|
||||
p.Lock()
|
||||
defer p.Unlock()
|
||||
p.RLock()
|
||||
defer p.RUnlock()
|
||||
|
||||
return p.max
|
||||
}
|
||||
|
@ -122,16 +122,16 @@ func (p *ProgressBar) SetProgress(progress int) {
|
|||
|
||||
// GetProgress gets the current progress.
|
||||
func (p *ProgressBar) GetProgress() int {
|
||||
p.Lock()
|
||||
defer p.Unlock()
|
||||
p.RLock()
|
||||
defer p.RUnlock()
|
||||
|
||||
return p.progress
|
||||
}
|
||||
|
||||
// Complete returns whether the progress bar has been filled.
|
||||
func (p *ProgressBar) Complete() bool {
|
||||
p.Lock()
|
||||
defer p.Unlock()
|
||||
p.RLock()
|
||||
defer p.RUnlock()
|
||||
|
||||
return p.progress >= p.max
|
||||
}
|
||||
|
|
36
table.go
36
table.go
|
@ -46,7 +46,7 @@ type TableCell struct {
|
|||
// The position and width of the cell the last time table was drawn.
|
||||
x, y, width int
|
||||
|
||||
sync.Mutex
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
// NewTableCell returns a new table cell with sensible defaults. That is, left
|
||||
|
@ -178,8 +178,8 @@ func (c *TableCell) SetReference(reference interface{}) *TableCell {
|
|||
|
||||
// GetReference returns this cell's reference object.
|
||||
func (c *TableCell) GetReference() interface{} {
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
c.RLock()
|
||||
defer c.RUnlock()
|
||||
|
||||
return c.Reference
|
||||
}
|
||||
|
@ -193,8 +193,8 @@ func (c *TableCell) GetReference() interface{} {
|
|||
// SetSelectedFunc()) or a "selectionChanged" event (see
|
||||
// SetSelectionChangedFunc()).
|
||||
func (c *TableCell) GetLastPosition() (x, y, width int) {
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
c.RLock()
|
||||
defer c.RUnlock()
|
||||
|
||||
return c.x, c.y, c.width
|
||||
}
|
||||
|
@ -319,7 +319,7 @@ type Table struct {
|
|||
// or Backtab. Also when the user presses Enter if nothing is selectable.
|
||||
done func(key tcell.Key)
|
||||
|
||||
sync.Mutex
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
// NewTable returns a new table.
|
||||
|
@ -440,8 +440,8 @@ func (t *Table) SetSelectable(rows, columns bool) *Table {
|
|||
// GetSelectable returns what can be selected in a table. Refer to
|
||||
// SetSelectable() for details.
|
||||
func (t *Table) GetSelectable() (rows, columns bool) {
|
||||
t.Lock()
|
||||
defer t.Unlock()
|
||||
t.RLock()
|
||||
defer t.RUnlock()
|
||||
|
||||
return t.rowsSelectable, t.columnsSelectable
|
||||
}
|
||||
|
@ -450,8 +450,8 @@ func (t *Table) GetSelectable() (rows, columns bool) {
|
|||
// If entire rows are selected, the column index is undefined.
|
||||
// Likewise for entire columns.
|
||||
func (t *Table) GetSelection() (row, column int) {
|
||||
t.Lock()
|
||||
defer t.Unlock()
|
||||
t.RLock()
|
||||
defer t.RUnlock()
|
||||
|
||||
return t.selectedRow, t.selectedColumn
|
||||
}
|
||||
|
@ -491,8 +491,8 @@ func (t *Table) SetOffset(row, column int) *Table {
|
|||
// GetOffset returns the current row and column offset. This indicates how many
|
||||
// rows and columns the table is scrolled down and to the right.
|
||||
func (t *Table) GetOffset() (row, column int) {
|
||||
t.Lock()
|
||||
defer t.Unlock()
|
||||
t.RLock()
|
||||
defer t.RUnlock()
|
||||
|
||||
return t.rowOffset, t.columnOffset
|
||||
}
|
||||
|
@ -588,8 +588,8 @@ func (t *Table) SetCellSimple(row, column int, text string) *Table {
|
|||
// be inserted. Therefore, repeated calls to this function may return different
|
||||
// pointers for uninitialized cells.
|
||||
func (t *Table) GetCell(row, column int) *TableCell {
|
||||
t.Lock()
|
||||
defer t.Unlock()
|
||||
t.RLock()
|
||||
defer t.RUnlock()
|
||||
|
||||
if row >= len(t.cells) || column >= len(t.cells[row]) {
|
||||
return &TableCell{}
|
||||
|
@ -665,16 +665,16 @@ func (t *Table) InsertColumn(column int) *Table {
|
|||
|
||||
// GetRowCount returns the number of rows in the table.
|
||||
func (t *Table) GetRowCount() int {
|
||||
t.Lock()
|
||||
defer t.Unlock()
|
||||
t.RLock()
|
||||
defer t.RUnlock()
|
||||
|
||||
return len(t.cells)
|
||||
}
|
||||
|
||||
// GetColumnCount returns the (maximum) number of columns in the table.
|
||||
func (t *Table) GetColumnCount() int {
|
||||
t.Lock()
|
||||
defer t.Unlock()
|
||||
t.RLock()
|
||||
defer t.RUnlock()
|
||||
|
||||
if len(t.cells) == 0 {
|
||||
return 0
|
||||
|
|
40
treeview.go
40
treeview.go
|
@ -52,7 +52,7 @@ type TreeNode struct {
|
|||
graphicsX int // The x-coordinate of the left-most graphics rune.
|
||||
textX int // The x-coordinate of the first rune of the text.
|
||||
|
||||
sync.Mutex
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
// NewTreeNode returns a new tree node.
|
||||
|
@ -113,8 +113,8 @@ func (n *TreeNode) SetReference(reference interface{}) *TreeNode {
|
|||
|
||||
// GetReference returns this node's reference object.
|
||||
func (n *TreeNode) GetReference() interface{} {
|
||||
n.Lock()
|
||||
defer n.Unlock()
|
||||
n.RLock()
|
||||
defer n.RUnlock()
|
||||
|
||||
return n.reference
|
||||
}
|
||||
|
@ -130,16 +130,16 @@ func (n *TreeNode) SetChildren(childNodes []*TreeNode) *TreeNode {
|
|||
|
||||
// GetText returns this node's text.
|
||||
func (n *TreeNode) GetText() string {
|
||||
n.Lock()
|
||||
defer n.Unlock()
|
||||
n.RLock()
|
||||
defer n.RUnlock()
|
||||
|
||||
return n.text
|
||||
}
|
||||
|
||||
// GetChildren returns this node's children.
|
||||
func (n *TreeNode) GetChildren() []*TreeNode {
|
||||
n.Lock()
|
||||
defer n.Unlock()
|
||||
n.RLock()
|
||||
defer n.RUnlock()
|
||||
|
||||
return n.children
|
||||
}
|
||||
|
@ -241,8 +241,8 @@ func (n *TreeNode) CollapseAll() *TreeNode {
|
|||
|
||||
// IsExpanded returns whether the child nodes of this node are visible.
|
||||
func (n *TreeNode) IsExpanded() bool {
|
||||
n.Lock()
|
||||
defer n.Unlock()
|
||||
n.RLock()
|
||||
defer n.RUnlock()
|
||||
|
||||
return n.expanded
|
||||
}
|
||||
|
@ -258,8 +258,8 @@ func (n *TreeNode) SetText(text string) *TreeNode {
|
|||
|
||||
// GetColor returns the node's color.
|
||||
func (n *TreeNode) GetColor() tcell.Color {
|
||||
n.Lock()
|
||||
defer n.Unlock()
|
||||
n.RLock()
|
||||
defer n.RUnlock()
|
||||
|
||||
return n.color
|
||||
}
|
||||
|
@ -363,7 +363,7 @@ type TreeView struct {
|
|||
// The visible nodes, top-down, as set by process().
|
||||
nodes []*TreeNode
|
||||
|
||||
sync.Mutex
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
// NewTreeView returns a new tree view.
|
||||
|
@ -389,8 +389,8 @@ func (t *TreeView) SetRoot(root *TreeNode) *TreeView {
|
|||
// GetRoot returns the root node of the tree. If no such node was previously
|
||||
// set, nil is returned.
|
||||
func (t *TreeView) GetRoot() *TreeNode {
|
||||
t.Lock()
|
||||
defer t.Unlock()
|
||||
t.RLock()
|
||||
defer t.RUnlock()
|
||||
|
||||
return t.root
|
||||
}
|
||||
|
@ -416,8 +416,8 @@ func (t *TreeView) SetCurrentNode(node *TreeNode) *TreeView {
|
|||
// GetCurrentNode returns the currently selected node or nil of no node is
|
||||
// currently selected.
|
||||
func (t *TreeView) GetCurrentNode() *TreeNode {
|
||||
t.Lock()
|
||||
defer t.Unlock()
|
||||
t.RLock()
|
||||
defer t.RUnlock()
|
||||
|
||||
return t.currentNode
|
||||
}
|
||||
|
@ -532,8 +532,8 @@ func (t *TreeView) SetDoneFunc(handler func(key tcell.Key)) *TreeView {
|
|||
// of the tree view. Note that when the user navigates the tree view, this value
|
||||
// is only updated after the tree view has been redrawn.
|
||||
func (t *TreeView) GetScrollOffset() int {
|
||||
t.Lock()
|
||||
defer t.Unlock()
|
||||
t.RLock()
|
||||
defer t.RUnlock()
|
||||
|
||||
return t.offsetY
|
||||
}
|
||||
|
@ -543,8 +543,8 @@ func (t *TreeView) GetScrollOffset() int {
|
|||
// of collapsed nodes. Note that this value is only up to date after the tree
|
||||
// view has been drawn.
|
||||
func (t *TreeView) GetRowCount() int {
|
||||
t.Lock()
|
||||
defer t.Unlock()
|
||||
t.RLock()
|
||||
defer t.RUnlock()
|
||||
|
||||
return len(t.nodes)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue