Started the new recontainerization..

This commit is contained in:
Pietro Gagliardi 2014-10-14 15:17:35 -04:00
parent aad6e4c699
commit eef3e1136b
5 changed files with 300 additions and 0 deletions

73
newctrl/button_windows.go Normal file
View File

@ -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)
*/
}

29
newctrl/control.go Normal file
View File

@ -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)
}

View File

@ -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)
}

101
newctrl/window_windows.go Normal file
View File

@ -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)
}
}

36
newctrl/zz_test.go Normal file
View File

@ -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
}