Added mouse button press input
This commit is contained in:
parent
47ee6545cb
commit
48510db209
131
backends/x/x.go
131
backends/x/x.go
@ -1,6 +1,7 @@
|
|||||||
package x
|
package x
|
||||||
|
|
||||||
import "os"
|
import "os"
|
||||||
|
// import "fmt"
|
||||||
import "sync"
|
import "sync"
|
||||||
import "image"
|
import "image"
|
||||||
import "image/draw"
|
import "image/draw"
|
||||||
@ -9,7 +10,7 @@ import "golang.org/x/image/math/fixed"
|
|||||||
import "golang.org/x/image/font/opentype"
|
import "golang.org/x/image/font/opentype"
|
||||||
import "golang.org/x/image/font/basicfont"
|
import "golang.org/x/image/font/basicfont"
|
||||||
|
|
||||||
import "github.com/jezek/xgb"
|
// import "github.com/jezek/xgb"
|
||||||
import "github.com/jezek/xgbutil"
|
import "github.com/jezek/xgbutil"
|
||||||
import "github.com/jezek/xgb/xproto"
|
import "github.com/jezek/xgb/xproto"
|
||||||
import "github.com/jezek/xgbutil/ewmh"
|
import "github.com/jezek/xgbutil/ewmh"
|
||||||
@ -31,12 +32,6 @@ type Backend struct {
|
|||||||
|
|
||||||
drawLock sync.Mutex
|
drawLock sync.Mutex
|
||||||
|
|
||||||
ping struct {
|
|
||||||
before chan(struct { })
|
|
||||||
after chan(struct { })
|
|
||||||
quit chan(struct { })
|
|
||||||
}
|
|
||||||
|
|
||||||
font struct {
|
font struct {
|
||||||
face font.Face
|
face font.Face
|
||||||
}
|
}
|
||||||
@ -62,30 +57,8 @@ type Backend struct {
|
|||||||
|
|
||||||
func (backend *Backend) Run (channel chan(stone.Event)) {
|
func (backend *Backend) Run (channel chan(stone.Event)) {
|
||||||
backend.channel = channel
|
backend.channel = channel
|
||||||
|
xevent.Main(backend.connection)
|
||||||
for {
|
backend.shutDown()
|
||||||
select {
|
|
||||||
case <- backend.ping.before:
|
|
||||||
// if the queue is empty, don't dequeue anything because
|
|
||||||
// it would cause a fucking segfault lmao (???)
|
|
||||||
if !xevent.Empty(backend.connection) {
|
|
||||||
event, err := xevent.Dequeue(backend.connection)
|
|
||||||
if err != nil {
|
|
||||||
// TODO: do something with err
|
|
||||||
}
|
|
||||||
|
|
||||||
if event != nil {
|
|
||||||
backend.handleXEvent(event)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
<- backend.ping.after
|
|
||||||
|
|
||||||
case <- backend.ping.quit:
|
|
||||||
backend.shutDown()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (backend *Backend) Draw () {
|
func (backend *Backend) Draw () {
|
||||||
@ -104,10 +77,6 @@ func (backend *Backend) Draw () {
|
|||||||
backend.canvas.XDraw()
|
backend.canvas.XDraw()
|
||||||
backend.canvas.XPaint(backend.window.Id)
|
backend.canvas.XPaint(backend.window.Id)
|
||||||
} else {
|
} else {
|
||||||
// backend.drawCells(false)
|
|
||||||
// backend.canvas.XDraw()
|
|
||||||
// backend.canvas.XPaint(backend.window.Id)
|
|
||||||
// FIXME use this instead once it works
|
|
||||||
backend.updateWindowAreas(backend.drawCells(false)...)
|
backend.updateWindowAreas(backend.drawCells(false)...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -154,28 +123,44 @@ func (backend *Backend) SetIcon (icons []image.Image) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (backend *Backend) handleXEvent (event xgb.Event) {
|
func (backend *Backend) handleConfigureNotify (
|
||||||
switch event.(type) {
|
connection *xgbutil.XUtil,
|
||||||
case xproto.ConfigureNotifyEvent:
|
event xevent.ConfigureNotifyEvent,
|
||||||
configureEvent := event.(xproto.ConfigureNotifyEvent)
|
) {
|
||||||
|
configureEvent := *event.ConfigureNotifyEvent
|
||||||
|
|
||||||
newWidth := int(configureEvent.Width)
|
newWidth := int(configureEvent.Width)
|
||||||
newHeight := int(configureEvent.Height)
|
newHeight := int(configureEvent.Height)
|
||||||
sizeChanged :=
|
sizeChanged :=
|
||||||
backend.metrics.windowWidth != newWidth ||
|
backend.metrics.windowWidth != newWidth ||
|
||||||
backend.metrics.windowHeight != newHeight
|
backend.metrics.windowHeight != newHeight
|
||||||
backend.metrics.windowWidth = newWidth
|
backend.metrics.windowWidth = newWidth
|
||||||
backend.metrics.windowHeight = newHeight
|
backend.metrics.windowHeight = newHeight
|
||||||
|
|
||||||
if sizeChanged {
|
if sizeChanged {
|
||||||
configureEvent =
|
configureEvent =
|
||||||
backend.compressConfigureNotify(configureEvent)
|
backend.compressConfigureNotify(configureEvent)
|
||||||
backend.application.SetSize(backend.calculateBufferSize())
|
backend.application.SetSize(backend.calculateBufferSize())
|
||||||
backend.channel <- stone.EventResize { }
|
backend.channel <- stone.EventResize { }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (backend *Backend) handleButtonPress (
|
||||||
|
connection *xgbutil.XUtil,
|
||||||
|
event xevent.ButtonPressEvent,
|
||||||
|
) {
|
||||||
|
buttonEvent := *event.ButtonPressEvent
|
||||||
|
backend.channel <- stone.EventPress(buttonEvent.Detail)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (backend *Backend) handleButtonRelease (
|
||||||
|
connection *xgbutil.XUtil,
|
||||||
|
event xevent.ButtonReleaseEvent,
|
||||||
|
) {
|
||||||
|
buttonEvent := *event.ButtonReleaseEvent
|
||||||
|
backend.channel <- stone.EventRelease(buttonEvent.Detail)
|
||||||
|
}
|
||||||
|
|
||||||
func (backend *Backend) compressConfigureNotify (
|
func (backend *Backend) compressConfigureNotify (
|
||||||
firstEvent xproto.ConfigureNotifyEvent,
|
firstEvent xproto.ConfigureNotifyEvent,
|
||||||
) (
|
) (
|
||||||
@ -253,7 +238,8 @@ func (backend *Backend) drawCells (forceRedraw bool) (areas []image.Rectangle) {
|
|||||||
|
|
||||||
cell := backend.application.Cell(x, y)
|
cell := backend.application.Cell(x, y)
|
||||||
content := cell.Rune()
|
content := cell.Rune()
|
||||||
if content < 32 { continue }
|
|
||||||
|
if forceRedraw && content < 32 { continue }
|
||||||
|
|
||||||
areas = append(areas, backend.boundsOfCell(x, y))
|
areas = append(areas, backend.boundsOfCell(x, y))
|
||||||
backend.drawRune(x, y, content)
|
backend.drawRune(x, y, content)
|
||||||
@ -269,13 +255,6 @@ func (backend *Backend) drawRune (x, y int, character rune) {
|
|||||||
// TODO: cache these draws as non-transparent buffers with the
|
// TODO: cache these draws as non-transparent buffers with the
|
||||||
// application background color as the background. that way, we won't
|
// application background color as the background. that way, we won't
|
||||||
// need to redraw the characters *or* composite them.
|
// need to redraw the characters *or* composite them.
|
||||||
origin := backend.originOfCell(x, y + 1)
|
|
||||||
destinationRectangle, mask, maskPoint, _, _ := backend.font.face.Glyph (
|
|
||||||
fixed.Point26_6 {
|
|
||||||
X: fixed.I(origin.X),
|
|
||||||
Y: fixed.I(origin.Y - backend.metrics.descent),
|
|
||||||
},
|
|
||||||
character)
|
|
||||||
|
|
||||||
fillRectangle (
|
fillRectangle (
|
||||||
&image.Uniform {
|
&image.Uniform {
|
||||||
@ -284,6 +263,16 @@ func (backend *Backend) drawRune (x, y int, character rune) {
|
|||||||
backend.canvas,
|
backend.canvas,
|
||||||
backend.boundsOfCell(x, y))
|
backend.boundsOfCell(x, y))
|
||||||
|
|
||||||
|
if character < 32 { return }
|
||||||
|
|
||||||
|
origin := backend.originOfCell(x, y + 1)
|
||||||
|
destinationRectangle, mask, maskPoint, _, _ := backend.font.face.Glyph (
|
||||||
|
fixed.Point26_6 {
|
||||||
|
X: fixed.I(origin.X),
|
||||||
|
Y: fixed.I(origin.Y - backend.metrics.descent),
|
||||||
|
},
|
||||||
|
character)
|
||||||
|
|
||||||
// strokeRectangle (
|
// strokeRectangle (
|
||||||
// &image.Uniform {
|
// &image.Uniform {
|
||||||
// C: backend.config.Color(stone.ColorForeground),
|
// C: backend.config.Color(stone.ColorForeground),
|
||||||
@ -382,7 +371,16 @@ func factory (application *stone.Application) (output stone.Backend, err error)
|
|||||||
backend.metrics.windowWidth, backend.metrics.windowHeight,
|
backend.metrics.windowWidth, backend.metrics.windowHeight,
|
||||||
0)
|
0)
|
||||||
backend.window.Map()
|
backend.window.Map()
|
||||||
backend.window.Listen(xproto.EventMaskStructureNotify)
|
// TODO: also listen to mouse movement (compressed) and mouse and
|
||||||
|
// keyboard buttons (uncompressed)
|
||||||
|
err = backend.window.Listen (
|
||||||
|
xproto.EventMaskStructureNotify,
|
||||||
|
// xproto.EventMaskPointerMotion,
|
||||||
|
// xproto.EventMaskKeyPress,
|
||||||
|
// xproto.EventMaskKeyRelease,
|
||||||
|
xproto.EventMaskButtonPress,
|
||||||
|
xproto.EventMaskButtonRelease,
|
||||||
|
)
|
||||||
backend.SetTitle(application.Title())
|
backend.SetTitle(application.Title())
|
||||||
backend.SetIcon(application.Icon())
|
backend.SetIcon(application.Icon())
|
||||||
|
|
||||||
@ -395,10 +393,13 @@ func factory (application *stone.Application) (output stone.Backend, err error)
|
|||||||
backend.shutDown()
|
backend.shutDown()
|
||||||
})
|
})
|
||||||
|
|
||||||
// start event loop
|
// attatch event handlers
|
||||||
backend.ping.before,
|
xevent.ConfigureNotifyFun(backend.handleConfigureNotify).
|
||||||
backend.ping.after,
|
Connect(backend.connection, backend.window.Id)
|
||||||
backend.ping.quit = xevent.MainPing(backend.connection)
|
xevent.ButtonPressFun(backend.handleButtonPress).
|
||||||
|
Connect(backend.connection, backend.window.Id)
|
||||||
|
xevent.ButtonReleaseFun(backend.handleButtonRelease).
|
||||||
|
Connect(backend.connection, backend.window.Id)
|
||||||
|
|
||||||
output = backend
|
output = backend
|
||||||
return
|
return
|
||||||
|
65
examples/draw/main.go
Normal file
65
examples/draw/main.go
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "os"
|
||||||
|
import "image"
|
||||||
|
import _ "image/png"
|
||||||
|
import "git.tebibyte.media/sashakoshka/stone"
|
||||||
|
import _ "git.tebibyte.media/sashakoshka/stone/backends/x"
|
||||||
|
|
||||||
|
var application = &stone.Application { }
|
||||||
|
var mousePressed bool
|
||||||
|
|
||||||
|
func main () {
|
||||||
|
application.SetTitle("hellorld")
|
||||||
|
application.SetSize(32, 16)
|
||||||
|
|
||||||
|
iconFile16, err := os.Open("assets/scaffold16.png")
|
||||||
|
if err != nil { panic(err) }
|
||||||
|
icon16, _, err := image.Decode(iconFile16)
|
||||||
|
if err != nil { panic(err) }
|
||||||
|
iconFile16.Close()
|
||||||
|
iconFile32, err := os.Open("assets/scaffold32.png")
|
||||||
|
if err != nil { panic(err) }
|
||||||
|
icon32, _, err := image.Decode(iconFile32)
|
||||||
|
if err != nil { panic(err) }
|
||||||
|
iconFile16.Close()
|
||||||
|
|
||||||
|
application.SetIcon([]image.Image { icon16, icon32 })
|
||||||
|
|
||||||
|
channel, err := application.Run()
|
||||||
|
if err != nil { panic(err) }
|
||||||
|
|
||||||
|
application.Draw()
|
||||||
|
|
||||||
|
for {
|
||||||
|
event := <- channel
|
||||||
|
switch event.(type) {
|
||||||
|
case stone.EventQuit:
|
||||||
|
os.Exit(0)
|
||||||
|
|
||||||
|
case stone.EventPress:
|
||||||
|
event := event.(stone.EventPress)
|
||||||
|
if stone.Button(event) == stone.MouseButtonLeft {
|
||||||
|
mousePressed = true
|
||||||
|
application.SetRune(0, 0, '+')
|
||||||
|
application.Draw()
|
||||||
|
}
|
||||||
|
|
||||||
|
case stone.EventRelease:
|
||||||
|
event := event.(stone.EventRelease)
|
||||||
|
if stone.Button(event) == stone.MouseButtonLeft {
|
||||||
|
mousePressed = false
|
||||||
|
application.SetRune(0, 0, 0)
|
||||||
|
application.Draw()
|
||||||
|
}
|
||||||
|
|
||||||
|
case stone.EventMouseMove:
|
||||||
|
event := event.(stone.EventMouseMove)
|
||||||
|
application.SetRune(event.X, event.Y, '#')
|
||||||
|
application.Draw()
|
||||||
|
|
||||||
|
case stone.EventResize:
|
||||||
|
application.Draw()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
31
input.go
31
input.go
@ -1,7 +1,5 @@
|
|||||||
package stone
|
package stone
|
||||||
|
|
||||||
// These should be identical to the glfw keys
|
|
||||||
|
|
||||||
type Button int
|
type Button int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -129,15 +127,22 @@ const (
|
|||||||
KeyRightSuper Button = 257
|
KeyRightSuper Button = 257
|
||||||
KeyMenu Button = 256
|
KeyMenu Button = 256
|
||||||
|
|
||||||
MouseButton1 Button = 0
|
MouseButton1 Button = 1
|
||||||
MouseButton2 Button = 1
|
MouseButton2 Button = 2
|
||||||
MouseButton3 Button = 2
|
MouseButton3 Button = 3
|
||||||
MouseButton4 Button = 3
|
MouseButton4 Button = 4
|
||||||
MouseButton5 Button = 4
|
MouseButton5 Button = 5
|
||||||
MouseButton6 Button = 5
|
MouseButton6 Button = 6
|
||||||
MouseButton7 Button = 6
|
MouseButton7 Button = 7
|
||||||
MouseButton8 Button = 7
|
MouseButton8 Button = 8
|
||||||
MouseButtonLeft Button = MouseButton1
|
MouseButton9 Button = 9
|
||||||
MouseButtonRight Button = MouseButton2
|
MouseButtonLeft Button = MouseButton1
|
||||||
MouseButtonMiddle Button = MouseButton3
|
MouseButtonMiddle Button = MouseButton2
|
||||||
|
MouseButtonRight Button = MouseButton3
|
||||||
|
MouseButtonScrollUp Button = MouseButton4
|
||||||
|
MouseButtonScrollDown Button = MouseButton5
|
||||||
|
MouseButtonScrollLeft Button = MouseButton6
|
||||||
|
MouseButtonScrollRight Button = MouseButton7
|
||||||
|
MouseButtonBack Button = MouseButton8
|
||||||
|
MouseButtonForward Button = MouseButton9
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user