Added mouse button press input
This commit is contained in:
		
							parent
							
								
									47ee6545cb
								
							
						
					
					
						commit
						48510db209
					
				
							
								
								
									
										133
									
								
								backends/x/x.go
									
									
									
									
									
								
							
							
						
						
									
										133
									
								
								backends/x/x.go
									
									
									
									
									
								
							| @ -1,6 +1,7 @@ | ||||
| package x | ||||
| 
 | ||||
| import "os" | ||||
| // import "fmt" | ||||
| import "sync" | ||||
| import "image" | ||||
| 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/basicfont" | ||||
| 
 | ||||
| import "github.com/jezek/xgb" | ||||
| // import "github.com/jezek/xgb" | ||||
| import "github.com/jezek/xgbutil" | ||||
| import "github.com/jezek/xgb/xproto" | ||||
| import "github.com/jezek/xgbutil/ewmh" | ||||
| @ -31,12 +32,6 @@ type Backend struct { | ||||
| 
 | ||||
| 	drawLock sync.Mutex | ||||
| 
 | ||||
| 	ping struct { | ||||
| 		before chan(struct { }) | ||||
| 		after  chan(struct { }) | ||||
| 		quit   chan(struct { }) | ||||
| 	} | ||||
| 
 | ||||
| 	font struct { | ||||
| 		face font.Face | ||||
| 	} | ||||
| @ -62,30 +57,8 @@ type Backend struct { | ||||
| 
 | ||||
| func (backend *Backend) Run (channel chan(stone.Event)) { | ||||
| 	backend.channel = channel | ||||
| 	 | ||||
| 	for { | ||||
| 		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 | ||||
| 		} | ||||
| 	} | ||||
| 	xevent.Main(backend.connection) | ||||
| 	backend.shutDown() | ||||
| } | ||||
| 
 | ||||
| func (backend *Backend) Draw () { | ||||
| @ -104,10 +77,6 @@ func (backend *Backend) Draw () { | ||||
| 		backend.canvas.XDraw() | ||||
| 		backend.canvas.XPaint(backend.window.Id) | ||||
| 	} 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)...) | ||||
| 	} | ||||
| } | ||||
| @ -154,28 +123,44 @@ func (backend *Backend) SetIcon (icons []image.Image) (err error) { | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func (backend *Backend) handleXEvent (event xgb.Event) { | ||||
| 	switch event.(type) { | ||||
| 	case xproto.ConfigureNotifyEvent: | ||||
| 		configureEvent := event.(xproto.ConfigureNotifyEvent) | ||||
| 		 | ||||
| 		newWidth  := int(configureEvent.Width) | ||||
| 		newHeight := int(configureEvent.Height) | ||||
| 		sizeChanged := | ||||
| 			backend.metrics.windowWidth  != newWidth || | ||||
| 			backend.metrics.windowHeight != newHeight | ||||
| 		backend.metrics.windowWidth  = newWidth | ||||
| 		backend.metrics.windowHeight = newHeight | ||||
| func (backend *Backend) handleConfigureNotify ( | ||||
| 	connection *xgbutil.XUtil, | ||||
| 	event xevent.ConfigureNotifyEvent, | ||||
| ) { | ||||
| 	configureEvent := *event.ConfigureNotifyEvent | ||||
| 	 | ||||
| 	newWidth  := int(configureEvent.Width) | ||||
| 	newHeight := int(configureEvent.Height) | ||||
| 	sizeChanged := | ||||
| 		backend.metrics.windowWidth  != newWidth || | ||||
| 		backend.metrics.windowHeight != newHeight | ||||
| 	backend.metrics.windowWidth  = newWidth | ||||
| 	backend.metrics.windowHeight = newHeight | ||||
| 
 | ||||
| 		if sizeChanged { | ||||
| 			configureEvent = | ||||
| 				backend.compressConfigureNotify(configureEvent) | ||||
| 			backend.application.SetSize(backend.calculateBufferSize()) | ||||
| 			backend.channel <- stone.EventResize { } | ||||
| 		} | ||||
| 	if sizeChanged { | ||||
| 		configureEvent = | ||||
| 			backend.compressConfigureNotify(configureEvent) | ||||
| 		backend.application.SetSize(backend.calculateBufferSize()) | ||||
| 		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 ( | ||||
| 	firstEvent xproto.ConfigureNotifyEvent, | ||||
| ) ( | ||||
| @ -253,7 +238,8 @@ func (backend *Backend) drawCells (forceRedraw bool) (areas []image.Rectangle) { | ||||
| 
 | ||||
| 		cell := backend.application.Cell(x, y) | ||||
| 		content := cell.Rune() | ||||
| 		if content < 32 { continue } | ||||
| 
 | ||||
| 		if forceRedraw && content < 32 { continue } | ||||
| 
 | ||||
| 		areas = append(areas, backend.boundsOfCell(x, y)) | ||||
| 		backend.drawRune(x, y, content) | ||||
| @ -269,6 +255,16 @@ func (backend *Backend) drawRune (x, y int, character rune) { | ||||
| 	// TODO: cache these draws as non-transparent buffers with the | ||||
| 	// application background color as the background. that way, we won't | ||||
| 	// need to redraw the characters *or* composite them. | ||||
| 	 | ||||
| 	fillRectangle ( | ||||
| 		&image.Uniform { | ||||
| 			C: backend.config.Color(stone.ColorApplication), | ||||
| 		}, | ||||
| 		backend.canvas, | ||||
| 		backend.boundsOfCell(x, y)) | ||||
| 
 | ||||
| 	if character < 32 { return } | ||||
| 	 | ||||
| 	origin := backend.originOfCell(x, y + 1) | ||||
| 	destinationRectangle, mask, maskPoint, _, _ := backend.font.face.Glyph ( | ||||
| 		fixed.Point26_6 { | ||||
| @ -277,13 +273,6 @@ func (backend *Backend) drawRune (x, y int, character rune) { | ||||
| 		}, | ||||
| 		character) | ||||
| 		 | ||||
| 	fillRectangle ( | ||||
| 		&image.Uniform { | ||||
| 			C: backend.config.Color(stone.ColorApplication), | ||||
| 		}, | ||||
| 		backend.canvas, | ||||
| 		backend.boundsOfCell(x, y)) | ||||
| 		 | ||||
| 	// strokeRectangle ( | ||||
| 		// &image.Uniform { | ||||
| 			// 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, | ||||
| 		0) | ||||
| 	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.SetIcon(application.Icon()) | ||||
| 
 | ||||
| @ -395,10 +393,13 @@ func factory (application *stone.Application) (output stone.Backend, err error) | ||||
| 		backend.shutDown() | ||||
| 	}) | ||||
| 
 | ||||
| 	// start event loop | ||||
| 	backend.ping.before, | ||||
| 	backend.ping.after, | ||||
| 	backend.ping.quit = xevent.MainPing(backend.connection) | ||||
| 	// attatch event handlers | ||||
| 	xevent.ConfigureNotifyFun(backend.handleConfigureNotify). | ||||
| 		Connect(backend.connection, backend.window.Id) | ||||
| 	xevent.ButtonPressFun(backend.handleButtonPress). | ||||
| 		Connect(backend.connection, backend.window.Id) | ||||
| 	xevent.ButtonReleaseFun(backend.handleButtonRelease). | ||||
| 		Connect(backend.connection, backend.window.Id) | ||||
| 	 | ||||
| 	output = backend | ||||
| 	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 | ||||
| 
 | ||||
| // These should be identical to the glfw keys | ||||
| 
 | ||||
| type Button int | ||||
| 
 | ||||
| const ( | ||||
| @ -129,15 +127,22 @@ const ( | ||||
| 	KeyRightSuper   Button = 257 | ||||
| 	KeyMenu         Button = 256 | ||||
| 	 | ||||
| 	MouseButton1      Button = 0 | ||||
| 	MouseButton2      Button = 1 | ||||
| 	MouseButton3      Button = 2 | ||||
| 	MouseButton4      Button = 3 | ||||
| 	MouseButton5      Button = 4 | ||||
| 	MouseButton6      Button = 5 | ||||
| 	MouseButton7      Button = 6 | ||||
| 	MouseButton8      Button = 7 | ||||
| 	MouseButtonLeft   Button = MouseButton1 | ||||
| 	MouseButtonRight  Button = MouseButton2 | ||||
| 	MouseButtonMiddle Button = MouseButton3 | ||||
| 	MouseButton1           Button = 1 | ||||
| 	MouseButton2           Button = 2 | ||||
| 	MouseButton3           Button = 3 | ||||
| 	MouseButton4           Button = 4 | ||||
| 	MouseButton5           Button = 5 | ||||
| 	MouseButton6           Button = 6 | ||||
| 	MouseButton7           Button = 7 | ||||
| 	MouseButton8           Button = 8 | ||||
| 	MouseButton9           Button = 9 | ||||
| 	MouseButtonLeft        Button = MouseButton1 | ||||
| 	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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user