diff --git a/editor/config.go b/editor/config.go index 75d618eb..729db163 100644 --- a/editor/config.go +++ b/editor/config.go @@ -85,6 +85,7 @@ type editorConfig struct { HideTitlebar bool HideMouseWhenTyping bool IgnoreSaveConfirmationWithCloseButton bool + RoundedSelection bool } type cursorConfig struct { diff --git a/editor/window.go b/editor/window.go index 37b8e164..cb2b96a2 100644 --- a/editor/window.go +++ b/editor/window.go @@ -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 @@ -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) } @@ -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 { @@ -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 { @@ -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] @@ -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++ { @@ -1865,7 +1887,19 @@ 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 @@ -1873,14 +1907,29 @@ func (w *Window) drawBackground(p *gui.QPainter, y int, col int, cols int) { 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 @@ -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, @@ -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