Fix issues with transparency (#301)
* Fix issues with transparency * Dispose of temporary alpha image
This commit is contained in:
parent
8d4ea4d7fe
commit
c18b702b61
|
@ -90,6 +90,7 @@ var rootCmd = &cobra.Command{
|
|||
gui.WithFontDPI(conf.Font.DPI),
|
||||
gui.WithFontSize(conf.Font.Size),
|
||||
gui.WithFontFamily(conf.Font.Family),
|
||||
gui.WithOpacity(conf.Opacity),
|
||||
}
|
||||
|
||||
if screenshotAfterMS > 0 {
|
||||
|
|
|
@ -73,7 +73,7 @@ func LoadThemeFromPath(conf *Config, path string) (*termutil.Theme, error) {
|
|||
|
||||
func loadThemeFromConf(conf *Config, themeConf *Theme) (*termutil.Theme, error) {
|
||||
|
||||
factory := termutil.NewThemeFactory().WithOpacity(conf.Opacity)
|
||||
factory := termutil.NewThemeFactory()
|
||||
|
||||
colours := map[termutil.Colour]string{
|
||||
termutil.ColourBlack: themeConf.Black,
|
||||
|
|
|
@ -14,6 +14,8 @@ import (
|
|||
// Draw renders the terminal GUI to the ebtien window. Required to implement the ebiten interface.
|
||||
func (g *GUI) Draw(screen *ebiten.Image) {
|
||||
|
||||
tmp := ebiten.NewImage(g.size.X, g.size.Y)
|
||||
|
||||
cellSize := g.fontManager.CharSize()
|
||||
dotDepth := g.fontManager.DotDepth()
|
||||
|
||||
|
@ -36,10 +38,10 @@ func (g *GUI) Draw(screen *ebiten.Image) {
|
|||
extraW := float64(g.size.X) - endX
|
||||
extraH := float64(g.size.Y) - endY
|
||||
if extraW > 0 {
|
||||
ebitenutil.DrawRect(screen, endX, 0, extraW, endY, defBg)
|
||||
ebitenutil.DrawRect(tmp, endX, 0, extraW, endY, defBg)
|
||||
}
|
||||
if extraH > 0 {
|
||||
ebitenutil.DrawRect(screen, 0, endY, float64(g.size.X), extraH, defBg)
|
||||
ebitenutil.DrawRect(tmp, 0, endY, float64(g.size.X), extraH, defBg)
|
||||
}
|
||||
|
||||
var inHighlight bool
|
||||
|
@ -52,7 +54,7 @@ func (g *GUI) Draw(screen *ebiten.Image) {
|
|||
for y := int(buffer.ViewHeight() - 1); y >= 0; y-- {
|
||||
py := cellSize.Y * y
|
||||
|
||||
ebitenutil.DrawRect(screen, 0, float64(py), float64(g.size.X), float64(cellSize.Y), defBg)
|
||||
ebitenutil.DrawRect(tmp, 0, float64(py), float64(g.size.X), float64(cellSize.Y), defBg)
|
||||
inHighlight = false
|
||||
for x := uint16(0); x < buffer.ViewWidth(); x++ {
|
||||
cell := buffer.GetCell(x, uint16(y))
|
||||
|
@ -74,7 +76,7 @@ func (g *GUI) Draw(screen *ebiten.Image) {
|
|||
colour = defBg
|
||||
}
|
||||
|
||||
ebitenutil.DrawRect(screen, float64(px), float64(py), float64(cellSize.X), float64(cellSize.Y), colour)
|
||||
ebitenutil.DrawRect(tmp, float64(px), float64(py), float64(cellSize.X), float64(cellSize.Y), colour)
|
||||
|
||||
if buffer.IsHighlighted(termutil.Position{
|
||||
Line: uint64(y),
|
||||
|
@ -106,7 +108,7 @@ func (g *GUI) Draw(screen *ebiten.Image) {
|
|||
}
|
||||
|
||||
if isCursor && !ebiten.IsFocused() {
|
||||
ebitenutil.DrawRect(screen, float64(px)+1, float64(py)+1, float64(cellSize.X)-2, float64(cellSize.Y)-2, g.terminal.Theme().DefaultBackground())
|
||||
ebitenutil.DrawRect(tmp, float64(px)+1, float64(py)+1, float64(cellSize.X)-2, float64(cellSize.Y)-2, g.terminal.Theme().DefaultBackground())
|
||||
}
|
||||
}
|
||||
for x := uint16(0); x < buffer.ViewWidth(); x++ {
|
||||
|
@ -139,13 +141,13 @@ func (g *GUI) Draw(screen *ebiten.Image) {
|
|||
|
||||
if cell.Underline() {
|
||||
uly := float64(py + (dotDepth+cellSize.Y)/2)
|
||||
ebitenutil.DrawLine(screen, float64(px), uly, float64(px+cellSize.X), uly, colour)
|
||||
ebitenutil.DrawLine(tmp, float64(px), uly, float64(px+cellSize.X), uly, colour)
|
||||
}
|
||||
|
||||
text.Draw(screen, string(cell.Rune().Rune), useFace, px, py+dotDepth, colour)
|
||||
text.Draw(tmp, string(cell.Rune().Rune), useFace, px, py+dotDepth, colour)
|
||||
|
||||
if cell.Strikethrough() {
|
||||
ebitenutil.DrawLine(screen, float64(px), float64(py+(cellSize.Y/2)), float64(px+cellSize.X), float64(py+(cellSize.Y/2)), colour)
|
||||
ebitenutil.DrawLine(tmp, float64(px), float64(py+(cellSize.Y/2)), float64(px+cellSize.X), float64(py+(cellSize.Y/2)), colour)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -157,7 +159,7 @@ func (g *GUI) Draw(screen *ebiten.Image) {
|
|||
|
||||
op := &ebiten.DrawImageOptions{}
|
||||
op.GeoM.Translate(sx, sy)
|
||||
screen.DrawImage(
|
||||
tmp.DrawImage(
|
||||
ebiten.NewImageFromImage(sixel.Sixel.Image),
|
||||
op,
|
||||
)
|
||||
|
@ -237,19 +239,19 @@ func (g *GUI) Draw(screen *ebiten.Image) {
|
|||
}
|
||||
|
||||
// draw opaque box below and above highlighted line(s)
|
||||
ebitenutil.DrawRect(screen, 0, float64(highlightMin.Line*uint64(cellSize.Y)), float64(cellSize.X*int(highlightMin.Col)), float64(cellSize.Y), color.RGBA{A: 0x80})
|
||||
ebitenutil.DrawRect(screen, float64((cellSize.X)*int(highlightMax.Col+1)), float64(highlightMax.Line*uint64(cellSize.Y)), float64(g.size.X), float64(cellSize.Y), color.RGBA{A: 0x80})
|
||||
ebitenutil.DrawRect(screen, 0, 0, float64(g.size.X), float64(highlightMin.Line*uint64(cellSize.Y)), color.RGBA{A: 0x80})
|
||||
ebitenutil.DrawRect(tmp, 0, float64(highlightMin.Line*uint64(cellSize.Y)), float64(cellSize.X*int(highlightMin.Col)), float64(cellSize.Y), color.RGBA{A: 0x80})
|
||||
ebitenutil.DrawRect(tmp, float64((cellSize.X)*int(highlightMax.Col+1)), float64(highlightMax.Line*uint64(cellSize.Y)), float64(g.size.X), float64(cellSize.Y), color.RGBA{A: 0x80})
|
||||
ebitenutil.DrawRect(tmp, 0, 0, float64(g.size.X), float64(highlightMin.Line*uint64(cellSize.Y)), color.RGBA{A: 0x80})
|
||||
afterLineY := float64((1 + highlightMax.Line) * uint64(cellSize.Y))
|
||||
ebitenutil.DrawRect(screen, 0, afterLineY, float64(g.size.X), float64(g.size.Y)-afterLineY, color.RGBA{A: 0x80})
|
||||
ebitenutil.DrawRect(tmp, 0, afterLineY, float64(g.size.X), float64(g.size.Y)-afterLineY, color.RGBA{A: 0x80})
|
||||
|
||||
// annotation border
|
||||
ebitenutil.DrawRect(screen, float64(annotationX)-padding, annotationY-padding, float64(annotationWidth)+(padding*2), annotationHeight+(padding*2), g.terminal.Theme().SelectionBackground())
|
||||
ebitenutil.DrawRect(tmp, float64(annotationX)-padding, annotationY-padding, float64(annotationWidth)+(padding*2), annotationHeight+(padding*2), g.terminal.Theme().SelectionBackground())
|
||||
// annotation background
|
||||
ebitenutil.DrawRect(screen, 1+float64(annotationX)-padding, 1+annotationY-padding, float64(annotationWidth)+(padding*2)-2, annotationHeight+(padding*2)-2, g.terminal.Theme().DefaultBackground())
|
||||
ebitenutil.DrawRect(tmp, 1+float64(annotationX)-padding, 1+annotationY-padding, float64(annotationWidth)+(padding*2)-2, annotationHeight+(padding*2)-2, g.terminal.Theme().DefaultBackground())
|
||||
|
||||
// vertical line
|
||||
ebitenutil.DrawLine(screen, lineX, float64(lineY), lineX, lineY+lineHeight, g.terminal.Theme().SelectionBackground())
|
||||
ebitenutil.DrawLine(tmp, lineX, float64(lineY), lineX, lineY+lineHeight, g.terminal.Theme().SelectionBackground())
|
||||
|
||||
var tY int
|
||||
var tX int
|
||||
|
@ -259,7 +261,7 @@ func (g *GUI) Draw(screen *ebiten.Image) {
|
|||
|
||||
op := &ebiten.DrawImageOptions{}
|
||||
op.GeoM.Translate(float64(annotationX), annotationY)
|
||||
screen.DrawImage(
|
||||
tmp.DrawImage(
|
||||
ebiten.NewImageFromImage(annotation.Image),
|
||||
op,
|
||||
)
|
||||
|
@ -271,7 +273,7 @@ func (g *GUI) Draw(screen *ebiten.Image) {
|
|||
tX = 0
|
||||
continue
|
||||
}
|
||||
text.Draw(screen, string(r), regularFace, annotationX+tX, int(annotationY)+dotDepth+tY, g.terminal.Theme().DefaultForeground())
|
||||
text.Draw(tmp, string(r), regularFace, annotationX+tX, int(annotationY)+dotDepth+tY, g.terminal.Theme().DefaultForeground())
|
||||
tX += cellSize.X
|
||||
}
|
||||
|
||||
|
@ -298,11 +300,11 @@ func (g *GUI) Draw(screen *ebiten.Image) {
|
|||
boxWidth = endX / 8
|
||||
}
|
||||
|
||||
ebitenutil.DrawRect(screen, float64(msgX-1), msgY-1, boxWidth+2, boxHeight+2, msg.Foreground)
|
||||
ebitenutil.DrawRect(screen, float64(msgX), msgY, boxWidth, boxHeight, msg.Background)
|
||||
ebitenutil.DrawRect(tmp, float64(msgX-1), msgY-1, boxWidth+2, boxHeight+2, msg.Foreground)
|
||||
ebitenutil.DrawRect(tmp, float64(msgX), msgY, boxWidth, boxHeight, msg.Background)
|
||||
for y, line := range lines {
|
||||
for x, r := range line {
|
||||
text.Draw(screen, string(r), regularFace, msgX+pad+(x*cellSize.X), pad+(y*cellSize.Y)+int(msgY)+dotDepth, msg.Foreground)
|
||||
text.Draw(tmp, string(r), regularFace, msgX+pad+(x*cellSize.X), pad+(y*cellSize.Y)+int(msgY)+dotDepth, msg.Foreground)
|
||||
}
|
||||
}
|
||||
msgEndY = msgEndY - float64(pad*4) - float64(len(lines)*g.CellSize().Y)
|
||||
|
@ -310,7 +312,11 @@ func (g *GUI) Draw(screen *ebiten.Image) {
|
|||
}
|
||||
|
||||
if g.screenshotRequested {
|
||||
g.takeScreenshot(screen)
|
||||
g.takeScreenshot(tmp)
|
||||
}
|
||||
|
||||
opt := &ebiten.DrawImageOptions{}
|
||||
opt.ColorM.Scale(1, 1, 1, g.opacity)
|
||||
screen.DrawImage(tmp, opt)
|
||||
tmp.Dispose()
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ type GUI struct {
|
|||
screenshotFilename string
|
||||
startupFuncs []func(g *GUI)
|
||||
keyState *keyState
|
||||
opacity float64
|
||||
}
|
||||
|
||||
type PopupMessage struct {
|
||||
|
@ -88,6 +89,7 @@ func (g *GUI) Run() error {
|
|||
}()
|
||||
|
||||
ebiten.SetScreenTransparent(true)
|
||||
ebiten.SetScreenClearedEveryFrame(true)
|
||||
ebiten.SetWindowResizable(true)
|
||||
ebiten.SetRunnableOnUnfocused(true)
|
||||
ebiten.SetFPSMode(ebiten.FPSModeVsyncOffMinimum)
|
||||
|
|
|
@ -8,6 +8,13 @@ func WithFontFamily(family string) func(g *GUI) error {
|
|||
}
|
||||
}
|
||||
|
||||
func WithOpacity(opacity float64) func(g *GUI) error {
|
||||
return func(g *GUI) error {
|
||||
g.opacity = opacity
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func WithFontSize(size float64) func(g *GUI) error {
|
||||
return func(g *GUI) error {
|
||||
g.fontManager.SetSize(size)
|
||||
|
|
|
@ -35,7 +35,6 @@ const (
|
|||
)
|
||||
|
||||
type Theme struct {
|
||||
alpha uint8
|
||||
colourMap map[Colour]color.Color
|
||||
}
|
||||
|
||||
|
@ -87,7 +86,7 @@ func (t *Theme) ColourFrom4Bit(code uint8) color.Color {
|
|||
func (t *Theme) DefaultBackground() color.Color {
|
||||
c, ok := t.colourMap[ColourBackground]
|
||||
if !ok {
|
||||
return color.RGBA{0, 0, 0, t.alpha}
|
||||
return color.RGBA{0, 0, 0, 0xff}
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
@ -95,7 +94,7 @@ func (t *Theme) DefaultBackground() color.Color {
|
|||
func (t *Theme) DefaultForeground() color.Color {
|
||||
c, ok := t.colourMap[ColourForeground]
|
||||
if !ok {
|
||||
return color.RGBA{255, 255, 255, t.alpha}
|
||||
return color.RGBA{255, 255, 255, 0xff}
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
@ -103,7 +102,7 @@ func (t *Theme) DefaultForeground() color.Color {
|
|||
func (t *Theme) SelectionBackground() color.Color {
|
||||
c, ok := t.colourMap[ColourSelectionBackground]
|
||||
if !ok {
|
||||
return color.RGBA{0, 0, 0, t.alpha}
|
||||
return color.RGBA{0, 0, 0, 0xff}
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
@ -111,7 +110,7 @@ func (t *Theme) SelectionBackground() color.Color {
|
|||
func (t *Theme) SelectionForeground() color.Color {
|
||||
c, ok := t.colourMap[ColourSelectionForeground]
|
||||
if !ok {
|
||||
return color.RGBA{255, 255, 255, t.alpha}
|
||||
return color.RGBA{255, 255, 255, 0xff}
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
@ -119,7 +118,7 @@ func (t *Theme) SelectionForeground() color.Color {
|
|||
func (t *Theme) CursorBackground() color.Color {
|
||||
c, ok := t.colourMap[ColourCursorBackground]
|
||||
if !ok {
|
||||
return color.RGBA{255, 255, 255, t.alpha}
|
||||
return color.RGBA{255, 255, 255, 0xff}
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
@ -127,7 +126,7 @@ func (t *Theme) CursorBackground() color.Color {
|
|||
func (t *Theme) CursorForeground() color.Color {
|
||||
c, ok := t.colourMap[ColourCursorForeground]
|
||||
if !ok {
|
||||
return color.RGBA{0, 0, 0, t.alpha}
|
||||
return color.RGBA{0, 0, 0, 0xff}
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
@ -149,12 +148,12 @@ func (t *Theme) ColourFrom8Bit(n string) (color.Color, error) {
|
|||
R: byte(c),
|
||||
G: byte(c),
|
||||
B: byte(c),
|
||||
A: t.alpha,
|
||||
A: 0xff,
|
||||
}, nil
|
||||
}
|
||||
|
||||
var colour color.RGBA
|
||||
colour.A = t.alpha
|
||||
colour.A = 0xff
|
||||
indexR := ((index - 16) / 36)
|
||||
if indexR > 0 {
|
||||
colour.R = uint8(55 + indexR*40)
|
||||
|
@ -188,7 +187,7 @@ func (t *Theme) ColourFrom24Bit(r, g, b string) (color.Color, error) {
|
|||
R: byte(ri),
|
||||
G: byte(gi),
|
||||
B: byte(bi),
|
||||
A: t.alpha,
|
||||
A: 0xff,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@ type ThemeFactory struct {
|
|||
func NewThemeFactory() *ThemeFactory {
|
||||
return &ThemeFactory{
|
||||
theme: &Theme{
|
||||
alpha: 0xff,
|
||||
colourMap: map[Colour]color.Color{},
|
||||
},
|
||||
colourMap: make(map[Colour]color.Color),
|
||||
|
@ -24,17 +23,12 @@ func (t *ThemeFactory) Build() *Theme {
|
|||
R: uint8(r / 0xff),
|
||||
G: uint8(g / 0xff),
|
||||
B: uint8(b / 0xff),
|
||||
A: t.theme.alpha,
|
||||
A: 0xff,
|
||||
}
|
||||
}
|
||||
return t.theme
|
||||
}
|
||||
|
||||
func (t *ThemeFactory) WithOpacity(opacity float64) *ThemeFactory {
|
||||
t.theme.alpha = uint8(0xff * opacity)
|
||||
return t
|
||||
}
|
||||
|
||||
func (t *ThemeFactory) WithColour(key Colour, colour color.Color) *ThemeFactory {
|
||||
t.colourMap[key] = colour
|
||||
return t
|
||||
|
|
Loading…
Reference in New Issue