mirror of https://github.com/fltk/fltk
Added Fl_Simple_Terminal widget, and mods to test+example programs (STR #3411).
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12506 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
parent
93ef00cca6
commit
68f07db58a
|
@ -0,0 +1,199 @@
|
|||
//
|
||||
// "$Id$"
|
||||
//
|
||||
// A simple terminal widget for Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 1998-2011 by Bill Spitzak and others.
|
||||
// Copyright 2017 by Greg Ercolano.
|
||||
//
|
||||
// This library is free software. Distribution and use rights are outlined in
|
||||
// the file "COPYING" which should have been included with this file. If this
|
||||
// file is missing or damaged, see the license at:
|
||||
//
|
||||
// http://www.fltk.org/COPYING.php
|
||||
//
|
||||
// Please report all bugs and problems on the following page:
|
||||
//
|
||||
// http://www.fltk.org/str.php
|
||||
//
|
||||
|
||||
/* \file
|
||||
Fl_Simple_Terminal widget . */
|
||||
|
||||
#ifndef Fl_Simple_Terminal_H
|
||||
#define Fl_Simple_Terminal_H
|
||||
|
||||
#include "Fl_Export.H"
|
||||
#include <FL/Fl_Text_Display.H>
|
||||
|
||||
/**
|
||||
This is a continuous text scroll widget for logging and debugging
|
||||
output, much like a terminal. Includes printf() for appending messages,
|
||||
a line limit for the screen history size, ANSI sequences to control
|
||||
text color, font face, font weight and font size.
|
||||
|
||||
This is useful in place of using stdout/stderr for logging messages
|
||||
when no terminal is available, such as when an application is invoked
|
||||
from a desktop shortcut, dock, or file browser.
|
||||
|
||||
Like a regular console terminal, the vertical scrollbar 'tracks'
|
||||
the bottom of the buffer as new output is added. If the user scrolls
|
||||
away from the bottom, this 'tracking' feature is temporarily suspended,
|
||||
so the user can browse the terminal history without fighting the scrollbar
|
||||
when new text is added asynchronously. When the user returns the
|
||||
scroller to the bottom of the display, the scrollbar's tracking resumes.
|
||||
|
||||
Features include:
|
||||
|
||||
- history_lines(int) can define a maximum size for the terminal screen history
|
||||
- stay_at_bottom(bool) can be used to cause the terminal to keep scrolled to the bottom
|
||||
- ansi(bool) enables ANSI sequences within the text to control text colors
|
||||
- style_table() can be used to define custom color/font/weight/size combinations
|
||||
|
||||
What this widget is NOT is a full terminal emulator; it does NOT
|
||||
handle stdio redirection, pipes, pseudo ttys, termio character cooking,
|
||||
keyboard input processing, screen addressing, random cursor positioning,
|
||||
curses(3) compatibility, or VT100/xterm emulation.
|
||||
|
||||
It is a simple text display widget that leverages the features of the
|
||||
Fl_Text_Display base class to handle terminal-like behavior, such as
|
||||
logging events or debug information.
|
||||
|
||||
Example use:
|
||||
\code
|
||||
|
||||
#include <FL/Fl_Simple_Terminal.H>
|
||||
:
|
||||
tty = new Fl_Simple_Terminal(...);
|
||||
tty->ansi(true); // enable use of "\033[#m"
|
||||
:
|
||||
tty->printf("The time is now: \033[32m%s\033[0m", date_time_str);
|
||||
|
||||
\endcode
|
||||
|
||||
Example application:
|
||||
\dontinclude simple-terminal.cxx
|
||||
\skip //START
|
||||
\until //END
|
||||
|
||||
Style Tables For Color/Font/Fontsize Control
|
||||
--------------------------------------------
|
||||
Internally this widget derives from Fl_Text_Display, and therefore
|
||||
inherits some of its idiosyncracies. In particular, when colors
|
||||
are used, the base class's concept of a 'style table' is used.
|
||||
|
||||
The 'style table' is similar to a color mapped image; where each
|
||||
pixel is a single value that is an index into a table of colors
|
||||
to minimize per-pixel memory use.
|
||||
|
||||
The style table has a similar goal; since every character in the
|
||||
terminal can potentially be a different color, instead of managing
|
||||
several integer attribute values per-character, a single character
|
||||
for each character is used as an index into the style table, choosing
|
||||
one of the available color/font/weight/size values available.
|
||||
This saves on as much as 3 to 4 times the memory use, useful when
|
||||
there's a large amount of text.
|
||||
|
||||
When ansi() is set to 'true', ANSI sequences of the form "\033[#m"
|
||||
can be used to select different colors, font faces, font weights (bold,italic..),
|
||||
and font sizes, where '#' is the index number into the style table. Example:
|
||||
|
||||
\code
|
||||
"\033[0mThis text uses the 1st entry in the style table\n"
|
||||
"\033[1mThis text uses the 2nd entry in the style table\n"
|
||||
"\033[2mThis text uses the 3rd entry in the style table\n"
|
||||
etc..
|
||||
\endcode
|
||||
|
||||
There is a built-in style table that provides some
|
||||
commonly used ANSI colors for "\033[30m" through "\033[37m"
|
||||
(blk,red,grn,yel,blu,mag,cyn,wht), and a brighter version of those
|
||||
colors for "\033[40" through "\033[47m". See ansi(bool) for more info.
|
||||
|
||||
You can also supply a custom style table using
|
||||
style_table(Style_Table_Entry*,int,int), allowing you to define
|
||||
your own color/font/weight/size combinations. See that method's docs
|
||||
for more info.
|
||||
|
||||
All style index numbers are rounded to the size of the style table
|
||||
(via modulus) to protect the style array from overruns.
|
||||
|
||||
*/
|
||||
class FL_EXPORT Fl_Simple_Terminal : public Fl_Text_Display {
|
||||
protected:
|
||||
Fl_Text_Buffer *buf; // text buffer
|
||||
Fl_Text_Buffer *sbuf; // style buffer
|
||||
|
||||
private:
|
||||
int history_lines_; // max lines allowed in screen history
|
||||
bool stay_at_bottom_; // lets scroller chase last line in buffer
|
||||
bool ansi_; // enables ANSI sequences
|
||||
// scroll management
|
||||
int lines; // #lines in buffer (optimization: Fl_Text_Buffer slow to calc this)
|
||||
bool scrollaway; // true when user changed vscroll away from bottom
|
||||
bool scrolling; // true while scroll callback active
|
||||
// Fl_Text_Display vscrollbar's callback+data
|
||||
Fl_Callback *orig_vscroll_cb;
|
||||
void *orig_vscroll_data;
|
||||
// Style table
|
||||
const Fl_Text_Display::Style_Table_Entry *stable_; // the active style table
|
||||
int stable_size_; // active style table size (in bytes)
|
||||
int normal_style_index_; // "normal" style used by "\033[0m" reset sequence
|
||||
int current_style_index_; // current style used for drawing text
|
||||
|
||||
public:
|
||||
Fl_Simple_Terminal(int X,int Y,int W,int H,const char *l=0);
|
||||
~Fl_Simple_Terminal();
|
||||
|
||||
// Terminal options
|
||||
void stay_at_bottom(bool);
|
||||
bool stay_at_bottom() const;
|
||||
void history_lines(int);
|
||||
int history_lines() const;
|
||||
void ansi(bool val);
|
||||
bool ansi() const;
|
||||
void style_table(Fl_Text_Display::Style_Table_Entry *stable, int stable_size, int normal_style_index=0);
|
||||
const Fl_Text_Display::Style_Table_Entry *style_table() const;
|
||||
int style_table_size() const;
|
||||
void normal_style_index(int);
|
||||
int normal_style_index() const;
|
||||
void current_style_index(int);
|
||||
int current_style_index() const;
|
||||
|
||||
// Terminal text management
|
||||
void append(const char *s, int len=-1);
|
||||
void text(const char *s, int len=-1);
|
||||
const char* text() const;
|
||||
void printf(const char *fmt, ...);
|
||||
void vprintf(const char *fmt, va_list ap);
|
||||
void clear();
|
||||
void remove_lines(int start, int count);
|
||||
|
||||
private:
|
||||
// Methods blocking public access to the subclass
|
||||
// These are subclass methods that would give unexpected
|
||||
// results if used. By making them private, we effectively
|
||||
// "block" them.
|
||||
//
|
||||
// TODO: There are probably other Fl_Text_Display methods that
|
||||
// need to be blocked.
|
||||
//
|
||||
void insert(const char*) { }
|
||||
|
||||
public:
|
||||
// Fltk
|
||||
virtual void draw();
|
||||
|
||||
protected:
|
||||
// Internal methods
|
||||
void enforce_stay_at_bottom();
|
||||
void enforce_history_lines();
|
||||
void vscroll_cb2(Fl_Widget*, void*);
|
||||
static void vscroll_cb(Fl_Widget*, void*);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
// End of "$Id$".
|
||||
//
|
|
@ -652,7 +652,7 @@ EXCLUDE_SYMBOLS += Fl_Native_File_Chooser_FLTK_Driver
|
|||
# directories that contain example code fragments that are included (see
|
||||
# the \include command).
|
||||
|
||||
EXAMPLE_PATH = ../test
|
||||
EXAMPLE_PATH = ../test ../examples
|
||||
|
||||
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
|
||||
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 31 KiB |
|
@ -26,6 +26,7 @@ ALL = clipboard$(EXEEXT) \
|
|||
table-spreadsheet-with-keyboard-nav$(EXEEXT) \
|
||||
table-with-keynav$(EXEEXT) \
|
||||
tabs-simple$(EXEEXT) \
|
||||
simple-terminal$(EXEEXT) \
|
||||
textdisplay-with-colors$(EXEEXT) \
|
||||
texteditor-simple$(EXEEXT) \
|
||||
tree-simple$(EXEEXT) \
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
//
|
||||
// "$Id$"
|
||||
//
|
||||
// Simple Example app using Fl_Simple_Terminal. - erco 10/12/2017
|
||||
//
|
||||
// Copyright 2017 Greg Ercolano.
|
||||
// Copyright 1998-2016 by Bill Spitzak and others.
|
||||
//
|
||||
// This library is free software. Distribution and use rights are outlined in
|
||||
// the file "COPYING" which should have been included with this file. If this
|
||||
// file is missing or damaged, see the license at:
|
||||
//
|
||||
// http://www.fltk.org/COPYING.php
|
||||
//
|
||||
// Please report all bugs and problems on the following page:
|
||||
//
|
||||
// http://www.fltk.org/str.php
|
||||
//
|
||||
|
||||
#include <time.h> //START
|
||||
#include <FL/Fl_Double_Window.H>
|
||||
#include <FL/Fl_Box.H>
|
||||
#include <FL/Fl_Simple_Terminal.H>
|
||||
|
||||
#define TERMINAL_HEIGHT 120
|
||||
|
||||
// Globals
|
||||
Fl_Double_Window *G_win = 0;
|
||||
Fl_Box *G_box = 0;
|
||||
Fl_Simple_Terminal *G_tty = 0;
|
||||
|
||||
// Append a date/time message to the terminal every 2 seconds
|
||||
void tick_cb(void *data) {
|
||||
time_t lt = time(NULL);
|
||||
G_tty->printf("Timer tick: \033[32m%s\033[0m\n", ctime(<));
|
||||
Fl::repeat_timeout(2.0, tick_cb, data);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
G_win = new Fl_Double_Window(500, 200+TERMINAL_HEIGHT, "Your App");
|
||||
G_win->begin();
|
||||
|
||||
G_box = new Fl_Box(0, 0, G_win->w(), 200,
|
||||
"Your app GUI in this area.\n\n"
|
||||
"Your app's debugging output in tty below");
|
||||
|
||||
// Add simple terminal to bottom of app window for scrolling history of status messages.
|
||||
G_tty = new Fl_Simple_Terminal(0,200,G_win->w(),TERMINAL_HEIGHT);
|
||||
G_tty->ansi(true); // enable use of "\033[32m"
|
||||
|
||||
G_win->end();
|
||||
G_win->resizable(G_win);
|
||||
G_win->show();
|
||||
Fl::add_timeout(0.5, tick_cb);
|
||||
return Fl::run();
|
||||
} //END
|
||||
|
||||
//
|
||||
// End of "$Id$".
|
||||
//
|
|
@ -59,6 +59,7 @@ set (CPPFILES
|
|||
Fl_Scroll.cxx
|
||||
Fl_Scrollbar.cxx
|
||||
Fl_Shared_Image.cxx
|
||||
Fl_Simple_Terminal.cxx
|
||||
Fl_Single_Window.cxx
|
||||
Fl_Slider.cxx
|
||||
Fl_Spinner.cxx
|
||||
|
|
|
@ -0,0 +1,747 @@
|
|||
//
|
||||
// "$Id$"
|
||||
//
|
||||
// A simple terminal widget for Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 1998-2011 by Bill Spitzak and others.
|
||||
// Copyright 2017 by Greg Ercolano.
|
||||
//
|
||||
// This library is free software. Distribution and use rights are outlined in
|
||||
// the file "COPYING" which should have been included with this file. If this
|
||||
// file is missing or damaged, see the license at:
|
||||
//
|
||||
// http://www.fltk.org/COPYING.php
|
||||
//
|
||||
// Please report all bugs and problems on the following page:
|
||||
//
|
||||
// http://www.fltk.org/str.php
|
||||
//
|
||||
|
||||
#include <ctype.h> /* isdigit */
|
||||
#include <string.h> /* memset */
|
||||
#include <stdlib.h> /* strtol */
|
||||
#include <FL/Fl_Simple_Terminal.H>
|
||||
#include <FL/Fl.H>
|
||||
#include <stdarg.h>
|
||||
#include "flstring.h"
|
||||
|
||||
#define STE_SIZE sizeof(Fl_Text_Display::Style_Table_Entry)
|
||||
|
||||
// Default style table
|
||||
// Simple ANSI style colors with an FL_COURIER font.
|
||||
// Due to how the modulo works for 20 items, the first 10 map to 40
|
||||
// and the second 10 map to 30.
|
||||
//
|
||||
static const Fl_Text_Display::Style_Table_Entry builtin_stable[] = {
|
||||
// FONT COLOR FONT FACE SIZE INDEX COLOR NAME ANSI ANSI MODULO INDEX
|
||||
// ---------- --------------- ------ ------ -------------- -------- -----------------
|
||||
{ 0x80808000, FL_COURIER, 14 }, // 0 - Bright Black \033[40m 0,20,40,..
|
||||
{ 0xff000000, FL_COURIER, 14 }, // 1 - Bright Red \033[41m ^^
|
||||
{ 0x00ff0000, FL_COURIER, 14 }, // 2 - Bright Green \033[42m
|
||||
{ 0xffff0000, FL_COURIER, 14 }, // 3 - Bright Yellow \033[43m
|
||||
{ 0x0000ff00, FL_COURIER, 14 }, // 4 - Bright Blue \033[44m
|
||||
{ 0xff00ff00, FL_COURIER, 14 }, // 5 - Bright Magenta \033[45m
|
||||
{ 0x00ffff00, FL_COURIER, 14 }, // 6 - Bright Cyan \033[46m
|
||||
{ 0xffffff00, FL_COURIER, 14 }, // 7 - Bright White \033[47m
|
||||
{ 0x00000000, FL_COURIER, 14 }, // 8 - x
|
||||
{ 0x00000000, FL_COURIER, 14 }, // 9 - x
|
||||
{ 0x00000000, FL_COURIER, 14 }, // 10 - Medium Black \033[30m 10,30,50,..
|
||||
{ 0xbb000000, FL_COURIER, 14 }, // 11 - Medium Red \033[31m ^^
|
||||
{ 0x00bb0000, FL_COURIER, 14 }, // 12 - Medium Green \033[32m
|
||||
{ 0xbbbb0000, FL_COURIER, 14 }, // 13 - Medium Yellow \033[33m
|
||||
{ 0x0000cc00, FL_COURIER, 14 }, // 14 - Medium Blue \033[34m
|
||||
{ 0xbb00bb00, FL_COURIER, 14 }, // 15 - Medium Magenta \033[35m
|
||||
{ 0x00bbbb00, FL_COURIER, 14 }, // 16 - Medium Cyan \033[36m
|
||||
{ 0xbbbbbb00, FL_COURIER, 14 }, // 17 - Medium White \033[37m (also "\033[0m" reset)
|
||||
{ 0x00000000, FL_COURIER, 14 }, // 18 - x
|
||||
{ 0x00000000, FL_COURIER, 14 } // 19 - x
|
||||
};
|
||||
static const int builtin_stable_size = sizeof(builtin_stable);
|
||||
static const char builtin_normal_index = 17; // the reset style index used by \033[0m
|
||||
|
||||
// Count how many times character 'c' appears in string 's'
|
||||
static int strcnt(const char *s, char c) {
|
||||
int count = 0;
|
||||
while ( *s ) { if ( *s++ == c ) ++count; }
|
||||
return count;
|
||||
}
|
||||
|
||||
// Vertical scrollbar callback intercept
|
||||
void Fl_Simple_Terminal::vscroll_cb2(Fl_Widget *w, void*) {
|
||||
scrolling = 1;
|
||||
orig_vscroll_cb(w, orig_vscroll_data);
|
||||
scrollaway = (mVScrollBar->value() != mVScrollBar->maximum());
|
||||
scrolling = 0;
|
||||
}
|
||||
void Fl_Simple_Terminal::vscroll_cb(Fl_Widget *w, void *data) {
|
||||
Fl_Simple_Terminal *o = (Fl_Simple_Terminal*)data;
|
||||
o->vscroll_cb2(w,(void*)0);
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a new Fl_Simple_Terminal widget that can be a child of other FLTK widgets.
|
||||
*/
|
||||
Fl_Simple_Terminal::Fl_Simple_Terminal(int X,int Y,int W,int H,const char *l) : Fl_Text_Display(X,Y,W,H,l) {
|
||||
history_lines_ = 500; // something 'reasonable'
|
||||
stay_at_bottom_ = true;
|
||||
ansi_ = false;
|
||||
lines = 0; // note: lines!=mNBufferLines when lines are wrapping
|
||||
scrollaway = false;
|
||||
scrolling = false;
|
||||
// These defaults similar to typical DOS/unix terminals
|
||||
textfont(FL_COURIER);
|
||||
color(FL_BLACK);
|
||||
textcolor(FL_WHITE);
|
||||
selection_color(FL_YELLOW); // default dark blue looks bad for black background
|
||||
show_cursor(true);
|
||||
cursor_color(FL_GREEN);
|
||||
cursor_style(Fl_Text_Display::BLOCK_CURSOR);
|
||||
// Setup text buffer
|
||||
buf = new Fl_Text_Buffer();
|
||||
buffer(buf);
|
||||
sbuf = new Fl_Text_Buffer(); // allocate whether we use it or not
|
||||
// XXX: We use WRAP_AT_BOUNDS to prevent the hscrollbar from /always/
|
||||
// being present, an annoying UI bug in Fl_Text_Display.
|
||||
wrap_mode(Fl_Text_Display::WRAP_AT_BOUNDS, 0);
|
||||
// Style table
|
||||
stable_ = &builtin_stable[0];
|
||||
stable_size_ = builtin_stable_size;
|
||||
normal_style_index_ = builtin_normal_index;
|
||||
current_style_index_ = builtin_normal_index;
|
||||
// Intercept vertical scrolling
|
||||
orig_vscroll_cb = mVScrollBar->callback();
|
||||
orig_vscroll_data = mVScrollBar->user_data();
|
||||
mVScrollBar->callback(vscroll_cb, (void*)this);
|
||||
}
|
||||
|
||||
/**
|
||||
Destructor for this widget; removes any internal allocations
|
||||
for the terminal, including text buffer, style buffer, etc.
|
||||
*/
|
||||
Fl_Simple_Terminal::~Fl_Simple_Terminal() {
|
||||
buffer(0); // disassociate buffer /before/ we delete it
|
||||
if ( buf ) { delete buf; buf = 0; }
|
||||
if ( sbuf ) { delete sbuf; sbuf = 0; }
|
||||
}
|
||||
|
||||
/**
|
||||
Gets the current value of the stay_at_bottom(bool) flag.
|
||||
|
||||
When true, the terminal tries to keep the scrollbar scrolled
|
||||
to the bottom when new text is added.
|
||||
|
||||
\see stay_at_bottom(bool)
|
||||
*/
|
||||
bool Fl_Simple_Terminal::stay_at_bottom() const {
|
||||
return stay_at_bottom_;
|
||||
}
|
||||
|
||||
/**
|
||||
Configure the terminal to remain scrolled to the bottom when possible,
|
||||
chasing the end of the buffer whenever new text is added.
|
||||
|
||||
If disabled, the terminal behaves more like a text display widget;
|
||||
the scrollbar does not chase the bottom of the buffer.
|
||||
|
||||
If the user scrolls away from the bottom, this 'chasing' feature is
|
||||
temporarily disabled. This prevents the user from having to fight
|
||||
the scrollbar chasing the end of the buffer while browsing when
|
||||
new text is also being added asynchronously. When the user returns the
|
||||
scroller to the bottom of the display, the chasing behavior resumes.
|
||||
|
||||
The default is 'true'.
|
||||
*/
|
||||
void Fl_Simple_Terminal::stay_at_bottom(bool val) {
|
||||
if ( stay_at_bottom_ == val ) return; // no change
|
||||
stay_at_bottom_ = val;
|
||||
if ( stay_at_bottom_ ) enforce_stay_at_bottom();
|
||||
}
|
||||
|
||||
/**
|
||||
Get the maximum number of terminal history lines last set by history_lines(int).
|
||||
|
||||
-1 indicates an unlimited scroll history.
|
||||
|
||||
\see history_lines(int)
|
||||
*/
|
||||
int Fl_Simple_Terminal::history_lines() const {
|
||||
return history_lines_;
|
||||
}
|
||||
|
||||
/**
|
||||
Sets the maximum number of lines for the terminal history.
|
||||
|
||||
The new limit value is automatically enforced on the current screen
|
||||
history, truncating off any lines that exceed the new limit.
|
||||
|
||||
When a limit is set, the buffer is trimmed as new text is appended,
|
||||
ensuring the buffer never displays more than the specified number of lines.
|
||||
|
||||
The default maximum is 500 lines.
|
||||
|
||||
\param maxlines Maximum number of lines kept on the terminal buffer history.
|
||||
Use -1 for an unlimited scroll history.
|
||||
A value of 0 is not recommended.
|
||||
*/
|
||||
void Fl_Simple_Terminal::history_lines(int maxlines) {
|
||||
history_lines_ = maxlines;
|
||||
enforce_history_lines();
|
||||
}
|
||||
|
||||
/**
|
||||
Get the state of the ANSI flag which enables/disables
|
||||
the handling of ANSI sequences in text.
|
||||
|
||||
When true, ANSI sequences in the text stream control color, font
|
||||
and font sizes of text (e.g. "\033[41mThis is Red\033[0m").
|
||||
For more info, see ansi(bool).
|
||||
|
||||
\see ansi(bool)
|
||||
*/
|
||||
bool Fl_Simple_Terminal::ansi() const {
|
||||
return ansi_;
|
||||
}
|
||||
|
||||
/**
|
||||
Enable/disable support of ANSI sequences like "\033[31m", which sets the
|
||||
color/font/weight/size of any text that follows.
|
||||
|
||||
If enabled, ANSI sequences of the form "\033[#m" can be used to change
|
||||
font color, face, and size, where '#' is an index number into the current
|
||||
style table. These "escape sequences" are hidden from view.
|
||||
|
||||
If disabled, the textcolor() / textfont() / textsize() methods define
|
||||
the color and font for all text in the terminal. ANSI sequences are not
|
||||
handled specially, and rendered as raw text.
|
||||
|
||||
A built-in style table is provided, but you can configure a custom style table
|
||||
using style_table(Style_Table_Entry*,int,int) for your own colors and fonts.
|
||||
|
||||
The built-in style table supports these ANSI sequences:
|
||||
|
||||
ANSI Sequence Color Name Font Face + Size Remarks
|
||||
------------- -------------- ---------------- -----------------------
|
||||
"\033[0m" "Normal" FL_COURIER, 14 Resets to default color/font/weight/size
|
||||
"\033[30m" Medium Black FL_COURIER, 14
|
||||
"\033[31m" Medium Red FL_COURIER, 14
|
||||
"\033[32m" Medium Green FL_COURIER, 14
|
||||
"\033[33m" Medium Yellow FL_COURIER, 14
|
||||
"\033[34m" Medium Blue FL_COURIER, 14
|
||||
"\033[35m" Medium Magenta FL_COURIER, 14
|
||||
"\033[36m" Medium Cyan FL_COURIER, 14
|
||||
"\033[37m" Medium White FL_COURIER, 14 The color when "\033[0m" reset is used
|
||||
"\033[40m" Bright Black FL_COURIER, 14
|
||||
"\033[41m" Bright Red FL_COURIER, 14
|
||||
"\033[42m" Bright Green FL_COURIER, 14
|
||||
"\033[43m" Bright Yellow FL_COURIER, 14
|
||||
"\033[44m" Bright Blue FL_COURIER, 14
|
||||
"\033[45m" Bright Magenta FL_COURIER, 14
|
||||
"\033[46m" Bright Cyan FL_COURIER, 14
|
||||
"\033[47m" Bright White FL_COURIER, 14
|
||||
|
||||
Here's example code demonstrating the use of ANSI codes to select
|
||||
the built-in colors, and how it looks in the terminal:
|
||||
|
||||
\image html simple-terminal-default-ansi.png "Fl_Simple_Terminal built-in ANSI sequences"
|
||||
\image latex simple-terminal-default-ansi.png "Fl_Simple_Terminal built-in ANSI sequences" width=4cm
|
||||
|
||||
\note Changing the ansi(bool) value clears the buffer and forces a redraw().
|
||||
\note Enabling ANSI mode overrides textfont(), textsize(), textcolor()
|
||||
completely, which are controlled instead by current_style_index()
|
||||
and the current style_table().
|
||||
\see style_table(Style_Table_Entry*,int,int),
|
||||
current_style_index(),
|
||||
normal_style_index()
|
||||
*/
|
||||
void Fl_Simple_Terminal::ansi(bool val) {
|
||||
ansi_ = val;
|
||||
clear();
|
||||
if ( ansi_ ) {
|
||||
highlight_data(sbuf, stable_, stable_size_/STE_SIZE, 'A', 0, 0);
|
||||
} else {
|
||||
// XXX: highlight_data(0,0,0,'A',0,0) can crash, so to disable
|
||||
// we use sbuf + builtin_stable but /set nitems to 0/.
|
||||
highlight_data(sbuf, builtin_stable, 0, 'A', 0, 0);
|
||||
}
|
||||
redraw();
|
||||
}
|
||||
|
||||
/**
|
||||
Return the current style table being used.
|
||||
|
||||
This is the value last passed as the 1st argument to
|
||||
style_table(Style_Table_Entry*,int,int). If no style table
|
||||
was defined, the built-in style table is returned.
|
||||
|
||||
ansi(bool) must be set to 'true' for the style table to be used at all.
|
||||
|
||||
\see style_table(Style_Table_Entry*,int,int)
|
||||
*/
|
||||
const Fl_Text_Display::Style_Table_Entry *Fl_Simple_Terminal::style_table() const {
|
||||
return stable_;
|
||||
}
|
||||
|
||||
/**
|
||||
Return the current style table's size (in bytes).
|
||||
|
||||
This is the value last passed as the 2nd argument to
|
||||
style_table(Style_Table_Entry*,int,int).
|
||||
*/
|
||||
int Fl_Simple_Terminal::style_table_size() const {
|
||||
return stable_size_;
|
||||
}
|
||||
|
||||
/**
|
||||
Sets the style table index used by the ANSI terminal reset
|
||||
sequence "\033[0m", which resets the current drawing
|
||||
color/font/weight/size to "normal".
|
||||
|
||||
Effective only when ansi(bool) is 'true'.
|
||||
|
||||
\see ansi(bool), style_table(Style_Table_Entry*,int,int)
|
||||
\note Changing this value does *not* change the current drawing color.
|
||||
To change that, use current_style_index(int).
|
||||
*/
|
||||
void Fl_Simple_Terminal::normal_style_index(int val) {
|
||||
// Wrap index to ensure it's never larger than table
|
||||
normal_style_index_ = val % (stable_size_ / STE_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
Gets the style table index used by the ANSI terminal reset
|
||||
sequence "\033[0m".
|
||||
|
||||
This is the value last set by normal_style_index(int), or as set by
|
||||
the 3rd argument to style_table(Style_Table_Entry*,int,int).
|
||||
|
||||
\see normal_style_index(int), ansi(bool), style_table(Style_Table_Entry*,int,int)
|
||||
*/
|
||||
int Fl_Simple_Terminal::normal_style_index() const {
|
||||
return normal_style_index_;
|
||||
}
|
||||
|
||||
/**
|
||||
Set the style table index used as the current drawing
|
||||
color/font/weight/size for new text.
|
||||
|
||||
For example:
|
||||
\code
|
||||
:
|
||||
tty->ansi(true);
|
||||
tty->append("Some normal text.\n");
|
||||
tty->current_style_index(2); // same as "\033[2m"
|
||||
tty->append("This text will be green.\n");
|
||||
tty->current_style_index(tty->normal_style_index()); // same as "\033[0m"
|
||||
tty->append("Back to normal text.\n");
|
||||
:
|
||||
\endcode
|
||||
|
||||
This value can also be changed by an ANSI sequence like "\033[#m",
|
||||
where # would be a new style index value. So if the application executes:
|
||||
<tt>term->append("\033[4mTesting")</tt>, then current_style_index()
|
||||
will be left set to 4.
|
||||
|
||||
The index number specified should be within the number of items in the
|
||||
current style table. Values larger than the table will be clamped to
|
||||
the size of the table with a modulus operation.
|
||||
|
||||
Effective only when ansi(bool) is 'true'.
|
||||
*/
|
||||
void Fl_Simple_Terminal::current_style_index(int val) {
|
||||
// Wrap index to ensure it's never larger than table
|
||||
current_style_index_ = abs(val) % (stable_size_ / STE_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
Get the style table index used as the current drawing
|
||||
color/font/weight/size for new text.
|
||||
|
||||
This value is also controlled by the ANSI sequence "\033[#m",
|
||||
where # would be a new style index value. So if the application executes:
|
||||
<tt>term->append("\033[4mTesting")</tt>, then current_style_index()
|
||||
returns 4.
|
||||
|
||||
\see current_style_index(int)
|
||||
*/
|
||||
int Fl_Simple_Terminal::current_style_index() const {
|
||||
return current_style_index_;
|
||||
}
|
||||
|
||||
/**
|
||||
Set a user defined style table, which controls the font colors,
|
||||
faces, weights and sizes available for the terminal's text content.
|
||||
|
||||
ansi(bool) must be set to 'true' for the defined style table
|
||||
to be used at all.
|
||||
|
||||
If 'table' and 'size' are 0, then the "built in" style table is used.
|
||||
For info about the built-in colors, see ansi(bool).
|
||||
|
||||
Which style table entry used for drawing depends on the value last set
|
||||
by current_style_index(), or by the ANSI sequence "\033[#m", where '#'
|
||||
is the index into the style table, limited to the size of the table
|
||||
via modulus.
|
||||
|
||||
If the index# passed via "\033[#m" is larger than the number of elements
|
||||
in the table, the value is clamped via modulus. So for a 10 element table,
|
||||
the following ANSI codes would all be equivalent, selecting the 5th element
|
||||
in the table: "\033[5m", "\033[15m", "\033[25m", etc. This is because
|
||||
5==(15%10)==(25%10), etc.
|
||||
|
||||
A special exception is made for "\033[0m", which is supposed to "reset"
|
||||
the current style table to default color/font/weight/size, as last set by
|
||||
\p normal_style_index, or by the API method normal_style_index(int).
|
||||
|
||||
In cases like the built-in style table, where the 17th item is the
|
||||
"normal" color, the 'normal_style_index' is set to 17 so that "\033[0m"
|
||||
resets to that color, instead of the first element in the table.
|
||||
|
||||
If you want "\033[0m" to simply pick the first element in the table,
|
||||
then set 'normal_style_index' to 0.
|
||||
|
||||
An example of defining a custom style table (white courier 14, red courier 14,
|
||||
and white helvetica 14):
|
||||
\code
|
||||
int main() {
|
||||
:
|
||||
// Our custom style table
|
||||
Fl_Text_Display::Style_Table_Entry mystyle[] = {
|
||||
// Font Color Font Face Font Size Index ANSI Sequence
|
||||
// ---------- ---------------- --------- ----- -------------
|
||||
{ FL_WHITE, FL_COURIER_BOLD, 14 }, // 0 "\033[0m" ("default")
|
||||
{ FL_RED, FL_COURIER_BOLD, 14 }, // 1 "\033[1m"
|
||||
{ FL_WHITE, FL_HELVETICA, 14 } // 2 "\033[2m"
|
||||
};
|
||||
// Create terminal, enable ANSI and our style table
|
||||
tty = new Fl_Simple_Terminal(..);
|
||||
tty->ansi(true); // enable ANSI codes
|
||||
tty->style_table(&mystyle[0], sizeof(mystyle), 0); // use our custom style table
|
||||
:
|
||||
// Now write to terminal, with ANSI that uses our style table
|
||||
tty->printf("\033[0mNormal Text\033[1mRed Courier Text\n");
|
||||
tty->append("\033[2mWhite Helvetica\033[0mBack to normal.\n");
|
||||
:
|
||||
\endcode
|
||||
|
||||
\note Changing the style table clear()s the terminal.
|
||||
\note You currently can't control /background/ color of text,
|
||||
a limitation of Fl_Text_Display's current implementation.
|
||||
\note The caller is responsible for managing the memory of the style table.
|
||||
\note Until STR#3412 is repaired, Fl_Text_Display has scrolling bug if the
|
||||
style table's font size != textsize()
|
||||
|
||||
\param stable - the style table, an array of structs of the type
|
||||
Fl_Text_Display::Style_Table_Entry
|
||||
\param stable_size - the sizeof() the style table (in bytes)
|
||||
\param normal_style_index - the style table index# used when the special
|
||||
ANSI sequence "\033[0m" is encountered.
|
||||
Normally use 0 so that sequence selects the
|
||||
first item in the table. Only use different
|
||||
values if a different entry in the table
|
||||
should be the default. This value should
|
||||
not be larger than the number of items in
|
||||
the table, or it will be clamped with a
|
||||
modulus operation.
|
||||
*/
|
||||
void Fl_Simple_Terminal::style_table(Fl_Text_Display::Style_Table_Entry *stable,
|
||||
int stable_size, int normal_style_index) {
|
||||
// Wrap index to ensure it's never larger than table
|
||||
normal_style_index = abs(normal_style_index) % (stable_size/STE_SIZE);
|
||||
|
||||
if ( stable_ == 0 ) {
|
||||
// User wants built-in style table?
|
||||
stable_ = &builtin_stable[0];
|
||||
stable_size_ = builtin_stable_size;
|
||||
normal_style_index_ = builtin_normal_index; // set the index used by \033[0m
|
||||
current_style_index_ = builtin_normal_index; // set the index used for drawing new text
|
||||
} else {
|
||||
// User supplying custom style table
|
||||
stable_ = stable;
|
||||
stable_size_ = stable_size;
|
||||
normal_style_index_ = normal_style_index; // set the index used by \033[0m
|
||||
current_style_index_ = normal_style_index; // set the index used for drawing new text
|
||||
}
|
||||
clear(); // don't take any chances with old style info
|
||||
highlight_data(sbuf, stable_, stable_size/STE_SIZE, 'A', 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
Scroll to last line unless someone has manually scrolled
|
||||
the vertical scrollbar away from the bottom.
|
||||
|
||||
This is a protected member called automatically by the public API functions.
|
||||
Only internal methods or subclasses adjusting the internal buffer directly
|
||||
should need to call this.
|
||||
*/
|
||||
void Fl_Simple_Terminal::enforce_stay_at_bottom() {
|
||||
if ( stay_at_bottom_ && buffer() && !scrollaway ) {
|
||||
scroll(mNBufferLines, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Enforce 'history_lines' limit on the history buffer by trimming off
|
||||
lines from the top of the buffer.
|
||||
|
||||
This is a protected member called automatically by the public API functions.
|
||||
Only internal methods or subclasses adjusting the internal buffer directly
|
||||
should need to call this.
|
||||
*/
|
||||
void Fl_Simple_Terminal::enforce_history_lines() {
|
||||
if ( history_lines() > -1 && lines > history_lines() ) {
|
||||
int trimlines = lines - history_lines();
|
||||
remove_lines(0, trimlines); // remove lines from top
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Appends new string 's' to terminal.
|
||||
|
||||
The string can contain UTF-8, crlf's, and ANSI sequences are
|
||||
also supported when ansi(bool) is set to 'true'.
|
||||
|
||||
\param s string to append.
|
||||
|
||||
\param len optional length of string can be specified if known
|
||||
to save the internals from having to call strlen()
|
||||
|
||||
\see printf(), vprintf(), text(), clear()
|
||||
*/
|
||||
void Fl_Simple_Terminal::append(const char *s, int len) {
|
||||
// Remove ansi codes and adjust style buffer accordingly.
|
||||
if ( ansi() ) {
|
||||
int nstyles = stable_size_ / STE_SIZE;
|
||||
if ( len < 0 ) len = strlen(s);
|
||||
// New text buffer (after ansi codes parsed+removed)
|
||||
char *ntm = (char*)malloc(len+1); // new text memory
|
||||
char *ntp = ntm;
|
||||
char *nsm = (char*)malloc(len+1); // new style memory
|
||||
char *nsp = nsm;
|
||||
// ANSI values
|
||||
char astyle = 'A'+current_style_index_; // the running style index
|
||||
const char *esc = 0;
|
||||
const char *sp = s;
|
||||
// Walk user's string looking for codes, modify new text/style text as needed
|
||||
while ( *sp ) {
|
||||
if ( *sp == 033 ) { // "\033.."
|
||||
esc = sp++;
|
||||
switch (*sp) {
|
||||
case 0: // "\033<NUL>"? stop
|
||||
continue;
|
||||
case '[': { // "\033[.."
|
||||
++sp;
|
||||
int vals[4], tv=0, seqdone=0;
|
||||
while ( *sp && !seqdone && isdigit(*sp) ) { // "\033[#;#.."
|
||||
char *newsp;
|
||||
long a = strtol(sp, &newsp, 10);
|
||||
sp = newsp;
|
||||
vals[tv++] = (a<0) ? 0 : a; // prevent negative values
|
||||
if ( tv >= 4 ) // too many #'s specified? abort sequence
|
||||
{ seqdone = 1; sp = esc+1; continue; }
|
||||
switch(*sp) {
|
||||
case ';': // numeric separator
|
||||
++sp;
|
||||
continue;
|
||||
case 'J': // erase in display
|
||||
switch (vals[0]) {
|
||||
case 0: // \033[0J -- clear to eol
|
||||
// unsupported
|
||||
break;
|
||||
case 1: // \033[1J -- clear to sol
|
||||
// unsupported
|
||||
break;
|
||||
case 2: // \033[2J -- clear entire screen
|
||||
clear(); // clear text buffer
|
||||
ntp = ntm; // clear text contents accumulated so far
|
||||
nsp = nsm; // clear style contents ""
|
||||
break;
|
||||
}
|
||||
++sp;
|
||||
seqdone = 1;
|
||||
continue;
|
||||
case 'm': // set color
|
||||
if ( tv > 0 ) { // at least one value parsed?
|
||||
current_style_index_ = (vals[0] == 0) // "reset"?
|
||||
? normal_style_index_ // use normal color for "reset"
|
||||
: (vals[0] % nstyles); // use user's value, wrapped to ensure not larger than table
|
||||
astyle = 'A' + current_style_index_; // convert index -> style buffer char
|
||||
}
|
||||
++sp;
|
||||
seqdone = 1;
|
||||
continue;
|
||||
case '\0': // EOS in middle of sequence?
|
||||
*ntp = 0; // end of text
|
||||
*nsp = 0; // end of style
|
||||
seqdone = 1;
|
||||
continue;
|
||||
default: // un-supported cmd?
|
||||
seqdone = 1;
|
||||
sp = esc+1; // continue parsing just past esc
|
||||
break;
|
||||
} // switch
|
||||
} // while
|
||||
} // case '['
|
||||
} // switch
|
||||
} // \033
|
||||
else {
|
||||
// Non-ANSI character?
|
||||
if ( *sp == '\n' ) ++lines; // keep track of #lines
|
||||
*ntp++ = *sp++; // pass char thru
|
||||
*nsp++ = astyle; // use current style
|
||||
}
|
||||
} // while
|
||||
*ntp = 0;
|
||||
*nsp = 0;
|
||||
//::printf(" RESULT: ntm='%s'\n", ntm);
|
||||
//::printf(" RESULT: nsm='%s'\n", nsm);
|
||||
buf->append(ntm); // new text memory
|
||||
sbuf->append(nsm); // new style memory
|
||||
free(ntm);
|
||||
free(nsm);
|
||||
} else {
|
||||
// non-ansi buffer
|
||||
buf->append(s);
|
||||
lines += ::strcnt(s, '\n'); // count total line feeds in string added
|
||||
}
|
||||
enforce_history_lines();
|
||||
enforce_stay_at_bottom();
|
||||
}
|
||||
|
||||
/**
|
||||
Replaces the terminal with new text content in string 's'.
|
||||
|
||||
The string can contain UTF-8, crlf's, and ANSI sequences are
|
||||
also supported when ansi(bool) is set to 'true'.
|
||||
|
||||
Old terminal content is completely cleared.
|
||||
|
||||
\param s string to append.
|
||||
|
||||
\param len optional length of string can be specified if known
|
||||
to save the internals from having to call strlen()
|
||||
|
||||
\see append(), printf(), vprintf(), clear()
|
||||
|
||||
*/
|
||||
void Fl_Simple_Terminal::text(const char *s, int len) {
|
||||
clear();
|
||||
append(s, len);
|
||||
}
|
||||
|
||||
/**
|
||||
Returns entire text content of the terminal as a single string.
|
||||
|
||||
This includes the screen history, as well as the visible
|
||||
onscreen content.
|
||||
*/
|
||||
const char* Fl_Simple_Terminal::text() const {
|
||||
return buf->text();
|
||||
}
|
||||
|
||||
/**
|
||||
Appends printf formatted messages to the terminal.
|
||||
|
||||
The string can contain UTF-8, crlf's, and ANSI sequences are
|
||||
also supported when ansi(bool) is set to 'true'.
|
||||
|
||||
Example:
|
||||
\code
|
||||
#include <FL/Fl_Simple_Terminal.H>
|
||||
int main(..) {
|
||||
:
|
||||
// Create a simple terminal, and append some messages to it
|
||||
Fl_Simple_Terminal *tty = new Fl_Simple_Terminal(..);
|
||||
:
|
||||
// Append three lines of formatted text to the buffer
|
||||
tty->printf("The current date is: %s.\nThe time is: %s\n", date_str, time_str);
|
||||
tty->printf("The current PID is %ld.\n", (long)getpid());
|
||||
:
|
||||
\endcode
|
||||
\note See Fl_Text_Buffer::vprintf() for limitations.
|
||||
\param[in] fmt is a printf format string for the message text.
|
||||
*/
|
||||
void Fl_Simple_Terminal::printf(const char *fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
Fl_Simple_Terminal::vprintf(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
/**
|
||||
Appends printf formatted messages to the terminal.
|
||||
|
||||
Subclasses can use this to implement their own printf()
|
||||
functionality.
|
||||
|
||||
The string can contain UTF-8, crlf's, and ANSI sequences are
|
||||
also supported when ansi(bool) is set to 'true'.
|
||||
|
||||
\note The expanded string is currently limited to 1024 characters.
|
||||
\param fmt is a printf format string for the message text.
|
||||
\param ap is a va_list created by va_start() and closed with va_end(),
|
||||
which the caller is responsible for handling.
|
||||
*/
|
||||
void Fl_Simple_Terminal::vprintf(const char *fmt, va_list ap) {
|
||||
char buffer[1024]; // XXX: should be user configurable..
|
||||
::vsnprintf(buffer, 1024, fmt, ap);
|
||||
buffer[1024-1] = 0; // XXX: MICROSOFT
|
||||
append(buffer);
|
||||
enforce_history_lines();
|
||||
}
|
||||
|
||||
/**
|
||||
Clears the terminal's screen and history. Cursor moves to top of window.
|
||||
*/
|
||||
void Fl_Simple_Terminal::clear() {
|
||||
buf->text("");
|
||||
sbuf->text("");
|
||||
lines = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
Remove the specified range of lines from the terminal, starting
|
||||
with line 'start' and removing 'count' lines.
|
||||
|
||||
This method is used to enforce the history limit.
|
||||
|
||||
\param start -- starting line to remove
|
||||
\param count -- number of lines to remove
|
||||
*/
|
||||
void Fl_Simple_Terminal::remove_lines(int start, int count) {
|
||||
int spos = skip_lines(0, start, true);
|
||||
int epos = skip_lines(spos, count, true);
|
||||
if ( ansi() ) {
|
||||
buf->remove(spos, epos);
|
||||
sbuf->remove(spos, epos);
|
||||
} else {
|
||||
buf->remove(spos, epos);
|
||||
}
|
||||
lines -= count;
|
||||
if ( lines < 0 ) lines = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
Draws the widget, including a cursor at the end of the buffer.
|
||||
This is needed since currently Fl_Text_Display doesn't provide
|
||||
a reliable way to always do this.
|
||||
*/
|
||||
void Fl_Simple_Terminal::draw() {
|
||||
// XXX: To do this right, we have to steal some of Fl_Text_Display's internal
|
||||
// magic numbers to do it right, e.g. LEFT_MARGIN, RIGHT_MARGIN.. :/
|
||||
//
|
||||
#define LEFT_MARGIN 3
|
||||
#define RIGHT_MARGIN 3
|
||||
int buflen = buf->length();
|
||||
// Force cursor to EOF so it doesn't draw at user's last left-click
|
||||
insert_position(buflen);
|
||||
// Let widget draw itself
|
||||
Fl_Text_Display::draw();
|
||||
// Now draw cursor at the end of the buffer
|
||||
fl_push_clip(text_area.x-LEFT_MARGIN,
|
||||
text_area.y,
|
||||
text_area.w+LEFT_MARGIN+RIGHT_MARGIN,
|
||||
text_area.h);
|
||||
int X = 0, Y = 0;
|
||||
if (position_to_xy(buflen, &X, &Y)) draw_cursor(X, Y);
|
||||
fl_pop_clip();
|
||||
}
|
|
@ -78,6 +78,7 @@ CPPFILES = \
|
|||
Fl_Scroll.cxx \
|
||||
Fl_Scrollbar.cxx \
|
||||
Fl_Shared_Image.cxx \
|
||||
Fl_Simple_Terminal.cxx \
|
||||
Fl_Single_Window.cxx \
|
||||
Fl_Slider.cxx \
|
||||
Fl_Spinner.cxx \
|
||||
|
|
|
@ -286,7 +286,7 @@ unittests$(EXEEXT): unittests.o
|
|||
|
||||
unittests.o: unittests.cxx unittest_about.cxx unittest_points.cxx unittest_lines.cxx unittest_circles.cxx \
|
||||
unittest_rects.cxx unittest_text.cxx unittest_symbol.cxx unittest_viewport.cxx unittest_images.cxx \
|
||||
unittest_schemes.cxx
|
||||
unittest_schemes.cxx unittest_simple_terminal.cxx
|
||||
|
||||
adjuster$(EXEEXT): adjuster.o
|
||||
|
||||
|
|
|
@ -58,6 +58,7 @@ That was a blank line above this.
|
|||
#include <FL/Fl_Button.H>
|
||||
#include <FL/Fl_Int_Input.H>
|
||||
#include <FL/Fl_Choice.H>
|
||||
#include <FL/Fl_Simple_Terminal.H>
|
||||
#include <FL/fl_ask.H>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
@ -74,6 +75,7 @@ Fl_Button *top,
|
|||
Fl_Choice *btype;
|
||||
Fl_Choice *wtype;
|
||||
Fl_Int_Input *field;
|
||||
Fl_Simple_Terminal *tty = 0;
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
|
@ -95,7 +97,7 @@ WhenItem when_items[] = {
|
|||
};
|
||||
|
||||
void b_cb(Fl_Widget* o, void*) {
|
||||
printf("callback, selection = %d, event_clicks = %d\n",
|
||||
tty->printf("callback, selection = \033[31m%d\033[0m, event_clicks = \033[32m%d\033[0m\n",
|
||||
((Fl_Browser*)o)->value(), Fl::event_clicks());
|
||||
}
|
||||
|
||||
|
@ -154,7 +156,7 @@ int main(int argc, char **argv) {
|
|||
int i;
|
||||
if (!Fl::args(argc,argv,i)) Fl::fatal(Fl::help);
|
||||
const char* fname = (i < argc) ? argv[i] : "browser.cxx";
|
||||
Fl_Double_Window window(720,400,fname);
|
||||
Fl_Double_Window window(720,520,fname);
|
||||
browser = new Fl_Select_Browser(0,0,window.w(),350,0);
|
||||
browser->type(FL_MULTI_BROWSER);
|
||||
//browser->type(FL_HOLD_BROWSER);
|
||||
|
@ -232,6 +234,11 @@ int main(int argc, char **argv) {
|
|||
wtype->callback(wtype_cb);
|
||||
wtype->value(4); // FL_WHEN_RELEASE_ALWAYS is Fl_Browser's default
|
||||
|
||||
// Small terminal window for callback messages
|
||||
tty = new Fl_Simple_Terminal(0,400,720,120);
|
||||
tty->history_lines(50);
|
||||
tty->ansi(true);
|
||||
|
||||
window.resizable(browser);
|
||||
window.show(argc,argv);
|
||||
return Fl::run();
|
||||
|
|
|
@ -41,8 +41,12 @@
|
|||
#include <FL/Fl_PNM_Image.H>
|
||||
#include <FL/Fl_Light_Button.H>
|
||||
#include <FL/Fl_Double_Window.H>
|
||||
#include <FL/Fl_Simple_Terminal.H>
|
||||
#include <string.h>
|
||||
|
||||
#define TERMINAL_HEIGHT 120
|
||||
#define TERMINAL_GREEN "\033[32m"
|
||||
#define TERMINAL_NORMAL "\033[0m"
|
||||
|
||||
//
|
||||
// Globals...
|
||||
|
@ -52,6 +56,7 @@ Fl_Input *filter;
|
|||
Fl_File_Browser *files;
|
||||
Fl_File_Chooser *fc;
|
||||
Fl_Shared_Image *image = 0;
|
||||
Fl_Simple_Terminal *tty = 0;
|
||||
|
||||
// for choosing extra groups
|
||||
Fl_Choice *ch_extra;
|
||||
|
@ -101,7 +106,10 @@ main(int argc, // I - Number of command-line arguments
|
|||
Fl_Shared_Image::add_handler(ps_check);
|
||||
|
||||
// Make the main window...
|
||||
window = new Fl_Double_Window(400, 215, "File Chooser Test");
|
||||
window = new Fl_Double_Window(400, 215+TERMINAL_HEIGHT, "File Chooser Test");
|
||||
|
||||
tty = new Fl_Simple_Terminal(0,215,window->w(),TERMINAL_HEIGHT);
|
||||
tty->ansi(true);
|
||||
|
||||
filter = new Fl_Input(50, 10, 315, 25, "Filter:");
|
||||
// Process standard arguments and find filter argument if present
|
||||
|
@ -221,11 +229,11 @@ fc_callback(Fl_File_Chooser *fc, // I - File chooser
|
|||
const char *filename; // Current filename
|
||||
|
||||
|
||||
printf("fc_callback(fc = %p, data = %p)\n", fc, data);
|
||||
tty->printf("fc_callback(fc = %p, data = %p)\n", fc, data);
|
||||
|
||||
filename = fc->value();
|
||||
|
||||
printf(" filename = \"%s\"\n", filename ? filename : "(null)");
|
||||
tty->printf(" filename = \"%s\"\n", filename ? filename : "(null)");
|
||||
}
|
||||
|
||||
|
||||
|
@ -365,6 +373,8 @@ show_callback(void)
|
|||
if (!fc->value(i))
|
||||
break;
|
||||
|
||||
tty->printf("%d/%d) %sPicked: '%s'%s\n", i, count, TERMINAL_GREEN, fc->value(i), TERMINAL_NORMAL);
|
||||
|
||||
fl_filename_relative(relative, sizeof(relative), fc->value(i));
|
||||
|
||||
files->add(relative,
|
||||
|
|
|
@ -28,9 +28,15 @@
|
|||
#include <FL/Fl_Toggle_Button.H>
|
||||
#include <FL/Fl_Light_Button.H>
|
||||
#include <FL/Fl_Color_Chooser.H>
|
||||
#include <FL/Fl_Simple_Terminal.H>
|
||||
|
||||
#define TERMINAL_HEIGHT 120
|
||||
|
||||
// Globals
|
||||
Fl_Simple_Terminal *G_tty = 0;
|
||||
|
||||
void cb(Fl_Widget *ob) {
|
||||
printf("Callback for %s '%s'\n",ob->label(),((Fl_Input*)ob)->value());
|
||||
G_tty->printf("Callback for %s '%s'\n",ob->label(),((Fl_Input*)ob)->value());
|
||||
}
|
||||
|
||||
int when = 0;
|
||||
|
@ -43,11 +49,11 @@ void toggle_cb(Fl_Widget *o, long v) {
|
|||
|
||||
void test(Fl_Input *i) {
|
||||
if (i->changed()) {
|
||||
i->clear_changed(); printf("%s '%s'\n",i->label(),i->value());
|
||||
i->clear_changed(); G_tty->printf("%s '%s'\n",i->label(),i->value());
|
||||
char utf8buf[10];
|
||||
int last = fl_utf8encode(i->index(i->position()), utf8buf);
|
||||
utf8buf[last] = 0;
|
||||
printf("Symbol at cursor position: %s\n", utf8buf);
|
||||
G_tty->printf("Symbol at cursor position: %s\n", utf8buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,7 +92,8 @@ int main(int argc, char **argv) {
|
|||
// calling fl_contrast below will return good results
|
||||
Fl::args(argc, argv);
|
||||
Fl::get_system_colors();
|
||||
Fl_Window *window = new Fl_Window(400,420);
|
||||
Fl_Window *window = new Fl_Window(400,420+TERMINAL_HEIGHT);
|
||||
G_tty = new Fl_Simple_Terminal(0,420,window->w(),TERMINAL_HEIGHT);
|
||||
|
||||
int y = 10;
|
||||
input[0] = new Fl_Input(70,y,300,30,"Normal:"); y += 35;
|
||||
|
@ -153,6 +160,7 @@ int main(int argc, char **argv) {
|
|||
b->tooltip("Color of the text");
|
||||
|
||||
window->end();
|
||||
window->resizable(G_tty);
|
||||
window->show(argc,argv);
|
||||
return Fl::run();
|
||||
}
|
||||
|
|
|
@ -20,6 +20,12 @@
|
|||
#include <FL/Fl_Button.H>
|
||||
#include <FL/Fl_Double_Window.H>
|
||||
#include <FL/Fl_Input_Choice.H>
|
||||
#include <FL/Fl_Simple_Terminal.H>
|
||||
|
||||
#define TERMINAL_HEIGHT 120
|
||||
|
||||
// Globals
|
||||
Fl_Simple_Terminal *G_tty = 0;
|
||||
|
||||
void buttcb(Fl_Widget*,void*data) {
|
||||
Fl_Input_Choice *in=(Fl_Input_Choice *)data;
|
||||
|
@ -28,18 +34,19 @@ void buttcb(Fl_Widget*,void*data) {
|
|||
if ( flag ) in->activate();
|
||||
else in->deactivate();
|
||||
if (in->changed()) {
|
||||
printf("Callback: changed() is set\n");
|
||||
G_tty->printf("Callback: changed() is set\n");
|
||||
in->clear_changed();
|
||||
}
|
||||
}
|
||||
|
||||
void input_choice_cb(Fl_Widget*,void*data) {
|
||||
Fl_Input_Choice *in=(Fl_Input_Choice *)data;
|
||||
fprintf(stderr, "Value='%s'\n", (const char*)in->value());
|
||||
G_tty->printf("Value='%s'\n", (const char*)in->value());
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
Fl_Double_Window win(300, 200);
|
||||
Fl_Double_Window win(300, 200+TERMINAL_HEIGHT);
|
||||
G_tty = new Fl_Simple_Terminal(0,200,win.w(),TERMINAL_HEIGHT);
|
||||
|
||||
Fl_Input_Choice in(40,40,100,28,"Test");
|
||||
in.callback(input_choice_cb, (void*)&in);
|
||||
|
|
|
@ -30,9 +30,15 @@
|
|||
#include <stdlib.h>
|
||||
#include "../src/flstring.h"
|
||||
#include <FL/fl_draw.H>
|
||||
#include <FL/Fl_Simple_Terminal.H>
|
||||
|
||||
#define TERMINAL_HEIGHT 120
|
||||
|
||||
// Globals
|
||||
Fl_Simple_Terminal *G_tty = 0;
|
||||
|
||||
void window_cb(Fl_Widget* w, void*) {
|
||||
puts("window callback called");
|
||||
puts("window callback called"); // end of program, so stdout instead of G_tty
|
||||
((Fl_Double_Window *)w)->hide();
|
||||
}
|
||||
|
||||
|
@ -40,11 +46,11 @@ void test_cb(Fl_Widget* w, void*) {
|
|||
Fl_Menu_* mw = (Fl_Menu_*)w;
|
||||
const Fl_Menu_Item* m = mw->mvalue();
|
||||
if (!m)
|
||||
printf("NULL\n");
|
||||
G_tty->printf("NULL\n");
|
||||
else if (m->shortcut())
|
||||
printf("%s - %s\n", m->label(), fl_shortcut_label(m->shortcut()));
|
||||
G_tty->printf("%s - %s\n", m->label(), fl_shortcut_label(m->shortcut()));
|
||||
else
|
||||
printf("%s\n", m->label());
|
||||
G_tty->printf("%s\n", m->label());
|
||||
}
|
||||
|
||||
void quit_cb(Fl_Widget*, void*) {exit(0);}
|
||||
|
@ -211,7 +217,9 @@ int main(int argc, char **argv) {
|
|||
sprintf(buf,"item %d",i);
|
||||
hugemenu[i].text = strdup(buf);
|
||||
}
|
||||
Fl_Double_Window window(WIDTH,400);
|
||||
Fl_Double_Window window(WIDTH,400+TERMINAL_HEIGHT);
|
||||
G_tty = new Fl_Simple_Terminal(0,400,WIDTH,TERMINAL_HEIGHT);
|
||||
|
||||
window.callback(window_cb);
|
||||
Fl_Menu_Bar menubar(0,0,WIDTH,30); menubar.menu(menutable);
|
||||
menubar.callback(test_cb);
|
||||
|
|
|
@ -27,10 +27,14 @@
|
|||
#include <FL/Fl_Box.H>
|
||||
#include <FL/Fl_Native_File_Chooser.H>
|
||||
#include <FL/Fl_Help_View.H>
|
||||
#include <FL/Fl_Simple_Terminal.H>
|
||||
|
||||
#define TERMINAL_HEIGHT 120
|
||||
|
||||
// GLOBALS
|
||||
Fl_Input *G_filename = NULL;
|
||||
Fl_Multiline_Input *G_filter = NULL;
|
||||
Fl_Simple_Terminal *G_tty = NULL;
|
||||
|
||||
void PickFile_CB(Fl_Widget*, void*) {
|
||||
// Create native chooser
|
||||
|
@ -41,13 +45,15 @@ void PickFile_CB(Fl_Widget*, void*) {
|
|||
native.preset_file(G_filename->value());
|
||||
// Show native chooser
|
||||
switch ( native.show() ) {
|
||||
case -1: fprintf(stderr, "ERROR: %s\n", native.errmsg()); break; // ERROR
|
||||
case 1: fprintf(stderr, "*** CANCEL\n"); fl_beep(); break; // CANCEL
|
||||
case -1: G_tty->printf("ERROR: %s\n", native.errmsg()); break; // ERROR
|
||||
case 1: G_tty->printf("*** CANCEL\n"); fl_beep(); break; // CANCEL
|
||||
default: // PICKED FILE
|
||||
if ( native.filename() ) {
|
||||
G_filename->value(native.filename());
|
||||
G_tty->printf("filename='%s'\n", native.filename());
|
||||
} else {
|
||||
G_filename->value("NULL");
|
||||
G_tty->printf("filename='(null)'\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -61,13 +67,15 @@ void PickDir_CB(Fl_Widget*, void*) {
|
|||
native.type(Fl_Native_File_Chooser::BROWSE_DIRECTORY);
|
||||
// Show native chooser
|
||||
switch ( native.show() ) {
|
||||
case -1: fprintf(stderr, "ERROR: %s\n", native.errmsg()); break; // ERROR
|
||||
case 1: fprintf(stderr, "*** CANCEL\n"); fl_beep(); break; // CANCEL
|
||||
case -1: G_tty->printf("ERROR: %s\n", native.errmsg()); break; // ERROR
|
||||
case 1: G_tty->printf("*** CANCEL\n"); fl_beep(); break; // CANCEL
|
||||
default: // PICKED DIR
|
||||
if ( native.filename() ) {
|
||||
G_filename->value(native.filename());
|
||||
G_tty->printf("dirname='%s'\n", native.filename());
|
||||
} else {
|
||||
G_filename->value("NULL");
|
||||
G_tty->printf("dirname='(null)'\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -91,10 +99,12 @@ int main(int argc, char **argv) {
|
|||
argn++;
|
||||
#endif
|
||||
|
||||
Fl_Window *win = new Fl_Window(640, 400, "Native File Chooser Test");
|
||||
Fl_Window *win = new Fl_Window(640, 400+TERMINAL_HEIGHT, "Native File Chooser Test");
|
||||
win->size_range(win->w(), win->h(), 0, 0);
|
||||
win->begin();
|
||||
{
|
||||
G_tty = new Fl_Simple_Terminal(0,400,win->w(),TERMINAL_HEIGHT);
|
||||
|
||||
int x = 80, y = 10;
|
||||
G_filename = new Fl_Input(x, y, win->w()-80-10, 25, "Filename");
|
||||
G_filename->value(argc <= argn ? "." : argv[argn]);
|
||||
|
@ -131,10 +141,10 @@ int main(int argc, char **argv) {
|
|||
" Apps<font color=#55f><Ctrl-I></font>*.app\n"
|
||||
"</pre>\n");
|
||||
|
||||
Fl_Button *but = new Fl_Button(win->w()-x-10, win->h()-25-10, 80, 25, "Pick File");
|
||||
Fl_Button *but = new Fl_Button(win->w()-x-10, win->h()-TERMINAL_HEIGHT-25-10, 80, 25, "Pick File");
|
||||
but->callback(PickFile_CB);
|
||||
|
||||
Fl_Button *butdir = new Fl_Button(but->x()-x-10, win->h()-25-10, 80, 25, "Pick Dir");
|
||||
Fl_Button *butdir = new Fl_Button(but->x()-x-10, win->h()-TERMINAL_HEIGHT-25-10, 80, 25, "Pick Dir");
|
||||
butdir->callback(PickDir_CB);
|
||||
|
||||
win->resizable(G_filter);
|
||||
|
|
|
@ -16,6 +16,12 @@
|
|||
#include <FL/fl_draw.H>
|
||||
#include <FL/fl_ask.H>
|
||||
#include <FL/Fl_Table_Row.H>
|
||||
#include <FL/Fl_Simple_Terminal.H>
|
||||
|
||||
#define TERMINAL_HEIGHT 120
|
||||
|
||||
// Globals
|
||||
Fl_Simple_Terminal *G_tty = 0;
|
||||
|
||||
// Simple demonstration class to derive from Fl_Table_Row
|
||||
class DemoTable : public Fl_Table_Row
|
||||
|
@ -99,7 +105,7 @@ void DemoTable::draw_cell(TableContext context,
|
|||
}
|
||||
|
||||
case CONTEXT_TABLE:
|
||||
fprintf(stderr, "TABLE CONTEXT CALLED\n");
|
||||
G_tty->printf("TABLE CONTEXT CALLED\n");
|
||||
return;
|
||||
|
||||
case CONTEXT_ENDPAGE:
|
||||
|
@ -121,9 +127,9 @@ void DemoTable::event_callback2()
|
|||
int R = callback_row(),
|
||||
C = callback_col();
|
||||
TableContext context = callback_context();
|
||||
printf("'%s' callback: ", (label() ? label() : "?"));
|
||||
printf("Row=%d Col=%d Context=%d Event=%d InteractiveResize? %d\n",
|
||||
R, C, (int)context, (int)Fl::event(), (int)is_interactive_resize());
|
||||
const char *name = label() ? label() : "?";
|
||||
G_tty->printf("'%s' callback: Row=%d Col=%d Context=%d Event=%d InteractiveResize? %d\n",
|
||||
name, R, C, (int)context, (int)Fl::event(), (int)is_interactive_resize());
|
||||
}
|
||||
|
||||
// GLOBAL TABLE WIDGET
|
||||
|
@ -339,7 +345,9 @@ Fl_Menu_Item type_choices[] = {
|
|||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
Fl_Window win(900, 730);
|
||||
Fl_Window win(900, 730+TERMINAL_HEIGHT);
|
||||
|
||||
G_tty = new Fl_Simple_Terminal(0,730,win.w(),TERMINAL_HEIGHT);
|
||||
|
||||
G_table = new DemoTable(20, 20, 860, 460, "Demo");
|
||||
G_table->selection_color(FL_YELLOW);
|
||||
|
|
43
test/tree.fl
43
test/tree.fl
|
@ -38,6 +38,9 @@ decl {\#include <FL/Fl_Color_Chooser.H>} {public global
|
|||
decl {\#include <FL/Fl_Text_Display.H>} {public global
|
||||
}
|
||||
|
||||
decl {\#include <FL/Fl_Simple_Terminal.H>} {public global
|
||||
}
|
||||
|
||||
decl {int G_cb_counter = 0;} {
|
||||
comment {// Global callback event counter} private local
|
||||
}
|
||||
|
@ -74,7 +77,7 @@ height += 10;
|
|||
if ( height > 50 ) height = 20;
|
||||
cw->resize(cw->x(), cw->y(), cw->w(), height);
|
||||
tree->redraw(); // adjusted height
|
||||
fprintf(stderr, "'%s' button pushed (height=%d)\\n", w->label(), height);} {}
|
||||
tty->printf("'%s' button pushed (height=%d)\\n", w->label(), height);} {}
|
||||
}
|
||||
|
||||
Function {AssignUserIcons()} {
|
||||
|
@ -144,8 +147,7 @@ for ( Fl_Tree_Item *item = tree->first(); item; item=item->next()) {
|
|||
item->userdeicon(0);
|
||||
}
|
||||
}
|
||||
tree->redraw();} {selected
|
||||
}
|
||||
tree->redraw();} {}
|
||||
}
|
||||
|
||||
Function {RebuildTree()} {
|
||||
|
@ -360,7 +362,7 @@ Function {} {open
|
|||
} {
|
||||
Fl_Window window {
|
||||
label tree open
|
||||
xywh {600 253 1045 580} type Double hide
|
||||
xywh {539 25 1045 730} type Double visible
|
||||
} {
|
||||
Fl_Group tree {
|
||||
label Tree
|
||||
|
@ -368,7 +370,7 @@ Function {} {open
|
|||
callback {G_cb_counter++; // Increment callback counter whenever tree callback is invoked
|
||||
Fl_Tree_Item *item = tree->callback_item();
|
||||
if ( item ) {
|
||||
fprintf(stderr, "TREE CALLBACK: label='%s' userdata=%ld reason=%s, changed=%d",
|
||||
tty->printf("TREE CALLBACK: label='%s' userdata=%ld reason=%s, changed=%d",
|
||||
item->label(),
|
||||
(long)(fl_intptr_t)tree->user_data(),
|
||||
reason_as_name(tree->callback_reason()),
|
||||
|
@ -377,12 +379,12 @@ if ( item ) {
|
|||
// Should only happen if reason==FL_TREE_REASON_RESELECTED.
|
||||
//
|
||||
if ( Fl::event_clicks() > 0 ) {
|
||||
fprintf(stderr, ", clicks=%d\\n", (Fl::event_clicks()+1));
|
||||
tty->printf(", clicks=%d\\n", (Fl::event_clicks()+1));
|
||||
} else {
|
||||
fprintf(stderr, "\\n");
|
||||
tty->printf("\\n");
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "TREE CALLBACK: reason=%s, changed=%d, item=(no item -- probably multiple items were changed at once)\\n",
|
||||
tty->printf("TREE CALLBACK: reason=%s, changed=%d, item=(no item -- probably multiple items were changed at once)\\n",
|
||||
reason_as_name(tree->callback_reason()),
|
||||
tree->changed() ? 1 : 0);
|
||||
}
|
||||
|
@ -896,7 +898,7 @@ Clears all items} xywh {570 471 95 16} labelsize 9
|
|||
Fl_Button testcallbackflag_button {
|
||||
label {Test Callback Flag}
|
||||
callback {Fl_Tree_Item *root = tree->root();
|
||||
fprintf(stderr, "--- Checking docallback off\\n");
|
||||
tty->printf("--- Checking docallback off\\n");
|
||||
if (!root) return;
|
||||
|
||||
//// "OFF" TEST
|
||||
|
@ -961,7 +963,7 @@ fl_alert("TEST COMPLETED\\n If you didn't see any error dialogs, test PASSED.");
|
|||
Fl_Button testrootshowself_button {
|
||||
label {Root Show Self}
|
||||
callback {Fl_Tree_Item *root = tree->root();
|
||||
fprintf(stderr, "--- Show Tree\\n");
|
||||
tty->printf("--- Show Tree\\n");
|
||||
if (root) root->show_self();}
|
||||
tooltip {Test the root->'show_self() method to show the entire tree on stdout} xywh {570 511 95 16} labelsize 9
|
||||
}
|
||||
|
@ -1231,11 +1233,11 @@ If nothing selected, all are changed} xywh {758 174 100 16} selection_color 1 la
|
|||
}
|
||||
Fl_Button showselected_button {
|
||||
label {Show Selected}
|
||||
callback {fprintf(stderr, "--- SELECTED ITEMS\\n");
|
||||
callback {tty->printf("--- SELECTED ITEMS\\n");
|
||||
for ( Fl_Tree_Item *item = tree->first_selected_item();
|
||||
item;
|
||||
item = tree->next_selected_item(item) ) {
|
||||
fprintf(stderr, "\\t%s\\n", item->label() ? item->label() : "???");
|
||||
tty->printf("\\t%s\\n", item->label() ? item->label() : "???");
|
||||
}}
|
||||
tooltip {Clears the selected items} xywh {864 134 95 16} labelsize 9
|
||||
}
|
||||
|
@ -1298,15 +1300,15 @@ tree->redraw();}
|
|||
}
|
||||
Fl_Button nextselected_button {
|
||||
label {next_selected()}
|
||||
callback {printf("--- TEST next_selected():\\n");
|
||||
printf(" // Walk down the tree (forwards)\\n");
|
||||
callback {tty->printf("--- TEST next_selected():\\n");
|
||||
tty->printf(" // Walk down the tree (forwards)\\n");
|
||||
for ( Fl_Tree_Item *i=tree->first_selected_item(); i; i=tree->next_selected_item(i, FL_Down) ) {
|
||||
printf(" Selected item: %s\\n", i->label()?i->label():"<nolabel>");
|
||||
tty->printf(" Selected item: %s\\n", i->label()?i->label():"<nolabel>");
|
||||
}
|
||||
|
||||
printf(" // Walk up the tree (backwards)\\n");
|
||||
tty->printf(" // Walk up the tree (backwards)\\n");
|
||||
for ( Fl_Tree_Item *i=tree->last_selected_item(); i; i=tree->next_selected_item(i, FL_Up) ) {
|
||||
printf(" Selected item: %s\\n", i->label()?i->label():"<nolabel>");
|
||||
tty->printf(" Selected item: %s\\n", i->label()?i->label():"<nolabel>");
|
||||
}}
|
||||
tooltip {Tests the Fl_Tree::next_selected() function} xywh {713 239 95 16} labelsize 9
|
||||
}
|
||||
|
@ -1703,7 +1705,7 @@ if ( !helpwin ) {
|
|||
}
|
||||
helpwin->resizable(helpdisp);
|
||||
helpwin->show();}
|
||||
tooltip {Suggestions on how to do tests} xywh {935 554 95 16} labelsize 9
|
||||
tooltip {Suggestions on how to do tests} xywh {935 545 95 16} labelsize 9
|
||||
}
|
||||
Fl_Value_Slider tree_scrollbar_size_slider {
|
||||
label {Fl_Tree::scrollbar_size()}
|
||||
|
@ -1730,6 +1732,11 @@ tree->redraw();}
|
|||
Fl_Box resizer_box {
|
||||
xywh {0 263 15 14}
|
||||
}
|
||||
Fl_Box tty {
|
||||
label label selected
|
||||
xywh {16 571 1014 149} box DOWN_BOX color 0
|
||||
class Fl_Simple_Terminal
|
||||
}
|
||||
}
|
||||
code {// Initialize Tree
|
||||
tree->root_label("ROOT");
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
//
|
||||
// "$Id$"
|
||||
//
|
||||
// Unit tests for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 1998-2017 by Bill Spitzak and others.
|
||||
//
|
||||
// This library is free software. Distribution and use rights are outlined in
|
||||
// the file "COPYING" which should have been included with this file. If this
|
||||
// file is missing or damaged, see the license at:
|
||||
//
|
||||
// http://www.fltk.org/COPYING.php
|
||||
//
|
||||
// Please report all bugs and problems on the following page:
|
||||
//
|
||||
// http://www.fltk.org/str.php
|
||||
//
|
||||
|
||||
#include <time.h>
|
||||
#include <FL/Fl_Group.H>
|
||||
#include <FL/Fl_Simple_Terminal.H>
|
||||
|
||||
//
|
||||
//------- test the Fl_Simple_Terminal drawing capabilities ----------
|
||||
//
|
||||
class SimpleTerminal : public Fl_Group {
|
||||
Fl_Simple_Terminal *tty1;
|
||||
Fl_Simple_Terminal *tty2;
|
||||
Fl_Simple_Terminal *tty3;
|
||||
void AnsiTestPattern(Fl_Simple_Terminal *tty) {
|
||||
tty->append("\033[30mBlack Courier 14\033[0m Normal text\n"
|
||||
"\033[31mRed Courier 14\033[0m Normal text\n"
|
||||
"\033[32mGreen Courier 14\033[0m Normal text\n"
|
||||
"\033[33mYellow Courier 14\033[0m Normal text\n"
|
||||
"\033[34mBlue Courier 14\033[0m Normal text\n"
|
||||
"\033[35mMagenta Courier 14\033[0m Normal text\n"
|
||||
"\033[36mCyan Courier 14\033[0m Normal text\n"
|
||||
"\033[37mWhite Courier 14\033[0m Normal text\n"
|
||||
"\033[40mBright Black Courier 14\033[0m Normal text\n"
|
||||
"\033[41mBright Red Courier 14\033[0m Normal text\n"
|
||||
"\033[42mBright Green Courier 14\033[0m Normal text\n"
|
||||
"\033[43mBright Yellow Courier 14\033[0m Normal text\n"
|
||||
"\033[44mBright Blue Courier 14\033[0m Normal text\n"
|
||||
"\033[45mBright Magenta Courier 14\033[0m Normal text\n"
|
||||
"\033[46mBright Cyan Courier 14\033[0m Normal text\n"
|
||||
"\033[47mBright White Courier 14\033[0m Normal text\n"
|
||||
"\n"
|
||||
"\033[31mRed\033[32mGreen\033[33mYellow\033[34mBlue\033[35mMagenta\033[36mCyan\033[37mWhite\033[0m - "
|
||||
"\033[31mX\033[32mX\033[33mX\033[34mX\033[35mX\033[36mX\033[37mX\033[0m\n"
|
||||
"\033[41mRed\033[42mGreen\033[43mYellow\033[44mBlue\033[45mMagenta\033[46mCyan\033[47mWhite\033[0m - "
|
||||
"\033[41mX\033[42mX\033[43mX\033[44mX\033[45mX\033[46mX\033[47mX\033[0m\n");
|
||||
}
|
||||
void GrayTestPattern(Fl_Simple_Terminal *tty) {
|
||||
tty->append("Grayscale Test Pattern\n"
|
||||
"--------------------------\n"
|
||||
"\033[0m 100% white Courier 14\n"
|
||||
"\033[1m 90% white Courier 14\n"
|
||||
"\033[2m 80% white Courier 14\n"
|
||||
"\033[3m 70% white Courier 14\n"
|
||||
"\033[4m 60% white Courier 14\n"
|
||||
"\033[5m 50% white Courier 14\n"
|
||||
"\033[6m 40% white Courier 14\n"
|
||||
"\033[7m 30% white Courier 14\n"
|
||||
"\033[8m 20% white Courier 14\n"
|
||||
"\033[9m 10% white Courier 14\n"
|
||||
"\033[0m");
|
||||
}
|
||||
static void DateTimer_CB(void *data) {
|
||||
Fl_Simple_Terminal *tty = (Fl_Simple_Terminal*)data;
|
||||
time_t lt = time(NULL);
|
||||
tty->printf("The time and date is now: %s", ctime(<));
|
||||
Fl::repeat_timeout(3.0, DateTimer_CB, data);
|
||||
}
|
||||
public:
|
||||
static Fl_Widget *create() {
|
||||
return new SimpleTerminal(TESTAREA_X, TESTAREA_Y, TESTAREA_W, TESTAREA_H);
|
||||
}
|
||||
SimpleTerminal(int x, int y, int w, int h) : Fl_Group(x, y, w, h) {
|
||||
static Fl_Text_Display::Style_Table_Entry my_stable[] = { // 10 entry grayscale
|
||||
// Font Color Font Face Font Size ANSI Sequence
|
||||
// ---------- ---------------- --------- -------------
|
||||
{ 0xffffff00, FL_COURIER_BOLD, 14 }, // "\033[0m" 0 white 100%
|
||||
{ 0xe6e6e600, FL_COURIER_BOLD, 14 }, // "\033[1m" 1 white 90%
|
||||
{ 0xcccccc00, FL_COURIER_BOLD, 14 }, // "\033[2m" 2 white 80%
|
||||
{ 0xb3b3b300, FL_COURIER_BOLD, 14 }, // "\033[3m" 3 white 70%
|
||||
{ 0x99999900, FL_COURIER_BOLD, 14 }, // "\033[4m" 4 white 60%
|
||||
{ 0x80808000, FL_COURIER_BOLD, 14 }, // "\033[5m" 5 white 50% "\033[0m"
|
||||
{ 0x66666600, FL_COURIER_BOLD, 14 }, // "\033[6m" 6 white 40%
|
||||
{ 0x4d4d4d00, FL_COURIER_BOLD, 14 }, // "\033[7m" 7 white 30%
|
||||
{ 0x33333300, FL_COURIER_BOLD, 14 }, // "\033[8m" 8 white 20%
|
||||
{ 0x1a1a1a00, FL_COURIER_BOLD, 14 }, // "\033[9m" 9 white 10%
|
||||
};
|
||||
int tty_h = (h/3.5);
|
||||
int tty_y1 = y+(tty_h*0)+20;
|
||||
int tty_y2 = y+(tty_h*1)+40;
|
||||
int tty_y3 = y+(tty_h*2)+60;
|
||||
|
||||
// TTY1
|
||||
tty1 = new Fl_Simple_Terminal(x, tty_y1, w, tty_h,"Tty 1: ANSI off");
|
||||
tty1->ansi(false);
|
||||
Fl::add_timeout(0.5, DateTimer_CB, (void*)tty1);
|
||||
|
||||
// TTY2
|
||||
tty2 = new Fl_Simple_Terminal(x, tty_y2, w, tty_h,"Tty 2: ANSI on");
|
||||
tty2->ansi(true);
|
||||
AnsiTestPattern(tty2);
|
||||
Fl::add_timeout(0.5, DateTimer_CB, (void*)tty2);
|
||||
|
||||
// TTY3
|
||||
tty3 = new Fl_Simple_Terminal(x, tty_y3, w, tty_h, "Tty 3: Grayscale Style Table");
|
||||
tty3->style_table(my_stable, sizeof(my_stable), 0);
|
||||
tty3->ansi(true);
|
||||
GrayTestPattern(tty3);
|
||||
Fl::add_timeout(0.5, DateTimer_CB, (void*)tty3);
|
||||
|
||||
end();
|
||||
}
|
||||
};
|
||||
|
||||
UnitTest simple_terminal("simple terminal", SimpleTerminal::create);
|
||||
|
||||
//
|
||||
// End of "$Id$"
|
||||
//
|
|
@ -153,6 +153,7 @@ public:
|
|||
#include "unittest_viewport.cxx"
|
||||
#include "unittest_scrollbarsize.cxx"
|
||||
#include "unittest_schemes.cxx"
|
||||
#include "unittest_simple_terminal.cxx"
|
||||
|
||||
// callback whenever the browser value changes
|
||||
void Browser_CB(Fl_Widget*, void*) {
|
||||
|
|
Loading…
Reference in New Issue