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  }