Merge branch 'master' into devel

This commit is contained in:
Jakub Sobon 2019-05-15 23:24:34 -04:00
commit 947b563927
No known key found for this signature in database
GPG Key ID: F2451A77FB05D3B7
6 changed files with 76 additions and 22 deletions

View File

@ -16,6 +16,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Lint issues found on the Go report card. - Lint issues found on the Go report card.
## [0.9.1] - 15-May-2019
### Fixed
- Termdash could deadlock when a `Button` or a `TextInput` was configured to
call the `Container.Update` method.
## [0.9.0] - 28-Apr-2019 ## [0.9.0] - 28-Apr-2019
### Added ### Added
@ -273,7 +280,8 @@ identifiers shouldn't be used externally.
- The Gauge widget. - The Gauge widget.
- The Text widget. - The Text widget.
[unreleased]: https://github.com/mum4k/termdash/compare/v0.9.0...devel [unreleased]: https://github.com/mum4k/termdash/compare/v0.9.1...devel
[0.9.1]: https://github.com/mum4k/termdash/compare/v0.9.0...v0.9.1
[0.9.0]: https://github.com/mum4k/termdash/compare/v0.8.0...v0.9.0 [0.9.0]: https://github.com/mum4k/termdash/compare/v0.8.0...v0.9.0
[0.8.0]: https://github.com/mum4k/termdash/compare/v0.7.2...v0.8.0 [0.8.0]: https://github.com/mum4k/termdash/compare/v0.7.2...v0.8.0
[0.7.2]: https://github.com/mum4k/termdash/compare/v0.7.1...v0.7.2 [0.7.2]: https://github.com/mum4k/termdash/compare/v0.7.1...v0.7.2

View File

