Skip to content

Commit

Permalink
Fix cursor color
Browse files Browse the repository at this point in the history
  • Loading branch information
hismailbulut committed Jul 10, 2022
1 parent e5432d4 commit 51f01a1
Show file tree
Hide file tree
Showing 14 changed files with 207 additions and 188 deletions.
46 changes: 19 additions & 27 deletions src/common/color.go
Original file line number Diff line number Diff line change
@@ -1,49 +1,41 @@
package common

import "fmt"
import (
"fmt"
)

// Zero values for reducing allocations
var (
ZeroColorF32 = F32Color{}
ZeroColorU8 = U8Color{}
ZeroColorF32 = Color[float32]{}
ZeroColorU8 = Color[uint8]{}
)

// We can't use generics for color types

type F32Color struct {
R, G, B, A float32
}

func (c F32Color) String() string {
return fmt.Sprintf("F32Color(R: %f, G: %f, B: %f, A: %f)", c.R, c.G, c.B, c.A)
type Color[T Numbers] struct {
R, G, B, A T
}

type U8Color struct {
R, G, B, A uint8
func (c Color[T]) String() string {
return fmt.Sprintf("%T(R: %v, G: %v, B: %v, A: %v)", c, c.R, c.G, c.B, c.A)
}

func (c U8Color) String() string {
return fmt.Sprintf("U8Color(R: %d, G: %d, B: %d, A: %d)", c.R, c.G, c.B, c.A)
}

func (color U8Color) Pack() uint32 {
rgb24 := uint32(color.R)
rgb24 = (rgb24 << 8) | uint32(color.G)
rgb24 = (rgb24 << 8) | uint32(color.B)
return rgb24
}
// func (color Color[T]) Pack() uint32 {
// rgb24 := uint32(color.R)
// rgb24 = (rgb24 << 8) | uint32(color.G)
// rgb24 = (rgb24 << 8) | uint32(color.B)
// return rgb24
// }

func ColorFromUint(color uint32) U8Color {
return U8Color{
func ColorFromUint(color uint32) Color[uint8] {
return Color[uint8]{
R: uint8((color >> 16) & 0xff),
G: uint8((color >> 8) & 0xff),
B: uint8(color & 0xff),
A: 255,
}
}

func (c U8Color) ToF32() F32Color {
return F32Color{
func (c Color[T]) ToF32() Color[float32] {
return Color[float32]{
R: float32(c.R) / 255,
G: float32(c.G) / 255,
B: float32(c.B) / 255,
Expand Down
34 changes: 17 additions & 17 deletions src/common/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ type Animation struct {
// delta time and lifetime. For lifeTime parameter, 1.0 value is 1 seconds
func NewAnimation(from, to Vector2[float32], lifeTime float32) Animation {
if lifeTime <= 0 {
panic("animation must has non zero lifetime")
panic("animation lifetime must bigger than zero")
}
return Animation{
from: from,
Expand Down Expand Up @@ -50,27 +50,27 @@ func (atomicBool *AtomicBool) Get() bool {
return val != 0
}

type AtomicInt int64

func (atomicInt *AtomicInt) Set(value int64) {
atomic.StoreInt64((*int64)(atomicInt), value)
}

func (atomicInt *AtomicInt) Get() int64 {
return atomic.LoadInt64((*int64)(atomicInt))
}

func (atomicInt *AtomicInt) Increment() {
atomicInt.Set(atomicInt.Get() + 1)
}
// type AtomicInt int64
//
// func (atomicInt *AtomicInt) Set(value int64) {
// atomic.StoreInt64((*int64)(atomicInt), value)
// }
//
// func (atomicInt *AtomicInt) Get() int64 {
// return atomic.LoadInt64((*int64)(atomicInt))
// }
//
// func (atomicInt *AtomicInt) Increment() {
// atomicInt.Set(atomicInt.Get() + 1)
// }

// This is just for making code more readable
// Can hold up to 16 enums
type BitMask uint16
// Can hold up to 32 enums
type BitMask uint32

func (mask BitMask) String() string {
str := ""
for i := 15; i >= 0; i-- {
for i := 31; i >= 0; i-- {
if mask.Has(1 << i) {
str += "1"
} else {
Expand Down
10 changes: 1 addition & 9 deletions src/common/math.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,8 @@ type Floats interface {
float32 | float64
}

func Lerp[T Floats](a, b, f T) T {
return (a * (1.0 - f)) + (b * f)
}

type SignedNumbers interface {
Integers | Floats
}

type Numbers interface {
SignedNumbers | UnsignedIntegers
Integers | UnsignedIntegers | Floats
}

func Min[T Numbers](v1, v2 T) T {
Expand Down
6 changes: 3 additions & 3 deletions src/common/rect.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ var (
ZeroRectangleINT = Rectangle[int]{}
)

type Rectangle[T SignedNumbers] struct {
type Rectangle[T Numbers] struct {
X, Y, W, H T
}

func (rect Rectangle[T]) String() string {
return fmt.Sprint("Rect(X: ", rect.X, ", Y: ", rect.Y, ", W: ", rect.W, ", H: ", rect.H, ")")
return fmt.Sprintf("%T(X: %v, Y: %v, W: %v, H: %v)", rect, rect.X, rect.Y, rect.W, rect.H)
}

func Rect[T SignedNumbers](X, Y, W, H T) Rectangle[T] {
func Rect[T Numbers](X, Y, W, H T) Rectangle[T] {
return Rectangle[T]{X: X, Y: Y, W: W, H: H}
}

Expand Down
46 changes: 22 additions & 24 deletions src/common/vector.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,16 @@ var (

// We will use generics for vectors

type Vector2[T SignedNumbers] struct {
type Vector2[T Numbers] struct {
X, Y T
}

func (v Vector2[T]) String() string {
return fmt.Sprintf("%T(X: %v, Y: %v)", v, v.X, v.Y)
}

// just a shortcut
func Vec2[T SignedNumbers](X, Y T) Vector2[T] {
func Vec2[T Numbers](X, Y T) Vector2[T] {
return Vector2[T]{X: X, Y: Y}
}

Expand All @@ -30,17 +34,6 @@ func (v Vector2[T]) Height() T {
return v.Y
}

var (
Vec2Up = Vector2[float32]{X: 0, Y: -1}
Vec2Down = Vector2[float32]{X: 0, Y: 1}
Vec2Left = Vector2[float32]{X: -1, Y: 0}
Vec2Right = Vector2[float32]{X: 1, Y: 0}
)

func (v Vector2[T]) String() string {
return fmt.Sprintf("Vec2(X: %v, Y: %v)", v.X, v.Y)
}

func (v Vector2[T]) ToVec3(Z T) Vector3[T] {
return Vector3[T]{X: v.X, Y: v.Y, Z: Z}
}
Expand Down Expand Up @@ -80,17 +73,17 @@ func (v Vector2[T]) Length() float32 {
return float32(math.Sqrt(float64(v.X*v.X + v.Y*v.Y)))
}

func (v Vector2[T]) LengthSquare() float32 {
return float32(v.X*v.X + v.Y*v.Y)
}
// func (v Vector2[T]) LengthSquare() float32 {
// return float32(v.X*v.X + v.Y*v.Y)
// }

func (v Vector2[T]) Distance(v2 Vector2[T]) float32 {
return v2.Minus(v).Length()
}
// func (v Vector2[T]) Distance(v2 Vector2[T]) float32 {
// return v2.Minus(v).Length()
// }

func (v Vector2[T]) DistanceSquare(v2 Vector2[T]) float32 {
return v2.Minus(v).LengthSquare()
}
// func (v Vector2[T]) DistanceSquare(v2 Vector2[T]) float32 {
// return v2.Minus(v).LengthSquare()
// }

func (v Vector2[T]) Normalized() Vector2[T] {
return v.DivideScalar(T(v.Length()))
Expand All @@ -108,11 +101,16 @@ func (v Vector2[T]) IsInRect(rect Rectangle[T]) bool {
return v.X >= rect.X && v.Y >= rect.Y && v.X < rect.X+rect.W && v.Y < rect.Y+rect.H
}

type Vector3[T SignedNumbers] struct {
type Vector3[T Numbers] struct {
X, Y, Z T
}

func Vec3[T SignedNumbers](X, Y, Z T) Vector3[T] {
func (v Vector3[T]) String() string {
return fmt.Sprintf("%T(X: %v, Y: %v, Z: %v)", v, v.X, v.Y, v.Z)
}

// just a shortcut
func Vec3[T Numbers](X, Y, Z T) Vector3[T] {
return Vector3[T]{X: X, Y: Y, Z: Z}
}

Expand Down
16 changes: 11 additions & 5 deletions src/context_menu.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,14 +138,20 @@ func (menu *ContextMenu) Draw() {
for row := 0; row < menu.rows; row++ {
for col := 0; col < menu.cols; col++ {
char := menu.cells[row][col]
attrib, _ := Editor.gridManager.Attribute(0)
attrib.bold = true
if menu.hlRow == row && col > 0 && col < menu.cols-1 {
menu.renderer.DrawCell(row, col, char, attrib)
// This is the highlighted cell
menu.renderer.DrawCell(row, col, char, HighlightAttribute{
foreground: Editor.gridManager.foreground,
background: Editor.gridManager.background,
bold: true,
})
} else {
// Normally we swap menu colors
attrib.foreground, attrib.background = attrib.background, attrib.foreground
menu.renderer.DrawCell(row, col, char, attrib)
menu.renderer.DrawCell(row, col, char, HighlightAttribute{
foreground: Editor.gridManager.background,
background: Editor.gridManager.foreground,
bold: true,
})
}
}
}
Expand Down
37 changes: 25 additions & 12 deletions src/cursor.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,24 @@ func (cursor *Cursor) modeRectangle(info ModeInfo, position, cellSize common.Vec
}
}

func (cursor *Cursor) AttributeColors(id int) (common.Color[uint8], common.Color[uint8]) {
// When attr_id is 0 we are using cursor foreground for default background and background for default foreground
fg := Editor.gridManager.background
bg := Editor.gridManager.foreground
if id != 0 {
attrib, ok := Editor.gridManager.attributes[id]
if ok {
if attrib.foreground.A > 0 {
fg = attrib.foreground
}
if attrib.background.A > 0 {
bg = attrib.background
}
}
}
return fg, bg
}

func (cursor *Cursor) Draw(delta float32) {
if cursor.hidden || cursor.bHidden {
return
Expand All @@ -175,12 +193,8 @@ func (cursor *Cursor) Draw(delta float32) {
defer EndBenchmark("Cursor.Draw")
// Draw
modeInfo := cursor.mode.Current()
cursorAttrib, found := Editor.gridManager.Attribute(modeInfo.attr_id)
// Reverse colors if attribute not found
if !found {
cursorAttrib.foreground, cursorAttrib.background = cursorAttrib.background, cursorAttrib.foreground
}
// Current grid where cursor is
cursorFg, cursorBg := cursor.AttributeColors(modeInfo.attr_id)
// Current grid where the cursor is
grid := cursor.Grid()
if grid != nil {
pos := cursor.anim.Step(delta).ToInt()
Expand All @@ -190,27 +204,26 @@ func (cursor *Cursor) Draw(delta float32) {
// has a printable character and cursor shape is block
if cursor.anim.IsFinished() && cell.char != 0 && blockShaped {
// We need to draw cell character to the cursor foreground
cellAttrib, _ := Editor.gridManager.Attribute(cell.attribID)
cellAttrib := Editor.gridManager.Attribute(cell.attribID)
// Draw undercurl to cursor if cell has
if cellAttrib.undercurl {
cursor.buffer.SetIndexSp(0, cursorAttrib.foreground.ToF32())
cursor.buffer.SetIndexSp(0, cursorFg.ToF32())
}
// Draw this cell to the cursor
charPos := grid.renderer.atlas.GetCharPos(cell.char, cellAttrib.bold, cellAttrib.italic, cellAttrib.underline, cellAttrib.strikethrough, grid.CellSize())
if charPos.W > grid.CellSize().Width() {
charPos.W /= 2
}
normalized := grid.renderer.atlas.Normalize(charPos)
cursor.buffer.SetIndexTex1(0, normalized)
cursor.buffer.SetIndexFg(0, cursorAttrib.foreground.ToF32())
cursor.buffer.SetIndexTex1(0, grid.renderer.atlas.Normalize(charPos))
cursor.buffer.SetIndexFg(0, cursorFg.ToF32())
} else {
// No cell drawing needed. Clear foreground.
cursor.buffer.SetIndexTex1(0, common.ZeroRectangleF32)
cursor.buffer.SetIndexFg(0, common.ZeroColorF32)
cursor.buffer.SetIndexSp(0, common.ZeroColorF32)
}
// Background and position is always required
cursor.buffer.SetIndexBg(0, cursorAttrib.background.ToF32())
cursor.buffer.SetIndexBg(0, cursorBg.ToF32())
cursor.buffer.SetIndexPos(0, rect)
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/editor.go
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ func UpdateHandler(delta float32) {
// Render calls
if Editor.cDraw || Editor.cForceDraw || Editor.cRender {
EndBenchmark := bench.BeginBenchmark()
Editor.window.GL().ClearScreen(Editor.gridManager.defaultBg)
Editor.window.GL().ClearScreen(Editor.gridManager.background.ToF32())
Editor.gridManager.Render()
Editor.cursor.Render()
Editor.contextMenu.Render()
Expand Down
7 changes: 4 additions & 3 deletions src/grid.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func (gridType GridType) String() string {
}

// Because of the struct packing, this order of elements is important
// Current size of the Cell is 16 bytes
// Current size of the Cell is 16 bytes in 64 bit systems
type Cell struct {
needsDraw bool
char rune
Expand Down Expand Up @@ -60,7 +60,7 @@ type Grid struct {

// For debugging purposes.
func (grid *Grid) String() string {
return fmt.Sprintf("Grid(ID: %d, Number: %d, Type: %s, Pos: %d %d, PixelPos: %v, Size: %d %d, WinID: %d, Hidden: %t)",
return fmt.Sprintf("Grid(ID: %d, Number: %d, Type: %s, Pos: %d %d, PixelPos: %v, Size: %d %d, Window: %d, Hidden: %t)",
grid.id,
grid.number,
grid.typ,
Expand Down Expand Up @@ -215,8 +215,9 @@ func (grid *Grid) Draw(force bool) {
for col := 0; col < grid.cols; col++ {
cell := grid.CellAt(row, col)
if force || cell.needsDraw {
attrib, _ := Editor.gridManager.Attribute(cell.attribID)
attrib := Editor.gridManager.Attribute(cell.attribID)
// Override background alpha
// TODO We must check whether it is default background or not
attrib.background.A = uint8(Editor.options.transparency * 255)
grid.renderer.DrawCell(row, col, cell.char, attrib)
cell.needsDraw = false
Expand Down
Loading

3 comments on commit 51f01a1

@damanis
Copy link

@damanis damanis commented on 51f01a1 Jul 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hismailbulut
I compiled this version. Sometimes a cursor still invisible, sometimes I get something like this:
image
instead of
image
Strange, but when I return to version 0.1.1 it also occures. There were no problems until I tried this version.

$ nvim --version
NVIM v0.8.0-dev+608-g778541067
Build type: RelWithDebInfo
LuaJIT 2.1.0-beta3

@hismailbulut
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@damanis can you create an issue with detailed information? Like how to reproduce, when this happens etc.

@damanis
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.