Basic support in X backend for new API
This commit is contained in:
parent
bb9c5df088
commit
e931717241
@ -10,18 +10,25 @@ type entity struct {
|
||||
children []*entity
|
||||
element tomo.Element
|
||||
|
||||
drawDirty bool
|
||||
layoutDirty bool
|
||||
|
||||
bounds image.Rectangle
|
||||
minWidth int
|
||||
minHeight int
|
||||
bounds image.Rectangle
|
||||
clippedBounds image.Rectangle
|
||||
minWidth int
|
||||
minHeight int
|
||||
|
||||
layoutInvalid bool
|
||||
isContainer bool
|
||||
}
|
||||
|
||||
func bind (element tomo.Element) *entity {
|
||||
entity := &entity { drawDirty: true }
|
||||
func bind (parent *entity, window *window, element tomo.Element) *entity {
|
||||
entity := &entity {
|
||||
window: window,
|
||||
parent: parent,
|
||||
element: element,
|
||||
}
|
||||
entity.Invalidate()
|
||||
if _, ok := element.(tomo.Container); ok {
|
||||
entity.layoutDirty = true
|
||||
entity.isContainer = true
|
||||
entity.InvalidateLayout()
|
||||
}
|
||||
|
||||
element.Bind(entity)
|
||||
@ -38,7 +45,8 @@ func (entity *entity) unbind () {
|
||||
// ----------- Entity ----------- //
|
||||
|
||||
func (entity *entity) Invalidate () {
|
||||
entity.drawDirty = true
|
||||
if entity.window.system.invalidateIgnore { return }
|
||||
entity.window.drawingInvalid.Add(entity)
|
||||
}
|
||||
|
||||
func (entity *entity) Bounds () image.Rectangle {
|
||||
@ -64,18 +72,20 @@ func (entity *entity) DrawBackground (destination canvas.Canvas, bounds image.Re
|
||||
// ----------- ContainerEntity ----------- //
|
||||
|
||||
func (entity *entity) InvalidateLayout () {
|
||||
entity.layoutDirty = true
|
||||
if !entity.isContainer { return }
|
||||
entity.layoutInvalid = true
|
||||
entity.window.system.anyLayoutInvalid = true
|
||||
}
|
||||
|
||||
func (entity *entity) Adopt (child tomo.Element) {
|
||||
entity.children = append(entity.children, bind(child))
|
||||
entity.children = append(entity.children, bind(entity, entity.window, child))
|
||||
}
|
||||
|
||||
func (entity *entity) Insert (index int, child tomo.Element) {
|
||||
entity.children = append (
|
||||
entity.children[:index + 1],
|
||||
entity.children[index:]...)
|
||||
entity.children[index] = bind(child)
|
||||
entity.children[index] = bind(entity, entity.window, child)
|
||||
}
|
||||
|
||||
func (entity *entity) Disown (index int) {
|
||||
@ -104,7 +114,13 @@ func (entity *entity) CountChildren () int {
|
||||
}
|
||||
|
||||
func (entity *entity) PlaceChild (index int, bounds image.Rectangle) {
|
||||
entity.children[index].bounds = bounds
|
||||
child := entity.children[index]
|
||||
child.bounds = bounds
|
||||
child.clippedBounds = entity.bounds.Intersect(bounds)
|
||||
child.Invalidate()
|
||||
if child.isContainer {
|
||||
child.InvalidateLayout()
|
||||
}
|
||||
}
|
||||
|
||||
func (entity *entity) ChildMinimumSize (index int) (width, height int) {
|
||||
|
@ -41,7 +41,6 @@ func (sum *scrollSum) add (button xproto.Button, window *window, state uint16) {
|
||||
sum.x += scrollDistance
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (window *window) handleExpose (
|
||||
@ -49,6 +48,7 @@ func (window *window) handleExpose (
|
||||
event xevent.ExposeEvent,
|
||||
) {
|
||||
_, region := window.compressExpose(*event.ExposeEvent)
|
||||
window.system.afterEvent()
|
||||
window.pushRegion(region)
|
||||
}
|
||||
|
||||
@ -74,7 +74,6 @@ func (window *window) handleConfigureNotify (
|
||||
window.updateBounds (
|
||||
configureEvent.X, configureEvent.Y,
|
||||
configureEvent.Width, configureEvent.Height)
|
||||
|
||||
|
||||
if sizeChanged {
|
||||
configureEvent = window.compressConfigureNotify(configureEvent)
|
||||
@ -85,8 +84,11 @@ func (window *window) handleConfigureNotify (
|
||||
window.resizeChildToFit()
|
||||
|
||||
if !window.exposeEventFollows(configureEvent) {
|
||||
window.redrawChildEntirely()
|
||||
window.child.Invalidate()
|
||||
window.child.InvalidateLayout()
|
||||
}
|
||||
|
||||
window.system.afterEvent()
|
||||
}
|
||||
}
|
||||
|
||||
@ -136,21 +138,21 @@ func (window *window) handleKeyPress (
|
||||
modifiers.NumberPad = numberPad
|
||||
|
||||
if key == input.KeyTab && modifiers.Alt {
|
||||
if child, ok := window.child.(tomo.Focusable); ok {
|
||||
direction := input.KeynavDirectionForward
|
||||
if modifiers.Shift {
|
||||
direction = input.KeynavDirectionBackward
|
||||
}
|
||||
|
||||
if !child.HandleFocus(direction) {
|
||||
child.HandleUnfocus()
|
||||
}
|
||||
}
|
||||
// if child, ok := window.child.element.(tomo.Focusable); ok {
|
||||
// direction := input.KeynavDirectionForward
|
||||
// if modifiers.Shift {
|
||||
// direction = input.KeynavDirectionBackward
|
||||
// }
|
||||
//
|
||||
// // TODO
|
||||
// }
|
||||
} else if key == input.KeyEscape && window.shy {
|
||||
window.Close()
|
||||
} else if child, ok := window.child.(tomo.KeyboardTarget); ok {
|
||||
} else if child, ok := window.child.element.(tomo.KeyboardTarget); ok {
|
||||
child.HandleKeyDown(key, modifiers)
|
||||
}
|
||||
|
||||
window.system.afterEvent()
|
||||
}
|
||||
|
||||
func (window *window) handleKeyRelease (
|
||||
@ -182,9 +184,11 @@ func (window *window) handleKeyRelease (
|
||||
modifiers := window.modifiersFromState(keyEvent.State)
|
||||
modifiers.NumberPad = numberPad
|
||||
|
||||
if child, ok := window.child.(tomo.KeyboardTarget); ok {
|
||||
if child, ok := window.child.element.(tomo.KeyboardTarget); ok {
|
||||
child.HandleKeyUp(key, modifiers)
|
||||
}
|
||||
|
||||
window.system.afterEvent()
|
||||
}
|
||||
|
||||
func (window *window) handleButtonPress (
|
||||
@ -205,7 +209,7 @@ func (window *window) handleButtonPress (
|
||||
if !insideWindow && window.shy && !scrolling {
|
||||
window.Close()
|
||||
} else if scrolling {
|
||||
if child, ok := window.child.(tomo.ScrollTarget); ok {
|
||||
if child, ok := window.child.element.(tomo.ScrollTarget); ok {
|
||||
sum := scrollSum { }
|
||||
sum.add(buttonEvent.Detail, window, buttonEvent.State)
|
||||
window.compressScrollSum(buttonEvent, &sum)
|
||||
@ -215,7 +219,7 @@ func (window *window) handleButtonPress (
|
||||
float64(sum.x), float64(sum.y))
|
||||
}
|
||||
} else {
|
||||
if child, ok := window.child.(tomo.MouseTarget); ok {
|
||||
if child, ok := window.child.element.(tomo.MouseTarget); ok {
|
||||
child.HandleMouseDown (
|
||||
int(buttonEvent.EventX),
|
||||
int(buttonEvent.EventY),
|
||||
@ -223,6 +227,7 @@ func (window *window) handleButtonPress (
|
||||
}
|
||||
}
|
||||
|
||||
window.system.afterEvent()
|
||||
}
|
||||
|
||||
func (window *window) handleButtonRelease (
|
||||
@ -231,7 +236,7 @@ func (window *window) handleButtonRelease (
|
||||
) {
|
||||
if window.child == nil { return }
|
||||
|
||||
if child, ok := window.child.(tomo.MouseTarget); ok {
|
||||
if child, ok := window.child.element.(tomo.MouseTarget); ok {
|
||||
buttonEvent := *event.ButtonReleaseEvent
|
||||
if buttonEvent.Detail >= 4 && buttonEvent.Detail <= 7 { return }
|
||||
child.HandleMouseUp (
|
||||
@ -239,6 +244,8 @@ func (window *window) handleButtonRelease (
|
||||
int(buttonEvent.EventY),
|
||||
input.Button(buttonEvent.Detail))
|
||||
}
|
||||
|
||||
window.system.afterEvent()
|
||||
}
|
||||
|
||||
func (window *window) handleMotionNotify (
|
||||
@ -247,12 +254,14 @@ func (window *window) handleMotionNotify (
|
||||
) {
|
||||
if window.child == nil { return }
|
||||
|
||||
if child, ok := window.child.(tomo.MotionTarget); ok {
|
||||
if child, ok := window.child.element.(tomo.MotionTarget); ok {
|
||||
motionEvent := window.compressMotionNotify(*event.MotionNotifyEvent)
|
||||
child.HandleMotion (
|
||||
int(motionEvent.EventX),
|
||||
int(motionEvent.EventY))
|
||||
}
|
||||
|
||||
window.system.afterEvent()
|
||||
}
|
||||
|
||||
func (window *window) handleSelectionNotify (
|
||||
|
109
backends/x/system.go
Normal file
109
backends/x/system.go
Normal file
@ -0,0 +1,109 @@
|
||||
package x
|
||||
|
||||
import "image"
|
||||
import "git.tebibyte.media/sashakoshka/tomo"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/canvas"
|
||||
|
||||
type entitySet map[*entity] struct { }
|
||||
|
||||
func (set entitySet) Empty () bool {
|
||||
return len(set) == 0
|
||||
}
|
||||
|
||||
func (set entitySet) Has (entity *entity) bool {
|
||||
_, ok := set[entity]
|
||||
return ok
|
||||
}
|
||||
|
||||
func (set entitySet) Add (entity *entity) {
|
||||
set[entity] = struct { } { }
|
||||
}
|
||||
|
||||
type system struct {
|
||||
child *entity
|
||||
focused *entity
|
||||
canvas canvas.BasicCanvas
|
||||
|
||||
theme tomo.Theme
|
||||
config tomo.Config
|
||||
|
||||
invalidateIgnore bool
|
||||
drawingInvalid entitySet
|
||||
anyLayoutInvalid bool
|
||||
|
||||
pushFunc func (image.Rectangle)
|
||||
}
|
||||
|
||||
func (system *system) initialize () {
|
||||
system.drawingInvalid = make(entitySet)
|
||||
}
|
||||
|
||||
func (system *system) SetTheme (theme tomo.Theme) {
|
||||
system.theme = theme
|
||||
if system.child == nil { return }
|
||||
if child, ok := system.child.element.(tomo.Themeable); ok {
|
||||
child.SetTheme(theme)
|
||||
}
|
||||
}
|
||||
|
||||
func (system *system) SetConfig (config tomo.Config) {
|
||||
system.config = config
|
||||
if system.child == nil { return }
|
||||
if child, ok := system.child.element.(tomo.Configurable); ok {
|
||||
child.SetConfig(config)
|
||||
}
|
||||
}
|
||||
|
||||
func (system *system) resizeChildToFit () {
|
||||
system.child.bounds = system.canvas.Bounds()
|
||||
system.child.clippedBounds = system.child.bounds
|
||||
system.child.Invalidate()
|
||||
if system.child.isContainer {
|
||||
system.child.InvalidateLayout()
|
||||
}
|
||||
}
|
||||
|
||||
func (system *system) afterEvent () {
|
||||
if system.anyLayoutInvalid {
|
||||
system.layout(system.child, false)
|
||||
system.anyLayoutInvalid = false
|
||||
}
|
||||
system.draw()
|
||||
}
|
||||
|
||||
func (system *system) layout (entity *entity, force bool) {
|
||||
if entity == nil { return }
|
||||
if entity.layoutInvalid == true || force {
|
||||
entity.element.(tomo.Container).Layout()
|
||||
entity.layoutInvalid = false
|
||||
force = true
|
||||
}
|
||||
|
||||
for _, child := range entity.children {
|
||||
system.layout(child, force)
|
||||
}
|
||||
}
|
||||
|
||||
func (system *system) draw () {
|
||||
finalBounds := image.Rectangle { }
|
||||
|
||||
// ignore invalidations that result from drawing elements, because if an
|
||||
// element decides to do that it really needs to rethink its life
|
||||
// choices.
|
||||
system.invalidateIgnore = true
|
||||
defer func () { system.invalidateIgnore = false } ()
|
||||
|
||||
for entity := range system.drawingInvalid {
|
||||
entity.element.Draw (canvas.Cut (
|
||||
system.canvas,
|
||||
entity.clippedBounds))
|
||||
finalBounds = finalBounds.Union(entity.clippedBounds)
|
||||
}
|
||||
system.drawingInvalid = make(entitySet)
|
||||
|
||||
// TODO: don't just union all the bounds together, we can definetly
|
||||
// consolidateupdated regions more efficiently than this.
|
||||
if !finalBounds.Empty() {
|
||||
system.pushFunc(finalBounds)
|
||||
}
|
||||
}
|
@ -13,20 +13,16 @@ import "github.com/jezek/xgbutil/mousebind"
|
||||
import "github.com/jezek/xgbutil/xgraphics"
|
||||
import "git.tebibyte.media/sashakoshka/tomo"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/data"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/input"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/canvas"
|
||||
// import "runtime/debug"
|
||||
|
||||
type mainWindow struct { *window }
|
||||
type menuWindow struct { *window }
|
||||
type window struct {
|
||||
system
|
||||
|
||||
backend *Backend
|
||||
xWindow *xwindow.Window
|
||||
xCanvas *xgraphics.Image
|
||||
canvas canvas.BasicCanvas
|
||||
child *entity
|
||||
focused *entity
|
||||
onClose func ()
|
||||
|
||||
title, application string
|
||||
|
||||
@ -34,15 +30,14 @@ type window struct {
|
||||
hasModal bool
|
||||
shy bool
|
||||
|
||||
theme tomo.Theme
|
||||
config tomo.Config
|
||||
|
||||
selectionRequest *selectionRequest
|
||||
selectionClaim *selectionClaim
|
||||
|
||||
metrics struct {
|
||||
bounds image.Rectangle
|
||||
}
|
||||
|
||||
onClose func ()
|
||||
}
|
||||
|
||||
func (backend *Backend) NewWindow (
|
||||
@ -53,6 +48,10 @@ func (backend *Backend) NewWindow (
|
||||
) {
|
||||
if backend == nil { panic("nil backend") }
|
||||
window, err := backend.newWindow(bounds, false)
|
||||
|
||||
window.system.initialize()
|
||||
window.system.pushFunc = window.paste
|
||||
|
||||
output = mainWindow { window }
|
||||
return output, err
|
||||
}
|
||||
@ -136,69 +135,24 @@ func (backend *Backend) newWindow (
|
||||
return
|
||||
}
|
||||
|
||||
func (window *window) NotifyMinimumSizeChange (child tomo.Element) {
|
||||
window.childMinimumSizeChangeCallback(child.MinimumSize())
|
||||
}
|
||||
|
||||
func (window *window) Window () tomo.Window {
|
||||
return window
|
||||
}
|
||||
|
||||
func (window *window) RequestFocus (
|
||||
child tomo.Focusable,
|
||||
) (
|
||||
granted bool,
|
||||
) {
|
||||
return true
|
||||
}
|
||||
|
||||
func (window *window) RequestFocusNext (child tomo.Focusable) {
|
||||
if child, ok := window.child.(tomo.Focusable); ok {
|
||||
if !child.HandleFocus(input.KeynavDirectionForward) {
|
||||
child.HandleUnfocus()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (window *window) RequestFocusPrevious (child tomo.Focusable) {
|
||||
if child, ok := window.child.(tomo.Focusable); ok {
|
||||
if !child.HandleFocus(input.KeynavDirectionBackward) {
|
||||
child.HandleUnfocus()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (window *window) Adopt (child tomo.Element) {
|
||||
// disown previous child
|
||||
if window.child != nil {
|
||||
window.child.SetParent(nil)
|
||||
window.child.DrawTo(nil, image.Rectangle { }, nil)
|
||||
window.child.unbind()
|
||||
window.child = nil
|
||||
}
|
||||
|
||||
// adopt new child
|
||||
if child != nil {
|
||||
// adopt new child
|
||||
window.child = child
|
||||
child.SetParent(window)
|
||||
if newChild, ok := child.(tomo.Themeable); ok {
|
||||
newChild.SetTheme(window.theme)
|
||||
}
|
||||
if newChild, ok := child.(tomo.Configurable); ok {
|
||||
newChild.SetConfig(window.config)
|
||||
}
|
||||
if child != nil {
|
||||
if !window.childMinimumSizeChangeCallback(child.MinimumSize()) {
|
||||
window.resizeChildToFit()
|
||||
window.redrawChildEntirely()
|
||||
}
|
||||
}
|
||||
window.child = bind(nil, window, child)
|
||||
window.resizeChildToFit()
|
||||
}
|
||||
}
|
||||
|
||||
func (window *window) Child () (child tomo.Element) {
|
||||
child = window.child
|
||||
return
|
||||
}
|
||||
|
||||
func (window *window) SetTitle (title string) {
|
||||
window.title = title
|
||||
ewmh.WmNameSet (
|
||||
@ -317,43 +271,6 @@ func (window menuWindow) Pin () {
|
||||
// TODO iungrab keyboard and mouse
|
||||
}
|
||||
|
||||
func (window *window) grabInput () {
|
||||
keybind.GrabKeyboard(window.backend.connection, window.xWindow.Id)
|
||||
mousebind.GrabPointer (
|
||||
window.backend.connection,
|
||||
window.xWindow.Id,
|
||||
window.backend.connection.RootWin(), 0)
|
||||
}
|
||||
|
||||
func (window *window) ungrabInput () {
|
||||
keybind.UngrabKeyboard(window.backend.connection)
|
||||
mousebind.UngrabPointer(window.backend.connection)
|
||||
}
|
||||
|
||||
func (window *window) inheritProperties (parent *window) {
|
||||
window.SetApplicationName(parent.application)
|
||||
}
|
||||
|
||||
func (window *window) setType (ty string) error {
|
||||
return ewmh.WmWindowTypeSet (
|
||||
window.backend.connection,
|
||||
window.xWindow.Id,
|
||||
[]string { "_NET_WM_WINDOW_TYPE_" + ty })
|
||||
}
|
||||
|
||||
func (window *window) setClientLeader (leader *window) error {
|
||||
hints, _ := icccm.WmHintsGet(window.backend.connection, window.xWindow.Id)
|
||||
if hints == nil {
|
||||
hints = &icccm.Hints { }
|
||||
}
|
||||
hints.Flags |= icccm.HintWindowGroup
|
||||
hints.WindowGroup = leader.xWindow.Id
|
||||
return icccm.WmHintsSet (
|
||||
window.backend.connection,
|
||||
window.xWindow.Id,
|
||||
hints)
|
||||
}
|
||||
|
||||
func (window *window) Show () {
|
||||
if window.child == nil {
|
||||
window.xCanvas.For (func (x, y int) xgraphics.BGRA {
|
||||
@ -362,7 +279,7 @@ func (window *window) Show () {
|
||||
|
||||
window.pushRegion(window.xCanvas.Bounds())
|
||||
}
|
||||
|
||||
|
||||
window.xWindow.Map()
|
||||
if window.shy { window.grabInput() }
|
||||
}
|
||||
@ -417,18 +334,41 @@ func (window *window) OnClose (callback func ()) {
|
||||
window.onClose = callback
|
||||
}
|
||||
|
||||
func (window *window) SetTheme (theme tomo.Theme) {
|
||||
window.theme = theme
|
||||
if child, ok := window.child.(tomo.Themeable); ok {
|
||||
child.SetTheme(theme)
|
||||
}
|
||||
func (window *window) grabInput () {
|
||||
keybind.GrabKeyboard(window.backend.connection, window.xWindow.Id)
|
||||
mousebind.GrabPointer (
|
||||
window.backend.connection,
|
||||
window.xWindow.Id,
|
||||
window.backend.connection.RootWin(), 0)
|
||||
}
|
||||
|
||||
func (window *window) SetConfig (config tomo.Config) {
|
||||
window.config = config
|
||||
if child, ok := window.child.(tomo.Configurable); ok {
|
||||
child.SetConfig(config)
|
||||
func (window *window) ungrabInput () {
|
||||
keybind.UngrabKeyboard(window.backend.connection)
|
||||
mousebind.UngrabPointer(window.backend.connection)
|
||||
}
|
||||
|
||||
func (window *window) inheritProperties (parent *window) {
|
||||
window.SetApplicationName(parent.application)
|
||||
}
|
||||
|
||||
func (window *window) setType (ty string) error {
|
||||
return ewmh.WmWindowTypeSet (
|
||||
window.backend.connection,
|
||||
window.xWindow.Id,
|
||||
[]string { "_NET_WM_WINDOW_TYPE_" + ty })
|
||||
}
|
||||
|
||||
func (window *window) setClientLeader (leader *window) error {
|
||||
hints, _ := icccm.WmHintsGet(window.backend.connection, window.xWindow.Id)
|
||||
if hints == nil {
|
||||
hints = &icccm.Hints { }
|
||||
}
|
||||
hints.Flags |= icccm.HintWindowGroup
|
||||
hints.WindowGroup = leader.xWindow.Id
|
||||
return icccm.WmHintsSet (
|
||||
window.backend.connection,
|
||||
window.xWindow.Id,
|
||||
hints)
|
||||
}
|
||||
|
||||
func (window *window) reallocateCanvas () {
|
||||
@ -464,26 +404,6 @@ func (window *window) reallocateCanvas () {
|
||||
|
||||
}
|
||||
|
||||
func (window *window) redrawChildEntirely () {
|
||||
window.paste(window.canvas.Bounds())
|
||||
window.pushRegion(window.canvas.Bounds())
|
||||
}
|
||||
|
||||
func (window *window) resizeChildToFit () {
|
||||
window.skipChildDrawCallback = true
|
||||
window.child.DrawTo (
|
||||
window.canvas,
|
||||
window.canvas.Bounds(),
|
||||
window.childDrawCallback)
|
||||
window.skipChildDrawCallback = false
|
||||
}
|
||||
|
||||
func (window *window) childDrawCallback (region image.Rectangle) {
|
||||
if window.skipChildDrawCallback { return }
|
||||
window.paste(region)
|
||||
window.pushRegion(region)
|
||||
}
|
||||
|
||||
func (window *window) paste (region image.Rectangle) {
|
||||
canvas := canvas.Cut(window.canvas, region)
|
||||
data, stride := canvas.Buffer()
|
||||
@ -492,7 +412,6 @@ func (window *window) paste (region image.Rectangle) {
|
||||
dstStride := window.xCanvas.Stride
|
||||
dstData := window.xCanvas.Pix
|
||||
|
||||
// debug.PrintStack()
|
||||
for y := bounds.Min.Y; y < bounds.Max.Y; y ++ {
|
||||
srcYComponent := y * stride
|
||||
dstYComponent := y * dstStride
|
||||
@ -507,6 +426,18 @@ func (window *window) paste (region image.Rectangle) {
|
||||
}
|
||||
}
|
||||
|
||||
func (window *window) pushRegion (region image.Rectangle) {
|
||||
if window.xCanvas == nil { panic("whoopsie!!!!!!!!!!!!!!") }
|
||||
image, ok := window.xCanvas.SubImage(region).(*xgraphics.Image)
|
||||
if ok {
|
||||
image.XDraw()
|
||||
image.XExpPaint (
|
||||
window.xWindow.Id,
|
||||
image.Bounds().Min.X,
|
||||
image.Bounds().Min.Y)
|
||||
}
|
||||
}
|
||||
|
||||
func (window *window) childMinimumSizeChangeCallback (width, height int) (resized bool) {
|
||||
icccm.WmNormalHintsSet (
|
||||
window.backend.connection,
|
||||
@ -528,15 +459,3 @@ func (window *window) childMinimumSizeChangeCallback (width, height int) (resize
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (window *window) pushRegion (region image.Rectangle) {
|
||||
if window.xCanvas == nil { panic("whoopsie!!!!!!!!!!!!!!") }
|
||||
image, ok := window.xCanvas.SubImage(region).(*xgraphics.Image)
|
||||
if ok {
|
||||
image.XDraw()
|
||||
image.XExpPaint (
|
||||
window.xWindow.Id,
|
||||
image.Bounds().Min.X,
|
||||
image.Bounds().Min.Y)
|
||||
}
|
||||
}
|
||||
|
@ -67,6 +67,9 @@ func (backend *Backend) Run () (err error) {
|
||||
<- pingAfter
|
||||
case callback := <- backend.doChannel:
|
||||
callback()
|
||||
for _, window := range backend.windows {
|
||||
window.system.afterEvent()
|
||||
}
|
||||
case <- pingQuit:
|
||||
return
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ func NewArtist () *Artist {
|
||||
|
||||
func (element *Artist) Bind (entity tomo.Entity) {
|
||||
element.entity = entity
|
||||
entity.SetMinimumSize(240, 240)
|
||||
if entity != nil { entity.SetMinimumSize(240, 240) }
|
||||
}
|
||||
|
||||
func (element *Artist) Draw (destination canvas.Canvas) {
|
||||
|
@ -15,9 +15,6 @@ type Window interface {
|
||||
// these at one time.
|
||||
Adopt (Element)
|
||||
|
||||
// Child returns the root element of the window.
|
||||
Child () Element
|
||||
|
||||
// SetTitle sets the title that appears on the window's title bar. This
|
||||
// method might have no effect with some backends.
|
||||
SetTitle (string)
|
||||
|
Reference in New Issue
Block a user