Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

180 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Terrocotta - Clay meets Roc

Rocotta

Terrocotta is a library for building native applications in Roc.

This is an experimental project to play with and test the performance of Roc and learn about GUI internals.

Features

  • Model-View-Update (MVU) architecture.
  • Clay layout engine ported to Roc.
    • Stack-based node layout (capacity + exponential growth allocation)
    • Flexbox
    • Mouse/Keyboard Events
    • Scrollable
    • Text wrapping
    • Text measurement caching
    • Floating
    • Transitions
  • Rendering: roc-ray platform built on raylib.
  • Status based styling (hovered/pressed/focused)
  • Theming
  • Widgets
    • Button
    • Slider
    • Checkbox
    • Toggle
    • Select
    • Input Text

NB: Theming and widgets are just proof of concept implementations. Users are expected to build their own UI toolkit on top of the 3 unique elements: box(id, style, events, children), text(content), image(blob).

Documentation

Examples

Quick counter example:

import terrocotta.Element exposing [box, text, style, View]

AppModel : { count : I32 }

Msg : [Decrement, Increment]

init! : Config => Try(AppModel, [Exit(I64), ..])
init! = |_config| Ok({ count: 0 })

update : AppModel, Msg -> AppModel
update = |model, msg| match msg {
	Decrement => { ..model, count: model.count - 1 }
	Increment => { ..model, count: model.count + 1 }
}

white = 0xFFFFFF.Color
blue = 0x2196F3.Color

button : Str, Msg -> View(Msg)
button = |label, msg| {
	box(
	  # id
		Auto,
		# style (status-based)
		|status| style
			.width(Fit({ min: 0, max: 10000 }))
			.pad((8, 8, 8, 8))
			.background(if status.hovered { blue.darken(50) } else { blue })
			.font_color(white)
			.font_size(16),
		# events
		[OnClick(msg)],
		# children
		[
			text(label),
		],
	)
}

view : AppModel -> View(Msg)
view = |model| {
	box(
		Auto,
		|_| style.direction(Row).height(Fit({ min: 0, max: 10000 })).gap(8).font_size(16),
		[],
		[
			button("-", Decrement),
			text("Count: ${model.count.to_str()}"),
			button("+", Increment),
		],
	)
}

Find more examples at:

  • roc examples/counter.roc: key and pointer event handling
  • roc examples/widgets.roc: button, toggle, checkbox, slider
  • roc examples/text_wrap.roc: text wrapping options
  • roc examples/scrollable.roc: scrollable list
  • roc examples/floating.roc: floating attachment points
  • roc examples/image.roc: image loading and sizing

Testing

roc test package/main.roc

About

Clay meets Roc

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages