Skip to content

Commit

Permalink
Merge pull request #875 from toaster/refactoring/internal_widgets
Browse files Browse the repository at this point in the history
Refactoring: internal widgets
  • Loading branch information
andydotxyz committed Apr 17, 2020
2 parents c324a03 + 3b8bbf2 commit 626c1aa
Show file tree
Hide file tree
Showing 29 changed files with 556 additions and 356 deletions.
83 changes: 83 additions & 0 deletions 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()
}
38 changes: 38 additions & 0 deletions internal/widget/base_renderer.go
@@ -0,0 +1,38 @@
package widget

import (
"image/color"

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

// 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()
}

// 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
}
129 changes: 129 additions & 0 deletions 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"
)

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}
}

// 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
}

// 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)
}

0 comments on commit 626c1aa

Please sign in to comment.