forked from joejulian/gio
widget,widget/material: move Image and Icon to widget package
There is nothing theme-specific about displaying images and icons, so move the types from the material package to the generic widget package. Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
@@ -39,7 +39,7 @@ type ButtonLayout struct {
|
||||
type IconButton struct {
|
||||
Background color.RGBA
|
||||
Color color.RGBA
|
||||
Icon *Icon
|
||||
Icon *widget.Icon
|
||||
Size unit.Value
|
||||
Padding unit.Value
|
||||
Inset layout.Inset
|
||||
@@ -69,7 +69,7 @@ func (t *Theme) ButtonLayout() ButtonLayout {
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Theme) IconButton(icon *Icon) IconButton {
|
||||
func (t *Theme) IconButton(icon *widget.Icon) IconButton {
|
||||
return IconButton{
|
||||
Background: t.Color.Primary,
|
||||
Color: t.Color.InvText,
|
||||
|
||||
@@ -22,13 +22,12 @@ type checkable struct {
|
||||
IconColor color.RGBA
|
||||
Size unit.Value
|
||||
shaper text.Shaper
|
||||
checkedStateIcon *Icon
|
||||
uncheckedStateIcon *Icon
|
||||
checkedStateIcon *widget.Icon
|
||||
uncheckedStateIcon *widget.Icon
|
||||
}
|
||||
|
||||
func (c *checkable) layout(gtx *layout.Context, checked bool) {
|
||||
|
||||
var icon *Icon
|
||||
var icon *widget.Icon
|
||||
if checked {
|
||||
icon = c.checkedStateIcon
|
||||
} else {
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
// SPDX-License-Identifier: Unlicense OR MIT
|
||||
|
||||
package material
|
||||
|
||||
import (
|
||||
"image"
|
||||
"image/color"
|
||||
"image/draw"
|
||||
|
||||
"gioui.org/f32"
|
||||
"gioui.org/layout"
|
||||
"gioui.org/op/paint"
|
||||
"gioui.org/unit"
|
||||
"golang.org/x/exp/shiny/iconvg"
|
||||
)
|
||||
|
||||
type Icon struct {
|
||||
Color color.RGBA
|
||||
src []byte
|
||||
// Cached values.
|
||||
op paint.ImageOp
|
||||
imgSize int
|
||||
imgColor color.RGBA
|
||||
}
|
||||
|
||||
// NewIcon returns a new Icon from IconVG data.
|
||||
func NewIcon(data []byte) (*Icon, error) {
|
||||
_, err := iconvg.DecodeMetadata(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Icon{src: data, Color: rgb(0x000000)}, nil
|
||||
}
|
||||
|
||||
func (ic *Icon) Layout(gtx *layout.Context, sz unit.Value) {
|
||||
ico := ic.image(gtx.Px(sz))
|
||||
ico.Add(gtx.Ops)
|
||||
paint.PaintOp{
|
||||
Rect: f32.Rectangle{
|
||||
Max: toPointF(ico.Size()),
|
||||
},
|
||||
}.Add(gtx.Ops)
|
||||
gtx.Dimensions = layout.Dimensions{
|
||||
Size: ico.Size(),
|
||||
}
|
||||
}
|
||||
|
||||
func (ic *Icon) image(sz int) paint.ImageOp {
|
||||
if sz == ic.imgSize && ic.Color == ic.imgColor {
|
||||
return ic.op
|
||||
}
|
||||
m, _ := iconvg.DecodeMetadata(ic.src)
|
||||
dx, dy := m.ViewBox.AspectRatio()
|
||||
img := image.NewRGBA(image.Rectangle{Max: image.Point{X: sz, Y: int(float32(sz) * dy / dx)}})
|
||||
var ico iconvg.Rasterizer
|
||||
ico.SetDstImage(img, img.Bounds(), draw.Src)
|
||||
m.Palette[0] = ic.Color
|
||||
iconvg.Decode(&ico, ic.src, &iconvg.DecodeOptions{
|
||||
Palette: &m.Palette,
|
||||
})
|
||||
ic.op = paint.NewImageOp(img)
|
||||
ic.imgSize = sz
|
||||
ic.imgColor = ic.Color
|
||||
return ic.op
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
// SPDX-License-Identifier: Unlicense OR MIT
|
||||
|
||||
package material
|
||||
|
||||
import (
|
||||
"image"
|
||||
|
||||
"gioui.org/f32"
|
||||
"gioui.org/layout"
|
||||
"gioui.org/op"
|
||||
"gioui.org/op/clip"
|
||||
"gioui.org/op/paint"
|
||||
"gioui.org/unit"
|
||||
)
|
||||
|
||||
// Image is a widget that displays an image.
|
||||
type Image struct {
|
||||
// Src is the image to display.
|
||||
Src paint.ImageOp
|
||||
// Scale is the ratio of image pixels to
|
||||
// dps.
|
||||
Scale float32
|
||||
}
|
||||
|
||||
func (t *Theme) Image(img paint.ImageOp) Image {
|
||||
return Image{
|
||||
Src: img,
|
||||
Scale: 160 / 72, // About 72 DPI.
|
||||
}
|
||||
}
|
||||
|
||||
func (im Image) Layout(gtx *layout.Context) {
|
||||
size := im.Src.Rect.Size()
|
||||
wf, hf := float32(size.X), float32(size.Y)
|
||||
w, h := gtx.Px(unit.Dp(wf*im.Scale)), gtx.Px(unit.Dp(hf*im.Scale))
|
||||
cs := gtx.Constraints
|
||||
d := image.Point{X: cs.Width.Constrain(w), Y: cs.Height.Constrain(h)}
|
||||
var s op.StackOp
|
||||
s.Push(gtx.Ops)
|
||||
clip.Rect{Rect: f32.Rectangle{Max: toPointF(d)}}.Op(gtx.Ops).Add(gtx.Ops)
|
||||
im.Src.Add(gtx.Ops)
|
||||
paint.PaintOp{Rect: f32.Rectangle{Max: f32.Point{X: float32(w), Y: float32(h)}}}.Add(gtx.Ops)
|
||||
s.Pop()
|
||||
gtx.Dimensions = layout.Dimensions{Size: d}
|
||||
}
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"gioui.org/op/paint"
|
||||
"gioui.org/text"
|
||||
"gioui.org/unit"
|
||||
"gioui.org/widget"
|
||||
"golang.org/x/exp/shiny/materialdesign/icons"
|
||||
)
|
||||
|
||||
@@ -24,10 +25,10 @@ type Theme struct {
|
||||
InvText color.RGBA
|
||||
}
|
||||
TextSize unit.Value
|
||||
checkBoxCheckedIcon *Icon
|
||||
checkBoxUncheckedIcon *Icon
|
||||
radioCheckedIcon *Icon
|
||||
radioUncheckedIcon *Icon
|
||||
checkBoxCheckedIcon *widget.Icon
|
||||
checkBoxUncheckedIcon *widget.Icon
|
||||
radioCheckedIcon *widget.Icon
|
||||
radioUncheckedIcon *widget.Icon
|
||||
}
|
||||
|
||||
func NewTheme() *Theme {
|
||||
@@ -40,15 +41,15 @@ func NewTheme() *Theme {
|
||||
t.Color.InvText = rgb(0xffffff)
|
||||
t.TextSize = unit.Sp(16)
|
||||
|
||||
t.checkBoxCheckedIcon = mustIcon(NewIcon(icons.ToggleCheckBox))
|
||||
t.checkBoxUncheckedIcon = mustIcon(NewIcon(icons.ToggleCheckBoxOutlineBlank))
|
||||
t.radioCheckedIcon = mustIcon(NewIcon(icons.ToggleRadioButtonChecked))
|
||||
t.radioUncheckedIcon = mustIcon(NewIcon(icons.ToggleRadioButtonUnchecked))
|
||||
t.checkBoxCheckedIcon = mustIcon(widget.NewIcon(icons.ToggleCheckBox))
|
||||
t.checkBoxUncheckedIcon = mustIcon(widget.NewIcon(icons.ToggleCheckBoxOutlineBlank))
|
||||
t.radioCheckedIcon = mustIcon(widget.NewIcon(icons.ToggleRadioButtonChecked))
|
||||
t.radioUncheckedIcon = mustIcon(widget.NewIcon(icons.ToggleRadioButtonUnchecked))
|
||||
|
||||
return t
|
||||
}
|
||||
|
||||
func mustIcon(ic *Icon, err error) *Icon {
|
||||
func mustIcon(ic *widget.Icon, err error) *widget.Icon {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user