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
|
/* SPDX-License-Identifier: MIT
*
* Copyright (C) 2019 WireGuard LLC. All Rights Reserved.
*/
package syntax
import (
"errors"
"strings"
"syscall"
"unsafe"
"github.com/lxn/walk"
"github.com/lxn/win"
)
// #include "syntaxedit.h"
import "C"
type SyntaxEdit struct {
walk.WidgetBase
textChangedPublisher walk.EventPublisher
privateKeyPublisher walk.StringEventPublisher
}
func (se *SyntaxEdit) LayoutFlags() walk.LayoutFlags {
return walk.GrowableHorz | walk.GrowableVert | walk.GreedyHorz | walk.GreedyVert
}
func (se *SyntaxEdit) MinSizeHint() walk.Size {
return walk.Size{20, 12}
}
func (se *SyntaxEdit) SizeHint() walk.Size {
return walk.Size{200, 100}
}
func (se *SyntaxEdit) Text() string {
textLength := se.SendMessage(win.WM_GETTEXTLENGTH, 0, 0)
buf := make([]uint16, textLength+1)
se.SendMessage(win.WM_GETTEXT, uintptr(textLength+1), uintptr(unsafe.Pointer(&buf[0])))
return strings.Replace(syscall.UTF16ToString(buf), "\r\n", "\n", -1)
}
func (se *SyntaxEdit) SetText(text string) (err error) {
if text == se.Text() {
return nil
}
text = strings.Replace(text, "\n", "\r\n", -1)
if win.TRUE != se.SendMessage(win.WM_SETTEXT, 0, uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(text)))) {
err = errors.New("WM_SETTEXT failed")
}
se.textChangedPublisher.Publish()
return
}
func (se *SyntaxEdit) TextChanged() *walk.Event {
return se.textChangedPublisher.Event()
}
func (se *SyntaxEdit) PrivateKeyChanged() *walk.StringEvent {
return se.privateKeyPublisher.Event()
}
func (se *SyntaxEdit) WndProc(hwnd win.HWND, msg uint32, wParam, lParam uintptr) uintptr {
switch msg {
case win.WM_NOTIFY, win.WM_COMMAND:
switch win.HIWORD(uint32(wParam)) {
case win.EN_CHANGE:
se.textChangedPublisher.Publish()
}
// This is a horrible trick from MFC where we reflect the event back to the child.
se.SendMessage(msg+C.WM_REFLECT, wParam, lParam)
case C.SE_PRIVATE_KEY:
if lParam == 0 {
se.privateKeyPublisher.Publish("")
} else {
se.privateKeyPublisher.Publish(C.GoString((*C.char)(unsafe.Pointer(lParam))))
}
}
return se.WidgetBase.WndProc(hwnd, msg, wParam, lParam)
}
func NewSyntaxEdit(parent walk.Container) (*SyntaxEdit, error) {
C.register_syntax_edit()
se := &SyntaxEdit{}
err := walk.InitWidget(
se,
parent,
"WgQuickSyntaxEdit",
C.SYNTAXEDIT_STYLE,
C.SYNTAXEDIT_EXTSTYLE,
)
if err != nil {
return nil, err
}
se.GraphicsEffects().Add(walk.InteractionEffect)
se.GraphicsEffects().Add(walk.FocusEffect)
se.MustRegisterProperty("Text", walk.NewProperty(
func() interface{} {
return se.Text()
},
func(v interface{}) error {
if s, ok := v.(string); ok {
return se.SetText(s)
} else {
return se.SetText("")
}
},
se.textChangedPublisher.Event()))
return se, nil
}
|