bento

package module
v0.5.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 24, 2023 License: MIT Imports: 23 Imported by: 0

README

Go Reference Build Status

Bento

Demo

An XML based UI builder for Ebiten

It's like HTML/React, but for Ebiten!

  • Support for buttons, text, scrollable paragraphs, text input, and text areas
  • Small but useful set of layout options to build a responsive UI

Screenshot of Page 1 of the Demo Screenshot of Page 2 of the Demo Screenshot of Page 1 in debug mode

package main

import "github.com/etherealmachine/bento"

type Page1 struct {
	Clicks     int
	Paragraphs []string
}

func (p *Page1) Click() {
	p.Clicks++
}

func (p *Page1) Debug(event *bento.Event) {
	event.Box.ToggleDebug()
}

func (p *Page1) UI() string {
	return `<col grow="1" justify="start" margin="24px">
		<text font="NotoSans 24" color="#ffffff" margin="4px" padding="12px" underline="true">
			What is Bento?
		</text>
		<col margin="0 0 0 16px">
			<text font="NotoSans 18" color="#ffffff" margin="4px" padding="12px">
				Bento is a GUI library for Ebiten that puts your UI in a box!
			</text>
			<text font="NotoSans 18" color="#ffffff" margin="4px" padding="12px">
				Bento has support for 9 components, including:
			</text>
			<text font="NotoSans 18" color="#ffffff" margin="4px" padding="12px">
				Text boxes, like this one
			</text>
			<text font="NotoSans 18" color="#ffffff" margin="4px" padding="12px">
				Clickable buttons, with hover, active, and disabled states, and events
			</text>
			<row justify="start center">
				<button onClick="Click" color="#ffffff" margin="12px" padding="12px" btn="button.png 6">Click Me</button>
				<text font="NotoSans 18" color="#ffffff" margin="4px" padding="12px">
					I've been clicked {{ .Clicks }} times
				</text>
			</row>
			<p
					border="frame.png 10"
					font="NotoSans 18"
					color="#ffffff"
					margin="4px"
					padding="16px 24px"
					maxWidth="50em"
					maxHeight="8lh"
					scrollbar="scrollbar.png 6">
It even supports scrollable paragraphs of text!
{{ range .Paragraphs }}
{{ . }}
{{ end }}
			</p>
			<row justify="start center">
				<text font="NotoSans 18" color="#ffffff" margin="4px" padding="12px">
					Check under the hood by enabling debug mode with CTRL-D or by toggling
				</text>
				<button onClick="Debug" color="#ffffff" margin="12px" padding="12px" btn="button.png 6">Debug Mode</button>
			</row>
		</col>
	</col>`
}

Supported Styling

  • Font Name and Size font="NotoSans 24"
  • Font Color color="#ffffff"
  • Margin margin="20px"
  • Padding padding="10px"
  • Underline Text underline="true"
  • minWidth, minHeight, maxWidth, maxHeight
  • Horizontal/Vertical Growth grow="1 2"
  • Horizontal/Vertical Justification justify="start center"
    • start, end, center, evenly, around, between
  • X/Y Offset offset="4 12"
  • Scale (img only) scale="2"

Events and Callbacks

type EventType string

const (
	Click  = EventType("Click")
	Scroll = EventType("Scroll")
	Hover  = EventType("Hover")
	Change = EventType("Change")
	Draw   = EventType("Draw")
	Update = EventType("Update")
)

type Event struct {
	X, Y             int // Mouse position, relative to the current box
	ScrollX, ScrollY float64
	Box              *Box
	Type             EventType
	Image            *ebiten.Image            // Canvas element
	Op               *ebiten.DrawImageOptions // Canvas element
	Value            string                   // Input and Textarea elements
}

onClick is fired on the first click event on a box (mousedown). Any element can register an onClick handler, not just buttons. The X and Y fields of the Event will have the mouse coordinates relative to the top left corner of the box.

onHover is fired if the mouse is over the bounds of the box (including the margin and padding). onHover is NOT fired if the mouse was just clicked (onClick takes precedence).

onChange is fired if when the value of input or textarea element changes, the Value field of the event contains the new value of the element

onUpdate is fired every frame

onDraw is fired on the canvas element. The Image field of the event contains the entire UI image, so the element can overdraw its assigned bounds. The Op field and event.Box.Bounds() is useful to get the current transformation and layout rectangle for the element and restrict drawing to inside this rect.

All handlers may return a boolean as an optimization hint. If the handler returns true, bento will automatically recompute the template and regenerate the UI tree. This is an expensive operation, so handlers should return false if no variables were changed during the callback.

Documentation

Overview

Bento is an XML based UI builder for Ebiten

Index

Constants

