Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a new SimpleRenderer to handle simple cases. #2279

Merged
merged 12 commits into from Jun 17, 2021
16 changes: 3 additions & 13 deletions dialog/color_picker.go
Expand Up @@ -192,7 +192,7 @@ func (p *colorAdvancedPicker) CreateRenderer() fyne.WidgetRenderer {
))

r := &colorPickerRenderer{
BaseRenderer: internalwidget.NewBaseRenderer([]fyne.CanvasObject{contents}),
SimpleRenderer: internalwidget.NewSimpleRenderer(contents),
fpabl0 marked this conversation as resolved.
Show resolved Hide resolved
picker: p,
redChannel: redChannel,
greenChannel: greenChannel,
Expand Down Expand Up @@ -253,7 +253,7 @@ func (p *colorAdvancedPicker) updateRGBA(r, g, b, a int) bool {
var _ fyne.WidgetRenderer = (*colorPickerRenderer)(nil)

type colorPickerRenderer struct {
internalwidget.BaseRenderer
*internalwidget.SimpleRenderer
picker *colorAdvancedPicker
redChannel *colorChannel
greenChannel *colorChannel
Expand All @@ -268,19 +268,9 @@ type colorPickerRenderer struct {
contents fyne.CanvasObject
}

func (r *colorPickerRenderer) Layout(size fyne.Size) {
r.contents.Move(fyne.NewPos(0, 0))
r.contents.Resize(size)
}

func (r *colorPickerRenderer) MinSize() fyne.Size {
return r.contents.MinSize()
}

func (r *colorPickerRenderer) Refresh() {
r.updateObjects()
r.Layout(r.picker.Size())
fpabl0 marked this conversation as resolved.
Show resolved Hide resolved
canvas.Refresh(r.picker)
r.SimpleRenderer.Refresh()
}

func (r *colorPickerRenderer) updateObjects() {
Expand Down
24 changes: 4 additions & 20 deletions internal/app/focus_manager_test.go
Expand Up @@ -151,12 +151,12 @@ var _ fyne.Disableable = (*focusable)(nil)

type focusable struct {
widget.DisableableWidget
children []fyne.CanvasObject
focused bool
child fyne.CanvasObject
focused bool
}

func (f *focusable) CreateRenderer() fyne.WidgetRenderer {
return &focusableRenderer{BaseRenderer: internalWidget.NewBaseRenderer(f.children)}
return internalWidget.NewSimpleRenderer(f.child)
}

func (f *focusable) FocusGained() {
Expand All @@ -176,27 +176,11 @@ func (f *focusable) TypedRune(_ rune) {
func (f *focusable) TypedKey(_ *fyne.KeyEvent) {
}

var _ fyne.WidgetRenderer = (*focusableRenderer)(nil)

type focusableRenderer struct {
internalWidget.BaseRenderer
}

func (f focusableRenderer) Layout(_ fyne.Size) {
}

func (f focusableRenderer) MinSize() fyne.Size {
return fyne.NewSize(0, 0)
}

func (f focusableRenderer) Refresh() {
}

func setupFocusManager(t *testing.T) (m *app.FocusManager, entry1, hidden, visibleInsideHidden, entry2, disabled, entry3 *focusable) {
entry1 = &focusable{}
visibleInsideHidden = &focusable{}
hidden = &focusable{
children: []fyne.CanvasObject{visibleInsideHidden},
child: visibleInsideHidden,
}
hidden.Hide()
entry2 = &focusable{}
Expand Down
65 changes: 65 additions & 0 deletions internal/widget/simple_renderer.go
@@ -0,0 +1,65 @@
package widget

import "fyne.io/fyne/v2"

var _ fyne.WidgetRenderer = (*SimpleRenderer)(nil)

// SimpleRenderer is a basic renderer that satisfies widget.Renderer interface by wrapping
// a single fyne.CanvasObject.
//
// Since: 2.1
type SimpleRenderer struct {
objects []fyne.CanvasObject
}

// NewSimpleRenderer creates a new SimpleRenderer to render a widget using a
// single CanvasObject.
//
// Since: 2.1
func NewSimpleRenderer(object fyne.CanvasObject) *SimpleRenderer {
return &SimpleRenderer{[]fyne.CanvasObject{object}}
}

// Destroy does nothing in this implementation.
//
// Implements: fyne.WidgetRenderer
//
// Since: 2.1
func (r *SimpleRenderer) Destroy() {
}

// Layout updates the contained object to be the requested size.
//
// Implements: fyne.WidgetRenderer
//
// Since: 2.1
func (r *SimpleRenderer) Layout(s fyne.Size) {
r.objects[0].Resize(s)
}

// MinSize returns the smallest size that this render can use, returned from the underlying object.
//
// Implements: fyne.WidgetRenderer
//
// Since: 2.1
func (r *SimpleRenderer) MinSize() fyne.Size {
return r.objects[0].MinSize()
}

// Objects returns the objects that should be rendered.
//
// Implements: fyne.WidgetRenderer
//
// Since: 2.1
func (r *SimpleRenderer) Objects() []fyne.CanvasObject {
return r.objects
}

// Refresh requests the underlying object to redraw.
//
// Implements: fyne.WidgetRenderer
//
// Since: 2.1
func (r *SimpleRenderer) Refresh() {
r.objects[0].Refresh()
}
30 changes: 30 additions & 0 deletions internal/widget/simple_renderer_test.go
@@ -0,0 +1,30 @@
package widget_test

import (
"image/color"
"testing"

"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/internal/widget"
"fyne.io/fyne/v2/test"
)

func TestNewSimpleRenderer(t *testing.T) {
r := canvas.NewRectangle(color.Transparent)
o := &simpleWidget{obj: r}
o.ExtendBaseWidget(o)
w := test.NewWindow(o)
w.Resize(fyne.NewSize(100, 100))

test.AssertRendersToMarkup(t, "simple_renderer.xml", w.Canvas())
}

type simpleWidget struct {
widget.Base
obj fyne.CanvasObject
}

func (s *simpleWidget) CreateRenderer() fyne.WidgetRenderer {
return widget.NewSimpleRenderer(s.obj)
}
7 changes: 7 additions & 0 deletions internal/widget/testdata/simple_renderer.xml
@@ -0,0 +1,7 @@
<canvas padded size="100x100">
<content>
<widget pos="4,4" size="92x92" type="*widget_test.simpleWidget">
<rectangle size="92x92"/>
</widget>
</content>
</canvas>
15 changes: 4 additions & 11 deletions widget/entry_password.go
@@ -1,12 +1,9 @@
package widget

import (
"image/color"

"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/driver/desktop"
"fyne.io/fyne/v2/internal/widget"
"fyne.io/fyne/v2/theme"
)

Expand All @@ -32,9 +29,9 @@ func newPasswordRevealer(e *Entry) *passwordRevealer {

func (r *passwordRevealer) CreateRenderer() fyne.WidgetRenderer {
return &passwordRevealerRenderer{
BaseRenderer: widget.NewBaseRenderer([]fyne.CanvasObject{r.icon}),
icon: r.icon,
entry: r.entry,
WidgetRenderer: NewSimpleRenderer(r.icon),
icon: r.icon,
entry: r.entry,
}
}

Expand All @@ -52,15 +49,11 @@ func (r *passwordRevealer) Tapped(*fyne.PointEvent) {
var _ fyne.WidgetRenderer = (*passwordRevealerRenderer)(nil)

type passwordRevealerRenderer struct {
widget.BaseRenderer
fyne.WidgetRenderer
entry *Entry
icon *canvas.Image
}

func (r *passwordRevealerRenderer) BackgroundColor() color.Color {
return color.Transparent
}

func (r *passwordRevealerRenderer) Layout(size fyne.Size) {
r.icon.Resize(fyne.NewSize(theme.IconInlineSize(), theme.IconInlineSize()))
r.icon.Move(fyne.NewPos((size.Width-theme.IconInlineSize())/2, (size.Height-theme.IconInlineSize())/2))
Expand Down
9 changes: 4 additions & 5 deletions widget/entry_validation.go
Expand Up @@ -3,7 +3,6 @@ package widget
import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/internal/widget"
"fyne.io/fyne/v2/theme"
)

Expand Down Expand Up @@ -69,16 +68,16 @@ func (r *validationStatus) CreateRenderer() fyne.WidgetRenderer {
icon := &canvas.Image{}
icon.Hide()
return &validationStatusRenderer{
BaseRenderer: widget.NewBaseRenderer([]fyne.CanvasObject{icon}),
icon: icon,
entry: r.entry,
WidgetRenderer: NewSimpleRenderer(icon),
icon: icon,
entry: r.entry,
}
}

var _ fyne.WidgetRenderer = (*validationStatusRenderer)(nil)

type validationStatusRenderer struct {
widget.BaseRenderer
fyne.WidgetRenderer
entry *Entry
icon *canvas.Image
}
Expand Down
3 changes: 2 additions & 1 deletion widget/form.go
Expand Up @@ -6,6 +6,7 @@ import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/internal/cache"
internalWidget "fyne.io/fyne/v2/internal/widget"
"fyne.io/fyne/v2/layout"
"fyne.io/fyne/v2/theme"
)
Expand Down Expand Up @@ -261,7 +262,7 @@ func (f *Form) CreateRenderer() fyne.WidgetRenderer {
}
f.itemGrid = fyne.NewContainerWithLayout(layout.NewFormLayout(), objects...)

renderer := &simpleRenderer{content: fyne.NewContainerWithLayout(layout.NewVBoxLayout(), f.itemGrid, f.buttonBox)}
renderer := internalWidget.NewSimpleRenderer(fyne.NewContainerWithLayout(layout.NewVBoxLayout(), f.itemGrid, f.buttonBox))
fpabl0 marked this conversation as resolved.
Show resolved Hide resolved
f.updateButtons() // will set correct visibility on the submit/cancel btns
f.checkValidation(nil) // will trigger a validation check for correct initial validation status
return renderer
Expand Down
14 changes: 4 additions & 10 deletions widget/separator.go
Expand Up @@ -3,7 +3,6 @@ package widget
import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/internal/widget"
"fyne.io/fyne/v2/theme"
)

Expand Down Expand Up @@ -31,11 +30,10 @@ func NewSeparator() *Separator {
func (s *Separator) CreateRenderer() fyne.WidgetRenderer {
s.ExtendBaseWidget(s)
bar := canvas.NewRectangle(theme.DisabledColor())
objects := []fyne.CanvasObject{bar}
return &separatorRenderer{
BaseRenderer: widget.NewBaseRenderer(objects),
bar: bar,
d: s,
WidgetRenderer: NewSimpleRenderer(bar),
bar: bar,
d: s,
}
}

Expand All @@ -51,15 +49,11 @@ func (s *Separator) MinSize() fyne.Size {
var _ fyne.WidgetRenderer = (*separatorRenderer)(nil)

type separatorRenderer struct {
widget.BaseRenderer
fyne.WidgetRenderer
bar *canvas.Rectangle
d *Separator
}

func (r *separatorRenderer) Layout(size fyne.Size) {
r.bar.Resize(size)
}

func (r *separatorRenderer) MinSize() fyne.Size {
t := theme.SeparatorThicknessSize()
return fyne.NewSize(t, t)
Expand Down
Binary file added widget/testdata/simple_renderer.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 7 additions & 21 deletions widget/widget.go
Expand Up @@ -7,6 +7,7 @@ import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/internal/cache"
internalWidget "fyne.io/fyne/v2/internal/widget"
)

// BaseWidget provides a helper that handles basic widget behaviours.
Expand Down Expand Up @@ -198,25 +199,10 @@ func (w *DisableableWidget) Disabled() bool {
return w.disabled
}

type simpleRenderer struct {
content *fyne.Container
}

func (s *simpleRenderer) Destroy() {
}

func (s *simpleRenderer) Layout(size fyne.Size) {
s.content.Resize(size)
}

func (s *simpleRenderer) MinSize() fyne.Size {
return s.content.MinSize()
}

func (s *simpleRenderer) Objects() []fyne.CanvasObject {
return []fyne.CanvasObject{s.content}
}

func (s *simpleRenderer) Refresh() {
s.content.Refresh()
// NewSimpleRenderer creates a new SimpleRenderer to render a widget using a
// single fyne.CanvasObject.
//
// Since: 2.1
func NewSimpleRenderer(object fyne.CanvasObject) fyne.WidgetRenderer {
return internalWidget.NewSimpleRenderer(object)
}