github.com/jmigpin/editor@v1.6.0/util/uiutil/widget/floatbox.go (about) 1 package widget 2 3 import ( 4 "image" 5 6 "github.com/jmigpin/editor/util/imageutil" 7 "github.com/jmigpin/editor/util/uiutil/event" 8 ) 9 10 // Should be a child of FloatLayer. 11 type FloatBox struct { 12 ENode 13 RefPoint image.Point 14 content Node 15 ml *MultiLayer 16 MaxSize image.Point 17 } 18 19 func NewFloatBox(ml *MultiLayer, content Node) *FloatBox { 20 fb := &FloatBox{content: content, ml: ml} 21 fb.Cursor = event.DefaultCursor 22 fb.Append(content) 23 fb.AddMarks(MarkNotDraggable | MarkInBoundsHandlesEvent) 24 return fb 25 } 26 27 //---------- 28 29 func (fb *FloatBox) Visible() bool { 30 return !fb.HasAnyMarks(MarkForceZeroBounds) 31 } 32 33 func (fb *FloatBox) Hide() { 34 fb.ml.AddMarkRect(fb.Bounds) 35 fb.AddMarks(MarkForceZeroBounds) 36 fb.MarkNeedsLayoutAndPaint() 37 } 38 39 func (fb *FloatBox) Show() { 40 fb.RemoveMarks(MarkForceZeroBounds) 41 fb.MarkNeedsLayoutAndPaint() 42 } 43 44 func (fb *FloatBox) Toggle() { 45 if !fb.Visible() { 46 fb.Show() 47 } else { 48 fb.Hide() 49 } 50 } 51 52 //---------- 53 54 func (fb *FloatBox) Measure(hint image.Point) image.Point { 55 panic("calling measure on floatbox") 56 } 57 58 func (fb *FloatBox) Layout() { 59 b := fb.Bounds 60 61 // max size 62 max := b.Size() 63 if fb.MaxSize != (image.Point{}) { 64 max = imageutil.MinPoint(max, fb.MaxSize) 65 } 66 m := fb.content.Measure(max) 67 68 // calc bounds attached to the reference point 69 r := image.Rectangle{} 70 r = r.Add(fb.RefPoint) 71 r.Max = r.Min.Add(m) 72 if r.Max.X > b.Max.X { 73 diffX := r.Max.X - b.Max.X 74 r = r.Sub(image.Point{diffX, 0}) 75 } 76 r = r.Intersect(b) 77 78 fb.content.Embed().Bounds = r 79 fb.Bounds = r // reduce own bounds to contain events 80 }