1 // SPDX-License-Identifier: Unlicense OR MIT
2 3 package widget
4 5 import (
6 "image"
7 8 "github.com/p9c/p9/pkg/gel/gio/f32"
9 "github.com/p9c/p9/pkg/gel/gio/layout"
10 "github.com/p9c/p9/pkg/gel/gio/op"
11 "github.com/p9c/p9/pkg/gel/gio/op/paint"
12 "github.com/p9c/p9/pkg/gel/gio/unit"
13 )
14 15 // Image is a widget that displays an image.
16 type Image struct {
17 // Src is the image to display.
18 Src paint.ImageOp
19 // Fit specifies how to scale the image to the constraints.
20 // By default it does not do any scaling.
21 Fit Fit
22 // Position specifies where to position the image within
23 // the constraints.
24 Position layout.Direction
25 // Scale is the ratio of image pixels to
26 // dps. If Scale is zero Image falls back to
27 // a scale that match a standard 72 DPI.
28 Scale float32
29 }
30 31 const defaultScale = float32(160.0 / 72.0)
32 33 func (im Image) Layout(gtx layout.Context) layout.Dimensions {
34 defer op.Save(gtx.Ops).Load()
35 36 scale := im.Scale
37 if scale == 0 {
38 scale = defaultScale
39 }
40 41 size := im.Src.Size()
42 wf, hf := float32(size.X), float32(size.Y)
43 w, h := gtx.Px(unit.Dp(wf*scale)), gtx.Px(unit.Dp(hf*scale))
44 45 dims := im.Fit.scale(gtx, im.Position, layout.Dimensions{Size: image.Pt(w, h)})
46 47 pixelScale := scale * gtx.Metric.PxPerDp
48 op.Affine(f32.Affine2D{}.Scale(f32.Point{}, f32.Pt(pixelScale, pixelScale))).Add(gtx.Ops)
49 50 im.Src.Add(gtx.Ops)
51 paint.PaintOp{}.Add(gtx.Ops)
52 53 return dims
54 }
55