aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2019-05-02 11:27:18 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2019-05-02 11:51:22 +0200
commitf460a4449efc34d5fc3cb1251b7726ac6536dd25 (patch)
treeee7593edf355714420ccf231a7afc0732977ec18
parentbuild: remove stray debugging echo (diff)
downloadwireguard-windows-f460a4449efc34d5fc3cb1251b7726ac6536dd25.tar.xz
wireguard-windows-f460a4449efc34d5fc3cb1251b7726ac6536dd25.zip
ui: render dots with svgs instead
-rw-r--r--Makefile2
-rw-r--r--resources.rc4
-rw-r--r--ui/icon/dot-gray.svg2
-rw-r--r--ui/icon/dot-green.svg2
-rw-r--r--ui/icon/dot-red.svg2
-rw-r--r--ui/icon/dot-yellow.svg2
-rw-r--r--ui/iconprovider.go204
-rw-r--r--ui/tray.go4
-rw-r--r--ui/updatepage.go5
9 files changed, 45 insertions, 182 deletions
diff --git a/Makefile b/Makefile
index 76c4c6d3..49601019 100644
--- a/Makefile
+++ b/Makefile
@@ -46,6 +46,6 @@ deploy: amd64/wireguard.exe
scp $< $(DEPLOYMENT_HOST):$(DEPLOYMENT_PATH)
clean:
- rm -rf *.syso x86/ amd64/ .deps
+ rm -rf *.syso ui/icon/*.ico x86/ amd64/ .deps
.PHONY: deploy clean all
diff --git a/resources.rc b/resources.rc
index 89e90bc6..f1b29f35 100644
--- a/resources.rc
+++ b/resources.rc
@@ -12,6 +12,10 @@ $wireguard.ico ICON ui/icon/wireguard.ico
add.ico ICON ui/icon/add.ico
delete.ico ICON ui/icon/delete.ico
export.ico ICON ui/icon/export.ico
+dot-gray.ico ICON ui/icon/dot-gray.ico
+dot-yellow.ico ICON ui/icon/dot-yellow.ico
+dot-green.ico ICON ui/icon/dot-green.ico
+dot-red.ico ICON ui/icon/dot-red.ico
VS_VERSION_INFO VERSIONINFO
FILEVERSION WIREGUARD_WINDOWS_VERSION_ARRAY
diff --git a/ui/icon/dot-gray.svg b/ui/icon/dot-gray.svg
new file mode 100644
index 00000000..db9a6468
--- /dev/null
+++ b/ui/icon/dot-gray.svg
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="32" height="32" version="1.1" viewBox="0 0 8.4667 8.4667" xmlns="http://www.w3.org/2000/svg"><g transform="translate(-11.837 -277.77)"><circle cx="16.07" cy="282" r="3.9688" fill="#e1e1e1" stroke="#cacaca" stroke-linecap="square" stroke-width=".5292"/></g></svg>
diff --git a/ui/icon/dot-green.svg b/ui/icon/dot-green.svg
new file mode 100644
index 00000000..5bec700e
--- /dev/null
+++ b/ui/icon/dot-green.svg
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="32" height="32" version="1.1" viewBox="0 0 8.4667 8.4667" xmlns="http://www.w3.org/2000/svg"><g transform="translate(-11.837 -277.77)"><circle cx="16.07" cy="282" r="3.9688" fill="#01a405" stroke="#019104" stroke-linecap="square" stroke-width=".5292"/></g></svg>
diff --git a/ui/icon/dot-red.svg b/ui/icon/dot-red.svg
new file mode 100644
index 00000000..10efd510
--- /dev/null
+++ b/ui/icon/dot-red.svg
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="32" height="32" version="1.1" viewBox="0 0 8.4667 8.4667" xmlns="http://www.w3.org/2000/svg"><g transform="translate(-11.837 -277.77)"><circle cx="16.07" cy="282" r="3.9688" fill="#cb0110" stroke="#b5010e" stroke-linecap="square" stroke-width=".5292"/></g></svg>
diff --git a/ui/icon/dot-yellow.svg b/ui/icon/dot-yellow.svg
new file mode 100644
index 00000000..e30b6a16
--- /dev/null
+++ b/ui/icon/dot-yellow.svg
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="32" height="32" version="1.1" viewBox="0 0 8.4667 8.4667" xmlns="http://www.w3.org/2000/svg"><g transform="translate(-11.837 -277.77)"><circle cx="16.07" cy="282" r="3.9688" fill="#fec440" stroke="#feba20" stroke-linecap="square" stroke-width=".5292"/></g></svg>
diff --git a/ui/iconprovider.go b/ui/iconprovider.go
index 64d5775d..5ebf93bb 100644
--- a/ui/iconprovider.go
+++ b/ui/iconprovider.go
@@ -8,7 +8,6 @@ package ui
import (
"github.com/lxn/walk"
"golang.zx2c4.com/wireguard/windows/service"
- "math"
)
type rectAndState struct {
@@ -20,95 +19,10 @@ type IconProvider struct {
wireguardIcon *walk.Icon
imagesByRectAndState map[rectAndState]*walk.Bitmap
iconsByState map[service.TunnelState]*walk.Icon
- stoppedBrush *walk.SolidColorBrush
- startingBrush *walk.SolidColorBrush
- startedBrush *walk.SolidColorBrush
- stoppedPen *walk.CosmeticPen
- startingPen *walk.CosmeticPen
- startedPen *walk.CosmeticPen
- updateAvailableImage *walk.Bitmap
+ updateAvailabeImage *walk.Bitmap
scale float64
}
-const (
- colorStopped = 0xe1e1e1
- colorStarting = 0xfec440
- colorStarted = 0x01a405
- colorUpdateAvailable = 0xcb0110
-)
-
-func hexColor(c uint32) walk.Color {
- return walk.Color((((c >> 16) & 0xff) << 0) | (((c >> 8) & 0xff) << 8) | (((c >> 0) & 0xff) << 16))
-}
-
-func darkColor(c walk.Color) walk.Color {
- // Convert to HSL
- r, g, b := float64((uint32(c)>>16)&0xff)/255.0, float64((uint32(c)>>8)&0xff)/255.0, float64((uint32(c)>>0)&0xff)/255.0
- min := math.Min(r, math.Min(g, b))
- max := math.Max(r, math.Max(g, b))
- deltaMinMax := max - min
- l := (max + min) / 2
- h, s := 0.0, 0.0
- if deltaMinMax != 0 {
- if l < 0.5 {
- s = deltaMinMax / (max + min)
- } else {
- s = deltaMinMax / (2 - max - min)
- }
- deltaRed := (((max - r) / 6) + (deltaMinMax / 2)) / deltaMinMax
- deltaGreen := (((max - g) / 6) + (deltaMinMax / 2)) / deltaMinMax
- deltaBlue := (((max - b) / 6) + (deltaMinMax / 2)) / deltaMinMax
- if r == max {
- h = deltaBlue - deltaGreen
- } else if g == max {
- h = (1.0 / 3.0) + deltaRed - deltaBlue
- } else if b == max {
- h = (2.0 / 3.0) + deltaGreen - deltaRed
- }
-
- if h < 0 {
- h += 1
- } else if h > 1 {
- h -= 1
- }
- }
-
- // Darken by 10%
- l = math.Max(0, l-0.1)
-
- // Convert back to RGB
- if s == 0 {
- return walk.Color((uint32(l*255) << 16) | (uint32(l*255) << 8) | (uint32(l*255) << 0))
- }
- var v1, v2 float64
- if l < 0.5 {
- v2 = l * (1 + s)
- } else {
- v2 = (l + s) - (s * l)
- }
- v1 = 2.0*l - v2
- co := func(v1, v2, vH float64) float64 {
- if vH < 0 {
- vH += 1
- }
- if vH > 1 {
- vH -= 1
- }
- if (6.0 * vH) < 1 {
- return v1 + (v2-v1)*6.0*vH
- }
- if (2.0 * vH) < 1 {
- return v2
- }
- if (3.0 * vH) < 2 {
- return v1 + (v2-v1)*((2.0/3.0)-vH)*6.0
- }
- return v1
- }
- r, g, b = co(v1, v2, h+(1.0/3.0)), co(v1, v2, h), co(v1, v2, h-(1.0/3.0))
- return walk.Color((uint32(r*255) << 16) | (uint32(g*255) << 8) | (uint32(b*255) << 0))
-}
-
func NewIconProvider(dpi int) (*IconProvider, error) {
tsip := &IconProvider{
imagesByRectAndState: make(map[rectAndState]*walk.Bitmap),
@@ -126,41 +40,6 @@ func NewIconProvider(dpi int) (*IconProvider, error) {
}
disposables.Add(tsip.wireguardIcon)
- if tsip.stoppedBrush, err = walk.NewSolidColorBrush(hexColor(colorStopped)); err != nil {
- return nil, err
- }
- disposables.Add(tsip.stoppedBrush)
-
- if tsip.startingBrush, err = walk.NewSolidColorBrush(hexColor(colorStarting)); err != nil {
- return nil, err
- }
- disposables.Add(tsip.startingBrush)
-
- if tsip.startedBrush, err = walk.NewSolidColorBrush(hexColor(colorStarted)); err != nil {
- return nil, err
- }
- disposables.Add(tsip.startedBrush)
-
- if tsip.stoppedPen, err = walk.NewCosmeticPen(walk.PenSolid, darkColor(hexColor(colorStopped))); err != nil {
- return nil, err
- }
- disposables.Add(tsip.stoppedPen)
-
- if tsip.startingPen, err = walk.NewCosmeticPen(walk.PenSolid, darkColor(hexColor(colorStarting))); err != nil {
- return nil, err
- }
- disposables.Add(tsip.startingPen)
-
- if tsip.startedPen, err = walk.NewCosmeticPen(walk.PenSolid, darkColor(hexColor(colorStarted))); err != nil {
- return nil, err
- }
- disposables.Add(tsip.startedPen)
-
- if tsip.updateAvailableImage, err = tsip.drawUpdateAvailableImage(16 /* This should be scaled for DPI, but isn't because of walk bug. */); err != nil {
- return nil, err
- }
- disposables.Add(tsip.updateAvailableImage)
-
disposables.Spare()
return tsip, nil
}
@@ -178,37 +57,13 @@ func (tsip *IconProvider) Dispose() {
}
tsip.iconsByState = nil
}
- if tsip.stoppedBrush != nil {
- tsip.stoppedBrush.Dispose()
- tsip.stoppedBrush = nil
- }
- if tsip.startingBrush != nil {
- tsip.startingBrush.Dispose()
- tsip.startingBrush = nil
- }
- if tsip.startedBrush != nil {
- tsip.startedBrush.Dispose()
- tsip.startedBrush = nil
- }
- if tsip.stoppedPen != nil {
- tsip.stoppedPen.Dispose()
- tsip.stoppedPen = nil
- }
- if tsip.startingPen != nil {
- tsip.startingPen.Dispose()
- tsip.startingPen = nil
- }
- if tsip.startedPen != nil {
- tsip.startedPen.Dispose()
- tsip.startedPen = nil
- }
if tsip.wireguardIcon != nil {
tsip.wireguardIcon.Dispose()
tsip.wireguardIcon = nil
}
- if tsip.updateAvailableImage != nil {
- tsip.updateAvailableImage.Dispose()
- tsip.updateAvailableImage = nil
+ if tsip.updateAvailabeImage != nil {
+ tsip.updateAvailabeImage.Dispose()
+ tsip.updateAvailabeImage = nil
}
}
@@ -216,23 +71,21 @@ func (tsip *IconProvider) scaleForDPI(i int) int {
return int(tsip.scale * float64(i))
}
-func (tsip *IconProvider) drawUpdateAvailableImage(size int) (*walk.Bitmap, error) {
- updateAvailableBrush, err := walk.NewSolidColorBrush(hexColor(colorUpdateAvailable))
- if err != nil {
- return nil, err
+func (tsip *IconProvider) UpdateAvailableImage() (*walk.Bitmap, error) {
+ if tsip.updateAvailabeImage != nil {
+ return tsip.updateAvailabeImage, nil
}
- defer updateAvailableBrush.Dispose()
- updateAvailablePen, err := walk.NewCosmeticPen(walk.PenSolid, darkColor(hexColor(colorUpdateAvailable)))
+
+ const size = 16 //TODO: this should use dynamic DPI, but we don't due to a walk bug with tab icons.
+ redDot, err := walk.NewIconFromResourceWithSize("dot-red.ico", walk.Size{size, size})
if err != nil {
return nil, err
}
- defer updateAvailablePen.Dispose()
-
+ defer redDot.Dispose()
img, err := walk.NewBitmapWithTransparentPixels(walk.Size{size, size})
if err != nil {
return nil, err
}
-
canvas, err := walk.NewCanvasFromImage(img)
if err != nil {
img.Dispose()
@@ -240,21 +93,18 @@ func (tsip *IconProvider) drawUpdateAvailableImage(size int) (*walk.Bitmap, erro
}
defer canvas.Dispose()
- // This should be scaled for DPI but instead we do the opposite, due to a walk bug.
+ // This should be scaled for DPI but instead we do the opposite, due to a walk bug with tab icons.
margin := int(3.0 - (tsip.scale-1.0)*3.0)
if margin < 0 {
margin = 0
}
rect := walk.Rectangle{margin, margin, size - margin*2, size - margin*2}
- if err := canvas.FillEllipse(updateAvailableBrush, rect); err != nil {
- img.Dispose()
- return nil, err
- }
- if err := canvas.DrawEllipse(updateAvailablePen, rect); err != nil {
+ if err := canvas.DrawImageStretched(redDot, rect); err != nil {
img.Dispose()
return nil, err
}
+ tsip.updateAvailabeImage = img
return img, nil
}
@@ -348,36 +198,32 @@ func (tsip *IconProvider) PaintForTunnel(tunnel *service.Tunnel, canvas *walk.Ca
}
func (tsip *IconProvider) PaintForState(state service.TunnelState, canvas *walk.Canvas, bounds walk.Rectangle) error {
- var (
- brush *walk.SolidColorBrush
- pen *walk.CosmeticPen
- )
+ iconSize := tsip.scaleForDPI(bounds.Height)
+ var dot *walk.Icon
+ var err error
switch state {
case service.TunnelStarted:
- brush = tsip.startedBrush
- pen = tsip.startedPen
+ dot, err = walk.NewIconFromResourceWithSize("dot-green.ico", walk.Size{iconSize, iconSize})
case service.TunnelStopped:
- brush = tsip.stoppedBrush
- pen = tsip.stoppedPen
+ dot, err = walk.NewIconFromResourceWithSize("dot-gray.ico", walk.Size{iconSize, iconSize})
default:
- brush = tsip.startingBrush
- pen = tsip.startingPen
+ dot, err = walk.NewIconFromResourceWithSize("dot-yellow.ico", walk.Size{iconSize, iconSize})
+ }
+ if err != nil {
+ return err
}
+ defer dot.Dispose()
b := bounds
-
b.X += tsip.scaleForDPI(2)
b.Y += tsip.scaleForDPI(2)
b.Height -= tsip.scaleForDPI(4)
b.Width = b.Height
- if err := canvas.FillEllipse(brush, b); err != nil {
- return err
- }
- if err := canvas.DrawEllipse(pen, b); err != nil {
+ if err := canvas.DrawImageStretched(dot, b); err != nil {
return err
}
diff --git a/ui/tray.go b/ui/tray.go
index 4f22fc4d..3d02e87e 100644
--- a/ui/tray.go
+++ b/ui/tray.go
@@ -289,7 +289,9 @@ func (tray *Tray) SetTunnelState(tunnel *service.Tunnel, state service.TunnelSta
func (tray *Tray) UpdateFound() {
action := walk.NewAction()
action.SetText("An Update is Available!")
- action.SetImage(iconProvider.updateAvailableImage)
+ if icon, err := iconProvider.UpdateAvailableImage(); err == nil {
+ action.SetImage(icon)
+ }
//TODO: Make bold
action.Triggered().Attach(func() {
tray.mtw.Show()
diff --git a/ui/updatepage.go b/ui/updatepage.go
index 9aa056a1..cffea839 100644
--- a/ui/updatepage.go
+++ b/ui/updatepage.go
@@ -25,7 +25,10 @@ func NewUpdatePage() (*UpdatePage, error) {
}
up.SetTitle("An Update is Available!")
- up.SetImage(iconProvider.updateAvailableImage)
+
+ if icon, err := iconProvider.UpdateAvailableImage(); err == nil {
+ up.SetImage(icon)
+ }
//TODO: make title bold
up.SetLayout(walk.NewVBoxLayout())