Git Product home page Git Product logo

tuicpp's Introduction

tuicpp

tuicpp is a C++ wrapper API for ncurses which eases the developement of text based interfaces and applications.

All API elements are enclosed inside the tuicpp namespace.

Table of Contents

Created by gh-md-toc

Overview of tuicpp

Setting up

The classes in tuicpp can be used almost immediately, however ncurses must actually be initialized with initscr(). Likewise, it must be manually ended with endwin() to prevent it from screwing with your terminal.

// Example main
int main()
{
	// Initialize ncurses
	initscr();

	// tuicpp stuff goes here...

	// End ncurses
	// 	don't worry about the ncurses window
	//	handles, they are managed by tuicpp's
	//	windows
	endwin();
}

Import Structures

ScreenInfo

The ScreenInfo struct is defined as follows.

// Screen info
struct ScreenInfo {
        int height;
        int width;
        int y;
        int x;
};

It describes the position and size of the window. Note that height is before width and y is before x. To avoid confusions with this altogether, initialize these objects as follows:

auto si = ScreenInfo {
	.height = 20,
	.width = 20,
	.y = 0,		// 0 is default
	.x = 0		// 0 is default
};

World

The World class does not represent an ncurses window, only the essential members that all derived Window types will have.

A method to note from this class is the static World::limits() which returns a std::pair <int, int> of the terminal's maximum height and width (note this order).

Window types

Now for the exciting stuff. Each section will show a snippet of code demonstrating the construction and usage of the window and an animation of the corresponding execution.

PlainWindow

As plain as a window can get.

auto win = tuicpp::PlainWindow(
	tuicpp::ScreenInfo {
		.height = height,
		.width = width,
		.y = y,
		.x = x
	}
);

win.printf("Hello World!\n");
win.printf("This is just an ordinary window!\n");
win.printf("Notice that the text is being wrapped!\n");
win.printf("Press any key to continue...\n");
win.getc();

Result:

This class is important because it contains a conventional set of methods that are inherited by all the remaining window types.

Method Summary
Method Description
refresh() Refreshes the window, essentially doing wrefresh().
clear() Clears the window, essentially doing wclear().
erase() Erase the window, essentially doing werases(). Unlike clear() there should not be as much flickering. All derived classes should this method as necessary.
resize(int height, int width) Resizes the window. Note the order of the arguments.
move(int y, int x) Moves the cursor to the yth row and xth column.
printf(const char *fmt, ...) Prints to the window, like wprintw.
mvprintf(int y, int x, const char *fmt, ...) Prints to the window starting at the yth row and xth column, like mvwprintw.
add_char(const chtype ch) Prints a characetr to the the window, like waddch.
mvadd_char(int y, int x, const chtype ch) Prints a characetr to the the window at the yth row and xth column, like mvwaddch.
getc() Get a character that the user pressed, like wgetc(). Will block until a key is pressed.
set_keypad(bool bl) Enables keypad for the window.
cursor(int y, int x) A more sensible alias for move().
attribute_on(int attr) Turn on the attribute attr for the window, like wattron().
attribute_off(int attr) Turn off the attribute attr for the window, like wattroff().
attribute_set(int attr) Set the attribute for the window to attr, like wattrset().

Some of these methods (i.e. refresh() and clear()) are overriden in derived classes.

BoxedWindow

A window with a border surrounding it.

auto win = tuicpp::BoxedWindow(
	tuicpp::ScreenInfo {
		.height = height,
		.width = width,
		.y = y,
		.x = x
	}
);

win.printf("Hello World!\n");
win.printf("This is no ordinary window ... it has a border!\n");
win.printf("Text is still being wrapped...\n");
win.printf("Press any key to continue...\n");
win.getc();

Result:

DecoratedWindow

A window with a border and a title bar.

auto win = tuicpp::DecoratedWindow(
	"My Decorated Window",
	tuicpp::ScreenInfo {
		.height = height,
		.width = width,
		.y = y,
		.x = x
	}
);

win.printf("Hello World!\n");
win.printf("This is a decorated window\n");
win.printf("It has a title bar and a border\n");
win.printf("Press any key to continue...\n");
win.getc();

