Grid draws a background kind of idk im goin gto bed
This commit is contained in:
parent
17df738557
commit
76d37df913
|
@ -0,0 +1,21 @@
|
|||
package main
|
||||
|
||||
import "git.tebibyte.media/sashakoshka/tomo"
|
||||
// import "git.tebibyte.media/sashakoshka/tomo/elements"
|
||||
import pissElements "git.tebibyte.media/sashakoshka/piss/elements"
|
||||
import _ "git.tebibyte.media/sashakoshka/tomo/backends/all"
|
||||
|
||||
func main () {
|
||||
tomo.Run(run)
|
||||
}
|
||||
|
||||
func run () {
|
||||
window, _ := tomo.NewWindow(480, 360)
|
||||
window.SetTitle("Terminal")
|
||||
|
||||
terminal := pissElements.NewTerminal()
|
||||
|
||||
window.Adopt(terminal)
|
||||
window.OnClose(tomo.Stop)
|
||||
window.Show()
|
||||
}
|
141
elements/grid.go
141
elements/grid.go
|
@ -1,39 +1,40 @@
|
|||
package elements
|
||||
|
||||
import "image"
|
||||
import "image/color"
|
||||
import "golang.org/x/image/font"
|
||||
import "git.tebibyte.media/sashakoshka/tomo"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/input"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/artist/shapes"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/default/theme"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/default/config"
|
||||
// import "git.tebibyte.media/sashakoshka/tomo/textdraw"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/core"
|
||||
|
||||
type Cell struct {
|
||||
Rune rune
|
||||
Style tomo.FontStyle
|
||||
Background tomo.Color
|
||||
Foreground tomo.Color
|
||||
}
|
||||
|
||||
type gridCell struct {
|
||||
rune
|
||||
tomo.FontStyle
|
||||
background tomo.Color
|
||||
foreground tomo.Color
|
||||
Cell
|
||||
clean bool
|
||||
}
|
||||
|
||||
func (cell *gridCell) initColor () {
|
||||
cell.background = tomo.ColorBackground
|
||||
cell.foreground = tomo.ColorForeground
|
||||
}
|
||||
|
||||
type gridBuffer struct {
|
||||
cells []gridCell
|
||||
stride int
|
||||
func (cell *Cell) initColor () {
|
||||
cell.Background = tomo.ColorBackground
|
||||
cell.Foreground = tomo.ColorForeground
|
||||
}
|
||||
|
||||
// Grid is an array of monospaced character cells. Each one has a foreground and
|
||||
// background color. It satisfies io.Writer and can be fed text with ANSI escape
|
||||
// codes.
|
||||
// background color.
|
||||
type Grid struct {
|
||||
*core.Core
|
||||
*core.FocusableCore
|
||||
core core.CoreControl
|
||||
focusableControl core.FocusableCoreControl
|
||||
|
||||
cells []gridCell
|
||||
stride int
|
||||
|
@ -42,9 +43,10 @@ type Grid struct {
|
|||
|
||||
cursor image.Point
|
||||
|
||||
face font.Face
|
||||
face font.Face
|
||||
config config.Wrapped
|
||||
theme theme.Wrapped
|
||||
colors [19]color.RGBA
|
||||
|
||||
onResize func ()
|
||||
}
|
||||
|
@ -52,18 +54,39 @@ type Grid struct {
|
|||
func NewGrid () (element *Grid) {
|
||||
element = &Grid { }
|
||||
element.theme.Case = tomo.C("tomo", "grid")
|
||||
element.Core, element.core = core.NewCore(element, element.drawAndPush)
|
||||
element.updateFont()
|
||||
element.Core, element.core = core.NewCore(element, element.drawAllAndPush)
|
||||
element.FocusableCore,
|
||||
element.focusableControl = core.NewFocusableCore(element.core, element.drawAndPush)
|
||||
element.updateFontAndColors()
|
||||
element.updateMinimumSize()
|
||||
return
|
||||
}
|
||||
|
||||
func (element *Grid) OnResize (callback func ()) {
|
||||
element.onResize = callback
|
||||
func (element *Grid) Size () (columns, rows int) {
|
||||
columns = element.stride
|
||||
if element.stride > 0 {
|
||||
rows = len(element.cells) / element.stride
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (element *Grid) Write (data []byte) (wrote int, err error) {
|
||||
// TODO process ansi escape codes etx
|
||||
func (element *Grid) At (point image.Point) Cell {
|
||||
if !element.inBounds(point) { return Cell { } }
|
||||
return element.cells[element.index(point)].Cell
|
||||
}
|
||||
|
||||
func (element *Grid) Set (point image.Point, cell Cell) {
|
||||
if !element.inBounds(point) { return }
|
||||
element.cells[element.index(point)].Cell = cell
|
||||
element.cells[element.index(point)].clean = false
|
||||
}
|
||||
|
||||
func (element *Grid) Push () {
|
||||
element.drawAndPush()
|
||||
}
|
||||
|
||||
func (element *Grid) OnResize (callback func ()) {
|
||||
element.onResize = callback
|
||||
}
|
||||
|
||||
func (element *Grid) HandleMouseDown (x, y int, button input.Button) {
|
||||
|
@ -84,7 +107,7 @@ func (element *Grid) HandleKeyUp(key input.Key, modifiers input.Modifiers) { }
|
|||
func (element *Grid) SetTheme (new tomo.Theme) {
|
||||
if new == element.theme.Theme { return }
|
||||
element.theme.Theme = new
|
||||
element.updateFont()
|
||||
element.updateFontAndColors()
|
||||
element.updateMinimumSize()
|
||||
element.drawAndPush()
|
||||
}
|
||||
|
@ -97,18 +120,31 @@ func (element *Grid) SetConfig (new tomo.Config) {
|
|||
element.drawAndPush()
|
||||
}
|
||||
|
||||
|
||||
// -------- private methods -------- //
|
||||
|
||||
|
||||
func (element *Grid) inBounds (point image.Point) bool {
|
||||
if point.X < 0 { return false }
|
||||
if point.Y < 0 { return false }
|
||||
width, height := element.Size()
|
||||
if point.X >= width { return false }
|
||||
if point.Y >= height { return false }
|
||||
return true
|
||||
}
|
||||
|
||||
func (element *Grid) index (point image.Point) int {
|
||||
return point.X + element.stride * point.Y
|
||||
}
|
||||
|
||||
func (element *Grid) alloc () bool {
|
||||
bounds := element.Bounds()
|
||||
width := bounds.Dx() / element.cellWidth
|
||||
height := bounds.Dy() / element.cellHeight
|
||||
unchanged :=
|
||||
width == element.stride &&
|
||||
height == len(element.cells) / element.stride
|
||||
if unchanged { return false }
|
||||
oldWidth, oldHeight := element.Size()
|
||||
if width == oldWidth && height == oldHeight { return false }
|
||||
|
||||
oldCells := element.cells
|
||||
oldWidth := element.stride
|
||||
oldHeight := len(element.cells) / element.stride
|
||||
heightLarger := height < oldHeight
|
||||
|
||||
element.stride = width
|
||||
|
@ -136,7 +172,7 @@ func (element *Grid) alloc () bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func (element *Grid) updateFont () {
|
||||
func (element *Grid) updateFontAndColors () {
|
||||
element.face = element.theme.FontFace (
|
||||
tomo.FontStyleMonospace,
|
||||
tomo.FontSizeNormal)
|
||||
|
@ -144,6 +180,12 @@ func (element *Grid) updateFont () {
|
|||
metrics := element.face.Metrics()
|
||||
element.cellWidth = emSpace.Round()
|
||||
element.cellHeight = metrics.Height.Round()
|
||||
|
||||
for index := range element.colors {
|
||||
element.colors[index] = element.theme.Color (
|
||||
tomo.Color(index),
|
||||
element.state())
|
||||
}
|
||||
}
|
||||
|
||||
func (element *Grid) updateMinimumSize () {
|
||||
|
@ -152,16 +194,51 @@ func (element *Grid) updateMinimumSize () {
|
|||
|
||||
func (element *Grid) state () tomo.State {
|
||||
return tomo.State {
|
||||
|
||||
Focused: element.Focused(),
|
||||
}
|
||||
}
|
||||
|
||||
func (element *Grid) drawAndPush () {
|
||||
if element.core.HasImage () {
|
||||
element.core.DamageRegion(element.draw(element.alloc()))
|
||||
}
|
||||
}
|
||||
|
||||
func (element *Grid) drawAllAndPush () {
|
||||
element.alloc()
|
||||
if element.core.HasImage () {
|
||||
element.core.DamageRegion(element.draw(true))
|
||||
}
|
||||
}
|
||||
|
||||
func (element *Grid) draw (force bool) image.Rectangle {
|
||||
|
||||
func (element *Grid) corner (index int) image.Point {
|
||||
return image.Point {
|
||||
X: (index % element.stride) * element.cellWidth,
|
||||
Y: (index / element.stride) * element.cellHeight,
|
||||
}.Add(element.Bounds().Min)
|
||||
}
|
||||
|
||||
func (element *Grid) bound (index int) image.Rectangle {
|
||||
corner := element.corner(index)
|
||||
return image.Rectangle {
|
||||
Min: corner,
|
||||
Max: image.Pt (
|
||||
corner.X + element.cellWidth,
|
||||
corner.Y + element.cellHeight),
|
||||
}
|
||||
}
|
||||
|
||||
func (element *Grid) draw (force bool) image.Rectangle {
|
||||
bounds := element.Bounds()
|
||||
|
||||
for index, cell := range element.cells {
|
||||
if force || !cell.clean {
|
||||
// TODO
|
||||
shapes.FillColorRectangle (
|
||||
element.core,
|
||||
element.colors[cell.Background],
|
||||
element.bound(index))
|
||||
}}
|
||||
|
||||
return bounds // FIXME
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
package elements
|
||||
|
||||
import "git.tebibyte.media/sashakoshka/piss/ansi"
|
||||
|
||||
type Terminal struct {
|
||||
*Grid
|
||||
decoder ansi.Decoder
|
||||
}
|
||||
|
||||
func NewTerminal () (element *Terminal) {
|
||||
element = &Terminal { Grid: NewGrid() }
|
||||
return
|
||||
}
|
||||
|
||||
func (element *Terminal) Write (buffer []byte) (wrote int, err error) {
|
||||
wrote, err = element.decoder.Write(buffer)
|
||||
element.Push()
|
||||
return
|
||||
}
|
9
go.mod
9
go.mod
|
@ -3,6 +3,13 @@ module git.tebibyte.media/sashakoshka/piss
|
|||
go 1.20
|
||||
|
||||
require (
|
||||
git.tebibyte.media/sashakoshka/tomo v0.0.0-20230408030342-43a664009c03
|
||||
git.tebibyte.media/sashakoshka/tomo v0.0.0-20230408034005-dc077a02abe8
|
||||
golang.org/x/image v0.7.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/freetype-go v0.0.0-20160129220410-b763ddbfe298 // indirect
|
||||
github.com/BurntSushi/graphics-go v0.0.0-20160129215708-b43f31a4a966 // indirect
|
||||
github.com/jezek/xgb v1.1.0 // indirect
|
||||
github.com/jezek/xgbutil v0.0.0-20230403164920-e2f86723ca07 // indirect
|
||||
)
|
||||
|
|
10
go.sum
10
go.sum
|
@ -1,5 +1,15 @@
|
|||
git.tebibyte.media/sashakoshka/tomo v0.0.0-20230408030342-43a664009c03 h1:muzaW520ATZPL8Nq/ROBqbxZbBkPLTEPS2lcrKmuv2Q=
|
||||
git.tebibyte.media/sashakoshka/tomo v0.0.0-20230408030342-43a664009c03/go.mod h1:A0HUbWbA5NgaPVN2ASSn2Y0DxWfaxSV2c0OCSDkYh4c=
|
||||
git.tebibyte.media/sashakoshka/tomo v0.0.0-20230408034005-dc077a02abe8 h1:H4VTKYHpZTM+HyCtfIhw1QDcvY6iJvLUyinPJnalCNU=
|
||||
git.tebibyte.media/sashakoshka/tomo v0.0.0-20230408034005-dc077a02abe8/go.mod h1:A0HUbWbA5NgaPVN2ASSn2Y0DxWfaxSV2c0OCSDkYh4c=
|
||||
github.com/BurntSushi/freetype-go v0.0.0-20160129220410-b763ddbfe298 h1:1qlsVAQJXZHsaM8b6OLVo6muQUQd4CwkH/D3fnnbHXA=
|
||||
github.com/BurntSushi/freetype-go v0.0.0-20160129220410-b763ddbfe298/go.mod h1:D+QujdIlUNfa0igpNMk6UIvlb6C252URs4yupRUV4lQ=
|
||||
github.com/BurntSushi/graphics-go v0.0.0-20160129215708-b43f31a4a966 h1:lTG4HQym5oPKjL7nGs+csTgiDna685ZXjxijkne828g=
|
||||
github.com/BurntSushi/graphics-go v0.0.0-20160129215708-b43f31a4a966/go.mod h1:Mid70uvE93zn9wgF92A/r5ixgnvX8Lh68fxp9KQBaI0=
|
||||
github.com/jezek/xgb v1.1.0 h1:wnpxJzP1+rkbGclEkmwpVFQWpuE2PUGNUzP8SbfFobk=
|
||||
github.com/jezek/xgb v1.1.0/go.mod h1:nrhwO0FX/enq75I7Y7G8iN1ubpSGZEiA3v9e9GyRFlk=
|
||||
github.com/jezek/xgbutil v0.0.0-20230403164920-e2f86723ca07 h1:Fr2Oaa4N2oo30/PGecdDkkrth26nD2/yfQFAoddzXmU=
|
||||
github.com/jezek/xgbutil v0.0.0-20230403164920-e2f86723ca07/go.mod h1:AHecLyFNy6AN9f/+0AH/h1MI7X1+JL5bmCz4XlVZk7Y=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
|
|
Loading…
Reference in New Issue