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

     1  package ui
     2  
     3  import (
     4  	"image"
     5  
     6  	"github.com/jmigpin/editor/util/evreg"
     7  	"github.com/jmigpin/editor/util/uiutil/event"
     8  	"github.com/jmigpin/editor/util/uiutil/widget"
     9  )
    10  
    11  // User Interface root (top) node.
    12  type Root struct {
    13  	*widget.MultiLayer
    14  	UI              *UI
    15  	Toolbar         *Toolbar
    16  	MainMenuButton  *MainMenuButton
    17  	ContextFloatBox *ContextFloatBox
    18  	Cols            *Columns
    19  	EvReg           evreg.Register
    20  }
    21  
    22  func NewRoot(ui *UI) *Root {
    23  	return &Root{MultiLayer: widget.NewMultiLayer(), UI: ui}
    24  }
    25  
    26  func (root *Root) Init() {
    27  	//  background layer
    28  	bgLayer := widget.NewBoxLayout()
    29  	bgLayer.YAxis = true
    30  	root.BgLayer.Append(bgLayer)
    31  
    32  	// background layer
    33  	{
    34  		// top toolbar
    35  		{
    36  			ttb := widget.NewBoxLayout()
    37  			bgLayer.Append(ttb)
    38  
    39  			// toolbar
    40  			root.Toolbar = NewToolbar(root.UI)
    41  			ttb.Append(root.Toolbar)
    42  			ttb.SetChildFlex(root.Toolbar, true, false)
    43  
    44  			// main menu button
    45  			mmb := NewMainMenuButton(root)
    46  			mmb.Label.Border.Left = 1
    47  			ttb.Append(mmb)
    48  			ttb.SetChildFill(mmb, false, true)
    49  			root.MainMenuButton = mmb
    50  		}
    51  
    52  		// columns
    53  		root.Cols = NewColumns(root)
    54  		bgLayer.Append(root.Cols)
    55  	}
    56  
    57  	root.ContextFloatBox = NewContextFloatBox(root)
    58  }
    59  
    60  func (l *Root) OnChildMarked(child widget.Node, newMarks widget.Marks) {
    61  	l.MultiLayer.OnChildMarked(child, newMarks)
    62  	// dynamic toolbar
    63  	if l.Toolbar != nil && l.Toolbar.HasAnyMarks(widget.MarkNeedsLayout) {
    64  		l.BgLayer.MarkNeedsLayout()
    65  	}
    66  }
    67  
    68  //----------
    69  
    70  func (l *Root) OnInputEvent(ev0 interface{}, p image.Point) event.Handled {
    71  	switch ev := ev0.(type) {
    72  	case *event.KeyDown:
    73  		m := ev.Mods.ClearLocks()
    74  		switch {
    75  		case m.Is(event.ModCtrl):
    76  			switch ev.KeySym {
    77  			case event.KSymF4:
    78  				l.selAnnEv(RootSelAnnTypeFirst)
    79  				return true
    80  			case event.KSymF5:
    81  				l.selAnnEv(RootSelAnnTypeLast)
    82  				return true
    83  			case event.KSymF9:
    84  				l.selAnnEv(RootSelAnnTypeClear)
    85  				return true
    86  			}
    87  		}
    88  	case *event.MouseDown:
    89  		m := ev.Mods.ClearLocks()
    90  		switch {
    91  		case m.Is(event.ModCtrl):
    92  			switch ev.Button {
    93  			case event.ButtonWheelUp:
    94  				l.selAnnEv(RootSelAnnTypePrev)
    95  				return true
    96  			case event.ButtonWheelDown:
    97  				l.selAnnEv(RootSelAnnTypeNext)
    98  				return true
    99  			}
   100  		}
   101  	}
   102  	return false
   103  }
   104  
   105  //----------
   106  
   107  func (l *Root) selAnnEv(typ RootSelectAnnotationType) {
   108  	ev2 := &RootSelectAnnotationEvent{typ}
   109  	l.EvReg.RunCallbacks(RootSelectAnnotationEventId, ev2)
   110  }
   111  
   112  //----------
   113  
   114  const (
   115  	RootSelectAnnotationEventId = iota
   116  )
   117  
   118  //----------
   119  
   120  type RootSelectAnnotationEvent struct {
   121  	Type RootSelectAnnotationType
   122  }
   123  
   124  type RootSelectAnnotationType int
   125  
   126  const (
   127  	RootSelAnnTypeFirst RootSelectAnnotationType = iota
   128  	RootSelAnnTypeLast
   129  	RootSelAnnTypePrev
   130  	RootSelAnnTypeNext
   131  	RootSelAnnTypeClear
   132  )