From 49de087c3b714310948352ee7e0b4b58894c0654 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Mon, 13 Apr 2020 17:18:45 +0200 Subject: [PATCH 1/7] move baseRenderer into internal widget package --- internal/widget/base_renderer.go | 38 +++++++++++++++++++++++++++++++ widget/base_renderer.go | 27 ---------------------- widget/box.go | 7 +++--- widget/button.go | 2 +- widget/check.go | 11 +++++++-- widget/entry.go | 5 ++-- widget/group.go | 5 ++-- widget/icon.go | 7 +++--- widget/icon_test.go | 4 ++-- widget/menu.go | 5 ++-- widget/popup.go | 5 ++-- widget/progressbar.go | 5 ++-- widget/progressbarinfinite.go | 5 ++-- widget/radio.go | 9 ++++---- widget/scroller.go | 15 ++++++------ widget/shadow.go | 13 ++++++----- widget/shadowing_renderer.go | 10 ++++---- widget/shadowing_renderer_test.go | 2 +- widget/slider.go | 5 ++-- widget/text.go | 5 ++-- widget/text_test.go | 4 ++-- widget/toolbar.go | 5 ++-- 22 files changed, 114 insertions(+), 80 deletions(-) create mode 100644 internal/widget/base_renderer.go delete mode 100644 widget/base_renderer.go diff --git a/internal/widget/base_renderer.go b/internal/widget/base_renderer.go new file mode 100644 index 0000000000..0c86e96a71 --- /dev/null +++ b/internal/widget/base_renderer.go @@ -0,0 +1,38 @@ +package widget + +import ( + "image/color" + + "fyne.io/fyne" + "fyne.io/fyne/theme" +) + +// NewBaseRenderer creates a new BaseRenderer. +func NewBaseRenderer(objects []fyne.CanvasObject) BaseRenderer { + return BaseRenderer{objects} +} + +// BaseRenderer is a renderer base providing the most common implementations of a part of the +// widget.Renderer interface. +type BaseRenderer struct { + objects []fyne.CanvasObject +} + +// BackgroundColor satisfies the fyne.WidgetRenderer interface. +func (r *BaseRenderer) BackgroundColor() color.Color { + return theme.BackgroundColor() +} + +// Destroy satisfies the fyne.WidgetRenderer interface. +func (r *BaseRenderer) Destroy() { +} + +// Objects satisfies the fyne.WidgetRenderer interface. +func (r *BaseRenderer) Objects() []fyne.CanvasObject { + return r.objects +} + +// SetObjects updates the objects of the renderer. +func (r *BaseRenderer) SetObjects(objects []fyne.CanvasObject) { + r.objects = objects +} diff --git a/widget/base_renderer.go b/widget/base_renderer.go deleted file mode 100644 index 507619609a..0000000000 --- a/widget/base_renderer.go +++ /dev/null @@ -1,27 +0,0 @@ -package widget - -import ( - "image/color" - - "fyne.io/fyne" - "fyne.io/fyne/theme" -) - -type baseRenderer struct { - objects []fyne.CanvasObject -} - -func (r *baseRenderer) BackgroundColor() color.Color { - return theme.BackgroundColor() -} - -func (r *baseRenderer) Destroy() { -} - -func (r *baseRenderer) Objects() []fyne.CanvasObject { - return r.objects -} - -func (r *baseRenderer) setObjects(objects []fyne.CanvasObject) { - r.objects = objects -} diff --git a/widget/box.go b/widget/box.go index a94add3d6f..597afd1716 100644 --- a/widget/box.go +++ b/widget/box.go @@ -5,6 +5,7 @@ import ( "fyne.io/fyne" "fyne.io/fyne/canvas" + "fyne.io/fyne/internal/widget" "fyne.io/fyne/layout" "fyne.io/fyne/theme" ) @@ -58,7 +59,7 @@ func (b *Box) CreateRenderer() fyne.WidgetRenderer { lay = layout.NewVBoxLayout() } - return &boxRenderer{baseRenderer: baseRenderer{b.Children}, layout: lay, box: b} + return &boxRenderer{BaseRenderer: widget.NewBaseRenderer(b.Children), layout: lay, box: b} } func (b *Box) setBackgroundColor(bg color.Color) { @@ -76,7 +77,7 @@ func NewVBox(children ...fyne.CanvasObject) *Box { } type boxRenderer struct { - baseRenderer + widget.BaseRenderer layout fyne.Layout box *Box } @@ -98,7 +99,7 @@ func (b *boxRenderer) BackgroundColor() color.Color { } func (b *boxRenderer) Refresh() { - b.setObjects(b.box.Children) + b.SetObjects(b.box.Children) for _, child := range b.Objects() { child.Refresh() } diff --git a/widget/button.go b/widget/button.go index 447dbf4628..0c6595e35e 100644 --- a/widget/button.go +++ b/widget/button.go @@ -99,7 +99,7 @@ func (b *buttonRenderer) Refresh() { if b.button.Icon != nil && b.button.Visible() { if b.icon == nil { b.icon = canvas.NewImageFromResource(b.button.Icon) - b.setObjects(append(b.Objects(), b.icon)) + b.SetObjects(append(b.Objects(), b.icon)) } else { if b.button.Disabled() { // if the icon has changed, create a new disabled version diff --git a/widget/check.go b/widget/check.go index 0737184a45..b7f1c9db32 100644 --- a/widget/check.go +++ b/widget/check.go @@ -4,11 +4,12 @@ import ( "fyne.io/fyne" "fyne.io/fyne/canvas" "fyne.io/fyne/driver/desktop" + "fyne.io/fyne/internal/widget" "fyne.io/fyne/theme" ) type checkRenderer struct { - baseRenderer + widget.BaseRenderer icon *canvas.Image label *canvas.Text focusIndicator *canvas.Circle @@ -158,7 +159,13 @@ func (c *Check) CreateRenderer() fyne.WidgetRenderer { text.Alignment = fyne.TextAlignLeading focusIndicator := canvas.NewCircle(theme.BackgroundColor()) - return &checkRenderer{baseRenderer{[]fyne.CanvasObject{focusIndicator, icon, text}}, icon, text, focusIndicator, c} + return &checkRenderer{ + widget.NewBaseRenderer([]fyne.CanvasObject{focusIndicator, icon, text}), + icon, + text, + focusIndicator, + c, + } } // NewCheck creates a new check widget with the set label and change handler diff --git a/widget/entry.go b/widget/entry.go index 541cc42482..dfdbe2f1c7 100644 --- a/widget/entry.go +++ b/widget/entry.go @@ -10,6 +10,7 @@ import ( "fyne.io/fyne" "fyne.io/fyne/canvas" "fyne.io/fyne/driver/desktop" + "fyne.io/fyne/internal/widget" "fyne.io/fyne/theme" ) @@ -1154,7 +1155,7 @@ func NewPasswordEntry() *Entry { } type passwordRevealerRenderer struct { - baseRenderer + widget.BaseRenderer entry *Entry icon *canvas.Image } @@ -1189,7 +1190,7 @@ type passwordRevealer struct { func (pr *passwordRevealer) CreateRenderer() fyne.WidgetRenderer { return &passwordRevealerRenderer{ - baseRenderer: baseRenderer{[]fyne.CanvasObject{pr.icon}}, + BaseRenderer: widget.NewBaseRenderer([]fyne.CanvasObject{pr.icon}), icon: pr.icon, entry: pr.entry, } diff --git a/widget/group.go b/widget/group.go index 8c14f4db07..d6a0ccfaa0 100644 --- a/widget/group.go +++ b/widget/group.go @@ -3,6 +3,7 @@ package widget import ( "fyne.io/fyne" "fyne.io/fyne/canvas" + "fyne.io/fyne/internal/widget" "fyne.io/fyne/theme" ) @@ -42,7 +43,7 @@ func (g *Group) CreateRenderer() fyne.WidgetRenderer { labelBg := canvas.NewRectangle(theme.BackgroundColor()) line := canvas.NewRectangle(theme.ButtonColor()) return &groupRenderer{ - baseRenderer: baseRenderer{[]fyne.CanvasObject{line, labelBg, label, g.content}}, + BaseRenderer: widget.NewBaseRenderer([]fyne.CanvasObject{line, labelBg, label, g.content}), label: label, line: line, labelBg: labelBg, @@ -70,7 +71,7 @@ func NewGroupWithScroller(title string, children ...fyne.CanvasObject) *Group { } type groupRenderer struct { - baseRenderer + widget.BaseRenderer label *Label line, labelBg *canvas.Rectangle group *Group diff --git a/widget/icon.go b/widget/icon.go index 247869bbf2..816efd17d3 100644 --- a/widget/icon.go +++ b/widget/icon.go @@ -5,11 +5,12 @@ import ( "fyne.io/fyne" "fyne.io/fyne/canvas" + "fyne.io/fyne/internal/widget" "fyne.io/fyne/theme" ) type iconRenderer struct { - baseRenderer + widget.BaseRenderer image *Icon } @@ -31,13 +32,13 @@ func (i *iconRenderer) BackgroundColor() color.Color { } func (i *iconRenderer) Refresh() { - i.setObjects(nil) + i.SetObjects(nil) if i.image.Resource != nil { raster := canvas.NewImageFromResource(i.image.Resource) raster.FillMode = canvas.ImageFillContain - i.setObjects([]fyne.CanvasObject{raster}) + i.SetObjects([]fyne.CanvasObject{raster}) } i.Layout(i.image.Size()) diff --git a/widget/icon_test.go b/widget/icon_test.go index 56e0f5f763..b2a3e9c58c 100644 --- a/widget/icon_test.go +++ b/widget/icon_test.go @@ -40,8 +40,8 @@ func TestIcon_MinSize(t *testing.T) { func TestIconRenderer_ApplyTheme(t *testing.T) { icon := NewIcon(theme.CancelIcon()) render := test.WidgetRenderer(icon).(*iconRenderer) - visible := render.objects[0].Visible() + visible := render.Objects()[0].Visible() render.Refresh() - assert.Equal(t, visible, render.objects[0].Visible()) + assert.Equal(t, visible, render.Objects()[0].Visible()) } diff --git a/widget/menu.go b/widget/menu.go index cd15f7550c..f89cd0756e 100644 --- a/widget/menu.go +++ b/widget/menu.go @@ -6,6 +6,7 @@ import ( "fyne.io/fyne" "fyne.io/fyne/canvas" "fyne.io/fyne/driver/desktop" + "fyne.io/fyne/internal/widget" "fyne.io/fyne/theme" ) @@ -60,7 +61,7 @@ func (t *menuItemWidget) Tapped(*fyne.PointEvent) { func (t *menuItemWidget) CreateRenderer() fyne.WidgetRenderer { text := canvas.NewText(t.Item.Label, theme.TextColor()) - return &menuItemWidgetRenderer{baseRenderer{[]fyne.CanvasObject{text}}, text, t} + return &menuItemWidgetRenderer{widget.NewBaseRenderer([]fyne.CanvasObject{text}), text, t} } // MouseIn is called when a desktop pointer enters the widget @@ -86,7 +87,7 @@ func newMenuItemWidget(item *fyne.MenuItem) *menuItemWidget { } type menuItemWidgetRenderer struct { - baseRenderer + widget.BaseRenderer text *canvas.Text w *menuItemWidget } diff --git a/widget/popup.go b/widget/popup.go index 547c2d1cc9..ca651f090e 100644 --- a/widget/popup.go +++ b/widget/popup.go @@ -5,6 +5,7 @@ import ( "fyne.io/fyne" "fyne.io/fyne/canvas" + "fyne.io/fyne/internal/widget" "fyne.io/fyne/theme" ) @@ -98,7 +99,7 @@ func (p *PopUp) CreateRenderer() fyne.WidgetRenderer { bg := canvas.NewRectangle(theme.BackgroundColor()) objects := []fyne.CanvasObject{bg, p.Content} if p.modal { - return &modalPopUpRenderer{baseRenderer{objects}, popUpBaseRenderer{popUp: p, bg: bg}} + return &modalPopUpRenderer{widget.NewBaseRenderer(objects), popUpBaseRenderer{popUp: p, bg: bg}} } return &popUpRenderer{newShadowingRenderer(objects, popUpLevel), popUpBaseRenderer{popUp: p, bg: bg}} @@ -229,7 +230,7 @@ func (r *popUpRenderer) BackgroundColor() color.Color { } type modalPopUpRenderer struct { - baseRenderer + widget.BaseRenderer popUpBaseRenderer } diff --git a/widget/progressbar.go b/widget/progressbar.go index 8605c73dca..4c76eb2a62 100644 --- a/widget/progressbar.go +++ b/widget/progressbar.go @@ -6,13 +6,14 @@ import ( "fyne.io/fyne" "fyne.io/fyne/canvas" + "fyne.io/fyne/internal/widget" "fyne.io/fyne/theme" ) const defaultText = "%d%%" type progressRenderer struct { - baseRenderer + widget.BaseRenderer bar *canvas.Rectangle label *canvas.Text progress *ProgressBar @@ -97,7 +98,7 @@ func (p *ProgressBar) CreateRenderer() fyne.WidgetRenderer { bar := canvas.NewRectangle(theme.PrimaryColor()) label := canvas.NewText("0%", theme.TextColor()) label.Alignment = fyne.TextAlignCenter - return &progressRenderer{baseRenderer{[]fyne.CanvasObject{bar, label}}, bar, label, p} + return &progressRenderer{widget.NewBaseRenderer([]fyne.CanvasObject{bar, label}), bar, label, p} } // NewProgressBar creates a new progress bar widget. diff --git a/widget/progressbarinfinite.go b/widget/progressbarinfinite.go index 510f2d4f8e..cffe5a97a3 100644 --- a/widget/progressbarinfinite.go +++ b/widget/progressbarinfinite.go @@ -8,6 +8,7 @@ import ( "fyne.io/fyne" "fyne.io/fyne/canvas" "fyne.io/fyne/internal/cache" + "fyne.io/fyne/internal/widget" "fyne.io/fyne/theme" ) @@ -19,7 +20,7 @@ const ( ) type infProgressRenderer struct { - baseRenderer + widget.BaseRenderer bar *canvas.Rectangle ticker *time.Ticker running atomic.Value @@ -173,7 +174,7 @@ func (p *ProgressBarInfinite) CreateRenderer() fyne.WidgetRenderer { p.ExtendBaseWidget(p) bar := canvas.NewRectangle(theme.PrimaryColor()) render := &infProgressRenderer{ - baseRenderer: baseRenderer{[]fyne.CanvasObject{bar}}, + BaseRenderer: widget.NewBaseRenderer([]fyne.CanvasObject{bar}), bar: bar, progress: p, } diff --git a/widget/radio.go b/widget/radio.go index c6ed27584a..2281656c07 100644 --- a/widget/radio.go +++ b/widget/radio.go @@ -6,6 +6,7 @@ import ( "fyne.io/fyne" "fyne.io/fyne/canvas" "fyne.io/fyne/driver/desktop" + "fyne.io/fyne/internal/widget" "fyne.io/fyne/theme" ) @@ -19,7 +20,7 @@ type radioRenderItem struct { } type radioRenderer struct { - baseRenderer + widget.BaseRenderer items []*radioRenderItem radio *Radio } @@ -112,14 +113,14 @@ func (r *radioRenderer) Refresh() { focusIndicator := canvas.NewCircle(theme.BackgroundColor()) - r.setObjects(append(r.Objects(), focusIndicator, icon, text)) + r.SetObjects(append(r.Objects(), focusIndicator, icon, text)) r.items = append(r.items, &radioRenderItem{icon, text, focusIndicator}) } r.Layout(r.radio.Size()) } else if len(r.items) > len(r.radio.Options) { total := len(r.radio.Options) r.items = r.items[:total] - r.setObjects(r.Objects()[:total*2]) + r.SetObjects(r.Objects()[:total*2]) } for i, item := range r.items { @@ -263,7 +264,7 @@ func (r *Radio) CreateRenderer() fyne.WidgetRenderer { items = append(items, &radioRenderItem{icon, text, focusIndicator}) } - return &radioRenderer{baseRenderer{objects}, items, r} + return &radioRenderer{widget.NewBaseRenderer(objects), items, r} } // SetSelected sets the radio option, it can be used to set a default option. diff --git a/widget/scroller.go b/widget/scroller.go index 97812e59d0..c261d463ab 100644 --- a/widget/scroller.go +++ b/widget/scroller.go @@ -6,6 +6,7 @@ import ( "fyne.io/fyne" "fyne.io/fyne/canvas" "fyne.io/fyne/driver/desktop" + "fyne.io/fyne/internal/widget" "fyne.io/fyne/theme" ) @@ -29,7 +30,7 @@ const ( ) type scrollBarRenderer struct { - baseRenderer + widget.BaseRenderer scrollBar *scrollBar minSize fyne.Size } @@ -106,7 +107,7 @@ func newScrollBar(area *scrollBarArea) *scrollBar { } type scrollBarAreaRenderer struct { - baseRenderer + widget.BaseRenderer area *scrollBarArea bar *scrollBar } @@ -177,7 +178,7 @@ type scrollBarArea struct { func (a *scrollBarArea) CreateRenderer() fyne.WidgetRenderer { bar := newScrollBar(a) - return &scrollBarAreaRenderer{baseRenderer: baseRenderer{[]fyne.CanvasObject{bar}}, area: a, bar: bar} + return &scrollBarAreaRenderer{BaseRenderer: widget.NewBaseRenderer([]fyne.CanvasObject{bar}), area: a, bar: bar} } func (a *scrollBarArea) MouseIn(*desktop.MouseEvent) { @@ -222,7 +223,7 @@ func newScrollBarArea(scroll *ScrollContainer, orientation scrollBarOrientation) } type scrollContainerRenderer struct { - baseRenderer + widget.BaseRenderer scroll *ScrollContainer vertArea *scrollBarArea horizArea *scrollBarArea @@ -324,20 +325,20 @@ type ScrollContainer struct { func (s *ScrollContainer) CreateRenderer() fyne.WidgetRenderer { s.ExtendBaseWidget(s) scr := &scrollContainerRenderer{ - baseRenderer: baseRenderer{[]fyne.CanvasObject{s.Content}}, + BaseRenderer: widget.NewBaseRenderer([]fyne.CanvasObject{s.Content}), scroll: s, } if s.Direction != ScrollHorizontalOnly { scr.vertArea = newScrollBarArea(s, scrollBarOrientationVertical) scr.topShadow = newShadow(shadowBottom, submergedContentLevel) scr.bottomShadow = newShadow(shadowTop, submergedContentLevel) - scr.setObjects(append(scr.Objects(), scr.vertArea, scr.topShadow, scr.bottomShadow)) + scr.SetObjects(append(scr.Objects(), scr.vertArea, scr.topShadow, scr.bottomShadow)) } if s.Direction != ScrollVerticalOnly { scr.horizArea = newScrollBarArea(s, scrollBarOrientationHorizontal) scr.leftShadow = newShadow(shadowRight, submergedContentLevel) scr.rightShadow = newShadow(shadowLeft, submergedContentLevel) - scr.setObjects(append(scr.Objects(), scr.horizArea, scr.leftShadow, scr.rightShadow)) + scr.SetObjects(append(scr.Objects(), scr.horizArea, scr.leftShadow, scr.rightShadow)) } return scr } diff --git a/widget/shadow.go b/widget/shadow.go index 0001be1c76..ef8b78a456 100644 --- a/widget/shadow.go +++ b/widget/shadow.go @@ -5,6 +5,7 @@ import ( "fyne.io/fyne" "fyne.io/fyne/canvas" + "fyne.io/fyne/internal/widget" "fyne.io/fyne/theme" ) @@ -51,7 +52,7 @@ func (s *shadow) CreateRenderer() fyne.WidgetRenderer { } type shadowRenderer struct { - baseRenderer + widget.BaseRenderer b, l, r, t *canvas.LinearGradient bl, br, tl, tr *canvas.RadialGradient minSize fyne.Size @@ -62,16 +63,16 @@ func (r *shadowRenderer) createShadows() { switch r.s.typ { case shadowLeft: r.l = canvas.NewHorizontalGradient(color.Transparent, theme.ShadowColor()) - r.setObjects([]fyne.CanvasObject{r.l}) + r.SetObjects([]fyne.CanvasObject{r.l}) case shadowRight: r.r = canvas.NewHorizontalGradient(theme.ShadowColor(), color.Transparent) - r.setObjects([]fyne.CanvasObject{r.r}) + r.SetObjects([]fyne.CanvasObject{r.r}) case shadowBottom: r.b = canvas.NewVerticalGradient(theme.ShadowColor(), color.Transparent) - r.setObjects([]fyne.CanvasObject{r.b}) + r.SetObjects([]fyne.CanvasObject{r.b}) case shadowTop: r.t = canvas.NewVerticalGradient(color.Transparent, theme.ShadowColor()) - r.setObjects([]fyne.CanvasObject{r.t}) + r.SetObjects([]fyne.CanvasObject{r.t}) case shadowAround: r.tl = canvas.NewRadialGradient(theme.ShadowColor(), color.Transparent) r.tl.CenterOffsetX = 0.5 @@ -89,7 +90,7 @@ func (r *shadowRenderer) createShadows() { r.bl.CenterOffsetX = 0.5 r.bl.CenterOffsetY = -0.5 r.l = canvas.NewHorizontalGradient(color.Transparent, theme.ShadowColor()) - r.setObjects([]fyne.CanvasObject{r.tl, r.t, r.tr, r.r, r.br, r.b, r.bl, r.l}) + r.SetObjects([]fyne.CanvasObject{r.tl, r.t, r.tr, r.r, r.br, r.b, r.bl, r.l}) } } diff --git a/widget/shadowing_renderer.go b/widget/shadowing_renderer.go index 5297544af5..184e64fd82 100644 --- a/widget/shadowing_renderer.go +++ b/widget/shadowing_renderer.go @@ -2,12 +2,13 @@ package widget import ( "fyne.io/fyne" + "fyne.io/fyne/internal/widget" ) // When using the shadowingRenderer the embedding renderer should call // layoutShadow(contentSize, contentPos) to lay out the shadow. type shadowingRenderer struct { - baseRenderer + widget.BaseRenderer shadow fyne.CanvasObject } @@ -17,7 +18,7 @@ func newShadowingRenderer(objects []fyne.CanvasObject, level elevationLevel) *sh s = newShadow(shadowAround, level) } r := &shadowingRenderer{shadow: s} - r.setObjects(objects) + r.SetObjects(objects) return r } @@ -29,9 +30,10 @@ func (r *shadowingRenderer) layoutShadow(size fyne.Size, pos fyne.Position) { r.shadow.Move(pos) } -func (r *shadowingRenderer) setObjects(objects []fyne.CanvasObject) { +// SetObjects updates the objects of the renderer. +func (r *shadowingRenderer) SetObjects(objects []fyne.CanvasObject) { if r.shadow != nil { objects = append([]fyne.CanvasObject{r.shadow}, objects...) } - r.baseRenderer.setObjects(objects) + r.BaseRenderer.SetObjects(objects) } diff --git a/widget/shadowing_renderer_test.go b/widget/shadowing_renderer_test.go index 9c3ac5fdc7..c4fcad5fea 100644 --- a/widget/shadowing_renderer_test.go +++ b/widget/shadowing_renderer_test.go @@ -29,7 +29,7 @@ func TestShadowingRenderer_Objects(t *testing.T) { assert.Equal(t, append(tt.wantPrependedObjects, objects...), r.Objects()) otherObjects := []fyne.CanvasObject{NewLabel("X"), NewLabel("Y")} - r.setObjects(otherObjects) + r.SetObjects(otherObjects) assert.Equal(t, append(tt.wantPrependedObjects, otherObjects...), r.Objects()) }) } diff --git a/widget/slider.go b/widget/slider.go index 9b8a60e6de..7bee062080 100644 --- a/widget/slider.go +++ b/widget/slider.go @@ -5,6 +5,7 @@ import ( "fyne.io/fyne" "fyne.io/fyne/canvas" + "fyne.io/fyne/internal/widget" "fyne.io/fyne/theme" ) @@ -128,7 +129,7 @@ func (s *Slider) CreateRenderer() fyne.WidgetRenderer { objects := []fyne.CanvasObject{track, active, thumb} - return &sliderRenderer{baseRenderer{objects}, track, active, thumb, s} + return &sliderRenderer{widget.NewBaseRenderer(objects), track, active, thumb, s} } const ( @@ -137,7 +138,7 @@ const ( ) type sliderRenderer struct { - baseRenderer + widget.BaseRenderer track *canvas.Rectangle active *canvas.Rectangle thumb *canvas.Circle diff --git a/widget/text.go b/widget/text.go index 65c674f21b..489e72e90f 100644 --- a/widget/text.go +++ b/widget/text.go @@ -8,6 +8,7 @@ import ( "fyne.io/fyne" "fyne.io/fyne/canvas" "fyne.io/fyne/internal/cache" + "fyne.io/fyne/internal/widget" "fyne.io/fyne/theme" ) @@ -226,7 +227,7 @@ func (t *textProvider) lineSizeToColumn(col, row int) fyne.Size { // Renderer type textRenderer struct { - baseRenderer + widget.BaseRenderer texts []*canvas.Text provider *textProvider } @@ -304,7 +305,7 @@ func (r *textRenderer) Refresh() { if add { r.texts = append(r.texts, textCanvas) - r.setObjects(append(r.Objects(), textCanvas)) + r.SetObjects(append(r.Objects(), textCanvas)) } } diff --git a/widget/text_test.go b/widget/text_test.go index e51fac5b05..8fb50c847d 100644 --- a/widget/text_test.go +++ b/widget/text_test.go @@ -248,8 +248,8 @@ func TestTextRenderer_ApplyTheme(t *testing.T) { label := NewLabel("Test\nLine2") render := test.WidgetRenderer(label).(*textRenderer) - text1 := render.objects[0].(*canvas.Text) - text2 := render.objects[0].(*canvas.Text) + text1 := render.Objects()[0].(*canvas.Text) + text2 := render.Objects()[0].(*canvas.Text) customTextSize1 := text1.TextSize customTextSize2 := text2.TextSize withTestTheme(func() { diff --git a/widget/toolbar.go b/widget/toolbar.go index 0d25cf92d5..33b32ff4b7 100644 --- a/widget/toolbar.go +++ b/widget/toolbar.go @@ -5,6 +5,7 @@ import ( "fyne.io/fyne" "fyne.io/fyne/canvas" + "fyne.io/fyne/internal/widget" "fyne.io/fyne/layout" "fyne.io/fyne/theme" ) @@ -106,7 +107,7 @@ func NewToolbar(items ...ToolbarItem) *Toolbar { } type toolbarRenderer struct { - baseRenderer + widget.BaseRenderer layout fyne.Layout objs []fyne.CanvasObject toolbar *Toolbar @@ -143,5 +144,5 @@ func (r *toolbarRenderer) resetObjects() { r.objs = append(r.objs, item.ToolbarObject()) } } - r.setObjects(r.objs) + r.SetObjects(r.objs) } From c3b69f50f5f54d40cc02e7071093c8623850dfee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Mon, 13 Apr 2020 16:48:34 +0200 Subject: [PATCH 2/7] move internal shadow widget to internal widget package --- {widget => internal/widget}/shadow.go | 247 ++++++++++++++------- {widget => internal/widget}/shadow_test.go | 16 +- widget/button.go | 5 +- widget/button_test.go | 6 +- widget/menu_test.go | 3 +- widget/popup.go | 2 +- widget/scroller.go | 12 +- widget/select.go | 3 +- widget/shadowing_renderer.go | 4 +- 9 files changed, 190 insertions(+), 108 deletions(-) rename {widget => internal/widget}/shadow.go (60%) rename {widget => internal/widget}/shadow_test.go (92%) diff --git a/widget/shadow.go b/internal/widget/shadow.go similarity index 60% rename from widget/shadow.go rename to internal/widget/shadow.go index ef8b78a456..1d680497ee 100644 --- a/widget/shadow.go +++ b/internal/widget/shadow.go @@ -5,138 +5,141 @@ import ( "fyne.io/fyne" "fyne.io/fyne/canvas" - "fyne.io/fyne/internal/widget" + "fyne.io/fyne/internal/cache" "fyne.io/fyne/theme" ) -// elevationLevel is the level of elevation of the shadow casting object. -type elevationLevel int +// ElevationLevel is the level of elevation of the shadow casting object. +type ElevationLevel int -// elevationLevel constants inspired by: +// ElevationLevel constants inspired by: // https://storage.googleapis.com/spec-host/mio-staging%2Fmio-design%2F1584058305895%2Fassets%2F0B6xUSjjSulxceF9udnA4Sk5tdU0%2Fbaselineelevation-chart.png const ( - baseLevel elevationLevel = 0 - buttonLevel elevationLevel = 2 - popUpLevel elevationLevel = 8 - submergedContentLevel elevationLevel = 8 + BaseLevel ElevationLevel = 0 + ButtonLevel ElevationLevel = 2 + PopUpLevel ElevationLevel = 8 + SubmergedContentLevel ElevationLevel = 8 ) -type shadowType int +// ShadowType specifies the type of the shadow. +type ShadowType int +// ShadowType constants const ( - shadowAround shadowType = iota - shadowLeft - shadowRight - shadowBottom - shadowTop + ShadowAround ShadowType = iota + ShadowLeft + ShadowRight + ShadowBottom + ShadowTop ) -func newShadow(typ shadowType, level elevationLevel) *shadow { - s := &shadow{typ: typ, level: level} - s.ExtendBaseWidget(s) - return s +// NewShadow create a new Shadow. +func NewShadow(typ ShadowType, level ElevationLevel) *Shadow { + return &Shadow{typ: typ, level: level} } -var _ fyne.Widget = (*shadow)(nil) +var _ fyne.Widget = (*Shadow)(nil) -type shadow struct { - BaseWidget - typ shadowType - level elevationLevel +// Shadow is a widget that renders a shadow. +type Shadow struct { + hidden bool + level ElevationLevel + pos fyne.Position + size fyne.Size + typ ShadowType } -func (s *shadow) CreateRenderer() fyne.WidgetRenderer { +// CreateRenderer satisfies the fyne.Widget interface. +func (s *Shadow) CreateRenderer() fyne.WidgetRenderer { r := &shadowRenderer{s: s} r.createShadows() return r } -type shadowRenderer struct { - widget.BaseRenderer - b, l, r, t *canvas.LinearGradient - bl, br, tl, tr *canvas.RadialGradient - minSize fyne.Size - s *shadow +// Hide satisfies the fyne.Widget interface. +func (s *Shadow) Hide() { + if s.hidden { + return + } + + s.hidden = true + canvas.Refresh(s) } -func (r *shadowRenderer) createShadows() { - switch r.s.typ { - case shadowLeft: - r.l = canvas.NewHorizontalGradient(color.Transparent, theme.ShadowColor()) - r.SetObjects([]fyne.CanvasObject{r.l}) - case shadowRight: - r.r = canvas.NewHorizontalGradient(theme.ShadowColor(), color.Transparent) - r.SetObjects([]fyne.CanvasObject{r.r}) - case shadowBottom: - r.b = canvas.NewVerticalGradient(theme.ShadowColor(), color.Transparent) - r.SetObjects([]fyne.CanvasObject{r.b}) - case shadowTop: - r.t = canvas.NewVerticalGradient(color.Transparent, theme.ShadowColor()) - r.SetObjects([]fyne.CanvasObject{r.t}) - case shadowAround: - r.tl = canvas.NewRadialGradient(theme.ShadowColor(), color.Transparent) - r.tl.CenterOffsetX = 0.5 - r.tl.CenterOffsetY = 0.5 - r.t = canvas.NewVerticalGradient(color.Transparent, theme.ShadowColor()) - r.tr = canvas.NewRadialGradient(theme.ShadowColor(), color.Transparent) - r.tr.CenterOffsetX = -0.5 - r.tr.CenterOffsetY = 0.5 - r.r = canvas.NewHorizontalGradient(theme.ShadowColor(), color.Transparent) - r.br = canvas.NewRadialGradient(theme.ShadowColor(), color.Transparent) - r.br.CenterOffsetX = -0.5 - r.br.CenterOffsetY = -0.5 - r.b = canvas.NewVerticalGradient(theme.ShadowColor(), color.Transparent) - r.bl = canvas.NewRadialGradient(theme.ShadowColor(), color.Transparent) - r.bl.CenterOffsetX = 0.5 - r.bl.CenterOffsetY = -0.5 - r.l = canvas.NewHorizontalGradient(color.Transparent, theme.ShadowColor()) - r.SetObjects([]fyne.CanvasObject{r.tl, r.t, r.tr, r.r, r.br, r.b, r.bl, r.l}) - } +// MinSize satisfies the fyne.Widget interface. +func (s *Shadow) MinSize() fyne.Size { + return fyne.NewSize(0, 0) } -func updateShadowStart(g *canvas.LinearGradient) { - if g == nil { +// Move satisfies the fyne.Widget interface. +func (s *Shadow) Move(pos fyne.Position) { + s.pos = pos +} + +// Position satisfies the fyne.Widget interface. +func (s *Shadow) Position() fyne.Position { + return s.pos +} + +// Refresh satisfies the fyne.Widget interface. +func (s *Shadow) Refresh() { + r := cache.Renderer(s) + if r == nil { return } - g.StartColor = theme.ShadowColor() - g.Refresh() + r.Refresh() } -func updateShadowEnd(g *canvas.LinearGradient) { - if g == nil { +// Resize satisfies the fyne.Widget interface. +func (s *Shadow) Resize(size fyne.Size) { + if s.size == size { return } - g.EndColor = theme.ShadowColor() - g.Refresh() + s.size = size + r := cache.Renderer(s) + if r == nil { + return + } + + r.Layout(size) } -func updateShadowRadial(g *canvas.RadialGradient) { - if g == nil { +// Show satisfies the fyne.Widget interface. +func (s *Shadow) Show() { + if !s.hidden { return } - g.StartColor = theme.ShadowColor() - g.Refresh() + s.hidden = false + s.Refresh() } -func (r *shadowRenderer) refreshShadows() { - updateShadowEnd(r.l) - updateShadowStart(r.r) - updateShadowStart(r.b) - updateShadowEnd(r.t) +// Size satisfies the fyne.Widget interface. +func (s *Shadow) Size() fyne.Size { + return s.size +} - updateShadowRadial(r.tl) - updateShadowRadial(r.tr) - updateShadowRadial(r.bl) - updateShadowRadial(r.br) +// Visible satisfies the fyne.Widget interface. +func (s *Shadow) Visible() bool { + return !s.hidden +} + +type shadowRenderer struct { + BaseRenderer + b, l, r, t *canvas.LinearGradient + bl, br, tl, tr *canvas.RadialGradient + minSize fyne.Size + s *Shadow } +// BackgroundColor satisfies the fyne.WidgetRenderer interface. func (r *shadowRenderer) BackgroundColor() color.Color { return color.Transparent } +// Layout satisfies the fyne.WidgetRenderer interface. func (r *shadowRenderer) Layout(size fyne.Size) { depth := int(r.s.level) if r.tl != nil { @@ -173,11 +176,87 @@ func (r *shadowRenderer) Layout(size fyne.Size) { } } +// MinSize satisfies the fyne.WidgetRenderer interface. func (r *shadowRenderer) MinSize() fyne.Size { return r.minSize } +// Refresh satisfies the fyne.WidgetRenderer interface. func (r *shadowRenderer) Refresh() { r.refreshShadows() r.Layout(r.s.Size()) } + +func (r *shadowRenderer) createShadows() { + switch r.s.typ { + case ShadowLeft: + r.l = canvas.NewHorizontalGradient(color.Transparent, theme.ShadowColor()) + r.SetObjects([]fyne.CanvasObject{r.l}) + case ShadowRight: + r.r = canvas.NewHorizontalGradient(theme.ShadowColor(), color.Transparent) + r.SetObjects([]fyne.CanvasObject{r.r}) + case ShadowBottom: + r.b = canvas.NewVerticalGradient(theme.ShadowColor(), color.Transparent) + r.SetObjects([]fyne.CanvasObject{r.b}) + case ShadowTop: + r.t = canvas.NewVerticalGradient(color.Transparent, theme.ShadowColor()) + r.SetObjects([]fyne.CanvasObject{r.t}) + case ShadowAround: + r.tl = canvas.NewRadialGradient(theme.ShadowColor(), color.Transparent) + r.tl.CenterOffsetX = 0.5 + r.tl.CenterOffsetY = 0.5 + r.t = canvas.NewVerticalGradient(color.Transparent, theme.ShadowColor()) + r.tr = canvas.NewRadialGradient(theme.ShadowColor(), color.Transparent) + r.tr.CenterOffsetX = -0.5 + r.tr.CenterOffsetY = 0.5 + r.r = canvas.NewHorizontalGradient(theme.ShadowColor(), color.Transparent) + r.br = canvas.NewRadialGradient(theme.ShadowColor(), color.Transparent) + r.br.CenterOffsetX = -0.5 + r.br.CenterOffsetY = -0.5 + r.b = canvas.NewVerticalGradient(theme.ShadowColor(), color.Transparent) + r.bl = canvas.NewRadialGradient(theme.ShadowColor(), color.Transparent) + r.bl.CenterOffsetX = 0.5 + r.bl.CenterOffsetY = -0.5 + r.l = canvas.NewHorizontalGradient(color.Transparent, theme.ShadowColor()) + r.SetObjects([]fyne.CanvasObject{r.tl, r.t, r.tr, r.r, r.br, r.b, r.bl, r.l}) + } +} + +func (r *shadowRenderer) refreshShadows() { + updateShadowEnd(r.l) + updateShadowStart(r.r) + updateShadowStart(r.b) + updateShadowEnd(r.t) + + updateShadowRadial(r.tl) + updateShadowRadial(r.tr) + updateShadowRadial(r.bl) + updateShadowRadial(r.br) +} + +func updateShadowEnd(g *canvas.LinearGradient) { + if g == nil { + return + } + + g.EndColor = theme.ShadowColor() + g.Refresh() +} + +func updateShadowRadial(g *canvas.RadialGradient) { + if g == nil { + return + } + + g.StartColor = theme.ShadowColor() + g.Refresh() +} + +func updateShadowStart(g *canvas.LinearGradient) { + if g == nil { + return + } + + g.StartColor = theme.ShadowColor() + g.Refresh() +} diff --git a/widget/shadow_test.go b/internal/widget/shadow_test.go similarity index 92% rename from widget/shadow_test.go rename to internal/widget/shadow_test.go index b6d04aa764..1f003ea755 100644 --- a/widget/shadow_test.go +++ b/internal/widget/shadow_test.go @@ -11,11 +11,11 @@ import ( "github.com/stretchr/testify/assert" ) -var shadowLevel = elevationLevel(5) +var shadowLevel = ElevationLevel(5) var shadowWidth = int(shadowLevel) func TestShadow_TopShadow(t *testing.T) { - s := newShadow(shadowTop, shadowLevel) + s := NewShadow(ShadowTop, shadowLevel) r := test.WidgetRenderer(s).(*shadowRenderer) r.Layout(fyne.NewSize(100, 100)) @@ -28,7 +28,7 @@ func TestShadow_TopShadow(t *testing.T) { } func TestShadow_BottomShadow(t *testing.T) { - s := newShadow(shadowBottom, shadowLevel) + s := NewShadow(ShadowBottom, shadowLevel) r := test.WidgetRenderer(s).(*shadowRenderer) r.Layout(fyne.NewSize(100, 100)) @@ -41,7 +41,7 @@ func TestShadow_BottomShadow(t *testing.T) { } func TestShadow_AroundShadow(t *testing.T) { - s := newShadow(shadowAround, shadowLevel) + s := NewShadow(ShadowAround, shadowLevel) r := test.WidgetRenderer(s).(*shadowRenderer) r.Layout(fyne.NewSize(100, 100)) @@ -106,7 +106,7 @@ func TestShadow_AroundShadow(t *testing.T) { func TestShadow_ApplyTheme(t *testing.T) { fyne.CurrentApp().Settings().SetTheme(theme.DarkTheme()) - s := newShadow(shadowAround, shadowLevel) + s := NewShadow(ShadowAround, shadowLevel) r := test.WidgetRenderer(s).(*shadowRenderer) assert.Equal(t, theme.ShadowColor(), r.b.StartColor) @@ -116,15 +116,15 @@ func TestShadow_ApplyTheme(t *testing.T) { } func TestShadow_BackgroundColor(t *testing.T) { - assert.Equal(t, color.Transparent, test.WidgetRenderer(newShadow(shadowAround, 1)).BackgroundColor()) + assert.Equal(t, color.Transparent, test.WidgetRenderer(NewShadow(ShadowAround, 1)).BackgroundColor()) } func TestShadow_MinSize(t *testing.T) { - assert.Equal(t, fyne.NewSize(0, 0), newShadow(shadowAround, 1).MinSize()) + assert.Equal(t, fyne.NewSize(0, 0), NewShadow(ShadowAround, 1).MinSize()) } func TestShadow_Theme(t *testing.T) { - shadow := newShadow(shadowAround, 1) + shadow := NewShadow(ShadowAround, 1) light := theme.LightTheme() fyne.CurrentApp().Settings().SetTheme(light) shadow.Refresh() diff --git a/widget/button.go b/widget/button.go index 0c6595e35e..a0047c1dca 100644 --- a/widget/button.go +++ b/widget/button.go @@ -7,6 +7,7 @@ import ( "fyne.io/fyne" "fyne.io/fyne/canvas" "fyne.io/fyne/driver/desktop" + "fyne.io/fyne/internal/widget" "fyne.io/fyne/theme" ) @@ -188,9 +189,9 @@ func (b *Button) CreateRenderer() fyne.WidgetRenderer { objects := []fyne.CanvasObject{ text, } - shadowLevel := buttonLevel + shadowLevel := widget.ButtonLevel if b.HideShadow { - shadowLevel = baseLevel + shadowLevel = widget.BaseLevel } if icon != nil { objects = append(objects, icon) diff --git a/widget/button_test.go b/widget/button_test.go index fc1898933e..a30cfe8ce5 100644 --- a/widget/button_test.go +++ b/widget/button_test.go @@ -7,6 +7,7 @@ import ( "fyne.io/fyne" "fyne.io/fyne/driver/desktop" + "fyne.io/fyne/internal/widget" "fyne.io/fyne/test" "fyne.io/fyne/theme" @@ -232,9 +233,8 @@ func TestButton_Shadow(t *testing.T) { button := NewButton("Test", func() {}) shadowFound := false for _, o := range test.LaidOutObjects(button) { - if s, ok := o.(*shadow); ok { + if _, ok := o.(*widget.Shadow); ok { shadowFound = true - assert.Equal(t, elevationLevel(2), s.level) } } if !shadowFound { @@ -245,7 +245,7 @@ func TestButton_Shadow(t *testing.T) { button := NewButton("Test", func() {}) button.HideShadow = true for _, o := range test.LaidOutObjects(button) { - if _, ok := o.(*shadow); ok { + if _, ok := o.(*widget.Shadow); ok { assert.Fail(t, "button with HideShadow == true should not create a shadow") } } diff --git a/widget/menu_test.go b/widget/menu_test.go index 1754ece4e8..ff905632fe 100644 --- a/widget/menu_test.go +++ b/widget/menu_test.go @@ -6,6 +6,7 @@ import ( "fyne.io/fyne" "fyne.io/fyne/canvas" + "fyne.io/fyne/internal/widget" "fyne.io/fyne/test" "fyne.io/fyne/theme" @@ -41,7 +42,7 @@ func TestPopUpMenu_Size(t *testing.T) { assert.Equal(t, expectedSize, pop.Content.Size()) for _, o := range test.LaidOutObjects(pop) { - if s, ok := o.(*shadow); ok { + if s, ok := o.(*widget.Shadow); ok { assert.Equal(t, expectedSize, s.Size(), "infer pop-up’s inner size from shadow’s size") } } diff --git a/widget/popup.go b/widget/popup.go index ca651f090e..926c216d0b 100644 --- a/widget/popup.go +++ b/widget/popup.go @@ -102,7 +102,7 @@ func (p *PopUp) CreateRenderer() fyne.WidgetRenderer { return &modalPopUpRenderer{widget.NewBaseRenderer(objects), popUpBaseRenderer{popUp: p, bg: bg}} } - return &popUpRenderer{newShadowingRenderer(objects, popUpLevel), popUpBaseRenderer{popUp: p, bg: bg}} + return &popUpRenderer{newShadowingRenderer(objects, widget.PopUpLevel), popUpBaseRenderer{popUp: p, bg: bg}} } // NewPopUpAtPosition creates a new popUp for the specified content at the specified absolute position. diff --git a/widget/scroller.go b/widget/scroller.go index c261d463ab..54ba0197d7 100644 --- a/widget/scroller.go +++ b/widget/scroller.go @@ -227,8 +227,8 @@ type scrollContainerRenderer struct { scroll *ScrollContainer vertArea *scrollBarArea horizArea *scrollBarArea - leftShadow, rightShadow *shadow - topShadow, bottomShadow *shadow + leftShadow, rightShadow *widget.Shadow + topShadow, bottomShadow *widget.Shadow } func (r *scrollContainerRenderer) Layout(size fyne.Size) { @@ -330,14 +330,14 @@ func (s *ScrollContainer) CreateRenderer() fyne.WidgetRenderer { } if s.Direction != ScrollHorizontalOnly { scr.vertArea = newScrollBarArea(s, scrollBarOrientationVertical) - scr.topShadow = newShadow(shadowBottom, submergedContentLevel) - scr.bottomShadow = newShadow(shadowTop, submergedContentLevel) + scr.topShadow = widget.NewShadow(widget.ShadowBottom, widget.SubmergedContentLevel) + scr.bottomShadow = widget.NewShadow(widget.ShadowTop, widget.SubmergedContentLevel) scr.SetObjects(append(scr.Objects(), scr.vertArea, scr.topShadow, scr.bottomShadow)) } if s.Direction != ScrollVerticalOnly { scr.horizArea = newScrollBarArea(s, scrollBarOrientationHorizontal) - scr.leftShadow = newShadow(shadowRight, submergedContentLevel) - scr.rightShadow = newShadow(shadowLeft, submergedContentLevel) + scr.leftShadow = widget.NewShadow(widget.ShadowRight, widget.SubmergedContentLevel) + scr.rightShadow = widget.NewShadow(widget.ShadowLeft, widget.SubmergedContentLevel) scr.SetObjects(append(scr.Objects(), scr.horizArea, scr.leftShadow, scr.rightShadow)) } return scr diff --git a/widget/select.go b/widget/select.go index 18d8d48b28..edea510ff0 100644 --- a/widget/select.go +++ b/widget/select.go @@ -6,6 +6,7 @@ import ( "fyne.io/fyne" "fyne.io/fyne/canvas" "fyne.io/fyne/driver/desktop" + "fyne.io/fyne/internal/widget" "fyne.io/fyne/theme" ) @@ -187,7 +188,7 @@ func (s *Select) CreateRenderer() fyne.WidgetRenderer { text.Alignment = fyne.TextAlignLeading objects := []fyne.CanvasObject{text, icon} - return &selectRenderer{newShadowingRenderer(objects, buttonLevel), icon, text, s} + return &selectRenderer{newShadowingRenderer(objects, widget.ButtonLevel), icon, text, s} } // ClearSelected clears the current option of the select widget. After diff --git a/widget/shadowing_renderer.go b/widget/shadowing_renderer.go index 184e64fd82..422cd044ec 100644 --- a/widget/shadowing_renderer.go +++ b/widget/shadowing_renderer.go @@ -12,10 +12,10 @@ type shadowingRenderer struct { shadow fyne.CanvasObject } -func newShadowingRenderer(objects []fyne.CanvasObject, level elevationLevel) *shadowingRenderer { +func newShadowingRenderer(objects []fyne.CanvasObject, level widget.ElevationLevel) *shadowingRenderer { var s fyne.CanvasObject if level > 0 { - s = newShadow(shadowAround, level) + s = widget.NewShadow(widget.ShadowAround, level) } r := &shadowingRenderer{shadow: s} r.SetObjects(objects) From 5b0ec87a5881fe49887baa628c812412b79df28b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Mon, 13 Apr 2020 16:35:52 +0200 Subject: [PATCH 3/7] move shadowingRenderer into internal widget package --- internal/widget/shadowing_renderer.go | 41 +++++++++++++++++++ .../widget}/shadowing_renderer_test.go | 14 ++++--- widget/button.go | 6 +-- widget/popup.go | 14 +++++-- widget/select.go | 6 +-- widget/shadowing_renderer.go | 39 ------------------ 6 files changed, 65 insertions(+), 55 deletions(-) create mode 100644 internal/widget/shadowing_renderer.go rename {widget => internal/widget}/shadowing_renderer_test.go (59%) delete mode 100644 widget/shadowing_renderer.go diff --git a/internal/widget/shadowing_renderer.go b/internal/widget/shadowing_renderer.go new file mode 100644 index 0000000000..d9caa56fe6 --- /dev/null +++ b/internal/widget/shadowing_renderer.go @@ -0,0 +1,41 @@ +package widget + +import ( + "fyne.io/fyne" +) + +// ShadowingRenderer is a renderer that adds a shadow arount the rendered content. +// When using the ShadowingRenderer the embedding renderer should call +// LayoutShadow(contentSize, contentPos) to lay out the shadow. +type ShadowingRenderer struct { + BaseRenderer + shadow fyne.CanvasObject +} + +// NewShadowingRenderer creates a ShadowingRenderer. +func NewShadowingRenderer(objects []fyne.CanvasObject, level ElevationLevel) *ShadowingRenderer { + var s fyne.CanvasObject + if level > 0 { + s = NewShadow(ShadowAround, level) + } + r := &ShadowingRenderer{shadow: s} + r.SetObjects(objects) + return r +} + +// LayoutShadow adjusts the size and position of the shadow if necessary. +func (r *ShadowingRenderer) LayoutShadow(size fyne.Size, pos fyne.Position) { + if r.shadow == nil { + return + } + r.shadow.Resize(size) + r.shadow.Move(pos) +} + +// SetObjects updates the renderer's objects including the shadow if necessary. +func (r *ShadowingRenderer) SetObjects(objects []fyne.CanvasObject) { + if r.shadow != nil { + objects = append([]fyne.CanvasObject{r.shadow}, objects...) + } + r.BaseRenderer.SetObjects(objects) +} diff --git a/widget/shadowing_renderer_test.go b/internal/widget/shadowing_renderer_test.go similarity index 59% rename from widget/shadowing_renderer_test.go rename to internal/widget/shadowing_renderer_test.go index c4fcad5fea..d17e535759 100644 --- a/widget/shadowing_renderer_test.go +++ b/internal/widget/shadowing_renderer_test.go @@ -1,4 +1,4 @@ -package widget +package widget_test import ( "testing" @@ -6,16 +6,18 @@ import ( "github.com/stretchr/testify/assert" "fyne.io/fyne" + w "fyne.io/fyne/internal/widget" + "fyne.io/fyne/widget" ) func TestShadowingRenderer_Objects(t *testing.T) { tests := map[string]struct { - level elevationLevel + level w.ElevationLevel wantPrependedObjects []fyne.CanvasObject }{ "with shadow": { 12, - []fyne.CanvasObject{newShadow(shadowAround, 12)}, + []fyne.CanvasObject{w.NewShadow(w.ShadowAround, 12)}, }, "without shadow": { 0, @@ -24,11 +26,11 @@ func TestShadowingRenderer_Objects(t *testing.T) { } for name, tt := range tests { t.Run(name, func(t *testing.T) { - objects := []fyne.CanvasObject{NewLabel("A"), NewLabel("B")} - r := newShadowingRenderer(objects, tt.level) + objects := []fyne.CanvasObject{widget.NewLabel("A"), widget.NewLabel("B")} + r := w.NewShadowingRenderer(objects, tt.level) assert.Equal(t, append(tt.wantPrependedObjects, objects...), r.Objects()) - otherObjects := []fyne.CanvasObject{NewLabel("X"), NewLabel("Y")} + otherObjects := []fyne.CanvasObject{widget.NewLabel("X"), widget.NewLabel("Y")} r.SetObjects(otherObjects) assert.Equal(t, append(tt.wantPrependedObjects, otherObjects...), r.Objects()) }) diff --git a/widget/button.go b/widget/button.go index a0047c1dca..faecb4f300 100644 --- a/widget/button.go +++ b/widget/button.go @@ -12,7 +12,7 @@ import ( ) type buttonRenderer struct { - *shadowingRenderer + *widget.ShadowingRenderer icon *canvas.Image label *canvas.Text @@ -47,7 +47,7 @@ func (b *buttonRenderer) MinSize() fyne.Size { // Layout the components of the button widget func (b *buttonRenderer) Layout(size fyne.Size) { - b.layoutShadow(size, fyne.NewPos(0, 0)) + b.LayoutShadow(size, fyne.NewPos(0, 0)) if b.button.Text != "" { padding := b.padding() innerSize := size.Subtract(padding) @@ -197,7 +197,7 @@ func (b *Button) CreateRenderer() fyne.WidgetRenderer { objects = append(objects, icon) } - return &buttonRenderer{newShadowingRenderer(objects, shadowLevel), icon, text, b} + return &buttonRenderer{widget.NewShadowingRenderer(objects, shadowLevel), icon, text, b} } // SetText allows the button label to be changed diff --git a/widget/popup.go b/widget/popup.go index 926c216d0b..c3744a02a2 100644 --- a/widget/popup.go +++ b/widget/popup.go @@ -99,10 +99,16 @@ func (p *PopUp) CreateRenderer() fyne.WidgetRenderer { bg := canvas.NewRectangle(theme.BackgroundColor()) objects := []fyne.CanvasObject{bg, p.Content} if p.modal { - return &modalPopUpRenderer{widget.NewBaseRenderer(objects), popUpBaseRenderer{popUp: p, bg: bg}} + return &modalPopUpRenderer{ + widget.NewBaseRenderer(objects), + popUpBaseRenderer{popUp: p, bg: bg}, + } } - return &popUpRenderer{newShadowingRenderer(objects, widget.PopUpLevel), popUpBaseRenderer{popUp: p, bg: bg}} + return &popUpRenderer{ + widget.NewShadowingRenderer(objects, widget.PopUpLevel), + popUpBaseRenderer{popUp: p, bg: bg}, + } } // NewPopUpAtPosition creates a new popUp for the specified content at the specified absolute position. @@ -179,7 +185,7 @@ func (r *popUpBaseRenderer) offset() fyne.Position { } type popUpRenderer struct { - *shadowingRenderer + *widget.ShadowingRenderer popUpBaseRenderer } @@ -211,7 +217,7 @@ func (r *popUpRenderer) Layout(_ fyne.Size) { r.bg.Resize(r.popUp.innerSize) r.bg.Move(innerPos) - r.layoutShadow(r.popUp.innerSize, innerPos) + r.LayoutShadow(r.popUp.innerSize, innerPos) } func (r *popUpRenderer) MinSize() fyne.Size { diff --git a/widget/select.go b/widget/select.go index edea510ff0..40e409812a 100644 --- a/widget/select.go +++ b/widget/select.go @@ -13,7 +13,7 @@ import ( const defaultPlaceHolder string = "(Select one)" type selectRenderer struct { - *shadowingRenderer + *widget.ShadowingRenderer icon *Icon label *canvas.Text @@ -36,7 +36,7 @@ func (s *selectRenderer) MinSize() fyne.Size { // Layout the components of the button widget func (s *selectRenderer) Layout(size fyne.Size) { - s.layoutShadow(size, fyne.NewPos(0, 0)) + s.LayoutShadow(size, fyne.NewPos(0, 0)) inner := size.Subtract(fyne.NewSize(theme.Padding()*4, theme.Padding()*2)) offset := fyne.NewSize(theme.IconInlineSize(), 0) @@ -188,7 +188,7 @@ func (s *Select) CreateRenderer() fyne.WidgetRenderer { text.Alignment = fyne.TextAlignLeading objects := []fyne.CanvasObject{text, icon} - return &selectRenderer{newShadowingRenderer(objects, widget.ButtonLevel), icon, text, s} + return &selectRenderer{widget.NewShadowingRenderer(objects, widget.ButtonLevel), icon, text, s} } // ClearSelected clears the current option of the select widget. After diff --git a/widget/shadowing_renderer.go b/widget/shadowing_renderer.go deleted file mode 100644 index 422cd044ec..0000000000 --- a/widget/shadowing_renderer.go +++ /dev/null @@ -1,39 +0,0 @@ -package widget - -import ( - "fyne.io/fyne" - "fyne.io/fyne/internal/widget" -) - -// When using the shadowingRenderer the embedding renderer should call -// layoutShadow(contentSize, contentPos) to lay out the shadow. -type shadowingRenderer struct { - widget.BaseRenderer - shadow fyne.CanvasObject -} - -func newShadowingRenderer(objects []fyne.CanvasObject, level widget.ElevationLevel) *shadowingRenderer { - var s fyne.CanvasObject - if level > 0 { - s = widget.NewShadow(widget.ShadowAround, level) - } - r := &shadowingRenderer{shadow: s} - r.SetObjects(objects) - return r -} - -func (r *shadowingRenderer) layoutShadow(size fyne.Size, pos fyne.Position) { - if r.shadow == nil { - return - } - r.shadow.Resize(size) - r.shadow.Move(pos) -} - -// SetObjects updates the objects of the renderer. -func (r *shadowingRenderer) SetObjects(objects []fyne.CanvasObject) { - if r.shadow != nil { - objects = append([]fyne.CanvasObject{r.shadow}, objects...) - } - r.BaseRenderer.SetObjects(objects) -} From 6fbd407f0340aeb5f2953154f83b40fd47028d8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Mon, 13 Apr 2020 20:46:02 +0200 Subject: [PATCH 4/7] extract internal widget base from Shadow widget --- internal/widget/base.go | 83 +++++++++++++++++++++++++++++++++++++++ internal/widget/shadow.go | 64 ++++-------------------------- 2 files changed, 91 insertions(+), 56 deletions(-) create mode 100644 internal/widget/base.go diff --git a/internal/widget/base.go b/internal/widget/base.go new file mode 100644 index 0000000000..d8d73fcea4 --- /dev/null +++ b/internal/widget/base.go @@ -0,0 +1,83 @@ +package widget + +import ( + "fyne.io/fyne" + "fyne.io/fyne/canvas" + "fyne.io/fyne/internal/cache" +) + +type base struct { + hidden bool + pos fyne.Position + size fyne.Size +} + +// Move satisfies the fyne.Widget interface. +func (b *base) Move(pos fyne.Position) { + b.pos = pos +} + +// Position satisfies the fyne.Widget interface. +func (b *base) Position() fyne.Position { + return b.pos +} + +// Size satisfies the fyne.Widget interface. +func (b *base) Size() fyne.Size { + return b.size +} + +// Visible satisfies the fyne.Widget interface. +func (b *base) Visible() bool { + return !b.hidden +} + +func (b *base) hide(w fyne.Widget) { + if b.hidden { + return + } + + b.hidden = true + canvas.Refresh(w) +} + +func (b *base) minSize(w fyne.Widget) fyne.Size { + r := cache.Renderer(w) + if r == nil { + return fyne.NewSize(0, 0) + } + + return r.MinSize() +} + +func (b *base) refresh(w fyne.Widget) { + r := cache.Renderer(w) + if r == nil { + return + } + + r.Refresh() +} + +func (b *base) resize(size fyne.Size, w fyne.Widget) { + if b.size == size { + return + } + + b.size = size + r := cache.Renderer(w) + if r == nil { + return + } + + r.Layout(size) +} + +func (b *base) show(w fyne.Widget) { + if !b.hidden { + return + } + + b.hidden = false + w.Refresh() +} diff --git a/internal/widget/shadow.go b/internal/widget/shadow.go index 1d680497ee..47ef96847c 100644 --- a/internal/widget/shadow.go +++ b/internal/widget/shadow.go @@ -5,7 +5,6 @@ import ( "fyne.io/fyne" "fyne.io/fyne/canvas" - "fyne.io/fyne/internal/cache" "fyne.io/fyne/theme" ) @@ -42,11 +41,9 @@ var _ fyne.Widget = (*Shadow)(nil) // Shadow is a widget that renders a shadow. type Shadow struct { - hidden bool - level ElevationLevel - pos fyne.Position - size fyne.Size - typ ShadowType + base + level ElevationLevel + typ ShadowType } // CreateRenderer satisfies the fyne.Widget interface. @@ -58,72 +55,27 @@ func (s *Shadow) CreateRenderer() fyne.WidgetRenderer { // Hide satisfies the fyne.Widget interface. func (s *Shadow) Hide() { - if s.hidden { - return - } - - s.hidden = true - canvas.Refresh(s) + s.hide(s) } // MinSize satisfies the fyne.Widget interface. func (s *Shadow) MinSize() fyne.Size { - return fyne.NewSize(0, 0) -} - -// Move satisfies the fyne.Widget interface. -func (s *Shadow) Move(pos fyne.Position) { - s.pos = pos -} - -// Position satisfies the fyne.Widget interface. -func (s *Shadow) Position() fyne.Position { - return s.pos + return s.minSize(s) } // Refresh satisfies the fyne.Widget interface. func (s *Shadow) Refresh() { - r := cache.Renderer(s) - if r == nil { - return - } - - r.Refresh() + s.refresh(s) } // Resize satisfies the fyne.Widget interface. func (s *Shadow) Resize(size fyne.Size) { - if s.size == size { - return - } - - s.size = size - r := cache.Renderer(s) - if r == nil { - return - } - - r.Layout(size) + s.resize(size, s) } // Show satisfies the fyne.Widget interface. func (s *Shadow) Show() { - if !s.hidden { - return - } - - s.hidden = false - s.Refresh() -} - -// Size satisfies the fyne.Widget interface. -func (s *Shadow) Size() fyne.Size { - return s.size -} - -// Visible satisfies the fyne.Widget interface. -func (s *Shadow) Visible() bool { - return !s.hidden + s.show(s) } type shadowRenderer struct { From 9716be8d7ef4071807aee88756274e513121404e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Wed, 15 Apr 2020 18:37:59 +0200 Subject: [PATCH 5/7] move menuItemWidget to internal widget.MenuItem --- internal/widget/menu_item.go | 129 +++++++++++++++++++++++++++++++++++ widget/menu.go | 96 +------------------------- 2 files changed, 132 insertions(+), 93 deletions(-) create mode 100644 internal/widget/menu_item.go diff --git a/internal/widget/menu_item.go b/internal/widget/menu_item.go new file mode 100644 index 0000000000..92f560b896 --- /dev/null +++ b/internal/widget/menu_item.go @@ -0,0 +1,129 @@ +package widget + +import ( + "image/color" + + "fyne.io/fyne" + "fyne.io/fyne/canvas" + "fyne.io/fyne/driver/desktop" + "fyne.io/fyne/theme" +) + +// NewMenuItem creates a new MenuItem. +func NewMenuItem(item *fyne.MenuItem) *MenuItem { + return &MenuItem{Item: item} +} + +// NewMenuItemSeparator creates a separator meant to separate MenuItems. +func NewMenuItemSeparator() fyne.CanvasObject { + s := canvas.NewRectangle(theme.DisabledTextColor()) + s.SetMinSize(fyne.NewSize(1, 2)) + return s +} + +var _ fyne.Widget = (*MenuItem)(nil) + +// MenuItem is a widget for displaying a fyne.MenuItem. +type MenuItem struct { + base + DismissAction func() + Item *fyne.MenuItem + + hovered bool +} + +// CreateRenderer satisfies the fyne.Widget interface. +func (i *MenuItem) CreateRenderer() fyne.WidgetRenderer { + text := canvas.NewText(i.Item.Label, theme.TextColor()) + return &menuItemRenderer{NewBaseRenderer([]fyne.CanvasObject{text}), i, text} +} + +// Hide satisfies the fyne.Widget interface. +func (i *MenuItem) Hide() { + i.hide(i) +} + +// MinSize satisfies the fyne.Widget interface. +func (i *MenuItem) MinSize() fyne.Size { + return i.minSize(i) +} + +// MouseIn satisfies the desktop.Hoverable interface. +func (i *MenuItem) MouseIn(*desktop.MouseEvent) { + i.hovered = true + i.Refresh() +} + +// MouseMoved satisfies the desktop.Hoverable interface. +func (i *MenuItem) MouseMoved(*desktop.MouseEvent) { +} + +// MouseOut satisfies the desktop.Hoverable interface. +func (i *MenuItem) MouseOut() { + i.hovered = false + i.Refresh() +} + +// Refresh satisfies the fyne.Widget interface. +func (i *MenuItem) Refresh() { + i.refresh(i) +} + +// Resize satisfies the fyne.Widget interface. +func (i *MenuItem) Resize(size fyne.Size) { + i.resize(size, i) +} + +// Show satisfies the fyne.Widget interface. +func (i *MenuItem) Show() { + i.show(i) +} + +// Tapped satisfies the fyne.Tappable interface. +func (i *MenuItem) Tapped(*fyne.PointEvent) { + i.Item.Action() + if i.DismissAction != nil { + i.DismissAction() + } +} + +type menuItemRenderer struct { + BaseRenderer + i *MenuItem + text *canvas.Text +} + +// BackgroundColor satisfies the fyne.WidgetRenderer interface. +func (r *menuItemRenderer) BackgroundColor() color.Color { + if r.i.hovered { + return theme.HoverColor() + } + + return color.Transparent +} + +// Layout satisfies the fyne.WidgetRenderer interface. +func (r *menuItemRenderer) Layout(fyne.Size) { + padding := r.padding() + r.text.Resize(r.text.MinSize()) + r.text.Move(fyne.NewPos(padding.Width/2, padding.Height/2)) +} + +// MinSize satisfies the fyne.WidgetRenderer interface. +func (r *menuItemRenderer) MinSize() fyne.Size { + return r.text.MinSize().Add(r.padding()) +} + +// Refresh satisfies the fyne.WidgetRenderer interface. +func (r *menuItemRenderer) Refresh() { + if r.text.TextSize != theme.TextSize() { + defer r.Layout(r.i.Size()) + } + r.text.TextSize = theme.TextSize() + r.text.Color = theme.TextColor() + canvas.Refresh(r.text) +} + +func (r *menuItemRenderer) padding() fyne.Size { + return fyne.NewSize(theme.Padding()*4, theme.Padding()*2) +} diff --git a/widget/menu.go b/widget/menu.go index f89cd0756e..de55516190 100644 --- a/widget/menu.go +++ b/widget/menu.go @@ -1,13 +1,8 @@ package widget import ( - "image/color" - "fyne.io/fyne" - "fyne.io/fyne/canvas" - "fyne.io/fyne/driver/desktop" "fyne.io/fyne/internal/widget" - "fyne.io/fyne/theme" ) // NewPopUpMenuAtPosition creates a PopUp widget populated with menu items from the passed menu structure. @@ -16,16 +11,16 @@ func NewPopUpMenuAtPosition(menu *fyne.Menu, c fyne.Canvas, pos fyne.Position) * options := NewVBox() for _, item := range menu.Items { if item.IsSeparator { - options.Append(newSeparator()) + options.Append(widget.NewMenuItemSeparator()) } else { - options.Append(newMenuItemWidget(item)) + options.Append(widget.NewMenuItem(item)) } } pop := newPopUp(options, c) pop.NotPadded = true focused := c.Focused() for _, o := range options.Children { - if item, ok := o.(*menuItemWidget); ok { + if item, ok := o.(*widget.MenuItem); ok { item.DismissAction = func() { if c.Focused() == nil { c.Focus(focused) @@ -43,88 +38,3 @@ func NewPopUpMenuAtPosition(menu *fyne.Menu, c fyne.Canvas, pos fyne.Position) * func NewPopUpMenu(menu *fyne.Menu, c fyne.Canvas) *PopUp { return NewPopUpMenuAtPosition(menu, c, fyne.NewPos(0, 0)) } - -type menuItemWidget struct { - BaseWidget - DismissAction func() - Item *fyne.MenuItem - - hovered bool -} - -func (t *menuItemWidget) Tapped(*fyne.PointEvent) { - t.Item.Action() - if t.DismissAction != nil { - t.DismissAction() - } -} - -func (t *menuItemWidget) CreateRenderer() fyne.WidgetRenderer { - text := canvas.NewText(t.Item.Label, theme.TextColor()) - return &menuItemWidgetRenderer{widget.NewBaseRenderer([]fyne.CanvasObject{text}), text, t} -} - -// MouseIn is called when a desktop pointer enters the widget -func (t *menuItemWidget) MouseIn(*desktop.MouseEvent) { - t.hovered = true - t.Refresh() -} - -// MouseOut is called when a desktop pointer exits the widget -func (t *menuItemWidget) MouseOut() { - t.hovered = false - t.Refresh() -} - -// MouseMoved is called when a desktop pointer hovers over the widget -func (t *menuItemWidget) MouseMoved(*desktop.MouseEvent) { -} - -func newMenuItemWidget(item *fyne.MenuItem) *menuItemWidget { - ret := &menuItemWidget{Item: item} - ret.ExtendBaseWidget(ret) - return ret -} - -type menuItemWidgetRenderer struct { - widget.BaseRenderer - text *canvas.Text - w *menuItemWidget -} - -func (r *menuItemWidgetRenderer) Layout(size fyne.Size) { - padding := r.padding() - r.text.Resize(r.text.MinSize()) - r.text.Move(fyne.NewPos(padding.Width/2, padding.Height/2)) -} - -func (r *menuItemWidgetRenderer) MinSize() fyne.Size { - return r.text.MinSize().Add(r.padding()) -} - -func (r *menuItemWidgetRenderer) Refresh() { - if r.text.TextSize != theme.TextSize() { - defer r.Layout(r.w.Size()) - } - r.text.TextSize = theme.TextSize() - r.text.Color = theme.TextColor() - canvas.Refresh(r.text) -} - -func (r *menuItemWidgetRenderer) BackgroundColor() color.Color { - if r.w.hovered { - return theme.HoverColor() - } - - return color.Transparent -} - -func (r *menuItemWidgetRenderer) padding() fyne.Size { - return fyne.NewSize(theme.Padding()*4, theme.Padding()*2) -} - -func newSeparator() fyne.CanvasObject { - s := canvas.NewRectangle(theme.DisabledTextColor()) - s.SetMinSize(fyne.NewSize(1, 2)) - return s -} From 597b7fe14e512de367c3d5a35fad0aa620977063 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Fri, 17 Apr 2020 07:01:54 +0200 Subject: [PATCH 6/7] organise code according to #827 --- internal/widget/base_renderer.go | 10 +++++----- internal/widget/menu_item.go | 22 +++++++++++----------- internal/widget/shadow.go | 18 +++++++++--------- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/internal/widget/base_renderer.go b/internal/widget/base_renderer.go index 0c86e96a71..261c6f8e77 100644 --- a/internal/widget/base_renderer.go +++ b/internal/widget/base_renderer.go @@ -7,17 +7,17 @@ import ( "fyne.io/fyne/theme" ) -// NewBaseRenderer creates a new BaseRenderer. -func NewBaseRenderer(objects []fyne.CanvasObject) BaseRenderer { - return BaseRenderer{objects} -} - // BaseRenderer is a renderer base providing the most common implementations of a part of the // widget.Renderer interface. type BaseRenderer struct { objects []fyne.CanvasObject } +// NewBaseRenderer creates a new BaseRenderer. +func NewBaseRenderer(objects []fyne.CanvasObject) BaseRenderer { + return BaseRenderer{objects} +} + // BackgroundColor satisfies the fyne.WidgetRenderer interface. func (r *BaseRenderer) BackgroundColor() color.Color { return theme.BackgroundColor() diff --git a/internal/widget/menu_item.go b/internal/widget/menu_item.go index 92f560b896..9531be0ca2 100644 --- a/internal/widget/menu_item.go +++ b/internal/widget/menu_item.go @@ -9,6 +9,17 @@ import ( "fyne.io/fyne/theme" ) +var _ fyne.Widget = (*MenuItem)(nil) + +// MenuItem is a widget for displaying a fyne.MenuItem. +type MenuItem struct { + base + DismissAction func() + Item *fyne.MenuItem + + hovered bool +} + // NewMenuItem creates a new MenuItem. func NewMenuItem(item *fyne.MenuItem) *MenuItem { return &MenuItem{Item: item} @@ -21,17 +32,6 @@ func NewMenuItemSeparator() fyne.CanvasObject { return s } -var _ fyne.Widget = (*MenuItem)(nil) - -// MenuItem is a widget for displaying a fyne.MenuItem. -type MenuItem struct { - base - DismissAction func() - Item *fyne.MenuItem - - hovered bool -} - // CreateRenderer satisfies the fyne.Widget interface. func (i *MenuItem) CreateRenderer() fyne.WidgetRenderer { text := canvas.NewText(i.Item.Label, theme.TextColor()) diff --git a/internal/widget/shadow.go b/internal/widget/shadow.go index 47ef96847c..f272c0c74c 100644 --- a/internal/widget/shadow.go +++ b/internal/widget/shadow.go @@ -8,6 +8,15 @@ import ( "fyne.io/fyne/theme" ) +var _ fyne.Widget = (*Shadow)(nil) + +// Shadow is a widget that renders a shadow. +type Shadow struct { + base + level ElevationLevel + typ ShadowType +} + // ElevationLevel is the level of elevation of the shadow casting object. type ElevationLevel int @@ -37,15 +46,6 @@ func NewShadow(typ ShadowType, level ElevationLevel) *Shadow { return &Shadow{typ: typ, level: level} } -var _ fyne.Widget = (*Shadow)(nil) - -// Shadow is a widget that renders a shadow. -type Shadow struct { - base - level ElevationLevel - typ ShadowType -} - // CreateRenderer satisfies the fyne.Widget interface. func (s *Shadow) CreateRenderer() fyne.WidgetRenderer { r := &shadowRenderer{s: s} From 3b8bbf256031062e73711079f21138181742cedd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Fri, 17 Apr 2020 07:02:30 +0200 Subject: [PATCH 7/7] sort shadow test methods alphabetically --- internal/widget/shadow_test.go | 62 +++++++++++++++++----------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/internal/widget/shadow_test.go b/internal/widget/shadow_test.go index 1f003ea755..f0bc5fa6dc 100644 --- a/internal/widget/shadow_test.go +++ b/internal/widget/shadow_test.go @@ -14,30 +14,15 @@ import ( var shadowLevel = ElevationLevel(5) var shadowWidth = int(shadowLevel) -func TestShadow_TopShadow(t *testing.T) { - s := NewShadow(ShadowTop, shadowLevel) - r := test.WidgetRenderer(s).(*shadowRenderer) - r.Layout(fyne.NewSize(100, 100)) - - assert.Equal(t, []fyne.CanvasObject{r.t}, r.Objects()) - assert.Equal(t, fyne.NewSize(100, shadowWidth), r.t.Size()) - assert.Equal(t, fyne.NewPos(0, -shadowWidth), r.t.Position()) - assert.Equal(t, 0.0, r.t.Angle) - assert.Equal(t, color.Transparent, r.t.StartColor) - assert.Equal(t, theme.ShadowColor(), r.t.EndColor) -} - -func TestShadow_BottomShadow(t *testing.T) { - s := NewShadow(ShadowBottom, shadowLevel) +func TestShadow_ApplyTheme(t *testing.T) { + fyne.CurrentApp().Settings().SetTheme(theme.DarkTheme()) + s := NewShadow(ShadowAround, shadowLevel) r := test.WidgetRenderer(s).(*shadowRenderer) - r.Layout(fyne.NewSize(100, 100)) + assert.Equal(t, theme.ShadowColor(), r.b.StartColor) - assert.Equal(t, []fyne.CanvasObject{r.b}, r.Objects()) - assert.Equal(t, fyne.NewSize(100, shadowWidth), r.b.Size()) - assert.Equal(t, fyne.NewPos(0, 100), r.b.Position()) - assert.Equal(t, 0.0, r.b.Angle) + fyne.CurrentApp().Settings().SetTheme(theme.LightTheme()) + r.Refresh() assert.Equal(t, theme.ShadowColor(), r.b.StartColor) - assert.Equal(t, color.Transparent, r.b.EndColor) } func TestShadow_AroundShadow(t *testing.T) { @@ -104,19 +89,21 @@ func TestShadow_AroundShadow(t *testing.T) { assert.Equal(t, theme.ShadowColor(), r.l.EndColor) } -func TestShadow_ApplyTheme(t *testing.T) { - fyne.CurrentApp().Settings().SetTheme(theme.DarkTheme()) - s := NewShadow(ShadowAround, shadowLevel) +func TestShadow_BackgroundColor(t *testing.T) { + assert.Equal(t, color.Transparent, test.WidgetRenderer(NewShadow(ShadowAround, 1)).BackgroundColor()) +} + +func TestShadow_BottomShadow(t *testing.T) { + s := NewShadow(ShadowBottom, shadowLevel) r := test.WidgetRenderer(s).(*shadowRenderer) - assert.Equal(t, theme.ShadowColor(), r.b.StartColor) + r.Layout(fyne.NewSize(100, 100)) - fyne.CurrentApp().Settings().SetTheme(theme.LightTheme()) - r.Refresh() + assert.Equal(t, []fyne.CanvasObject{r.b}, r.Objects()) + assert.Equal(t, fyne.NewSize(100, shadowWidth), r.b.Size()) + assert.Equal(t, fyne.NewPos(0, 100), r.b.Position()) + assert.Equal(t, 0.0, r.b.Angle) assert.Equal(t, theme.ShadowColor(), r.b.StartColor) -} - -func TestShadow_BackgroundColor(t *testing.T) { - assert.Equal(t, color.Transparent, test.WidgetRenderer(NewShadow(ShadowAround, 1)).BackgroundColor()) + assert.Equal(t, color.Transparent, r.b.EndColor) } func TestShadow_MinSize(t *testing.T) { @@ -139,3 +126,16 @@ func TestShadow_Theme(t *testing.T) { assert.Equal(t, dark.ShadowColor(), test.WidgetRenderer(shadow).(*shadowRenderer).r.StartColor) assert.Equal(t, dark.ShadowColor(), test.WidgetRenderer(shadow).(*shadowRenderer).tr.StartColor) } + +func TestShadow_TopShadow(t *testing.T) { + s := NewShadow(ShadowTop, shadowLevel) + r := test.WidgetRenderer(s).(*shadowRenderer) + r.Layout(fyne.NewSize(100, 100)) + + assert.Equal(t, []fyne.CanvasObject{r.t}, r.Objects()) + assert.Equal(t, fyne.NewSize(100, shadowWidth), r.t.Size()) + assert.Equal(t, fyne.NewPos(0, -shadowWidth), r.t.Position()) + assert.Equal(t, 0.0, r.t.Angle) + assert.Equal(t, color.Transparent, r.t.StartColor) + assert.Equal(t, theme.ShadowColor(), r.t.EndColor) +}