mirror of
https://github.com/bloeys/gopad.git
synced 2025-12-29 06:58:21 +00:00
Simplify and correct cursor behavior+get char at cursor
This commit is contained in:
71
editor.go
71
editor.go
@ -9,6 +9,7 @@ import (
|
||||
"github.com/inkyblackness/imgui-go/v4"
|
||||
)
|
||||
|
||||
// hello there my friend
|
||||
const (
|
||||
linesPerNode = 100
|
||||
textPadding = 10
|
||||
@ -67,7 +68,7 @@ func (e *Editor) RefreshFontSettings() {
|
||||
e.CharWidth = imgui.CalcTextSize("abcdefghijklmnopqrstuvwxyz", false, 1000).X / 26
|
||||
}
|
||||
|
||||
func (e *Editor) RoundToNearestChar(x float32) float32 {
|
||||
func (e *Editor) RoundToGrid(x float32) float32 {
|
||||
return float32(math.Round(float64(x/e.CharWidth))) * e.CharWidth
|
||||
}
|
||||
|
||||
@ -102,26 +103,26 @@ func (e *Editor) Render(drawStartPos, winSize *imgui.Vec2) {
|
||||
//char window pos.
|
||||
//
|
||||
//Since Gopad only supports fixed-width fonts, we treat the text area as a grid with each
|
||||
//cell having identical width and one char.
|
||||
//cell having identical width and one char inside.
|
||||
//
|
||||
//Global suffix means the position is in window coords.
|
||||
//Editor suffix means coords are within the text editor coords, where sidebar and tabs have been adjusted for
|
||||
//'Global' suffix means the position is in window coords.
|
||||
//'Editor' suffix means coords are within the text editor coords, where sidebar and tabs have been adjusted for
|
||||
clickedColWindowYEditor := clampInt(e.MouseY-int(paddedDrawStartPos.Y), 0, math.MaxInt)
|
||||
clickedColGridYEditor := clampInt(clickedColWindowYEditor/int(e.LineHeight), 0, e.LineCount)
|
||||
|
||||
clickedColWindowXGlobal := clampInt(int(e.RoundToNearestChar(float32(e.MouseX))), 0, math.MaxInt)
|
||||
clickedColWindowXEditor := clampInt(int(e.RoundToNearestChar(float32(e.MouseX)-paddedDrawStartPos.X)), 0, math.MaxInt)
|
||||
clickedColGridXEditor := clickedColWindowXEditor / int(e.CharWidth)
|
||||
|
||||
roundedMouseX := e.RoundToGrid(float32(e.MouseX))
|
||||
clickedColWindowXGlobal := clampInt(int(roundedMouseX), 0, math.MaxInt)
|
||||
clickedColGridXEditor := int(
|
||||
roundF32(
|
||||
(float32(clickedColWindowXGlobal) - paddedDrawStartPos.X) / e.CharWidth,
|
||||
))
|
||||
//Draw cursor
|
||||
clickedLine := e.GetLine(startLine + clickedColGridYEditor)
|
||||
tabCount, charOffsetFromTabs := getTabs(clickedLine, clickedColGridXEditor)
|
||||
tabCount, _ := getTabs(clickedLine, clickedColGridXEditor)
|
||||
|
||||
textWidth := float32(len(clickedLine.chars)-tabCount+tabCount*settings.TabSize) * e.CharWidth
|
||||
lineX := clampF32(
|
||||
e.RoundToNearestChar(float32(clickedColWindowXGlobal)+float32(charOffsetFromTabs)*e.CharWidth),
|
||||
0,
|
||||
paddedDrawStartPos.X+textWidth,
|
||||
)
|
||||
lineX := clampF32(float32(clickedColWindowXGlobal), 0, paddedDrawStartPos.X+textWidth)
|
||||
|
||||
lineStart := imgui.Vec2{
|
||||
X: lineX,
|
||||
Y: paddedDrawStartPos.Y + float32(clickedColGridYEditor)*e.LineHeight - e.LineHeight*0.25,
|
||||
@ -130,13 +131,45 @@ func (e *Editor) Render(drawStartPos, winSize *imgui.Vec2) {
|
||||
X: lineX,
|
||||
Y: paddedDrawStartPos.Y + float32(clickedColGridYEditor)*e.LineHeight + e.LineHeight*0.75,
|
||||
}
|
||||
dl.AddLineV(lineStart, lineEnd, imgui.PackedColorFromVec4(imgui.Vec4{Z: 0.7, W: 1}), settings.CursorWidthFactor*e.CharWidth)
|
||||
dl.AddLineV(lineStart, lineEnd, imgui.PackedColorFromVec4(settings.CursorColor), settings.CursorWidthFactor*e.CharWidth)
|
||||
|
||||
// charAtCursor := getCharLeftOfCursor(clickedLine, clickedColGridXEditor)
|
||||
// println("Chars:", "'"+charAtCursor+"'", ";", clickedColGridXEditor)
|
||||
}
|
||||
|
||||
func getCharLeftOfCursor(l *Line, cursorGridX int) string {
|
||||
|
||||
if cursorGridX <= 0 || len(l.chars) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
gridSize := 0
|
||||
for i := 0; i < len(l.chars) && i <= cursorGridX; i++ {
|
||||
|
||||
if l.chars[i] == '\t' {
|
||||
gridSize += settings.TabSize
|
||||
} else {
|
||||
gridSize++
|
||||
}
|
||||
|
||||
if gridSize < cursorGridX {
|
||||
continue
|
||||
}
|
||||
|
||||
return string(l.chars[i])
|
||||
}
|
||||
|
||||
if cursorGridX >= gridSize {
|
||||
return string(l.chars[len(l.chars)-1])
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
//TODO: The offset chars must be how many grid cols between cursor col and the nearest non-tab char.
|
||||
func getTabs(l *Line, col int) (tabCount, charsToOffsetBy int) {
|
||||
func getTabs(l *Line, gridPosX int) (tabCount, charsToOffsetBy int) {
|
||||
|
||||
for i := 0; i < len(l.chars) && i < col; i++ {
|
||||
for i := 0; i < len(l.chars) && i < gridPosX; i++ {
|
||||
if l.chars[i] == '\t' {
|
||||
tabCount++
|
||||
}
|
||||
@ -147,8 +180,8 @@ func getTabs(l *Line, col int) (tabCount, charsToOffsetBy int) {
|
||||
return tabCount, charsToOffsetBy
|
||||
}
|
||||
|
||||
charsToRemove := col / charsToOffsetBy * settings.TabSize
|
||||
charsToRemove += col % charsToOffsetBy
|
||||
charsToRemove := gridPosX / charsToOffsetBy * settings.TabSize
|
||||
charsToRemove += gridPosX % charsToOffsetBy
|
||||
return tabCount, clampInt(charsToOffsetBy-charsToRemove, 0, charsToOffsetBy)
|
||||
}
|
||||
|
||||
|
||||
2
go.mod
2
go.mod
@ -4,7 +4,7 @@ go 1.17
|
||||
|
||||
require (
|
||||
github.com/bloeys/nmage v0.0.10
|
||||
github.com/inkyblackness/imgui-go/v4 v4.3.0
|
||||
github.com/inkyblackness/imgui-go/v4 v4.4.0
|
||||
github.com/veandco/go-sdl2 v0.4.14
|
||||
)
|
||||
|
||||
|
||||
7
go.sum
7
go.sum
@ -2,10 +2,6 @@ github.com/bloeys/assimp-go v0.4.2 h1:ArVK74BCFcTO/rCGj2NgZG9xtbjnJdEn5npIeJx1Z0
|
||||
github.com/bloeys/assimp-go v0.4.2/go.mod h1:my3yRxT7CfOztmvi+0svmwbaqw0KFrxaHxncoyaEIP0=
|
||||
github.com/bloeys/gglm v0.3.1 h1:Sy9upW7SBsBfDXrSmEhid3aQ+7J7itej+upwcxOnPMQ=
|
||||
github.com/bloeys/gglm v0.3.1/go.mod h1:qwJQ0WzV191wAMwlGicbfbChbKoSedMk7gFFX6GnyOk=
|
||||
github.com/bloeys/nmage v0.0.8 h1:HCoEaTBWTucnXrjQ+8OCUTzG/3rjpV1eliXWUW44+FY=
|
||||
github.com/bloeys/nmage v0.0.8/go.mod h1:4h2tKtMvk9ab8r/+rem4QonPXEBTho6VWvpCMm0M6iM=
|
||||
github.com/bloeys/nmage v0.0.9 h1:dP0g8e7VeygbX5AcYLTIPheLJr+CZmG2uOICQfcDTDA=
|
||||
github.com/bloeys/nmage v0.0.9/go.mod h1:4h2tKtMvk9ab8r/+rem4QonPXEBTho6VWvpCMm0M6iM=
|
||||
github.com/bloeys/nmage v0.0.10 h1:6Ryl3qjEbXxeIL+9BnBxOrGaW9mKObyY/JbRYkR8ogQ=
|
||||
github.com/bloeys/nmage v0.0.10/go.mod h1:4h2tKtMvk9ab8r/+rem4QonPXEBTho6VWvpCMm0M6iM=
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
@ -13,8 +9,9 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||
github.com/go-gl/gl v0.0.0-20211025173605-bda47ffaa784/go.mod h1:9YTyiznxEY1fVinfM7RvRcjRHbw2xLBJ3AAGIT0I4Nw=
|
||||
github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6 h1:zDw5v7qm4yH7N8C8uWd+8Ii9rROdgWxQuGoJ9WDXxfk=
|
||||
github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6/go.mod h1:9YTyiznxEY1fVinfM7RvRcjRHbw2xLBJ3AAGIT0I4Nw=
|
||||
github.com/inkyblackness/imgui-go/v4 v4.3.0 h1:iyAzqWXq/dG5+6ckDPhGivtrIo6AywGQMvENKzun04s=
|
||||
github.com/inkyblackness/imgui-go/v4 v4.3.0/go.mod h1:g8SAGtOYUP7rYaOB2AsVKCEHmPMDmJKgt4z6d+flhb0=
|
||||
github.com/inkyblackness/imgui-go/v4 v4.4.0 h1:jY32Xl18aRwTBXaDfyefCmPDxJOtGM8kGfu/kMNJpbE=
|
||||
github.com/inkyblackness/imgui-go/v4 v4.4.0/go.mod h1:g8SAGtOYUP7rYaOB2AsVKCEHmPMDmJKgt4z6d+flhb0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
|
||||
@ -6,7 +6,10 @@ var (
|
||||
FontSize float32 = 16
|
||||
TextSelectionColor imgui.Vec4 = imgui.Vec4{X: 84 / 255.0, Y: 153 / 255.0, Z: 199 / 255.0, W: 0.4}
|
||||
EditorBgColor imgui.Vec4 = imgui.Vec4{X: 0.1, Y: 0.1, Z: 0.1, W: 1}
|
||||
|
||||
//NOTE: Imgui hardcodes tab size to 4 in '#define IM_TABSIZE 4'
|
||||
TabSize int = 4
|
||||
ScrollSpeed float32 = 4
|
||||
CursorWidthFactor float32 = 0.15
|
||||
CursorColor imgui.Vec4 = imgui.Vec4{X: 1, Y: 1, Z: 1, W: 1}
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user