Skip to content

Commit

Permalink
Support visual selections with rounded corners
Browse files Browse the repository at this point in the history
  • Loading branch information
akiyosi committed Jan 6, 2023
1 parent eb1ed9b commit e01c08c
Show file tree
Hide file tree
Showing 2 changed files with 215 additions and 14 deletions.
1 change: 1 addition & 0 deletions editor/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ type editorConfig struct {
HideTitlebar bool
HideMouseWhenTyping bool
IgnoreSaveConfirmationWithCloseButton bool
RoundedSelection bool
}

type cursorConfig struct {
Expand Down
228 changes: 214 additions & 14 deletions editor/window.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ type HlDecoration struct {
strikethrough bool
}

type VSelection struct {
highlight *Highlight
start int
end int
}

// Cell is
type Cell struct {
highlight *Highlight
Expand Down Expand Up @@ -247,11 +253,15 @@ func (w *Window) paint(event *gui.QPaintEvent) {
}

// Draw contents
var vsSlice []*VSelection
// for y := row; y < row+rows; y++ {
for y := row; y < w.rows; y++ {
vsSlice = w.drawBackground(p, y, col, cols, vsSlice)
}
for y := row; y < row+rows; y++ {
if y >= w.rows {
continue
}
w.drawBackground(p, y, col, cols)
w.drawForeground(p, y, col, cols)
}

Expand Down Expand Up @@ -1584,6 +1594,11 @@ func (w *Window) update() {
end = w.rows
}

if editor.config.Editor.RoundedSelection && w.grid != 1 && !w.isMsgGrid {
start = 0
end = w.rows
}

for i := start; i < end; i++ {

if len(w.content) <= i {
Expand All @@ -1599,6 +1614,11 @@ func (w *Window) update() {

drawWithSingleRect := false

if editor.config.Editor.RoundedSelection && w.grid != 1 && !w.isMsgGrid {
width = w.maxLenContent
drawWithSingleRect = true
}

// If DrawIndentGuide is enabled
if editor.config.Editor.IndentGuide {
if i < w.rows-1 {
Expand Down Expand Up @@ -1741,9 +1761,9 @@ func (w *Window) queueRedraw(x, y, width, height int) {
w.redrawMutex.Unlock()
}

func (w *Window) drawBackground(p *gui.QPainter, y int, col int, cols int) {
func (w *Window) drawBackground(p *gui.QPainter, y int, col int, cols int, vsSlice []*VSelection) []*VSelection {
if y >= len(w.content) {
return
return vsSlice
}

line := w.content[y]
Expand Down Expand Up @@ -1821,9 +1841,11 @@ func (w *Window) drawBackground(p *gui.QPainter, y int, col int, cols int) {
// }

// The same color combines the rectangular areas and paints at once

var start, end int
var lastBg *RGBA
var lastHighlight, highlight *Highlight
var vss []*VSelection

for x := col; x <= col+cols; x++ {

Expand Down Expand Up @@ -1865,22 +1887,49 @@ func (w *Window) drawBackground(p *gui.QPainter, y int, col int, cols int) {
end = x
}
if !lastBg.equals(bg) || x == bounds {
w.fillCellRect(p, lastHighlight, lastBg, y, start, end, horScrollPixels, verScrollPixels, isDrawDefaultBg)

w.fillCellRect(p, lastHighlight, lastBg, y, start, end, horScrollPixels, verScrollPixels, isDrawDefaultBg, vsSlice)
width := end - start + 1
if !isDrawDefaultBg && lastBg.equals(w.background) {
width = 0
}
if width > 0 {
vss = append(vss, &VSelection{
highlight: lastHighlight,
start: start,
end: end,
})
}

start = x
end = x
lastBg = bg
lastHighlight = highlight

if x == bounds {
w.fillCellRect(p, lastHighlight, lastBg, y, start, end, horScrollPixels, verScrollPixels, isDrawDefaultBg)

w.fillCellRect(p, lastHighlight, lastBg, y, start, end, horScrollPixels, verScrollPixels, isDrawDefaultBg, vsSlice)
width := end - start + 1
if !isDrawDefaultBg && lastBg.equals(w.background) {
width = 0
}
if width > 0 {
vss = append(vss, &VSelection{
highlight: lastHighlight,
start: start,
end: end,
})
}

}
}
}
}

return vss
}

func (w *Window) fillCellRect(p *gui.QPainter, lastHighlight *Highlight, lastBg *RGBA, y, start, end, horScrollPixels, verScrollPixels int, isDrawDefaultBg bool) {
func (w *Window) fillCellRect(p *gui.QPainter, lastHighlight *Highlight, lastBg *RGBA, y, start, end, horScrollPixels, verScrollPixels int, isDrawDefaultBg bool, vsSlice []*VSelection) {

if lastHighlight == nil {
return
Expand All @@ -1903,15 +1952,50 @@ func (w *Window) fillCellRect(p *gui.QPainter, lastHighlight *Highlight, lastBg
// Set diff pattern
pattern, color, transparent := w.getFillpatternAndTransparent(lastHighlight)

// Fill background with pattern
rectF := core.NewQRectF4(
float64(start)*font.cellwidth+float64(horScrollPixels),
float64((y)*font.lineHeight+verScrollPixels),
float64(width)*font.cellwidth,
float64(font.lineHeight),
if !(editor.config.Editor.RoundedSelection && w.grid != 1 && !w.isMsgGrid) {
// Fill background with pattern
rectF := core.NewQRectF4(
float64(start)*font.cellwidth+float64(horScrollPixels),
float64((y)*font.lineHeight+verScrollPixels),
float64(width)*font.cellwidth,
float64(font.lineHeight),
)
p.FillRect(
rectF,
gui.NewQBrush3(
gui.NewQColor3(
color.R,
color.G,
color.B,
transparent,
),
pattern,
),
)

return
}

// ---------------------
// Apply rounded corners
// ---------------------

path := gui.NewQPainterPath()
path.AddRoundedRect(
core.NewQRectF4(
float64(start)*font.cellwidth+float64(horScrollPixels),
float64((y)*font.lineHeight+verScrollPixels),
float64(width)*font.cellwidth,
float64(font.lineHeight),
),
font.cellwidth/2.5,
font.cellwidth/2.5,
core.Qt__AbsoluteSize,
)
p.FillRect(
rectF,

p.SetPen2(color.QColor())
p.FillPath(
path,
gui.NewQBrush3(
gui.NewQColor3(
color.R,
Expand All @@ -1922,9 +2006,125 @@ func (w *Window) fillCellRect(p *gui.QPainter, lastHighlight *Highlight, lastBg
pattern,
),
)

for _, vs := range vsSlice {
if !vs.highlight.bg().equals(color) {
continue
}

if start < vs.start && end >= vs.start {
w.drawRoundedCorner("rightbottom", p, y, pattern, color, transparent, start, end, vs, horScrollPixels, verScrollPixels)
}
if end > vs.end && start <= vs.end {
w.drawRoundedCorner("leftbottom", p, y, pattern, color, transparent, start, end, vs, horScrollPixels, verScrollPixels)
}

if vs.start < start && vs.end >= start {
w.drawRoundedCorner("topright", p, y, pattern, color, transparent, start, end, vs, horScrollPixels, verScrollPixels)
}
if vs.end > end && vs.start <= end {
w.drawRoundedCorner("topleft", p, y, pattern, color, transparent, start, end, vs, horScrollPixels, verScrollPixels)
}

if vs.start == start {
w.drawRoundedCorner("leftside", p, y, pattern, color, transparent, start, end, vs, horScrollPixels, verScrollPixels)
}
if vs.end == end {
w.drawRoundedCorner("rightside", p, y, pattern, color, transparent, start, end, vs, horScrollPixels, verScrollPixels)
}

}

}
}

func (w *Window) drawRoundedCorner(pStr string, p *gui.QPainter, y int, pattern core.Qt__BrushStyle, color *RGBA, transparent, start, end int, vs *VSelection, horScrollPixels, verScrollPixels int) {
font := w.getFont()

var a [2]float64
var b [2]int
switch pStr {
case "rightbottom":
a[0] = float64(vs.start) - 0.5
a[1] = -0.5
b[0] = vs.start - 1
b[1] = -1
case "leftbottom":
a[0] = float64(vs.end+1) - 0.5
a[1] = -0.5
b[0] = vs.end + 1
b[1] = -1
case "topright":
a[0] = float64(start) - 0.5
a[1] = 0
b[0] = start - 1
b[1] = 0
case "topleft":
a[0] = float64(end+1) - 0.5
a[1] = 0
b[0] = end + 1
b[1] = 0
case "rightside":
a[0] = float64(end)
a[1] = -0.25
b[0] = 0
b[1] = 0
case "leftside":
a[0] = float64(start)
a[1] = -0.25
b[0] = 0
b[1] = 0
}

rect := core.NewQRectF4(
a[0]*font.cellwidth+float64(horScrollPixels),
(float64(y)+a[1])*float64(font.lineHeight)+float64(verScrollPixels),
float64(1.0)*font.cellwidth,
float64(font.lineHeight)*0.5,
)
p.FillRect(
rect,
gui.NewQBrush3(
gui.NewQColor3(
vs.highlight.bg().R,
vs.highlight.bg().G,
vs.highlight.bg().B,
transparent,
),
pattern,
),
)

if pStr == "leftside" || pStr == "rightside" {
return
}

path := gui.NewQPainterPath()
path.AddRoundedRect(
core.NewQRectF4(
float64(b[0])*font.cellwidth+float64(horScrollPixels),
float64((y+b[1])*font.lineHeight+verScrollPixels),
float64(1)*font.cellwidth,
float64(font.lineHeight),
),
font.cellwidth/2.5,
font.cellwidth/2.5,
core.Qt__AbsoluteSize,
)
p.FillPath(
path,
gui.NewQBrush3(
gui.NewQColor3(
w.background.R,
w.background.G,
w.background.B,
transparent,
),
pattern,
),
)
}

func (w *Window) drawText(p *gui.QPainter, y int, col int, cols int) {
if y >= len(w.content) {
return
Expand Down

0 comments on commit e01c08c

Please sign in to comment.