From 32fa31aeac72c20732b4af5de87d9c1526c94b7c Mon Sep 17 00:00:00 2001 From: Alexander Neumann Date: Thu, 28 Nov 2019 15:47:48 +0100 Subject: ui: make confview status image look the same as in listview Signed-off-by: Alexander Neumann --- ui/confview.go | 60 +++++++++++++++++++++++++++++++++++++++++++++++------- ui/iconprovider.go | 39 +++++++++++++++++++++++++++++++++++ ui/listview.go | 36 ++++++++------------------------ 3 files changed, 100 insertions(+), 35 deletions(-) (limited to 'ui') diff --git a/ui/confview.go b/ui/confview.go index 1c378aa1..f45b2689 100644 --- a/ui/confview.go +++ b/ui/confview.go @@ -79,17 +79,63 @@ func (lsl *labelStatusLine) widgets() (walk.Widget, walk.Widget) { return lsl.label, lsl.statusComposite } -func (lsl *labelStatusLine) update(state manager.TunnelState) { - icon, err := iconForState(state, 14) - if err == nil { - lsl.statusImage.SetImage(icon) - } else { - lsl.statusImage.SetImage(nil) - } +var cachedStatusBitmapsForWidthAndState = make(map[widthAndState]*walk.Bitmap) +func (lsl *labelStatusLine) update(state manager.TunnelState) { s, e := lsl.statusLabel.TextSelection() lsl.statusLabel.SetText(textForState(state, false)) lsl.statusLabel.SetTextSelection(s, e) + + const size96dpi = 14 + + image := walk.NewPaintFuncImagePixels(walk.Size{size96dpi, size96dpi}, func(canvas *walk.Canvas, bounds walk.Rectangle) error { + dpi := lsl.statusImage.DPI() + size := walk.IntFrom96DPI(size96dpi, dpi) + + var bmp *walk.Bitmap + cacheKey := widthAndState{size, state} + + var ok bool + if bmp, ok = cachedStatusBitmapsForWidthAndState[cacheKey]; !ok { + bitmap, err := bitmapForState(state, size, 0, dpi) + if err != nil { + return err + } + + iml, err := walk.NewImageListForDPI(walk.Size{size, size}, 0, dpi) + if err != nil { + return err + } + defer iml.Dispose() + + index, err := iml.AddMasked(bitmap) + if err != nil { + return err + } + + if bmp, err = walk.NewBitmapWithTransparentPixelsForDPI(walk.Size{size, size}, dpi); err != nil { + return err + } + + canvas, err := walk.NewCanvasFromImage(bmp) + if err != nil { + return err + } + defer canvas.Dispose() + + if err := iml.DrawPixels(canvas, int(index), walk.Rectangle{0, 0, size, size}); err != nil { + return err + } + + canvas.Dispose() + + cachedStatusBitmapsForWidthAndState[cacheKey] = bmp + } + + return canvas.DrawImagePixels(bmp, bounds.Location()) + }) + + lsl.statusImage.SetImage(image) } func (lsl *labelStatusLine) Dispose() { diff --git a/ui/iconprovider.go b/ui/iconprovider.go index e5177ac3..c4daa61e 100644 --- a/ui/iconprovider.go +++ b/ui/iconprovider.go @@ -84,6 +84,45 @@ func iconForState(state manager.TunnelState, size int) (icon *walk.Icon, err err return } +var cachedBitmapsForWidthAndState = make(map[widthAndState]*walk.Bitmap) + +func bitmapForState(state manager.TunnelState, iconSize, margin, dpi int) (bitmap *walk.Bitmap, err error) { + icon, err := iconForState(state, iconSize) + if err != nil { + return + } + + bitmapSize := walk.IntFrom96DPI(iconSize+margin*2, dpi) + + cacheKey := widthAndState{bitmapSize, state} + if cacheValue, ok := cachedBitmapsForWidthAndState[cacheKey]; ok { + bitmap = cacheValue + return + } + + bitmap, err = walk.NewBitmapWithTransparentPixelsForDPI(walk.Size{bitmapSize, bitmapSize}, dpi) + if err != nil { + return + } + + var canvas *walk.Canvas + canvas, err = walk.NewCanvasFromImage(bitmap) + if err != nil { + return + } + + bounds := walk.Rectangle{X: margin, Y: margin, Height: iconSize, Width: iconSize} + err = canvas.DrawImageStretchedPixels(icon, bounds) + canvas.Dispose() + if err != nil { + return + } + + cachedBitmapsForWidthAndState[cacheKey] = bitmap + + return +} + func textForState(state manager.TunnelState, withEllipsis bool) (text string) { switch state { case manager.TunnelStarted: diff --git a/ui/listview.go b/ui/listview.go index e9ecb2f8..af970814 100644 --- a/ui/listview.go +++ b/ui/listview.go @@ -26,8 +26,6 @@ type ListModel struct { lastObservedState map[manager.Tunnel]manager.TunnelState } -var cachedListViewIconsForWidthAndState = make(map[widthAndState]*walk.Bitmap) - func (t *ListModel) RowCount() int { return len(t.tunnels) } @@ -134,38 +132,16 @@ func (tv *ListView) StyleCell(style *walk.CellStyle) { tv.model.lastObservedState[tv.model.tunnels[row]] = state } - icon, err := iconForState(state, 14) - if err != nil { - return - } margin := tv.IntFrom96DPI(1) - bitmapWidth := tv.IntFrom96DPI(16) + bitmapWidth := tv.IntFrom96DPI(14) + 2*margin if win.IsAppThemed() { - cacheKey := widthAndState{bitmapWidth, state} - if cacheValue, ok := cachedListViewIconsForWidthAndState[cacheKey]; ok { - style.Image = cacheValue - return + if bitmap, err := bitmapForState(state, bitmapWidth-2*margin, 1, tv.DPI()); err == nil { + style.Image = bitmap } - bitmap, err := walk.NewBitmapWithTransparentPixelsForDPI(walk.Size{bitmapWidth, bitmapWidth}, tv.DPI()) - if err != nil { - return - } - canvas, err := walk.NewCanvasFromImage(bitmap) - if err != nil { - return - } - bounds := walk.Rectangle{X: margin, Y: margin, Height: bitmapWidth - 2*margin, Width: bitmapWidth - 2*margin} - err = canvas.DrawImageStretchedPixels(icon, bounds) - canvas.Dispose() - if err != nil { - return - } - cachedListViewIconsForWidthAndState[cacheKey] = bitmap - style.Image = bitmap } else { if dummyBitmap == nil { - dummyBitmap, _ = walk.NewBitmapForDPI(tv.SizeFrom96DPI(walk.Size{}), 96) + dummyBitmap, _ = walk.NewBitmapForDPI(walk.Size{}, 96) } style.Image = dummyBitmap canvas := style.Canvas() @@ -177,6 +153,10 @@ func (tv *ListView) StyleCell(style *walk.CellStyle) { bounds.X = (bounds.Height - bounds.Width) / 2 bounds.Height = bounds.Width bounds.Y += bounds.X + icon, err := iconForState(state, 14) + if err != nil { + return + } canvas.DrawImageStretchedPixels(icon, bounds) } } -- cgit v1.2.3-59-g8ed1b