rebui

package module
v0.0.0-...-0a2a33c Latest Latest
Warning

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

Go to latest
Published: Nov 25, 2025 License: MPL-2.0 Imports: 19 Imported by: 0

README

rebui

Go Reference

rebui is a relatively simple UI library for Ebitengine. It manages UI layout and event handling in a clear and dynamic fashion. It does not seek to directly implement flexbox, grids, or other automatic container-based layout systems, but rather provides a simple-to-use framework to create and use widgets within a shared screen space. However, flexbox or grid-like functionality can be implemented, as the layout engine allows placing widgets relative to one another and/or using percentage-based size and position calculations.

How Does It Look?

A full example of a large red button in the middle of the screen would be:

package main

import (
	"github.com/hajimehoshi/ebiten/v2"
	"github.com/kettek/rebui"
	// Blank import ensures all the default widgets are available.
	_ "github.com/kettek/rebui/widgets"
)

type Game struct {
	layout rebui.Layout
}

func (g *Game) Update() error {
	g.layout.Update()
	return nil
}

func (g *Game) Draw(screen *ebiten.Image) {
	g.layout.Draw(screen)
}

func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
  return outsideWidth, outsideHeight
}

func main() {
	g := &Game{}

	g.layout.AddNode(rebui.Node{
		Type:            "Button",
		Width:           "50%",
		Height:          "50%",
		X:               "50%",
		Y:               "50%",
		OriginX:         "-50%",
		OriginY:         "-50%",
		BackgroundColor: "red",
	})

	ebiten.SetWindowSize(320, 240)

	if err := ebiten.RunGame(g); err != nil {
		log.Fatal(err)
	}
}

Another example with a draggable and resizable custom widget would be:

package main

import (
	"image/color"
	"log"
	"os"

	"github.com/hajimehoshi/ebiten/v2"
	"github.com/kettek/rebui"
	"github.com/kettek/rebui/widgets"
)

type Game struct {
	layout *rebui.Layout
}

func (g *Game) Update() error {
	g.layout.Update()
	return nil
}

func (g *Game) Draw(screen *ebiten.Image) {
	g.layout.Draw(screen)
}

func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
	return outsideWidth, outsideHeight
}

func main() {
	g := &Game{}

	g.layout.AddNode(rebui.Node{
		Type:            "DraggableButton",
		Width:           "25%",
		Height:          "25%",
		X:               "50%",
		Y:               "50%",
		OriginX:         "-50%",
		OriginY:         "-50%",
	})

	ebiten.SetWindowSize(320, 240)

	if err := ebiten.RunGame(g); err != nil {
		log.Fatal(err)
	}
}

type DraggableButton struct {
	widgets.Button
}

func (b *DraggableButton) HandlePointerGlobalMove(evt rebui.EventPointerMove) {
	// left mouse button to drag
	if evt.PointerID == 0 {
		b.X += e.DX
		b.Y += e.DY
	}
	// right mouse button to resize
	if evt.PointerID == 2 {
		b.Width += e.DX
		b.Height += e.DY
	}
}

func init() {
	rebui.RegisterWidget("DraggableButton", &DraggableButton{})
}

For most use-cases, Nodes will not be defined manually, but through an external layout file. The default format is through JSON, but any type of unmarshalling type/process can be used.

Coordinates, Dimensions, and IDs

rebui Nodes can have their coordinates and dimensions specify pixel values, percentage values of their container, or percentage values of another node.

For, example, a JSON layout with 2 buttons next to each other on the x axis, one of which is half the size of the other, would be as follows:

[
  {
    "Type": "Button",
    "ID": "button1",
    "X": "50",
    "Y": "50",
    "Width": "100",
    "Height": "100"
  },
  {
    "Type": "Button",
    "X": "after button1",
    "Y": "at button1",
    "Width": "50% of button1",
    "Height": "50% of button1"
  }
]

Origin

An additional step when determining a Node's position is the OriginX and OriginY values. These values are relative to the dimensions of the node, so to have a node that spawns in the middle of the screen centered about its own middle-point, would be:

{
  "Type": "Button",
  "X": "50%",
  "Y": "50%",
  "OriginX": "-50%",
  "OriginY": "-50%",
  "Width": "100",
  "Height": "100"
}

GetByID

rebui Nodes can be accessed by calling the Layout.GetByID(string) method. This allows one to retrieve the Node which also contains the node.Widget field that can be used to directly access the underlying widget.

node := layout.GetByID("button1")
node.Widget.(*widgets.Button).SetBackgroundColor(color.Black)

Events

rebui Events are sent to Widget handlers or to Node event callbacks.

A custom Widget that receives a pointer pressed event:

type MyButton struct {
	widgets.Button
}

func (b *MyButton) HandlePointerPressed(evt rebui.EventPointerPressed) {
	b.SetBackgroundColor(color.NRGBA{255, 0, 255, 255})
}

A locally scoped Node variable:

node := layout.GetByID("button1")

node.OnPointerPressed = func(evt rebui.EventPointerPressed) {
	node.Widget.(*widgets.Button).SetBackgroundColor(color.NRGBA{255, 0, 255, 255})
}

Or a Widget acquired from the pointer event:

layout.GetByID("button1").OnPointerPressed = func(evt rebui.EventPointerPressed) {
	evt.Widget.(*widgets.Button).SetBackgroundColor(color.NRGBA{255, 0, 255, 255})
}

Documentation

Index

Constants

View Source
const (
	AlignLeft   = style.Left
	AlignCenter = style.Center
	AlignRight  = style.Right
	AlignTop    = style.Top
	AlignMiddle = style.Middle
	AlignBottom = style.Bottom
)

Our alignment types. See style package for more info.

View Source
const (
	WrapNone = style.NoWrap
	WrapWord = style.Word
	WrapRune = style.Rune
)

Our wrapping types. See style package for more info.

View Source
const (
	ImageStretchNone    = style.None
	ImageStretchFill    = style.Fill
	ImageStretchCover   = style.Cover
	ImageStretchNearest = style.Nearest
)

Our image scaling types. See style package for more info.

Variables

View Source
var (
	ErrNoImageLoader    = errors.New("no image loader set")
	ErrNoFontLoader     = errors.New("no font loader set")
	ErrNoTemplateLoader = errors.New("no template loader set")
)

Errors

View Source
var CurrentTheme = style.CurrentTheme

CurrentTheme is an alias for style.CurrentTheme.

View Source
var DefaultTheme = style.DefaultTheme

DefaultTheme is an alias for style.DefaultTheme.

Functions

func LoadFont

func LoadFont(path string) (text.Face, error)

LoadFont loads the given path using the loader set in SetFontLoader.

func LoadImage

func LoadImage(path string) (*ebiten.Image, error)

LoadImage loads the given path using the loader set in SetImageLoader.

func RegisterWidget

func RegisterWidget(name string, el Widget)

RegisterWidget is used to register an Widget for parsing into the passed in type.

func SetFontLoader

func SetFontLoader(loader func(path string) (text.Face, error))

SetFontLoader sets the function to load a font by path.

func SetImageLoader

func SetImageLoader(loader func(path string) (*ebiten.Image, error))

SetImageLoader sets the function to load an image by path.

func SetTemplateLoader

func SetTemplateLoader(loader func(path string) (Nodes, error))

SetTemplateLoader sets the function to load a template by path.

Types

type Alignment

type Alignment = style.Alignment

Alignment is a type alias for style.Alignment.

type AssignerBackgroundColor

type AssignerBackgroundColor = assigners.BackgroundColor

AssignerBackgroundColor is an alias.

type AssignerBorderColor

type AssignerBorderColor = assigners.BorderColor

AssignerBorderColor is an alias.

type AssignerDisable

type AssignerDisable = assigners.Disable

AssignerDisable is an alias.

type AssignerFontFace

type AssignerFontFace = assigners.FontFace

AssignerFontFace is an alias.

type AssignerFontSize

type AssignerFontSize = assigners.FontSize

AssignerFontSize is an alias.

type AssignerForegroundColor

type AssignerForegroundColor = assigners.ForegroundColor

AssignerForegroundColor is an alias.

type AssignerHeight

type AssignerHeight = assigners.Height

AssignerHeight is an alias.

type AssignerHorizontalAlignment

type AssignerHorizontalAlignment = assigners.HorizontalAlignment

AssignerHorizontalAlignment is an alias.

type AssignerImage

type AssignerImage = assigners.Image

AssignerImage is an alias.

type AssignerImageStretch

type AssignerImageStretch = assigners.ImageStretch

AssignerImageStretch is an alias.

type AssignerOriginX

type AssignerOriginX = assigners.OriginX

AssignerOriginX is an alias.

type AssignerOriginY

type AssignerOriginY = assigners.OriginY

AssignerOriginY is an alias.

type AssignerText

type AssignerText = assigners.Text

AssignerText is an alias.

type AssignerTextWrap

type AssignerTextWrap = assigners.TextWrap

AssignerTextWrap is an alias.

type AssignerVerticalAlignment

type AssignerVerticalAlignment = assigners.VerticalAlignment

AssignerVerticalAlignment is an alias.

type AssignerWidth

type AssignerWidth = assigners.Width

AssignerWidth is an alias.

type AssignerX

type AssignerX = assigners.X

AssignerX is an alias.

type AssignerY

type AssignerY = assigners.Y

AssignerY is an alias.

type Event

type Event interface {
}

Event is our most basic event interface.

type EventCancelable

type EventCancelable interface {
	Cancel()
	Canceled() bool
}

EventCancelable is an event that is cancelable. This applies to all events.

type EventFocus

type EventFocus = *events.Focus

EventFocus is triggered when a widget gains focus.

type EventKeyInput

type EventKeyInput = *events.KeyInput

EventKeyInput is used to receive key input events. Only the focused element will receive this event.

type EventKeyPress

type EventKeyPress = *events.KeyPress

EventKeyPress is used to receive key press events. Only the focused element will receive this event.

type EventKeyRelease

type EventKeyRelease = *events.KeyRelease

EventKeyRelease is used to receive key release events. Only the focused element will receive this event.

type EventPointerIn

type EventPointerIn = *events.PointerIn

EventPointerIn is an event that is triggered when a pointer enters an element.

type EventPointerMove

type EventPointerMove = *events.PointerMove

EventPointerMove is an event that is triggered when a pointer within an element or when an element is pressed and the pointer moves anywhere.

type EventPointerOut

type EventPointerOut = *events.PointerOut

EventPointerOut is an event that is triggered when a pointer leaves an element.

type EventPointerPress

type EventPointerPress = *events.PointerPress

EventPointerPress is an event that is triggered when a pointer has depressed an element.

type EventPointerPressed

type EventPointerPressed = *events.PointerPressed

EventPointerPressed is an event that is triggered when a pointer has depressed an element.

type EventPointerRelease

type EventPointerRelease = *events.PointerRelease

EventPointerRelease is an event that is triggered when a pointer has released an element.

type EventUnfocus

type EventUnfocus = *events.Unfocus

EventUnfocus is triggered when a widget has lost focus.

type GetterDisabled

type GetterDisabled = getters.Disabled

GetterDisabled is an alias.

type GetterX

type GetterX = getters.X

GetterX is an alias.

type GetterY

type GetterY = getters.Y

GetterY is an alias.

type HitChecker

type HitChecker interface {
	Hit(x, y float64) bool
}

HitChecker checks if the given coordinate hits the target element.

type ImageStretch

type ImageStretch = style.ImageStretch

ImageStretch is a type alias for style.ImageStretch.

type Layout

type Layout struct {
	RenderTarget  *ebiten.Image
	ClampPointers bool

	Nodes Nodes
	// contains filtered or unexported fields
}

Layout is used to control layout and manage evts.

func NewLayout

func NewLayout(src string) (*Layout, error)

NewLayout creates a new layout from the given JSON string.

func (*Layout) AddNode

func (l *Layout) AddNode(n Node) *Node

AddNode adds the given node and generates it.

func (*Layout) ClearEvents

func (l *Layout) ClearEvents()

ClearEvents clears all events that have been processed, such as pointer presses, key presses, etc.

func (*Layout) Draw

func (l *Layout) Draw(screen *ebiten.Image)

Draw draws the Nodes to the screen

func (*Layout) Generate

func (l *Layout) Generate()

Generate creates proper Widgets from the list of Nodes.

func (*Layout) GetByID

func (l *Layout) GetByID(id string) *Node

GetByID returns the given node by its ID.

func (*Layout) HasEvents

func (l *Layout) HasEvents() bool

HasEvents returns if there are any active events like a mouse press,

func (*Layout) Layout

func (l *Layout) Layout(ctx LayoutContext)

Layout repositions all nodes.

func (*Layout) Parse

func (l *Layout) Parse(src string) error

Parse parses the given JSON source string.

func (*Layout) RemoveNode

func (l *Layout) RemoveNode(n *Node)

RemoveNode removes the given node from the layout.

func (*Layout) Update

func (l *Layout) Update()

Update collects evts and propagates them to the contained Widgets.

type LayoutContext

type LayoutContext struct {
	OuterX      float64
	OuterY      float64
	OuterWidth  float64
	OuterHeight float64
}

LayoutContext is used to contain pertinent information for widget layout.

type LayoutWidget

type LayoutWidget interface {
	Widget
	Layout(width, height float64) (float64, float64)
}

LayoutWidget is an optional interface that widgets can implement to allow for changing their size.

type Node

type Node struct {
	ID   string
	Type string
	X    string

	Y string

	Width string

	Height string

	OriginX         string
	OriginY         string
	Text            string
	TextWrap        Wrap
	Obfuscated      bool
	Font            string
	FontSize        string
	Widget          Widget `json:"-"`
	BackgroundColor string
	ForegroundColor string
	BorderColor     string
	BorderWidth     string
	VerticalAlign   Alignment
	HorizontalAlign Alignment
	ImageStretch    ImageStretch
	Image           string // ???
	Source          string // TODO: maybe merge with Image? This is only used by Templates atm.
	FocusIndex      int
	Children        Nodes
	Hidden          bool
	Disabled        bool
	Parent          *Node // Hmm... uncertain if this paradigm is wise.
	// contains filtered or unexported fields
}

Node is a parseable structure used for determining element position, style, and beyond.

type Nodes

type Nodes []*Node

Nodes are a slice of nodes, wow.

func LoadTemplate

func LoadTemplate(path string) (Nodes, error)

LoadTemplate loads the given path using the loader set in SetTemplateLoader

func (*Nodes) ForEach

func (ns *Nodes) ForEach(cb func(*Node) bool) bool

ForEach iterates through all nodes and traverses their children. If cb returns true, the for each processing is canceled.

func (*Nodes) ForEachDeepest

func (ns *Nodes) ForEachDeepest(cb func(*Node) bool) bool

ForEachDeepest iterates through nodes from the first to last with the deepest node in each occurring first.

func (*Nodes) GetByID

func (ns *Nodes) GetByID(id string) *Node

GetByID returns nil or a Node pointer, iterating through children.

type ReceiverGenerate

type ReceiverGenerate = receivers.Generate

ReceiverGenerate is an anlias.

type ReceiverGlobalRelease

type ReceiverGlobalRelease = receivers.PointerGlobalRelease

ReceiverGlobalRelease is an alias.

type ReceiverPointerGlobalMove

type ReceiverPointerGlobalMove = receivers.PointerGlobalMove

ReceiverPointerGlobalMove is an alias.

type ReceiverPointerIn

type ReceiverPointerIn = receivers.PointerIn

ReceiverPointerIn is an alias.

type ReceiverPointerMove

type ReceiverPointerMove = receivers.PointerMove

ReceiverPointerMove is an alias.

type ReceiverPointerOut

type ReceiverPointerOut = receivers.PointerOut

ReceiverPointerOut is an alias.

type ReceiverPointerPress

type ReceiverPointerPress = receivers.PointerPress

ReceiverPointerPress is an alias.

type ReceiverPointerPressed

type ReceiverPointerPressed = receivers.PointerPressed

ReceiverPointerPressed is an alias.

type ReceiverPointerRelease

type ReceiverPointerRelease = receivers.PointerRelease

ReceiverPointerRelease is an alias.

type Theme

type Theme = style.Theme

Theme is a type alias for style.Theme.

type Widget

type Widget interface {
	Draw(*ebiten.Image, *ebiten.DrawImageOptions)
}

Widget is the interface that all widgets must implement.

type Wrap

type Wrap = style.Wrap

Wrap is a type alias for style.Wrap.

Directories

Path Synopsis
defaults
examples
buttons command
direct command
draggable command
focus command
hooks command
icon command
images command
lifetime command
templates command
text command
textinput command
yaml command

Jump to

Keyboard shortcuts

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