aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/ui/iconprovider.go
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2019-05-08 11:52:18 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2019-05-08 12:16:49 +0200
commit4835f350ffe6b4fa589748e808fb84cc7c53e103 (patch)
treee0a3488aa1447bd741735037a9b347963b428d1d /ui/iconprovider.go
parentinstaller: smarter detection of SYSTEM profile folder (diff)
downloadwireguard-windows-4835f350ffe6b4fa589748e808fb84cc7c53e103.tar.xz
wireguard-windows-4835f350ffe6b4fa589748e808fb84cc7c53e103.zip
ui: get correctly sized system iconsv0.0.1
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'ui/iconprovider.go')
-rw-r--r--ui/iconprovider.go69
1 files changed, 20 insertions, 49 deletions
diff --git a/ui/iconprovider.go b/ui/iconprovider.go
index ac373d90..e2647939 100644
--- a/ui/iconprovider.go
+++ b/ui/iconprovider.go
@@ -14,41 +14,14 @@ import (
"path"
)
-type IconProvider struct {
- wireguardIcon *walk.Icon
- overlayIconsByState map[service.TunnelState]*walk.Icon
-}
-
-func NewIconProvider() (*IconProvider, error) {
- tsip := &IconProvider{overlayIconsByState: make(map[service.TunnelState]*walk.Icon)}
- var err error
- if tsip.wireguardIcon, err = walk.NewIconFromResource("$wireguard.ico"); err != nil {
+func iconWithOverlayForState(state service.TunnelState, size int) (*walk.Icon, error) {
+ wireguardIcon, err := walk.NewIconFromResourceWithSize("$wireguard.ico", walk.Size{size, size})
+ if err != nil {
return nil, err
}
- return tsip, nil
-}
-
-func (tsip *IconProvider) Dispose() {
- if tsip.overlayIconsByState != nil {
- for _, icon := range tsip.overlayIconsByState {
- icon.Dispose()
- }
- tsip.overlayIconsByState = nil
- }
- if tsip.wireguardIcon != nil {
- tsip.wireguardIcon.Dispose()
- tsip.wireguardIcon = nil
- }
-}
-
-func (tsip *IconProvider) IconWithOverlayForState(state service.TunnelState) (*walk.Icon, error) {
- if icon, ok := tsip.overlayIconsByState[state]; ok {
- return icon, nil
- }
-
- size := tsip.wireguardIcon.Size()
-
- bmp, err := walk.NewBitmapWithTransparentPixels(size)
+ defer wireguardIcon.Dispose()
+ iconSize := wireguardIcon.Size()
+ bmp, err := walk.NewBitmapWithTransparentPixels(iconSize)
if err != nil {
return nil, err
}
@@ -60,20 +33,18 @@ func (tsip *IconProvider) IconWithOverlayForState(state service.TunnelState) (*w
}
defer canvas.Dispose()
- if err := canvas.DrawImage(tsip.wireguardIcon, walk.Point{}); err != nil {
+ if err := canvas.DrawImage(wireguardIcon, walk.Point{}); err != nil {
return nil, err
}
- overlayIcon, err := tsip.IconForState(state)
+ w := int(float64(iconSize.Width) * 0.65)
+ h := int(float64(iconSize.Height) * 0.65)
+ bounds := walk.Rectangle{iconSize.Width - w, iconSize.Height - h, w, h}
+ overlayIcon, err := iconForState(state, bounds.Width)
if err != nil {
return nil, err
}
defer overlayIcon.Dispose()
-
- w := int(float64(size.Width) * 0.65)
- h := int(float64(size.Height) * 0.65)
- bounds := walk.Rectangle{size.Width - w, size.Height - h, w, h}
-
if err := canvas.DrawImageStretched(overlayIcon, bounds); err != nil {
return nil, err
}
@@ -83,32 +54,32 @@ func (tsip *IconProvider) IconWithOverlayForState(state service.TunnelState) (*w
if err != nil {
return nil, err
}
- tsip.overlayIconsByState[state] = icon
return icon, nil
}
-func (tsip *IconProvider) IconForState(state service.TunnelState) (icon *walk.Icon, err error) {
+func iconForState(state service.TunnelState, size int) (icon *walk.Icon, err error) {
switch state {
case service.TunnelStarted:
- icon, err = loadSystemIcon("imageres", 101)
+ icon, err = loadSystemIcon("imageres", 101, size)
case service.TunnelStopped:
- icon, err = walk.NewIconFromResource("dot-gray.ico") //TODO: replace with real icon
+ icon, err = walk.NewIconFromResourceWithSize("dot-gray.ico", walk.Size{size, size}) //TODO: replace with real icon
default:
- icon, err = loadSystemIcon("shell32", 238) //TODO: this doesn't look that great overlayed on the app icon
+ icon, err = loadSystemIcon("shell32", 238, size) //TODO: this doesn't look that great overlayed on the app icon
}
return
}
-func loadSystemIcon(dll string, index uint) (*walk.Icon, error) {
+func loadSystemIcon(dll string, index int32, size int) (*walk.Icon, error) {
system32, err := windows.GetSystemDirectory()
if err != nil {
return nil, err
}
- hicon := win.ExtractIcon(win.GetModuleHandle(nil), windows.StringToUTF16Ptr(path.Join(system32, dll+".dll")), int32(index))
- if hicon <= 1 {
- return nil, fmt.Errorf("Unable to find icon %d of %s", index, dll)
+ var hicon win.HICON
+ ret := win.SHDefExtractIcon(windows.StringToUTF16Ptr(path.Join(system32, dll+".dll")), index, 0, &hicon, nil, uint32(size))
+ if ret != 0 {
+ return nil, fmt.Errorf("Unable to find icon %d of %s due to error %d", index, dll, ret)
}
return walk.NewIconFromHICON(hicon)
}