@ -62,7 +62,6 @@ go get -u github.com/mum4k/termdash
The usage of most of these elements is demonstrated in The usage of most of these elements is demonstrated in
[termdashdemo.go](termdashdemo/termdashdemo.go). To execute the demo: [termdashdemo.go](termdashdemo/termdashdemo.go). To execute the demo:
```go ```go
go run github.com/mum4k/termdash/termdashdemo/termdashdemo.go go run github.com/mum4k/termdash/termdashdemo/termdashdemo.go
``` ```
@ -194,6 +193,20 @@ before contributing.
If you're developing a new widget, please see the [widget If you're developing a new widget, please see the [widget
development](doc/widget_development.md) section. development](doc/widget_development.md) section.
Termdash uses [this branching model](https://nvie.com/posts/a-successful-git-branching-model/). When you fork the repository, base your changes off the [devel](https://github.com/mum4k/termdash/tree/devel) branch and the pull request should merge it back to the devel branch. Commits to the master branch are limited to releases, major bug fixes and documentation updates.
# Similar projects in Go
- [termui](https://github.com/gizak/termui)
- [tview](https://github.com/rivo/tview)
- [gocui](https://github.com/jroimartin/gocui)
- [gowid](https://github.com/gcla/gowid)
- [clui](https://github.com/VladimirMarkelov/clui)
- [tui-go](https://github.com/marcusolsson/tui-go)
# Projects using Termdash
- [grafterm](https://github.com/slok/grafterm): Metrics dashboards visualization on the terminal.
# Disclaimer # Disclaimer

View File

@ -5,7 +5,7 @@
Develop infrastructure of dashboard widgets. The widgets should support both Develop infrastructure of dashboard widgets. The widgets should support both
input (mouse and keyboard) and output (display of information to the user). input (mouse and keyboard) and output (display of information to the user).
Fulfill the requirements outlined in the main Fulfil the requirements outlined in the main
[README](http://github.com/mum4k/termdash). [README](http://github.com/mum4k/termdash).
## Background ## Background
@ -76,11 +76,11 @@ The infrastructure handles terminal setup, input events and manages containers.
#### Input events #### Input events
The infrastructure regularly polls events from the terminal layer and feeds The infrastructure regularly polls events from the terminal layer and feeds
them into the event distribution system (EDS). The EDS fulfills the following them into the event distribution system (EDS). The EDS fulfils the following
functions: functions:
- Allow subscribers to specify the type of events they want to receive. - Allow subscribers to specify the type of events they want to receive.
- Distributeis events in a non-blocking manner, i.e. a single slow subscriber - Distributes events in a non-blocking manner, i.e. a single slow subscriber
cannot slow down other subscribers. cannot slow down other subscribers.
- Events to each subscriber are throttled, if a subscriber builds a long tail - Events to each subscriber are throttled, if a subscriber builds a long tail
of unprocessed input events, the EDS selectively drops repetitive events of unprocessed input events, the EDS selectively drops repetitive events

View File

@ -13,7 +13,7 @@
// limitations under the License. // limitations under the License.
// Binary termdashdemo demonstrates the functionality of termdash and its various widgets. // Binary termdashdemo demonstrates the functionality of termdash and its various widgets.
// Exist when 'q' is pressed. // Exits when 'q' is pressed.
package main package main
import ( import (

View File

@ -154,11 +154,8 @@ func (b *Button) Draw(cvs *canvas.Canvas, meta *widgetapi.Meta) error {
) )
} }
// Keyboard processes keyboard events, acts as a button press on the configured // activated asserts whether the keyboard event activated the button.
// Key. func (b *Button) keyActivated(k *terminalapi.Keyboard) bool {
//
// Implements widgetapi.Widget.Keyboard.
func (b *Button) Keyboard(k *terminalapi.Keyboard) error {
b.mu.Lock() b.mu.Lock()
defer b.mu.Unlock() defer b.mu.Unlock()
@ -166,16 +163,27 @@ func (b *Button) Keyboard(k *terminalapi.Keyboard) error {
b.state = button.Down b.state = button.Down
now := time.Now().UTC() now := time.Now().UTC()
b.keyTriggerTime = &now b.keyTriggerTime = &now
return true
}
return false
}
// Keyboard processes keyboard events, acts as a button press on the configured
// Key.
//
// Implements widgetapi.Widget.Keyboard.
func (b *Button) Keyboard(k *terminalapi.Keyboard) error {
if b.keyActivated(k) {
// Mutex must be released when calling the callback.
// Users might call container methods from the callback like the
// Container.Update, see #205.
return b.callback() return b.callback()
} }
return nil return nil
} }
// Mouse processes mouse events, acts as a button press if both the press and // mouseActivated asserts whether the mouse event activated the button.
// the release happen inside the button. func (b *Button) mouseActivated(m *terminalapi.Mouse) bool {
//
// Implements widgetapi.Widget.Mouse.
func (b *Button) Mouse(m *terminalapi.Mouse) error {
b.mu.Lock() b.mu.Lock()
defer b.mu.Unlock() defer b.mu.Unlock()
@ -183,7 +191,18 @@ func (b *Button) Mouse(m *terminalapi.Mouse) error {
b.state = state b.state = state
b.keyTriggerTime = nil b.keyTriggerTime = nil
if clicked { return clicked
}
// Mouse processes mouse events, acts as a button press if both the press and
// the release happen inside the button.
//
// Implements widgetapi.Widget.Mouse.
func (b *Button) Mouse(m *terminalapi.Mouse) error {
if b.mouseActivated(m) {
// Mutex must be released when calling the callback.
// Users might call container methods from the callback like the
// Container.Update, see #205.
return b.callback() return b.callback()
} }
return nil return nil

View File

@ -214,9 +214,11 @@ func (ti *TextInput) Draw(cvs *canvas.Canvas, meta *widgetapi.Meta) error {
return nil return nil
} }
// Keyboard processes keyboard events. // keyboard processes keyboard events.
// Returns a bool indicating if the content was submitted and the text in the
// field at submission time.
// Implements widgetapi.Widget.Keyboard. // Implements widgetapi.Widget.Keyboard.
func (ti *TextInput) Keyboard(k *terminalapi.Keyboard) error { func (ti *TextInput) keyboard(k *terminalapi.Keyboard) (bool, string) {
ti.mu.Lock() ti.mu.Lock()
defer ti.mu.Unlock() defer ti.mu.Unlock()
@ -245,21 +247,33 @@ func (ti *TextInput) Keyboard(k *terminalapi.Keyboard) error {
ti.editor.reset() ti.editor.reset()
} }
if ti.opts.onSubmit != nil { if ti.opts.onSubmit != nil {
return ti.opts.onSubmit(text) return true, text
} }
default: default:
if err := wrap.ValidText(string(k.Key)); err != nil { if err := wrap.ValidText(string(k.Key)); err != nil {
// Ignore unsupported runes. // Ignore unsupported runes.
return nil return false, ""
} }
if ti.opts.filter != nil && !ti.opts.filter(rune(k.Key)) { if ti.opts.filter != nil && !ti.opts.filter(rune(k.Key)) {
// Ignore filtered runes. // Ignore filtered runes.
return nil return false, ""
} }
ti.editor.insert(rune(k.Key)) ti.editor.insert(rune(k.Key))
} }
return false, ""
}
// Keyboard processes keyboard events.
// Implements widgetapi.Widget.Keyboard.
func (ti *TextInput) Keyboard(k *terminalapi.Keyboard) error {
if submitted, text := ti.keyboard(k); submitted {
// Mutex must be released when calling the callback.
// Users might call container methods from the callback like the
// Container.Update, see #205.
return ti.opts.onSubmit(text)
}
return nil return nil
} }