mirror of https://github.com/liamg/aminal.git
things
This commit is contained in:
parent
5889d744f9
commit
5e2c2ca690
48
README.md
48
README.md
|
@ -52,33 +52,27 @@ Ensure you have your latest graphics card drivers installed before use.
|
|||
| Mouse interaction | |
|
||||
| Sweet render effects | |
|
||||
|
||||
## Configuration
|
||||
|
||||
Raft looks for a config file in the following places: `~/.raft.yml`, `~/.config/raft.yml` (earlier in the list prioritised).
|
||||
|
||||
Example config:
|
||||
```
|
||||
debug: False
|
||||
```
|
||||
|
||||
The following options are available:
|
||||
|
||||
| Name | Type | Default |Description |
|
||||
|---------------|---------|---------|-----------------------|
|
||||
| debug | bool | False | Enables debug logging
|
||||
|
||||
|
||||
## Flags
|
||||
|
||||
| Name | Type | Default |Description |
|
||||
|------------------|---------|---------|-----------------------|
|
||||
| --debug | bool | False | Enables debug logging |
|
||||
| --ignore-config | bool | False | Ignores user config files and uses defaults
|
||||
| --always-repaint | bool | False | Redraw the terminal constantly, even when no changes have been made
|
||||
|
||||
## Keyboard Shortcuts
|
||||
|
||||
| Operation | Key(s) |
|
||||
|-----------|---------------------|
|
||||
| Paste | ctrl + shift + v
|
||||
| Operation | Key(s) |
|
||||
|--------------------|---------------------|
|
||||
| Paste | ctrl + shift + v
|
||||
| Interrupt (SIGINT) | ctrl + c
|
||||
| Suspend | ctrl + s
|
||||
| Resume | ctrl + q
|
||||
|
||||
## Configuration
|
||||
|
||||
Raft looks for a config file in `~/.raft.toml`, and will write one there the first time it runs, if it doesn't already exist.
|
||||
|
||||
You can ignore the config and use defauls by specifying `--ignore-config` as a CLI flag.
|
||||
|
||||
### Config Options/CLI Flags
|
||||
|
||||
| CLI Flag | Config Section | Config Name | Type | Default | Description |
|
||||
|--------------------|---------------------|------------------------|---------|--------------|-------------|
|
||||
| --debug | _root_ | debug | boolean | false | Enable debug mode, with debug logging and debug info terminal overlay.
|
||||
| --slomo | _root_ | slomo | boolean | false | Enable slomo mode, delay the handling of each incoming byte (or escape sequence) from the pty by 100ms. Useful for debugging.
|
||||
| --always-repaint | rendering | always_repaint | boolean | false | Redraw the terminal GUI constantly, even when no changes have occurred.
|
||||
|
||||
|
||||
|
|
|
@ -21,19 +21,16 @@ func newCell() Cell {
|
|||
return Cell{}
|
||||
}
|
||||
|
||||
func (cell *Cell) Attr() CellAttributes {
|
||||
return cell.attr
|
||||
}
|
||||
|
||||
func (cell *Cell) Rune() rune {
|
||||
if cell.r == 0 {
|
||||
return '~'
|
||||
}
|
||||
return cell.r
|
||||
}
|
||||
|
||||
func (cell *Cell) Fg() [3]float32 {
|
||||
if cell.r == 0 {
|
||||
return [3]float32{0.5, 0.5, 0.5}
|
||||
}
|
||||
return [3]float32{0.9, 0.9, 0.9} // @todo fix this
|
||||
//return cell.attr.FgColour
|
||||
return cell.attr.FgColour
|
||||
}
|
||||
|
||||
func (cell *Cell) Bg() [3]float32 {
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"math"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Colour [3]float32
|
||||
|
||||
func (c *Colour) UnmarshalText(data []byte) error {
|
||||
|
||||
hexStr := string(data)
|
||||
|
||||
if strings.HasPrefix(hexStr, "#") {
|
||||
hexStr = hexStr[1:]
|
||||
}
|
||||
|
||||
if len(hexStr) != 6 {
|
||||
return fmt.Errorf("Invalid colour format. Should be like #ffffff")
|
||||
}
|
||||
|
||||
bytes, err := hex.DecodeString(hexStr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c[0] = float32(bytes[0]) / 255
|
||||
c[1] = float32(bytes[1]) / 255
|
||||
c[2] = float32(bytes[2]) / 255
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c Colour) MarshalText() (text []byte, err error) {
|
||||
return []byte(fmt.Sprintf(
|
||||
"#%02x%02x%02x",
|
||||
uint8(math.Floor(float64(255*c[0]))),
|
||||
uint8(math.Floor(float64(255*c[1]))),
|
||||
uint8(math.Floor(float64(255*c[2]))),
|
||||
)), nil
|
||||
}
|
||||
|
||||
type ColourScheme struct {
|
||||
Cursor Colour `toml:"cursor"`
|
||||
DefaultFg Colour `toml:"default_fg"`
|
||||
BlackFg Colour `toml:"black_fg"`
|
||||
RedFg Colour `toml:"red_fg"`
|
||||
GreenFg Colour `toml:"green_fg"`
|
||||
YellowFg Colour `toml:"yellow_fg"`
|
||||
BlueFg Colour `toml:"blue_fg"`
|
||||
MagentaFg Colour `toml:"magenta_fg"`
|
||||
CyanFg Colour `toml:"cyan_fg"`
|
||||
LightGreyFg Colour `toml:"light_grey_fg"`
|
||||
DarkGreyFg Colour `toml:"dark_grey_fg"`
|
||||
LightRedFg Colour `toml:"light_red_fg"`
|
||||
LightGreenFg Colour `toml:"light_green_fg"`
|
||||
LightYellowFg Colour `toml:"light_yellow_fg"`
|
||||
LightBlueFg Colour `toml:"light_blue_fg"`
|
||||
LightMagentaFg Colour `toml:"light_magenta_fg"`
|
||||
LightCyanFg Colour `toml:"light_cyan_fg"`
|
||||
WhiteFg Colour `toml:"white_fg"`
|
||||
DefaultBg Colour `toml:"default_bg"`
|
||||
BlackBg Colour `toml:"black_bg"`
|
||||
RedBg Colour `toml:"red_bg"`
|
||||
GreenBg Colour `toml:"green_bg"`
|
||||
YellowBg Colour `toml:"yellow_bg"`
|
||||
BlueBg Colour `toml:"blue_bg"`
|
||||
MagentaBg Colour `toml:"magenta_bg"`
|
||||
CyanBg Colour `toml:"cyan_bg"`
|
||||
LightGreyBg Colour `toml:"light_grey_bg"`
|
||||
DarkGreyBg Colour `toml:"dark_grey_bg"`
|
||||
LightRedBg Colour `toml:"light_red_bg"`
|
||||
LightGreenBg Colour `toml:"light_green_bg"`
|
||||
LightYellowBg Colour `toml:"light_yellow_bg"`
|
||||
LightBlueBg Colour `toml:"light_blue_bg"`
|
||||
LightMagentaBg Colour `toml:"light_magenta_bg"`
|
||||
LightCyanBg Colour `toml:"light_cyan_bg"`
|
||||
WhiteBg Colour `toml:"white_bg"`
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestColourTomlEncoding(t *testing.T) {
|
||||
target := struct {
|
||||
Orange Colour `toml:"colour"`
|
||||
}{
|
||||
Orange: Colour([3]float32{1, 0.5, 0}),
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
e := toml.NewEncoder(&buf)
|
||||
err := e.Encode(target)
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, `colour = "#ff7f00"
|
||||
`, buf.String())
|
||||
|
||||
}
|
||||
func TestColourTomlUnmarshalling(t *testing.T) {
|
||||
target := struct {
|
||||
Purple Colour `toml:"colour"`
|
||||
}{}
|
||||
err := toml.Unmarshal([]byte(`colour = "#7f00ff"`), &target)
|
||||
require.Nil(t, err)
|
||||
assert.InDelta(t, 0.5, target.Purple[0], 0.01)
|
||||
assert.InDelta(t, 0.0, target.Purple[1], 0.01)
|
||||
assert.InDelta(t, 1.0, target.Purple[2], 0.01)
|
||||
}
|
105
config/config.go
105
config/config.go
|
@ -1,105 +1,34 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
"bytes"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
DebugMode bool `yaml:"debug"`
|
||||
ColourScheme ColourScheme
|
||||
Rendering RenderingConfig `yaml:"rendering"`
|
||||
Slomo bool `yaml:"slomo"`
|
||||
DebugMode bool `toml:"debug"`
|
||||
Rendering RenderingConfig `toml:"rendering"`
|
||||
Slomo bool `toml:"slomo"`
|
||||
ColourScheme ColourScheme `toml:"colours"`
|
||||
}
|
||||
|
||||
type RenderingConfig struct {
|
||||
AlwaysRepaint bool `yaml:"always_repaint"`
|
||||
}
|
||||
|
||||
var DefaultConfig = Config{
|
||||
DebugMode: false,
|
||||
ColourScheme: DefaultColourScheme,
|
||||
AlwaysRepaint bool `toml:"always_repaint"`
|
||||
}
|
||||
|
||||
func Parse(data []byte) (*Config, error) {
|
||||
c := DefaultConfig
|
||||
err := yaml.Unmarshal(data, &c)
|
||||
err := toml.Unmarshal(data, &c)
|
||||
return &c, err
|
||||
}
|
||||
|
||||
type ColourScheme struct {
|
||||
Cursor [3]float32
|
||||
DefaultFg [3]float32
|
||||
BlackFg [3]float32
|
||||
RedFg [3]float32
|
||||
GreenFg [3]float32
|
||||
YellowFg [3]float32
|
||||
BlueFg [3]float32
|
||||
MagentaFg [3]float32
|
||||
CyanFg [3]float32
|
||||
LightGreyFg [3]float32
|
||||
DarkGreyFg [3]float32
|
||||
LightRedFg [3]float32
|
||||
LightGreenFg [3]float32
|
||||
LightYellowFg [3]float32
|
||||
LightBlueFg [3]float32
|
||||
LightMagentaFg [3]float32
|
||||
LightCyanFg [3]float32
|
||||
WhiteFg [3]float32
|
||||
DefaultBg [3]float32
|
||||
BlackBg [3]float32
|
||||
RedBg [3]float32
|
||||
GreenBg [3]float32
|
||||
YellowBg [3]float32
|
||||
BlueBg [3]float32
|
||||
MagentaBg [3]float32
|
||||
CyanBg [3]float32
|
||||
LightGreyBg [3]float32
|
||||
DarkGreyBg [3]float32
|
||||
LightRedBg [3]float32
|
||||
LightGreenBg [3]float32
|
||||
LightYellowBg [3]float32
|
||||
LightBlueBg [3]float32
|
||||
LightMagentaBg [3]float32
|
||||
LightCyanBg [3]float32
|
||||
WhiteBg [3]float32
|
||||
}
|
||||
|
||||
var DefaultColourScheme = ColourScheme{
|
||||
Cursor: [3]float32{0.8, 0.8, 0.8},
|
||||
//fg
|
||||
DefaultFg: [3]float32{1, 1, 1},
|
||||
BlackFg: [3]float32{0, 0, 0},
|
||||
RedFg: [3]float32{1, 0, 0},
|
||||
GreenFg: [3]float32{0, 1, 0},
|
||||
YellowFg: [3]float32{1, 1, 0},
|
||||
BlueFg: [3]float32{0, 0, 1},
|
||||
MagentaFg: [3]float32{1, 0, 1},
|
||||
CyanFg: [3]float32{0, 1, 1},
|
||||
LightGreyFg: [3]float32{0.7, 0.7, 0.7},
|
||||
DarkGreyFg: [3]float32{0.3, 0.3, 0.3},
|
||||
LightRedFg: [3]float32{1, 0.5, 0.5},
|
||||
LightGreenFg: [3]float32{0.5, 1, 0.5},
|
||||
LightYellowFg: [3]float32{1, 1, 0.5},
|
||||
LightBlueFg: [3]float32{0.5, 0.5, 1},
|
||||
LightMagentaFg: [3]float32{1, 0.5, 1},
|
||||
LightCyanFg: [3]float32{0.5, 1, 1},
|
||||
WhiteFg: [3]float32{1, 1, 1},
|
||||
// bg
|
||||
DefaultBg: [3]float32{0.1, 0.1, 0.1},
|
||||
BlackBg: [3]float32{0, 0, 0},
|
||||
RedBg: [3]float32{1, 0, 0},
|
||||
GreenBg: [3]float32{0, 1, 0},
|
||||
YellowBg: [3]float32{1, 1, 0},
|
||||
BlueBg: [3]float32{0, 0, 1},
|
||||
MagentaBg: [3]float32{1, 0, 1},
|
||||
CyanBg: [3]float32{0, 1, 1},
|
||||
LightGreyBg: [3]float32{0.7, 0.7, 0.7},
|
||||
DarkGreyBg: [3]float32{0.3, 0.3, 0.3},
|
||||
LightRedBg: [3]float32{1, 0.5, 0.5},
|
||||
LightGreenBg: [3]float32{0.5, 1, 0.5},
|
||||
LightYellowBg: [3]float32{1, 1, 0.5},
|
||||
LightBlueBg: [3]float32{0.5, 0.5, 1},
|
||||
LightMagentaBg: [3]float32{1, 0.5, 1},
|
||||
LightCyanBg: [3]float32{0.5, 1, 1},
|
||||
WhiteBg: [3]float32{1, 1, 1},
|
||||
func (c *Config) Encode() ([]byte, error) {
|
||||
var buf bytes.Buffer
|
||||
e := toml.NewEncoder(&buf)
|
||||
err := e.Encode(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
package config
|
||||
|
||||
var DefaultConfig = Config{
|
||||
DebugMode: false,
|
||||
ColourScheme: ColourScheme{
|
||||
Cursor: [3]float32{0.8, 0.8, 0.8},
|
||||
//fg
|
||||
DefaultFg: [3]float32{1, 1, 1},
|
||||
BlackFg: [3]float32{0, 0, 0},
|
||||
RedFg: [3]float32{1, 0, 0},
|
||||
GreenFg: [3]float32{0, 1, 0},
|
||||
YellowFg: [3]float32{1, 1, 0},
|
||||
BlueFg: [3]float32{0, 0, 1},
|
||||
MagentaFg: [3]float32{1, 0, 1},
|
||||
CyanFg: [3]float32{0, 1, 1},
|
||||
LightGreyFg: [3]float32{0.7, 0.7, 0.7},
|
||||
DarkGreyFg: [3]float32{0.3, 0.3, 0.3},
|
||||
LightRedFg: [3]float32{1, 0.5, 0.5},
|
||||
LightGreenFg: [3]float32{0.5, 1, 0.5},
|
||||
LightYellowFg: [3]float32{1, 1, 0.5},
|
||||
LightBlueFg: [3]float32{0.5, 0.5, 1},
|
||||
LightMagentaFg: [3]float32{1, 0.5, 1},
|
||||
LightCyanFg: [3]float32{0.5, 1, 1},
|
||||
WhiteFg: [3]float32{1, 1, 1},
|
||||
// bg
|
||||
DefaultBg: [3]float32{0.1, 0.1, 0.1},
|
||||
BlackBg: [3]float32{0, 0, 0},
|
||||
RedBg: [3]float32{1, 0, 0},
|
||||
GreenBg: [3]float32{0, 1, 0},
|
||||
YellowBg: [3]float32{1, 1, 0},
|
||||
BlueBg: [3]float32{0, 0, 1},
|
||||
MagentaBg: [3]float32{1, 0, 1},
|
||||
CyanBg: [3]float32{0, 1, 1},
|
||||
LightGreyBg: [3]float32{0.7, 0.7, 0.7},
|
||||
DarkGreyBg: [3]float32{0.3, 0.3, 0.3},
|
||||
LightRedBg: [3]float32{1, 0.5, 0.5},
|
||||
LightGreenBg: [3]float32{0.5, 1, 0.5},
|
||||
LightYellowBg: [3]float32{1, 1, 0.5},
|
||||
LightBlueBg: [3]float32{0.5, 0.5, 1},
|
||||
LightMagentaBg: [3]float32{1, 0.5, 1},
|
||||
LightCyanBg: [3]float32{0.5, 1, 1},
|
||||
WhiteBg: [3]float32{1, 1, 1},
|
||||
},
|
||||
}
|
|
@ -106,7 +106,7 @@ func (gui *GUI) Render() error {
|
|||
return fmt.Errorf("Failed to load font: %s", err)
|
||||
}
|
||||
|
||||
gui.renderer = NewOpenGLRenderer(gui.font, gui.fontScale, 0, 0, gui.width, gui.height)
|
||||
gui.renderer = NewOpenGLRenderer(gui.config, gui.font, gui.fontScale, 0, 0, gui.width, gui.height)
|
||||
|
||||
gui.window.SetFramebufferSizeCallback(gui.resize)
|
||||
gui.window.SetKeyCallback(gui.key)
|
||||
|
@ -137,7 +137,7 @@ func (gui *GUI) Render() error {
|
|||
//glfw.SwapInterval(1)
|
||||
|
||||
gl.ClearColor(
|
||||
gui.config.ColourScheme.DefaultBg[0],
|
||||
1.0, //gui.config.ColourScheme.DefaultBg[0],
|
||||
gui.config.ColourScheme.DefaultBg[1],
|
||||
gui.config.ColourScheme.DefaultBg[2],
|
||||
1.0,
|
||||
|
|
147
gui/renderer.go
147
gui/renderer.go
|
@ -4,8 +4,10 @@ import (
|
|||
"fmt"
|
||||
"math"
|
||||
|
||||
"github.com/go-gl/gl/all-core/gl"
|
||||
"github.com/liamg/glfont"
|
||||
"gitlab.com/liamg/raft/buffer"
|
||||
"gitlab.com/liamg/raft/config"
|
||||
)
|
||||
|
||||
type Renderer interface {
|
||||
|
@ -27,9 +29,90 @@ type OpenGLRenderer struct {
|
|||
termCols int
|
||||
termRows int
|
||||
cellPositions map[[2]int][2]float32
|
||||
rectangles map[[2]int]*rectangle
|
||||
config config.Config
|
||||
}
|
||||
|
||||
func NewOpenGLRenderer(font *glfont.Font, fontScale int32, areaX int, areaY int, areaWidth int, areaHeight int) *OpenGLRenderer {
|
||||
type rectangle struct {
|
||||
vao uint32
|
||||
vbo uint32
|
||||
cv uint32
|
||||
colourAttr uint32
|
||||
colour [3]float32
|
||||
points []float32
|
||||
}
|
||||
|
||||
func (r *OpenGLRenderer) newRectangle(x float32, y float32) *rectangle {
|
||||
|
||||
x = (x - float32(r.areaWidth/2)) / float32(r.areaWidth/2)
|
||||
y = -(y - float32(r.areaHeight/2)) / float32(r.areaHeight/2)
|
||||
w := r.cellWidth / float32(r.areaWidth/2)
|
||||
h := r.cellHeight / float32(r.areaHeight/2)
|
||||
|
||||
rect := &rectangle{
|
||||
colour: [3]float32{0, 0, 1},
|
||||
points: []float32{
|
||||
x, y + h, 0,
|
||||
x, y, 0,
|
||||
x + w, y, 0,
|
||||
x, y + h, 0,
|
||||
x + w, y + h, 0,
|
||||
x + w, y, 0,
|
||||
},
|
||||
}
|
||||
|
||||
rect.gen()
|
||||
|
||||
return rect
|
||||
}
|
||||
|
||||
func (rect *rectangle) gen() {
|
||||
|
||||
colour := []float32{
|
||||
rect.colour[0], rect.colour[1], rect.colour[2],
|
||||
rect.colour[0], rect.colour[1], rect.colour[2],
|
||||
rect.colour[0], rect.colour[1], rect.colour[2],
|
||||
rect.colour[0], rect.colour[1], rect.colour[2],
|
||||
rect.colour[0], rect.colour[1], rect.colour[2],
|
||||
rect.colour[0], rect.colour[1], rect.colour[2],
|
||||
}
|
||||
|
||||
// SHAPE
|
||||
gl.GenBuffers(1, &rect.vbo)
|
||||
gl.BindBuffer(gl.ARRAY_BUFFER, rect.vbo)
|
||||
gl.BufferData(gl.ARRAY_BUFFER, 4*len(rect.points), gl.Ptr(rect.points), gl.STATIC_DRAW)
|
||||
|
||||
gl.GenVertexArrays(1, &rect.vao)
|
||||
gl.BindVertexArray(rect.vao)
|
||||
gl.EnableVertexAttribArray(0)
|
||||
|
||||
gl.BindBuffer(gl.ARRAY_BUFFER, rect.vbo)
|
||||
gl.VertexAttribPointer(0, 3, gl.FLOAT, false, 0, nil)
|
||||
|
||||
// colour
|
||||
gl.GenBuffers(1, &rect.cv)
|
||||
gl.BindBuffer(gl.ARRAY_BUFFER, rect.cv)
|
||||
gl.BufferData(gl.ARRAY_BUFFER, len(colour)*4, gl.Ptr(colour), gl.STATIC_DRAW)
|
||||
gl.EnableVertexAttribArray(rect.colourAttr)
|
||||
gl.VertexAttribPointer(rect.colourAttr, 3, gl.FLOAT, false, 0, gl.PtrOffset(0))
|
||||
}
|
||||
|
||||
func (rect *rectangle) setColour(colour [3]float32) {
|
||||
if rect.colour == colour || true {
|
||||
return
|
||||
}
|
||||
rect.Free()
|
||||
rect.colour = colour
|
||||
rect.gen()
|
||||
}
|
||||
|
||||
func (rect *rectangle) Free() {
|
||||
gl.DeleteVertexArrays(1, &rect.vao)
|
||||
gl.DeleteBuffers(1, &rect.vbo)
|
||||
gl.DeleteBuffers(1, &rect.cv)
|
||||
}
|
||||
|
||||
func NewOpenGLRenderer(config config.Config, font *glfont.Font, fontScale int32, areaX int, areaY int, areaWidth int, areaHeight int) *OpenGLRenderer {
|
||||
r := &OpenGLRenderer{
|
||||
areaWidth: areaWidth,
|
||||
areaHeight: areaHeight,
|
||||
|
@ -37,6 +120,8 @@ func NewOpenGLRenderer(font *glfont.Font, fontScale int32, areaX int, areaY int,
|
|||
areaY: areaY,
|
||||
fontScale: fontScale,
|
||||
cellPositions: map[[2]int][2]float32{},
|
||||
rectangles: map[[2]int]*rectangle{},
|
||||
config: config,
|
||||
}
|
||||
r.SetFont(font)
|
||||
return r
|
||||
|
@ -59,7 +144,7 @@ func (r *OpenGLRenderer) SetFontScale(fontScale int32) {
|
|||
r.SetFont(r.font)
|
||||
}
|
||||
|
||||
func (r *OpenGLRenderer) SetFont(font *glfont.Font) {
|
||||
func (r *OpenGLRenderer) SetFont(font *glfont.Font) { // @todo check for monospace and return error if not?
|
||||
r.font = font
|
||||
r.verticalCellPadding = (0.3 * float32(r.fontScale))
|
||||
r.cellWidth = font.Width(1, "X")
|
||||
|
@ -67,14 +152,15 @@ func (r *OpenGLRenderer) SetFont(font *glfont.Font) {
|
|||
r.termCols = int(math.Floor(float64(float32(r.areaWidth) / r.cellWidth)))
|
||||
r.termRows = int(math.Floor(float64(float32(r.areaHeight) / r.cellHeight)))
|
||||
r.calculatePositions()
|
||||
r.generateRectangles()
|
||||
}
|
||||
|
||||
func (r *OpenGLRenderer) calculatePositions() {
|
||||
for line := 0; line < r.termRows; line++ {
|
||||
for col := 0; col < r.termCols; col++ {
|
||||
// rounding to whole pixels makes everything nice
|
||||
x := float32(math.Floor(float64((float32(col) * r.cellWidth) + (r.cellWidth / 2))))
|
||||
y := float32(math.Floor(float64(
|
||||
x := float32(math.Round(float64((float32(col) * r.cellWidth))))
|
||||
y := float32(math.Round(float64(
|
||||
(float32(line) * r.cellHeight) + (r.cellHeight / 2) + r.verticalCellPadding,
|
||||
)))
|
||||
r.cellPositions[[2]int{col, line}] = [2]float32{x, y}
|
||||
|
@ -82,19 +168,66 @@ func (r *OpenGLRenderer) calculatePositions() {
|
|||
}
|
||||
}
|
||||
|
||||
func (r *OpenGLRenderer) generateRectangles() {
|
||||
for line := 0; line < r.termRows; line++ {
|
||||
for col := 0; col < r.termCols; col++ {
|
||||
|
||||
rect, ok := r.rectangles[[2]int{col, line}]
|
||||
if ok {
|
||||
rect.Free()
|
||||
}
|
||||
|
||||
// rounding to whole pixels makes everything nice
|
||||
x := float32(float64((float32(col) * r.cellWidth)))
|
||||
y := float32(float64((float32(line) * r.cellHeight) + (r.cellHeight)))
|
||||
r.rectangles[[2]int{col, line}] = r.newRectangle(x, y)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (r *OpenGLRenderer) DrawCell(cell *buffer.Cell, col int, row int) {
|
||||
|
||||
if cell == nil {
|
||||
if cell == nil || cell.Attr().Hidden || cell.Rune() == 0x00 {
|
||||
return
|
||||
}
|
||||
|
||||
fg := cell.Fg()
|
||||
r.font.SetColor(fg[0], fg[1], fg[2], 1)
|
||||
var fg [3]float32
|
||||
var bg [3]float32
|
||||
|
||||
if cell.Attr().Reverse {
|
||||
fg = cell.Bg()
|
||||
bg = cell.Fg()
|
||||
} else {
|
||||
fg = cell.Fg()
|
||||
bg = cell.Bg()
|
||||
}
|
||||
|
||||
var alpha float32 = 1
|
||||
if cell.Attr().Dim {
|
||||
alpha = 0.5
|
||||
}
|
||||
r.font.SetColor(fg[0], fg[1], fg[2], alpha)
|
||||
|
||||
pos, ok := r.cellPositions[[2]int{col, row}]
|
||||
if !ok {
|
||||
panic(fmt.Sprintf("Missing position data for cell at %d,%d", col, row))
|
||||
}
|
||||
|
||||
rect, ok := r.rectangles[[2]int{col, row}]
|
||||
if !ok {
|
||||
panic(fmt.Sprintf("Missing rectangle data for cell at %d,%d", col, row))
|
||||
}
|
||||
|
||||
//rect.setColour(bg)
|
||||
_ = bg
|
||||
rect.setColour([3]float32{0, 0, 1})
|
||||
|
||||
gl.BindVertexArray(rect.vao)
|
||||
gl.DrawArrays(gl.TRIANGLES, 0, 6)
|
||||
|
||||
if cell.Attr().Bold { // bold means draw text again one pixel to right, so it's fatter
|
||||
r.font.Print(pos[0]+1, pos[1], 1, string(cell.Rune()))
|
||||
}
|
||||
r.font.Print(pos[0], pos[1], 1, string(cell.Rune()))
|
||||
|
||||
/*
|
||||
|
|
16
main.go
16
main.go
|
@ -21,6 +21,7 @@ func getConfig() config.Config {
|
|||
}
|
||||
|
||||
conf := loadConfigFile()
|
||||
|
||||
flag.BoolVar(&conf.DebugMode, "debug", conf.DebugMode, "Enable debug logging")
|
||||
flag.BoolVar(&conf.Slomo, "slomo", conf.Slomo, "Render in slow motion (useful for debugging)")
|
||||
flag.BoolVar(&conf.Rendering.AlwaysRepaint, "always-repaint", conf.Rendering.AlwaysRepaint, "Always repaint the window, even when no changes have occurred")
|
||||
|
@ -37,8 +38,8 @@ func loadConfigFile() config.Config {
|
|||
}
|
||||
|
||||
places := []string{
|
||||
fmt.Sprintf("%s/.raft.yml", home),
|
||||
fmt.Sprintf("%s/.config/raft.yml", home),
|
||||
//fmt.Sprintf("%s/.config/raft.yml", home),
|
||||
fmt.Sprintf("%s/.raft.toml", home),
|
||||
}
|
||||
|
||||
for _, place := range places {
|
||||
|
@ -51,6 +52,13 @@ func loadConfigFile() config.Config {
|
|||
}
|
||||
}
|
||||
|
||||
if b, err := config.DefaultConfig.Encode(); err != nil {
|
||||
fmt.Printf("Failed to encode config file: %s\n", err)
|
||||
} else {
|
||||
if err := ioutil.WriteFile(fmt.Sprintf("%s/.raft.toml", home), b, 0644); err != nil {
|
||||
fmt.Printf("Failed to encode config file: %s\n", err)
|
||||
}
|
||||
}
|
||||
return config.DefaultConfig
|
||||
}
|
||||
|
||||
|
@ -61,7 +69,9 @@ func getLogger(conf config.Config) (*zap.SugaredLogger, error) {
|
|||
if conf.DebugMode {
|
||||
logger, err = zap.NewDevelopment()
|
||||
} else {
|
||||
logger, err = zap.NewProduction()
|
||||
loggerConfig := zap.NewProductionConfig()
|
||||
loggerConfig.Encoding = "console"
|
||||
logger, err = loggerConfig.Build()
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to create logger: %s", err)
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
package terminal
|
||||
|
||||
type Cell struct {
|
||||
r rune
|
||||
attr CellAttributes
|
||||
}
|
||||
|
||||
type CellAttributes struct {
|
||||
FgColour [3]float32
|
||||
BgColour [3]float32
|
||||
Bold bool
|
||||
Dim bool
|
||||
Underline bool
|
||||
Blink bool
|
||||
Reverse bool
|
||||
Hidden bool
|
||||
}
|
||||
|
||||
func (terminal *Terminal) NewCell() Cell {
|
||||
return Cell{
|
||||
attr: CellAttributes{
|
||||
FgColour: terminal.config.ColourScheme.DefaultFg,
|
||||
BgColour: terminal.config.ColourScheme.DefaultBg,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (cell *Cell) GetRune() rune {
|
||||
return cell.r
|
||||
}
|
||||
|
||||
func (cell *Cell) IsHidden() bool {
|
||||
return cell.attr.Hidden
|
||||
}
|
||||
|
||||
func (cell *Cell) GetFgColour() (r float32, g float32, b float32) {
|
||||
|
||||
if cell.attr.Reverse {
|
||||
return cell.attr.BgColour[0], cell.attr.BgColour[1], cell.attr.BgColour[2]
|
||||
}
|
||||
return cell.attr.FgColour[0], cell.attr.FgColour[1], cell.attr.FgColour[2]
|
||||
}
|
||||
|
||||
func (cell *Cell) GetBgColour() (r float32, g float32, b float32) {
|
||||
|
||||
if cell.attr.Reverse {
|
||||
return cell.attr.FgColour[0], cell.attr.FgColour[1], cell.attr.FgColour[2]
|
||||
}
|
||||
return cell.attr.BgColour[0], cell.attr.BgColour[1], cell.attr.BgColour[2]
|
||||
}
|
|
@ -28,11 +28,6 @@ type Terminal struct {
|
|||
resumeChan chan bool
|
||||
}
|
||||
|
||||
type Line struct {
|
||||
Cells []Cell
|
||||
wrapped bool
|
||||
}
|
||||
|
||||
type Winsize struct {
|
||||
Height uint16
|
||||
Width uint16
|
||||
|
|
Loading…
Reference in New Issue