File: cellmod.go

package info (click to toggle)
golang-github-gcla-gowid 1.4.0-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 1,456 kB
  • sloc: makefile: 4
file content (120 lines) | stat: -rw-r--r-- 3,078 bytes parent folder | download
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: