aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--ui/manage_tunnels.go8
-rw-r--r--ui/tray.go4
-rw-r--r--ui/tunnelstatusimageprovider.go93
-rw-r--r--ui/tunnelsview.go1
4 files changed, 91 insertions, 15 deletions
diff --git a/ui/manage_tunnels.go b/ui/manage_tunnels.go
index f5e41fed..dbe719b9 100644
--- a/ui/manage_tunnels.go
+++ b/ui/manage_tunnels.go
@@ -177,7 +177,13 @@ func (mtw *ManageTunnelsWindow) SetTunnelTracker(tunnelTracker *TunnelTracker) {
func (mtw *ManageTunnelsWindow) SetTunnelState(tunnel *service.Tunnel, state service.TunnelState) {
mtw.tunnelsView.SetTunnelState(tunnel, state)
- // mtw.confView.SetTunnelState(tunnel, state)
+
+ icon, err := mtw.tunnelsView.imageProvider.IconWithOverlayForState(mtw.icon, state)
+ if err != nil {
+ return
+ }
+
+ mtw.SetIcon(icon)
}
func (mtw *ManageTunnelsWindow) updateConfView() {
diff --git a/ui/tray.go b/ui/tray.go
index c9091211..e15d2549 100644
--- a/ui/tray.go
+++ b/ui/tray.go
@@ -148,6 +148,10 @@ func (tray *Tray) SetTunnelState(tunnel *service.Tunnel, state service.TunnelSta
}
func (tray *Tray) SetTunnelStateWithNotification(tunnel *service.Tunnel, state service.TunnelState, showNotifications bool) {
+ if icon, err := tray.mtw.tunnelsView.imageProvider.IconWithOverlayForState(tray.icon, state); err == nil {
+ tray.SetIcon(icon)
+ }
+
tunnelAction := tray.tunnels[tunnel.Name]
actions := tray.ContextMenu().Actions()
diff --git a/ui/tunnelstatusimageprovider.go b/ui/tunnelstatusimageprovider.go
index f1ddcda1..99447526 100644
--- a/ui/tunnelstatusimageprovider.go
+++ b/ui/tunnelstatusimageprovider.go
@@ -15,18 +15,28 @@ type sizeAndState struct {
state service.TunnelState
}
+type iconAndState struct {
+ icon *walk.Icon
+ state service.TunnelState
+}
+
type TunnelStatusImageProvider struct {
- imagesBySizeAndState map[sizeAndState]*walk.Bitmap
- stoppedBrush *walk.SolidColorBrush
- startingBrush *walk.SolidColorBrush
- startedBrush *walk.SolidColorBrush
- stoppedPen *walk.CosmeticPen
- startingPen *walk.CosmeticPen
- startedPen *walk.CosmeticPen
+ imagesBySizeAndState map[sizeAndState]*walk.Bitmap
+ iconsByBaseIconAndState map[iconAndState]*walk.Icon
+ stoppedBrush *walk.SolidColorBrush
+ startingBrush *walk.SolidColorBrush
+ startedBrush *walk.SolidColorBrush
+ stoppedPen *walk.CosmeticPen
+ startingPen *walk.CosmeticPen
+ startedPen *walk.CosmeticPen
}
func NewTunnelStatusImageProvider() (*TunnelStatusImageProvider, error) {
- tsip := &TunnelStatusImageProvider{imagesBySizeAndState: make(map[sizeAndState]*walk.Bitmap)}
+ tsip := &TunnelStatusImageProvider{
+ imagesBySizeAndState: make(map[sizeAndState]*walk.Bitmap),
+ iconsByBaseIconAndState: make(map[iconAndState]*walk.Icon),
+ }
+
var err error
var disposables walk.Disposables
@@ -74,6 +84,12 @@ func (tsip *TunnelStatusImageProvider) Dispose() {
}
tsip.imagesBySizeAndState = nil
}
+ if tsip.iconsByBaseIconAndState != nil {
+ for _, icon := range tsip.iconsByBaseIconAndState {
+ icon.Dispose()
+ }
+ tsip.iconsByBaseIconAndState = nil
+ }
if tsip.stoppedBrush != nil {
tsip.stoppedBrush.Dispose()
tsip.stoppedBrush = nil
@@ -116,9 +132,6 @@ func (tsip *TunnelStatusImageProvider) ImageForState(state service.TunnelState,
return img, nil
}
- var disposables walk.Disposables
- defer disposables.Treat()
-
img, err := walk.NewBitmapWithTransparentPixels(size)
if err != nil {
return nil, err
@@ -136,11 +149,63 @@ func (tsip *TunnelStatusImageProvider) ImageForState(state service.TunnelState,
tsip.imagesBySizeAndState[key] = img
- disposables.Spare()
-
return img, nil
}
+func (tsip *TunnelStatusImageProvider) IconWithOverlayForTunnel(baseIcon *walk.Icon, tunnel *service.Tunnel) (*walk.Icon, error) {
+ state, err := tunnel.State()
+ if err != nil {
+ return nil, err
+ }
+
+ return tsip.IconWithOverlayForState(baseIcon, state)
+}
+
+func (tsip *TunnelStatusImageProvider) IconWithOverlayForState(baseIcon *walk.Icon, state service.TunnelState) (*walk.Icon, error) {
+ key := iconAndState{baseIcon, state}
+
+ if icon, ok := tsip.iconsByBaseIconAndState[key]; ok {
+ return icon, nil
+ }
+
+ size := baseIcon.Size()
+
+ bmp, err := walk.NewBitmapWithTransparentPixels(size)
+ if err != nil {
+ return nil, err
+ }
+ defer bmp.Dispose()
+
+ canvas, err := walk.NewCanvasFromImage(bmp)
+ if err != nil {
+ return nil, err
+ }
+ defer canvas.Dispose()
+
+ if err := canvas.DrawImage(baseIcon, walk.Point{}); err != nil {
+ return nil, err
+ }
+
+ w := int(float64(size.Width) * 0.75)
+ h := int(float64(size.Height) * 0.75)
+ bounds := walk.Rectangle{4 + size.Width - w, 4 + size.Height - h, w, h}
+
+ if err := tsip.PaintForState(state, canvas, bounds); err != nil {
+ return nil, err
+ }
+
+ canvas.Dispose()
+
+ icon, err := walk.NewIconFromBitmap(bmp)
+ if err != nil {
+ return nil, err
+ }
+
+ tsip.iconsByBaseIconAndState[key] = icon
+
+ return icon, nil
+}
+
func (tsip *TunnelStatusImageProvider) PaintForTunnel(tunnel *service.Tunnel, canvas *walk.Canvas, bounds walk.Rectangle) error {
state, err := tunnel.State()
if err != nil {
@@ -172,7 +237,7 @@ func (tsip *TunnelStatusImageProvider) PaintForState(state service.TunnelState,
b := bounds
- b.X = 4
+ b.X += 4
b.Y += 4
b.Height -= 8
b.Width = b.Height
diff --git a/ui/tunnelsview.go b/ui/tunnelsview.go
index 1e70c5bc..2f6ea2a4 100644
--- a/ui/tunnelsview.go
+++ b/ui/tunnelsview.go
@@ -103,6 +103,7 @@ func (tv *TunnelsView) StyleCell(style *walk.CellStyle) {
b.Width -= b.Height
canvas.DrawText(tunnel.Name, tv.Font(), 0, b, walk.TextVCenter)
+ b.X = 0
b.Width = b.Height
tv.imageProvider.PaintForTunnel(tunnel, canvas, b)