Result:

Now we get into more niche window types.

SelectionWindow

A window which handles the selection from a set of options. The constructor for this class requires passing a struct of type SelectionWindow::Option to specify certain options.

auto opts = tuicpp::SelectionWindow {
	// Dictates whether the options should
	//	be center within the window
	.centered = true,

	// Allows multiple options to be selected
	//	(and then be confirmed by an [OK] button)
	.multi = false
};

Construction is fairly simple:

// List of options -- OptionList is just an alias
//	for std::vector <std::string>
auto opt_list = tuicpp::SelectionWindow {
	"Option A",
	"Option B",
	"Option C",
	"Option D"
};

// As will be shown later, it should be more
//	common to allocate the window on heap,
//	so that it can be smoothly removed from
//	the screen when it is done
auto win = new tuicpp::SelectionWindow(
	"Selection Window",
	screen_info,
	opt_list,
	opts
);

The options that the user selects will be stored as indices to the OptionList in a SelectionWindow::Selection object (an alias for std::set <int>).

auto selection = tuicpp::SelectionWindow::Selection {};

// The return of this method is whether the
//	user has selected at least one option
//	(i.e. selection.size() > 0)
bool yeilded = win->yield(selection);

// Delete the window now that we are done with it
delete win;

// Whatever else we want to do...

The result of this is the following: [TODO]

With opts.multi = true it would instead look this: [TODO]

Table

The Table class is a templated interface designed to conveniently display a table in ncurses. Its construction requires an auxiliarly structure, Table <T> ::From, which describes the columns of the table and how to generate them.

// This lambda describes how to generate the column
//	entries for the table for one data input
//	(float, in our case)
auto to_str = [](const float &i, size_t column) {
	if (column == 0) {
		// First column is x
		return std::to_string(i);
	} else {
		// Second column is x * x
		return std::to_string(i * i);
	}
};

auto from = auto from = tuicpp::Table <float> ::From({"x", "f(x)"}, to_str);

To fill in the actual data for the table, one must assign the .data field (a std::vector of the template parameter).

from.data = {
	0, 0.5, 1.0, 1.5, 2.0, 2.5,
	3.0, 3.5, 4.0, 4.5, 5.0
};

Now, construction is simply as follows.

auto win = tuicpp::Table <float> (
	from,
	tuicpp::ScreenInfo {
		.height = height,
		.width = width,
		.y = y,
		.x = x
	}
);

The result is the following:

Additional options can be supplied to the table through the From structure. The .length member (std::vector <size_t>) specifies the width of each table column, and the boolean .auto_resize dictates whether the Table object's window will be resized to fit the entire table.

The Table class also comes with the following methods.

Method Description
set_data(const Data &data, bool auto_resize = false) Changes the table's data to data. If auto_resize is set to true, then the window will resize to fit the whole table.
set_lengths(const Lengths &lengths) Sets the width of each column.
set_generator(const Generator &generator) Changes the column generator function to generator. The expected signature for Generator is std::string (const T &, size).
highlight_row(int row) Highlight's a specific row in the table.

FieldEditor

Edit fields in a slick little window. Construction is very easy:

// We allocate this on the heap to remove it from
//	our app seamlessly
auto win = new tuicpp::FieldEditor(
	"Employee Editor",
	{"Name", "Email"},		// Names of the fields
	tuicpp::ScreenInfo {
		.height = height,
		.width = width,
		.y = y,
		.x = x
	}
);

This defines an editor with the fields "Name" and "Email". To get user input (and display the editor), one does the following:

// Assign the initial values of the fields
std::string name = "Bob Joe";
std::string email;

// "Yield" the user input
win->yield({
	tuicpp::yielder(&name),
	tuicpp::yielder(&email)
});

// Done with the editor, we can free it now
delete win;

// Do whatever else...

The yield method takes some pretty weird objects. For now, think of yielder(&name) as a wrapper to the reference to name. When the editor is done with the yield method, the contents of the fields will the stored in name and email. No extra hassle.

The result of this setup is the following.

tuicpp's People

Contributors

iveevi avatar

Stargazers

xMonody avatar  avatar  avatar  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.