2014-10-28 14:46:13 -05:00
|
|
|
// 28 october 2014
|
|
|
|
|
|
|
|
package ui
|
|
|
|
|
|
|
|
import (
|
|
|
|
"unsafe"
|
|
|
|
)
|
|
|
|
|
|
|
|
// #include "winapi_windows.h"
|
|
|
|
import "C"
|
|
|
|
|
|
|
|
// TODO do we have to manually monitor user changes to the edit control?
|
2014-10-30 09:49:22 -05:00
|
|
|
// TODO WS_EX_CLIENTEDGE on the updown?
|
2014-10-28 14:46:13 -05:00
|
|
|
|
|
|
|
type spinbox struct {
|
|
|
|
hwndEdit C.HWND
|
|
|
|
hwndUpDown C.HWND
|
2014-10-30 09:42:59 -05:00
|
|
|
// updown state
|
|
|
|
updownVisible bool
|
2014-10-30 11:43:06 -05:00
|
|
|
// keep these here to avoid having to get them out
|
|
|
|
value int
|
|
|
|
min int
|
|
|
|
max int
|
2014-10-28 14:46:13 -05:00
|
|
|
}
|
|
|
|
|
2014-10-30 11:43:06 -05:00
|
|
|
func newSpinbox(min int, max int) Spinbox {
|
2014-10-28 14:46:13 -05:00
|
|
|
s := new(spinbox)
|
|
|
|
s.hwndEdit = C.newControl(editclass,
|
|
|
|
C.textfieldStyle | C.ES_NUMBER,
|
|
|
|
C.textfieldExtStyle)
|
2014-10-30 09:42:59 -05:00
|
|
|
s.updownVisible = true // initially shown
|
2014-10-30 11:43:06 -05:00
|
|
|
s.min = min
|
|
|
|
s.max = max
|
|
|
|
s.value = s.min
|
2014-10-30 09:42:59 -05:00
|
|
|
s.remakeUpDown()
|
2014-10-28 14:46:13 -05:00
|
|
|
return s
|
|
|
|
}
|
|
|
|
|
2014-10-30 11:43:06 -05:00
|
|
|
func (s *spinbox) Value() int {
|
|
|
|
// TODO TODO TODO TODO TODO
|
|
|
|
// this CAN error out!!!
|
|
|
|
// we need to update s.value but we need to implement events first
|
|
|
|
return int(C.SendMessageW(s.hwndUpDown, C.UDM_GETPOS32, 0, 0))
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *spinbox) SetValue(value int) {
|
|
|
|
// UDM_SETPOS32 is documented to do what we want, but since we're keeping a copy of value we need to do it anyway
|
|
|
|
if value < s.min {
|
|
|
|
value = s.min
|
|
|
|
}
|
|
|
|
if value > s.max {
|
|
|
|
value = s.max
|
|
|
|
}
|
|
|
|
s.value = value
|
|
|
|
C.SendMessageW(s.hwndUpDown, C.UDM_SETPOS32, 0, C.LPARAM(value))
|
|
|
|
}
|
|
|
|
|
2014-10-28 14:46:13 -05:00
|
|
|
func (s *spinbox) setParent(p *controlParent) {
|
|
|
|
C.controlSetParent(s.hwndEdit, p.hwnd)
|
|
|
|
C.controlSetParent(s.hwndUpDown, p.hwnd)
|
|
|
|
}
|
|
|
|
|
2014-10-30 09:42:59 -05:00
|
|
|
// an up-down control will only properly position itself the first time
|
|
|
|
// stupidly, there are no messages to force a size calculation, nor can I seem to reset the buddy window to force a new position
|
|
|
|
// alas, we have to make a new up/down control each time :(
|
|
|
|
// TODO we'll need to store a copy of the current position and range for this
|
|
|
|
func (s *spinbox) remakeUpDown() {
|
|
|
|
// destroying the previous one and setting the parent properly is handled here
|
|
|
|
s.hwndUpDown = C.newUpDown(s.hwndUpDown)
|
|
|
|
// for this to work, hwndUpDown needs to have rect [0 0 0 0]
|
|
|
|
C.moveWindow(s.hwndUpDown, 0, 0, 0, 0)
|
|
|
|
C.SendMessageW(s.hwndUpDown, C.UDM_SETBUDDY, C.WPARAM(uintptr(unsafe.Pointer(s.hwndEdit))), 0)
|
2014-10-30 11:43:06 -05:00
|
|
|
C.SendMessageW(s.hwndUpDown, C.UDM_SETRANGE32, C.WPARAM(s.min), C.LPARAM(s.max))
|
|
|
|
C.SendMessageW(s.hwndUpDown, C.UDM_SETPOS32, 0, C.LPARAM(s.value))
|
2014-10-30 09:42:59 -05:00
|
|
|
if s.updownVisible {
|
|
|
|
C.ShowWindow(s.hwndUpDown, C.SW_SHOW)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-28 14:46:13 -05:00
|
|
|
func (s *spinbox) preferredSize(d *sizing) (width, height int) {
|
|
|
|
// TODO
|
|
|
|
return 20, 20
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *spinbox) resize(x int, y int, width int, height int, d *sizing) {
|
|
|
|
C.moveWindow(s.hwndEdit, C.int(x), C.int(y), C.int(width), C.int(height))
|
2014-10-30 09:42:59 -05:00
|
|
|
s.remakeUpDown()
|
2014-10-28 14:46:13 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
func (s *spinbox) nTabStops() int {
|
|
|
|
// TODO does the up-down control count?
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO be sure to modify this when we add Show()/Hide()
|
|
|
|
func (s *spinbox) containerShow() {
|
|
|
|
C.ShowWindow(s.hwndEdit, C.SW_SHOW)
|
|
|
|
C.ShowWindow(s.hwndUpDown, C.SW_SHOW)
|
2014-10-30 09:42:59 -05:00
|
|
|
s.updownVisible = true
|
2014-10-28 14:46:13 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// TODO be sure to modify this when we add Show()/Hide()
|
|
|
|
func (s *spinbox) containerHide() {
|
|
|
|
C.ShowWindow(s.hwndEdit, C.SW_HIDE)
|
|
|
|
C.ShowWindow(s.hwndUpDown, C.SW_HIDE)
|
2014-10-30 09:42:59 -05:00
|
|
|
s.updownVisible = false
|
2014-10-28 14:46:13 -05:00
|
|
|
}
|