|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<article>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<artheader>
|
|
Packit Service |
8876fe |
<title>Writing Programs Using <literal remap="tt">newt</literal></title>
|
|
Packit Service |
8876fe |
<author>
|
|
Packit Service |
8876fe |
<firstname>Erik Troan, <ewt@redhat.com></firstname>
|
|
Packit Service |
8876fe |
</author>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<pubdate>v0.31, 2003-Jan-06</pubdate>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<abstract>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
The <literal remap="tt">newt</literal> windowing system is a terminal-based window and widget
|
|
Packit Service |
8876fe |
library designed for writing applications with a simple, but user-friendly,
|
|
Packit Service |
8876fe |
interface. While <literal remap="tt">newt</literal> is not intended to provide the rich feature
|
|
Packit Service |
8876fe |
set advanced applications may require, it has proven to be flexible enough
|
|
Packit Service |
8876fe |
for a wide range of applications (most notably, Red Hat's installation
|
|
Packit Service |
8876fe |
process). This tutorial explains the design philosophy behind <literal remap="tt">newt</literal> and
|
|
Packit Service |
8876fe |
how to use <literal remap="tt">newt</literal> from your programs.
|
|
Packit Service |
8876fe |
</para>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
</abstract>
|
|
Packit Service |
8876fe |
</artheader>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<sect1><title>Introduction</title>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
<literal remap="tt">Newt</literal> has a definite design philosophy behind it, and knowing that design
|
|
Packit Service |
8876fe |
makes it significantly easier to craft robust <literal remap="tt">newt</literal> applications. This
|
|
Packit Service |
8876fe |
tutorial documents <literal remap="tt">newt</literal> 0.30 --- older versions of <literal remap="tt">newt</literal> had
|
|
Packit Service |
8876fe |
annoying inconsistencies in it (which writing this tutorial pointed out),
|
|
Packit Service |
8876fe |
which were removed while this tutorial was written. The latest version of
|
|
Packit Service |
8876fe |
<literal remap="tt">newt</literal> is always available from Red Hat.</para>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<sect2><title>Background</title>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
<literal remap="tt">Newt</literal> was originally designed for use in the install code for
|
|
Packit Service |
8876fe |
Red Hat Linux. As this install code runs in an environment with limited
|
|
Packit Service |
8876fe |
resources (most importantly limited filesystem space), <literal remap="tt">newt</literal>'s size
|
|
Packit Service |
8876fe |
was immediately an issue. To help minimize its size, the following design
|
|
Packit Service |
8876fe |
decisions were made early in its implementation:
|
|
Packit Service |
8876fe |
</para>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<itemizedlist>
|
|
Packit Service |
8876fe |
<listitem>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
<literal remap="tt">newt</literal> does not use an event-driven architecture.
|
|
Packit Service |
8876fe |
</para>
|
|
Packit Service |
8876fe |
</listitem>
|
|
Packit Service |
8876fe |
<listitem>
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
<literal remap="tt">newt</literal> is written in C, not C++. While there has been interest
|
|
Packit Service |
8876fe |
in constructing C++ wrapper classes around the <literal remap="tt">newt</literal> API, nothing has
|
|
Packit Service |
8876fe |
yet come of those ideas.</para>
|
|
Packit Service |
8876fe |
</listitem>
|
|
Packit Service |
8876fe |
<listitem>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
Windows must be created and destroyed as a stack (in other words, all
|
|
Packit Service |
8876fe |
<literal remap="tt">newt</literal> windows behave as modal dialogs). This is probably
|
|
Packit Service |
8876fe |
the greatest functionality restriction of <literal remap="tt">newt</literal>.</para>
|
|
Packit Service |
8876fe |
</listitem>
|
|
Packit Service |
8876fe |
<listitem>
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
The tty keyboard is the only supported input device.</para>
|
|
Packit Service |
8876fe |
</listitem>
|
|
Packit Service |
8876fe |
<listitem>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
Many behaviours, such as widget traversal order, are difficult
|
|
Packit Service |
8876fe |
or impossible to change.
|
|
Packit Service |
8876fe |
</para>
|
|
Packit Service |
8876fe |
</listitem>
|
|
Packit Service |
8876fe |
</itemizedlist>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
While <literal remap="tt">newt</literal> provides a complete API, it does not handle the low-level
|
|
Packit Service |
8876fe |
screen drawing itself. Instead, <literal remap="tt">newt</literal> is layered on top of the screen
|
|
Packit Service |
8876fe |
management capabilities of John E. Davis's
|
|
Packit Service |
8876fe |
<ulink url="ftp://space.mit.edu/pub/davis/slang/">S-Lang</ulink> library.</para></sect2>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<sect2><title>Designing <literal remap="tt">newt</literal> applications</title>
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
As <literal remap="tt">newt</literal> is not event driven and forces modal windows (forcing window
|
|
Packit Service |
8876fe |
order to behave like a stack), newt applications tend to look quite like
|
|
Packit Service |
8876fe |
other text-mode programs. It is quite straightforward to convert a command
|
|
Packit Service |
8876fe |
line program which uses simple user prompts into a <literal remap="tt">newt</literal> application.
|
|
Packit Service |
8876fe |
Some of the programs run as part of the Red Hat installation process
|
|
Packit Service |
8876fe |
(such as <literal remap="tt">Xconfigurator</literal> and <literal remap="tt">mouseconfig</literal>) were originally written
|
|
Packit Service |
8876fe |
as simple terminal mode programs which used line-oriented menus to get
|
|
Packit Service |
8876fe |
input from the user and were later converted into <literal remap="tt">newt</literal> applications
|
|
Packit Service |
8876fe |
(through a process affectionately known as newtering). Such a conversion
|
|
Packit Service |
8876fe |
does not require changes to the control flow of most applications.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
Programming <literal remap="tt">newt</literal> is dramatically different from writing programs for
|
|
Packit Service |
8876fe |
most other windowing systems as <literal remap="tt">newt</literal>'s API is not event driven. This
|
|
Packit Service |
8876fe |
means that <literal remap="tt">newt</literal> applications look dramatically different from programs
|
|
Packit Service |
8876fe |
written for event-driven architectures such as Motif, <literal remap="tt">gtk</literal>, or even
|
|
Packit Service |
8876fe |
Borland's old TurboVision libraries.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
When you're designing your <literal remap="tt">newt</literal> program, keep this differentiation
|
|
Packit Service |
8876fe |
in mind. As long as you plan your application to call a function to
|
|
Packit Service |
8876fe |
get input and then continue (rather then having your program called
|
|
Packit Service |
8876fe |
when input is ready), programming with the newt libraries should be
|
|
Packit Service |
8876fe |
simple.</para></sect2>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<sect2><title>Components</title>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
Displayable items in <literal remap="tt">newt</literal> are known as <emphasis remap="bf">components</emphasis>, which are
|
|
Packit Service |
8876fe |
analogous to the widgets provided by most Unix widget sets. There are
|
|
Packit Service |
8876fe |
two main types of components in <literal remap="tt">newt</literal>, forms and everything else.
|
|
Packit Service |
8876fe |
Forms logically group components into functional sets. When an application
|
|
Packit Service |
8876fe |
is ready to get input from a user, it ``runs a form'', which makes the
|
|
Packit Service |
8876fe |
form active and lets the user enter information into the components the
|
|
Packit Service |
8876fe |
form contains. A form may contain any other component, including other
|
|
Packit Service |
8876fe |
forms. Using subforms in this manner lets the application change the details
|
|
Packit Service |
8876fe |
of how the user tabs between components on the form, scroll regions of the
|
|
Packit Service |
8876fe |
screen, and control background colors for portions of windows.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
Every component is of type <literal remap="tt">newtComponent</literal>, which is an opaque type. It's
|
|
Packit Service |
8876fe |
guaranteed to be a pointer though, which lets applications move it through
|
|
Packit Service |
8876fe |
void pointers if the need arises. Variables of type <literal remap="tt">newtComponent</literal> should
|
|
Packit Service |
8876fe |
never be directly manipulated -- they should only be passed to <literal remap="tt">newt</literal>
|
|
Packit Service |
8876fe |
functions. As <literal remap="tt">newtComponent</literal> variables are pointers, remember that
|
|
Packit Service |
8876fe |
they are always passed by value -- if you pass a <literal remap="tt">newtComponent</literal> to
|
|
Packit Service |
8876fe |
a function which manipulates it, that component is manipulated everywhere,
|
|
Packit Service |
8876fe |
not just inside of that function (which is nearly always the behaviour
|
|
Packit Service |
8876fe |
you want).</para></sect2>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<sect2><title>Conventions</title>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
<literal remap="tt">Newt</literal> uses a number of conventions to make it easier for programmers
|
|
Packit Service |
8876fe |
to use.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<itemizedlist>
|
|
Packit Service |
8876fe |
<listitem>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
All functions which manipulate data structures take the data
|
|
Packit Service |
8876fe |
structure being modified as their first parameter. For example, all
|
|
Packit Service |
8876fe |
of the functions which manipulate forms expect the <literal remap="tt">newtComponent</literal>
|
|
Packit Service |
8876fe |
for that form to be the first parameter.</para></listitem>
|
|
Packit Service |
8876fe |
<listitem>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
As <literal remap="tt">newt</literal> is loosely typed (forcing all of the components into
|
|
Packit Service |
8876fe |
a single variable makes coding easier, but nullifies the value of type
|
|
Packit Service |
8876fe |
checking), <literal remap="tt">newt</literal> functions include the name of the type they are
|
|
Packit Service |
8876fe |
manipulating. An example of this is <literal remap="tt">newtFormAddComponent()</literal>, which
|
|
Packit Service |
8876fe |
adds a component to a form. Note that the first parameter to this function
|
|
Packit Service |
8876fe |
is a form, as the name would suggest.</para></listitem>
|
|
Packit Service |
8876fe |
<listitem>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
When screen coordinates are passed into a function, the
|
|
Packit Service |
8876fe |
x location precedes the y location. To help keep this clear,
|
|
Packit Service |
8876fe |
we'll use the words ``left'' and ``top'' to describe those indicators (with
|
|
Packit Service |
8876fe |
left corresponding to the x position).</para></listitem>
|
|
Packit Service |
8876fe |
<listitem>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
When box sizes are passed, the horizontal width precedes the vertical
|
|
Packit Service |
8876fe |
width.</para></listitem>
|
|
Packit Service |
8876fe |
<listitem>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
When both a screen location and a box size are being passed, the
|
|
Packit Service |
8876fe |
screen location precedes the box size.</para></listitem>
|
|
Packit Service |
8876fe |
<listitem>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
When any component other then a form is created, the first two
|
|
Packit Service |
8876fe |
parameters are always the (left, right) location.</para></listitem>
|
|
Packit Service |
8876fe |
<listitem>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
Many functions take a set of flags as the final parameter. These
|
|
Packit Service |
8876fe |
flags may be logically ORed together to pass more then one flag at a time.</para></listitem>
|
|
Packit Service |
8876fe |
<listitem>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
<literal remap="tt">Newt</literal> uses <emphasis remap="bf">callback</emphasis> functions to convey certain events to
|
|
Packit Service |
8876fe |
the application. While callbacks differ slightly in their parameters, most
|
|
Packit Service |
8876fe |
of them allow the application to specify an arbitrary argument to be passed
|
|
Packit Service |
8876fe |
to the callback when the callback is invoked. This argument is always a
|
|
Packit Service |
8876fe |
<literal remap="tt">void *</literal>, which allows the application great flexibility.
|
|
Packit Service |
8876fe |
</para>
|
|
Packit Service |
8876fe |
</listitem>
|
|
Packit Service |
8876fe |
</itemizedlist>
|
|
Packit Service |
8876fe |
</para></sect2></sect1>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<sect1><title>Basic <literal remap="tt">Newt</literal> Functions</title>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
While most <literal remap="tt">newt</literal> functions are concerned with widgets or groups
|
|
Packit Service |
8876fe |
of widgets (called grids and forms), some parts of the <literal remap="tt">newt</literal> API
|
|
Packit Service |
8876fe |
deal with more global issues, such as initializing <literal remap="tt">newt</literal> or writing
|
|
Packit Service |
8876fe |
to the root window.</para>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<sect2><title>Starting and Ending <literal remap="tt">newt</literal> Services</title>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
There are three functions which nearly every <literal remap="tt">newt</literal> application use. The
|
|
Packit Service |
8876fe |
first two are used to initialize the system.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<screen>
|
|
Packit Service |
8876fe |
int newtInit(void);
|
|
Packit Service |
8876fe |
void newtCls(void);
|
|
Packit Service |
8876fe |
</screen>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<literal remap="tt">newtInit()</literal> should be the first function called by every <literal remap="tt">newt</literal>
|
|
Packit Service |
8876fe |
program. It initializes internal data structures and places the terminal
|
|
Packit Service |
8876fe |
in raw mode. Most applications invoke <literal remap="tt">newtCls()</literal> immediately after
|
|
Packit Service |
8876fe |
<literal remap="tt">newtInit()</literal>, which causes the screen to be cleared. It's not
|
|
Packit Service |
8876fe |
necessary to call <literal remap="tt">newtCls()</literal> to use any of <literal remap="tt">newt</literal>'s features, but
|
|
Packit Service |
8876fe |
doing so will normally give a much neater appearance.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
When a <literal remap="tt">newt</literal> program is ready to exit, it should call <literal remap="tt">newtFinished()</literal>.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<screen>
|
|
Packit Service |
8876fe |
int newtFinished(void);
|
|
Packit Service |
8876fe |
</screen>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<literal remap="tt">newtFinished()</literal> restores the terminal to its appearance when
|
|
Packit Service |
8876fe |
<literal remap="tt">newtInit()</literal> was called (if possible -- on some terminals the cursor will
|
|
Packit Service |
8876fe |
be moved to the bottom, but it won't be possible to remember the original
|
|
Packit Service |
8876fe |
terminal contents) and places the terminal in its original input state.
|
|
Packit Service |
8876fe |
If this function isn't called, the terminal will probably need to be
|
|
Packit Service |
8876fe |
reset with the <literal remap="tt">reset</literal> command before it can be used easily.</para></sect2>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<sect2><title>Handling Keyboard Input</title>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
Normally, <literal remap="tt">newt</literal> programs don't read input directly from the
|
|
Packit Service |
8876fe |
user. Instead, they let <literal remap="tt">newt</literal> read the input and hand it to the
|
|
Packit Service |
8876fe |
program in a semi-digested form. <literal remap="tt">Newt</literal> does provide a couple of simple
|
|
Packit Service |
8876fe |
functions which give programs (a bit of) control over the terminal.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<screen>
|
|
Packit Service |
8876fe |
void newtWaitForKey(void);
|
|
Packit Service |
8876fe |
void newtClearKeyBuffer(void);
|
|
Packit Service |
8876fe |
</screen></para>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
The first of these, <literal remap="tt">newtWaitForKey()</literal>, doesn't return until a key
|
|
Packit Service |
8876fe |
has been pressed. The keystroke is then ignored. If a key is already in
|
|
Packit Service |
8876fe |
the terminal's buffer, <literal remap="tt">newtWaitForKey()</literal> discards a keystroke and
|
|
Packit Service |
8876fe |
returns immediately.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<literal remap="tt">newtClearKeyBuffer()</literal> discards the contents of the terminal's input
|
|
Packit Service |
8876fe |
buffer without waiting for additional input.</para></sect2>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<sect2><title>Drawing on the Root Window</title>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
The background of the terminal's display (the part without any windows
|
|
Packit Service |
8876fe |
covering it) is known as the <emphasis remap="bf">root window</emphasis> (it's the parent of all
|
|
Packit Service |
8876fe |
windows, just like the system's root directory is the parent of all
|
|
Packit Service |
8876fe |
subdirectories). Normally, applications don't use the root window, instead
|
|
Packit Service |
8876fe |
drawing all of their text inside of windows (<literal remap="tt">newt</literal> doesn't require
|
|
Packit Service |
8876fe |
this though -- widgets may be placed directly on the root window without
|
|
Packit Service |
8876fe |
difficulty). It is often desirable to display some text, such as a
|
|
Packit Service |
8876fe |
program's name or copyright information, on the root window, however.
|
|
Packit Service |
8876fe |
<literal remap="tt">Newt</literal> provides two ways of displaying text on the root window. These
|
|
Packit Service |
8876fe |
functions may be called at any time. They are the only <literal remap="tt">newt</literal> functions
|
|
Packit Service |
8876fe |
which are meant to write outside of the current window.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<screen>
|
|
Packit Service |
8876fe |
void newtDrawRootText(int left, int top, const char * text);
|
|
Packit Service |
8876fe |
</screen></para>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
This function is straightforward. It displays the string <literal remap="tt">text</literal> at
|
|
Packit Service |
8876fe |
the position indicated. If either the <literal remap="tt">left</literal> or <literal remap="tt">top</literal> is
|
|
Packit Service |
8876fe |
negative, the position is measured from the opposite side of the
|
|
Packit Service |
8876fe |
screen. The final measurement will seem to be off by one though. For
|
|
Packit Service |
8876fe |
example, a <literal remap="tt">top</literal> of -1 indicates the last line on the screen, and
|
|
Packit Service |
8876fe |
one of -2 is the line above that.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
As it's common to use the last line on the screen to display help information,
|
|
Packit Service |
8876fe |
<literal remap="tt">newt</literal> includes special support for doing exactly that. The last
|
|
Packit Service |
8876fe |
line on the display is known as the <emphasis remap="bf">help line</emphasis>, and is treated as a
|
|
Packit Service |
8876fe |
stack. As the value of the help line normally relates to the window
|
|
Packit Service |
8876fe |
currently displayed, using the same structure for window order and the
|
|
Packit Service |
8876fe |
help line is very natural. Two functions are provided to manipulate the
|
|
Packit Service |
8876fe |
help line.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<screen>
|
|
Packit Service |
8876fe |
void newtPushHelpLine(const char * text);
|
|
Packit Service |
8876fe |
void newtPopHelpLine(void);
|
|
Packit Service |
8876fe |
</screen>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
The first function, <literal remap="tt">newtPushHelpLine()</literal>, saves the current help line
|
|
Packit Service |
8876fe |
on a stack (which is independent of the window stack) and displays the
|
|
Packit Service |
8876fe |
new line. If <literal remap="tt">text</literal> is <literal remap="tt">NULL</literal>, <literal remap="tt">newt</literal>'s default help line is
|
|
Packit Service |
8876fe |
displayed (which provides basic instructions on using <literal remap="tt">newt</literal>). If
|
|
Packit Service |
8876fe |
<literal remap="tt">text</literal> is a string of length 0, the help line is cleared. For all
|
|
Packit Service |
8876fe |
other values of <literal remap="tt">text</literal>, the passed string is displayed at the bottom,
|
|
Packit Service |
8876fe |
left-hand corner of the display. The space between the end of the displayed
|
|
Packit Service |
8876fe |
string the the right-hand edge of the terminal is cleared.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<literal remap="tt">newtPopHelpLine()</literal> replaces the current help line with the one it
|
|
Packit Service |
8876fe |
replaced. It's important not to call tt/newtPopHelpLine()/ more then
|
|
Packit Service |
8876fe |
<literal remap="tt">newtPushHelpLine()</literal>!
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<literal remap="tt">Suspending Newt Applications</literal>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
By default, <literal remap="tt">newt</literal> programs cannot be suspended by the user (compare
|
|
Packit Service |
8876fe |
this to most Unix programs which can be suspended by pressing the suspend
|
|
Packit Service |
8876fe |
key (normally <literal remap="tt">^Z</literal>). Instead, programs can specify a <emphasis remap="bf">callback</emphasis>
|
|
Packit Service |
8876fe |
function which gets invoked when the user presses the suspend key.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<screen>
|
|
Packit Service |
8876fe |
typedef void (*newtSuspendCallback)(void);
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
void newtSetSuspendCallback(newtSuspendCallback cb);
|
|
Packit Service |
8876fe |
</screen>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
The suspend function neither expects nor returns any value, and can
|
|
Packit Service |
8876fe |
do whatever it likes to when it is invoked. If no suspend callback
|
|
Packit Service |
8876fe |
is registered, the suspend keystroke is ignored.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
If the application should suspend and continue like most user applications,
|
|
Packit Service |
8876fe |
the suspend callback needs two other <literal remap="tt">newt</literal> functions.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<screen>
|
|
Packit Service |
8876fe |
void newtSuspend(void);
|
|
Packit Service |
8876fe |
void newtResume(void);
|
|
Packit Service |
8876fe |
</screen>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<literal remap="tt">newtSuspend()</literal> tells <literal remap="tt">newt</literal> to return the terminal to its initial
|
|
Packit Service |
8876fe |
state. Once this is done, the application can suspend itself (by
|
|
Packit Service |
8876fe |
sending itself a <literal remap="tt">SIGTSTP</literal>, fork a child program, or do whatever
|
|
Packit Service |
8876fe |
else it likes. When it wants to resume using the <literal remap="tt">newt</literal> interface,
|
|
Packit Service |
8876fe |
it must call <literal remap="tt">newtResume</literal> before doing so.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
Note that suspend callbacks are not signal handlers. When <literal remap="tt">newtInit()</literal>
|
|
Packit Service |
8876fe |
takes over the terminal, it disables the part of the terminal interface
|
|
Packit Service |
8876fe |
which sends the suspend signal. Instead, if <literal remap="tt">newt</literal> sees the suspend
|
|
Packit Service |
8876fe |
keystroke during normal input processing, it immediately calls the suspend
|
|
Packit Service |
8876fe |
callback if one has been set. This means that suspending newt applications
|
|
Packit Service |
8876fe |
is not asynchronous.</para></sect2>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<sect2><title>Refreshing the Screen</title>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
To increase performance, S-Lang only updates the display when it needs
|
|
Packit Service |
8876fe |
to, not when the program tells S-Lang to write to the terminal. ``When it
|
|
Packit Service |
8876fe |
needs to'' is implemented as ``right before the we wait for the user to
|
|
Packit Service |
8876fe |
press a key''. While this allows for optimized screen displays most of
|
|
Packit Service |
8876fe |
the time, this optimization makes things difficult for programs which
|
|
Packit Service |
8876fe |
want to display progress messages without forcing the user to input
|
|
Packit Service |
8876fe |
characters. Applications can force S-Lang to immediately update modified
|
|
Packit Service |
8876fe |
portions of the screen by calling <literal remap="tt">newtRefresh</literal>.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<orderedlist>
|
|
Packit Service |
8876fe |
<listitem>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
The program wants to display a progress message, without forcing
|
|
Packit Service |
8876fe |
for the user to enter any characters.</para></listitem>
|
|
Packit Service |
8876fe |
<listitem>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
A misfeature of the program causes part of the screen to be
|
|
Packit Service |
8876fe |
corrupted. Ideally, the program would be fixed, but that may not
|
|
Packit Service |
8876fe |
always be practical.
|
|
Packit Service |
8876fe |
</para>
|
|
Packit Service |
8876fe |
</listitem></orderedlist>
|
|
Packit Service |
8876fe |
</para></sect2>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<sect2><title>Other Miscellaneous Functions</title>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
As always, some function defy characterization. Two of <literal remap="tt">newt</literal>'s general
|
|
Packit Service |
8876fe |
function fit this oddball category.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<screen>
|
|
Packit Service |
8876fe |
void newtBell(void);
|
|
Packit Service |
8876fe |
void newtGetScreenSize(int * cols, int * rows);
|
|
Packit Service |
8876fe |
</screen>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
The first sends a beep to the terminal. Depending on the terminal's
|
|
Packit Service |
8876fe |
settings, this been may or may not be audible. The second function,
|
|
Packit Service |
8876fe |
<literal remap="tt">newtGetScreenSize()</literal>, fills in the passed pointers with the
|
|
Packit Service |
8876fe |
current size of the terminal.</para></sect2>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<sect2><title>Basic <literal remap="tt">newt</literal> Example</title>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
To help illustrate the functions presented in this section here is a short
|
|
Packit Service |
8876fe |
sample <literal remap="tt">newt</literal> program which uses many of them. While it doesn't do
|
|
Packit Service |
8876fe |
anything interesting, it does show the basic structure of <literal remap="tt">newt</literal> programs.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<screen>
|
|
Packit Service |
8876fe |
#include <newt.h>
|
|
Packit Service |
8876fe |
#include <stdlib.h>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
int main(void) {
|
|
Packit Service |
8876fe |
newtInit();
|
|
Packit Service |
8876fe |
newtCls();
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
newtDrawRootText(0, 0, "Some root text");
|
|
Packit Service |
8876fe |
newtDrawRootText(-25, -2, "Root text in the other corner");
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
newtPushHelpLine(NULL);
|
|
Packit Service |
8876fe |
newtRefresh();
|
|
Packit Service |
8876fe |
sleep(1);
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
newtPushHelpLine("A help line");
|
|
Packit Service |
8876fe |
newtRefresh();
|
|
Packit Service |
8876fe |
sleep(1);
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
newtPopHelpLine();
|
|
Packit Service |
8876fe |
newtRefresh();
|
|
Packit Service |
8876fe |
sleep(1);
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
newtFinished();
|
|
Packit Service |
8876fe |
}
|
|
Packit Service |
8876fe |
</screen></para></sect2></sect1>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<sect1><title>Windows</title>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
While most <literal remap="tt">newt</literal> applications do use windows, <literal remap="tt">newt</literal>'s window
|
|
Packit Service |
8876fe |
support is actually extremely limited. Windows must be destroyed in the
|
|
Packit Service |
8876fe |
opposite of the order they were created, and only the topmost window may be
|
|
Packit Service |
8876fe |
active. Corollaries to this are:
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<itemizedlist>
|
|
Packit Service |
8876fe |
<listitem>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
The user may not switch between windows.</para></listitem>
|
|
Packit Service |
8876fe |
<listitem>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
Only the top window may be destroyed.
|
|
Packit Service |
8876fe |
</para>
|
|
Packit Service |
8876fe |
</listitem></itemizedlist>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
While this is quite a severe limitation, adopting it greatly simplifies
|
|
Packit Service |
8876fe |
both writing <literal remap="tt">newt</literal> applications and developing <literal remap="tt">newt</literal> itself, as it
|
|
Packit Service |
8876fe |
separates <literal remap="tt">newt</literal> from the world of event-driven programming. However,
|
|
Packit Service |
8876fe |
this tradeoff between function and simplicity may make <literal remap="tt">newt</literal>
|
|
Packit Service |
8876fe |
unsuitable for some tasks.
|
|
Packit Service |
8876fe |
</para>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<sect2><title>Creating Windows</title>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
There are two main ways of opening <literal remap="tt">newt</literal> windows: with or without
|
|
Packit Service |
8876fe |
explicit sizings. When grids (which will be introduced later in this
|
|
Packit Service |
8876fe |
tutorial) are used, a window may be made to just fit the grid. When
|
|
Packit Service |
8876fe |
grids are not used, explicit sizing must be given.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<screen>
|
|
Packit Service |
8876fe |
int newtCenteredWindow(int width, int height, const char * title);
|
|
Packit Service |
8876fe |
int newtOpenWindow(int left, int top, int width, int height,
|
|
Packit Service |
8876fe |
const char * title);
|
|
Packit Service |
8876fe |
</screen>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
The first of these functions open a centered window of the specified
|
|
Packit Service |
8876fe |
size. The <literal remap="tt">title</literal> is optional -- if it is <literal remap="tt">NULL</literal>, then no title
|
|
Packit Service |
8876fe |
is used. <literal remap="tt">newtOpenWindow*(</literal> is similar, but it requires a specific
|
|
Packit Service |
8876fe |
location for the upper left-hand corner of the window.</para></sect2>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<sect2><title>Destroying Windows</title>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
All windows are destroyed in the same manner, no matter how the windows
|
|
Packit Service |
8876fe |
were originally created.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<screen>
|
|
Packit Service |
8876fe |
void newtPopWindow(void);
|
|
Packit Service |
8876fe |
</screen>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
This function removes the top window from the display, and redraws the
|
|
Packit Service |
8876fe |
display areas which the window overwrote.</para></sect2></sect1>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<sect1><title>Components</title>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
Components are the basic user interface element <literal remap="tt">newt</literal> provides. A
|
|
Packit Service |
8876fe |
single component may be (for example) a listbox, push button checkbox,
|
|
Packit Service |
8876fe |
a collection of other components. Most components are used to display
|
|
Packit Service |
8876fe |
information in a window, provide a place for the user to enter data, or a
|
|
Packit Service |
8876fe |
combination of these two functions.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
Forms, however, are a component whose primary purpose is not noticed by
|
|
Packit Service |
8876fe |
the user at all. Forms are collections of components (a form may contain
|
|
Packit Service |
8876fe |
another form) which logically relate the components to one another. Once
|
|
Packit Service |
8876fe |
a form is created and had all of its constituent components added to it,
|
|
Packit Service |
8876fe |
applications normally then run the form. This gives control of the
|
|
Packit Service |
8876fe |
application to the form, which then lets the user enter data onto the
|
|
Packit Service |
8876fe |
form. When the user is done (a number of different events qualify as
|
|
Packit Service |
8876fe |
``done''), the form returns control to the part of the application which
|
|
Packit Service |
8876fe |
invoked it. The application may then read the information the user provided
|
|
Packit Service |
8876fe |
and continue appropriately.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
All <literal remap="tt">newt</literal> components are stored in a common data type, a
|
|
Packit Service |
8876fe |
<literal remap="tt">newtComponent</literal> (some of the particulars of <literal remap="tt">newtComponent</literal>s have
|
|
Packit Service |
8876fe |
already been mentioned. While this makes it easy for programmers to pass
|
|
Packit Service |
8876fe |
components around, it does force them to make sure they don't pass
|
|
Packit Service |
8876fe |
entry boxes to routines expecting push buttons, as the compiler can't
|
|
Packit Service |
8876fe |
ensure that for them.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
We start off with a brief introduction to forms. While not terribly
|
|
Packit Service |
8876fe |
complete, this introduction is enough to let us illustrate the rest of
|
|
Packit Service |
8876fe |
the components with some sample code. We'll then discuss the remainder of
|
|
Packit Service |
8876fe |
the components, and end this section with a more exhaustive description of
|
|
Packit Service |
8876fe |
forms.</para>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<sect2><title>Introduction to Forms</title>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
As we've mentioned, forms are simply collections of components. As only one
|
|
Packit Service |
8876fe |
form can be active (or running) at a time, every component which the user
|
|
Packit Service |
8876fe |
should be able to access must be on the running form (or on a subform of
|
|
Packit Service |
8876fe |
the running form). A form is itself a component, which means forms are
|
|
Packit Service |
8876fe |
stored in <literal remap="tt">newtComponent</literal> data structures.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<screen>
|
|
Packit Service |
8876fe |
newtComponent newtForm(newtComponent vertBar, const char * help, int flags);
|
|
Packit Service |
8876fe |
</screen>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
To create a form, call <literal remap="tt">newtForm()</literal>. The first parameter is a vertical
|
|
Packit Service |
8876fe |
scrollbar which should be associated with the form. For now, that should
|
|
Packit Service |
8876fe |
always be <literal remap="tt">NULL</literal> (we'll discuss how to create scrolling forms later in
|
|
Packit Service |
8876fe |
this section). The second parameter, <literal remap="tt">help</literal>, is currently unused and
|
|
Packit Service |
8876fe |
should always be <literal remap="tt">NULL</literal>. The <literal remap="tt">flags</literal> is normally 0, and other values
|
|
Packit Service |
8876fe |
it can take will be discussed later. Now that we've waved away the
|
|
Packit Service |
8876fe |
complexity of this function, creating a form boils down to simply:
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<screen>
|
|
Packit Service |
8876fe |
newtComponent myForm;
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
myForm = newtForm(NULL, NULL, 0);
|
|
Packit Service |
8876fe |
</screen>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
After a form is created, components need to be added to it --- after all,
|
|
Packit Service |
8876fe |
an empty form isn't terribly useful. There are two functions which add
|
|
Packit Service |
8876fe |
components to a form.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<screen>
|
|
Packit Service |
8876fe |
void newtFormAddComponent(newtComponent form, newtComponent co);
|
|
Packit Service |
8876fe |
void newtFormAddComponents(newtComponent form, ...);
|
|
Packit Service |
8876fe |
</screen>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
The first function, <literal remap="tt">newtFormAddComponent()</literal>, adds a single component
|
|
Packit Service |
8876fe |
to the form which is passed as the first parameter. The second function
|
|
Packit Service |
8876fe |
is simply a convenience function. After passing the form to
|
|
Packit Service |
8876fe |
<literal remap="tt">newtFormAddComponents()</literal>, an arbitrary number of components is then
|
|
Packit Service |
8876fe |
passed, followed by <literal remap="tt">NULL</literal>. Every component passed is added to the form.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
Once a form has been created and components have been added to it, it's
|
|
Packit Service |
8876fe |
time to run the form.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<screen>
|
|
Packit Service |
8876fe |
newtComponent newtRunForm(newtComponent form);
|
|
Packit Service |
8876fe |
</screen>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
This function runs the form passed to it, and returns the component which
|
|
Packit Service |
8876fe |
caused the form to stop running. For now, we'll ignore the return value
|
|
Packit Service |
8876fe |
completely.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
Notice that this function doesn't fit in with <literal remap="tt">newt</literal>'s normal
|
|
Packit Service |
8876fe |
naming convention. It is an older interface which will not work for all
|
|
Packit Service |
8876fe |
forms. It was left in <literal remap="tt">newt</literal> only for legacy applications. It is a
|
|
Packit Service |
8876fe |
simpler interface than the new <literal remap="tt">newtFormRun()</literal> though, and is still used
|
|
Packit Service |
8876fe |
quite often as a result.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
When an application is done with a form, it destroys the form and
|
|
Packit Service |
8876fe |
all of the components the form contains.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<screen>
|
|
Packit Service |
8876fe |
void newtFormDestroy(newtComponent form);
|
|
Packit Service |
8876fe |
</screen>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
This function frees the memory resources used by the form and all of the
|
|
Packit Service |
8876fe |
components which have been added to the form (including those components
|
|
Packit Service |
8876fe |
which are on subforms). Once a form has been destroyed, none of the form's
|
|
Packit Service |
8876fe |
components can be used.</para></sect2>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<sect2><title>Components</title>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
Non-form components are the most important user-interface component for
|
|
Packit Service |
8876fe |
users. They determine how users interact with <literal remap="tt">newt</literal> and how information
|
|
Packit Service |
8876fe |
is presented to them.</para></sect2>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<sect2><title>General Component Manipulation</title>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
There are a couple of functions which work on more then one type of
|
|
Packit Service |
8876fe |
components. The description of each component indicates which (if any)
|
|
Packit Service |
8876fe |
of these functions are valid for that particular component.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<screen>
|
|
Packit Service |
8876fe |
typedef void (*newtCallback)(newtComponent, void *);
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
void newtComponentAddCallback(newtComponent co, newtCallback f, void * data);
|
|
Packit Service |
8876fe |
void newtComponentTakesFocus(newtComponent co, int val);
|
|
Packit Service |
8876fe |
</screen>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
The first registers a callback function for that component. A callback
|
|
Packit Service |
8876fe |
function is a function the application provides which <literal remap="tt">newt</literal> calls for a
|
|
Packit Service |
8876fe |
particular component. Exactly when (if ever) the callback is invoked
|
|
Packit Service |
8876fe |
depends on the type of component the callback is attached to, and will be
|
|
Packit Service |
8876fe |
discussed for the components which support callbacks.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<literal remap="tt">newtComponentTakesFocus()</literal> works on all components. It allows the
|
|
Packit Service |
8876fe |
application to change which components the user is allowed to select as the
|
|
Packit Service |
8876fe |
current component, and hence provide input to. Components which do not
|
|
Packit Service |
8876fe |
take focus are skipped over during form traversal, but they are displayed
|
|
Packit Service |
8876fe |
on the terminal. Some components should never be set to take focus, such
|
|
Packit Service |
8876fe |
as those which display static text.</para></sect2>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<sect2><title>Buttons</title>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
Nearly all forms contain at least one button. <literal remap="tt">Newt</literal> buttons come in two
|
|
Packit Service |
8876fe |
flavors, full buttons and compact buttons. Full buttons take up quit a bit
|
|
Packit Service |
8876fe |
of screen space, but look much better then the single-row compact buttons.
|
|
Packit Service |
8876fe |
Other then their size, both button styles behave identically. Different
|
|
Packit Service |
8876fe |
functions are used to create the two types of buttons.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<screen>
|
|
Packit Service |
8876fe |
newtComponent newtButton(int left, int top, const char * text);
|
|
Packit Service |
8876fe |
newtComponent newtCompactButton(int left, int top, const char * text);
|
|
Packit Service |
8876fe |
</screen>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
Both functions take identical parameters. The first two parameters are the
|
|
Packit Service |
8876fe |
location of the upper left corner of the button, and the final parameter is
|
|
Packit Service |
8876fe |
the text which should be displayed in the button (such as ``Ok'' or
|
|
Packit Service |
8876fe |
``Cancel'').</para>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<sect3><title>Button Example</title>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
Here is a simple example of both full and compact buttons. It also
|
|
Packit Service |
8876fe |
illustrates opening and closing windows, as well a simple form.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<screen>
|
|
Packit Service |
8876fe |
#include <newt.h>
|
|
Packit Service |
8876fe |
#include <stdlib.h>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
void main(void) {
|
|
Packit Service |
8876fe |
newtComponent form, b1, b2;
|
|
Packit Service |
8876fe |
newtInit();
|
|
Packit Service |
8876fe |
newtCls();
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
newtOpenWindow(10, 5, 40, 6, "Button Sample");
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
b1 = newtButton(10, 1, "Ok");
|
|
Packit Service |
8876fe |
b2 = newtCompactButton(22, 2, "Cancel");
|
|
Packit Service |
8876fe |
form = newtForm(NULL, NULL, 0);
|
|
Packit Service |
8876fe |
newtFormAddComponents(form, b1, b2, NULL);
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
newtRunForm(form);
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
newtFormDestroy(form);
|
|
Packit Service |
8876fe |
newtFinished();
|
|
Packit Service |
8876fe |
}
|
|
Packit Service |
8876fe |
</screen></para></sect3></sect2>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<sect2><title>Labels</title>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
Labels are <literal remap="tt">newt</literal>'s simplest component. They display some given text and
|
|
Packit Service |
8876fe |
don't allow any user input.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<screen>
|
|
Packit Service |
8876fe |
newtComponent newtLabel(int left, int top, const char * text);
|
|
Packit Service |
8876fe |
void newtLabelSetText(newtComponent co, const char * text);
|
|
Packit Service |
8876fe |
</screen>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
Creating a label is just like creating a button; just pass the location of
|
|
Packit Service |
8876fe |
the label and the text it should display. Unlike buttons, labels do let the
|
|
Packit Service |
8876fe |
application change the text in the label with <literal remap="tt">newtLabelSetText</literal>. When
|
|
Packit Service |
8876fe |
the label's text is changed, the label automatically redraws itself. It
|
|
Packit Service |
8876fe |
does not clear out any old text which may be leftover from the previous
|
|
Packit Service |
8876fe |
time is was displayed, however, so be sure that the new text is at least
|
|
Packit Service |
8876fe |
as long as the old text.</para></sect2>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<sect2><title>Entry Boxes</title>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
Entry boxes allow the user to enter a text string into the form which the
|
|
Packit Service |
8876fe |
application can later retrieve.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<screen>
|
|
Packit Service |
8876fe |
typedef int (*newtEntryFilter)(newtComponent entry, void * data, int ch,
|
|
Packit Service |
8876fe |
int cursor);
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
newtComponent newtEntry(int left, int top, const char * initialValue, int width,
|
|
Packit Service |
8876fe |
char ** resultPtr, int flags);
|
|
Packit Service |
8876fe |
void newtEntrySet(newtComponent co, const char * value, int cursorAtEnd);
|
|
Packit Service |
8876fe |
char * newtEntryGetValue(newtComponent co);
|
|
Packit Service |
8876fe |
void newtEntrySetFilter(newtComponent co, newtEntryFilter filter, void * data);
|
|
Packit Service |
8876fe |
</screen></para>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
<literal remap="tt">newtEntry()</literal> creates a new entry box. After the location of the entry
|
|
Packit Service |
8876fe |
box, the initial value for the entry box is passed, which may be <literal remap="tt">NULL</literal>
|
|
Packit Service |
8876fe |
if the box should start off empty. Next, the width of the physical box is
|
|
Packit Service |
8876fe |
given. This width may or may not limit the length of the string the user is
|
|
Packit Service |
8876fe |
allowed to enter; that depends on the <literal remap="tt">flags</literal>. The <literal remap="tt">resultPtr</literal> must
|
|
Packit Service |
8876fe |
be the address of a <literal remap="tt">char *</literal>. Until the entry box is destroyed by
|
|
Packit Service |
8876fe |
<literal remap="tt">newtFormDestroy()</literal>, that <literal remap="tt">char *</literal> will point to the current value
|
|
Packit Service |
8876fe |
of the entry box. It's important that applications make a copy of that
|
|
Packit Service |
8876fe |
value before destroying the form if they need to use it later. The
|
|
Packit Service |
8876fe |
<literal remap="tt">resultPtr</literal> may be <literal remap="tt">NULL</literal>, in which case the user must use the
|
|
Packit Service |
8876fe |
<literal remap="tt">newtEntryGetValue()</literal> function to get the value of the entry box.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
Entry boxes support a number of flags:
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<variablelist>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<varlistentry>
|
|
Packit Service |
8876fe |
<term>NEWT_ENTRY_SCROLL</term>
|
|
Packit Service |
8876fe |
<listitem>
|
|
Packit Service |
8876fe |
<para>If this flag is not specified, the user cannot
|
|
Packit Service |
8876fe |
enter text into the entry box which is wider then the entry box itself.
|
|
Packit Service |
8876fe |
This flag removes this limitation, and lets the user enter data of an
|
|
Packit Service |
8876fe |
arbitrary length.</para></listitem>
|
|
Packit Service |
8876fe |
</varlistentry>
|
|
Packit Service |
8876fe |
<varlistentry>
|
|
Packit Service |
8876fe |
<term>NEWT_FLAG_HIDDEN</term>
|
|
Packit Service |
8876fe |
<listitem>
|
|
Packit Service |
8876fe |
<para>If this flag is specified, the value of the entry box
|
|
Packit Service |
8876fe |
is not displayed. This is useful when the application needs to read a
|
|
Packit Service |
8876fe |
password, for example.</para></listitem>
|
|
Packit Service |
8876fe |
</varlistentry>
|
|
Packit Service |
8876fe |
<varlistentry>
|
|
Packit Service |
8876fe |
<term>NEWT_FLAG_RETURNEXIT</term>
|
|
Packit Service |
8876fe |
<listitem>
|
|
Packit Service |
8876fe |
<para>When this flag is given, the entry box will cause
|
|
Packit Service |
8876fe |
the form to stop running if the user pressed return inside of the entry
|
|
Packit Service |
8876fe |
box. This can provide a nice shortcut for users.</para>
|
|
Packit Service |
8876fe |
</listitem>
|
|
Packit Service |
8876fe |
</varlistentry>
|
|
Packit Service |
8876fe |
</variablelist>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
After an entry box has been created, its contents can be set by
|
|
Packit Service |
8876fe |
<literal remap="tt">newtEntrySet()</literal>. After the entry box itself, the new string to place
|
|
Packit Service |
8876fe |
in the entry box is passed. The final parameter, <literal remap="tt">cursorAtEnd</literal>, controls
|
|
Packit Service |
8876fe |
where the cursor will appear in the entry box. If it is zero, the cursor
|
|
Packit Service |
8876fe |
remains at its present location; a nonzero value moves the cursor to the
|
|
Packit Service |
8876fe |
end of the entry box's new value.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
While the simplest way to find the value of an entry box is by using a
|
|
Packit Service |
8876fe |
<literal remap="tt">resultPtr</literal>, doing so complicates some applications.
|
|
Packit Service |
8876fe |
<literal remap="tt">newtEntryGetValue()</literal> returns a pointer to the string which the entry
|
|
Packit Service |
8876fe |
box currently contains. The returned pointer may not be valid once the
|
|
Packit Service |
8876fe |
user further modifies the entry box, and will not be valid after the
|
|
Packit Service |
8876fe |
entry box has been destroyed, so be sure to save its value in a more
|
|
Packit Service |
8876fe |
permanent location if necessary.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
Entry boxes allow applications to filter characters as they are entered.
|
|
Packit Service |
8876fe |
This allows programs to ignore characters which are invalid (such as
|
|
Packit Service |
8876fe |
entering a ^ in the middle of a phone number) and provide intelligent aids
|
|
Packit Service |
8876fe |
to the user (such as automatically adding a '.' after the user has typed in
|
|
Packit Service |
8876fe |
the first three numbers in an IP address).
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
When a filter is registered through <literal remap="tt">newtEntrySetFilter()</literal>, both the
|
|
Packit Service |
8876fe |
filter itself and an arbitrary <literal remap="tt">void *</literal>, which passed to the filter
|
|
Packit Service |
8876fe |
whenever it is invoked, are recorded. This data pointer isn't used for any
|
|
Packit Service |
8876fe |
other purpose, and may be <literal remap="tt">NULL</literal>. Entry filters take four arguments.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<orderedlist>
|
|
Packit Service |
8876fe |
<listitem>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
The entry box which had data entered into it</para></listitem>
|
|
Packit Service |
8876fe |
<listitem>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
The data pointer which was registered along with the filter</para></listitem>
|
|
Packit Service |
8876fe |
<listitem>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
The new character which <literal remap="tt">newt</literal> is considering inserting into the
|
|
Packit Service |
8876fe |
entry box</para></listitem>
|
|
Packit Service |
8876fe |
<listitem>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
The current cursor position (0 is the leftmost position)
|
|
Packit Service |
8876fe |
</para>
|
|
Packit Service |
8876fe |
</listitem>
|
|
Packit Service |
8876fe |
</orderedlist>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
The filter returns 0 if the character should be ignored, or the value of
|
|
Packit Service |
8876fe |
the character which should be inserted into the entry box. Filter functions
|
|
Packit Service |
8876fe |
which want to do complex manipulations of the string should use
|
|
Packit Service |
8876fe |
<literal remap="tt">newtEntrySet()</literal> to update the entry box and then return 0 to prevent
|
|
Packit Service |
8876fe |
the new character from being inserted.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
When a callback is attached to a entry box, the callback is invoked
|
|
Packit Service |
8876fe |
whenever the user moves off of the callback and on to another component.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
Here is a sample program which illustrates the use of both labels and
|
|
Packit Service |
8876fe |
entry boxes.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<screen>
|
|
Packit Service |
8876fe |
#include <newt.h>
|
|
Packit Service |
8876fe |
#include <stdlib.h>
|
|
Packit Service |
8876fe |
#include <stdio.h>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
void main(void) {
|
|
Packit Service |
8876fe |
newtComponent form, label, entry, button;
|
|
Packit Service |
8876fe |
char * entryValue;
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
newtInit();
|
|
Packit Service |
8876fe |
newtCls();
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
newtOpenWindow(10, 5, 40, 8, "Entry and Label Sample");
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
label = newtLabel(1, 1, "Enter a string");
|
|
Packit Service |
8876fe |
entry = newtEntry(16, 1, "sample", 20, &entryValue,
|
|
Packit Service |
8876fe |
NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT);
|
|
Packit Service |
8876fe |
button = newtButton(17, 3, "Ok");
|
|
Packit Service |
8876fe |
form = newtForm(NULL, NULL, 0);
|
|
Packit Service |
8876fe |
newtFormAddComponents(form, label, entry, button, NULL);
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
newtRunForm(form);
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
newtFinished();
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
printf("Final string was: %s\n", entryValue);
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
/* We cannot destroy the form until after we've used the value
|
|
Packit Service |
8876fe |
from the entry widget. */
|
|
Packit Service |
8876fe |
newtFormDestroy(form);
|
|
Packit Service |
8876fe |
}
|
|
Packit Service |
8876fe |
</screen></para></sect2>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<sect2><title>Checkboxes</title>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
Most widget sets include checkboxes which toggle between two value (checked
|
|
Packit Service |
8876fe |
or not checked). <literal remap="tt">Newt</literal> checkboxes are more flexible. When the user
|
|
Packit Service |
8876fe |
presses the space bar on a checkbox, the checkbox's value changes to the
|
|
Packit Service |
8876fe |
next value in an arbitrary sequence (which wraps). Most checkboxes have
|
|
Packit Service |
8876fe |
two items in that sequence, checked or not, but <literal remap="tt">newt</literal> allows an
|
|
Packit Service |
8876fe |
arbitrary number of value. This is useful when the user must pick from a
|
|
Packit Service |
8876fe |
limited number of choices.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
Each item in the sequence is a single character, and the sequence itself is
|
|
Packit Service |
8876fe |
represented as a string. The checkbox components displays the character
|
|
Packit Service |
8876fe |
which currently represents its value the left of a text label, and returns
|
|
Packit Service |
8876fe |
the same character as its current value. The default sequence for
|
|
Packit Service |
8876fe |
checkboxes is <literal remap="tt">" *"</literal>, with <literal remap="tt">' '</literal> indicating false and <literal remap="tt">'*'</literal> true.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<screen>
|
|
Packit Service |
8876fe |
newtComponent newtCheckbox(int left, int top, const char * text, char defValue,
|
|
Packit Service |
8876fe |
const char * seq, char * result);
|
|
Packit Service |
8876fe |
char newtCheckboxGetValue(newtComponent co);
|
|
Packit Service |
8876fe |
</screen></para>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
Like most components, the position of the checkbox is the first thing
|
|
Packit Service |
8876fe |
passed to the function that creates one. The next parameter, <literal remap="tt">text</literal>, is
|
|
Packit Service |
8876fe |
the text which is displayed to the right of the area which is checked. The
|
|
Packit Service |
8876fe |
<literal remap="tt">defValue</literal> is the initial value for the checkbox, and <literal remap="tt">seq</literal> is the
|
|
Packit Service |
8876fe |
sequence which the checkbox should go through (<literal remap="tt">defValue</literal> must be
|
|
Packit Service |
8876fe |
in <literal remap="tt">seq</literal>. <literal remap="tt">seq</literal> may be <literal remap="tt">NULL</literal>, in which case <literal remap="tt">" *"</literal> is used.
|
|
Packit Service |
8876fe |
The final parameter, <literal remap="tt">result</literal>, should point to a character which the
|
|
Packit Service |
8876fe |
checkbox should always record its current value in. If <literal remap="tt">result</literal> is
|
|
Packit Service |
8876fe |
<literal remap="tt">NULL</literal>, <literal remap="tt">newtCheckboxGetValue()</literal> must be used to get the current
|
|
Packit Service |
8876fe |
value of the checkbox.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<literal remap="tt">newtCheckboxGetValue()</literal> is straightforward, returning the character
|
|
Packit Service |
8876fe |
in the sequence which indicates the current value of the checkbox
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
If a callback is attached to a checkbox, the callback is invoked whenever
|
|
Packit Service |
8876fe |
the checkbox responds to a user's keystroke. The entry box may respond by
|
|
Packit Service |
8876fe |
taking focus or giving up focus, as well as by changing its current value.</para></sect2>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<sect2><title>Radio Buttons</title>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
Radio buttons look very similar to checkboxes. The key difference between
|
|
Packit Service |
8876fe |
the two is that radio buttons are grouped into sets, and exactly one radio
|
|
Packit Service |
8876fe |
button in that set may be turned on. If another radio button is selected,
|
|
Packit Service |
8876fe |
the button which was selected is automatically deselected.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<screen>
|
|
Packit Service |
8876fe |
newtComponent newtRadiobutton(int left, int top, const char * text,
|
|
Packit Service |
8876fe |
int isDefault, newtComponent prevButton);
|
|
Packit Service |
8876fe |
newtComponent newtRadioGetCurrent(newtComponent setMember);
|
|
Packit Service |
8876fe |
</screen>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
Each radio button is created by calling <literal remap="tt">newtRadiobutton()</literal>. After
|
|
Packit Service |
8876fe |
the position of the radio button, the text displayed with the button
|
|
Packit Service |
8876fe |
is passed. <literal remap="tt">isDefault</literal> should be nonzero if the radio button is to
|
|
Packit Service |
8876fe |
be turned on by default. The final parameter, <literal remap="tt">prevMember</literal> is used
|
|
Packit Service |
8876fe |
to group radio buttons into sets. If <literal remap="tt">prevMember</literal> is <literal remap="tt">NULL</literal>, the
|
|
Packit Service |
8876fe |
radio button is assigned to a new set. If the radio button should belong
|
|
Packit Service |
8876fe |
to a preexisting set, <literal remap="tt">prevMember</literal> must be the previous radio button
|
|
Packit Service |
8876fe |
added to that set.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
Discovering which radio button in a set is currently selected necessitates
|
|
Packit Service |
8876fe |
<literal remap="tt">newtRadioGetCurrent()</literal>. It may be passed any radio button in the set
|
|
Packit Service |
8876fe |
you're interested in, and it returns the radio button component currently
|
|
Packit Service |
8876fe |
selected.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
Here is an example of both checkboxes and radio buttons.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<screen>
|
|
Packit Service |
8876fe |
#include <newt.h>
|
|
Packit Service |
8876fe |
#include <stdlib.h>
|
|
Packit Service |
8876fe |
#include <stdio.h>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
void main(void) {
|
|
Packit Service |
8876fe |
newtComponent form, checkbox, rb[3], button;
|
|
Packit Service |
8876fe |
char cbValue;
|
|
Packit Service |
8876fe |
int i;
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
newtInit();
|
|
Packit Service |
8876fe |
newtCls();
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
newtOpenWindow(10, 5, 40, 11, "Checkboxes and Radio buttons");
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
checkbox = newtCheckbox(1, 1, "A checkbox", ' ', " *X", &cbValue);
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
rb[0] = newtRadiobutton(1, 3, "Choice 1", 1, NULL);
|
|
Packit Service |
8876fe |
rb[1] = newtRadiobutton(1, 4, "Choice 2", 0, rb[0]);
|
|
Packit Service |
8876fe |
rb[2] = newtRadiobutton(1, 5, "Choice 3", 0, rb[1]);
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
button = newtButton(1, 7, "Ok");
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
form = newtForm(NULL, NULL, 0);
|
|
Packit Service |
8876fe |
newtFormAddComponent(form, checkbox);
|
|
Packit Service |
8876fe |
for (i = 0; i < 3; i++)
|
|
Packit Service |
8876fe |
newtFormAddComponent(form, rb[i]);
|
|
Packit Service |
8876fe |
newtFormAddComponent(form, button);
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
newtRunForm(form);
|
|
Packit Service |
8876fe |
newtFinished();
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
/* We cannot destroy the form until after we've found the current
|
|
Packit Service |
8876fe |
radio button */
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
for (i = 0; i < 3; i++)
|
|
Packit Service |
8876fe |
if (newtRadioGetCurrent(rb[0]) == rb[i])
|
|
Packit Service |
8876fe |
printf("radio button picked: %d\n", i);
|
|
Packit Service |
8876fe |
newtFormDestroy(form);
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
/* But the checkbox's value is stored locally */
|
|
Packit Service |
8876fe |
printf("checkbox value: '%c'\n", cbValue);
|
|
Packit Service |
8876fe |
}
|
|
Packit Service |
8876fe |
</screen></para></sect2>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<sect2><title>Scales</title>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
It's common for programs to need to display a progress meter on the
|
|
Packit Service |
8876fe |
terminal while it performs some length operation (it behaves like an
|
|
Packit Service |
8876fe |
anesthetic). The scale component is a simple way of doing this. It
|
|
Packit Service |
8876fe |
displays a horizontal bar graph which the application can update as the
|
|
Packit Service |
8876fe |
operation continues.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<screen>
|
|
Packit Service |
8876fe |
newtComponent newtScale(int left, int top, int width, long long fullValue);
|
|
Packit Service |
8876fe |
void newtScaleSet(newtComponent co, unsigned long long amount);
|
|
Packit Service |
8876fe |
</screen>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
When the scale is created with <literal remap="tt">newtScale</literal>, it is given the width of the
|
|
Packit Service |
8876fe |
scale itself as well as the value which means that the scale should be
|
|
Packit Service |
8876fe |
drawn as full. When the position of the scale is set with
|
|
Packit Service |
8876fe |
<literal remap="tt">newtScaleSet()</literal>, the scale is told the amount of the scale which should
|
|
Packit Service |
8876fe |
be filled in relative to the <literal remap="tt">fullAmount</literal>. For example, if the
|
|
Packit Service |
8876fe |
application is copying a file, <literal remap="tt">fullValue</literal> could be the number of bytes
|
|
Packit Service |
8876fe |
in the file, and when the scale is updated <literal remap="tt">newtScaleSet()</literal> would be
|
|
Packit Service |
8876fe |
passed the number of bytes which have been copied so far.</para></sect2>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<sect2><title>Textboxes</title>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
Textboxes display a block of text on the terminal, and is appropriate for
|
|
Packit Service |
8876fe |
display large amounts of text.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<screen>
|
|
Packit Service |
8876fe |
newtComponent newtTextbox(int left, int top, int width, int height, int flags);
|
|
Packit Service |
8876fe |
void newtTextboxSetText(newtComponent co, const char * text);
|
|
Packit Service |
8876fe |
</screen>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<literal remap="tt">newtTextbox()</literal> creates a new textbox, but does not fill it with data.
|
|
Packit Service |
8876fe |
The function is passed the location for the textbox on the screen, the
|
|
Packit Service |
8876fe |
width and height of the textbox (in characters), and zero or more of the
|
|
Packit Service |
8876fe |
following flags:
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<variablelist>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<varlistentry>
|
|
Packit Service |
8876fe |
<term>NEWT_FLAG_WRAP</term>
|
|
Packit Service |
8876fe |
<listitem>
|
|
Packit Service |
8876fe |
<para>All text in the textbox should be wrapped to fit
|
|
Packit Service |
8876fe |
the width of the textbox. If this flag is not specified, each newline
|
|
Packit Service |
8876fe |
delimited line in the text is truncated if it is too long to fit.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
When <literal remap="tt">newt</literal> wraps text, it tries not to break lines on spaces or tabs.
|
|
Packit Service |
8876fe |
Literal newline characters are respected, and may be used to force line
|
|
Packit Service |
8876fe |
breaks.</para>
|
|
Packit Service |
8876fe |
<variablelist>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<varlistentry>
|
|
Packit Service |
8876fe |
<term>NEWT_FLAG_SCROLL</term>
|
|
Packit Service |
8876fe |
<listitem>
|
|
Packit Service |
8876fe |
<para>The text box should be scrollable. When this option
|
|
Packit Service |
8876fe |
is used, the scrollbar which is added increases the width of the area used
|
|
Packit Service |
8876fe |
by the textbox by 2 characters; that is the textbox is 2 characters wider
|
|
Packit Service |
8876fe |
then the width passed to <literal remap="tt">newtTextbox()</literal>.
|
|
Packit Service |
8876fe |
</para></listitem>
|
|
Packit Service |
8876fe |
</varlistentry>
|
|
Packit Service |
8876fe |
</variablelist>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
After a textbox has been created, text may be added to it through
|
|
Packit Service |
8876fe |
<literal remap="tt">newtTextboxSetText()</literal>, which takes only the textbox and the new text as
|
|
Packit Service |
8876fe |
parameters. If the textbox already contained text, that text is replaced by
|
|
Packit Service |
8876fe |
the new text. The textbox makes its own copy of the passed text, so these
|
|
Packit Service |
8876fe |
is no need to keep the original around unless it's convenient.</para></listitem></varlistentry></variablelist></para>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<sect3><title>Reflowing Text</title>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
When applications need to display large amounts of text, it's common not to
|
|
Packit Service |
8876fe |
know exactly where the linebreaks should go. While textboxes are quite
|
|
Packit Service |
8876fe |
willing to scroll the text, the programmer still must know what width the
|
|
Packit Service |
8876fe |
text will look ``best'' at (where ``best'' means most exactly rectangular;
|
|
Packit Service |
8876fe |
no lines much shorter or much longer then the rest). This common is
|
|
Packit Service |
8876fe |
especially prevalent in internationalized programs, which need to make a
|
|
Packit Service |
8876fe |
wide variety of message string look god on a screen.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
To help with this, <literal remap="tt">newt</literal> provides routines to reformat text to look
|
|
Packit Service |
8876fe |
good. It tries different widths to figure out which one will look ``best''
|
|
Packit Service |
8876fe |
to the user. As these commons are almost always used to format text for
|
|
Packit Service |
8876fe |
textbox components, <literal remap="tt">newt</literal> makes it easy to construct a textbox with
|
|
Packit Service |
8876fe |
reflowed text.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<screen>
|
|
Packit Service |
8876fe |
char * newtReflowText(char * text, int width, int flexDown, int flexUp,
|
|
Packit Service |
8876fe |
int * actualWidth, int * actualHeight);
|
|
Packit Service |
8876fe |
newtComponent newtTextboxReflowed(int left, int top, char * text, int width,
|
|
Packit Service |
8876fe |
int flexDown, int flexUp, int flags);
|
|
Packit Service |
8876fe |
int newtTextboxGetNumLines(newtComponent co);
|
|
Packit Service |
8876fe |
</screen></para>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
<literal remap="tt">newtReflowText()</literal> reflows the <literal remap="tt">text</literal> to a target width of
|
|
Packit Service |
8876fe |
<literal remap="tt">width</literal>. The actual width of the longest line in the returned string is
|
|
Packit Service |
8876fe |
between <literal remap="tt">width - flexDown</literal> and <literal remap="tt">width + flexUp</literal>; the actual maximum
|
|
Packit Service |
8876fe |
line length is chosen to make the displayed check look rectangular.
|
|
Packit Service |
8876fe |
The <literal remap="tt">int</literal>s pointed to by <literal remap="tt">actualWidth</literal> and <literal remap="tt">actualHeight</literal> are set
|
|
Packit Service |
8876fe |
to the width of the longest line and the number of lines in in the
|
|
Packit Service |
8876fe |
returned text, respectively. Either one may be <literal remap="tt">NULL</literal>. The return
|
|
Packit Service |
8876fe |
value points to the reflowed text, and is allocated through <literal remap="tt">malloc()</literal>.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
When the reflowed text is being placed in a textbox it may be easier to use
|
|
Packit Service |
8876fe |
<literal remap="tt">newtTextboxReflowed()</literal>, which creates a textbox, reflows the text, and
|
|
Packit Service |
8876fe |
places the reflowed text in the listbox. It's parameters consist of the
|
|
Packit Service |
8876fe |
position of the final textbox, the width and flex values for the text
|
|
Packit Service |
8876fe |
(which are identical to the parameters passed to <literal remap="tt">newtReflowText()</literal>,
|
|
Packit Service |
8876fe |
and the flags for the textbox (which are the same as the flags for
|
|
Packit Service |
8876fe |
<literal remap="tt">newtTextbox()</literal>. This function does not let you limit the height of the
|
|
Packit Service |
8876fe |
textbox, however, making limiting it's use to constructing textboxes which
|
|
Packit Service |
8876fe |
don't need to scroll.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
To find out how tall the textbox created by <literal remap="tt">newtTextboxReflowed()</literal> is,
|
|
Packit Service |
8876fe |
use <literal remap="tt">newtTextboxGetNumLines()</literal>, which returns the number of lines in the
|
|
Packit Service |
8876fe |
textbox. For textboxes created by <literal remap="tt">newtTextboxReflowed()</literal>, this is
|
|
Packit Service |
8876fe |
always the same as the height of the textbox.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
Here's a simple program which uses a textbox to display a message.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<screen>
|
|
Packit Service |
8876fe |
#include <newt.h>
|
|
Packit Service |
8876fe |
#include <stdlib.h>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
char message[] = "This is a pretty long message. It will be displayed "
|
|
Packit Service |
8876fe |
"in a newt textbox, and illustrates how to construct "
|
|
Packit Service |
8876fe |
"a textbox from arbitrary text which may not have "
|
|
Packit Service |
8876fe |
"very good line breaks.\n\n"
|
|
Packit Service |
8876fe |
"Notice how literal \\n characters are respected, and "
|
|
Packit Service |
8876fe |
"may be used to force line breaks and blank lines.";
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
void main(void) {
|
|
Packit Service |
8876fe |
newtComponent form, text, button;
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
newtInit();
|
|
Packit Service |
8876fe |
newtCls();
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
text = newtTextboxReflowed(1, 1, message, 30, 5, 5, 0);
|
|
Packit Service |
8876fe |
button = newtButton(12, newtTextboxGetNumLines(text) + 2, "Ok");
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
newtOpenWindow(10, 5, 37,
|
|
Packit Service |
8876fe |
newtTextboxGetNumLines(text) + 7, "Textboxes");
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
form = newtForm(NULL, NULL, 0);
|
|
Packit Service |
8876fe |
newtFormAddComponents(form, text, button, NULL);
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
newtRunForm(form);
|
|
Packit Service |
8876fe |
newtFormDestroy(form);
|
|
Packit Service |
8876fe |
newtFinished();
|
|
Packit Service |
8876fe |
}
|
|
Packit Service |
8876fe |
</screen></para></sect3></sect2>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<sect2><title>Scrollbars</title>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
Scrollbars (which, currently, are always vertical in <literal remap="tt">newt</literal>), may be
|
|
Packit Service |
8876fe |
attached to forms to let them contain more data then they have space for.
|
|
Packit Service |
8876fe |
While the actual process of making scrolling forms is discussed at the end
|
|
Packit Service |
8876fe |
of this section, we'll go ahead and introduce scrollbars now so you'll be
|
|
Packit Service |
8876fe |
ready.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<screen>
|
|
Packit Service |
8876fe |
newtComponent newtVerticalScrollbar(int left, int top, int height,
|
|
Packit Service |
8876fe |
int normalColorset, int thumbColorset);
|
|
Packit Service |
8876fe |
</screen>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
When a scrollbar is created, it is given a position on the screen, a
|
|
Packit Service |
8876fe |
height, and two colors. The first color is the color used for drawing the
|
|
Packit Service |
8876fe |
scrollbar, and the second color is used for drawing the thumb. This is the
|
|
Packit Service |
8876fe |
only place in newt where an application specifically sets colors for a
|
|
Packit Service |
8876fe |
component. It's done here to let the colors a scrollbar use match the
|
|
Packit Service |
8876fe |
colors of the component the scrollbar is mated too. When a scrollbar is
|
|
Packit Service |
8876fe |
being used with a form, <literal remap="tt">normalColorset</literal> is often
|
|
Packit Service |
8876fe |
<literal remap="tt">NEWT_COLORSET_WINDOW</literal> and <literal remap="tt">thumbColorset</literal>
|
|
Packit Service |
8876fe |
<literal remap="tt">NEWT_COLORSET_ACTCHECKBOX</literal>. Of course, feel free to peruse
|
|
Packit Service |
8876fe |
<literal remap="tt"><newt.h></literal> and pick your own colors.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
As the scrollbar is normally updated by the component it is mated with,
|
|
Packit Service |
8876fe |
there is no public interface for moving the thumb.</para></sect2>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<sect2><title>Listboxes</title>
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
Listboxes are the most complicated components
|
|
Packit Service |
8876fe |
<literal remap="tt">newt</literal> provides. They can
|
|
Packit Service |
8876fe |
allow a single selection or multiple selection, and are easy to update.
|
|
Packit Service |
8876fe |
Unfortunately, their API is also the least consistent of <literal remap="tt">newt</literal>'s
|
|
Packit Service |
8876fe |
components. Each entry in a listbox is a ordered pair of the text which should be
|
|
Packit Service |
8876fe |
displayed for that item and a <emphasis remap="bf">key</emphasis>, which is a <literal remap="tt">void *</literal> that
|
|
Packit Service |
8876fe |
uniquely identifies that listbox item. Many applications pass integers in
|
|
Packit Service |
8876fe |
as keys, but using arbitrary pointers makes many applications significantly
|
|
Packit Service |
8876fe |
easier to code.</para>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<sect3><title>Basic Listboxes</title>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
Let's start off by looking at the most important listbox functions.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<screen>
|
|
Packit Service |
8876fe |
newtComponent newtListbox(int left, int top, int height, int flags);
|
|
Packit Service |
8876fe |
int newtListboxAppendEntry(newtComponent co, const char * text,
|
|
Packit Service |
8876fe |
const void * data);
|
|
Packit Service |
8876fe |
void * newtListboxGetCurrent(newtComponent co);
|
|
Packit Service |
8876fe |
void newtListboxSetWidth(newtComponent co, int width);
|
|
Packit Service |
8876fe |
void newtListboxSetCurrent(newtComponent co, int num);
|
|
Packit Service |
8876fe |
void newtListboxSetCurrentByKey(newtComponent co, void * key);
|
|
Packit Service |
8876fe |
</screen></para>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
A listbox is created at a certain position and a given height. The
|
|
Packit Service |
8876fe |
<literal remap="tt">height</literal> is used for two things. First of all, it is the minimum
|
|
Packit Service |
8876fe |
height the listbox will use. If there are less items in the listbox then
|
|
Packit Service |
8876fe |
the height, suggests the listbox will still take up that minimum amount
|
|
Packit Service |
8876fe |
of space. Secondly, if the listbox is set to be scrollable (by setting
|
|
Packit Service |
8876fe |
the <literal remap="tt">NEWT_FLAG_SCROLL flag</literal>, the <literal remap="tt">height</literal> is also the maximum height
|
|
Packit Service |
8876fe |
of the listbox. If the listbox may not scroll, it increases its height to
|
|
Packit Service |
8876fe |
display all of its items.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
The following flags may be used when creating a listbox:
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<variablelist>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<varlistentry>
|
|
Packit Service |
8876fe |
<term>NEWT_FLAG_SCROLL</term>
|
|
Packit Service |
8876fe |
<listitem>
|
|
Packit Service |
8876fe |
<para>The listbox should scroll to display all of the
|
|
Packit Service |
8876fe |
items it contains.</para></listitem>
|
|
Packit Service |
8876fe |
</varlistentry>
|
|
Packit Service |
8876fe |
<varlistentry>
|
|
Packit Service |
8876fe |
<term>NEWT_FLAG_RETURNEXIT</term>
|
|
Packit Service |
8876fe |
<listitem>
|
|
Packit Service |
8876fe |
<para>When the user presses return on an item in the
|
|
Packit Service |
8876fe |
list, the form should return.</para></listitem>
|
|
Packit Service |
8876fe |
</varlistentry>
|
|
Packit Service |
8876fe |
<varlistentry>
|
|
Packit Service |
8876fe |
<term>NEWT_FLAG_BORDER</term>
|
|
Packit Service |
8876fe |
<listitem>
|
|
Packit Service |
8876fe |
<para>A frame is drawn around the listbox, which can make
|
|
Packit Service |
8876fe |
it easier to see which listbox has the focus when a form contains multiple
|
|
Packit Service |
8876fe |
listboxes.</para></listitem>
|
|
Packit Service |
8876fe |
</varlistentry>
|
|
Packit Service |
8876fe |
<varlistentry>
|
|
Packit Service |
8876fe |
<term>NEWT_FLAG_MULTIPLE</term>
|
|
Packit Service |
8876fe |
<listitem>
|
|
Packit Service |
8876fe |
<para>By default, a listbox only lets the user select
|
|
Packit Service |
8876fe |
one item in the list at a time. When this flag is specified, they may
|
|
Packit Service |
8876fe |
select multiple items from the list.</para></listitem></varlistentry>
|
|
Packit Service |
8876fe |
</variablelist></para>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
Once a listbox has been created, items are added to it by invoking
|
|
Packit Service |
8876fe |
<literal remap="tt">newtListboxAppendEntry()</literal>, which adds new items to the end of the list.
|
|
Packit Service |
8876fe |
In addition to the listbox component, <literal remap="tt">newtListboxAppendEntry()</literal> needs
|
|
Packit Service |
8876fe |
both elements of the (text, key) ordered pair.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
For lists which only allow a single selection, <literal remap="tt">newtListboxGetCurrent()</literal>
|
|
Packit Service |
8876fe |
should be used to find out which listbox item is currently selected. It
|
|
Packit Service |
8876fe |
returns the key of the currently selected item.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
Normally, a listbox is as wide as its widest element, plus space for a
|
|
Packit Service |
8876fe |
scrollbar if the listbox is supposed to have one. To make the listbox
|
|
Packit Service |
8876fe |
any larger then that, use <literal remap="tt">newtListboxSetWidth()</literal>, which overrides the
|
|
Packit Service |
8876fe |
natural list of the listbox. Once the width has been set, it's fixed. The
|
|
Packit Service |
8876fe |
listbox will no longer grow to accommodate new entries, so bad things may
|
|
Packit Service |
8876fe |
happen!
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
An application can change the current position of the listbox (where the
|
|
Packit Service |
8876fe |
selection bar is displayed) by calling <literal remap="tt">newtListboxSetCurrent()</literal> or
|
|
Packit Service |
8876fe |
<literal remap="tt">newtListboxSetCurrentByKey()</literal>. The first sets the current position to the
|
|
Packit Service |
8876fe |
entry number which is passed as the second argument, with 0 indicating
|
|
Packit Service |
8876fe |
the first entry. <literal remap="tt">newtListboxSetCurrentByKey()</literal> sets the current position
|
|
Packit Service |
8876fe |
to the entry whose <literal remap="tt">key</literal> is passed into the function.</para></sect3>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<sect3><title>Manipulating Listbox Contents</title>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
While the contents of many listboxes never need to change, some applications
|
|
Packit Service |
8876fe |
need to change the contents of listboxes regularly. <literal remap="tt">Newt</literal> includes
|
|
Packit Service |
8876fe |
complete support for updating listboxes. These new functions are in
|
|
Packit Service |
8876fe |
addition to <literal remap="tt">newtListboxAppendEntry()</literal>, which was already discussed.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<screen>
|
|
Packit Service |
8876fe |
void newtListboxSetEntry(newtComponent co, void * key, const char * text);
|
|
Packit Service |
8876fe |
int newtListboxInsertEntry(newtComponent co, const char * text,
|
|
Packit Service |
8876fe |
const void * data, void * key);
|
|
Packit Service |
8876fe |
int newtListboxDeleteEntry(newtComponent co, void * key);
|
|
Packit Service |
8876fe |
void newtListboxClear(newtComponent co);
|
|
Packit Service |
8876fe |
</screen></para>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
The first of these, <literal remap="tt">newtListboxSetEntry()</literal>, updates the text for a
|
|
Packit Service |
8876fe |
key which is already in the listbox. The <literal remap="tt">key</literal> specifies which listbox
|
|
Packit Service |
8876fe |
entry should be modified, and <literal remap="tt">text</literal> becomes the new text for that entry
|
|
Packit Service |
8876fe |
in the listbox.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<literal remap="tt">newtListboxInsertEntry()</literal> inserts a new listbox entry <emphasis remap="bf">after</emphasis> an
|
|
Packit Service |
8876fe |
already existing entry, which is specified by the <literal remap="tt">key</literal> parameter.
|
|
Packit Service |
8876fe |
The <literal remap="tt">text</literal> and <literal remap="tt">data</literal> parameters specify the new entry which should
|
|
Packit Service |
8876fe |
be added.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
Already-existing entries are removed from a listbox with
|
|
Packit Service |
8876fe |
<literal remap="tt">newtListboxDeleteEntry()</literal>. It removes the listbox entry with the
|
|
Packit Service |
8876fe |
specified <literal remap="tt">key</literal>. If you want to remove all of the entries from a
|
|
Packit Service |
8876fe |
listbox, use <literal remap="tt">newtListboxClear()</literal>.</para></sect3>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<sect3><title>Multiple Selections</title>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
When a listbox is created with <literal remap="tt">NEWT_FLAG_MULTIPLE</literal>, the user can select
|
|
Packit Service |
8876fe |
multiple items from the list. When this option is used, a different set of
|
|
Packit Service |
8876fe |
functions must be used to manipulate the listbox selection.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<screen>
|
|
Packit Service |
8876fe |
void newtListboxClearSelection(newtComponent co);
|
|
Packit Service |
8876fe |
void **newtListboxGetSelection(newtComponent co, int *numitems);
|
|
Packit Service |
8876fe |
void newtListboxSelectItem(newtComponent co, const void * key,
|
|
Packit Service |
8876fe |
enum newtFlagsSense sense);
|
|
Packit Service |
8876fe |
</screen>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
The simplest of these is <literal remap="tt">newtListboxClearSelection()</literal>, which deselects
|
|
Packit Service |
8876fe |
all of the items in the list (listboxes which allow multiple selections
|
|
Packit Service |
8876fe |
also allow zero selections). <literal remap="tt">newtListboxGetSelection()</literal> returns a
|
|
Packit Service |
8876fe |
pointer to an array which contains the keys for all of the items in the
|
|
Packit Service |
8876fe |
listbox currently selected. The <literal remap="tt">int</literal> pointed to by <literal remap="tt">numitems</literal> is
|
|
Packit Service |
8876fe |
set to the number of items currently selected (and hence the number of
|
|
Packit Service |
8876fe |
items in the returned array). The returned array is dynamically allocated,
|
|
Packit Service |
8876fe |
and must be released through <literal remap="tt">free()</literal>.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<literal remap="tt">newtListboxSelectItem()</literal> lets the program select and deselect specific
|
|
Packit Service |
8876fe |
listbox entries. The <literal remap="tt">key</literal> of the listbox entry is being affected is
|
|
Packit Service |
8876fe |
passed, and <literal remap="tt">sense</literal> is one of <literal remap="tt">NEWT_FLAGS_RESET</literal>, which deselects
|
|
Packit Service |
8876fe |
the entry, <literal remap="tt">NEWT_FLAGS_SET</literal>, which selects the entry, or
|
|
Packit Service |
8876fe |
<literal remap="tt">NEWT_FLAGS_TOGGLE</literal>, which reverses the current selection status.</para></sect3></sect2>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<sect2><title>Advanced Forms</title>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
Forms, which tie components together, are quite important in the world of
|
|
Packit Service |
8876fe |
<literal remap="tt">newt</literal>. While we've already discussed the basics of forms, we've omitted
|
|
Packit Service |
8876fe |
many of the details.</para>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<sect3><title>Exiting From Forms</title>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
Forms return control to the application for a number of reasons:
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<itemizedlist>
|
|
Packit Service |
8876fe |
<listitem>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
A component can force the form to exit. Buttons do this whenever they
|
|
Packit Service |
8876fe |
are pushed, and other components exit when <literal remap="tt">NEWT_FLAG_RETURNEXIT</literal> has
|
|
Packit Service |
8876fe |
been specified.</para></listitem>
|
|
Packit Service |
8876fe |
<listitem>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
Applications can setup hot keys which cause the form to exit when
|
|
Packit Service |
8876fe |
they are pressed.</para></listitem>
|
|
Packit Service |
8876fe |
<listitem>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<para>
|
|
Packit Service |
8876fe |
<literal remap="tt">Newt</literal> can exit when file descriptors are ready to be read or
|
|
Packit Service |
8876fe |
ready to be written to.
|
|
Packit Service |
8876fe |
</para>
|
|
Packit Service |
8876fe |
</listitem></itemizedlist>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
By default, <literal remap="tt">newt</literal> forms exit when the F12 key is pressed (F12 is setup
|
|
Packit Service |
8876fe |
as a hot key by default). <literal remap="tt">Newt</literal> applications should treat F12 as an
|
|
Packit Service |
8876fe |
``Ok'' button. If applications don't want F12 to exit the form, they can
|
|
Packit Service |
8876fe |
specify <literal remap="tt">NEWT_FLAG_NOF12</literal> as flag when creating the form with
|
|
Packit Service |
8876fe |
<literal remap="tt">newtForm</literal>.
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<screen>
|
|
Packit Service |
8876fe |
void newtFormAddHotKey(newtComponent co, int key);
|
|
Packit Service |
8876fe |
void newtFormWatchFd(newtComponent form, int fd, int fdFlags);
|
|
Packit Service |
8876fe |
</screen>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<screen>
|
|
Packit Service |
8876fe |
void newtDrawForm(newtComponent form);
|
|
Packit Service |
8876fe |
newtComponent newtFormGetCurrent(newtComponent co);
|
|
Packit Service |
8876fe |
void newtFormSetCurrent(newtComponent co, newtComponent subco);
|
|
Packit Service |
8876fe |
void newtFormRun(newtComponent co, struct newtExitStruct * es);
|
|
Packit Service |
8876fe |
</screen>
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
|
|
Packit Service |
8876fe |
<screen>
|
|
Packit Service |
8876fe |
newtComponent newtForm(newtComponent vertBar, const char * help, int flags);
|
|
Packit Service |
8876fe |
void newtFormSetBackground(newtComponent co, int color);
|
|
Packit Service |
8876fe |
void newtFormSetHeight(newtComponent co, int height);
|
|
Packit Service |
8876fe |
void newtFormSetWidth(newtComponent co, int width);
|
|
Packit Service |
8876fe |
</screen>
|
|
Packit Service |
8876fe |
</para>
|
|
Packit Service |
8876fe |
</sect3>
|
|
Packit Service |
8876fe |
</sect2>
|
|
Packit Service |
8876fe |
</sect1>
|
|
Packit Service |
8876fe |
</article>
|
|
Packit Service |
8876fe |
|