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 113 114 115 116 117 118 119 120
|
// 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 cellmod provides a widget that can change the cell data of an inner widget.
package cellmod
import (
"github.com/gcla/gowid"
)
//======================================================================
type ICellMod interface {
Transform(gowid.Cell, gowid.Selector) gowid.Cell
}
type Func func(gowid.Cell, gowid.Selector) gowid.Cell
func (f Func) Transform(cell gowid.Cell, focus gowid.Selector) gowid.Cell {
return f(cell, focus)
}
type IWidget interface {
gowid.ICompositeWidget
ICellMod
}
// Widget that adjusts the palette used - if the rendering context provides for a foreground
// color of red (when focused), this widget can provide a map from red -> green to change its
// display
type Widget struct {
gowid.IWidget
mod ICellMod
*gowid.Callbacks
gowid.SubWidgetCallbacks
}
func New(inner gowid.IWidget, mod ICellMod) *Widget {
res := &Widget{
IWidget: inner,
mod: mod,
}
res.SubWidgetCallbacks = gowid.SubWidgetCallbacks{CB: &res.Callbacks}
var _ gowid.IWidget = res
var _ gowid.ICompositeWidget = res
var _ IWidget = res
return res
}
func Opaque(inner gowid.IWidget) *Widget {
return New(inner,
Func(func(c gowid.Cell, focus gowid.Selector) gowid.Cell {
if !c.HasRune() {
c = c.WithRune(' ')
}
return c
}))
}
func (w *Widget) String() string {
return "cellmod"
}
func (w *Widget) SubWidget() gowid.IWidget {
return w.IWidget
}
func (w *Widget) SetSubWidget(inner gowid.IWidget, app gowid.IApp) {
w.IWidget = inner
gowid.RunWidgetCallbacks(w, gowid.SubWidgetCB{}, app, w)
}
func (w *Widget) Mod() ICellMod {
return w.mod
}
func (w *Widget) SetMod(mod ICellMod) {
w.mod = mod
}
func (w *Widget) Transform(c gowid.Cell, focus gowid.Selector) gowid.Cell {
return w.Mod().Transform(c, focus)
}
func (w *Widget) SubWidgetSize(size gowid.IRenderSize, focus gowid.Selector, app gowid.IApp) gowid.IRenderSize {
return w.SubWidget().RenderSize(size, focus, app)
}
func (w *Widget) RenderSize(size gowid.IRenderSize, focus gowid.Selector, app gowid.IApp) gowid.IRenderBox {
return w.SubWidget().RenderSize(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 gowid.UserInputIfSelectable(w.IWidget, ev, size, focus, app)
}
//''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
func Render(w IWidget, size gowid.IRenderSize, focus gowid.Selector, app gowid.IApp) gowid.ICanvas {
c := w.SubWidget().Render(size, focus, app)
gowid.RangeOverCanvas(c, gowid.CellRangeFunc(func(cell gowid.Cell) gowid.Cell {
return w.Transform(cell, focus)
}))
return c
}
//======================================================================
// Local Variables:
// mode: Go
// fill-column: 110
// End:
|