github.com/Kintar/etxt@v0.0.0-20221224033739-2fc69f000137/examples/ebiten/select_rect_viz/main.go (about)

     1  package main
     2  
     3  import "image"
     4  import "os"
     5  import "image/color"
     6  import "log"
     7  import "fmt"
     8  
     9  import "github.com/hajimehoshi/ebiten/v2"
    10  import "github.com/Kintar/etxt"
    11  
    12  // This example allows you to interactively write text in an Ebitengine
    13  // program and see how the SelectionRect for the text changes. You
    14  // can use backspace to remove characters, and enter to create line
    15  // breaks.
    16  
    17  type Game struct {
    18  	txtRenderer         *etxt.Renderer
    19  	sinceLastSpecialKey int
    20  	text                []rune
    21  }
    22  
    23  func (self *Game) Layout(w int, h int) (int, int) {
    24  	scale := ebiten.DeviceScaleFactor()
    25  	return int(float64(w) * scale), int(float64(h) * scale)
    26  }
    27  func (self *Game) Update() error {
    28  	backspacePressed := ebiten.IsKeyPressed(ebiten.KeyBackspace)
    29  	enterPressed := ebiten.IsKeyPressed(ebiten.KeyEnter)
    30  
    31  	if backspacePressed && self.sinceLastSpecialKey >= 7 && len(self.text) >= 1 {
    32  		self.sinceLastSpecialKey = 0
    33  		self.text = self.text[0 : len(self.text)-1]
    34  	} else if enterPressed && self.sinceLastSpecialKey >= 20 {
    35  		self.sinceLastSpecialKey = 0
    36  		self.text = append(self.text, '\n')
    37  	} else {
    38  		self.sinceLastSpecialKey += 1
    39  		self.text = ebiten.AppendInputChars(self.text)
    40  	}
    41  
    42  	return nil
    43  }
    44  
    45  func (self *Game) Draw(screen *ebiten.Image) {
    46  	// dark background
    47  	screen.Fill(color.RGBA{2, 1, 0, 255})
    48  
    49  	// draw text's selection rect
    50  	x, y := 8, 8
    51  	rect := self.txtRenderer.SelectionRect(string(self.text)).ImageRect()
    52  	rectImg := screen.SubImage(rect.Add(image.Pt(x, y))).(*ebiten.Image)
    53  	rectImg.Fill(color.RGBA{8, 72, 88, 255})
    54  
    55  	// draw text
    56  	self.txtRenderer.SetTarget(screen)
    57  	self.txtRenderer.Draw(string(self.text), x, y)
    58  
    59  	// draw fps and other info for fun
    60  	self.txtRenderer.SetAlign(etxt.Bottom, etxt.Right)
    61  	w, h := screen.Size()
    62  	info := fmt.Sprintf("%d glyphs - %.2fFPS", len(self.text), ebiten.CurrentFPS())
    63  	self.txtRenderer.Draw(info, w-2, h-2)
    64  	self.txtRenderer.SetAlign(etxt.Top, etxt.Left)
    65  }
    66  
    67  func main() {
    68  	// get font path
    69  	if len(os.Args) != 2 {
    70  		msg := "Usage: expects one argument with the path to the font to be used\n"
    71  		fmt.Fprint(os.Stderr, msg)
    72  		os.Exit(1)
    73  	}
    74  
    75  	// parse font
    76  	font, fontName, err := etxt.ParseFontFrom(os.Args[1])
    77  	if err != nil {
    78  		log.Fatal(err)
    79  	}
    80  	fmt.Printf("Font loaded: %s\n", fontName)
    81  
    82  	// create cache
    83  	cache := etxt.NewDefaultCache(1024 * 1024 * 1024) // 1GB cache
    84  
    85  	// create and configure renderer
    86  	scale := ebiten.DeviceScaleFactor()
    87  	renderer := etxt.NewStdRenderer()
    88  	renderer.SetCacheHandler(cache.NewHandler())
    89  	renderer.SetSizePx(int(18 * scale))
    90  	renderer.SetFont(font)
    91  	renderer.SetAlign(etxt.Top, etxt.Left)
    92  	renderer.SetColor(color.RGBA{255, 255, 255, 255}) // white
    93  
    94  	// run the game
    95  	ebiten.SetWindowTitle("etxt/examples/ebiten/select_rect_viz")
    96  	ebiten.SetWindowSize(640, 480)
    97  	err = ebiten.RunGame(&Game{renderer, 0, []rune("Interactive text")})
    98  	if err != nil {
    99  		log.Fatal(err)
   100  	}
   101  }