fl_help_view.cxx
来自「SRI international 发布的OAA框架软件」· CXX 代码 · 共 2,703 行 · 第 1/5 页
CXX
2,703 行
//
// "$Id: Fl_Help_View.cxx,v 1.1.1.1 2003/06/03 22:25:42 agno Exp $"
//
// Fl_Help_View widget routines.
//
// Copyright 1997-2003 by Easy Software Products.
// Image support donated by Matthias Melcher, Copyright 2000.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA.
//
// Please report all bugs and problems to "fltk-bugs@fltk.org".
//
// Contents:
//
// Fl_Help_View::add_block() - Add a text block to the list.
// Fl_Help_View::add_link() - Add a new link to the list.
// Fl_Help_View::add_target() - Add a new target to the list.
// Fl_Help_View::compare_targets() - Compare two targets.
// Fl_Help_View::do_align() - Compute the alignment for a line in
// a block.
// Fl_Help_View::draw() - Draw the Fl_Help_View widget.
// Fl_Help_View::format() - Format the help text.
// Fl_Help_View::format_table() - Format a table...
// Fl_Help_View::get_align() - Get an alignment attribute.
// Fl_Help_View::get_attr() - Get an attribute value from the string.
// Fl_Help_View::get_color() - Get an alignment attribute.
// Fl_Help_View::handle() - Handle events in the widget.
// Fl_Help_View::Fl_Help_View() - Build a Fl_Help_View widget.
// Fl_Help_View::~Fl_Help_View() - Destroy a Fl_Help_View widget.
// Fl_Help_View::load() - Load the specified file.
// Fl_Help_View::resize() - Resize the help widget.
// Fl_Help_View::topline() - Set the top line to the named target.
// Fl_Help_View::topline() - Set the top line by number.
// Fl_Help_View::value() - Set the help text directly.
// scrollbar_callback() - A callback for the scrollbar.
//
//
// Include necessary header files...
//
#include <FL/Fl_Help_View.H>
#include <FL/Fl_Pixmap.H>
#include <stdio.h>
#include <stdlib.h>
#include "flstring.h"
#include <ctype.h>
#include <errno.h>
#if defined(WIN32) && ! defined(__CYGWIN__)
# include <io.h>
# include <direct.h>
#else
# include <unistd.h>
#endif // WIN32
#define MAX_COLUMNS 200
//
// Typedef the C API sort function type the only way I know how...
//
extern "C"
{
typedef int (*compare_func_t)(const void *, const void *);
}
//
// Local functions...
//
static int quote_char(const char *);
static void scrollbar_callback(Fl_Widget *s, void *);
static void hscrollbar_callback(Fl_Widget *s, void *);
//
// Broken image...
//
static const char *broken_xpm[] =
{
"16 24 4 1",
"@ c #000000",
" c #ffffff",
"+ c none",
"x c #ff0000",
// pixels
"@@@@@@@+++++++++",
"@ @++++++++++",
"@ @+++++++++++",
"@ @++@++++++++",
"@ @@+++++++++",
"@ @+++@+++++",
"@ @++@@++++@",
"@ xxx @@ @++@@",
"@ xxx xx@@ @",
"@ xxx xxx @",
"@ xxxxxx @",
"@ xxxx @",
"@ xxxxxx @",
"@ xxx xxx @",
"@ xxx xxx @",
"@ xxx xxx @",
"@ @",
"@ @",
"@ @",
"@ @",
"@ @",
"@ @",
"@ @",
"@@@@@@@@@@@@@@@@",
NULL
};
static Fl_Pixmap broken_image(broken_xpm);
//
// 'Fl_Help_View::add_block()' - Add a text block to the list.
//
Fl_Help_Block * // O - Pointer to new block
Fl_Help_View::add_block(const char *s, // I - Pointer to start of block text
int xx, // I - X position of block
int yy, // I - Y position of block
int ww, // I - Right margin of block
int hh, // I - Height of block
unsigned char border) // I - Draw border?
{
Fl_Help_Block *temp; // New block
// printf("add_block(s = %p, xx = %d, yy = %d, ww = %d, hh = %d, border = %d)\n",
// s, xx, yy, ww, hh, border);
if (nblocks_ >= ablocks_)
{
ablocks_ += 16;
if (ablocks_ == 16)
blocks_ = (Fl_Help_Block *)malloc(sizeof(Fl_Help_Block) * ablocks_);
else
blocks_ = (Fl_Help_Block *)realloc(blocks_, sizeof(Fl_Help_Block) * ablocks_);
}
temp = blocks_ + nblocks_;
memset(temp, 0, sizeof(Fl_Help_Block));
temp->start = s;
temp->end = s;
temp->x = xx;
temp->y = yy;
temp->w = ww;
temp->h = hh;
temp->border = border;
temp->bgcolor = bgcolor_;
nblocks_ ++;
return (temp);
}
//
// 'Fl_Help_View::add_link()' - Add a new link to the list.
//
void
Fl_Help_View::add_link(const char *n, // I - Name of link
int xx, // I - X position of link
int yy, // I - Y position of link
int ww, // I - Width of link text
int hh) // I - Height of link text
{
Fl_Help_Link *temp; // New link
char *target; // Pointer to target name
if (nlinks_ >= alinks_)
{
alinks_ += 16;
if (alinks_ == 16)
links_ = (Fl_Help_Link *)malloc(sizeof(Fl_Help_Link) * alinks_);
else
links_ = (Fl_Help_Link *)realloc(links_, sizeof(Fl_Help_Link) * alinks_);
}
temp = links_ + nlinks_;
temp->x = xx;
temp->y = yy;
temp->w = xx + ww;
temp->h = yy + hh;
strlcpy(temp->filename, n, sizeof(temp->filename));
if ((target = strrchr(temp->filename, '#')) != NULL)
{
*target++ = '\0';
strlcpy(temp->name, target, sizeof(temp->name));
}
else
temp->name[0] = '\0';
nlinks_ ++;
}
//
// 'Fl_Help_View::add_target()' - Add a new target to the list.
//
void
Fl_Help_View::add_target(const char *n, // I - Name of target
int yy) // I - Y position of target
{
Fl_Help_Target *temp; // New target
if (ntargets_ >= atargets_)
{
atargets_ += 16;
if (atargets_ == 16)
targets_ = (Fl_Help_Target *)malloc(sizeof(Fl_Help_Target) * atargets_);
else
targets_ = (Fl_Help_Target *)realloc(targets_, sizeof(Fl_Help_Target) * atargets_);
}
temp = targets_ + ntargets_;
temp->y = yy;
strlcpy(temp->name, n, sizeof(temp->name));
ntargets_ ++;
}
//
// 'Fl_Help_View::compare_targets()' - Compare two targets.
//
int // O - Result of comparison
Fl_Help_View::compare_targets(const Fl_Help_Target *t0, // I - First target
const Fl_Help_Target *t1) // I - Second target
{
return (strcasecmp(t0->name, t1->name));
}
//
// 'Fl_Help_View::do_align()' - Compute the alignment for a line in a block.
//
int // O - New line
Fl_Help_View::do_align(Fl_Help_Block *block, // I - Block to add to
int line, // I - Current line
int xx, // I - Current X position
int a, // I - Current alignment
int &l) // IO - Starting link
{
int offset; // Alignment offset
switch (a)
{
case RIGHT : // Right align
offset = block->w - xx;
break;
case CENTER : // Center
offset = (block->w - xx) / 2;
break;
default : // Left align
offset = 0;
break;
}
block->line[line] = block->x + offset;
if (line < 31)
line ++;
while (l < nlinks_)
{
links_[l].x += offset;
links_[l].w += offset;
l ++;
}
return (line);
}
//
// 'Fl_Help_View::draw()' - Draw the Fl_Help_View widget.
//
void
Fl_Help_View::draw()
{
int i; // Looping var
const Fl_Help_Block *block; // Pointer to current block
const char *ptr, // Pointer to text in block
*attrs; // Pointer to start of element attributes
char *s, // Pointer into buffer
buf[1024], // Text buffer
attr[1024]; // Attribute buffer
int xx, yy, ww, hh; // Current positions and sizes
int line; // Current line
unsigned char font, fsize; // Current font and size
int head, pre, // Flags for text
needspace; // Do we need whitespace?
Fl_Boxtype b = box() ? box() : FL_DOWN_BOX;
// Box to draw...
// Draw the scrollbar(s) and box first...
ww = w();
hh = h();
i = 0;
if (hscrollbar_.visible()) {
draw_child(hscrollbar_);
hh -= 17;
i ++;
}
if (scrollbar_.visible()) {
draw_child(scrollbar_);
ww -= 17;
i ++;
}
if (i == 2) {
fl_color(FL_GRAY);
fl_rectf(x() + ww, y() + hh, 17, 17);
}
draw_box(b, x(), y(), ww, hh, bgcolor_);
if (!value_)
return;
// Clip the drawing to the inside of the box...
fl_push_clip(x() + Fl::box_dx(b), y() + Fl::box_dy(b),
ww - Fl::box_dw(b), hh - Fl::box_dh(b));
fl_color(textcolor_);
// Draw all visible blocks...
for (i = 0, block = blocks_; i < nblocks_; i ++, block ++)
if ((block->y + block->h) >= topline_ && block->y < (topline_ + h()))
{
line = 0;
xx = block->line[line];
yy = block->y - topline_;
hh = 0;
pre = 0;
head = 0;
needspace = 0;
initfont(font, fsize);
for (ptr = block->start, s = buf; ptr < block->end;)
{
if ((*ptr == '<' || isspace(*ptr)) && s > buf)
{
if (!head && !pre)
{
// Check width...
*s = '\0';
s = buf;
ww = (int)fl_width(buf);
if (needspace && xx > block->x)
xx += (int)fl_width(' ');
if ((xx + ww) > block->w)
{
if (line < 31)
line ++;
xx = block->line[line];
yy += hh;
hh = 0;
}
fl_draw(buf, xx + x() - leftline_, yy + y());
xx += ww;
if ((fsize + 2) > hh)
hh = fsize + 2;
needspace = 0;
}
else if (pre)
{
while (isspace(*ptr))
{
if (*ptr == '\n')
{
*s = '\0';
s = buf;
fl_draw(buf, xx + x() - leftline_, yy + y());
if (line < 31)
line ++;
xx = block->line[line];
yy += hh;
hh = fsize + 2;
}
else if (*ptr == '\t')
{
// Do tabs every 8 columns...
while (((s - buf) & 7))
*s++ = ' ';
}
else
*s++ = ' ';
if ((fsize + 2) > hh)
hh = fsize + 2;
ptr ++;
}
if (s > buf)
{
*s = '\0';
s = buf;
fl_draw(buf, xx + x() - leftline_, yy + y());
xx += (int)fl_width(buf);
}
needspace = 0;
}
else
{
s = buf;
while (isspace(*ptr))
ptr ++;
}
}
if (*ptr == '<')
{
ptr ++;
if (strncmp(ptr, "!--", 3) == 0)
{
// Comment...
ptr += 3;
if ((ptr = strstr(ptr, "-->")) != NULL)
{
ptr += 3;
continue;
}
else
break;
}
while (*ptr && *ptr != '>' && !isspace(*ptr))
if (s < (buf + sizeof(buf) - 1))
*s++ = *ptr++;
else
ptr ++;
*s = '\0';
s = buf;
attrs = ptr;
while (*ptr && *ptr != '>')
ptr ++;
if (*ptr == '>')
ptr ++;
if (strcasecmp(buf, "HEAD") == 0)
head = 1;
else if (strcasecmp(buf, "BR") == 0)
{
if (line < 31)
line ++;
xx = block->line[line];
yy += hh;
hh = 0;
}
else if (strcasecmp(buf, "HR") == 0)
{
fl_line(block->x + x(), yy + y(), block->w + x(),
yy + y());
if (line < 31)
line ++;
xx = block->line[line];
yy += 2 * hh;
hh = 0;
}
else if (strcasecmp(buf, "CENTER") == 0 ||
strcasecmp(buf, "P") == 0 ||
strcasecmp(buf, "H1") == 0 ||
strcasecmp(buf, "H2") == 0 ||
strcasecmp(buf, "H3") == 0 ||
strcasecmp(buf, "H4") == 0 ||
strcasecmp(buf, "H5") == 0 ||
strcasecmp(buf, "H6") == 0 ||
strcasecmp(buf, "UL") == 0 ||
strcasecmp(buf, "OL") == 0 ||
strcasecmp(buf, "DL") == 0 ||
strcasecmp(buf, "LI") == 0 ||
strcasecmp(buf, "DD") == 0 ||
strcasecmp(buf, "DT") == 0 ||
strcasecmp(buf, "PRE") == 0)
{
if (tolower(buf[0]) == 'h')
{
font = FL_HELVETICA_BOLD;
fsize = (uchar)(textsize_ + '7' - buf[1]);
}
else if (strcasecmp(buf, "DT") == 0)
{
font = (uchar)(textfont_ | FL_ITALIC);
fsize = textsize_;
}
else if (strcasecmp(buf, "PRE") == 0)
{
font = FL_COURIER;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?