Started the new recontainerization..
This commit is contained in:
parent
aad6e4c699
commit
eef3e1136b
|
@ -0,0 +1,73 @@
|
|||
// 15 july 2014
|
||||
|
||||
package ui
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// #include "winapi_windows.h"
|
||||
import "C"
|
||||
|
||||
type button struct {
|
||||
*controlSingleHWNDWithText
|
||||
clicked *event
|
||||
}
|
||||
|
||||
var buttonclass = toUTF16("BUTTON")
|
||||
|
||||
func newButton(text string) *button {
|
||||
hwnd := C.newControl(buttonclass,
|
||||
C.BS_PUSHBUTTON|C.WS_TABSTOP,
|
||||
0)
|
||||
b := &button{
|
||||
controlSingleHWNDWithText: newControlSingleHWNDWithText(hwnd),
|
||||
clicked: newEvent(),
|
||||
}
|
||||
b.fpreferredSize = b.preferredSize
|
||||
b.SetText(text)
|
||||
C.controlSetControlFont(b.hwnd)
|
||||
C.setButtonSubclass(b.hwnd, unsafe.Pointer(b))
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *button) OnClicked(e func()) {
|
||||
b.clicked.set(e)
|
||||
}
|
||||
|
||||
func (b *button) Text() string {
|
||||
return b.text()
|
||||
}
|
||||
|
||||
func (b *button) SetText(text string) {
|
||||
b.setText(text)
|
||||
}
|
||||
|
||||
//export buttonClicked
|
||||
func buttonClicked(data unsafe.Pointer) {
|
||||
b := (*button)(data)
|
||||
b.clicked.fire()
|
||||
}
|
||||
|
||||
const (
|
||||
// from http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing
|
||||
buttonHeight = 14
|
||||
)
|
||||
|
||||
func (b *button) preferredSize(d *sizing) (width, height int) {
|
||||
return 0,0/*TODO/*
|
||||
// comctl32.dll version 6 thankfully provides a method to grab this...
|
||||
var size C.SIZE
|
||||
|
||||
size.cx = 0 // explicitly ask for ideal size
|
||||
size.cy = 0
|
||||
if C.SendMessageW(b.hwnd, C.BCM_GETIDEALSIZE, 0, C.LPARAM(uintptr(unsafe.Pointer(&size)))) != C.FALSE {
|
||||
return int(size.cx), int(size.cy)
|
||||
}
|
||||
// that failed, fall back
|
||||
println("message failed; falling back")
|
||||
// don't worry about the error return from GetSystemMetrics(); there's no way to tell (explicitly documented as such)
|
||||
xmargins := 2 * int(C.GetSystemMetrics(C.SM_CXEDGE))
|
||||
return xmargins + int(b.textlen), fromdlgunitsY(buttonHeight, d)
|
||||
*/
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
// 30 july 2014
|
||||
|
||||
package ui
|
||||
|
||||
// Control represents a control.
|
||||
type Control interface {
|
||||
setParent(p *controlParent) // controlParent defined per-platform
|
||||
// nChildren() int // TODO
|
||||
preferredSize(d *sizing) (width, height int)
|
||||
resize(x int, y int, width int, height int, d *sizing)
|
||||
}
|
||||
|
||||
type controlbase struct {
|
||||
fsetParent func(p *controlParent)
|
||||
fpreferredSize func(d *sizing) (width, height int)
|
||||
fresize func(x int, y int, width int, height int, d *sizing)
|
||||
}
|
||||
|
||||
func (c *controlbase) setParent(p *controlParent) {
|
||||
c.fsetParent(p)
|
||||
}
|
||||
|
||||
func (c *controlbase) preferredSize(d *sizing) (width, height int) {
|
||||
return c.fpreferredSize(d)
|
||||
}
|
||||
|
||||
func (c *controlbase) resize(x int, y int, width int, height int, d *sizing) {
|
||||
c.fresize(x, y, width, height, d)
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
// 30 july 2014
|
||||
|
||||
package ui
|
||||
|
||||
// #include "winapi_windows.h"
|
||||
import "C"
|
||||
|
||||
type controlParent struct {
|
||||
hwnd C.HWND
|
||||
}
|
||||
type sizing struct {
|
||||
// TODO
|
||||
}
|
||||
|
||||
// don't specify preferredSize in any of these; they're per-control
|
||||
|
||||
type controlSingleHWND struct {
|
||||
*controlbase
|
||||
hwnd C.HWND
|
||||
}
|
||||
|
||||
func newControlSingleHWND(hwnd C.HWND) *controlSingleHWND {
|
||||
c := new(controlSingleHWND)
|
||||
c.controlbase = &controlbase{
|
||||
fsetParent: c.setParent,
|
||||
fresize: c.resize,
|
||||
}
|
||||
c.hwnd = hwnd
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *controlSingleHWND) setParent(p *controlParent) {
|
||||
C.controlSetParent(c.hwnd, p.hwnd)
|
||||
}
|
||||
|
||||
func (c *controlSingleHWND) resize(x int, y int, width int, height int, d *sizing) {
|
||||
C.moveWindow(c.hwnd, C.int(x), C.int(y), C.int(width), C.int(height))
|
||||
}
|
||||
|
||||
// these are provided for convenience
|
||||
|
||||
type controlSingleHWNDWithText struct {
|
||||
*controlSingleHWND
|
||||
textlen C.LONG
|
||||
}
|
||||
|
||||
func newControlSingleHWNDWithText(h C.HWND) *controlSingleHWNDWithText {
|
||||
return &controlSingleHWNDWithText{
|
||||
controlSingleHWND: newControlSingleHWND(h),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *controlSingleHWNDWithText) text() string {
|
||||
return getWindowText(c.hwnd)
|
||||
}
|
||||
|
||||
func (c *controlSingleHWNDWithText) setText(text string) {
|
||||
t := toUTF16(text)
|
||||
C.setWindowText(c.hwnd, t)
|
||||
c.textlen = C.controlTextLength(c.hwnd, t)
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
// 12 july 2014
|
||||
|
||||
package ui
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// #include "winapi_windows.h"
|
||||
import "C"
|
||||
|
||||
type window struct {
|
||||
hwnd C.HWND
|
||||
shownbefore bool
|
||||
|
||||
closing *event
|
||||
|
||||
child Control
|
||||
}
|
||||
|
||||
func makeWindowWindowClass() error {
|
||||
var errmsg *C.char
|
||||
|
||||
err := C.makeWindowWindowClass(&errmsg)
|
||||
if err != 0 || errmsg != nil {
|
||||
return fmt.Errorf("%s: %v", C.GoString(errmsg), syscall.Errno(err))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func newWindow(title string, width int, height int, control Control) *window {
|
||||
w := &window{
|
||||
// hwnd set in WM_CREATE handler
|
||||
closing: newEvent(),
|
||||
child: control,
|
||||
}
|
||||
hwnd := C.newWindow(toUTF16(title), C.int(width), C.int(height), unsafe.Pointer(w))
|
||||
if hwnd != w.hwnd {
|
||||
panic(fmt.Errorf("inconsistency: hwnd returned by CreateWindowEx() (%p) and hwnd stored in Window (%p) differ", hwnd, w.hwnd))
|
||||
}
|
||||
hresult := C.EnableThemeDialogTexture(w.hwnd, C.ETDT_ENABLE|C.ETDT_USETABTEXTURE)
|
||||
if hresult != C.S_OK {
|
||||
panic(fmt.Errorf("error setting tab background texture on Window; HRESULT: 0x%X", hresult))
|
||||
}
|
||||
w.child.setParent(&controlParent{w.hwnd})
|
||||
return w
|
||||
}
|
||||
|
||||
func (w *window) Title() string {
|
||||
return getWindowText(w.hwnd)
|
||||
}
|
||||
|
||||
func (w *window) SetTitle(title string) {
|
||||
C.setWindowText(w.hwnd, toUTF16(title))
|
||||
}
|
||||
|
||||
func (w *window) Show() {
|
||||
if !w.shownbefore {
|
||||
C.ShowWindow(w.hwnd, C.nCmdShow)
|
||||
C.updateWindow(w.hwnd)
|
||||
w.shownbefore = true
|
||||
} else {
|
||||
C.ShowWindow(w.hwnd, C.SW_SHOW)
|
||||
}
|
||||
}
|
||||
|
||||
func (w *window) Hide() {
|
||||
C.ShowWindow(w.hwnd, C.SW_HIDE)
|
||||
}
|
||||
|
||||
func (w *window) Close() {
|
||||
C.windowClose(w.hwnd)
|
||||
}
|
||||
|
||||
func (w *window) OnClosing(e func() bool) {
|
||||
w.closing.setbool(e)
|
||||
}
|
||||
|
||||
//export storeWindowHWND
|
||||
func storeWindowHWND(data unsafe.Pointer, hwnd C.HWND) {
|
||||
w := (*window)(data)
|
||||
w.hwnd = hwnd
|
||||
}
|
||||
|
||||
//export windowResize
|
||||
func windowResize(data unsafe.Pointer, r *C.RECT) {
|
||||
w := (*window)(data)
|
||||
TODO := &sizing{}
|
||||
w.child.resize(int(r.left), int (r.top), int(r.right - r.left), int(r.bottom - r.top), TODO)
|
||||
}
|
||||
|
||||
//export windowClosing
|
||||
func windowClosing(data unsafe.Pointer) {
|
||||
w := (*window)(data)
|
||||
close := w.closing.fire()
|
||||
if close {
|
||||
C.windowClose(w.hwnd)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
// 14 october 2014
|
||||
|
||||
package ui
|
||||
|
||||
import "flag"
|
||||
import "testing"
|
||||
|
||||
var twindow *window
|
||||
|
||||
func maketw(done chan struct{}) {
|
||||
button := newButton("Greet")
|
||||
twindow = newWindow("Hello", 200, 100, button)
|
||||
twindow.OnClosing(func() bool {
|
||||
Stop()
|
||||
return true
|
||||
})
|
||||
twindow.Show()
|
||||
}
|
||||
|
||||
// because Cocoa hates being run off the main thread, even if it's run exclusively off the main thread
|
||||
func init() {
|
||||
flag.Parse()
|
||||
go func() {
|
||||
done := make(chan struct{})
|
||||
Do(func() { maketw(done) })
|
||||
<-done
|
||||
}()
|
||||
err := Go()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDummy(t *testing.T) {
|
||||
// do nothing
|
||||
}
|
Loading…
Reference in New Issue