Grid draws a background kind of idk im goin gto bed

This commit is contained in:
Sasha Koshka 2023-04-08 00:40:10 -04:00
parent 17df738557
commit 76d37df913
5 changed files with 167 additions and 33 deletions

21
cmd/piss/main.go Normal file
View File

@ -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()
}

View File

@ -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
}

19
elements/terminal.go Normal file
View File

@ -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
View File

@ -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
View File

@ -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=