nwid

A terminal widget framework for humans.


Keywords
server, development, terminal, programming, widgets
License
MIT
Install
pip install nwid==0.1

Documentation

nwid

A terminal widgets framework for humans.

Code issues

Please note that this is a work in progress. The API will likely change many times before it becomes stable. Use at your own risk.

Nwid is a terminal widgets framework for humans.

It is designed to be an easy-to-use, light-weight (no dependencies), terminal widget library and application framework for building terminal GUIs. It has intuitive widgets, a simple and recognizable event loop, and a container App that can be extended or used as-is. Its design and components take some inspiration from the well-known web browser DOM as well as the python packages urwid and npyscreen.

Although there already are a handful of terminal user-interface libraries in python, I have found them to be either cumbersome to use or difficult to extend because of their design. The python curses module is itself unweildly and desperately needs a layer of abstraction to hide its unique details and oddly named functions. Nwid aims to be this intuitive, easy to extend abstraction layer. The nwid philosophy is to let you create and describe the widgets with intuitive attributes and methods, and the framework will take care of the cumbersome terminal details. The code is pythonic and easy to read, which makes it easy to extend.

A low-level knowledge of terminals and tty is not necessary to using this framework. To get started, check out the examples in the examples directory. Nwid is designed to be conceptually easy to understand, and the examples are intended to exhibit the basic concepts in order to give a helpful overview of the capabilities and structure of the framework. After looking at the examples, you can read Modules and Components for more specific details about the framework.

If you have any questions, comments, or suggestions I'd love to hear them: harold (a) bradleystudio.net

Installing and including in projects

Installing nwid

$ pip install nwid

Running Tests

$ cd <project directory>
$ py.test

Importing and Basic Usage

>>> import nwid

>>> app = nwid.App()
>>> app.window.add( {
        nwid.Title : { 'text' : 'An nwid App!' },
        nwid.LabeledTextBox : {
            'text' : 'Your input:',
            'validator' : App.validate_function,
            'name' :
            }
        nwid.Button : {
            'text' : 'Click me!',
            'click' : App.callback_function,
            }
        })

>>> app.run()

Modules and Components

Overview

The nwid framework is made of three major components, the App class for managing windows and running the event loop, the Window class for containing and managing widgets, and the widget module for creating the user interactive widgets (such as, textfields, labels, and dropdown boxes).

The App is the base controller for the application. Besides controling the event loop, it is responsible for initializing the curses environment and handling the screen object. This class can be used as-is or may be extended by a custom class with application-specific controller methods. The App class has a special property, the App.window_stack, that keeps track of the current window and any open window that has not yet been closed but is covered up (partly or completely) by the current window.

For instance, the first window may be a form that has a button that opens a second window with a select box containing a list of options to choose from. The first window hasn't yet closed but is waiting for the second window to provide the user selected choice. At this point, the second window is the second and top-most window on the stack. Any events that are triggered are now given to this window. It may completely cover the first window or might only cover a portion of it being centered on the screen with the edges revealing the first window behind it. This second window may contain a select box with a list of several objects or strings to pass back to the first window. One of these options might be 'new', indicating that the user wishes to create a new string or object. Selecting this item, might open a third window for this task, putting this third window on top of the stack. This stacking could go on indefinitely with each window appending to the App.window_stack. When the topmost window is closed, this window is 'popped' from the stack and the next window down in the stack is given back the focus. When an App no longer has any windows, the application is closed.

The Window class is the container class for the widgets. It sets the bounds for where a widget can be drawn. It may have a border and title set. Note that this is not the same thing as the curses window object. Although it should have a reference to this object in Window.screen.

A widget is a user interface object that can be displayed in a window. It is defined by its height and width, its location on the window, and its foreground and background colors. It has contents such as a string of text or a more complicated widget may contain other widgets. In fact, a Window class is actually a special kind of top-level widget. You can create your own custom widgets by extending widget.Base, although nwid comes with a number of useful generic widgets such as TextBox, LabledTextBox, CheckBox, String, Button, Label, and SelectBox. Widgets can register events to callback functions in order to handle keyboard or mouse events.

The App Module

The nwid.app module comprises

The App controller is also responsible for the event loop that catches keyboard and mouse events. It passes these events to the window in focus (App.window) for the window to handle.

Lastly, the App is responsible for setting up and tearing down the curses environment. It initializes the curses screen and binds this object to any window that is put in the window stack. This is done using a CursesManager object, which is both a context manager and a wrapper for the curses library. This object is part of the nwid internals and generally doesn't need to be accessed directly. It takes care of the nitty-gritty details.

The App Class

The nwid.App class is the primary

You can either use it as is or you can inherit from App.

>>>

The current window or top-most window is always the window with the focus, meaning that any events that are triggered are given only to that window. The App.window attribute always points to this window. Setting this attribute to a new window will automatically make this new window the window with the focus and put it on top of the 'window stack'.

Attributes
Methods

The CursesManager Context Manager

TODO

The Event Loop

The event loop is inspired by the design of an Internet browser's event loop.

Registering Events

A widget can register an event with a callback function by

Example:

>>> def widget.callback_function(self):
>>>     print 'Event triggered!'

>>> widget.register_event('x', widget.callback_function)
Event Propagation

When an event is fired, the main window's trigger function is called with the event name. It then calls the trigger function of its child that has focus. If this child has a child widget, the process continues down until it gets to the lowest widget in focus that has no children. This widget attempts to run any registered callback functions. The function may return as normal and the parent regains control and attempts to run any registered callback function that it may have. This process continues until the main window regains control or if the exception PreventDefault is raised. A callback function may choose to raise PreventDefault in order to prevent other callback functions from interferring. This is very similar to JavaScript's Event.preventDefault() method.

Widget Module

A Widget is a reusable modular component that is displayed on the screen as a button, a text field, or other graphical interface. It can be combined to make a more complex widget component. The widgets that make up this more comlpex component are the children widgets to the parent widget.

The parent widget is responsible for the layout of its children. The parent controls the vertical and horizontal alignment as well as whether or not it has the ability to scroll.

Base Widget

The nwid.widget.Base class is the foundation for all other widgets. If you wish to create your own widget, you should inherit from Base.

For example:

>>>

String Widget

The nwid.widget.String class is a basic string widget. This widget is used for displaying strings.

TextBox Widget

The nwid.widget.TextBox class is a textbox widget for accepting user input.

ComboBox Widget

The nwid.widget.ComboBox class is a textbox widget for accepting user input.


Soli Deo gloria.