github.com/jmigpin/editor@v1.6.0/ui/toolbar.go (about)

     1  package ui
     2  
     3  import (
     4  	"image"
     5  
     6  	"github.com/jmigpin/editor/util/drawutil/drawer4"
     7  	"github.com/jmigpin/editor/util/uiutil/event"
     8  )
     9  
    10  type Toolbar struct {
    11  	*TextArea
    12  	warpPointerOnNextLayout bool
    13  }
    14  
    15  func NewToolbar(ui *UI) *Toolbar {
    16  	tb := &Toolbar{}
    17  	tb.TextArea = NewTextArea(ui)
    18  	tb.SetThemePaletteNamePrefix("toolbar_")
    19  	if d, ok := tb.TextArea.Drawer.(*drawer4.Drawer); ok {
    20  		d.Opt.EarlyExitMeasure = true // performance
    21  	}
    22  	return tb
    23  }
    24  
    25  //----------
    26  
    27  func (tb *Toolbar) OnInputEvent(ev interface{}, p image.Point) event.Handled {
    28  	switch ev.(type) {
    29  	case *event.KeyDown, *event.KeyUp:
    30  		// allow typing in the toolbar (dynamic size) without losing focus
    31  		// It is incorrect to do this via rw callback since, for example, restoring a session (writes the toolbar) would trigger the possibility of warping the pointer.
    32  		tb.keepPointerInsideToolbar()
    33  	}
    34  	return tb.TextArea.OnInputEvent(ev, p)
    35  }
    36  
    37  func (tb *Toolbar) keepPointerInsideToolbar() {
    38  	p, err := tb.ui.QueryPointer()
    39  	if err == nil && p.In(tb.Bounds) {
    40  		tb.warpPointerOnNextLayout = true
    41  		tb.MarkNeedsLayout()
    42  	}
    43  }
    44  
    45  func (tb *Toolbar) Layout() {
    46  	tb.TextArea.Layout()
    47  
    48  	// warp pointer to inside the toolbar
    49  	if tb.warpPointerOnNextLayout {
    50  		tb.warpPointerOnNextLayout = false
    51  		p, err := tb.ui.QueryPointer()
    52  		if err == nil && !p.In(tb.Bounds) {
    53  			tb.ui.WarpPointerToRectanglePad(tb.Bounds)
    54  		}
    55  	}
    56  }