Giter VIP home page Giter VIP logo

ex_termbox's Introduction

ExTermbox

Hex.pm Hexdocs.pm Travis CI

Low-level termbox bindings for Elixir.

For high-level, declarative terminal UIs in Elixir, see Ratatouille. It builds on top of this library and the termbox API to provide an HTML-like DSL for defining views.

For the API Reference, see: https://hexdocs.pm/ex_termbox.

Getting Started

Termbox bindings

ExTermbox implements the termbox API functions via NIFs:

Hello World

Let's go through the bundled hello world example. To follow along, clone this repo and edit the example.

This repository makes use of Git submodules, so make sure you include them in your clone. In recent versions of git, this can be accomplished by including the --recursive flag, e.g.

git clone --recursive [email protected]:ndreynolds/ex_termbox.git

When the clone is complete, the c_src/termbox/ directory should have files in it.

You can also create an Elixir script in any Mix project with ex_termbox in the dependencies list. Later, we'll run the example with mix run <file>.

In a real project, you'll probably want to use an OTP application with a proper supervision tree, but here we'll keep it as simple as possible.

First, some aliases for the modules we'll use.

alias ExTermbox.Bindings, as: Termbox
alias ExTermbox.{Cell, EventManager, Event, Position}

Next, we initialize the termbox application. This initialization should come before any other termbox functions are called. (Otherwise, your program will probably crash.)

:ok = Termbox.init()

In order to react to keyboard, click or resize events later, we need to start the event manager and subscribe the current process to any events. The event manager is an abstraction over poll_event/1 that constantly polls for events and notifies its subscribers whenever one is received.

{:ok, _pid} = EventManager.start_link()
:ok = EventManager.subscribe(self())

To render content to the screen, we use put_cell/1. We pass it %Cell{} structs that each have a position and a ch.

The position is a struct representing an (x, y) cartesian coordinate. The top-left-most cell of the screen represents the origin (0, 0).

The ch should be an integer representing the character (e.g., ?a or 97). In the example, we're using charlists for this reason.

for {ch, x} <- Enum.with_index('Hello, World!') do
  :ok = Termbox.put_cell(%Cell{position: %Position{x: x, y: 0}, ch: ch})
end

for {ch, x} <- Enum.with_index('(Press <q> to quit)') do
  :ok = Termbox.put_cell(%Cell{position: %Position{x: x, y: 2}, ch: ch})
end

Since Elixir is a functional language, it's good practice to avoid this sort of imperative style in real applications. Instead, you might build and transform a canvas defined as map or list of cells. Then, when your canvas is ready for rendering, it can be synced to termbox via put_cell/1 in one sweep. This is how the Ratatouille library works.

Until now, we've only updated termbox's internal buffer. To actually render the content to the screen, we need to call present/0:

Termbox.present()

When a key is pressed, it'll be sent to us by the event manager. Once we receive a 'q' key press, we'll shut down the application.

receive do
  {:event, %Event{ch: ?q}} ->
    :ok = Termbox.shutdown()
end

You can use this event-handling logic to respond to events any way you like---e.g., render different content, switch tabs, resize content, etc.

Finally, run the example like this:

$ mix run examples/hello_world.exs

You shuld see the text we rendered and be able to quit with 'q'.

Installation

From Hex

Add ExTermbox as a dependency in your project's mix.exs:

def deps do
  [
    {:ex_termbox, "~> 0.3"}
  ]
end

The Hex package bundles a compatible version of termbox. There are some compile hooks to automatically build and link a local copy of ltermbox for your application. This should happen the first time you build ExTermbox (e.g., via mix deps.compile).

So far the build has been tested on macOS and a few Linux distros. Please add an issue if you encounter any problems with the build.

From Source

To try out the master branch, first clone the repo:

git clone --recurse-submodules https://github.com/ndreynolds/ex_termbox.git
cd ex_termbox

The --recurse-submodules flag (--recursive before Git 2.13) is necessary in order to additionally clone the termbox source code, which is required to build this project.

Next, fetch the deps:

mix deps.get

Finally, try out the included event viewer application:

mix run examples/event_viewer.exs

If you see the application drawn and can trigger events, you're good to go. Use 'q' to quit the examples.

ex_termbox's People

Contributors

fhunleth avatar fireproofsocks avatar ndreynolds avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.