mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-02 16:06:19 +00:00
op: add package op for operations
Extract operation types from package ui into package op. Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
@@ -12,11 +12,11 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"gioui.org/ui"
|
||||
"gioui.org/app/internal/gl"
|
||||
"gioui.org/f32"
|
||||
"gioui.org/internal/opconst"
|
||||
"gioui.org/internal/ops"
|
||||
"gioui.org/op"
|
||||
"gioui.org/paint"
|
||||
"golang.org/x/image/draw"
|
||||
)
|
||||
@@ -74,7 +74,7 @@ type drawOps struct {
|
||||
|
||||
type drawState struct {
|
||||
clip f32.Rectangle
|
||||
t ui.TransformOp
|
||||
t op.TransformOp
|
||||
cpath *pathOp
|
||||
rect bool
|
||||
z int
|
||||
@@ -398,7 +398,7 @@ func (g *GPU) Refresh() {
|
||||
g.setErr(<-g.refreshErr)
|
||||
}
|
||||
|
||||
func (g *GPU) Draw(profile bool, viewport image.Point, root *ui.Ops) {
|
||||
func (g *GPU) Draw(profile bool, viewport image.Point, root *op.Ops) {
|
||||
if g.err != nil {
|
||||
return
|
||||
}
|
||||
@@ -678,7 +678,7 @@ func (d *drawOps) reset(cache *resourceCache, viewport image.Point) {
|
||||
d.pathOpCache = d.pathOpCache[:0]
|
||||
}
|
||||
|
||||
func (d *drawOps) collect(cache *resourceCache, root *ui.Ops, viewport image.Point) {
|
||||
func (d *drawOps) collect(cache *resourceCache, root *op.Ops, viewport image.Point) {
|
||||
d.reset(cache, viewport)
|
||||
clip := f32.Rectangle{
|
||||
Max: f32.Point{X: float32(viewport.X), Y: float32(viewport.Y)},
|
||||
@@ -704,8 +704,8 @@ loop:
|
||||
for encOp, ok := r.Decode(); ok; encOp, ok = r.Decode() {
|
||||
switch opconst.OpType(encOp.Data[0]) {
|
||||
case opconst.TypeTransform:
|
||||
op := ops.DecodeTransformOp(encOp.Data)
|
||||
state.t = state.t.Multiply(ui.TransformOp(op))
|
||||
dop := ops.DecodeTransformOp(encOp.Data)
|
||||
state.t = state.t.Multiply(op.TransformOp(dop))
|
||||
case opconst.TypeAux:
|
||||
aux = encOp.Data[opconst.TypeAuxLen:]
|
||||
auxKey = encOp.Key
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"gioui.org/internal/ops"
|
||||
"gioui.org/io/event"
|
||||
"gioui.org/io/key"
|
||||
"gioui.org/ui"
|
||||
"gioui.org/op"
|
||||
)
|
||||
|
||||
type TextInputState uint8
|
||||
@@ -44,7 +44,7 @@ func (q *keyQueue) InputState() TextInputState {
|
||||
return q.state
|
||||
}
|
||||
|
||||
func (q *keyQueue) Frame(root *ui.Ops, events *handlerEvents) {
|
||||
func (q *keyQueue) Frame(root *op.Ops, events *handlerEvents) {
|
||||
if q.handlers == nil {
|
||||
q.handlers = make(map[event.Key]*keyHandler)
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"gioui.org/internal/ops"
|
||||
"gioui.org/io/event"
|
||||
"gioui.org/io/pointer"
|
||||
"gioui.org/ui"
|
||||
"gioui.org/op"
|
||||
)
|
||||
|
||||
type pointerQueue struct {
|
||||
@@ -42,7 +42,7 @@ type pointerInfo struct {
|
||||
type pointerHandler struct {
|
||||
area int
|
||||
active bool
|
||||
transform ui.TransformOp
|
||||
transform op.TransformOp
|
||||
wantsGrab bool
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ type areaOp struct {
|
||||
}
|
||||
|
||||
type areaNode struct {
|
||||
trans ui.TransformOp
|
||||
trans op.TransformOp
|
||||
next int
|
||||
area areaOp
|
||||
}
|
||||
@@ -64,7 +64,7 @@ const (
|
||||
areaEllipse
|
||||
)
|
||||
|
||||
func (q *pointerQueue) collectHandlers(r *ops.Reader, events *handlerEvents, t ui.TransformOp, area, node int, pass bool) {
|
||||
func (q *pointerQueue) collectHandlers(r *ops.Reader, events *handlerEvents, t op.TransformOp, area, node int, pass bool) {
|
||||
for encOp, ok := r.Decode(); ok; encOp, ok = r.Decode() {
|
||||
switch opconst.OpType(encOp.Data[0]) {
|
||||
case opconst.TypePush:
|
||||
@@ -86,8 +86,8 @@ func (q *pointerQueue) collectHandlers(r *ops.Reader, events *handlerEvents, t u
|
||||
})
|
||||
node = len(q.hitTree) - 1
|
||||
case opconst.TypeTransform:
|
||||
op := ops.DecodeTransformOp(encOp.Data)
|
||||
t = t.Multiply(ui.TransformOp(op))
|
||||
dop := ops.DecodeTransformOp(encOp.Data)
|
||||
t = t.Multiply(op.TransformOp(dop))
|
||||
case opconst.TypePointerInput:
|
||||
op := decodePointerInputOp(encOp.Data, encOp.Refs)
|
||||
q.hitTree = append(q.hitTree, hitNode{
|
||||
@@ -158,7 +158,7 @@ func (q *pointerQueue) init() {
|
||||
}
|
||||
}
|
||||
|
||||
func (q *pointerQueue) Frame(root *ui.Ops, events *handlerEvents) {
|
||||
func (q *pointerQueue) Frame(root *op.Ops, events *handlerEvents) {
|
||||
q.init()
|
||||
for _, h := range q.handlers {
|
||||
// Reset handler.
|
||||
@@ -167,7 +167,7 @@ func (q *pointerQueue) Frame(root *ui.Ops, events *handlerEvents) {
|
||||
q.hitTree = q.hitTree[:0]
|
||||
q.areas = q.areas[:0]
|
||||
q.reader.Reset(root)
|
||||
q.collectHandlers(&q.reader, events, ui.TransformOp{}, -1, -1, false)
|
||||
q.collectHandlers(&q.reader, events, op.TransformOp{}, -1, -1, false)
|
||||
for k, h := range q.handlers {
|
||||
if !h.active {
|
||||
q.dropHandler(k)
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
"gioui.org/io/key"
|
||||
"gioui.org/io/pointer"
|
||||
"gioui.org/io/profile"
|
||||
"gioui.org/ui"
|
||||
"gioui.org/op"
|
||||
)
|
||||
|
||||
// Router is a Queue implementation that routes events from
|
||||
@@ -53,7 +53,7 @@ func (q *Router) Events(k event.Key) []event.Event {
|
||||
return events
|
||||
}
|
||||
|
||||
func (q *Router) Frame(ops *ui.Ops) {
|
||||
func (q *Router) Frame(ops *op.Ops) {
|
||||
q.handlers.Clear()
|
||||
q.wakeup = false
|
||||
q.profHandlers = q.profHandlers[:0]
|
||||
@@ -160,12 +160,12 @@ func decodeProfileOp(d []byte, refs []interface{}) profile.Op {
|
||||
}
|
||||
}
|
||||
|
||||
func decodeInvalidateOp(d []byte) ui.InvalidateOp {
|
||||
func decodeInvalidateOp(d []byte) op.InvalidateOp {
|
||||
bo := binary.LittleEndian
|
||||
if opconst.OpType(d[0]) != opconst.TypeInvalidate {
|
||||
panic("invalid op")
|
||||
}
|
||||
var o ui.InvalidateOp
|
||||
var o op.InvalidateOp
|
||||
if nanos := bo.Uint64(d[1:]); nanos > 0 {
|
||||
o.At = time.Unix(0, int64(nanos))
|
||||
}
|
||||
|
||||
+6
-5
@@ -12,6 +12,7 @@ import (
|
||||
"gioui.org/app/internal/input"
|
||||
"gioui.org/io/event"
|
||||
"gioui.org/io/profile"
|
||||
"gioui.org/op"
|
||||
"gioui.org/ui"
|
||||
)
|
||||
|
||||
@@ -36,7 +37,7 @@ type Window struct {
|
||||
in chan event.Event
|
||||
ack chan struct{}
|
||||
invalidates chan struct{}
|
||||
frames chan *ui.Ops
|
||||
frames chan *op.Ops
|
||||
|
||||
stage Stage
|
||||
animating bool
|
||||
@@ -99,7 +100,7 @@ func NewWindow(options ...WindowOption) *Window {
|
||||
out: make(chan event.Event),
|
||||
ack: make(chan struct{}),
|
||||
invalidates: make(chan struct{}, 1),
|
||||
frames: make(chan *ui.Ops),
|
||||
frames: make(chan *op.Ops),
|
||||
}
|
||||
go w.run(opts)
|
||||
return w
|
||||
@@ -120,11 +121,11 @@ func (w *Window) Queue() *Queue {
|
||||
// window contents, input operations declare input handlers,
|
||||
// and so on. The supplied operations list completely replaces
|
||||
// the window state from previous calls.
|
||||
func (w *Window) Update(frame *ui.Ops) {
|
||||
func (w *Window) Update(frame *op.Ops) {
|
||||
w.frames <- frame
|
||||
}
|
||||
|
||||
func (w *Window) draw(size image.Point, frame *ui.Ops) {
|
||||
func (w *Window) draw(size image.Point, frame *op.Ops) {
|
||||
var drawDur time.Duration
|
||||
if !w.drawStart.IsZero() {
|
||||
drawDur = time.Since(w.drawStart)
|
||||
@@ -265,7 +266,7 @@ func (w *Window) run(opts *windowOptions) {
|
||||
w.drawStart = time.Now()
|
||||
w.hasNextFrame = false
|
||||
w.out <- e
|
||||
var frame *ui.Ops
|
||||
var frame *op.Ops
|
||||
// Wait for either a frame or the ack event,
|
||||
// which meant that the client didn't draw.
|
||||
select {
|
||||
|
||||
Vendored
+1
-2
@@ -7,7 +7,6 @@ import (
|
||||
"image/color"
|
||||
"log"
|
||||
|
||||
"gioui.org/ui"
|
||||
"gioui.org/app"
|
||||
"gioui.org/f32"
|
||||
"gioui.org/paint"
|
||||
@@ -25,7 +24,7 @@ func main() {
|
||||
|
||||
func loop(w *app.Window) error {
|
||||
background := color.RGBA{255, 0, 0, 255}
|
||||
ops := new(ui.Ops)
|
||||
ops := new(op.Ops)
|
||||
for {
|
||||
e := <-w.Events()
|
||||
switch e := e.(type) {
|
||||
|
||||
+4
-3
@@ -16,6 +16,7 @@ import (
|
||||
"gioui.org/internal/fling"
|
||||
"gioui.org/io/event"
|
||||
"gioui.org/io/pointer"
|
||||
"gioui.org/op"
|
||||
"gioui.org/ui"
|
||||
)
|
||||
|
||||
@@ -95,7 +96,7 @@ const (
|
||||
var touchSlop = ui.Dp(3)
|
||||
|
||||
// Add the handler to the operation list to receive click events.
|
||||
func (c *Click) Add(ops *ui.Ops) {
|
||||
func (c *Click) Add(ops *op.Ops) {
|
||||
op := pointer.InputOp{Key: c}
|
||||
op.Add(ops)
|
||||
}
|
||||
@@ -140,11 +141,11 @@ func (c *Click) Events(q event.Queue) []ClickEvent {
|
||||
}
|
||||
|
||||
// Add the handler to the operation list to receive scroll events.
|
||||
func (s *Scroll) Add(ops *ui.Ops) {
|
||||
func (s *Scroll) Add(ops *op.Ops) {
|
||||
oph := pointer.InputOp{Key: s, Grab: s.grab}
|
||||
oph.Add(ops)
|
||||
if s.flinger.Active() {
|
||||
ui.InvalidateOp{}.Add(ops)
|
||||
op.InvalidateOp{}.Add(ops)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -6,17 +6,17 @@ import (
|
||||
"encoding/binary"
|
||||
"math"
|
||||
|
||||
"gioui.org/ui"
|
||||
"gioui.org/f32"
|
||||
"gioui.org/internal/opconst"
|
||||
"gioui.org/op"
|
||||
)
|
||||
|
||||
func DecodeTransformOp(d []byte) ui.TransformOp {
|
||||
func DecodeTransformOp(d []byte) op.TransformOp {
|
||||
bo := binary.LittleEndian
|
||||
if opconst.OpType(d[0]) != opconst.TypeTransform {
|
||||
panic("invalid op")
|
||||
}
|
||||
return ui.TransformOp{}.Offset(f32.Point{
|
||||
return op.TransformOp{}.Offset(f32.Point{
|
||||
X: math.Float32frombits(bo.Uint32(d[1:])),
|
||||
Y: math.Float32frombits(bo.Uint32(d[5:])),
|
||||
})
|
||||
|
||||
@@ -5,15 +5,15 @@ package ops
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"gioui.org/ui"
|
||||
"gioui.org/internal/opconst"
|
||||
"gioui.org/op"
|
||||
)
|
||||
|
||||
// Reader parses an ops list.
|
||||
type Reader struct {
|
||||
pc pc
|
||||
stack []macro
|
||||
ops *ui.Ops
|
||||
ops *op.Ops
|
||||
}
|
||||
|
||||
// EncodedOp represents an encoded op returned by
|
||||
@@ -26,14 +26,14 @@ type EncodedOp struct {
|
||||
|
||||
// Key is a unique key for a given op.
|
||||
type Key struct {
|
||||
ops *ui.Ops
|
||||
ops *op.Ops
|
||||
pc int
|
||||
version int
|
||||
}
|
||||
|
||||
// Shadow of ui.MacroOp.
|
||||
// Shadow of op.MacroOp.
|
||||
type macroOp struct {
|
||||
ops *ui.Ops
|
||||
ops *op.Ops
|
||||
version int
|
||||
pc pc
|
||||
}
|
||||
@@ -44,7 +44,7 @@ type pc struct {
|
||||
}
|
||||
|
||||
type macro struct {
|
||||
ops *ui.Ops
|
||||
ops *op.Ops
|
||||
retPC pc
|
||||
endPC pc
|
||||
}
|
||||
@@ -58,7 +58,7 @@ type opAux struct {
|
||||
}
|
||||
|
||||
// Reset start reading from the op list.
|
||||
func (r *Reader) Reset(ops *ui.Ops) {
|
||||
func (r *Reader) Reset(ops *op.Ops) {
|
||||
r.stack = r.stack[:0]
|
||||
r.pc = pc{}
|
||||
r.ops = ops
|
||||
@@ -170,7 +170,7 @@ func (m *macroOp) decode(data []byte, refs []interface{}) {
|
||||
refsIdx := int(int32(bo.Uint32(data[5:])))
|
||||
version := int(int32(bo.Uint32(data[9:])))
|
||||
*m = macroOp{
|
||||
ops: refs[0].(*ui.Ops),
|
||||
ops: refs[0].(*op.Ops),
|
||||
pc: pc{
|
||||
data: dataIdx,
|
||||
refs: refsIdx,
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ The following example declares a handler ready for key input:
|
||||
|
||||
import gioui.org/io/key
|
||||
|
||||
ops := new(ui.Ops)
|
||||
ops := new(op.Ops)
|
||||
var h *Handler = ...
|
||||
key.InputOp{Key: h}.Add(ops)
|
||||
|
||||
|
||||
+3
-3
@@ -12,7 +12,7 @@ package key
|
||||
import (
|
||||
"gioui.org/internal/opconst"
|
||||
"gioui.org/io/event"
|
||||
"gioui.org/ui"
|
||||
"gioui.org/op"
|
||||
)
|
||||
|
||||
// InputOp declares a handler ready for key events.
|
||||
@@ -86,7 +86,7 @@ func (m Modifiers) Contain(m2 Modifiers) bool {
|
||||
return m&m2 == m2
|
||||
}
|
||||
|
||||
func (h InputOp) Add(o *ui.Ops) {
|
||||
func (h InputOp) Add(o *op.Ops) {
|
||||
data := make([]byte, opconst.TypeKeyInputLen)
|
||||
data[0] = byte(opconst.TypeKeyInput)
|
||||
if h.Focus {
|
||||
@@ -95,7 +95,7 @@ func (h InputOp) Add(o *ui.Ops) {
|
||||
o.Write(data, h.Key)
|
||||
}
|
||||
|
||||
func (h HideInputOp) Add(o *ui.Ops) {
|
||||
func (h HideInputOp) Add(o *op.Ops) {
|
||||
data := make([]byte, opconst.TypeHideInputLen)
|
||||
data[0] = byte(opconst.TypeHideInput)
|
||||
o.Write(data)
|
||||
|
||||
+3
-3
@@ -15,7 +15,7 @@ subsequent InputOp are active.
|
||||
|
||||
For example, to set up a rectangular hit area:
|
||||
|
||||
var ops ui.Ops
|
||||
var ops op.Ops
|
||||
var h *Handler = ...
|
||||
|
||||
r := image.Rectangle{...}
|
||||
@@ -33,8 +33,8 @@ with the most recent node.
|
||||
|
||||
For example:
|
||||
|
||||
ops := new(ui.Ops)
|
||||
var stack ui.StackOp
|
||||
ops := new(op.Ops)
|
||||
var stack op.StackOp
|
||||
var h1, h2 *Handler
|
||||
|
||||
stack.Push(ops)
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
"gioui.org/f32"
|
||||
"gioui.org/internal/opconst"
|
||||
"gioui.org/io/event"
|
||||
"gioui.org/ui"
|
||||
"gioui.org/op"
|
||||
)
|
||||
|
||||
// Event is a pointer event.
|
||||
@@ -33,7 +33,7 @@ type Event struct {
|
||||
// outside it.
|
||||
Hit bool
|
||||
// Position is the position of the event, relative to
|
||||
// the current transformation, as set by ui.TransformOp.
|
||||
// the current transformation, as set by op.TransformOp.
|
||||
Position f32.Point
|
||||
// Scroll is the scroll amount, if any.
|
||||
Scroll f32.Point
|
||||
@@ -124,21 +124,21 @@ const (
|
||||
areaEllipse
|
||||
)
|
||||
|
||||
func (op RectAreaOp) Add(ops *ui.Ops) {
|
||||
func (op RectAreaOp) Add(ops *op.Ops) {
|
||||
areaOp{
|
||||
kind: areaRect,
|
||||
rect: op.Rect,
|
||||
}.add(ops)
|
||||
}
|
||||
|
||||
func (op EllipseAreaOp) Add(ops *ui.Ops) {
|
||||
func (op EllipseAreaOp) Add(ops *op.Ops) {
|
||||
areaOp{
|
||||
kind: areaEllipse,
|
||||
rect: op.Rect,
|
||||
}.add(ops)
|
||||
}
|
||||
|
||||
func (op areaOp) add(o *ui.Ops) {
|
||||
func (op areaOp) add(o *op.Ops) {
|
||||
data := make([]byte, opconst.TypeAreaLen)
|
||||
data[0] = byte(opconst.TypeArea)
|
||||
data[1] = byte(op.kind)
|
||||
@@ -150,7 +150,7 @@ func (op areaOp) add(o *ui.Ops) {
|
||||
o.Write(data)
|
||||
}
|
||||
|
||||
func (h InputOp) Add(o *ui.Ops) {
|
||||
func (h InputOp) Add(o *op.Ops) {
|
||||
data := make([]byte, opconst.TypePointerInputLen)
|
||||
data[0] = byte(opconst.TypePointerInput)
|
||||
if h.Grab {
|
||||
@@ -159,7 +159,7 @@ func (h InputOp) Add(o *ui.Ops) {
|
||||
o.Write(data, h.Key)
|
||||
}
|
||||
|
||||
func (op PassOp) Add(o *ui.Ops) {
|
||||
func (op PassOp) Add(o *op.Ops) {
|
||||
data := make([]byte, opconst.TypePassLen)
|
||||
data[0] = byte(opconst.TypePass)
|
||||
if op.Pass {
|
||||
|
||||
@@ -7,7 +7,7 @@ package profile
|
||||
import (
|
||||
"gioui.org/internal/opconst"
|
||||
"gioui.org/io/event"
|
||||
"gioui.org/ui"
|
||||
"gioui.org/op"
|
||||
)
|
||||
|
||||
// Op registers a handler for receiving
|
||||
@@ -23,7 +23,7 @@ type Event struct {
|
||||
Timings string
|
||||
}
|
||||
|
||||
func (p Op) Add(o *ui.Ops) {
|
||||
func (p Op) Add(o *op.Ops) {
|
||||
data := make([]byte, opconst.TypeProfileLen)
|
||||
data[0] = byte(opconst.TypeProfile)
|
||||
o.Write(data, p.Key)
|
||||
|
||||
+5
-5
@@ -6,7 +6,7 @@ import (
|
||||
"image"
|
||||
|
||||
"gioui.org/f32"
|
||||
"gioui.org/ui"
|
||||
"gioui.org/op"
|
||||
)
|
||||
|
||||
// Flex lays out child elements along an axis,
|
||||
@@ -21,7 +21,7 @@ type Flex struct {
|
||||
Alignment Alignment
|
||||
|
||||
ctx *Context
|
||||
macro ui.MacroOp
|
||||
macro op.MacroOp
|
||||
mode flexMode
|
||||
size int
|
||||
rigidSize int
|
||||
@@ -33,7 +33,7 @@ type Flex struct {
|
||||
|
||||
// FlexChild is the layout result of a call End.
|
||||
type FlexChild struct {
|
||||
macro ui.MacroOp
|
||||
macro op.MacroOp
|
||||
dims Dimensions
|
||||
}
|
||||
|
||||
@@ -189,9 +189,9 @@ func (f *Flex) Layout(children ...FlexChild) {
|
||||
cross = f.maxBaseline - b
|
||||
}
|
||||
}
|
||||
var stack ui.StackOp
|
||||
var stack op.StackOp
|
||||
stack.Push(f.ctx.Ops)
|
||||
ui.TransformOp{}.Offset(toPointF(axisPoint(f.Axis, mainSize, cross))).Add(f.ctx.Ops)
|
||||
op.TransformOp{}.Offset(toPointF(axisPoint(f.Axis, mainSize, cross))).Add(f.ctx.Ops)
|
||||
child.macro.Add(f.ctx.Ops)
|
||||
stack.Pop()
|
||||
mainSize += axisMain(f.Axis, dims.Size)
|
||||
|
||||
+8
-7
@@ -6,6 +6,7 @@ import (
|
||||
"image"
|
||||
|
||||
"gioui.org/io/event"
|
||||
"gioui.org/op"
|
||||
"gioui.org/ui"
|
||||
)
|
||||
|
||||
@@ -53,7 +54,7 @@ type Context struct {
|
||||
|
||||
ui.Config
|
||||
event.Queue
|
||||
*ui.Ops
|
||||
*op.Ops
|
||||
}
|
||||
|
||||
const (
|
||||
@@ -97,7 +98,7 @@ func (c *Context) Reset(cfg ui.Config, cs Constraints) {
|
||||
c.Dimensions = Dimensions{}
|
||||
c.Config = cfg
|
||||
if c.Ops == nil {
|
||||
c.Ops = new(ui.Ops)
|
||||
c.Ops = new(op.Ops)
|
||||
}
|
||||
c.Ops.Reset()
|
||||
}
|
||||
@@ -157,9 +158,9 @@ func (in Inset) Layout(gtx *Context, w Widget) {
|
||||
if mcs.Height.Max < mcs.Height.Min {
|
||||
mcs.Height.Max = mcs.Height.Min
|
||||
}
|
||||
var stack ui.StackOp
|
||||
var stack op.StackOp
|
||||
stack.Push(gtx.Ops)
|
||||
ui.TransformOp{}.Offset(toPointF(image.Point{X: left, Y: top})).Add(gtx.Ops)
|
||||
op.TransformOp{}.Offset(toPointF(image.Point{X: left, Y: top})).Add(gtx.Ops)
|
||||
dims := gtx.Layout(mcs, w)
|
||||
stack.Pop()
|
||||
gtx.Dimensions = Dimensions{
|
||||
@@ -176,7 +177,7 @@ func UniformInset(v ui.Value) Inset {
|
||||
|
||||
// Layout a widget.
|
||||
func (a Align) Layout(gtx *Context, w Widget) {
|
||||
var macro ui.MacroOp
|
||||
var macro op.MacroOp
|
||||
macro.Record(gtx.Ops)
|
||||
cs := gtx.Constraints
|
||||
mcs := cs
|
||||
@@ -204,9 +205,9 @@ func (a Align) Layout(gtx *Context, w Widget) {
|
||||
case SW, S, SE:
|
||||
p.Y = sz.Y - dims.Size.Y
|
||||
}
|
||||
var stack ui.StackOp
|
||||
var stack op.StackOp
|
||||
stack.Push(gtx.Ops)
|
||||
ui.TransformOp{}.Offset(toPointF(p)).Add(gtx.Ops)
|
||||
op.TransformOp{}.Offset(toPointF(p)).Add(gtx.Ops)
|
||||
macro.Add(gtx.Ops)
|
||||
stack.Pop()
|
||||
gtx.Dimensions = Dimensions{
|
||||
|
||||
+6
-6
@@ -7,13 +7,13 @@ import (
|
||||
|
||||
"gioui.org/gesture"
|
||||
"gioui.org/io/pointer"
|
||||
"gioui.org/op"
|
||||
"gioui.org/paint"
|
||||
"gioui.org/ui"
|
||||
)
|
||||
|
||||
type scrollChild struct {
|
||||
size image.Point
|
||||
macro ui.MacroOp
|
||||
macro op.MacroOp
|
||||
}
|
||||
|
||||
// List displays a subsection of a potentially infinitely
|
||||
@@ -33,8 +33,8 @@ type List struct {
|
||||
beforeEnd bool
|
||||
|
||||
ctx *Context
|
||||
macro ui.MacroOp
|
||||
child ui.MacroOp
|
||||
macro op.MacroOp
|
||||
child op.MacroOp
|
||||
scroll gesture.Scroll
|
||||
scrollDelta int
|
||||
|
||||
@@ -246,10 +246,10 @@ func (l *List) layout() Dimensions {
|
||||
Min: axisPoint(l.Axis, min, -inf),
|
||||
Max: axisPoint(l.Axis, max, inf),
|
||||
}
|
||||
var stack ui.StackOp
|
||||
var stack op.StackOp
|
||||
stack.Push(ops)
|
||||
paint.RectClip(r).Add(ops)
|
||||
ui.TransformOp{}.Offset(toPointF(axisPoint(l.Axis, pos, cross))).Add(ops)
|
||||
op.TransformOp{}.Offset(toPointF(axisPoint(l.Axis, pos, cross))).Add(ops)
|
||||
child.macro.Add(ops)
|
||||
stack.Pop()
|
||||
pos += childSize
|
||||
|
||||
+5
-5
@@ -5,7 +5,7 @@ package layout
|
||||
import (
|
||||
"image"
|
||||
|
||||
"gioui.org/ui"
|
||||
"gioui.org/op"
|
||||
)
|
||||
|
||||
// Stack lays out child elements on top of each other,
|
||||
@@ -15,7 +15,7 @@ type Stack struct {
|
||||
// smaller than the available space.
|
||||
Alignment Direction
|
||||
|
||||
macro ui.MacroOp
|
||||
macro op.MacroOp
|
||||
constrained bool
|
||||
ctx *Context
|
||||
maxSZ image.Point
|
||||
@@ -24,7 +24,7 @@ type Stack struct {
|
||||
|
||||
// StackChild is the layout result of a call to End.
|
||||
type StackChild struct {
|
||||
macro ui.MacroOp
|
||||
macro op.MacroOp
|
||||
dims Dimensions
|
||||
}
|
||||
|
||||
@@ -99,9 +99,9 @@ func (s *Stack) Layout(children ...StackChild) {
|
||||
case SW, S, SE:
|
||||
p.Y = s.maxSZ.Y - sz.Y
|
||||
}
|
||||
var stack ui.StackOp
|
||||
var stack op.StackOp
|
||||
stack.Push(s.ctx.Ops)
|
||||
ui.TransformOp{}.Offset(toPointF(p)).Add(s.ctx.Ops)
|
||||
op.TransformOp{}.Offset(toPointF(p)).Add(s.ctx.Ops)
|
||||
ch.macro.Add(s.ctx.Ops)
|
||||
stack.Pop()
|
||||
}
|
||||
|
||||
+7
-6
@@ -10,10 +10,11 @@ import (
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
|
||||
"gioui.org/ui"
|
||||
"gioui.org/f32"
|
||||
"gioui.org/op"
|
||||
"gioui.org/paint"
|
||||
"gioui.org/text"
|
||||
"gioui.org/ui"
|
||||
"golang.org/x/image/font"
|
||||
"golang.org/x/image/font/sfnt"
|
||||
"golang.org/x/image/math/fixed"
|
||||
@@ -34,7 +35,7 @@ type cachedLayout struct {
|
||||
|
||||
type cachedPath struct {
|
||||
active bool
|
||||
path ui.MacroOp
|
||||
path op.MacroOp
|
||||
}
|
||||
|
||||
type layoutKey struct {
|
||||
@@ -128,7 +129,7 @@ func (f *Face) Layout(str string, opts text.LayoutOptions) *text.Layout {
|
||||
return l
|
||||
}
|
||||
|
||||
func (f *Face) Path(str text.String) ui.MacroOp {
|
||||
func (f *Face) Path(str text.String) op.MacroOp {
|
||||
ppem := fixed.Int26_6(f.faces.config.Px(f.size) * 64)
|
||||
pk := pathKey{
|
||||
f: f.font.Font,
|
||||
@@ -234,14 +235,14 @@ func layoutText(ppem fixed.Int26_6, str string, f *opentype, opts text.LayoutOpt
|
||||
return &text.Layout{Lines: lines}
|
||||
}
|
||||
|
||||
func textPath(ppem fixed.Int26_6, f *opentype, str text.String) ui.MacroOp {
|
||||
func textPath(ppem fixed.Int26_6, f *opentype, str text.String) op.MacroOp {
|
||||
var lastPos f32.Point
|
||||
var builder paint.PathBuilder
|
||||
ops := new(ui.Ops)
|
||||
ops := new(op.Ops)
|
||||
builder.Init(ops)
|
||||
var x fixed.Int26_6
|
||||
var advIdx int
|
||||
var m ui.MacroOp
|
||||
var m op.MacroOp
|
||||
m.Record(ops)
|
||||
for _, r := range str.String {
|
||||
if !unicode.IsSpace(r) {
|
||||
|
||||
+115
-1
@@ -1,10 +1,67 @@
|
||||
// SPDX-License-Identifier: Unlicense OR MIT
|
||||
|
||||
package ui
|
||||
/*
|
||||
|
||||
Package op implements operations for updating a user interface.
|
||||
|
||||
Gio programs use operations, or ops, for describing their user
|
||||
interfaces. There are operations for drawing, defining input
|
||||
handlers, changing window properties as well as operations for
|
||||
controlling the execution of other operations.
|
||||
|
||||
Ops represents a list of operations. The most important use
|
||||
for an Ops list is to describe a complete user interface update
|
||||
to a ui/app.Window's Update method.
|
||||
|
||||
Drawing a colored square:
|
||||
|
||||
import "gioui.org/ui"
|
||||
import "gioui.org/app"
|
||||
import "gioui.org/paint"
|
||||
|
||||
var w app.Window
|
||||
ops := new(op.Ops)
|
||||
...
|
||||
ops.Reset()
|
||||
paint.ColorOp{Color: ...}.Add(ops)
|
||||
paint.PaintOp{Rect: ...}.Add(ops)
|
||||
w.Update(ops)
|
||||
|
||||
State
|
||||
|
||||
An Ops list can be viewed as a very simple virtual machine: it has an implicit
|
||||
mutable state stack and execution flow can be controlled with macros.
|
||||
|
||||
The StackOp saves the current state to the state stack and restores it later:
|
||||
|
||||
ops := new(op.Ops)
|
||||
var stack op.StackOp
|
||||
// Save the current state, in particular the transform.
|
||||
stack.Push(ops)
|
||||
// Apply a transform to subsequent operations.
|
||||
op.TransformOp{}.Offset(...).Add(ops)
|
||||
...
|
||||
// Restore the previous transform.
|
||||
stack.Pop()
|
||||
|
||||
The MacroOp records a list of operations to be executed later:
|
||||
|
||||
ops := new(op.Ops)
|
||||
var macro op.MacroOp
|
||||
macro.Record()
|
||||
// Record operations by adding them.
|
||||
op.InvalidateOp{}.Add(ops)
|
||||
...
|
||||
|
||||
*/
|
||||
package op
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"math"
|
||||
"time"
|
||||
|
||||
"gioui.org/f32"
|
||||
"gioui.org/internal/opconst"
|
||||
)
|
||||
|
||||
@@ -45,6 +102,18 @@ type MacroOp struct {
|
||||
pc pc
|
||||
}
|
||||
|
||||
// InvalidateOp requests a redraw at the given time. Use
|
||||
// the zero value to request an immediate redraw.
|
||||
type InvalidateOp struct {
|
||||
At time.Time
|
||||
}
|
||||
|
||||
// TransformOp applies a transform to the current transform.
|
||||
type TransformOp struct {
|
||||
// TODO: general transformations.
|
||||
offset f32.Point
|
||||
}
|
||||
|
||||
type pc struct {
|
||||
data int
|
||||
refs int
|
||||
@@ -208,3 +277,48 @@ func (m MacroOp) Add(o *Ops) {
|
||||
bo.PutUint32(data[9:], uint32(m.version))
|
||||
o.Write(data, m.ops)
|
||||
}
|
||||
|
||||
func (r InvalidateOp) Add(o *Ops) {
|
||||
data := make([]byte, opconst.TypeRedrawLen)
|
||||
data[0] = byte(opconst.TypeInvalidate)
|
||||
bo := binary.LittleEndian
|
||||
// UnixNano cannot represent the zero time.
|
||||
if t := r.At; !t.IsZero() {
|
||||
nanos := t.UnixNano()
|
||||
if nanos > 0 {
|
||||
bo.PutUint64(data[1:], uint64(nanos))
|
||||
}
|
||||
}
|
||||
o.Write(data)
|
||||
}
|
||||
|
||||
// Offset the transformation.
|
||||
func (t TransformOp) Offset(o f32.Point) TransformOp {
|
||||
return t.Multiply(TransformOp{o})
|
||||
}
|
||||
|
||||
// Invert the transformation.
|
||||
func (t TransformOp) Invert() TransformOp {
|
||||
return TransformOp{offset: t.offset.Mul(-1)}
|
||||
}
|
||||
|
||||
// Transform a point.
|
||||
func (t TransformOp) Transform(p f32.Point) f32.Point {
|
||||
return p.Add(t.offset)
|
||||
}
|
||||
|
||||
// Multiply by a transformation.
|
||||
func (t TransformOp) Multiply(t2 TransformOp) TransformOp {
|
||||
return TransformOp{
|
||||
offset: t.offset.Add(t2.offset),
|
||||
}
|
||||
}
|
||||
|
||||
func (t TransformOp) Add(o *Ops) {
|
||||
data := make([]byte, opconst.TypeTransformLen)
|
||||
data[0] = byte(opconst.TypeTransform)
|
||||
bo := binary.LittleEndian
|
||||
bo.PutUint32(data[1:], math.Float32bits(t.offset.X))
|
||||
bo.PutUint32(data[5:], math.Float32bits(t.offset.Y))
|
||||
o.Write(data)
|
||||
}
|
||||
+4
-4
@@ -8,9 +8,9 @@ import (
|
||||
"image/color"
|
||||
"math"
|
||||
|
||||
"gioui.org/ui"
|
||||
"gioui.org/f32"
|
||||
"gioui.org/internal/opconst"
|
||||
"gioui.org/op"
|
||||
)
|
||||
|
||||
// ImageOp sets the material to a section of an
|
||||
@@ -33,7 +33,7 @@ type PaintOp struct {
|
||||
Rect f32.Rectangle
|
||||
}
|
||||
|
||||
func (i ImageOp) Add(o *ui.Ops) {
|
||||
func (i ImageOp) Add(o *op.Ops) {
|
||||
data := make([]byte, opconst.TypeImageLen)
|
||||
data[0] = byte(opconst.TypeImage)
|
||||
bo := binary.LittleEndian
|
||||
@@ -44,7 +44,7 @@ func (i ImageOp) Add(o *ui.Ops) {
|
||||
o.Write(data, i.Src)
|
||||
}
|
||||
|
||||
func (c ColorOp) Add(o *ui.Ops) {
|
||||
func (c ColorOp) Add(o *op.Ops) {
|
||||
data := make([]byte, opconst.TypeColorLen)
|
||||
data[0] = byte(opconst.TypeColor)
|
||||
data[1] = c.Color.R
|
||||
@@ -54,7 +54,7 @@ func (c ColorOp) Add(o *ui.Ops) {
|
||||
o.Write(data)
|
||||
}
|
||||
|
||||
func (d PaintOp) Add(o *ui.Ops) {
|
||||
func (d PaintOp) Add(o *op.Ops) {
|
||||
data := make([]byte, opconst.TypePaintLen)
|
||||
data[0] = byte(opconst.TypePaint)
|
||||
bo := binary.LittleEndian
|
||||
|
||||
+4
-4
@@ -7,10 +7,10 @@ import (
|
||||
"math"
|
||||
"unsafe"
|
||||
|
||||
"gioui.org/ui"
|
||||
"gioui.org/f32"
|
||||
"gioui.org/internal/opconst"
|
||||
"gioui.org/internal/path"
|
||||
"gioui.org/op"
|
||||
)
|
||||
|
||||
// PathBuilder builds and adds a general ClipOp clip path
|
||||
@@ -19,7 +19,7 @@ import (
|
||||
// dynamic paths; path data is stored directly in the Ops
|
||||
// list supplied to Init.
|
||||
type PathBuilder struct {
|
||||
ops *ui.Ops
|
||||
ops *op.Ops
|
||||
firstVert int
|
||||
nverts int
|
||||
maxy float32
|
||||
@@ -33,7 +33,7 @@ type ClipOp struct {
|
||||
bounds f32.Rectangle
|
||||
}
|
||||
|
||||
func (p ClipOp) Add(o *ui.Ops) {
|
||||
func (p ClipOp) Add(o *op.Ops) {
|
||||
data := make([]byte, opconst.TypeClipLen)
|
||||
data[0] = byte(opconst.TypeClip)
|
||||
bo := binary.LittleEndian
|
||||
@@ -46,7 +46,7 @@ func (p ClipOp) Add(o *ui.Ops) {
|
||||
|
||||
// Init the builder and specify the operations list for
|
||||
// storing the path data and final ClipOp.
|
||||
func (p *PathBuilder) Init(ops *ui.Ops) {
|
||||
func (p *PathBuilder) Init(ops *op.Ops) {
|
||||
p.ops = ops
|
||||
}
|
||||
|
||||
|
||||
+7
-6
@@ -14,6 +14,7 @@ import (
|
||||
"gioui.org/io/key"
|
||||
"gioui.org/io/pointer"
|
||||
"gioui.org/layout"
|
||||
"gioui.org/op"
|
||||
"gioui.org/paint"
|
||||
"gioui.org/ui"
|
||||
|
||||
@@ -33,12 +34,12 @@ type Editor struct {
|
||||
Submit bool
|
||||
|
||||
// Material for drawing the text.
|
||||
Material ui.MacroOp
|
||||
Material op.MacroOp
|
||||
// Hint contains the text displayed to the user when the
|
||||
// Editor is empty.
|
||||
Hint string
|
||||
// Mmaterial is used to draw the hint.
|
||||
HintMaterial ui.MacroOp
|
||||
HintMaterial op.MacroOp
|
||||
|
||||
oldScale int
|
||||
blinkStart time.Time
|
||||
@@ -218,7 +219,7 @@ func (e *Editor) Layout(gtx *layout.Context) {
|
||||
Width: e.viewWidth(),
|
||||
Offset: off,
|
||||
}
|
||||
var stack ui.StackOp
|
||||
var stack op.StackOp
|
||||
stack.Push(gtx.Ops)
|
||||
// Apply material. Set a default color in case the material is empty.
|
||||
if e.rr.len() > 0 {
|
||||
@@ -233,9 +234,9 @@ func (e *Editor) Layout(gtx *layout.Context) {
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
var stack ui.StackOp
|
||||
var stack op.StackOp
|
||||
stack.Push(gtx.Ops)
|
||||
ui.TransformOp{}.Offset(lineOff).Add(gtx.Ops)
|
||||
op.TransformOp{}.Offset(lineOff).Add(gtx.Ops)
|
||||
e.Face.Path(str).Add(gtx.Ops)
|
||||
paint.PaintOp{Rect: toRectF(clip).Sub(lineOff)}.Add(gtx.Ops)
|
||||
stack.Pop()
|
||||
@@ -267,7 +268,7 @@ func (e *Editor) Layout(gtx *layout.Context) {
|
||||
}
|
||||
}
|
||||
if blinking {
|
||||
redraw := ui.InvalidateOp{At: nextBlink}
|
||||
redraw := op.InvalidateOp{At: nextBlink}
|
||||
redraw.Add(gtx.Ops)
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -8,9 +8,9 @@ import (
|
||||
"image/color"
|
||||
"unicode/utf8"
|
||||
|
||||
"gioui.org/ui"
|
||||
"gioui.org/f32"
|
||||
"gioui.org/layout"
|
||||
"gioui.org/op"
|
||||
"gioui.org/paint"
|
||||
|
||||
"golang.org/x/image/math/fixed"
|
||||
@@ -22,7 +22,7 @@ type Label struct {
|
||||
Face Face
|
||||
// Material is a macro recording the material to draw the
|
||||
// text. Use a ColorOp for colored text.
|
||||
Material ui.MacroOp
|
||||
Material op.MacroOp
|
||||
// Alignment specify the text alignment.
|
||||
Alignment Alignment
|
||||
// Text is the string to draw.
|
||||
@@ -118,9 +118,9 @@ func (l Label) Layout(gtx *layout.Context) {
|
||||
break
|
||||
}
|
||||
lclip := toRectF(clip).Sub(off)
|
||||
var stack ui.StackOp
|
||||
var stack op.StackOp
|
||||
stack.Push(gtx.Ops)
|
||||
ui.TransformOp{}.Offset(off).Add(gtx.Ops)
|
||||
op.TransformOp{}.Offset(off).Add(gtx.Ops)
|
||||
l.Face.Path(str).Add(gtx.Ops)
|
||||
// Set a default color in case the material is empty.
|
||||
paint.ColorOp{Color: color.RGBA{A: 0xff}}.Add(gtx.Ops)
|
||||
|
||||
+2
-2
@@ -6,8 +6,8 @@ import (
|
||||
"fmt"
|
||||
"image"
|
||||
|
||||
"gioui.org/ui"
|
||||
"gioui.org/layout"
|
||||
"gioui.org/op"
|
||||
"golang.org/x/image/math/fixed"
|
||||
)
|
||||
|
||||
@@ -50,7 +50,7 @@ type Face interface {
|
||||
// options.
|
||||
Layout(s string, opts LayoutOptions) *Layout
|
||||
// Path returns the ClipOp outline of a text recorded in a macro.
|
||||
Path(s String) ui.MacroOp
|
||||
Path(s String) op.MacroOp
|
||||
}
|
||||
|
||||
type Alignment uint8
|
||||
|
||||
@@ -4,64 +4,6 @@
|
||||
Package ui defines operations buffers, units and common operations
|
||||
for GUI programs written with the Gio module.
|
||||
|
||||
Operations
|
||||
|
||||
Gio programs use operations, or ops, for describing their user
|
||||
interfaces. There are operations for drawing, defining input
|
||||
handlers, changing window properties as well as operations for
|
||||
controlling the execution of other operations.
|
||||
|
||||
Ops represents a list of operations. The most important use
|
||||
for an Ops list is to describe a complete user interface update
|
||||
to a ui/app.Window's Update method.
|
||||
|
||||
Drawing a colored square:
|
||||
|
||||
import "gioui.org/ui"
|
||||
import "gioui.org/app"
|
||||
import "gioui.org/paint"
|
||||
|
||||
var w app.Window
|
||||
ops := new(ui.Ops)
|
||||
...
|
||||
ops.Reset()
|
||||
paint.ColorOp{Color: ...}.Add(ops)
|
||||
paint.PaintOp{Rect: ...}.Add(ops)
|
||||
w.Update(ops)
|
||||
|
||||
State
|
||||
|
||||
An Ops list can be viewed as a very simple virtual machine: it has an implicit
|
||||
mutable state stack and execution flow can be controlled with macros.
|
||||
|
||||
The StackOp saves the current state to the state stack and restores it later:
|
||||
|
||||
ops := new(ui.Ops)
|
||||
var stack ui.StackOp
|
||||
// Save the current state, in particular the transform.
|
||||
stack.Push(ops)
|
||||
// Apply a transform to subsequent operations.
|
||||
ui.TransformOp{}.Offset(...).Add(ops)
|
||||
...
|
||||
// Restore the previous transform.
|
||||
stack.Pop()
|
||||
|
||||
The MacroOp records a list of operations to be executed later:
|
||||
|
||||
ops := new(ui.Ops)
|
||||
var macro ui.MacroOp
|
||||
macro.Record()
|
||||
// Record operations by adding them.
|
||||
ui.InvalidateOp{}.Add(ops)
|
||||
...
|
||||
macro.Stop()
|
||||
...
|
||||
// Execute the recorded operations.
|
||||
macro.Add(ops)
|
||||
|
||||
Note that operations added between Record and Stop are not executed until
|
||||
the macro is Added.
|
||||
|
||||
Units
|
||||
|
||||
A Value is a value with a Unit attached.
|
||||
|
||||
@@ -3,12 +3,7 @@
|
||||
package ui
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"math"
|
||||
"time"
|
||||
|
||||
"gioui.org/f32"
|
||||
"gioui.org/internal/opconst"
|
||||
)
|
||||
|
||||
// Config define the essential properties of
|
||||
@@ -19,60 +14,3 @@ type Config interface {
|
||||
// Px converts a Value to pixels.
|
||||
Px(v Value) int
|
||||
}
|
||||
|
||||
// InvalidateOp requests a redraw at the given time. Use
|
||||
// the zero value to request an immediate redraw.
|
||||
type InvalidateOp struct {
|
||||
At time.Time
|
||||
}
|
||||
|
||||
// TransformOp applies a transform to the current transform.
|
||||
type TransformOp struct {
|
||||
// TODO: general transformations.
|
||||
offset f32.Point
|
||||
}
|
||||
|
||||
func (r InvalidateOp) Add(o *Ops) {
|
||||
data := make([]byte, opconst.TypeRedrawLen)
|
||||
data[0] = byte(opconst.TypeInvalidate)
|
||||
bo := binary.LittleEndian
|
||||
// UnixNano cannot represent the zero time.
|
||||
if t := r.At; !t.IsZero() {
|
||||
nanos := t.UnixNano()
|
||||
if nanos > 0 {
|
||||
bo.PutUint64(data[1:], uint64(nanos))
|
||||
}
|
||||
}
|
||||
o.Write(data)
|
||||
}
|
||||
|
||||
// Offset the transformation.
|
||||
func (t TransformOp) Offset(o f32.Point) TransformOp {
|
||||
return t.Multiply(TransformOp{o})
|
||||
}
|
||||
|
||||
// Invert the transformation.
|
||||
func (t TransformOp) Invert() TransformOp {
|
||||
return TransformOp{offset: t.offset.Mul(-1)}
|
||||
}
|
||||
|
||||
// Transform a point.
|
||||
func (t TransformOp) Transform(p f32.Point) f32.Point {
|
||||
return p.Add(t.offset)
|
||||
}
|
||||
|
||||
// Multiply by a transformation.
|
||||
func (t TransformOp) Multiply(t2 TransformOp) TransformOp {
|
||||
return TransformOp{
|
||||
offset: t.offset.Add(t2.offset),
|
||||
}
|
||||
}
|
||||
|
||||
func (t TransformOp) Add(o *Ops) {
|
||||
data := make([]byte, opconst.TypeTransformLen)
|
||||
data[0] = byte(opconst.TypeTransform)
|
||||
bo := binary.LittleEndian
|
||||
bo.PutUint32(data[1:], math.Float32bits(t.offset.X))
|
||||
bo.PutUint32(data[5:], math.Float32bits(t.offset.Y))
|
||||
o.Write(data)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user