1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
|
// Copyright 2019-2022 Graham Clark. All rights reserved. Use of this source code is governed by the MIT license
// that can be found in the LICENSE file.
// Package fixedadaptor provides a widget that will render a fixed widget when
// supplied with a box context.
package fixedadapter
import (
"fmt"
"github.com/gcla/gowid"
tcell "github.com/gdamore/tcell/v2"
)
//======================================================================
// Wraps a Fixed widget and turns it into a Box widget. If rendered in a Fixed
// context, render as normal. If rendered in a Box context, render as a Fixed
// widget, then either truncate or grow the resulting canvas to meet the
// box size requirement.
//
type Widget struct {
gowid.IWidget
*gowid.Callbacks
gowid.SubWidgetCallbacks
}
func New(inner gowid.IWidget) *Widget {
res := &Widget{
IWidget: inner,
}
res.SubWidgetCallbacks = gowid.SubWidgetCallbacks{CB: &res.Callbacks}
var _ gowid.IWidget = res
var _ gowid.IComposite = res
return res
}
func (w *Widget) String() string {
return fmt.Sprintf("fixedadapter[%v]", w.SubWidget())
}
func (w *Widget) SubWidget() gowid.IWidget {
return w.IWidget
}
func (w *Widget) SetSubWidget(wi gowid.IWidget, app gowid.IApp) {
w.IWidget = wi
gowid.RunWidgetCallbacks(w, gowid.SubWidgetCB{}, app, w)
}
func (w *Widget) SubWidgetSize(size gowid.IRenderSize, focus gowid.Selector, app gowid.IApp) gowid.IRenderSize {
return SubWidgetSize(w, size, focus, app)
}
func (w *Widget) RenderSize(size gowid.IRenderSize, focus gowid.Selector, app gowid.IApp) gowid.IRenderBox {
return RenderSize(w, size, focus, app)
}
func (w *Widget) Render(size gowid.IRenderSize, focus gowid.Selector, app gowid.IApp) gowid.ICanvas {
return Render(w, size, focus, app)
}
func (w *Widget) UserInput(ev interface{}, size gowid.IRenderSize, focus gowid.Selector, app gowid.IApp) bool {
return UserInput(w, ev, size, focus, app)
}
//''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
func RenderSize(w gowid.IWidget, size gowid.IRenderSize, focus gowid.Selector, app gowid.IApp) gowid.IRenderBox {
return gowid.CalculateRenderSizeFallback(w, size, focus, app)
}
func SubWidgetSize(w interface{}, size gowid.IRenderSize, focus gowid.Selector, app gowid.IApp) gowid.IRenderSize {
return gowid.RenderFixed{}
}
func Render(w gowid.IComposite, size gowid.IRenderSize, focus gowid.Selector, app gowid.IApp) gowid.ICanvas {
res := w.SubWidget().Render(SubWidgetSize(w, size, focus, app), focus, app)
cols, ok := size.(gowid.IColumns)
if !ok {
panic(gowid.WidgetSizeError{Widget: w, Size: size, Required: "gowid.IColumns"})
}
// Make sure that if we're rendered as a box, we have enough rows.
gowid.FixCanvasHeight(res, size)
res.ExtendRight(gowid.EmptyLine(cols.Columns() - res.BoxColumns()))
return res
}
// Ensure that a valid mouse interaction with a flow widget will result in a
// mouse interaction with the subwidget
func UserInput(w gowid.ICompositeWidget, ev interface{}, size gowid.IRenderSize, focus gowid.Selector, app gowid.IApp) bool {
if evm, ok := ev.(*tcell.EventMouse); ok {
box := RenderSize(w, size, focus, app)
mx, my := evm.Position()
if (my < box.BoxRows() && my >= 0) && (mx < box.BoxColumns() && mx >= 0) {
return gowid.UserInputIfSelectable(w.SubWidget(), ev, SubWidgetSize(w, size, focus, app), focus, app)
}
} else {
return gowid.UserInputIfSelectable(w.SubWidget(), ev, SubWidgetSize(w, size, focus, app), focus, app)
}
return false
}
//======================================================================
// Local Variables:
// mode: Go
// fill-column: 110
// End:
|