View Source
const (
	Click  = EventType("Click")
	Scroll = EventType("Scroll")
	Hover  = EventType("Hover")
	Change = EventType("Change")
	Draw   = EventType("Draw")
	Update = EventType("Update")
)
View Source
const (
	// The items are packed flush to each other toward the start edge of the alignment container in the main axis.
	// [item1 item2              ]
	Start = Justification("start")
	// The items are packed flush to each other toward the end edge of the alignment container in the main axis.
	// [              item1 item2]
	End = Justification("end")
	// The items are packed flush to each other toward the center of the alignment container along the main axis.
	// [       item1 item2       ]
	Center = Justification("center")
	// The items are evenly distributed within the alignment container along the main axis.
	// The spacing between each pair of adjacent items, the main-start edge and the first item, and the main-end edge and the last item, are all exactly the same.
	// [     item1     item2     ]
	Evenly = Justification("evenly")
	// The items are evenly distributed within the alignment container along the main axis.
	// The spacing between each pair of adjacent items is the same.
	// The empty space before the first and after the last item equals half of the space between each pair of adjacent items.
	// [   item1         item2   ]
	Around = Justification("around")
	// The items are evenly distributed within the alignment container along the main axis.
	// The spacing between each pair of adjacent items is the same.
	// The first item is flush with the main-start edge, and the last item is flush with the main-end edge.
	// [item1               item2]
	Between = Justification("between")
)

Variables

This section is empty.

Functions

func ParseButton added in v0.3.1

func ParseButton(spec string) (*[4]*NineSlice, error)

e.g. "button.png 6"

func ParseScrollbar added in v0.3.1

func ParseScrollbar(spec string) (*[3][4]*NineSlice, error)

e.g. "scrollbar.png 6"

Types

type Box

type Box struct {
	Tag       string
	Parent    *Box
	Children  []*Box
	Content   string
	Component Component
	Attrs     map[string]string
	Style     Style
	// contains filtered or unexported fields
}

func Build

func Build(c Component) (*Box, error)

func (*Box) Bounds

func (n *Box) Bounds() image.Rectangle

func (*Box) Draw

func (n *Box) Draw(img *ebiten.Image)

func (*Box) Rebuild added in v0.4.1

func (n *Box) Rebuild() error

func (*Box) String added in v0.4.1

func (n *Box) String() string

func (*Box) ToggleDebug added in v0.4.1

func (n *Box) ToggleDebug()

func (*Box) UnmarshalXML added in v0.3.1

func (n *Box) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

func (*Box) Update

func (n *Box) Update() error

type Component

type Component interface {
	UI() string
}

type Editable added in v0.4.1

type Editable struct {
	// contains filtered or unexported fields
}

func (*Editable) Cursor added in v0.4.1

func (e *Editable) Cursor() int

type Event added in v0.4.1

type Event struct {
	X, Y             int // Mouse position, relative to the current box
	ScrollX, ScrollY float64
	Box              *Box
	Type             EventType
	Image            *ebiten.Image            // Canvas element
	Op               *ebiten.DrawImageOptions // Canvas element
	Value            string                   // Input and Textarea elements
}

type EventType added in v0.4.1

type EventType string

type Justification

type Justification string

func (Justification) Valid added in v0.3.1

func (j Justification) Valid() bool

type NineSlice

type NineSlice struct {
	// contains filtered or unexported fields
}

A NineSlice is an image that can be drawn with any width and height. It is basically a 3x3 grid of image tiles: The corner tiles are drawn as-is, while the center columns and rows of tiles will be stretched to fit the desired width and height.

func NewNineSlice

func NewNineSlice(img *ebiten.Image, widths, heights [3]int, offsetX, offsetY int) *NineSlice

func (*NineSlice) Draw

func (n *NineSlice) Draw(screen *ebiten.Image, x, y, width, height int, op *ebiten.DrawImageOptions)

func (*NineSlice) Height added in v0.3.1

func (n *NineSlice) Height() int

func (*NineSlice) Width added in v0.3.1

func (n *NineSlice) Width() int

type Scrollable added in v0.4.1

type Scrollable struct {
	// contains filtered or unexported fields
}

type Spacing

type Spacing struct {
	Top, Right, Bottom, Left int `xml:",attr,omitempty"`
}

type State added in v0.4.1

type State int

type Style

type Style struct {
	Extends              string
	Attrs                map[string]string
	FontName             string
	FontSize             int
	Font                 font.Face
	Underline            bool
	Border               *NineSlice
	Button               *[4]*NineSlice
	Scrollbar            *[3][4]*NineSlice
	Input                *[4]*NineSlice
	Image                *ebiten.Image
	MinWidth, MinHeight  int
	MaxWidth, MaxHeight  int
	HJust, VJust         Justification
	HJustSelf, VJustSelf Justification
	HGrow, VGrow         int
	Margin, Padding      Spacing
	Color                color.Color
	OffsetX, OffsetY     int
	Float                bool
	Hidden               bool
	Display              bool
	ScaleX, ScaleY       float64
	ZIndex               int
	// contains filtered or unexported fields
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL