1
0
mirror of https://github.com/gdamore/tcell.git synced 2025-04-26 13:48:53 +08:00

fixes #116 Various improvements to tcell Views API

This commit is contained in:
Garrett D'Amore 2016-05-24 00:50:38 -07:00
parent e05a300454
commit c3e5bc256f
5 changed files with 82 additions and 48 deletions

View File

@ -1,4 +1,4 @@
// Copyright 2015 The Tcell Authors
// Copyright 2016 The Tcell Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
@ -202,7 +202,6 @@ func (b *BoxLayout) Draw() {
if b.changed {
b.layout()
}
// b.view.Clear()
b.view.Fill('*', b.style)
w, h := b.view.Size()
for y := 0; y < h; y++ {
@ -238,6 +237,7 @@ func (b *BoxLayout) HandleEvent(ev tcell.Event) bool {
case *EventWidgetContent:
// This can only have come from one of our children.
b.changed = true
b.PostEventWidgetContent(b)
return true
}
for _, c := range b.cells {
@ -255,7 +255,7 @@ func (b *BoxLayout) AddWidget(widget Widget, fill float64) {
fill: fill,
view: NewViewPort(b.view, 0, 0, 0, 0),
}
c.widget.SetView(c.view)
widget.SetView(c.view)
b.cells = append(b.cells, c)
b.changed = true
widget.Watch(b)

View File

@ -1,4 +1,4 @@
// Copyright 2015 The Tcell Authors
// Copyright 2016 The Tcell Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
@ -15,6 +15,8 @@
package views
import (
"sync"
"github.com/gdamore/tcell"
)
@ -40,6 +42,7 @@ type CellView struct {
style tcell.Style
lines []string
model CellModel
once sync.Once
WidgetWatchers
}
@ -49,7 +52,7 @@ func (a *CellView) Draw() {
port := a.port
model := a.model
port.Clear()
port.Fill(' ', a.style)
if a.view == nil {
return
@ -185,6 +188,7 @@ func (a *CellView) SetModel(model CellModel) {
a.model = model
a.port.SetContentSize(w, h, true)
a.port.ValidateView()
a.PostEventWidgetContent(a)
}
// SetView sets the View context.
@ -242,10 +246,17 @@ func (a *CellView) SetStyle(s tcell.Style) {
a.style = s
}
// Init initializes a new CellView for use.
func (a *CellView) Init() {
a.once.Do(func() {
a.port = NewViewPort(nil, 0, 0, 0, 0)
a.style = tcell.StyleDefault
})
}
// NewCellView creates a CellView.
func NewCellView() *CellView {
return &CellView{
port: NewViewPort(nil, 0, 0, 0, 0),
style: tcell.StyleDefault,
}
cv := &CellView{}
cv.Init()
return cv
}

View File

@ -15,8 +15,8 @@
package views
import (
"unicode"
"github.com/gdamore/tcell"
"unicode"
)
// SimpleStyledText is a form of Text that offers highlighting of the text

View File

@ -26,10 +26,10 @@ import (
// They align to the left, center, and right respectively.
// This is basically a convenience type on top SimpleStyledText and BoxLayout.
type SimpleStyledTextBar struct {
left *SimpleStyledText
right *SimpleStyledText
center *SimpleStyledText
once sync.Once
left *SimpleStyledText
right *SimpleStyledText
center *SimpleStyledText
once sync.Once
BoxLayout
}
@ -37,35 +37,56 @@ type SimpleStyledTextBar struct {
// SetRight sets the right text for the textbar.
// It is always right-aligned.
func (s *SimpleStyledTextBar) SetRight(m string) {
s.initialize()
s.right.SetMarkup(m)
}
// SetLeft sets the left text for the textbar.
// It is always left-aligned.
func (s *SimpleStyledTextBar) SetLeft(m string) {
s.initialize()
s.left.SetMarkup(m)
}
// SetCenter sets the center text for the textbar.
// It is always centered.
func (s *SimpleStyledTextBar) SetCenter(m string) {
s.initialize()
s.center.SetMarkup(m)
}
func (s *SimpleStyledTextBar) RegisterRightStyle(r rune, style tcell.Style) {
s.initialize()
s.right.RegisterStyle(r, style)
}
func (s *SimpleStyledTextBar) RegisterLeftStyle(r rune, style tcell.Style) {
s.initialize()
s.left.RegisterStyle(r, style)
}
func (s *SimpleStyledTextBar) RegisterCenterStyle(r rune, style tcell.Style) {
s.initialize()
s.center.RegisterStyle(r, style)
}
func (s *SimpleStyledTextBar) Size() (int, int) {
s.initialize()
w, h := s.BoxLayout.Size()
if h < 1 {
h = 1
}
if w < 1 {
w = 1
}
return w, h
}
func (s *SimpleStyledTextBar) initialize() {
s.once.Do(func() {
s.center = NewSimpleStyledText()
s.left = NewSimpleStyledText()
s.right = NewSimpleStyledText()
s.center.SetAlignment(VAlignTop | HAlignCenter)
s.left.SetAlignment(VAlignTop | HAlignLeft)
s.right.SetAlignment(VAlignTop | HAlignRight)
@ -78,13 +99,15 @@ func (s *SimpleStyledTextBar) initialize() {
})
}
// Init prepares the widget for use, ensuring resources needed are
// allocated, etc.
func (s *SimpleStyledTextBar) Init() {
s.initialize()
}
// NewSimpleStyledTextBar creates an empty, initialized TextBar.
func NewSimpleStyledTextBar() *SimpleStyledTextBar {
s := &SimpleStyledTextBar{
center: NewSimpleStyledText(),
left: NewSimpleStyledText(),
right: NewSimpleStyledText(),
}
s := &SimpleStyledTextBar{}
s.initialize()
return s
}

View File

@ -1,4 +1,4 @@
// Copyright 2015 The Tcell Authors
// Copyright 2016 The Tcell Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
@ -16,6 +16,7 @@ package views
import (
"strings"
"sync"
"github.com/gdamore/tcell"
)
@ -26,8 +27,9 @@ import (
// a single line to display. All text in the TextArea has the same
// style. An optional soft cursor is available.
type TextArea struct {
view *CellView
model *linesModel
once sync.Once
CellView
}
type linesModel struct {
@ -38,15 +40,16 @@ type linesModel struct {
y int
hide bool
cursor bool
style tcell.Style
}
func (m *linesModel) GetCell(x, y int) (rune, tcell.Style, []rune, int) {
var ch rune
if x < 0 || y < 0 || y >= len(m.lines) || x >= len(m.lines[y]) {
return ch, tcell.StyleDefault, nil, 1
return ch, m.style, nil, 1
}
// XXX: extend this to support combining and full width chars
return rune(m.lines[y][x]), tcell.StyleDefault, nil, 1
return rune(m.lines[y][x]), m.style, nil, 1
}
func (m *linesModel) GetBounds() (int, int) {
@ -85,6 +88,7 @@ func (m *linesModel) GetCursor() (int, int, bool, bool) {
// SetLines sets the content text to display.
func (ta *TextArea) SetLines(lines []string) {
ta.Init()
m := ta.model
m.width = 0
m.height = len(lines)
@ -94,11 +98,17 @@ func (ta *TextArea) SetLines(lines []string) {
m.width = len(l)
}
}
ta.view.SetModel(m)
ta.CellView.SetModel(m)
}
func (ta *TextArea) SetStyle(style tcell.Style) {
ta.model.style = style
ta.CellView.SetStyle(style)
}
// EnableCursor enables a soft cursor in the TextArea.
func (ta *TextArea) EnableCursor(on bool) {
ta.Init()
ta.model.cursor = on
}
@ -106,41 +116,31 @@ func (ta *TextArea) EnableCursor(on bool) {
// If on is true, the cursor is hidden. Note that a cursor is only
// shown if it is enabled.
func (ta *TextArea) HideCursor(on bool) {
ta.Init()
ta.model.hide = on
}
// Draw draws the TextArea.
func (ta *TextArea) Draw() {
ta.view.Draw()
}
// HandleEvent handles any events.
func (ta *TextArea) HandleEvent(ev tcell.Event) bool {
return ta.view.HandleEvent(ev)
}
// Resize is called when the drawing context (View) changes size.
func (ta *TextArea) Resize() {
ta.view.Resize()
}
// SetView sets the drawing context.
func (ta *TextArea) SetView(view View) {
ta.view.SetView(view)
}
// SetContent is used to set the textual content, passed as a
// single string. Lines within the string are delimited by newlines.
func (ta *TextArea) SetContent(text string) {
ta.Init()
lines := strings.Split(strings.Trim(text, "\n"), "\n")
ta.SetLines(lines)
}
// Init initializes the TextArea.
func (ta *TextArea) Init() {
ta.once.Do(func() {
lm := &linesModel{lines: []string{}, width: 0}
ta.model = lm
ta.CellView.Init()
ta.CellView.SetModel(lm)
})
}
// NewTextArea creates a blank TextArea.
func NewTextArea() *TextArea {
lm := &linesModel{lines: []string{}, width: 0}
ta := &TextArea{model: lm}
ta.view = NewCellView()
ta.view.SetModel(lm)
ta := &TextArea{}
ta.Init()
return ta
}