Skip to content

Commit

Permalink
Attempt to change textWidget to require parent context.
Browse files Browse the repository at this point in the history
Less state in the text widget as our embedding Label and Entry widgets have the properties
  • Loading branch information
andydotxyz committed Jan 28, 2019
1 parent 8ace64e commit 6d2ac8a
Show file tree
Hide file tree
Showing 6 changed files with 214 additions and 63 deletions.
78 changes: 60 additions & 18 deletions widget/entry.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,14 @@ func (e *entryRenderer) BackgroundColor() color.Color {
}

func (e *entryRenderer) Refresh() {
e.placeholder.Hide()
if e.text.len() == 0 {
if e.text.len() > 0 {
e.placeholder.Hide()
} else {
e.placeholder.Show()
e.placeholder.refreshTextRenderer()
}

e.text.refreshTextRenderer()
if e.entry.focused {
e.cursor.FillColor = theme.FocusColor()
} else {
Expand Down Expand Up @@ -154,8 +157,7 @@ func (e *Entry) SetText(text string) {
// SetPlaceHolder sets the text that will be displayed if the entry is otherwise empty
func (e *Entry) SetPlaceHolder(text string) {
e.PlaceHolder = text
e.placeholderWidget().SetText(text)
Renderer(e).Refresh()
e.placeholderWidget().SetText(text) // refreshes
}

// SetReadOnly sets whether or not the Entry should not be editable
Expand Down Expand Up @@ -331,22 +333,65 @@ func (e *Entry) placeholderWidget() *textWidget {
return Renderer(e).(*entryRenderer).placeholder
}

// textWidgetRenderer returns the renderer for the current text widget
func (e *Entry) textWidgetRenderer() *textRenderer {
return Renderer(e.textWidget()).(*textRenderer)
// textAlign tells the rendering textWidget our alignment
func (e *Entry) textAlign() fyne.TextAlign {
return fyne.TextAlignLeading
}

// textStyle tells the rendering textWidget our style
func (e *Entry) textStyle() fyne.TextStyle {
return fyne.TextStyle{}
}

// textColor tells the rendering textWidget our color
func (e *Entry) textColor() color.Color {
return theme.TextColor()
}

// password tells the rendering textWidget if we are a password field
func (e *Entry) password() bool {
return e.Password
}

// object returns the root object of the widget so it can be referenced
func (e *Entry) object() fyne.Widget {
return nil
}

type placeholderParent struct {
e *Entry
}

// textAlign tells the rendering textWidget our alignment
func (p *placeholderParent) textAlign() fyne.TextAlign {
return fyne.TextAlignLeading
}

// textStyle tells the rendering textWidget our style
func (p *placeholderParent) textStyle() fyne.TextStyle {
return fyne.TextStyle{}
}

// textColor tells the rendering textWidget our color
func (p *placeholderParent) textColor() color.Color {
return theme.PlaceHolderColor()
}

// password tells the rendering textWidget if we are a password field
func (p *placeholderParent) password() bool {
return p.e.Password
}

// object returns the root object of the widget so it can be referenced
func (p *placeholderParent) object() fyne.Widget {
return nil
}

// CreateRenderer is a private method to Fyne which links this widget to it's renderer
func (e *Entry) CreateRenderer() fyne.WidgetRenderer {
text := &textWidget{
password: e.Password,
}
text.SetText(e.Text)
text := &textWidget{buffer: []rune(e.Text), parent: e}
placeholder := &textWidget{parent: &placeholderParent{e}, buffer: []rune(e.PlaceHolder)}

placeholder := &textWidget{
color: theme.PlaceHolderColor(),
}
placeholder.SetText(e.PlaceHolder)
box := canvas.NewRectangle(theme.BackgroundColor())
cursor := canvas.NewRectangle(theme.BackgroundColor())

Expand All @@ -358,7 +403,6 @@ func (e *Entry) CreateRenderer() fyne.WidgetRenderer {
func NewEntry() *Entry {
e := &Entry{}

Renderer(e).Layout(e.MinSize())
Renderer(e).Refresh()
return e
}
Expand All @@ -367,7 +411,6 @@ func NewEntry() *Entry {
func NewMultiLineEntry() *Entry {
e := &Entry{MultiLine: true}

Renderer(e).Layout(e.MinSize())
Renderer(e).Refresh()
return e
}
Expand All @@ -376,7 +419,6 @@ func NewMultiLineEntry() *Entry {
func NewPasswordEntry() *Entry {
e := &Entry{Password: true}

Renderer(e).Layout(e.MinSize())
Renderer(e).Refresh()
return e
}
12 changes: 9 additions & 3 deletions widget/entry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,18 @@ import (
"testing"

"fyne.io/fyne"
"fyne.io/fyne/canvas"
"fyne.io/fyne/test"
"fyne.io/fyne/theme"

"github.com/stretchr/testify/assert"
)

func entryRenderTexts(e *Entry) []*canvas.Text {
textWid := Renderer(e).(*entryRenderer).text
return Renderer(textWid).(*textRenderer).texts
}

func TestEntry_MinSize(t *testing.T) {
entry := NewEntry()
min := entry.MinSize()
Expand Down Expand Up @@ -141,8 +147,8 @@ func TestEntry_OnKeyDown_Newline(t *testing.T) {
key.String = "o"
entry.OnKeyDown(key)
assert.Equal(t, "H\noi", entry.textWidget().String())
assert.Equal(t, "H", entry.textWidgetRenderer().texts[0].Text)
assert.Equal(t, "oi", entry.textWidgetRenderer().texts[1].Text)
assert.Equal(t, "H", entryRenderTexts(entry)[0].Text)
assert.Equal(t, "oi", entryRenderTexts(entry)[1].Text)
}

func TestEntry_OnKeyDown_Backspace(t *testing.T) {
Expand Down Expand Up @@ -439,5 +445,5 @@ func TestPasswordEntry_Obfuscation(t *testing.T) {
key.String = "Hié™שרה"
entry.OnKeyDown(key)
assert.Equal(t, "Hié™שרה", entry.Text)
assert.Equal(t, "*******", entry.textWidgetRenderer().texts[0].Text)
assert.Equal(t, "*******", entryRenderTexts(entry)[0].Text)
}
42 changes: 31 additions & 11 deletions widget/label.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package widget

import (
"image/color"

"fyne.io/fyne"
"fyne.io/fyne/theme"
)

// Label widget is a label component with appropriate padding and layout.
Expand All @@ -25,27 +28,44 @@ func NewLabelWithStyle(text string, alignment fyne.TextAlign, style fyne.TextSty
TextStyle: style,
}

Renderer(l).Refresh()
return l
}

// SetText sets the text of the label
func (l *Label) SetText(text string) {
l.Text = text
l.textWidget.SetText(text)
Renderer(l).Refresh()
l.textWidget.SetText(text) // calls refresh
}

// textAlign tells the rendering textWidget our alignment
func (l *Label) textAlign() fyne.TextAlign {
return l.Alignment
}

// textStyle tells the rendering textWidget our style
func (l *Label) textStyle() fyne.TextStyle {
return l.TextStyle
}

// textColor tells the rendering textWidget our color
func (l *Label) textColor() color.Color {
return theme.TextColor()
}

// password tells the rendering textWidget if we are a password field
func (l *Label) password() bool {
return false
}

// object returns the root object of the widget so it can be referenced
func (l *Label) object() fyne.Widget {
return l
}

// CreateRenderer is a private method to Fyne which links this widget to it's renderer
func (l *Label) CreateRenderer() fyne.WidgetRenderer {
l.textWidget = textWidget{
Alignment: l.Alignment,
TextStyle: l.TextStyle,
}
l.textWidget.SetText(l.Text)
r := l.textWidget.CreateRenderer()
r.Refresh()
return r
l.textWidget = newTextWidget(l.Text, l)
return l.textWidget.CreateRenderer()
}

// Resize sets a new size for a widget.
Expand Down
32 changes: 31 additions & 1 deletion widget/label_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,39 @@ func TestLabel_MinSize(t *testing.T) {
label.SetText("Longer")
assert.True(t, label.MinSize().Width > min.Width)
}

func TestLabel_Text(t *testing.T) {
label := &Label{Text: "Test"}
Renderer(label).Refresh()

assert.Equal(t, "Test", label.Text)
assert.Equal(t, "Test", textRenderTexts(label)[0].Text)
}

func TestLabel_SetText(t *testing.T) {
label := &Label{Text: "Test"}
Renderer(label).Refresh()
label.SetText("New")

assert.Equal(t, "New", label.Text)
assert.Equal(t, "New", textRenderTexts(label)[0].Text)
}

func TestLabel_Alignment(t *testing.T) {
label := &Label{Text: "Test", Alignment: fyne.TextAlignTrailing}
assert.Equal(t, fyne.TextAlignTrailing, Renderer(label).(*textRenderer).texts[0].Alignment)
Renderer(label).Refresh()

assert.Equal(t, fyne.TextAlignTrailing, textRenderTexts(label)[0].Alignment)
}

func TestLabel_Alignment_Later(t *testing.T) {
label := &Label{Text: "Test"}
Renderer(label).Refresh()
assert.Equal(t, fyne.TextAlignLeading, textRenderTexts(label)[0].Alignment)

label.Alignment = fyne.TextAlignTrailing
Renderer(label).Refresh()
assert.Equal(t, fyne.TextAlignTrailing, textRenderTexts(label)[0].Alignment)
}

func TestText_MinSize_MultiLine(t *testing.T) {
Expand Down
Loading

0 comments on commit 6d2ac8a

Please sign in to comment.