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. // in platform-native ways is painful.
// [Use TextArea instead, providing a TextAreaHandler.] // [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 { type Area struct {
lock sync.Mutex lock sync.Mutex
created bool created bool
sysData *sysData sysData *sysData
handler AreaHandler handler AreaHandler
initwidth int
initheight int
} }
// AreaHandler represents the events that an Area should respond to. // AreaHandler represents the events that an Area should respond to.
@ -210,18 +212,34 @@ const (
// TODO add Super // 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. // It panics if handler is nil.
func NewArea(handler AreaHandler) *Area { func NewArea(width int, height int, handler AreaHandler) *Area {
if handler == nil { if handler == nil {
panic("handler passed to NewArea() must not be nil") panic("handler passed to NewArea() must not be nil")
} }
return &Area{ return &Area{
sysData: mksysdata(c_area), sysData: mksysdata(c_area),
handler: handler, 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 { func (a *Area) make(window *sysData) error {
a.lock.Lock() a.lock.Lock()
defer a.lock.Unlock() defer a.lock.Unlock()
@ -231,6 +249,7 @@ func (a *Area) make(window *sysData) error {
if err != nil { if err != nil {
return err return err
} }
a.sysData.setAreaSize(a.initwidth, a.initheight)
a.created = true a.created = true
return nil return nil
} }

View File

@ -24,7 +24,7 @@ import "C"
func gtkAreaNew() *gtkWidget { func gtkAreaNew() *gtkWidget {
drawingarea := C.gtk_drawing_area_new() 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 // we need to explicitly subscribe to mouse events with GtkDrawingArea
C.gtk_widget_add_events(drawingarea, 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) 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) { func gtk_progress_bar_pulse(w *gtkWidget) {
C.gtk_progress_bar_pulse(togtkprogressbar(w)) 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 { func (c *cSysData) len() int {
panic(runtime.GOOS + " sysData does not define len()") 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. // 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 // 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 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" _ "image/png"
"bytes" "bytes"
"time" "time"
"strconv"
. "github.com/andlabs/ui" . "github.com/andlabs/ui"
) )
@ -158,13 +159,25 @@ func areaTest() {
img := image.NewNRGBA(ximg.Bounds()) img := image.NewNRGBA(ximg.Bounds())
draw.Draw(img, img.Rect, ximg, image.ZP, draw.Over) draw.Draw(img, img.Rect, ximg, image.ZP, draw.Over)
w := NewWindow("Area Test", 100, 100) w := NewWindow("Area Test", 100, 100)
a := NewArea(&areaHandler{ a := NewArea(320, 240, &areaHandler{
img: img, img: img,
}) })
timedisp := NewLabel("") timedisp := NewLabel("")
timechan := time.Tick(time.Second) 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, layout := NewVerticalStack(a,
NewHorizontalStack(timedisp)) NewHorizontalStack(timedisp),
sizeStack)
layout.SetStretchy(0) layout.SetStretchy(0)
err = w.Open(layout) err = w.Open(layout)
if err != nil { if err != nil {
@ -176,6 +189,13 @@ func areaTest() {
return return
case t := <-timechan: case t := <-timechan:
timedisp.SetText(t.String()) 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)
} }
} }
} }