2014-08-02 21:35:58 -05:00
|
|
|
// 15 july 2014
|
|
|
|
|
|
|
|
package ui
|
|
|
|
|
2014-08-20 11:04:36 -05:00
|
|
|
import (
|
|
|
|
"unsafe"
|
|
|
|
)
|
|
|
|
|
2014-08-02 21:35:58 -05:00
|
|
|
// #include "winapi_windows.h"
|
|
|
|
import "C"
|
|
|
|
|
2014-08-05 16:46:42 -05:00
|
|
|
type textfield struct {
|
2014-10-18 16:03:07 -05:00
|
|
|
*controlSingleHWNDWithText
|
2014-10-02 09:05:53 -05:00
|
|
|
changed *event
|
2014-08-02 21:35:58 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
var editclass = toUTF16("EDIT")
|
|
|
|
|
2014-08-05 16:46:42 -05:00
|
|
|
func startNewTextField(style C.DWORD) *textfield {
|
2014-08-03 20:52:21 -05:00
|
|
|
hwnd := C.newControl(editclass,
|
2014-10-02 09:05:53 -05:00
|
|
|
style|C.textfieldStyle,
|
|
|
|
C.textfieldExtStyle) // WS_EX_CLIENTEDGE without WS_BORDER will show the canonical visual styles border (thanks to MindChild in irc.efnet.net/#winprog)
|
2014-08-05 16:46:42 -05:00
|
|
|
t := &textfield{
|
2014-10-18 16:03:07 -05:00
|
|
|
controlSingleHWNDWithText: newControlSingleHWNDWithText(hwnd),
|
2014-10-02 09:05:53 -05:00
|
|
|
changed: newEvent(),
|
2014-08-02 21:35:58 -05:00
|
|
|
}
|
2014-10-18 16:03:07 -05:00
|
|
|
t.fpreferredSize = t.xpreferredSize
|
|
|
|
C.controlSetControlFont(t.hwnd)
|
|
|
|
C.setTextFieldSubclass(t.hwnd, unsafe.Pointer(t))
|
2014-08-02 21:35:58 -05:00
|
|
|
return t
|
|
|
|
}
|
|
|
|
|
2014-08-05 16:46:42 -05:00
|
|
|
func newTextField() *textfield {
|
2014-08-02 21:35:58 -05:00
|
|
|
return startNewTextField(0)
|
|
|
|
}
|
|
|
|
|
2014-08-05 16:46:42 -05:00
|
|
|
func newPasswordField() *textfield {
|
2014-08-02 21:35:58 -05:00
|
|
|
return startNewTextField(C.ES_PASSWORD)
|
|
|
|
}
|
|
|
|
|
2014-08-05 16:46:42 -05:00
|
|
|
func (t *textfield) Text() string {
|
2014-10-18 16:03:07 -05:00
|
|
|
return t.text()
|
2014-08-02 21:35:58 -05:00
|
|
|
}
|
|
|
|
|
2014-08-05 16:46:42 -05:00
|
|
|
func (t *textfield) SetText(text string) {
|
2014-10-18 16:03:07 -05:00
|
|
|
t.setText(text)
|
2014-08-03 20:52:21 -05:00
|
|
|
}
|
|
|
|
|
2014-08-20 11:04:36 -05:00
|
|
|
func (t *textfield) OnChanged(f func()) {
|
|
|
|
t.changed.set(f)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *textfield) Invalid(reason string) {
|
2014-08-20 13:17:00 -05:00
|
|
|
if reason == "" {
|
2014-10-18 16:03:07 -05:00
|
|
|
C.textfieldHideInvalidBalloonTip(t.hwnd)
|
2014-08-20 13:17:00 -05:00
|
|
|
return
|
|
|
|
}
|
2014-10-18 16:03:07 -05:00
|
|
|
C.textfieldSetAndShowInvalidBalloonTip(t.hwnd, toUTF16(reason))
|
2014-08-20 11:04:36 -05:00
|
|
|
}
|
|
|
|
|
2014-11-05 11:59:44 -06:00
|
|
|
func (t *textfield) ReadOnly() bool {
|
|
|
|
return C.textfieldReadOnly(t.hwnd) != 0
|
|
|
|
}
|
|
|
|
|
2015-03-03 18:07:51 -06:00
|
|
|
// TODO check visuals: http://www.microsoft.com/en-us/download/details.aspx?id=34587
|
2014-11-05 11:59:44 -06:00
|
|
|
func (t *textfield) SetReadOnly(readonly bool) {
|
|
|
|
if readonly {
|
|
|
|
C.textfieldSetReadOnly(t.hwnd, C.TRUE)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
C.textfieldSetReadOnly(t.hwnd, C.FALSE)
|
|
|
|
}
|
|
|
|
|
2014-08-20 11:04:36 -05:00
|
|
|
//export textfieldChanged
|
|
|
|
func textfieldChanged(data unsafe.Pointer) {
|
|
|
|
t := (*textfield)(data)
|
|
|
|
t.changed.fire()
|
|
|
|
}
|
|
|
|
|
2014-08-02 21:35:58 -05:00
|
|
|
const (
|
|
|
|
// from http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing
|
2014-10-02 09:05:53 -05:00
|
|
|
textfieldWidth = 107 // this is actually the shorter progress bar width, but Microsoft only indicates as wide as necessary
|
2014-08-02 21:35:58 -05:00
|
|
|
textfieldHeight = 14
|
|
|
|
)
|
|
|
|
|
2014-10-23 15:54:21 -05:00
|
|
|
// TODO allow custom preferred widths
|
2014-10-18 16:03:07 -05:00
|
|
|
func (t *textfield) xpreferredSize(d *sizing) (width, height int) {
|
2014-08-02 21:35:58 -05:00
|
|
|
return fromdlgunitsX(textfieldWidth, d), fromdlgunitsY(textfieldHeight, d)
|
|
|
|
}
|