static int luabox_getcell( lua_State *L ) { uint16_t x = luaL_checknumber( L, 1 ); uint16_t y = luaL_checknumber( L, 2 ); if ( x >= 0 && x < tb_width() && y >= 0 && y < tb_height()) { struct tb_cell *cell = (tb_cell_buffer() + y * tb_width() + x); lua_pushnumber( L, cell->ch ); lua_pushnumber( L, cell->fg ); lua_pushnumber( L, cell->bg ); return 3; } else { luaL_error( L, "coordinates out of bounds" ); return 0; } }
static int ui_draw_chars(char *chars, int x, int y, uint16_t fg, uint16_t bg) { int width = tb_width(); int pointer = 0; int counter = 0; int length; mbstate_t state; wchar_t ch; // Initialize multi-byte state mbrlen(NULL, 0, &state); while (chars[pointer] != '\0') { length = mbrtowc(&ch, chars + pointer, 4, &state); tb_change_cell(x + pointer, y, ch, fg, bg); pointer += length; counter++; } // Draw spaces for the remaining of the line for (int i = counter; i < width; i++) { tb_change_cell(x + i, y, ' ', fg, bg); } return counter; }
inline Manager(std::unique_ptr<Widget>&& widget) { tb_init(); tb_select_input_mode(TB_INPUT_ESC | TB_INPUT_MOUSE); tb_select_output_mode(TB_OUTPUT_256); root = std::move(widget); resize(tb_width(), tb_height()); }
int main(int argv, char **argc) { int code = tb_init(); if (code < 0) { fprintf(stderr, "termbox init failed, code: %d\n", code); return -1; } tb_select_input_mode(TB_INPUT_ESC | TB_INPUT_MOUSE); int w = tb_width(); int h = tb_height(); reallocBackBuffer(w, h); updateAndRedrawAll(-1, -1); for (;;) { struct tb_event ev; int mx = -1; int my = -1; int t = tb_poll_event(&ev); if (t == -1) { tb_shutdown(); fprintf(stderr, "termbox poll event error\n"); return -1; } switch (t) { case TB_EVENT_KEY: if (ev.key == TB_KEY_ESC) { tb_shutdown(); return 0; } break; case TB_EVENT_MOUSE: if (ev.key == TB_KEY_MOUSE_LEFT) { mx = ev.x; my = ev.y; } break; case TB_EVENT_RESIZE: reallocBackBuffer(ev.w, ev.h); break; } updateAndRedrawAll(mx, my); } }
CAMLprim value tbstub_width() { return Val_int(tb_width()); }
static int lua_tb_width( lua_State *L ) { lua_pushinteger( L, tb_width()); return 1; }
static int luabox_print( lua_State *L ) { const char *chstr = luaL_checkstring( L, 1 ); int x = luaL_checkint( L, 2 ); int y = luaL_checkint( L, 3 ); uint16_t fg; uint16_t bg; int w; int h; int xfrom = x; int len; int lensaved; const char *chstrfrom = chstr; int mode; int CR = 0; int NL = 0; int wrapped = 0; lua_len( L, 1 ); len = lensaved = (int) lua_tonumber( L, -1 ); lua_pop( L, 1 ); fg = lua_isnumber( L, 4 ) ? lua_tonumber( L, 4 ) : TB_DEFAULT; bg = lua_isnumber( L, 5 ) ? lua_tonumber( L, 5 ) : TB_DEFAULT; w = lua_isnumber( L, 6 ) ? lua_tonumber( L, 6 ) : tb_width(); h = lua_isnumber( L, 7 ) ? lua_tonumber( L, 7 ) : tb_height(); mode = lua_isnumber( L, 8 ) ? lua_tonumber( L, 8 ) : LUABOX_WRAP; w = w + xfrom; h = h + y; while ( len > 0 ) { uint32_t ch; int chlen = tb_utf8_char_to_unicode( &ch, chstr ); if ( ch == '\n' && CR ) { CR = 0; } else if ( ch == '\r' || ch == '\n' ) { NL = 1; } else { tb_change_cell( x, y, ch, fg, bg ); if ( x >= w-1 ) { NL = 1; wrapped = 1; } else { if ( wrapped && mode == LUABOX_WRAP && ( ch == ' ' || ch == '\t' ) && x == xfrom ) { } else { x++; wrapped = 0; } } } len -= chlen; chstr += chlen; if ( NL ) { NL = 0; if ( mode == LUABOX_TRUNC || y >= h-1 ) { break; } else { if ( ch == '\r' ) CR = 1; y++; x = xfrom; } } if ( len <= 0 && mode == LUABOX_REPEAT ) { chstr = chstrfrom; len = lensaved; } } return 0; }