Added Area resizing. Everything mostly works, but not making things smaller...

This commit is contained in:
Pietro Gagliardi 2014-03-23 20:54:11 -04:00
parent 0cc13633cb
commit a41f582866
6 changed files with 70 additions and 12 deletions

37
area.go
View File

@ -21,12 +21,14 @@ import (
// in platform-native ways is painful.
// [Use TextArea instead, providing a TextAreaHandler.]
//
// To facilitate development and debugging, for the time being, Areas have a fixed size of 320x240 and only work on GTK+.
// To facilitate development and debugging, for the time being, Areas only work on GTK+.
type Area struct {
lock sync.Mutex
created bool
sysData *sysData
handler AreaHandler
lock sync.Mutex
created bool
sysData *sysData
handler AreaHandler
initwidth int
initheight int
}
// AreaHandler represents the events that an Area should respond to.
@ -210,18 +212,34 @@ const (
// TODO add Super
)
// NewArea creates a new Area.
// NewArea creates a new Area with the given size and handler.
// It panics if handler is nil.
func NewArea(handler AreaHandler) *Area {
func NewArea(width int, height int, handler AreaHandler) *Area {
if handler == nil {
panic("handler passed to NewArea() must not be nil")
}
return &Area{
sysData: mksysdata(c_area),
handler: handler,
sysData: mksysdata(c_area),
handler: handler,
initwidth: width,
initheight: height,
}
}
// SetSize sets the Area's internal drawing size.
// It has no effect on the actual control size.
func (a *Area) SetSize(width int, height int) {
a.lock.Lock()
defer a.lock.Unlock()
if a.created {
a.sysData.setAreaSize(width, height)
return
}
a.initwidth = width
a.initheight = height
}
func (a *Area) make(window *sysData) error {
a.lock.Lock()
defer a.lock.Unlock()
@ -231,6 +249,7 @@ func (a *Area) make(window *sysData) error {
if err != nil {
return err
}
a.sysData.setAreaSize(a.initwidth, a.initheight)
a.created = true
return nil
}

View File

@ -24,7 +24,7 @@ import "C"
func gtkAreaNew() *gtkWidget {
drawingarea := C.gtk_drawing_area_new()
C.gtk_widget_set_size_request(drawingarea, 320, 240)
C.gtk_widget_set_size_request(drawingarea, 100, 100) // default initial size (TODO do we need it?); use C. to avoid casting drawingarea
// we need to explicitly subscribe to mouse events with GtkDrawingArea
C.gtk_widget_add_events(drawingarea,
C.GDK_BUTTON_PRESS_MASK | C.GDK_BUTTON_RELEASE_MASK | C.GDK_POINTER_MOTION_MASK | C.GDK_BUTTON_MOTION_MASK)

View File

@ -217,3 +217,7 @@ func gtk_progress_bar_set_fraction(w *gtkWidget, percent int) {
func gtk_progress_bar_pulse(w *gtkWidget) {
C.gtk_progress_bar_pulse(togtkprogressbar(w))
}
func gtk_widget_queue_draw(widget *gtkWidget) {
C.gtk_widget_queue_draw(togtkwidget(widget))
}

View File

@ -76,6 +76,9 @@ func (c *cSysData) setProgress(int) {
func (c *cSysData) len() int {
panic(runtime.GOOS + " sysData does not define len()")
}
func (c *cSysData) setAreaSize(int, int) {
panic(runtime.GOOS + " sysData does not define setAreaSize()")
}
// signal sends the event signal. This raise is done asynchronously to avoid deadlocking the UI task.
// Thanks skelterjohn for this techinque: if we can't queue any more events, drop them

View File

@ -350,3 +350,15 @@ func (s *sysData) len() int {
}
return <-ret
}
func (s *sysData) setAreaSize(width int, height int) {
ret := make(chan struct{})
defer close(ret)
uitask <- func() {
c := gtkAreaGetControl(s.widget)
gtk_widget_set_size_request(c, width, height)
gtk_widget_queue_draw(c) // force repaint (TODO doesn't have an effect when shrinking?)
ret <- struct{}{}
}
<-ret
}

View File

@ -10,6 +10,7 @@ import (
_ "image/png"
"bytes"
"time"
"strconv"
. "github.com/andlabs/ui"
)
@ -158,13 +159,25 @@ func areaTest() {
img := image.NewNRGBA(ximg.Bounds())
draw.Draw(img, img.Rect, ximg, image.ZP, draw.Over)
w := NewWindow("Area Test", 100, 100)
a := NewArea(&areaHandler{
a := NewArea(320, 240, &areaHandler{
img: img,
})
timedisp := NewLabel("")
timechan := time.Tick(time.Second)
widthbox := NewLineEdit("320")
heightbox := NewLineEdit("240")
resize := NewButton("Resize")
sizeStack := NewHorizontalStack(widthbox, heightbox, resize)
sizeStack.SetStretchy(0)
sizeStack.SetStretchy(1)
sizeStack.SetStretchy(2)
sizeStack = NewHorizontalStack(sizeStack, Space(), Space())
sizeStack.SetStretchy(0)
sizeStack.SetStretchy(1)
sizeStack.SetStretchy(2)
layout := NewVerticalStack(a,
NewHorizontalStack(timedisp))
NewHorizontalStack(timedisp),
sizeStack)
layout.SetStretchy(0)
err = w.Open(layout)
if err != nil {
@ -176,6 +189,13 @@ func areaTest() {
return
case t := <-timechan:
timedisp.SetText(t.String())
case <-resize.Clicked:
width, err := strconv.Atoi(widthbox.Text())
if err != nil { println(err); continue }
height, err := strconv.Atoi(heightbox.Text())
if err != nil { println(err); continue }
println(width, height)
a.SetSize(width, height)
}
}
}