Skip to content

Commit

Permalink
InputChars (hajimehoshi#403)
Browse files Browse the repository at this point in the history
This implements hajimehoshi#400
  • Loading branch information
j7b authored and hajimehoshi committed Aug 14, 2017
1 parent 9317350 commit 0d703ca
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 2 deletions.
51 changes: 51 additions & 0 deletions examples/runes/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright 2017 The Ebiten Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// +build example

package main

import (
"log"

"github.com/hajimehoshi/ebiten"
"github.com/hajimehoshi/ebiten/ebitenutil"
)

var runes = append(make([]rune, 0, 1024), []rune("Type on the keyboard:\n")...)

var buf = make([]rune, 1024)

var counter int

func update(screen *ebiten.Image) error {
runes = append(runes, ebiten.InputChars()...)
if ebiten.IsKeyPressed(ebiten.KeyEnter) {
if len(runes) > 0 && runes[len(runes)-1] != '\n' {
runes = append(runes, '\n')
}
}
counter++
if ebiten.IsRunningSlowly() {
return nil
}
if counter%60 < 30 {
return ebitenutil.DebugPrint(screen, string(append(runes, '_')))
}
return ebitenutil.DebugPrint(screen, string(runes))
}

func main() {
log.Fatal(ebiten.Run(update, 320, 240, 2.0, "Runes (Ebiten Demo)")) // ebiterm?
}
14 changes: 14 additions & 0 deletions input.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,20 @@ import (
"github.com/hajimehoshi/ebiten/internal/ui"
)

// InputChars return "printable" runes read from the keyboard at the time update is called.
//
// InputChars represents the environment's locale-dependent translation of keyboard
// input to Unicode characters.
//
// IsKeyPressed is based on a mapping of device codes to input device keys.
// "Control" and modifier keys should be handled with IsKeyPressed.
//
// This function is concurrent-safe.
func InputChars() []rune {
rb := ui.CurrentInput().RuneBuffer()
return append(make([]rune, 0, len(rb)), rb...)
}

// IsKeyPressed returns a boolean indicating whether key is pressed.
//
// This function is concurrent-safe.
Expand Down
19 changes: 18 additions & 1 deletion internal/ui/input_glfw.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ package ui

import (
"sync"
"unicode"

glfw "github.com/go-gl/glfw/v3.2/glfw"
)
Expand All @@ -32,9 +33,16 @@ type Input struct {
cursorY int
gamepads [16]gamePad
touches []touch
runeBuffer []rune
m sync.RWMutex
}

func (i *Input) RuneBuffer() []rune {
i.m.RLock()
defer i.m.RUnlock()
return i.runeBuffer
}

func (i *Input) IsKeyPressed(key Key) bool {
i.m.RLock()
defer i.m.RUnlock()
Expand Down Expand Up @@ -78,7 +86,16 @@ var glfwMouseButtonToMouseButton = map[glfw.MouseButton]MouseButton{
func (i *Input) update(window *glfw.Window, scale float64) {
i.m.Lock()
defer i.m.Unlock()

if i.runeBuffer == nil {
i.runeBuffer = make([]rune, 0, 1024)
window.SetCharModsCallback(func(w *glfw.Window, char rune, mods glfw.ModifierKey) {
if unicode.IsPrint(char) {
i.m.Lock()
i.runeBuffer = append(i.runeBuffer, char)
i.m.Unlock()
}
})
}
if i.keyPressed == nil {
i.keyPressed = map[glfw.Key]bool{}
}
Expand Down
5 changes: 5 additions & 0 deletions internal/ui/input_js.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,14 @@ type Input struct {
cursorY int
gamepads [16]gamePad
touches []touch
runeBuffer []rune
m mockRWLock
}

func (i *Input) RuneBuffer() []rune {
return i.runeBuffer
}

func (i *Input) IsKeyPressed(key Key) bool {
if i.keyPressed != nil {
for _, c := range keyToCodes[key] {
Expand Down
4 changes: 4 additions & 0 deletions internal/ui/input_mobile.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ type Input struct {
m sync.RWMutex
}

func (i *Input) RuneBuffer() []rune {
return nil
}

func (i *Input) IsKeyPressed(key Key) bool {
return false
}
Expand Down
1 change: 1 addition & 0 deletions internal/ui/ui_glfw.go
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,7 @@ func (u *userInterface) update(g GraphicsContext) error {
if err := g.Update(); err != nil {
return err
}
currentInput.runeBuffer = currentInput.runeBuffer[:0]
return nil
}

Expand Down
9 changes: 8 additions & 1 deletion internal/ui/ui_js.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package ui
import (
"strconv"
"strings"
"unicode"

"github.com/gopherjs/gopherjs/js"
"github.com/hajimehoshi/ebiten/internal/opengl"
Expand Down Expand Up @@ -134,6 +135,7 @@ func (u *userInterface) update(g GraphicsContext) error {
if err := g.Update(); err != nil {
return err
}
currentInput.runeBuffer = nil
return nil
}

Expand Down Expand Up @@ -238,7 +240,6 @@ func initialize() error {

// Keyboard
canvas.Call("addEventListener", "keydown", func(e *js.Object) {
e.Call("preventDefault")
if e.Get("code") == js.Undefined {
// Assume that UA is Safari.
code := e.Get("keyCode").Int()
Expand All @@ -248,6 +249,12 @@ func initialize() error {
code := e.Get("code").String()
currentInput.keyDown(code)
})
canvas.Call("addEventListener", "keypress", func(e *js.Object) {
e.Call("preventDefault")
if r := rune(e.Get("charCode").Int()); unicode.IsPrint(r) {
currentInput.runeBuffer = append(currentInput.runeBuffer, r)
}
})
canvas.Call("addEventListener", "keyup", func(e *js.Object) {
e.Call("preventDefault")
if e.Get("code") == js.Undefined {
Expand Down

0 comments on commit 0d703ca

Please sign in to comment.