forked from lxn/walk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
customwidget.go
117 lines (93 loc) · 2.28 KB
/
customwidget.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
// Copyright 2010 The Walk Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package walk
import (
"github.com/lxn/win"
)
const customWidgetWindowClass = `\o/ Walk_CustomWidget_Class \o/`
func init() {
MustRegisterWindowClass(customWidgetWindowClass)
}
type PaintFunc func(canvas *Canvas, updateBounds Rectangle) error
type CustomWidget struct {
WidgetBase
paint PaintFunc
clearsBackground bool
invalidatesOnResize bool
}
func NewCustomWidget(parent Container, style uint, paint PaintFunc) (*CustomWidget, error) {
cw := &CustomWidget{paint: paint}
if err := InitWidget(
cw,
parent,
customWidgetWindowClass,
win.WS_VISIBLE|uint32(style),
0); err != nil {
return nil, err
}
return cw, nil
}
func (*CustomWidget) LayoutFlags() LayoutFlags {
return ShrinkableHorz | ShrinkableVert | GrowableHorz | GrowableVert | GreedyHorz | GreedyVert
}
func (cw *CustomWidget) SizeHint() Size {
return Size{100, 100}
}
func (cw *CustomWidget) ClearsBackground() bool {
return cw.clearsBackground
}
func (cw *CustomWidget) SetClearsBackground(value bool) {
cw.clearsBackground = value
}
func (cw *CustomWidget) InvalidatesOnResize() bool {
return cw.invalidatesOnResize
}
func (cw *CustomWidget) SetInvalidatesOnResize(value bool) {
cw.invalidatesOnResize = value
}
func (cw *CustomWidget) WndProc(hwnd win.HWND, msg uint32, wParam, lParam uintptr) uintptr {
switch msg {
case win.WM_PAINT:
if cw.paint == nil {
newError("paint func is nil")
break
}
var ps win.PAINTSTRUCT
hdc := win.BeginPaint(cw.hWnd, &ps)
if hdc == 0 {
newError("BeginPaint failed")
break
}
defer win.EndPaint(cw.hWnd, &ps)
canvas, err := newCanvasFromHDC(hdc)
if err != nil {
newError("newCanvasFromHDC failed")
break
}
defer canvas.Dispose()
r := &ps.RcPaint
err = cw.paint(
canvas,
Rectangle{
int(r.Left),
int(r.Top),
int(r.Right - r.Left),
int(r.Bottom - r.Top),
})
if err != nil {
newError("paint failed")
break
}
return 0
case win.WM_ERASEBKGND:
if !cw.clearsBackground {
return 1
}
case win.WM_SIZE, win.WM_SIZING:
if cw.invalidatesOnResize {
cw.Invalidate()
}
}
return cw.WidgetBase.WndProc(hwnd, msg, wParam, lParam)
}