summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorAlexander Neumann <alexander.neumann@picos-software.com>2018-12-06 15:57:21 +0100
committerAlexander Neumann <alexander.neumann@picos-software.com>2018-12-06 15:57:21 +0100
commitca8a4696abc7dcba6f49a86c4594ad612e95f524 (patch)
treee5e8c24fdfee87123f89e38137643240b49a17f1
parentLabel, TextLabel: Make sure to publish TextChanged events when changed through Text property (diff)
downloadwireguard-windows-ca8a4696abc7dcba6f49a86c4594ad612e95f524.tar.xz
wireguard-windows-ca8a4696abc7dcba6f49a86c4594ad612e95f524.zip
Labels: Let an embedded static control do the painting
-rw-r--r--datelabel.go4
-rw-r--r--label.go12
-rw-r--r--numberlabel.go4
-rw-r--r--static.go167
-rw-r--r--textlabel.go6
5 files changed, 143 insertions, 50 deletions
diff --git a/datelabel.go b/datelabel.go
index b7c046ea..7cbb8bff 100644
--- a/datelabel.go
+++ b/datelabel.go
@@ -51,6 +51,10 @@ func NewDateLabel(parent Container) (*DateLabel, error) {
return dl, nil
}
+func (dl *DateLabel) asStatic() *static {
+ return &dl.static
+}
+
func (dl *DateLabel) TextAlignment() Alignment1D {
return dl.textAlignment1D()
}
diff --git a/label.go b/label.go
index 1ff989ba..25944739 100644
--- a/label.go
+++ b/label.go
@@ -36,8 +36,16 @@ func NewLabelWithStyle(parent Container, style uint32) (*Label, error) {
return l, nil
}
-func (*Label) LayoutFlags() LayoutFlags {
- return ShrinkableHorz | ShrinkableVert | GrowableHorz | GrowableVert
+func (l *Label) asStatic() *static {
+ return &l.static
+}
+
+func (l *Label) LayoutFlags() LayoutFlags {
+ if l.TextAlignment() == AlignNear {
+ return GrowableVert
+ }
+
+ return GrowableHorz | GrowableVert
}
func (l *Label) TextAlignment() Alignment1D {
diff --git a/numberlabel.go b/numberlabel.go
index 964c9e45..2f76eb34 100644
--- a/numberlabel.go
+++ b/numberlabel.go
@@ -62,6 +62,10 @@ func NewNumberLabel(parent Container) (*NumberLabel, error) {
return nl, nil
}
+func (nl *NumberLabel) asStatic() *static {
+ return &nl.static
+}
+
func (nl *NumberLabel) TextAlignment() Alignment1D {
return nl.textAlignment1D()
}
diff --git a/static.go b/static.go
index 1c7f9452..b48d8917 100644
--- a/static.go
+++ b/static.go
@@ -7,33 +7,80 @@
package walk
import (
- "unsafe"
+ "syscall"
"github.com/lxn/win"
)
+const staticWindowClass = `\o/ Walk_Static_Class \o/`
+
+var staticWndProcPtr = syscall.NewCallback(staticWndProc)
+
+func init() {
+ MustRegisterWindowClass(staticWindowClass)
+}
+
type static struct {
WidgetBase
- textAlignment Alignment2D
- textColor Color
+ hwndStatic win.HWND
+ origStaticWndProcPtr uintptr
+ textAlignment Alignment2D
+ textColor Color
}
func (s *static) init(widget Widget, parent Container) error {
if err := InitWidget(
widget,
parent,
- "STATIC",
- win.WS_VISIBLE|win.SS_OWNERDRAW,
- 0); err != nil {
+ staticWindowClass,
+ win.WS_VISIBLE,
+ win.WS_EX_CONTROLPARENT); err != nil {
return err
}
+ if s.hwndStatic = win.CreateWindowEx(
+ 0,
+ syscall.StringToUTF16Ptr("static"),
+ nil,
+ win.WS_CHILD|win.WS_CLIPSIBLINGS|win.WS_VISIBLE|win.SS_LEFT,
+ win.CW_USEDEFAULT,
+ win.CW_USEDEFAULT,
+ win.CW_USEDEFAULT,
+ win.CW_USEDEFAULT,
+ s.hWnd,
+ 0,
+ 0,
+ nil,
+ ); s.hwndStatic == 0 {
+ return newErr("creating static failed")
+ }
+
+ s.origStaticWndProcPtr = win.SetWindowLongPtr(s.hwndStatic, win.GWLP_WNDPROC, staticWndProcPtr)
+ if s.origStaticWndProcPtr == 0 {
+ return lastError("SetWindowLongPtr")
+ }
+
+ s.applyFont(s.Font())
+
s.SetBackground(nullBrushSingleton)
return nil
}
-func (*static) LayoutFlags() LayoutFlags {
+func (s *static) Dispose() {
+ if s.hwndStatic != 0 {
+ win.DestroyWindow(s.hwndStatic)
+ s.hwndStatic = 0
+ }
+
+ s.WidgetBase.Dispose()
+}
+
+func (s *static) LayoutFlags() LayoutFlags {
+ if s.textAlignment1D() == AlignNear {
+ return GrowableVert
+ }
+
return GrowableHorz | GrowableVert
}
@@ -45,16 +92,24 @@ func (s *static) SizeHint() Size {
return s.MinSizeHint()
}
-func (s *static) HeightForWidth(width int) int {
- return s.MinSizeHint().Height
+func (s *static) applyEnabled(enabled bool) {
+ s.WidgetBase.applyEnabled(enabled)
+
+ setWindowEnabled(s.hwndStatic, enabled)
+}
+
+func (s *static) applyFont(font *Font) {
+ s.WidgetBase.applyFont(font)
+
+ setWindowFont(s.hwndStatic, font)
}
func (s *static) textAlignment1D() Alignment1D {
switch s.textAlignment {
- case AlignHCenterVCenter:
+ case AlignHCenterVNear, AlignHCenterVCenter, AlignHCenterVFar:
return AlignCenter
- case AlignHFarVCenter:
+ case AlignHFarVNear, AlignHFarVCenter, AlignHFarVFar:
return AlignFar
default:
@@ -84,6 +139,23 @@ func (s *static) setTextAlignment(alignment Alignment2D) error {
return nil
}
+ var styleBit uint32
+
+ switch alignment {
+ case AlignHNearVNear, AlignHNearVCenter, AlignHNearVFar:
+ styleBit |= win.SS_LEFT
+
+ case AlignHCenterVNear, AlignHCenterVCenter, AlignHCenterVFar:
+ styleBit |= win.SS_CENTER
+
+ case AlignHFarVNear, AlignHFarVCenter, AlignHFarVFar:
+ styleBit |= win.SS_RIGHT
+ }
+
+ if err := setAndClearWindowLongBits(s.hwndStatic, win.GWL_STYLE, styleBit, win.SS_LEFT|win.SS_CENTER|win.SS_RIGHT); err != nil {
+ return err
+ }
+
s.textAlignment = alignment
s.Invalidate()
@@ -91,12 +163,16 @@ func (s *static) setTextAlignment(alignment Alignment2D) error {
return nil
}
-func (s *static) setText(value string) (changed bool, err error) {
- if value == s.text() {
+func (s *static) setText(text string) (changed bool, err error) {
+ if text == s.text() {
return false, nil
}
- if err := s.WidgetBase.setText(value); err != nil {
+ if err := s.WidgetBase.setText(text); err != nil {
+ return false, err
+ }
+
+ if err := setWindowText(s.hwndStatic, text); err != nil {
return false, err
}
@@ -113,24 +189,15 @@ func (s *static) SetTextColor(c Color) {
s.Invalidate()
}
-func (s *static) WndProc(hwnd win.HWND, msg uint32, wParam, lParam uintptr) uintptr {
+func (s *static) WndProc(hwnd win.HWND, msg uint32, wp, lp uintptr) uintptr {
switch msg {
- case win.WM_NCHITTEST:
- return win.HTCLIENT
-
- case win.WM_SIZE, win.WM_SIZING:
- s.Invalidate()
-
- case win.WM_DRAWITEM:
- dis := (*win.DRAWITEMSTRUCT)(unsafe.Pointer(lParam))
-
- canvas, err := newCanvasFromHDC(dis.HDC)
- if err != nil {
- break
+ case win.WM_CTLCOLORSTATIC:
+ if hBrush := s.handleWMCTLCOLOR(wp, uintptr(s.hWnd)); hBrush != 0 {
+ return hBrush
}
- canvas.Dispose()
- format := TextWordbreak
+ case win.WM_SIZE, win.WM_SIZING:
+ var format DrawTextFormat
switch s.textAlignment {
case AlignHNearVNear, AlignHNearVCenter, AlignHNearVFar:
@@ -154,37 +221,43 @@ func (s *static) WndProc(hwnd win.HWND, msg uint32, wParam, lParam uintptr) uint
format |= TextBottom
}
- bounds := rectangleFromRECT(dis.RcItem)
+ cb := s.ClientBounds()
if format&TextVCenter != 0 || format&TextBottom != 0 {
- size := s.calculateTextSizeForWidth(bounds.Width)
+ var size Size
+ if _, ok := s.window.(HeightForWidther); ok {
+ size = s.calculateTextSizeForWidth(cb.Width)
+ } else {
+ size = s.calculateTextSize()
+ }
if format&TextVCenter != 0 {
- bounds.Y += (bounds.Height - size.Height) / 2
+ cb.Y += (cb.Height - size.Height) / 2
} else {
- bounds.Y += bounds.Height - size.Height
+ cb.Y += cb.Height - size.Height
}
- bounds.Height = size.Height
+ cb.Height = size.Height
}
- bg, wnd := s.backgroundEffective()
- if bg == nil {
- bg = sysColorBtnFaceBrushSingleton
- }
+ win.MoveWindow(s.hwndStatic, int32(cb.X), int32(cb.Y), int32(cb.Width), int32(cb.Height), true)
+ }
- s.prepareDCForBackground(dis.HDC, s.hWnd, wnd)
+ return s.WidgetBase.WndProc(hwnd, msg, wp, lp)
+}
- if err := canvas.FillRectangle(bg, s.ClientBounds()); err != nil {
- break
- }
+func staticWndProc(hwnd win.HWND, msg uint32, wp, lp uintptr) uintptr {
+ as, ok := windowFromHandle(win.GetParent(hwnd)).(interface{ asStatic() *static })
+ if !ok {
+ return 0
+ }
- if err := canvas.DrawText(s.text(), s.Font(), s.textColor, bounds, format); err != nil {
- break
- }
+ s := as.asStatic()
- return 1
+ switch msg {
+ case win.WM_NCHITTEST:
+ return win.HTCLIENT
}
- return s.WidgetBase.WndProc(hwnd, msg, wParam, lParam)
+ return win.CallWindowProc(s.origStaticWndProcPtr, hwnd, msg, wp, lp)
}
diff --git a/textlabel.go b/textlabel.go
index 073a2ba6..44b6018c 100644
--- a/textlabel.go
+++ b/textlabel.go
@@ -36,8 +36,12 @@ func NewTextLabelWithStyle(parent Container, style uint32) (*TextLabel, error) {
return tl, nil
}
+func (tl *TextLabel) asStatic() *static {
+ return &tl.static
+}
+
func (*TextLabel) LayoutFlags() LayoutFlags {
- return ShrinkableHorz | ShrinkableVert | GrowableHorz | GrowableVert
+ return GrowableHorz | GrowableVert
}
func (tl *TextLabel) MinSizeHint() Size {