dslinux/user/pixil/libs/flek/src FDate.cxx FFile.cxx FImage.cxx FJPEG.cxx FPNM.cxx FSGI.cxx FSocket.cxx FSocket_Posix.H FSocket_Posix.cxx FVector.cxx Fl_App_Window.cxx Fl_Better_Window.cxx Fl_Calendar.cxx Fl_Dockable_Window.cxx Fl_Stock.cxx Fl_Time.cxx Fl_Toggle_Node.cxx Fl_Toggle_Node_Base.cxx Fl_Toggle_Tree.cxx Fl_Toggle_Tree_Base.cxx Flv_CStyle.cxx Flv_List.cxx Flv_Style.cxx Flv_Table.cxx Flve_Check_Button.cxx Flve_Combo.cxx Flve_Input.cxx Makefile makedepend
amadeus
dslinux_amadeus at user.in-berlin.de
Tue Oct 3 13:24:53 CEST 2006
Update of /cvsroot/dslinux/dslinux/user/pixil/libs/flek/src
In directory antilope:/tmp/cvs-serv11916/libs/flek/src
Added Files:
FDate.cxx FFile.cxx FImage.cxx FJPEG.cxx FPNM.cxx FSGI.cxx
FSocket.cxx FSocket_Posix.H FSocket_Posix.cxx FVector.cxx
Fl_App_Window.cxx Fl_Better_Window.cxx Fl_Calendar.cxx
Fl_Dockable_Window.cxx Fl_Stock.cxx Fl_Time.cxx
Fl_Toggle_Node.cxx Fl_Toggle_Node_Base.cxx Fl_Toggle_Tree.cxx
Fl_Toggle_Tree_Base.cxx Flv_CStyle.cxx Flv_List.cxx
Flv_Style.cxx Flv_Table.cxx Flve_Check_Button.cxx
Flve_Combo.cxx Flve_Input.cxx Makefile makedepend
Log Message:
adding pristine copy of pixil to HEAD so I can branch from it
--- NEW FILE: Flv_Table.cxx ---
// ======================================================================
// File: Flv_Table.cxx - Flv_Table implementation
// Program: Flv_Table - FLTK Table Widget
// Version: 0.1.0
// Started: 11/21/99
//
// Copyright (C) 1999 Laurence Charlton
//
// Description:
// Flv_Table implements a table/grid. No data is stored
// in the widget. Supports headers/footers for rows and columns,
// natively supports a single row height and column width per table.
// Row and column grids can be turned on and off. Supports no scroll
// bars as well as horizontal/vertical automatic or always on scroll bars.
// Also support cell selection and row selection modes. In row selection
// mode it acts like a pumped-up list widget.
// Uses absolute cell references.
//
// row -1 is defined as the row header
[...1523 lines suppressed...]
veditor->show();
Fl::focus(veditor);
//veditor->take_focus();
veditor->handle(FL_FOCUS);
veditor->damage(FL_DAMAGE_ALL);
veditor->redraw();
}
}
}
if (!veditor) {
vediting = false;
edit_row = -1;
edit_col = -1;
}
if (!veditor && wfocused) {
Fl::focus(this);
// take_focus();
handle(FL_FOCUS);
}
}
--- NEW FILE: Flv_CStyle.cxx ---
// ======================================================================
// File: Flv_CStyle.cxx - Flv_CStyle implementation
// Program: Flv_Style - FLTK Virtual List/Table Styles Widget
// Version: 0.1.0
// Started: 11/21/99
//
// Copyright (C) 1999 Laurence Charlton
//
// Description:
// The complex styles will be used in the complex table. Should be basically
// the same as Flv_Style with x,y positional data.
// ======================================================================
#include <Flek/Flv_CStyle.H>
#include <stdio.h>
#ifdef WIN32
#include <mem.h>
#else
#include <memory.h>
#endif
#define ADDSIZE 10
// **********************************************************************
// Routines for Flv_CStyle
//
// Defines the additional properties for a complex layout table.
// A complex layout table allows the placement of cells (columns) within
// a row. The overall layout is used to determine minimum row heights/
// widths, etc.
// **********************************************************************
Flv_CStyle::Flv_CStyle():
Flv_Style()
{
vx = 0;
vy = 0;
width(0);
height(0);
}
// Set x
int
Flv_CStyle::x(int n)
{
if (n < 0)
n = 0;
return (vx = n);
}
// Set y
int
Flv_CStyle::y(int n)
{
if (n < 0)
n = 0;
return (vy = n);
}
const Flv_CStyle &
Flv_CStyle::operator=(const Flv_CStyle & n)
{
Flv_Style::operator=(n);
vx = n.vx;
vy = n.vy;
return *this;
}
--- NEW FILE: Fl_Toggle_Node.cxx ---
#include <Flek/Fl_Toggle_Node.H>
--- NEW FILE: Fl_App_Window.cxx ---
#include <stdio.h>
#include <stdlib.h>
#include <FL/Fl.H>
#include <FL/Fl_Window.H> // needed by FLTK2
#include <FL/x.H>
#include <FL/fl_draw.H>
#include <Flek/Fl_App_Window.H>
// #define FL_APP_WINDOW_DEBUG
Fl_App_Window::Fl_App_Window(int x, int y, int w, int h, const char *l):
Fl_Window(x, y, w, h, l)
{
create_app_window(w, h, l);
}
Fl_App_Window::Fl_App_Window(int w, int h, const char *l):
Fl_Window(w, h, l)
{
create_app_window(w, h, l);
}
Fl_App_Window::~Fl_App_Window()
{
free(dockable_windows);
}
void
Fl_App_Window::create_app_window(int w, int h, const char *l)
{
#ifdef FL_APP_WINDOW_DEBUG
printf("Fl_App_Window::create_app_window win %p %dx%d\n", this, w, h);
#endif
// Make room for the list of dockable windows.
dockable_windows_capacity = 4;
dockable_windows =
(Fl_Dockable_Window **) malloc(sizeof(Fl_Dockable_Window *) *
dockable_windows_capacity);
dockable_windows_size = 0;
// Contents window and docked windows will complete obscure the
// toplevel window, so set it to no box.
Fl_Window::box(FL_NO_BOX);
// Create the pack that holds the contents window and docked windows.
// Contents window and docked windows will complete obscure the
// the pack area, so set it to no box.
_pack = new Fl_Pack(0, 0, w, h, "Fl_App_Window::pack");
_pack->type(Fl_Pack::VERTICAL);
_pack->box(FL_NO_BOX);
// Create the contents window.
_contents = new Fl_Window(0, 0, w, h, "Fl_App_Window::contents");
// Contents area is the resizable for the pack group.
// As dockables get added and removed, contents resizes.
// Now, wouldn't that be just dandy?
// However, Fl_Pack apparently doesn't work that way,
// at least AFAICT at this point.
// _pack->resizable(_contents);
// Pack group is the resizable for the window.
// Maybe this isn't so cool, as it makes the window resizable,
// which maybe isn't what everyone wants.
// Code in resize below emulates this instead.
// resizable(_pack);
#ifdef FL_APP_WINDOW_DEBUG
// Turn on borders so we can see what is what.
Fl_Window::box(FL_BORDER_BOX);
Fl_Window::color(FL_WHITE);
_pack->box(FL_DOWN_BOX);
_contents->box(FL_UP_BOX);
_contents->color(FL_LIGHT3);
#endif
}
int
Fl_App_Window::handle(int event)
{
if (event == FL_UNDOCK) {
#ifdef FL_APP_WINDOW_DEBUG
printf("Fl_App_Window::handle - undock\n");
#endif
repack();
return 1;
}
if (event == FL_DOCK) {
// Isn't it in this windows list of dockable widows?
if (!may_dock(Fl_Dockable_Window::current))
// Don't dock it.
return 1;
int dx = Fl::event_x_root();
int dy = Fl::event_y_root();
int ex = x_root();
int ey = y_root();
// Check to see if we can dock along any of
// the pack boundaries.
// This code should probably go into Pack_2's handle:
// Fl_Widget*const* a = _pack->array();
for (int i = 0; i <= _pack->children(); i++) {
int cY;
if (i == _pack->children())
cY = h();
else {
// Fl_Widget* o = *a++;
Fl_Widget *o = _pack->child(i);
cY = o->y();
}
if ((dx < (ex + FL_DOCK_DELTA + w())) // xmax
&& (dx > (ex - FL_DOCK_DELTA)) // xmin
&& (dy < (ey + FL_DOCK_DELTA + cY)) // ymax
&& (dy > (ey - FL_DOCK_DELTA + cY))) // ymin
{
#ifdef FL_APP_WINDOW_DEBUG
printf("Fl_App_Window::handle - dock\n");
#endif
add_dockable(Fl_Dockable_Window::current, i);
return 1;
}
}
return 0;
}
return Fl_Window::handle(event);
}
void
Fl_App_Window::add(Fl_Widget * w)
{
// Anything added to Fl_App should actually get
// added to the contents group.
_contents->add(w);
}
bool
Fl_App_Window::may_dock(Fl_Dockable_Window * W)
{
// Is the dockable window in the dockable_windows list?
for (int i = 0; i < dockable_windows_size; i++)
if (dockable_windows[i] == W)
return true;
return false;
}
void
Fl_App_Window::accept_dockable(Fl_Dockable_Window * W)
{
// Does this dockable window already have permission to dock?
// In other words, is it already in the list?
if (may_dock(W))
// Already in the list, don't add it again.
return;
// Is there room left in the list?
if (dockable_windows_size >= dockable_windows_capacity) {
// Out of space. That's okay. We'll make more.
dockable_windows_capacity *= 2;
dockable_windows = (Fl_Dockable_Window **) realloc(dockable_windows,
sizeof
(Fl_Dockable_Window
*) *
dockable_windows_capacity);
}
// Add it to the list.
dockable_windows[dockable_windows_size++] = W;
}
void
Fl_App_Window::add_dockable(Fl_Dockable_Window * W, int pos)
{
// Add the dockable window to this window's list of dockable windows.
accept_dockable(W);
// Dock the dockable window on this window.
Fl_Dockable_Window::current = W;
if (W->shown())
W->hide();
_pack->insert(*W, pos);
repack();
W->docked(1);
if (shown())
W->show();
}
void
Fl_App_Window::show()
{
#ifdef FL_APP_WINDOW_DEBUG
printf("Fl_App_Window::show() win %p\n", this);
#endif
// Show ourself.
Fl_Window::show();
// Show our dockable windows.
for (int i = 0; i < dockable_windows_size; i++)
dockable_windows[i]->show();
}
void
Fl_App_Window::hide()
{
for (int i = 0; i < dockable_windows_size; i++)
dockable_windows[i]->hide();
Fl_Window::hide();
}
void
Fl_App_Window::flush()
{
#ifdef FL_APP_WINDOW_DEBUG
printf("Fl_App_Window::flush() win %p\n", this);
#endif
make_current();
Fl_X *i = Fl_X::i(this);
fl_clip_region(i->region);
i->region = 0;
// Based on my testing, this draw() is required. bdl
draw();
}
void
Fl_App_Window::repack()
{
// Figure how much space everything but the contents takes up.
int children_w = 0;
int children_h = 0;
for (int i = 0; i < _pack->children(); i++) {
if (_pack->child(i) == _contents)
continue;
// HACK: don't consider width since packing is vertical.
// children_w += _pack->child(i)->w();
children_h += _pack->child(i)->h();
#ifdef FL_APP_WINDOW_DEBUG
printf("Fl_App_Window::repack win %p child %d size %dx%d\n",
this, i, _pack->child(i)->w(), _pack->child(i)->h());
#endif
}
// Make contents fill all remaining space.
_contents->resize(0, 0, w() - children_w, h() - children_h);
// Resize the pack to fill the window.
_pack->resize(0, 0, w(), h());
#ifdef FL_APP_WINDOW_DEBUG
printf("Fl_App_Window::repack win %p pack %dx%d contents %dx%d\n",
this, w(), h(), w() - children_w, h() - children_h);
#endif
}
void
Fl_App_Window::resize(int X, int Y, int W, int H)
{
#ifdef FL_APP_WINDOW_DEBUG
printf("Fl_App_Window::resize() win %p %dx%d+%d+%d\n", this, W, H, X, Y);
#endif
Fl_Widget::resize(X, Y, W, H);
repack();
}
#if FL_MAJOR_VERSION == 2
void
Fl_App_Window::layout()
{
printf("layout called\n");
printf("1AppWin- x:%d y:%d w:%d h:%d\n", x(), y(), w(), h());
printf("1pack- x:%d y:%d w:%d h:%d\n", _pack->x(), _pack->y(), _pack->w(),
_pack->h());
printf("1contents- x:%d y:%d w:%d h:%d\n", _contents->x(), _contents->y(),
_contents->w(), _contents->h());
repack();
printf("2AppWin- x:%d y:%d w:%d h:%d\n", x(), y(), w(), h());
printf("2pack- x:%d y:%d w:%d h:%d\n", _pack->x(), _pack->y(), _pack->w(),
_pack->h());
printf("2contents- x:%d y:%d w:%d h:%d\n", _contents->x(), _contents->y(),
_contents->w(), _contents->h());
}
#endif
--- NEW FILE: FFile.cxx ---
#include <Flek/FFile.H>
#include <FL/filename.H>
#include <string.h>
#include <stdlib.h>
#include <unistd.h> // realpath
#include <stdio.h> // tmpnam
#include <sys/stat.h>
void
lo_to_hi(ulong * buffer, int len)
{
// return;
char *cbuffer = (char *) buffer;
register ulong value;
for (register int i = 0; i < len; i++, cbuffer += 4) {
value = buffer[i];
cbuffer[0] = ((value >> 24) & 0xff);
cbuffer[1] = ((value >> 16) & 0xff);
cbuffer[2] = ((value >> 8) & 0xff);
cbuffer[3] = ((value & 0xff));
}
}
void
FFile::open(char *filename, FFileMode mode)
{
char *m = 0;
switch (mode) {
case FFileNull:
m = "";
break;
case FFileRead:
m = "r";
break;
case FFileReadPlus:
m = "r+";
break;
case FFileWrite:
m = "w";
break;
case FFileWritePlus:
m = "w+";
break;
case FFileAppend:
m = "a";
break;
case FFileAppendPlus:
m = "a+";
break;
}
Fd = fopen(filename, m);
if (!Fd)
Error = 1;
else
Error = 0;
}
--- NEW FILE: FSocket.cxx ---
#ifdef WIN32
#include "FSocket_Win32.cxx"
#else
#include "FSocket_Posix.cxx"
#endif
--- NEW FILE: Makefile ---
### Flek Makefile
# This makefile has been changed to adjust to the Pixil build environement.
# Check the readme for details on the changes that we have made
LIB_STATIC=libflek.a
LIB_SHARED=libflek.so
CPPFILES= FDate.cxx FSocket.cxx FFile.cxx FVector.cxx \
FImage.cxx FSGI.cxx FPNM.cxx Fl_App_Window.cxx \
Fl_Better_Window.cxx Fl_Calendar.cxx Fl_Dockable_Window.cxx \
Fl_Stock.cxx Fl_Toggle_Node_Base.cxx Fl_Toggle_Node.cxx \
Fl_Toggle_Tree_Base.cxx Fl_Toggle_Tree.cxx Flv_CStyle.cxx \
Flv_Style.cxx Flv_List.cxx Flv_Table.cxx Flve_Check_Button.cxx \
Flve_Input.cxx Flve_Combo.cxx Fl_Time.cxx
OBJS = $(CPPFILES:.cxx=.o)
CFLAGS ?=
CFLAGS += -DPIXIL
ifeq ($(CROSS_COMPILE),y)
CFLAGS += -fpermissive
endif
INCLUDES=-I. -I../
include $(BASE_DIR)/Rules.make
--- NEW FILE: FImage.cxx ---
#include <Flek/math.H>
#include <Flek/FImage.H>
#include <string.h>
//#include <iostream.h>
//#include <fstream.h>
typedef unsigned long ulong;
typedef unsigned long *ulongPtr;
typedef unsigned short ushort;
typedef unsigned short *ushortPtr;
typedef unsigned char uchar;
typedef unsigned char *ucharPtr;
#define INT_MULT(a,b,t) ((t) = (a) * (b) + 0x80, ((((t) >> 8) + (t)) >> 8))
#define INT_BLEND(a,b,alpha,tmp) (INT_MULT((a)-(b), alpha, tmp) + (b))
FImage::FImage()
{
Data = 0;
W = 0;
H = 0;
Channels = 4;
}
FImage::FImage(int w, int h, int channels)
{
W = w;
H = h;
Channels = channels;
Data = new uchar[W * H * Channels];
}
FImage::FImage(FImage * src)
{
W = src->width();
H = src->height();
Channels = src->channels();
Data = new uchar[W * H * Channels];
memcpy((void *) Data, (void *) *(src->begin()), W * H * Channels);
}
FImage::~FImage()
{
if (Data)
delete[]Data;
}
void
FImage::channels(int dest_channels)
{
uchar *src = Data;
int src_channels = Channels;
int k_max = min(src_channels, dest_channels);
uchar *r = new uchar[W * H * dest_channels];
uchar *dest = r;
unsigned char *end = dest + dest_channels * W * H;
for (; dest < end; dest += dest_channels, src += src_channels) {
for (int k = 0; k < k_max; k++)
dest[k] = src[k];
}
if ((Channels == 3) && (dest_channels == 4)) {
dest = r;
for (; dest < end; dest += dest_channels)
dest[3] = 255;
}
delete[]Data;
Data = r;
Channels = dest_channels;
}
void
FImage::flip_vertical()
{
uchar row[Channels * W];
for (int i = 0; i < H / 2; i++) {
memcpy(row, &Data[Channels * W * i], Channels * W);
memcpy(&Data[Channels * W * i], &Data[Channels * W * (H - i - 1)],
Channels * W);
memcpy(&Data[Channels * W * (H - i - 1)], row, Channels * W);
}
}
void
FImage::clear(uchar r, uchar g, uchar b, uchar a)
{
int i;
if (Channels >= 4)
for (i = 0; i < Channels * W * H; i += Channels) {
Data[i] = r;
Data[i + 1] = g;
Data[i + 2] = b;
Data[i + 3] = a;
} else if (Channels == 3) {
for (i = 0; i < Channels * W * H; i += Channels) {
Data[i] = r;
Data[i + 1] = g;
Data[i + 2] = b;
}
} else if (Channels == 2) {
for (i = 0; i < Channels * W * H; i += Channels) {
Data[i] = r;
Data[i + 1] = g;
}
} else if (Channels == 1) {
for (i = 0; i < Channels * W * H; i += Channels)
Data[i] = r;
}
}
FImage *
FImage::scale(int x, int y)
{
FImage *r = new FImage(x, y, Channels);
uchar *dest = *(r->begin());
for (int i = 0; i < y; i++)
for (int j = 0; j < x; j++)
for (int k = 0; k < Channels; k++, dest++) {
float tx = ((float) j / (float) x);
float ty = ((float) i / (float) y);
int ix = (int) (tx * W);
int iy = (int) (ty * H);
dest[0] = Data[iy * Channels * W + ix * Channels + k];
}
return r;
}
/*
* All operations are done "in-place" on image A and do not return a
* new image for efficiency. If you want a new image, copy image A
* and then work on the copy.
*/
void
composite(unsigned char *dest,
const unsigned char *src,
int opacity, int length, int dest_channels, int src_channels)
{
int a;
register long t1;
unsigned char *end = dest + dest_channels * length;
for (; dest < end; dest += dest_channels, src += src_channels) {
if (src_channels > 3) {
a = INT_MULT(src[3], opacity, t1);
// b + (1-b)*a
if (dest_channels > 3)
dest[3] = min(src[3] + INT_MULT(255 - src[3], dest[3], t1), 255); //INT_MULT(dest[3], a, t1); //dest[3] = 255;
} else
a = opacity;
dest[0] = INT_BLEND(src[0], dest[0], a, t1);
dest[1] = INT_BLEND(src[1], dest[1], a, t1);
dest[2] = INT_BLEND(src[2], dest[2], a, t1);
}
}
FImage *
composite(FImage * A, FImage * B, int xo, int yo, float value)
{
int xi = max(xo, 0);
int yi = max(yo, 0);
int xf = min(max(xo + B->width(), 0), A->width());
int yf = min(max(yo + B->height(), 0), A->height());
for (int row = yi; row < yf; row++)
composite(*(*A) (xi, row), *(*B) (xi - xo, row - yo),
(int) (value * 255), xf - xi, A->channels(), B->channels());
return A;
}
void
add(unsigned char *dest,
const unsigned char *src,
int opacity, int length, int dest_channels, int src_channels)
{
int a;
register long t1;
unsigned char *end = dest + dest_channels * length;
for (; dest < end; dest += dest_channels, src += src_channels) {
if (src_channels > 3) {
a = INT_MULT(src[3], opacity, t1);
if (dest_channels > 3)
dest[3] = 255;
} else
a = opacity;
dest[0] =
INT_BLEND(clamp_upper(src[0] + dest[0], 255), dest[0], a, t1);
dest[1] =
INT_BLEND(clamp_upper(src[1] + dest[1], 255), dest[1], a, t1);
dest[2] =
INT_BLEND(clamp_upper(src[2] + dest[2], 255), dest[2], a, t1);
}
}
FImage *
add(FImage * A, FImage * B, int xo, int yo, float value)
{
int xi = max(xo, 0);
int yi = max(yo, 0);
int xf = min(max(xo + B->width(), 0), A->width());
int yf = min(max(yo + B->height(), 0), A->height());
for (int row = yi; row < yf; row++)
add(*(*A) (xi, row), *(*B) (xi - xo, row - yo), (int) (value * 255),
xf - xi, A->channels(), B->channels());
return A;
}
void
subtract(unsigned char *dest,
const unsigned char *src,
int opacity, int length, int dest_channels, int src_channels)
{
int a;
register long t1;
unsigned char *end = dest + dest_channels * length;
for (; dest < end; dest += dest_channels, src += src_channels) {
if (src_channels > 3) {
a = INT_MULT(src[3], opacity, t1);
if (dest_channels > 3)
dest[3] = 255;
} else
a = opacity;
dest[0] = INT_BLEND(clamp_lower(dest[0] - src[0], 0), dest[0], a, t1);
dest[1] = INT_BLEND(clamp_lower(dest[1] - src[1], 0), dest[1], a, t1);
dest[2] = INT_BLEND(clamp_lower(dest[2] - src[2], 0), dest[2], a, t1);
}
}
FImage *
subtract(FImage * A, FImage * B, int xo, int yo, float value)
{
int xi = max(xo, 0);
int yi = max(yo, 0);
int xf = min(max(xo + B->width(), 0), A->width());
int yf = min(max(yo + B->height(), 0), A->height());
for (int row = yi; row < yf; row++)
subtract(*(*A) (xi, row), *(*B) (xi - xo, row - yo),
(int) (value * 255), xf - xi, A->channels(), B->channels());
return A;
}
void
difference(unsigned char *dest,
const unsigned char *src,
int opacity, int length, int dest_channels, int src_channels)
{
int a;
register long t1;
unsigned char *end = dest + dest_channels * length;
for (; dest < end; dest += dest_channels, src += src_channels) {
if (src_channels > 3) {
a = INT_MULT(src[3], opacity, t1);
if (dest_channels > 3)
dest[3] = 255;
} else
a = opacity;
dest[0] =
INT_BLEND(max(dest[0], src[0]) - min(dest[0], src[0]), dest[0], a,
t1);
dest[1] =
INT_BLEND(max(dest[1], src[1]) - min(dest[1], src[1]), dest[1], a,
t1);
dest[2] =
INT_BLEND(max(dest[2], src[2]) - min(dest[2], src[2]), dest[2], a,
t1);
}
}
FImage *
difference(FImage * A, FImage * B, int xo, int yo, float value)
{
int xi = max(xo, 0);
int yi = max(yo, 0);
int xf = min(max(xo + B->width(), 0), A->width());
int yf = min(max(yo + B->height(), 0), A->height());
for (int row = yi; row < yf; row++)
difference(*(*A) (xi, row), *(*B) (xi - xo, row - yo),
(int) (value * 255), xf - xi, A->channels(),
B->channels());
return A;
}
void
lighten_only(unsigned char *dest,
const unsigned char *src,
int opacity, int length, int dest_channels, int src_channels)
{
int a;
register long t1;
unsigned char *end = dest + dest_channels * length;
for (; dest < end; dest += dest_channels, src += src_channels) {
if (src_channels > 3) {
a = INT_MULT(src[3], opacity, t1);
if (dest_channels > 3)
dest[3] = 255;
} else
a = opacity;
dest[0] = INT_BLEND(max(dest[0], src[0]), dest[0], a, t1);
dest[1] = INT_BLEND(max(dest[1], src[1]), dest[1], a, t1);
dest[2] = INT_BLEND(max(dest[2], src[2]), dest[2], a, t1);
}
}
FImage *
lighten_only(FImage * A, FImage * B, int xo, int yo, float value)
{
int xi = max(xo, 0);
int yi = max(yo, 0);
int xf = min(max(xo + B->width(), 0), A->width());
int yf = min(max(yo + B->height(), 0), A->height());
for (int row = yi; row < yf; row++)
lighten_only(*(*A) (xi, row), *(*B) (xi - xo, row - yo),
(int) (value * 255), xf - xi, A->channels(),
B->channels());
return A;
}
void
darken_only(unsigned char *dest,
const unsigned char *src,
int opacity, int length, int dest_channels, int src_channels)
{
int a;
register long t1;
unsigned char *end = dest + dest_channels * length;
for (; dest < end; dest += dest_channels, src += src_channels) {
if (src_channels > 3) {
a = INT_MULT(src[3], opacity, t1);
if (dest_channels > 3)
dest[3] = 255;
} else
a = opacity;
dest[0] = INT_BLEND(min(dest[0], src[0]), dest[0], a, t1);
dest[1] = INT_BLEND(min(dest[1], src[1]), dest[1], a, t1);
dest[2] = INT_BLEND(min(dest[2], src[2]), dest[2], a, t1);
}
}
FImage *
darken_only(FImage * A, FImage * B, int xo, int yo, float value)
{
int xi = max(xo, 0);
int yi = max(yo, 0);
int xf = min(max(xo + B->width(), 0), A->width());
int yf = min(max(yo + B->height(), 0), A->height());
for (int row = yi; row < yf; row++)
darken_only(*(*A) (xi, row), *(*B) (xi - xo, row - yo),
(int) (value * 255), xf - xi, A->channels(),
B->channels());
return A;
}
void
divide(unsigned char *dest,
const unsigned char *src,
int opacity, int length, int dest_channels, int src_channels)
{
int a;
register long t1;
unsigned char *end = dest + dest_channels * length;
for (; dest < end; dest += dest_channels, src += src_channels) {
if (src_channels > 3) {
a = INT_MULT(src[3], opacity, t1);
if (dest_channels > 3)
dest[3] = min(dest[3], src[3]);
} else
a = opacity;
dest[0] =
INT_BLEND(min((dest[0] * 256) / (1 + src[0]), 255), dest[0], a,
t1);
dest[1] =
INT_BLEND(min((dest[1] * 256) / (1 + src[1]), 255), dest[1], a,
t1);
dest[2] =
INT_BLEND(min((dest[2] * 256) / (1 + src[2]), 255), dest[2], a,
t1);
}
}
FImage *
divide(FImage * A, FImage * B, int xo, int yo, float value)
{
int xi = max(xo, 0);
int yi = max(yo, 0);
int xf = min(max(xo + B->width(), 0), A->width());
int yf = min(max(yo + B->height(), 0), A->height());
for (int row = yi; row < yf; row++)
divide(*(*A) (xi, row), *(*B) (xi - xo, row - yo),
(int) (value * 255), xf - xi, A->channels(), B->channels());
return A;
}
void
multiply(unsigned char *dest,
const unsigned char *src,
int opacity, int length, int dest_channels, int src_channels)
{
int a;
register long t1;
unsigned char *end = dest + dest_channels * length;
for (; dest < end; dest += dest_channels, src += src_channels) {
if (src_channels > 3) {
a = INT_MULT(src[3], opacity, t1);
if (dest_channels > 3)
dest[3] = min(dest[3], src[3]);
} else
a = opacity;
dest[0] = INT_BLEND(INT_MULT(src[0], dest[0], t1), dest[0], a, t1);
dest[1] = INT_BLEND(INT_MULT(src[1], dest[1], t1), dest[1], a, t1);
dest[2] = INT_BLEND(INT_MULT(src[2], dest[2], t1), dest[2], a, t1);
}
}
FImage *
multiply(FImage * A, FImage * B, int xo, int yo, float value)
{
int xi = max(xo, 0);
int yi = max(yo, 0);
int xf = min(max(xo + B->width(), 0), A->width());
int yf = min(max(yo + B->height(), 0), A->height());
for (int row = yi; row < yf; row++)
multiply(*(*A) (xi, row), *(*B) (xi - xo, row - yo),
(int) (value * 255), xf - xi, A->channels(), B->channels());
return A;
}
void
screen(unsigned char *dest,
const unsigned char *src,
int opacity, int length, int dest_channels, int src_channels)
{
int a;
register long t1;
unsigned char *end = dest + dest_channels * length;
for (; dest < end; dest += dest_channels, src += src_channels) {
if (src_channels > 3) {
a = INT_MULT(src[3], opacity, t1);
if (dest_channels > 3)
dest[3] = min(dest[3], src[3]);
} else
a = opacity;
dest[0] =
INT_BLEND(255 - INT_MULT(255 - src[0], 255 - dest[0], t1),
dest[0], a, t1);
dest[1] =
INT_BLEND(255 - INT_MULT(255 - src[1], 255 - dest[1], t1),
dest[1], a, t1);
dest[2] =
INT_BLEND(255 - INT_MULT(255 - src[2], 255 - dest[2], t1),
dest[2], a, t1);
}
}
FImage *
screen(FImage * A, FImage * B, int xo, int yo, float value)
{
int xi = max(xo, 0);
int yi = max(yo, 0);
int xf = min(max(xo + B->width(), 0), A->width());
int yf = min(max(yo + B->height(), 0), A->height());
for (int row = yi; row < yf; row++)
screen(*(*A) (xi, row), *(*B) (xi - xo, row - yo),
(int) (value * 255), xf - xi, A->channels(), B->channels());
return A;
}
void
overlay(unsigned char *dest,
const unsigned char *src,
int opacity, int length, int dest_channels, int src_channels)
{
int a;
register long t1;
unsigned char *end = dest + dest_channels * length;
for (; dest < end; dest += dest_channels, src += src_channels) {
if (src_channels > 3) {
a = INT_MULT(src[3], opacity, t1);
if (dest_channels > 3)
dest[3] = min(dest[3], src[3]);
} else
a = opacity;
dest[0] =
INT_BLEND(INT_MULT
(dest[0],
dest[0] + INT_MULT(2 * src[0], 255 - dest[0], t1), t1),
dest[0], a, t1);
dest[1] =
INT_BLEND(INT_MULT
(dest[1],
dest[0] + INT_MULT(2 * src[1], 255 - dest[1], t1), t1),
dest[1], a, t1);
dest[2] =
INT_BLEND(INT_MULT
(dest[2],
dest[0] + INT_MULT(2 * src[2], 255 - dest[2], t1), t1),
dest[2], a, t1);
}
}
FImage *
overlay(FImage * A, FImage * B, int xo, int yo, float value)
{
int xi = max(xo, 0);
int yi = max(yo, 0);
int xf = min(max(xo + B->width(), 0), A->width());
int yf = min(max(yo + B->height(), 0), A->height());
for (int row = yi; row < yf; row++)
overlay(*(*A) (xi, row), *(*B) (xi - xo, row - yo),
(int) (value * 255), xf - xi, A->channels(), B->channels());
return A;
}
--- NEW FILE: Flve_Check_Button.cxx ---
// ======================================================================
// File: Flve_Input.cxx - Flve_Input implementation
// Library: flvw - FLTK Virtual widget library
// Version: 0.1.0
// Started: 01/12/2000
//
// Copyright (C) 1999 Laurence Charlton
//
// Description:
// Flve_Input implements cell text editing for a list/table.
// ======================================================================
#include <FL/Fl.H>
#include <FL/fl_draw.H>
#include <Flek/Flve_Check_Button.H>
int
Flve_Check_Button::handle(int event)
{
int stat;
stat = Fl_Check_Button::handle(event);
if (!stat) {
switch (event) {
case FL_FOCUS:
case FL_UNFOCUS:
return 1;
case FL_KEYBOARD:
switch (Fl::event_key()) {
case ' ':
value(!value());
redraw();
return 1;
}
break;
}
if (owner && event == FL_KEYBOARD)
if (owner->handle(FL_SHORTCUT))
return 1;
}
return stat;
}
void
draw_flve_check_button(int X, int Y, int W, int H, Flve_Check_Button * b,
char *v)
{
int x, y, w, h;
w = W;
h = H;
if (H < W)
w = h;
else
h = w;
x = X; // + (W-w)/2;
y = Y; // + (H-h)/2;
x++;
y++;
w -= 2;
h -= 2;
fl_color(b ? b->color() : (Fl_Color) (FL_GRAY_RAMP + 17));
fl_rectf(X, Y, W, H);
if (b) {
#if FL_MAJOR_VERSION == 1
if (*v == '1')
fl_draw_box(b->down_box(), x, y, w, h, b->selection_color());
else
fl_draw_box(b->down_box(), x, y, w, h, b->color());
#endif
} else {
if (*v == '1')
fl_draw_box(FL_THIN_DOWN_BOX, x, y, w, h, FL_RED);
else
fl_draw_box(FL_THIN_DOWN_BOX, x, y, w, h,
(Fl_Color) (FL_GRAY_RAMP + 17));
}
}
--- NEW FILE: Fl_Time.cxx ---
// Fl_Time.cxx
// Source file for the time widget class
//
// Copyright (C) 2000 Softfield Research Ltd.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <Flek/Fl_Time.H>
Fl_Time::Fl_Time(int x, int y, int w, int h, char *l):
Fl_Group(x, y, w, h, l)
{
int button_width = (int) (w / 7);
input_time = new Fl_Input(x, y, w - button_width * 4, h, 0);
input_time->callback(input_changed_cb, this);
input_time->when(FL_WHEN_CHANGED);
input_time->textsize(10);
button_decrease_hour =
new Fl_Repeat_Button(x + w - 4 * button_width, y, button_width, h,
"H-");
button_decrease_hour->callback(button_cb, this);
button_decrease_hour->labelsize(10);
button_increase_hour =
new Fl_Repeat_Button(x + w - 3 * button_width, y, button_width, h,
"H+");
button_increase_hour->callback(button_cb, this);
button_increase_hour->labelsize(10);
button_decrease_minute =
new Fl_Repeat_Button(x + w - 2 * button_width, y, button_width, h,
"M-");
button_decrease_minute->callback(button_cb, this);
button_decrease_minute->labelsize(10);
button_increase_minute =
new Fl_Repeat_Button(x + w - button_width, y, button_width, h, "M+");
button_increase_minute->callback(button_cb, this);
button_increase_minute->labelsize(10);
end();
type(FL_TIME_12HOUR);
current_time();
}
void
Fl_Time::current_time()
{
struct tm *display_time_tm;
gettimeofday(¤t_tv, 0);
display_tv.tv_sec = current_tv.tv_sec;
display_tv.tv_usec = current_tv.tv_usec;
display_time_tm = localtime(¤t_tv.tv_sec);
if (type() == FL_TIME_24HOUR)
strftime(time_string, 19, "%2H:%2M", display_time_tm);
else
strftime(time_string, 19, "%2I:%2M %p", display_time_tm);
input_time->value(time_string);
}
void
Fl_Time::refresh()
{
long different;
struct tm *display_time_tm;
if (valid()) {
different = -display_tv.tv_sec + current_tv.tv_sec;
gettimeofday(¤t_tv, 0);
display_tv.tv_sec = current_tv.tv_sec - different;
display_time_tm = localtime(&display_tv.tv_sec);
if (type() == FL_TIME_24HOUR)
strftime(time_string, 19, "%2H:%2M", display_time_tm);
else
strftime(time_string, 19, "%2I:%2M %p", display_time_tm);
input_time->value(time_string);
}
}
int
Fl_Time::hour()
{
struct tm *display_time_tm;
display_time_tm = localtime(&display_tv.tv_sec);
return display_time_tm->tm_hour;
}
int
Fl_Time::minute()
{
struct tm *display_time_tm;
display_time_tm = localtime(&display_tv.tv_sec);
return display_time_tm->tm_min;
}
void
Fl_Time::redisplay()
{
struct tm *display_time_tm;
display_time_tm = localtime(&display_tv.tv_sec);
if (type() == FL_TIME_24HOUR)
strftime(time_string, 19, "%2H:%2M", display_time_tm);
else
strftime(time_string, 19, "%2I:%2M %p", display_time_tm);
input_time->value(time_string);
}
void
Fl_Time::hour(int value)
{
struct tm *display_time_tm;
display_time_tm = localtime(&display_tv.tv_sec);
display_time_tm->tm_hour = value;
display_tv.tv_sec = mktime(display_time_tm);
}
void
Fl_Time::minute(int value)
{
struct tm *display_time_tm;
display_time_tm = localtime(&display_tv.tv_sec);
if (value < 0) {
display_time_tm->tm_min = 59;
} else if (value >= 0 && value <= 59) {
display_time_tm->tm_min = value;
} else if (value > 59) {
display_time_tm->tm_min = 0;
}
display_time_tm->tm_sec = 0;
display_tv.tv_sec = mktime(display_time_tm);
}
void
Fl_Time::value(int h, int m)
{
hour(h);
minute(m);
}
bool
Fl_Time::valid()
{
int h, m;
char a[5];
if (type() == FL_TIME_12HOUR) {
if (sscanf(input_time->value(), "%d:%d %s", &h, &m, a) == 3) {
if (h >= 1 && h <= 12 && m >= 0 && m <= 59
&& (strcasecmp(a, "am") == 0 || strcasecmp(a, "pm") == 0)) {
last_valid = true;
return true;
}
}
} else {
if (sscanf(input_time->value(), "%d:%d", &h, &m) == 2) {
if (h >= 0 && h <= 23 && m >= 0 && m <= 59) {
last_valid = true;
return true;
}
}
}
last_valid = false;
return false;
}
void
Fl_Time::input_changed_cb(Fl_Widget * widget, void *data)
{
Fl_Time *t = (Fl_Time *) data;
int h, m;
char a[5];
if (t->valid()) {
if (t->type() == FL_TIME_12HOUR) {
sscanf(t->input_time->value(), "%d:%d %2s", &h, &m, a);
if (strcasecmp(a, "am") == 0) {
if (h < 12) {
t->hour(h);
} else {
t->hour(0);
}
} else {
if (h < 12) {
t->hour(h + 12);
} else {
t->hour(12);
}
}
} else {
sscanf(t->input_time->value(), "%d:%d", &h, &m);
t->hour(h);
}
t->minute(m);
}
t->do_callback();
}
void
Fl_Time::button_cb(Fl_Widget * widget, void *data)
{
Fl_Time *t = (Fl_Time *) data;
if (widget == t->button_decrease_hour) {
t->hour(t->hour() - 1);
}
if (widget == t->button_decrease_minute) {
t->minute(t->minute() - 1);
}
if (widget == t->button_increase_minute) {
t->minute(t->minute() + 1);
}
if (widget == t->button_increase_hour) {
t->hour(t->hour() + 1);
}
t->redisplay();
t->do_callback();
}
void
Fl_Time::textsize(int size)
{
input_time->textsize(size);
}
void
Fl_Time::labelsize(int size)
{
button_decrease_hour->labelsize(size);
button_decrease_minute->labelsize(size);
button_increase_minute->labelsize(size);
button_increase_hour->labelsize(size);
Fl_Group::labelsize(size);
}
void
Fl_Time::textfont(Fl_Font font)
{
input_time->textfont(font);
}
void
Fl_Time::labelfont(Fl_Font font)
{
button_decrease_hour->labelfont(font);
button_decrease_minute->labelfont(font);
button_increase_minute->labelfont(font);
button_increase_hour->labelfont(font);
Fl_Group::labelfont(font);
}
void
Fl_Time::textcolor(Fl_Color color)
{
input_time->textcolor(color);
}
void
Fl_Time::labelcolor(Fl_Color color)
{
button_decrease_hour->labelcolor(color);
button_decrease_minute->labelcolor(color);
button_increase_minute->labelcolor(color);
button_increase_hour->labelcolor(color);
Fl_Group::labelcolor(color);
}
int
Fl_Time::textsize()
{
return input_time->textsize();
}
int
Fl_Time::labelsize()
{
return button_decrease_hour->labelsize();
}
Fl_Font
Fl_Time::labelfont()
{
return button_decrease_hour->labelfont();
}
Fl_Font
Fl_Time::textfont()
{
return input_time->textfont();
}
Fl_Color
Fl_Time::labelcolor()
{
return button_decrease_hour->labelcolor();
}
Fl_Color
Fl_Time::textcolor()
{
return input_time->textcolor();
}
--- NEW FILE: FSocket_Posix.cxx ---
// FSocket was adapted from K.A. Knizhnik's very nice SAL library.
#if defined(__svr4__)
#define mutex system_mutex
#endif
#if defined(__FreeBSD__) || defined(__linux__) || defined(__CYGWIN__)
#include <sys/ioctl.h>
#else
#include <stropts.h>
#endif
#include <fcntl.h>
#include <sys/time.h>
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/utsname.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#ifndef __CYGWIN__
#include <netinet/tcp.h>
#endif
#include <unistd.h>
#include <errno.h>
extern "C"
{
#include <netdb.h>
}
#undef mutex
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include "FSocket_Posix.H"
#include <signal.h>
#define MAX_HOST_NAME 256
char *
FSocket_Posix::unix_socket_dir =
"/tmp/";
class
FSocket_Posix_library
{
public:
FSocket_Posix_library()
{
static struct sigaction
sigpipe_ignore;
sigpipe_ignore.
sa_handler =
SIG_IGN;
sigaction(SIGPIPE, &sigpipe_ignore, NULL);
}
};
static FSocket_Posix_library
unisock_lib;
int
FSocket_Posix::open(int listen_queue_size)
{
char hostname[MAX_HOST_NAME];
unsigned short port;
char *p;
assert(address != NULL);
if ((p = strchr(address, ':')) == NULL
|| unsigned (p - address) >= sizeof(hostname)
|| sscanf(p + 1, "%hd", &port) != 1) {
errcode = bad_address;
return 0;
}
memcpy(hostname, address, p - address);
hostname[p - address] = '\0';
create_file = 0;
union
{
sockaddr sock;
sockaddr_in sock_inet;
//char name[MAX_HOST_NAME];
}
u;
int sa_length;
if (domain == sock_local_domain) {
u.sock.sa_family = AF_UNIX;
assert(strlen(unix_socket_dir) + strlen(address)
< MAX_HOST_NAME - offsetof(sockaddr, sa_data));
sa_length = offsetof(sockaddr, sa_data) +
sprintf(u.sock.sa_data, "%s%s", unix_socket_dir, address);
unlink(u.sock.sa_data); // remove file if existed
create_file = 1;
} else {
u.sock_inet.sin_family = AF_INET;
u.sock_inet.sin_addr.s_addr = htonl(INADDR_ANY);
u.sock_inet.sin_port = htons(port);
sa_length = sizeof(sockaddr_in);
}
if ((fd = socket(u.sock.sa_family, SOCK_STREAM, 0)) < 0) {
errcode = errno;
return 0;
}
if (bind(fd, &u.sock, sa_length) < 0) {
errcode = errno;
::close(fd);
return 0;
}
if (listen(fd, listen_queue_size) < 0) {
errcode = errno;
::close(fd);
return 0;
}
errcode = ok;
state = ss_open;
return 1;
}
int
FSocket_Posix::valid()
{
return errcode == ok;
}
void
FSocket_Posix::get_error_text(char *buf, size_t buf_size)
{
char *msg;
switch (errcode) {
case ok:
msg = "ok";
break;
case not_opened:
msg = "socket not opened";
break;
case bad_address:
msg = "bad address";
break;
case connection_failed:
msg = "exceed limit of attempts of connection to server";
break;
case broken_pipe:
msg = "connection is broken";
break;
case invalid_access_mode:
msg = "invalid access mode";
break;
default:
msg = strerror(errcode);
}
strncpy(buf, msg, buf_size);
}
FSocket *
FSocket_Posix::accept()
{
int s;
if (state != ss_open) {
errcode = not_opened;
return NULL;
}
while ((s =::accept(fd, NULL, NULL)) < 0 && errno == EINTR);
if (s < 0) {
errcode = errno;
return NULL;
} else if (state != ss_open) {
errcode = not_opened;
return NULL;
} else {
static struct linger l = { 1, LINGER_TIME };
if (domain == sock_global_domain) {
int enabled = 1;
if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char *) &enabled,
sizeof enabled) != 0) {
errcode = errno;
::close(s);
return NULL;
}
}
if (setsockopt(s, SOL_SOCKET, SO_LINGER, (char *) &l, sizeof l) != 0) {
errcode = invalid_access_mode;
::close(s);
return NULL;
}
errcode = ok;
return new FSocket_Posix(s);
}
}
int
FSocket_Posix::cancel_accept()
{
// Wakeup listener
state = ss_shutdown;
delete FSocket::connect(address, domain, 1, 0);
return 1;
}
int
FSocket_Posix::connect(int max_attempts, time_t timeout)
{
int rc;
char *p;
char hostname[MAX_HOST_NAME];
unsigned short port;
assert(address != NULL);
if (domain != sock_local_domain) {
if ((p = strchr(address, ':')) == NULL
|| unsigned (p - address) >= sizeof(hostname)
|| sscanf(p + 1, "%hd", &port) != 1) {
errcode = bad_address;
return 0;
}
memcpy(hostname, address, p - address);
hostname[p - address] = '\0';
}
create_file = 0;
union
{
sockaddr sock;
sockaddr_in sock_inet;
char name[MAX_HOST_NAME];
}
u;
int sa_length;
if (domain == sock_local_domain || (domain == sock_any_domain &&
strcmp(hostname, "localhost") == 0)) {
// connect UNIX socket
u.sock.sa_family = AF_UNIX;
assert(strlen(unix_socket_dir) + strlen(address)
< MAX_HOST_NAME - offsetof(sockaddr, sa_data));
sa_length = offsetof(sockaddr, sa_data) +
sprintf(u.sock.sa_data, "%s%s", unix_socket_dir, address);
} else {
u.sock_inet.sin_family = AF_INET;
u.sock_inet.sin_addr.s_addr = inet_addr(hostname);
if ((int) (u.sock_inet.sin_addr.s_addr) == -1) {
struct hostent *hp; // entry in hosts table
if ((hp = gethostbyname(hostname)) == NULL ||
hp->h_addrtype != AF_INET) {
errcode = bad_address;
return 0;
}
memcpy(&u.sock_inet.sin_addr, hp->h_addr,
sizeof u.sock_inet.sin_addr);
}
u.sock_inet.sin_port = htons(port);
sa_length = sizeof(u.sock_inet);
}
while (1) {
if ((fd = socket(u.sock.sa_family, SOCK_STREAM, 0)) < 0) {
errcode = errno;
return 0;
}
do {
rc =::connect(fd, &u.sock, sa_length);
} while (rc < 0 && errno == EINTR);
if (rc < 0) {
errcode = errno;
::close(fd);
if (errcode == ENOENT || errcode == ECONNREFUSED) {
if (--max_attempts > 0) {
sleep(timeout);
} else {
break;
}
} else {
return 0;
}
} else {
if (u.sock_inet.sin_family == AF_INET) {
int enabled = 1;
if (setsockopt
(fd, IPPROTO_TCP, TCP_NODELAY, (char *) &enabled,
sizeof enabled) != 0) {
errcode = errno;
::close(fd);
return 0;
}
}
errcode = ok;
state = ss_open;
return 1;
}
}
errcode = connection_failed;
return 0;
}
int
FSocket_Posix::read(void *buf, size_t min_size, size_t max_size,
time_t timeout)
{
size_t size = 0;
time_t start = 0;
if (state != ss_open) {
errcode = not_opened;
return -1;
}
if (timeout != WAIT_FOREVER) {
start = time(NULL);
}
do {
ssize_t rc;
if (timeout != WAIT_FOREVER) {
fd_set events;
struct timeval tm;
FD_ZERO(&events);
FD_SET(fd, &events);
tm.tv_sec = timeout;
tm.tv_usec = 0;
while ((rc = select(fd + 1, &events, NULL, NULL, &tm)) < 0
&& errno == EINTR);
if (rc < 0) {
errcode = errno;
return -1;
}
if (rc == 0) {
return size;
}
time_t now = time(NULL);
timeout = start + timeout >= now ? 0 : timeout + start - now;
}
while ((rc =::read(fd, (char *) buf + size, max_size - size)) < 0
&& errno == EINTR);
if (rc < 0) {
errcode = errno;
return -1;
} else if (rc == 0) {
errcode = broken_pipe;
return -1;
} else {
size += rc;
}
} while (size < min_size);
return (int) size;
}
int
FSocket_Posix::read(void *buf, size_t size)
{
if (state != ss_open) {
errcode = not_opened;
return 0;
}
do {
ssize_t rc;
while ((rc =::read(fd, buf, size)) < 0 && errno == EINTR);
if (rc < 0) {
errcode = errno;
return 0;
} else if (rc == 0) {
errcode = broken_pipe;
return 0;
} else {
buf = (char *) buf + rc;
size -= rc;
}
} while (size != 0);
return 1;
}
int
FSocket_Posix::write(void const *buf, size_t size)
{
if (state != ss_open) {
errcode = not_opened;
return 0;
}
do {
ssize_t rc;
while ((rc =::write(fd, buf, size)) < 0 && errno == EINTR);
if (rc < 0) {
errcode = errno;
return 0;
} else if (rc == 0) {
errcode = broken_pipe;
return 0;
} else {
buf = (char *) buf + rc;
size -= rc;
}
} while (size != 0);
//
// errcode is not assigned 'ok' value beacuse write function
// can be called in parallel with other socket operations, so
// we want to preserve old error code here.
//
return 1;
}
int
FSocket_Posix::close()
{
if (state != ss_close) {
state = ss_close;
if (::close(fd) == 0) {
errcode = ok;
return 1;
} else {
errcode = errno;
return 0;
}
}
errcode = ok;
return 1;
}
int
FSocket_Posix::shutdown()
{
if (state == ss_open) {
state = ss_shutdown;
int rc =::shutdown(fd, 2);
if (rc != 0) {
errcode = errno;
return 0;
}
}
return 1;
}
FSocket_Posix::~FSocket_Posix()
{
close();
if (create_file) {
char name[MAX_HOST_NAME];
sprintf(name, "%s%s", unix_socket_dir, address);
unlink(name);
}
delete[]address;
}
FSocket_Posix::FSocket_Posix(const char *addr, socket_domain domain)
{
address = strdup(addr);
this->domain = domain;
create_file = 0;
errcode = ok;
}
FSocket_Posix::FSocket_Posix(int new_fd)
{
fd = new_fd;
address = NULL;
create_file = 0;
state = ss_open;
errcode = ok;
}
FSocket *
FSocket::create_local(char const *address, int listen_queue_size)
{
FSocket_Posix *sock = new FSocket_Posix(address, sock_local_domain);
sock->open(listen_queue_size);
return sock;
}
FSocket *
FSocket::create_global(char const *address, int listen_queue_size)
{
FSocket_Posix *sock = new FSocket_Posix(address, sock_global_domain);
sock->open(listen_queue_size);
return sock;
}
FSocket *
FSocket::connect(char const *address,
socket_domain domain, int max_attempts, time_t timeout)
{
FSocket_Posix *sock = new FSocket_Posix(address, domain);
sock->connect(max_attempts, timeout);
return sock;
}
char const *
get_process_name()
{
static char name[MAX_HOST_NAME + 8];
struct utsname local_host;
uname(&local_host);
sprintf(name, "%s:%d", local_host.nodename, (int) getpid());
return name;
}
--- NEW FILE: FSocket_Posix.H ---
/* -*-C++-*-
"$Id: FSocket_Posix.H,v 1.1 2006-10-03 11:24:50 dslinux_amadeus Exp $"
Copyright 1997 GARRET.
Copyright 1999-2000 by the Flek development team.
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 "flek-devel at sourceforge.net".
*/
// FSocket was adapted from K.A. Knizhnik's very nice SAL library.
#ifndef __FSOCKET_POSIX_H__
#define __FSOCKET_POSIX_H__
#include <Flek/FSocket.H>
class FSocket_Posix : public FSocket {
protected:
descriptor_t fd;
int errcode; // error code of last failed operation
char* address; // host address
socket_domain domain; // Unix domain or INET socket
int create_file; // Unix domain sockets use files for connection
enum error_codes {
ok = 0,
not_opened = -1,
bad_address = -2,
connection_failed = -3,
broken_pipe = -4,
invalid_access_mode = -5
};
public:
//
// Directory for Unix Domain socket files. This directory should be
// either empty or be terminated with "/". Dafault value is "/tmp/"
//
static char* unix_socket_dir;
int open(int listen_queue_size);
int connect(int max_attempts, time_t timeout);
int read(void* buf, size_t min_size, size_t max_size,time_t timeout);
int read(void* buf, size_t size);
int write(void const* buf, size_t size);
int valid();
int shutdown();
int close();
void get_error_text(char* buf, size_t buf_size);
FSocket* accept();
int cancel_accept();
FSocket_Posix(const char* address, socket_domain domain);
FSocket_Posix(int new_fd);
~FSocket_Posix();
};
#endif
--- NEW FILE: Fl_Calendar.cxx ---
/* -*-C++-*-
"$Id: Fl_Calendar.cxx,v 1.1 2006-10-03 11:24:51 dslinux_amadeus Exp $"
Copyright 1999-2000 by the Flek development team.
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
[...962 lines suppressed...]
}
prv_year->size(prv_year->w(), title_height);
prv_year->label("Y-");
prv_month->size(prv_month->w(), title_height);
prv_month->label("M-");
nxt_month->size(nxt_month->w(), title_height);
nxt_month->label("M+");
nxt_year->size(nxt_year->w(), title_height);
nxt_year->label("Y+");
caption->size(caption->w(), title_height);
Fl_Calendar_Base::csize(x, y + title_height + (h - title_height) / 7, w,
h - title_height - (h - title_height) / 7);
update();
}
--- NEW FILE: Fl_Toggle_Node_Base.cxx ---
--- NEW FILE: Flve_Input.cxx ---
// ======================================================================
// File: Flve_Input.cxx - Flve_Input implementation
// Library: flvw - FLTK Virtual widget library
// Version: 0.1.0
// Started: 01/12/2000
//
// Copyright (C) 1999 Laurence Charlton
//
// Description:
// Flve_Input implements cell text editing for a list/table.
// ======================================================================
#include <FL/Fl.H>
#include <Flek/Flve_Input.H>
int
Flve_Input::handle(int event)
{
int stat = Fl_Input::handle(event);
if (event == FL_KEYBOARD) {
//if (stat)
//{
//damage(FL_DAMAGE_CHILD);
//draw();
//}
if (!stat && owner) {
if (owner->handle(FL_SHORTCUT))
return 1;
}
}
return stat;
}
--- NEW FILE: FSGI.cxx ---
#include <Flek/math.H>
#include <Flek/FFile.H>
#include <Flek/FImage.H>
#include <Flek/FSGI.H>
#include <stdio.h>
#include <string.h>
/*
* Reads 8 bit run length encoded data of size width from input.
* The read data is stored in the array row.
*/
static int
get_rle8(FFile & input, int width, uchar * row)
{
int i;
uchar c;
int run_count; // RLE runs
int length; // Bytes read
length = 0;
while (width > 0) {
input.get_hi(c);
if (input.bad()) {
// CET - libstdc++ is evil on Linux
// cerr << "ERROR" << endl;
fprintf(stderr, "ERROR\n");
return -1;
}
length++;
run_count = c & 127;
if (run_count == 0)
break;
if (c & 128) {
input.read(row, run_count);
length += run_count;
width -= run_count;
row += run_count;
} else {
input.get_hi(c);
length++;
for (i = 0; i < run_count; i++, row++, width--)
*row = c;
}
}
return (width > 0 ? -1 : length);
}
static int
put_rle8(FFile & output, int width, uchar * row)
{
int length; // Byte count of output line
int run_count; // Number of repeated/non-repeated pixels
int x;
int i;
uchar *start, repeat;
for (x = width, length = 0; x > 0;) {
start = row;
row += 2;
x -= 2;
while (x > 0 && (row[-2] != row[-1] || row[-1] != row[0])) {
row++;
x--;
}
row -= 2;
x += 2;
run_count = row - start;
while (run_count > 0) {
i = run_count > 126 ? 126 : run_count;
run_count -= i;
output.put_hi((uchar) (128 | i));
length++;
while (i > 0) {
output.put_hi((uchar) * start);
start++;
length++;
i--;
}
}
if (x <= 0)
break;
start = row;
repeat = row[0];
row++;
x--;
while (x > 0 && *row == repeat) {
row++;
x--;
}
run_count = row - start;
while (run_count > 0) {
i = run_count > 126 ? 126 : run_count;
run_count -= i;
output.put_hi((uchar) i);
output.put_hi((uchar) repeat);
length += 2;
}
}
length++;
output.put_hi((char) 0);
if (output.bad())
return -1;
return length;
}
typedef struct
{
int bpc; // Bytes per channel
int compression; // Compression
ushort width, // Width in pixels
height, // Height in pixels
channels; // Number of channels
ulong first_row, // File offset for first row
next_row, // File offset for next row
**table, // Offset table for compression
**length; // Length table for compression
uchar *arle_row; // Advanced RLE compression buffer
long arle_offset, // Advanced RLE buffer offset
arle_length; // Advanced RLE buffer length
}
sgiT;
int
sgi_put_row(FFile & output, sgiT & img, uchar * row, int y, int channel)
{
int x;
long offset;
if (!row)
return -1;
switch (img.compression) {
case FSGI::NONE:
offset = 512 + (y + channel * img.height) * img.width * img.bpc;
if (offset != output.tell())
output.seek(offset);
if (img.bpc == 1)
output.write((char *) row, img.width);
break;
case FSGI::ARLE:
// Check the last row written.
if (img.arle_offset > 0) {
for (x = 0; x < img.width; x++)
if (row[x] != img.arle_row[x])
break;
if (x == img.width) {
img.table[channel][y] = img.arle_offset;
img.length[channel][y] = img.arle_length;
return (0);
}
}
// If that didn't match, search the previous rows.
output.seek((long) img.first_row);
if (img.bpc == 1) {
do {
img.arle_offset = output.tell();
if ((img.arle_length =
get_rle8(output, img.width, img.arle_row)) < 0) {
x = 0;
break;
}
for (x = 0; x < img.width; x++)
if (row[x] != img.arle_row[x])
break;
}
while (x < img.width);
} else {
// CET - libstdc++ is evil on Linux
//cerr << "SGI files larger than 1 byte per channel are not supported." << endl;
fprintf(stderr,
"SGI files larger than 1 byte per channel are not supported.\n");
return -1;
}
if (x == img.width) {
img.table[channel][y] = img.arle_offset;
img.length[channel][y] = img.arle_length;
return 0;
} else
output.seek(0);
case FSGI::RLE:
img.table[channel][y] = img.next_row;
offset = (long) img.next_row;
if (offset != output.tell())
output.seek(offset);
if (img.bpc == 1)
x = put_rle8(output, img.width, row);
else {
// CET - libstdc++ is evil on Linux
//cerr << "SGI files larger than 1 byte per channel are not supported." << endl;
// CET - libstdc++ is evil on Linux
fprintf(stderr,
"SGI files larger than 1 byte per channel are not supported.\n");
return -1;
}
if (img.compression == FSGI::ARLE) {
img.arle_offset = offset;
img.arle_length = x;
memcpy(img.arle_row, row, img.width);
}
img.next_row = output.tell();
img.length[channel][y] = x;
return x;
}
return 0;
}
int
sgi_get_row(FFile & input, sgiT & img, uchar * row, int y, int channel)
{
ulong offset;
if ((!row) ||
(y < 0) || (y >= img.height) ||
(channel < 0) || (channel >= img.channels))
return -1;
switch (img.compression) {
case FSGI::NONE:
offset = 512 + (y + channel * img.height) * img.width * img.bpc;
if (offset != (ulong) input.tell())
input.seek((long) offset);
if (img.bpc == 1) {
input.read(row, img.width);
row += img.width;
} else {
// CET - libstdc++ is evil on Linux
//cerr << "Not supported" << endl;
fprintf(stderr, "Not supported\n");
return -1;
}
break;
case FSGI::RLE:
offset = img.table[channel][y];
if (offset != (ulong) input.tell())
input.seek((long) offset);
if (input.bad()) {
// CET - libstdc++ is evil on Linux
//cerr << "ERROR: Bad seek" << endl;
fprintf(stderr, "ERROR: Bad seek\n");
}
if (input.bad()) {
// CET - libstdc++ is evil on Linux
//cerr << "ERROR: Bad seek (EOF)" << endl;
fprintf(stderr, "ERROR: Bad seek (EOF)\n");
}
if (img.bpc == 1)
return (get_rle8(input, img.width, row));
// CET - libstdc++ is evil on Linux
//cerr << "SGI files larger than 1 byte per channel are not supported." << endl;
fprintf(stderr,
"SGI files larger than 1 byte per channel are not supported.\n");
return -1;
}
return 0;
}
#include <stdlib.h>
FImage *
FSGI::read(char *filename)
{
FFile input;
sgiT img;
input.open(filename, FFileRead);
uchar c;
short magic;
input.get_hi(magic);
if (magic != MAGIC)
return 0;
input.get_hi(c);
img.compression = c;
input.get_hi(c);
img.bpc = c;
input.get_hi(img.width); // Dimensions (ignore)
input.get_hi(img.width);
input.get_hi(img.height);
input.get_hi(img.channels);
unsigned long t;
input.get_hi(t); // Minimum pixel
input.get_hi(t); // Maximum pixel
FImage *Nimg = new FImage(img.width, img.height, 4);
if (img.compression) {
int i, j;
input.seek(512);
if (input.bad()) {
// CET - libstdc++ is evil on Linux
//cerr << "ERROR @sgiReadFile." << endl;
fprintf(stderr, "ERROR @sgiReadFile.\n");
}
img.table = new ulongPtr[img.channels];
img.table[0] = new ulong[img.height * img.channels];
for (i = 1; i < img.channels; i++)
img.table[i] = img.table[0] + i * img.height;
for (i = 0; i < img.channels; i++)
for (j = 0; j < img.height; j++) {
ulong offset;
input.get_hi(offset);
img.table[i][j] = offset;
}
}
uchar *pixel = *(Nimg->begin());
// Allocate enough memory for one line of the image.
uchar **rows = new ucharPtr[img.channels];
rows[0] = new uchar[img.width * img.channels];
for (int z = 0; z < img.channels; z++)
rows[z] = rows[0] + z * img.width;
if (img.channels == 4) {
for (int y = 0; y < img.height; y++) {
sgi_get_row(input, img, rows[0], y, 0);
sgi_get_row(input, img, rows[1], y, 1);
sgi_get_row(input, img, rows[2], y, 2);
sgi_get_row(input, img, rows[3], y, 3);
for (int x = 0; x < img.width; x++, pixel += 4) {
pixel[0] = rows[0][x];
pixel[1] = rows[1][x];
pixel[2] = rows[2][x];
pixel[3] = rows[3][x];
}
}
} else if (img.channels == 3) {
for (int y = 0; y < img.height; y++) {
sgi_get_row(input, img, rows[0], y, 0);
sgi_get_row(input, img, rows[1], y, 1);
sgi_get_row(input, img, rows[2], y, 2);
for (int x = 0; x < img.width; x++, pixel += 4) {
pixel[0] = rows[0][x];
pixel[1] = rows[1][x];
pixel[2] = rows[2][x];
pixel[3] = 255;
}
}
} else if (img.channels == 2) {
for (int y = 0; y < img.height; y++) {
sgi_get_row(input, img, rows[0], y, 0);
sgi_get_row(input, img, rows[1], y, 1);
for (int x = 0; x < img.width; x++, pixel += 4) {
pixel[0] = rows[0][x];
pixel[1] = rows[1][x];
pixel[2] = 0;
pixel[3] = 255;
}
}
} else if (img.channels == 1) // Gray
{
for (int y = 0; y < img.height; y++) {
sgi_get_row(input, img, rows[0], y, 0);
for (int x = 0; x < img.width; x++, pixel += 4) {
pixel[0] = pixel[1] = pixel[2] = rows[0][x];
pixel[3] = 255;
}
}
}
if (img.compression) {
delete img.table[0];
img.table[0] = 0;
delete[]img.table;
}
delete[]rows[0];
delete[]rows;
return Nimg;
}
#include <string.h>
int
FSGI::write(char *filename, FImage * data, int compression, int channels)
{
FFile output;
output.open(filename, FFileWritePlus);
sgiT img;
uchar c;
int i;
img.bpc = 1;
img.compression = compression;
img.width = data->width();
img.height = data->height();
img.channels = channels;
img.first_row = 0;
img.next_row = 0;
img.table = 0;
img.length = 0;
img.arle_row = 0;
img.arle_offset = 0;
img.arle_length = 0;
output.put_hi((unsigned short) MAGIC);
c = (img.compression != 0);
output.put_hi(c); // compression
c = img.bpc;
output.put_hi(c); // bpc
output.put_hi((unsigned short) 3); // dimensions
output.put_hi(img.width);
output.put_hi(img.height);
output.put_hi(img.channels);
output.put_hi((long) 0); // Minimum pixel
output.put_hi((long) 255); // Maximum pixel
output.put_hi((long) 0); // Reserved
// This bit helps stop us from wasting processor time on blank space.
int blankSize =
max((unsigned short)
max((unsigned short) 488,
(unsigned short) (img.width * img.channels)),
(unsigned short) (img.height * img.channels * 4));
char *blank = new char[blankSize];
memset(blank, 0, blankSize);
output.write(blank, 488); // 80+102*4 = 488
switch (compression) {
case FSGI::NONE:
for (i = img.height; i > 0; i--)
output.write(blank, img.width * img.channels);
break;
case FSGI::ARLE:
// Allocate an extra row for ARLE
img.arle_row = new uchar[img.width];
img.arle_offset = 0;
case FSGI::RLE:
// Write blank scanline tables for RLE and ARLE
// Write 0s for img.height * img.channels * 2 * sizeof (long)
output.write(blank, img.height * sizeof(long) * img.channels);
output.write(blank, img.height * sizeof(long) * img.channels);
img.first_row = output.tell();
img.next_row = output.tell();
img.table = new ulongPtr[img.channels];
img.table[0] = new ulong[img.height * img.channels];
img.length = new ulongPtr[img.channels];
img.length[0] = new ulong[img.height * img.channels];
for (i = 1; i < img.channels; i++) {
img.table[i] = img.table[0] + (i * img.height);
img.length[i] = img.length[0] + (i * img.height);
}
break;
}
uchar *pixel;
uchar **rows = new ucharPtr[img.channels];
rows[0] = new uchar[img.width * img.channels];
for (int z = 1; z < img.channels; z++)
rows[z] = rows[0] + z * img.width;
pixel = *(data->begin());
if (img.channels == 4) {
for (int y = 0; y < img.height; y++) {
for (int x = 0; x < img.width; x++, pixel += 4) {
rows[0][x] = pixel[0];
rows[1][x] = pixel[1];
rows[2][x] = pixel[2];
rows[3][x] = pixel[3];
}
sgi_put_row(output, img, rows[0], y, 0);
sgi_put_row(output, img, rows[1], y, 1);
sgi_put_row(output, img, rows[2], y, 2);
sgi_put_row(output, img, rows[3], y, 3);
}
} else if (img.channels == 3) {
for (int y = 0; y < img.height; y++) {
for (int x = 0; x < img.width; x++, pixel += 4) {
rows[0][x] = pixel[0];
rows[1][x] = pixel[1];
rows[2][x] = pixel[2];
}
sgi_put_row(output, img, rows[0], y, 0);
sgi_put_row(output, img, rows[1], y, 1);
sgi_put_row(output, img, rows[2], y, 2);
}
} else if (img.channels == 2) {
for (int y = 0; y < img.height; y++) {
for (int x = 0; x < img.width; x++, pixel += 4) {
rows[0][x] = pixel[0];
rows[1][x] = pixel[1];
}
sgi_put_row(output, img, rows[0], y, 0);
sgi_put_row(output, img, rows[1], y, 1);
}
} else if (img.channels == 1) {
for (int y = 0; y < img.height; y++) {
for (int x = 0; x < img.width; x++, pixel += 4) {
rows[0][x] = pixel[0];
}
sgi_put_row(output, img, rows[0], y, 0);
}
}
if (img.compression != NONE) {
output.seek(512);
// Write the offset table.
lo_to_hi(img.table[0], img.channels * img.height);
output.write((char *) img.table[0], img.height * img.channels * 4);
// Write the length table.
lo_to_hi(img.length[0], img.channels * img.height);
output.write((char *) img.length[0], img.height * img.channels * 4);
}
output.close();
if (compression == FSGI::ARLE)
delete[]img.arle_row;
if (compression) {
delete[]img.table[0];
delete[]img.table;
delete[]img.length[0];
delete[]img.length;
}
delete[]rows[0];
delete[]rows;
delete[]blank;
return 0;
}
bool
FSGI::valid(char *filename)
{
FFile input;
input.open(filename, FFileRead);
short magic;
input.get_hi(magic);
input.close();
if (magic != MAGIC)
return false;
return true;
}
--- NEW FILE: Flve_Combo.cxx ---
// ======================================================================
// File: Flve_Combo.cxx - Flve_Combo implementation
// Library: flvw - FLTK Virtual widget library
// Version: 0.1.0
// Started: 01/12/2000
//
// Copyright (C) 1999 Laurence Charlton
//
// Description:
// Flve_Combo implements combo box functionality
// Included are select from list, text with list, incremental search
// ======================================================================
#include <FL/Fl.H>
#include <Flek/Flve_Combo.H>
#include <FL/fl_draw.H>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#if FL_MAJOR_VERSION == 1
#define text_color() FL_BLACK
#define text_font() FL_HELVETICA
#define text_size() 12
#define fl_contrast(x,y) FL_BLACK
#define selection_text_color() FL_WHITE
#define FL_DAMAGE_HIGHLIGHT FL_DAMAGE_CHILD
#define label_font labelfont
#define label_size labelsize
#define label_color labelcolor
#define label_type labeltype
#endif
#define ADDSIZE 10
#define BUTTON_WIDTH 17
#ifdef WIN32
#define STRCASECMP stricmp
#define STRNCASECMP strncmpi
#else
#define STRCASECMP strcasecmp
#define STRNCASECMP strncasecmp
#endif
char *
get_value(int R)
{
static char buf[20];
sprintf(buf, "%d", R);
return buf;
}
class Flvl_Drop:public Flv_List
{
public:
int last_row;
Flvl_Drop(int x, int y, int w, int h, const char *l =
0):Flv_List(x, y, w, h, l)
{
combo = 0;
last_row = -1;
};
Flve_Combo *combo;
protected:
void draw_row(int Offset, int &X, int &Y, int &W, int &H, int R);
};
class Flvw_Drop:public Fl_Window
{
public:
int key;
Flvl_Drop *drop_list;
Flve_Combo *combo;
Fl_Widget *pushed;
Flvw_Drop(int w, int h, const char *l = 0);
~Flvw_Drop();
protected:
int handle(int event);
};
class Flvt_Input:public Fl_Input
{
public:
Flvt_Input(int x, int y, int w, int h, const char *l =
0):Fl_Input(x, y, w, h, l)
{
};
protected:
int handle(int event);
void draw(void);
};
Flvw_Drop::Flvw_Drop(int w, int h, const char *l):
Fl_Window(w, h, l)
{
drop_list = new Flvl_Drop(0, 0, w, h);
((Flvl_Drop *) drop_list)->has_scrollbar(FLVS_VERTICAL);
pushed = 0;
}
Flvw_Drop::~Flvw_Drop()
{
if (drop_list)
delete drop_list;
}
int
Flvw_Drop::handle(int event)
{
int ex, ey, stat, r;
ex = Fl::event_x();
ey = Fl::event_y();
r = drop_list->row();
switch (event) {
case FL_PUSH:
if (ex < 0 || ex > w() || ey < 0 || ey > h()) {
key = 0;
hide();
return 1;
}
break;
case FL_KEYBOARD:
stat = Fl::event_key();
if (Fl::event_ctrl())
stat = flv_ctrl(stat);
if (Fl::event_alt())
stat = flv_alt(stat);
if (Fl::event_shift())
stat = flv_shift(stat);
if (stat == combo->drop_key()) {
key = 0;
hide();
return 1;
}
switch (Fl::event_key()) {
// modified behavior of escape key to restore original value
// of the input widget.
// TAB and Enter both accept the new value
// D.Freese (dfreese at intrepid.net)
case FL_Escape:
key = 0;
hide();
return 1;
case FL_Enter:
case FL_Tab:
combo->item.index(drop_list->row());
key = Fl::event_key();
//if (key==FL_Escape)
// key = 0;
hide();
return 1;
}
break;
}
if (pushed && (event == FL_DRAG || event == FL_RELEASE) &&
contains(pushed) && pushed != this)
stat = pushed->handle(event);
else
stat = ((Fl_Widget *) drop_list)->handle(event);
if (!stat && event == FL_KEYBOARD)
stat = ((Fl_Widget *) combo)->handle(event);
pushed = Fl::pushed();
if (event == FL_PUSH && r == drop_list->row() && pushed == this) {
combo->item.index(drop_list->row());
key = 0;
hide();
return 1;
}
return stat;
}
void
Flvl_Drop::draw_row(int Offset, int &X, int &Y, int &W, int &H, int R)
{
Flv_Style s;
get_style(s, R);
Flv_List::draw_row(Offset, X, Y, W, H, R);
fl_draw(combo->item[R].item(), X - Offset, Y, W, H, s.align());
if (last_row != row()) {
combo->value(combo->item[row()].item());
last_row = row();
}
}
void
Flvt_Input::draw(void)
{
Fl_Widget *f = Fl::focus();
// Kludge so that events don't get fired all over the place
// We just want the input to draw correctly as though it had the
// focus.
if (f && f != parent())
f = NULL;
if (f)
Fl::focus_ = this;
Fl_Input::draw();
if (f)
Fl::focus_ = f;
}
int
Flvt_Input::handle(int event)
{
int stat, t, i = 0;
Flve_Combo *w;
w = (Flve_Combo *) parent();
if (w)
i = w->item.index();
switch (event) {
case FL_FOCUS:
case FL_UNFOCUS:
Fl_Input::handle(event);
return 0;
}
t = (position() == mark());
stat = Fl_Input::handle(event);
if (event != FL_KEYBOARD)
return stat;
switch (Fl::event_key()) {
case FL_BackSpace:
// If nothing was selected, Backspace already worked
if (t)
break;
Fl_Input::handle(event);
break;
case FL_Pause:
case FL_Scroll_Lock:
case FL_Num_Lock:
case FL_Caps_Lock:
case FL_Shift_L:
case FL_Shift_R:
case FL_Control_L:
case FL_Control_R:
case FL_Meta_L:
case FL_Meta_R:
case FL_Alt_L:
case FL_Alt_R:
return stat;
}
//printf("At this point, my value is [%s]\n", value());
if (!w) {
#ifdef PIXIL
Fl_Input::redraw();
#endif
return stat;
}
if (!w->incremental_search()) {
#ifdef PIXIL
Fl_Input::redraw();
#endif
return stat;
}
if (w->item.findi(value()) > -1) {
t = position();
if (w->list) {
((Flvw_Drop *) w->list)->drop_list->row(w->item.index());
((Flvw_Drop *) w->list)->drop_list->last_row =
((Flvw_Drop *) w->list)->drop_list->row();
}
value(w->item[w->item.index()].item());
position(t + 1, size());
} else if (w->list_only()) {
t = position();
value(w->item[i].item());
position((t ? t - 1 : t), size());
}
#ifdef PIXIL
Fl_Input::redraw();
#endif
return stat;
}
Flve_Combo::Flve_Combo(int x, int y, int w, int h, const char *l):
Fl_Widget(x, y, w, h, l)
{
vlist_only = true;
vincremental_search = true;
vlist_title = 0;
Fl_Group *gsave = Fl_Group::current();
Fl_Group::current(0);
input = new Flvt_Input(x, y, w, h);
Fl_Group::current(gsave);
box(input->box());
input->box(FL_NO_BOX);
resize(x, y, w, h);
color((Fl_Color) (input->color()));
vdisplay_rows = 8;
vdrop_key = flv_ctrl('E'); // Control+E
}
Flve_Combo::~Flve_Combo()
{
if (vlist_title)
delete vlist_title;
}
bool
Flve_Combo::list_only(bool v)
{
if (v != vlist_only) {
vlist_only = v;
if (v) {
input->value(item[item.index()].item());
input->position(0, input->size());
input->set_changed();
}
}
return vlist_only;
}
void
Flve_Combo::list_title(const char *v)
{
if (vlist_title)
delete vlist_title;
vlist_title = 0;
if (v) {
vlist_title = new char[strlen(v) + 1];
strcpy(vlist_title, v);
}
}
void
Flve_Combo::resize(int X, int Y, int W, int H)
{
Fl_Widget::resize(X, Y, W, H);
X += (Fl::box_dx(box()));
Y += (Fl::box_dy(box()));
W -= (Fl::box_dw(box()));
H -= (Fl::box_dh(box()));
W -= BUTTON_WIDTH;
input->resize(X, Y, W, H);
}
int
Flve_Combo::handle(int event)
{
int stat, ex, ey, X, Y, W, H;
Fl_Widget *wid;
switch (event) {
case FL_UNFOCUS:
if (Fl::focus() == input)
take_focus();
redraw();
case FL_FOCUS:
input->handle(event);
// input->position(0, input->size() );
return 1;
case FL_KEYBOARD:
X = Fl::event_key();
if (Fl::event_ctrl())
X = flv_ctrl(X);
if (Fl::event_alt())
X = flv_alt(X);
if (Fl::event_shift())
X = flv_shift(X);
if (X == vdrop_key) {
open_list();
return 1;
}
#ifdef PIXIL
// Kludge to make input think it's focused
wid = Fl::focus_;
Fl::focus_ = input;
stat = input->handle(event);
input->redraw();
Fl::focus_ = wid;
#endif
// Shouldn't be doing searching if the value couldn't have changed!
break;
case FL_PUSH:
// Test for button push
ex = Fl::event_x();
ey = Fl::event_y();
X = x() + w() - BUTTON_WIDTH;
Y = y();
W = BUTTON_WIDTH;
H = h();
if (ex >= X && ex < X + W && ey >= Y && ey <= Y + H) {
open_list();
return 1;
}
return input->handle(event);
default:
wid = Fl::focus_;
Fl::focus_ = input;
stat = input->handle(event);
Fl::focus_ = wid;
}
return stat;
}
void
Flve_Combo::draw(void)
{
int X, Y, W, H, bx;
// modified to allow a zero length string string in input widget
// if input widget is modifiable
if (list_only() == true)
if (*(input->value()) == 0)
input->value(item[item.index()].item());
if ((damage() & FL_DAMAGE_ALL) != 0)
draw_box();
X = x() + (Fl::box_dx(box()));
Y = y() + (Fl::box_dy(box()));
W = w() - (Fl::box_dw(box()));
H = h() - (Fl::box_dh(box()));
bx = X + W - BUTTON_WIDTH;
#if FL_MAJOR_VERSION == 2
FL_UP_BOX->draw(bx + 1, Y, BUTTON_WIDTH, H,
(Fl_Color) (FL_GRAY_RAMP + 17));
#else
draw_box(FL_UP_BOX, bx + 1, Y, BUTTON_WIDTH, H,
(Fl_Color) (FL_GRAY_RAMP + 17));
#endif
fl_draw_symbol("@#2>", bx + 3, Y, BUTTON_WIDTH - 5, H, FL_BLACK);
fl_color((Fl_Color) (FL_GRAY_RAMP + 17));
fl_yxline(bx, Y, Y + H);
input->draw();
}
void
Flve_Combo::open_list()
{
int W, H, r;
Fl_Window *win;
Flvw_Drop *lst;
fl_font(text_font(), text_size());
fl_measure("X", W, H);
r = item.count();
if (vlist_title)
r++;
if (r > display_rows())
r = display_rows();
list = lst = new Flvw_Drop(w(), H * r + 4 + (vlist_title ? 4 : 0));
list->box(FL_DOWN_BOX);
list->end();
// This is a horrible hack .. This should have a parent of the root to allow
// it to pop up over the application window, instead of being contained
// within it. However, the screentop and window managers pick up this window
// and do Bad Things (TM) with it. Therefore, I've made the temporary change
// to make this a child of the application, and thus, it may look weird.
// This need's fixed.
// -Anonymous (anon at fixthisyourself.net)
list->parent(parent());
// list->parent(NULL);
lst->drop_list->rows(item.count());
if (vlist_title)
lst->drop_list->label(vlist_title);
list->clear_border();
list->set_modal();
lst->drop_list->combo = this;
lst->combo = this;
// highlight the present contents of the input widget
// if input contains a value and it can be found in the list
// added by Dave Freese (dfreese at intrepid.net)
if (item.findi(input->value()) > -1)
lst->drop_list->row(item.index());
else
lst->drop_list->row(0);
lst->drop_list->last_row = lst->drop_list->row();
// end hightlight code
win = window();
int nx = win->x();
int ny = win->y();
while (win && win->parent()) {
win = win->window();
nx += win->x();
ny += win->y();
}
if (win)
list->position(nx + x(), ny + y() + h() - 3);
Fl::grab(list);
list->show();
while (list->shown())
Fl::wait();
Fl::release();
take_focus();
// ****
// if (((Flvw_Drop *)list)->key)
value(item[item.index()].item());
do_callback();
if (win && ((Flvw_Drop *) list)->key)
Fl::handle(FL_KEYBOARD, win);
delete list;
list = 0;
}
const char *
Flve_Combo::value()
{
return input->value();
}
void
Flve_Combo::value(const char *v)
{
input->value(v);
input->set_changed();
input->mark(256);
// input->position(0, input->size() );
}
void
Flve_Combo::display_rows(int v)
{
vdisplay_rows = v;
}
// =================================================================
// Flv_Combo_Item
// =================================================================
Flv_Combo_Item::Flv_Combo_Item()
{
vitem = 0;
vvalue = 0;
}
Flv_Combo_Item::~Flv_Combo_Item()
{
if (vitem)
delete vitem;
}
const char *
Flv_Combo_Item::item(void)
{
return (vitem ? vitem : "");
}
void
Flv_Combo_Item::item(const char *v)
{
if (vitem)
delete vitem;
vitem = 0;
if (v) {
vitem = new char[strlen(v) + 1];
strcpy(vitem, v);
}
}
long
Flv_Combo_Item::value(void)
{
return vvalue;
}
void
Flv_Combo_Item::value(long v)
{
vvalue = v;
}
// =================================================================
// Flv_Combo_Items
// =================================================================
Flv_Combo_Items::Flv_Combo_Items()
{
list = 0;
vcount = 0;
vallocated = 0;
vcurrent = 0;
nodups = true;
}
Flv_Combo_Items::~Flv_Combo_Items()
{
clear();
}
void
Flv_Combo_Items::add(const char *item, long v)
{
Flv_Combo_Item *i;
if (vcount == vallocated)
make_room_for(vallocated + 10);
if (vcount == vallocated)
return;
if (strlen(item) == 0)
return;
if (nodups)
if (find(item) != -1)
return;
i = new Flv_Combo_Item();
i->item(item);
i->value(v);
list[vcount++] = i;
}
void
Flv_Combo_Items::insert(int index, const char *item, long v)
{
int t;
Flv_Combo_Item *i;
if (vcount == vallocated)
make_room_for(vallocated + 10);
if (vcount == vallocated)
return;
if (strlen(item) == 0)
return;
if (nodups)
if (find(item) != -1)
return;
i = new Flv_Combo_Item();
i->item(item);
i->value(v);
if (index < 0)
index = 0;
if (index > vcount)
index = vcount;
for (t = vcount; t > index; t--)
list[t] = list[t - 1];
list[index] = i;
vcount++;
}
void
Flv_Combo_Items::remove(int index)
{
int t;
if (index < 0 || index >= vcount)
return;
if (list[index])
delete list[index];
for (t = index; t < vcount - 1; t++)
list[t] = list[t + 1];
list[t] = 0;
vcount--;
if (vcurrent >= vcount && vcurrent)
vcurrent--;
}
void
Flv_Combo_Items::change(int i, const char *item, long v)
{
if (i < 0 || i > vcount)
return;
list[i]->item(item);
list[i]->value(v);
}
void
Flv_Combo_Items::change(int i, const char *item)
{
if (i < 0 || i > vcount)
return;
list[i]->item(item);
}
void
Flv_Combo_Items::change(int i, long v)
{
if (i < 0 || i > vcount)
return;
list[i]->value(v);
}
#define C(x) ((Flv_Combo_Item *)(x))
static int
cmp(const void *a, const void *b)
{
Flv_Combo_Item *ai = *((Flv_Combo_Item **) (a)),
*bi = *((Flv_Combo_Item **) (b));
const char *a_item = ai->item(), *b_item = bi->item();
long a_value = ai->value(), b_value = bi->value();
int status = STRCASECMP(a_item, b_item);
if (status)
return status;
return (a_value - b_value);
}
void
Flv_Combo_Items::sort(void) // Sort list
{
if (list && vcount > 1)
qsort(list, vcount, sizeof(Flv_Combo_Item *), cmp);
}
void
Flv_Combo_Items::clear(void) // Clear list
{
int t;
for (t = 0; t < vcount; t++)
if (list[t])
delete list[t];
if (list)
delete[]list;
list = 0;
vallocated = 0;
vcount = 0;
vcurrent = 0;
}
void
Flv_Combo_Items::index(int i) // Set current index
{
if (i < 0 || i >= vcount)
return;
vcurrent = i;
}
int
Flv_Combo_Items::findi(const char *v) // Find text return index (-1 not found)
{
int t;
// added for case where v is zero length
if (*v == 0)
return -1;
for (t = 0; t < vcount; t++) {
if (STRNCASECMP(list[t]->item(), v, strlen(v)) == 0) {
vcurrent = t;
return t;
}
}
return -1;
}
int
Flv_Combo_Items::find(const char *v) // Find text return index (-1 not found)
{
int t;
// added for case where v is zero length
if (*v == 0)
return -1;
for (t = 0; t < vcount; t++) {
if (STRCASECMP(list[t]->item(), v) == 0) {
vcurrent = t;
return t;
}
}
return -1;
}
int
Flv_Combo_Items::find(long v) // Find value return index (-1 not found)
{
int t;
for (t = 0; t < vcount; t++) {
if (list[t]->value() == v) {
vcurrent = t;
return t;
}
}
return -1;
}
Flv_Combo_Item *
Flv_Combo_Items::current(void)
{
if (list)
return list[vcurrent];
return NULL;
}
Flv_Combo_Item & Flv_Combo_Items::operator[](int index) {
static Flv_Combo_Item
x;
if (index < 0 || index >= vcount)
return x;
return *(list[index]);
}
void
Flv_Combo_Items::make_room_for(int n)
{
if (n >= vallocated) {
Flv_Combo_Item **a = new Flv_Combo_Item *[n];
if (!a)
return;
// Wasted CPU cycles, but list is pretty
memset(a, 0, sizeof(Flv_Style *) * (vallocated + ADDSIZE));
if (vcount)
memcpy(a, list, sizeof(Flv_Combo_Item *) * vcount);
vallocated += ADDSIZE;
if (list)
delete[]list;
list = a;
}
}
--- NEW FILE: FDate.cxx ---
#include <time.h>
// Evil #include <iostream.h>
#include <iomanip.h>
#include <stdio.h>
#include <string.h>
#include <Flek/FDate.H>
// This class is based on the date class by Dave Freese
// <dfreese at intrepid.net>
const int
FDate::days[] = {
0,
31,
28,
31,
30,
31,
30,
31,
31,
30,
31,
30,
31 };
const int
FDate::julian_days[2][13] = {
{0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334},
{0, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335}
};
const char *
FDate::month_name[] = {
"January",
"Febuary",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
};
void
FDate::today()
{
time_t t;
struct tm *now;
time(&t);
now = localtime(&t);
Year = now->tm_year + 1900;
Month = now->tm_mon + 1;
Day = now->tm_mday;
}
FDate::FDate()
{
today();
Fmt = 0;
}
FDate::FDate(const FDate & dt):
FBase(dt)
{
set_date(dt);
}
FDate::FDate(int y, int m, int d)
{
set_date(y, m, d);
Fmt = 0;
}
FBase::Ptr FDate::copy(void) const
{
return new FDate(*this);
}
void
FDate::set_date(int y, int m, int d)
{
if (valid(y, m, d)) {
Year = y;
Month = m;
Day = d;
} else
today();
}
void
FDate::set_date(const FDate & dt)
{
Year = dt.Year;
Month = dt.Month;
Day = dt.Day;
Fmt = dt.Fmt;
}
void
FDate::set_format(int iFmt)
{
Fmt = iFmt;
}
void
FDate::year(int y)
{
Year = y;
}
int
FDate::year()
{
return Year;
}
void
FDate::month(int m)
{
Month = m;
}
int
FDate::month()
{
return Month;
}
void
FDate::day(int d)
{
Day = d;
}
int
FDate::day()
{
return Day;
}
bool
FDate::leap_year(int y)
{
if (y % 400 == 0 || (y % 100 != 0 && y % 4 == 0))
return true;
return false;
}
bool
FDate::valid(int y, int m, int d)
{
if (y < 1970 || y > 2035)
return false;
if (m < 1 || m > 12)
return false;
if (d < 1)
return false;
if (leap_year(y)) {
if ((m == 2) && (d > 29))
return false;
else
return true;
}
if (d > days[m])
return false;
return true;
}
/* Always link all apps with with libstdc++ for a trivial thing
like this? This should probably be put in a separate flek-stdc++
library?
ostream &operator<< (ostream &output, const FDate &d) {
output << d.to_string ();
return output;
}
*/
bool
FDate::end_of_month(int d)
{
if (Month == 2 && leap_year(Year))
return (d == 29); // last day of Feb in leap year
else
return (d == days[Month]);
}
void
FDate::help_increment()
{
if (end_of_month(Day) && Month == 12) { // end year
Day = 1;
Month = 1;
++Year;
} else if (end_of_month(Day)) {
Day = 1;
++Month;
} else
++Day;
}
FDate & FDate::operator++()
{
help_increment();
return *this; // reference return to create an lvalue
}
FDate
FDate::operator++(int)
{
FDate temp = *this;
help_increment();
return temp; // return non-increment, saved temporary object
}
const FDate &
FDate::operator+=(int ndays)
{
for (int i = 0; i < ndays; i++)
help_increment();
return *this; // enables cascading
}
bool
FDate::operator==(const FDate & d)
{
if (this->Year != d.Year)
return false;
if (this->Month != d.Month)
return false;
if (this->Day != d.Day)
return false;
return true;
}
bool
FDate::operator!=(const FDate & d)
{
return (!(*this == d));
}
bool
FDate::operator<(const FDate & d)
{
if (this->Year < d.Year)
return true;
if (this->Year > d.Year)
return false;
if (this->Month < d.Month)
return true;
if (this->Month > d.Month)
return false;
if (this->Day < d.Day)
return true;
return false;
}
bool
FDate::operator>(const FDate & d)
{
if (*this < d)
return false;
if (*this == d)
return false;
return true;
}
void
FDate::operator=(const FDate & d)
{
this->Year = d.Year;
this->Month = d.Month;
this->Day = d.Day;
}
double
FDate::julian_date()
{
int days_in_year = 365;
if (leap_year())
days_in_year++;
return (Year + 1.0 * (day_of_year(Year, Month, Day) - 1) / days_in_year);
}
void
FDate::next_month()
{
if (Month == 12) {
Month = 1;
Year++;
} else
Month++;
while ((Day >= 1) && (!valid()))
Day--;
}
void
FDate::previous_month()
{
if (Month == 1) {
Month = 12;
Year--;
} else
Month--;
while ((Day >= 1) && (!valid()))
Day--;
}
void
FDate::previous_year()
{
if (Month == 2 && Day == 29)
Day = 28;
Year--;
}
void
FDate::next_year()
{
if (Month == 2 && Day == 29)
Day = 28;
Year++;
}
char *
FDate::to_string(int fmt) const
{
static char temp[20];
char temp_month[10];
switch (fmt) {
case 1:
sprintf(temp, "%02d/%02d/%04d", Month, Day, Year);
break;
case 2:
sprintf(temp, "%s %2d, %4d", month_name[Month - 1], Day, Year);
break;
case 3:
strcpy(temp_month, month_name[Month - 1]);
temp_month[3] = 0;
sprintf(temp, "%s %2d, %4d", temp_month, Day, Year);
break;
case 4:
strcpy(temp_month, month_name[Month - 1]);
temp_month[3] = 0;
sprintf(temp, "%d %s %4d", Day, temp_month, Year);
break;
case 0:
default:
sprintf(temp, "%02d/%02d/%02d", Month, Day,
Year > 1999 ? Year - 2000 : Year - 1900);
break;
}
return temp;
}
char *
FDate::to_string() const
{
return to_string(Fmt);
}
int
FDate::days_in_month(int month, int leap)
{
/* Validate the month. */
if (month < JANUARY || month > DECEMBER)
return -1;
/* Return 28, 29, 30, or 31 based on month/leap. */
switch (month) {
case FEBRUARY:
return leap ? 29 : 28;
default:
return days[month];
}
}
int
FDate::day_of_year(int year, int mon, int mday)
{
/* Return day of year. */
return mday + julian_days[leap_year(year) ? 1 : 0][mon];
}
int
FDate::day_of_epoch(int year, int mon, int mday)
{
int doe;
int era, cent, quad, rest;
/* break down the year into 400, 100, 4, and 1 year multiples */
rest = year - 1;
quad = rest / 4;
rest %= 4;
cent = quad / 25;
quad %= 25;
era = cent / 4;
cent %= 4;
/* set up doe */
doe = day_of_year(year, mon, mday);
doe += era * (400 * 365 + 97);
doe += cent * (100 * 365 + 24);
doe += quad * (4 * 365 + 1);
doe += rest * 365;
return doe;
}
int
FDate::day_of_week(int year, int mon, int mday)
{
return day_of_epoch(year, mon, mday) % 7;
}
--- NEW FILE: Flv_Style.cxx ---
// ======================================================================
// File: Flv_Style.cxx - Flv_Style implementation
// Program: Flv_Style - FLTK Virtual List/Table Styles Widget
// Version: 0.1.0
// Started: 11/21/99
//
// Copyright (C) 1999 Laurence Charlton
//
// Description:
// The styles classes are basically defined to make life easier while
// working with styles for the virtual classes.
// ======================================================================
#include <FL/Fl_Widget.H>
#include <Flek/Flv_Style.H>
#include <stdio.h>
#ifdef WIN32
#include <mem.h>
#else
#include <memory.h>
#include <string.h>
#endif
#define ADDSIZE 10
// Flv_Style bits
#define STYLE_DEFINE_FONT 0x0001
#define STYLE_DEFINE_FONT_SIZE 0x0002
#define STYLE_DEFINE_FOREGROUND 0x0004
#define STYLE_DEFINE_BACKGROUND 0x0008
#define STYLE_DEFINE_ALIGN 0x0010
#define STYLE_DEFINE_FRAME 0x0020
#define STYLE_DEFINE_RESIZABLE 0x0040
#define STYLE_DEFINE_HEIGHT 0x0080
#define STYLE_DEFINE_WIDTH 0x0100
#define STYLE_DEFINE_LOCKED 0x0200
#define STYLE_DEFINE_BORDER 0x0400
#define STYLE_DEFINE_BORDER_COLOR 0x0800
#define STYLE_DEFINE_BORDER_SPACING 0x1000
#define STYLE_DEFINE_X_MARGIN 0x2000
#define STYLE_DEFINE_Y_MARGIN 0x4000
#define STYLE_DEFINE_EDITOR 0x8000
#define CLEAR(n) vdefined &= ~(n)
#define DEFINED(n) ((vdefined & (n))!= 0)
#define DEFINED2(v,n) ((v.vdefined & (n))!= 0)
Flv_Style::Flv_Style()
{
vdefined = 0;
vvalue = 0;
// I'm not worried about initializing the rest of the private
// variables since they are undefined.
}
Flv_Style::Flv_Style(int value)
{
vdefined = 0;
vvalue = value;
// I'm not worried about initializing the rest of the private
// variables since they are undefined.
}
// ==================================================================
// Set drawing alignment
const Fl_Align &
Flv_Style::align(const Fl_Align & n)
{
valign = n;
vdefined |= STYLE_DEFINE_ALIGN;
return valign;
}
// Undefine drawing alignment
void
Flv_Style::clear_align(void)
{
CLEAR(STYLE_DEFINE_ALIGN);
}
// Is drawing alignment defined?
bool
Flv_Style::align_defined(void) const
{
return DEFINED(STYLE_DEFINE_ALIGN);
}
// ==================================================================
// Set background color
Fl_Color
Flv_Style::background(Fl_Color n)
{
vbackground = n;
vdefined |= STYLE_DEFINE_BACKGROUND;
return vbackground;
}
// Undefine background color
void
Flv_Style::clear_background(void)
{
CLEAR(STYLE_DEFINE_BACKGROUND);
}
// Is background defined?
bool
Flv_Style::background_defined(void) const
{
return DEFINED(STYLE_DEFINE_BACKGROUND);
}
// ==================================================================
// Set border
int
Flv_Style::border(int n)
{
vborder = (unsigned char) n;
vdefined |= STYLE_DEFINE_BORDER;
return vborder;
}
// Undefine border
void
Flv_Style::clear_border(void)
{
CLEAR(STYLE_DEFINE_BORDER);
}
// Is border defined?
bool
Flv_Style::border_defined(void) const
{
return DEFINED(STYLE_DEFINE_BORDER);
}
// ==================================================================
// Set border_color
Fl_Color
Flv_Style::border_color(Fl_Color n)
{
vborder_color = n;
vdefined |= STYLE_DEFINE_BORDER_COLOR;
return vborder_color;
}
// Undefine border_color
void
Flv_Style::clear_border_color(void)
{
CLEAR(STYLE_DEFINE_BORDER_COLOR);
}
// Is border_color defined?
bool
Flv_Style::border_color_defined(void) const
{
return DEFINED(STYLE_DEFINE_BORDER_COLOR);
}
// ==================================================================
// Set border_spacing
int
Flv_Style::border_spacing(int n)
{
vborder_spacing = (unsigned char) n;
vdefined |= STYLE_DEFINE_BORDER_SPACING;
return vborder_spacing;
}
// Undefine border_spacing
void
Flv_Style::clear_border_spacing(void)
{
CLEAR(STYLE_DEFINE_BORDER_SPACING);
}
// Is border_spacing defined?
bool
Flv_Style::border_spacing_defined(void) const
{
return DEFINED(STYLE_DEFINE_BORDER_SPACING);
}
// ==================================================================
// Set content editor
Fl_Widget *
Flv_Style::editor(Fl_Widget * v)
{
veditor = v;
if (Fl::focus() != v && veditor)
veditor->hide();
vdefined |= STYLE_DEFINE_EDITOR;
return veditor;
}
// Undefine border_spacing
void
Flv_Style::clear_editor(void)
{
CLEAR(STYLE_DEFINE_EDITOR);
}
// Is border_spacing defined?
bool
Flv_Style::editor_defined(void) const
{
return DEFINED(STYLE_DEFINE_EDITOR);
}
// ==================================================================
// Set current font
const Fl_Font &
Flv_Style::font(const Fl_Font & n)
{
vfont = n;
vdefined |= STYLE_DEFINE_FONT;
return vfont;
}
// Undefine font
void
Flv_Style::clear_font(void)
{
CLEAR(STYLE_DEFINE_FONT);
}
// Is font defined
bool
Flv_Style::font_defined(void) const
{
return DEFINED(STYLE_DEFINE_FONT);
}
// ==================================================================
// Set font size
int
Flv_Style::font_size(int n)
{
if (n < 1) // Clip at 1 as the smallest font size
n = 1;
vfont_size = n;
vdefined |= STYLE_DEFINE_FONT_SIZE;
return vfont_size;
}
// Undefine font size
void
Flv_Style::clear_font_size(void)
{
CLEAR(STYLE_DEFINE_FONT_SIZE);
}
// Is font size defined?
bool
Flv_Style::font_size_defined(void) const
{
return DEFINED(STYLE_DEFINE_FONT_SIZE);
}
// ==================================================================
// Set foreground color
Fl_Color
Flv_Style::foreground(Fl_Color n)
{
vforeground = n;
vdefined |= STYLE_DEFINE_FOREGROUND;
return vforeground;
}
// Undefine foreground color
void
Flv_Style::clear_foreground(void)
{
CLEAR(STYLE_DEFINE_FOREGROUND);
}
// Is foreground defined?
bool
Flv_Style::foreground_defined(void) const
{
return DEFINED(STYLE_DEFINE_FOREGROUND);
}
// ==================================================================
// Set frame type
const Fl_Boxtype &
Flv_Style::frame(const Fl_Boxtype & n)
{
vframe = n;
vdefined |= STYLE_DEFINE_FRAME;
return vframe;
}
// Undefine frame type
void
Flv_Style::clear_frame(void)
{
CLEAR(STYLE_DEFINE_FRAME);
}
// Is frame type defined?
bool
Flv_Style::frame_defined(void) const
{
return DEFINED(STYLE_DEFINE_FRAME);
}
// ==================================================================
// Set height
int
Flv_Style::height(int n)
{
if (n < 0)
n = 0;
vdefined |= STYLE_DEFINE_HEIGHT;
return (vheight = n);
}
// Undefine row height
void
Flv_Style::clear_height(void)
{
CLEAR(STYLE_DEFINE_HEIGHT);
}
// Is row height defined?
bool
Flv_Style::height_defined(void) const
{
return DEFINED(STYLE_DEFINE_HEIGHT);
}
// ==================================================================
// Set locked
bool
Flv_Style::locked(bool n)
{
vdefined |= STYLE_DEFINE_LOCKED;
return (vlocked = n);
}
// Undefine locked
void
Flv_Style::clear_locked(void)
{
CLEAR(STYLE_DEFINE_LOCKED);
}
// Is locked defined?
bool
Flv_Style::locked_defined(void) const
{
return DEFINED(STYLE_DEFINE_LOCKED);
}
// ==================================================================
// Set resizable
bool
Flv_Style::resizable(bool n)
{
vresizable = n;
vdefined |= STYLE_DEFINE_RESIZABLE;
return vresizable;
}
// Undefine resizable
void
Flv_Style::clear_resizable(void)
{
CLEAR(STYLE_DEFINE_RESIZABLE);
}
// Is resizable defined?
bool
Flv_Style::resizable_defined(void) const
{
return DEFINED(STYLE_DEFINE_RESIZABLE);
}
// ==================================================================
// Set column width
int
Flv_Style::width(int n)
{
if (n < 0)
n = 0;
vdefined |= STYLE_DEFINE_WIDTH;
return (vwidth = n);
}
// Undefine column width
void
Flv_Style::clear_width(void)
{
CLEAR(STYLE_DEFINE_WIDTH);
}
// Is column width defined?
bool
Flv_Style::width_defined(void) const
{
return DEFINED(STYLE_DEFINE_WIDTH);
}
// ==================================================================
// Set x margin
int
Flv_Style::x_margin(int x)
{
if (x < 0)
x = 0;
if (x != vx_margin) {
vdefined |= STYLE_DEFINE_X_MARGIN;
vx_margin = (unsigned char) x;
}
return vx_margin;
}
// Undefine x margin
void
Flv_Style::clear_x_margin(void)
{
CLEAR(STYLE_DEFINE_X_MARGIN);
}
// Is x margin defined
bool
Flv_Style::x_margin_defined(void) const
{
return DEFINED(STYLE_DEFINE_X_MARGIN);
}
// ==================================================================
// Set y margin
int
Flv_Style::y_margin(int y)
{
if (y < 0)
y = 0;
if (y != vy_margin) {
vdefined |= STYLE_DEFINE_Y_MARGIN;
vy_margin = (unsigned char) y;
}
return vy_margin;
}
// Undefine y margin
void
Flv_Style::clear_y_margin(void)
{
CLEAR(STYLE_DEFINE_Y_MARGIN);
}
// Is y margin defined
bool
Flv_Style::y_margin_defined(void) const
{
return DEFINED(STYLE_DEFINE_Y_MARGIN);
}
// ==================================================================
// Cumulative assignment operator
// This will only assign portions that are defined.
const Flv_Style &
Flv_Style::operator=(const Flv_Style & n)
{
if (n.align_defined())
align(n.valign);
if (n.background_defined())
background(n.vbackground);
if (n.border_defined())
border(n.vborder);
if (n.border_color_defined())
border_color(n.vborder_color);
if (n.border_spacing_defined())
border_spacing(n.vborder_spacing);
if (n.editor_defined())
editor(n.veditor);
if (n.font_defined())
font(n.vfont);
if (n.font_size_defined())
font_size(n.vfont_size);
if (n.foreground_defined())
foreground(n.vforeground);
if (n.frame_defined())
frame(n.vframe);
if (n.height_defined())
height(n.vheight);
if (n.locked_defined())
locked(n.vlocked);
if (n.resizable_defined())
resizable(n.vresizable);
if (n.width_defined())
width(n.vwidth);
if (n.x_margin_defined())
x_margin(n.vx_margin);
if (n.y_margin_defined())
y_margin(n.vy_margin);
// I'm not copying value because it seems meaningless in every context
// I can think of.
// I'm not copying cell_style either for the same reason. It just seems like
// a REALLY bad idea.
return *this;
}
// **********************************************************************
// Routines for Flv_Style_List
//
// Implemented as a dynamic sparse array
// **********************************************************************
Flv_Style_List::Flv_Style_List()
{
list = NULL;
vcount = vallocated = vcurrent = 0;
}
void
Flv_Style_List::compact(void)
{
int n, t;
// Release memory for any dead items
for (t = 0; t < vcount; t++) {
list[t]->cell_style.compact(); // Compact cells!
if (list[t]->cell_style.count() == 0 && list[t]->all_clear()) {
delete list[t];
list[t] = NULL;
}
}
// Compact list now
for (t = n = 0; t < vcount; t++) {
if (list[t])
list[n++] = list[t];
else if (vcurrent <= t && vcurrent > 0)
vcurrent--;
}
// Make list easy to view, wasted CPU cycles
for (t = n; t < vcount; t++)
list[t] = NULL;
vcount = n; // Update count
if (!vcount && list) {
delete[]list;
list = NULL;
vcount = vcurrent = vallocated = 0;
}
}
// Undefine all styles in list
void
Flv_Style_List::clear(void)
{
int t;
for (t = 0; t < vcount; t++) // Make all entries clear
list[t]->clear_all();
compact(); // Remove dead space thats left
}
// Free memory for all (including cell
void
Flv_Style_List::release(void)
{
int t;
for (t = 0; t < vcount; t++) {
list[t]->cell_style.release();
delete list[t];
}
if (list)
delete[]list;
list = NULL;
vcurrent = vcount = vallocated = 0;
}
Flv_Style *
Flv_Style_List::current(void) // Current node
{
if (!list)
return NULL;
return list[vcurrent];
}
// Find closest match
// It will find the first value >= n
Flv_Style *
Flv_Style_List::find(int n)
{
int t, l, h;
if (!list || vcount == 0) // If list is empty, there will be no matches
return NULL;
// How a about a nice binary search? It will be slower for sequential
// processing and a small number of styles, but worlds faster as the
// number of styles increases. Use skip_to for sequential processing
// and find for random access.
l = 0;
h = vcount - 1;
while (l + 1 < h) {
vcurrent = (l + h) / 2;
t = list[vcurrent]->value();
if (t == n)
return list[vcurrent];
else if (t < n)
l = vcurrent;
else
h = vcurrent;
}
// This needs cleaning, I fairly certain there's way too much logic here
// While this will work, I think we only need to check one of the values
// but I've been wrong before... :)
vcurrent = l;
t = list[vcurrent]->value();
if (t == n)
return list[vcurrent];
if (t < n && vcurrent < vcount - 1) {
vcurrent = h;
t = list[vcurrent]->value();
if (t == n)
return list[vcurrent];
}
return NULL;
}
Flv_Style *
Flv_Style_List::first(void) // Get first style
{
if (!list)
return NULL;
vcurrent = 0;
return list[vcurrent];
}
bool
Flv_Style_List::insert(Flv_Style * n) // Add style (if doesn't exist)
{
int t;
// Make sure there is room for a new item
if (vcount == vallocated) {
Flv_Style **a = new Flv_Style *[vallocated + ADDSIZE];
if (!a)
return false;
// Wasted CPU cycles, but list is pretty
memset(a, 0, sizeof(Flv_Style *) * (vallocated + ADDSIZE));
if (vcount)
memcpy(a, list, sizeof(Flv_Style *) * vcount);
vallocated += ADDSIZE;
if (list)
delete[]list;
list = a;
}
if (vcount) {
find(n->value()); // Point to insert candidate
if (n->value() == list[vcurrent]->value()) // No duplicates
return false;
if (n->value() > list[vcurrent]->value()) // Insert at end of list
vcurrent++;
}
// Make room for insert if not appending
for (t = vcount; t > vcurrent; t--)
list[t] = list[t - 1];
list[vcurrent] = n;
vcount++;
return true;
}
Flv_Style *
Flv_Style_List::next(void) // Next style
{
if (!list || vcurrent >= vcount - 1)
return NULL;
vcurrent++;
return list[vcurrent];
}
Flv_Style *
Flv_Style_List::prior(void)
{
if (!vcurrent || !list)
return 0;
vcurrent--;
return list[vcurrent];
}
bool
Flv_Style_List::clear_current(void)
{
if (!list)
return false;
if (list[vcurrent]->cell_style.count() == 0)
return release_current();
list[vcurrent]->clear_all();
return true;
}
bool
Flv_Style_List::release_current(void) // Remove current style
{
if (!list)
return false;
delete list[vcurrent];
if (vcurrent < vcount - 1) {
memmove(list + vcurrent, list + vcurrent + 1,
sizeof(Flv_Style *) * (vcount - vcurrent));
vcount--;
list[vcount] = NULL;
}
if (vcurrent == vcount)
vcurrent--;
return true;
}
// From n skip up to value v
Flv_Style *
Flv_Style_List::skip_to(int v)
{
int c;
if (!list || !vcount)
return NULL;
// In case we're backing up or starting over
// We're checking vcurrent-1 so if the last search found
// an entry > the desired value, and this search isn't quite
// to the last found value, we don't want to start over, just
// stay where we are.
// Style 1, 2, 3, 7 & 10 defined
// search for 4 (current points to 7) returns false
// search for 5 (stay at seven since 3 is < value, return false)
// If we started at 0 we'd end up here anyway... :)
// search for 7 (stay at seven, we'll find it quick, return true)
if (vcurrent) {
if (list[vcurrent - 1]->value() >= v)
vcurrent = 0;
}
for (; vcurrent < vcount; vcurrent++) {
c = list[vcurrent]->value();
if (c == v)
return list[vcurrent];
else if (c > v)
return NULL;
}
vcurrent--;
return NULL;
}
// Note: this could be a little wierd since it's actually returning
// the style with value 'value' instead of list index 'value'
// Plus: it's going to define the style if it doesn't already exist!
//
// If you don't want extraneous styles getting inserted, be sure to
// use the find operator first. (I.e. If your reading a style value
// and the style didn't previously exist, all the style information
// will be undefined!
Flv_Style & Flv_Style_List::operator[](int value) {
Flv_Style *
p;
if (find(value)) // If it exists
return *(list[vcurrent]); // return it
p = new Flv_Style;
p->value(value);
insert(p);
return *p;
}
--- NEW FILE: Flv_List.cxx ---
// ======================================================================
// File: Flv_List.cxx - Flv_List implementation
// Program: Flv_List - FLTK List Widget
// Version: 0.1.0
// Started: 11/21/99
//
// Copyright (C) 1999 Laurence Charlton
//
// Description:
// Flv_List implements a scrollable list. No data is stored
// in the widget. Supports headers/footers, natively supports a single
// row height per list. Row grids can be turned on and off. Supports
// no scroll bars as well as horizontal/vertical automatic or always
// on scroll bars.
// Uses absolute row references.
//
// row -1 is defined as the row header
// row -2 is defined as the row footer
//
[...1400 lines suppressed...]
}
if (edit_when() == FLV_EDIT_ALWAYS)
vediting = true;
if (nr && vediting) {
get_style(s, nr);
if (s.editor_defined() && !s.locked()) {
veditor = s.editor();
if (veditor) {
edit_row = nr;
load_editor(veditor, nr);
veditor->damage(FL_DAMAGE_ALL);
veditor->hide();
veditor->show();
Fl::focus(veditor);
}
}
}
if (veditor && veditor->parent() != this)
veditor->parent(this);
}
--- NEW FILE: makedepend ---
--- NEW FILE: Fl_Toggle_Tree.cxx ---
#include <stdio.h>
#include <FL/Fl_Input.H>
#include <FL/Fl_Group.H>
#include <FL/Fl.H>
#ifdef PIXIL
#include <nxapp.h>
#endif
#include <Flek/Fl_Toggle_Node.H>
#include <Flek/Fl_Toggle_Tree.H>
#include "pixmaps/tt_open_icon.xpm"
#include "pixmaps/tt_closed_icon.xpm"
#include "pixmaps/tt_file_small.xpm"
#include "pixmaps/tt_folder_small.xpm"
void
Fl_Toggle_Tree::select_range(Fl_Toggle_Node * start,
Fl_Toggle_Node * end, int add)
{
Fl_Toggle_Node *tnode = (Fl_Toggle_Node *) first_;
Fl_Toggle_Node *selecting = 0;
selection_current_ = 0;
selection_count_ = 0;
traverse_start(tnode);
while (tnode) {
if (!selecting) {
if (tnode == start)
selecting = end;
else if (tnode == end)
selecting = start;
}
// add == 0 - pick one only (unpick rest)
// add == 1 - add picked (never unpick)
// add > 1 - toggle picked
int tmp = tnode->selected_;
if (selecting && (add > 1))
tnode->selected_ = !tnode->selected_;
else if (selecting)
tnode->selected_ = 1;
else if (add == 0)
tnode->selected_ = 0;
tnode->changed_ = tmp != tnode->selected_;
if (tnode == selecting)
selecting = 0;
tnode = traverse_forward();
}
current_ = 0;
if (selection_count() == 1)
current_ = selection();
}
Fl_Pixmap *
Fl_Toggle_Tree::s_closed_pixmap_ =
0;
Fl_Pixmap *
Fl_Toggle_Tree::s_opened_pixmap_ =
0;
static const int
no_columns[1] = {
0 };
Fl_Toggle_Tree::Fl_Toggle_Tree(int x, int y, int w, int h):
Fl_Toggle_Tree_Base(x, y, w, h)
{
pixmap_offset_ = 16;
label_offset_ = 40;
current_ = 0;
state_ = FL_TOGGLE_NONE;
closed_pixmap_ = 0;
opened_pixmap_ = 0;
if (s_closed_pixmap_ == 0) {
s_closed_pixmap_ = new Fl_Pixmap(tt_closed_icon_xpm);
}
if (s_opened_pixmap_ == 0) {
s_opened_pixmap_ = new Fl_Pixmap(tt_open_icon_xpm);
}
closed_pixmap(s_closed_pixmap_);
opened_pixmap(s_opened_pixmap_);
column_widths_ = no_columns;
column_char_ = '\t';
selection_i_ = 0;
selection_count_ = 0;
selection_current_ = 0;
#if FL_MAJOR_VERSION == 1
textfont_ = FL_HELVETICA;
#endif
textsize_ = 12;
#ifdef PIXIL
textcolor_ = NxApp::GlobalColor(APP_FG);
#else
textcolor_ = FL_BLACK;
#endif
edit_input_ = new Fl_Input(x, y, 0, 0);
edit_input_->box(FL_FLAT_BOX);
#ifdef PIXIL
edit_input_->color(NxApp::GlobalColor(APP_BG));
#else
edit_input_->color(FL_WHITE);
#endif
#if FL_MAJOR_VERSION == 1
edit_input_->textcolor(FL_BLACK);
edit_input_->textfont(textfont_);
edit_input_->textsize(textsize_);
#endif
edit_callback((Fl_Callback *) edit_default_callback, this);
edit_input_->
when(FL_WHEN_RELEASE | FL_WHEN_ENTER_KEY | FL_WHEN_NOT_CHANGED);
edit_input_->hide();
edit_on_reselect_ = 1;
#ifdef PIXIL
color(NxApp::GlobalColor(HILIGHT_LITE));
selection_color(NxApp::GlobalColor(HILIGHT));
selection_label_color(NxApp::GlobalColor(HILIGHT_TEXT));
alternate_color(NxApp::GlobalColor(HILIGHT_DARK));
#else
color(FL_WHITE);
selection_color(FL_BLACK);
selection_label_color(FL_YELLOW);
alternate_color(FL_LIGHT2);
#endif
trim_color(FL_LIGHT1);
draw_lines_ = 0;
#ifdef PIXIL
NxApp::DefaultFont(this);
#endif
}
Fl_Toggle_Tree::~Fl_Toggle_Tree()
{
delete edit_input_;
}
int cnt = 0;
void
Fl_Toggle_Tree::draw_node(int depth, int cy, Fl_Toggle_Node_Base * node)
{
Fl_Toggle_Node *tnode = (Fl_Toggle_Node *) node;
if (damage() == FL_DAMAGE_CHILD && !tnode->changed_ && damaged_ == 0) {
return;
}
tnode->changed_ = 0;
if (tnode->selected_) {
fl_color(selection_color());
fl_rectf(x(), cy + 1, w(), height_(tnode) - 1);
} else {
fl_color((cy - y()) & 1 ? color() : alternate_color());
fl_rectf(x(), cy + 1, w(), height_(tnode) - 1);
}
fl_color(trim_color());
fl_line(x(), cy, x() + w(), cy);
fl_color(FL_BLACK);
if (draw_lines_) {
int i;
Fl_Toggle_Node *n;
fl_xyline(x() + depth * 16 + 8, cy + 8, x() + (depth + 1) * 16,
cy + 8);
if (tnode->next_)
fl_xyline(x() + depth * 16 + 8, cy, x() + depth * 16 + 8,
cy + 16);
else
fl_xyline(x() + depth * 16 + 8, cy, x() + depth * 16 + 8, cy + 8);
for (i = depth - 1, n = (Fl_Toggle_Node *) tnode->up_; n; i--,
n = (Fl_Toggle_Node *) n->up_)
if (n->next_)
fl_xyline(x() + i * 16 + 8, cy, x() + i * 16 + 8, cy + 16);
}
if (tnode->can_open_) {
if (tnode->opened_)
opened_pixmap_->draw(x() + depth * 16, cy);
else
closed_pixmap_->draw(x() + depth * 16, cy);
}
#if FL_MAJOR_VERSION == 1
if (tnode->selected_)
textcolor(selection_label_color());
else
textcolor(labelcolor());
#endif
if (tnode->label_) {
int D = depth * 16 + label_offset_;
draw_label(tnode->label_, D, x(), cy, w(), 16);
}
if (tnode->pixmap_) {
tnode->pixmap_->draw(x() + depth * 16 + pixmap_offset_, cy + 1);
}
}
void
Fl_Toggle_Tree::draw_label(char *str, int indent, int x, int y, int w, int h)
{
const int *i = column_widths();
while (w > 6) { // do each tab-seperated field
int w1 = w; // width for this field
char *e = 0; // pointer to end of field or null if none
if (*i) { // find end of field and temporarily replace with 0
for (e = str; *e && *e != column_char(); e++);
if (*e) {
*e = 0;
w1 = *i++;
} else
e = 0;
}
int size = textsize();
Fl_Font font = textfont();
Fl_Color lcol = textcolor();
Fl_Align align = (Fl_Align) (FL_ALIGN_LEFT | FL_ALIGN_CLIP);
// check for all the @-lines recognized by XForms:
/* while (*str == format_char() && *++str && *str != format_char()) {
switch (*str++) {
case 'l': case 'L': size = 24; break;
case 'm': case 'M': size = 18; break;
case 's': size = 11; break;
case 'b': font = (Fl_Font)(font|FL_BOLD); break;
case 'i': font = (Fl_Font)(font|FL_ITALIC); break;
case 'f': case 't': font = FL_COURIER; break;
case 'c': align = FL_ALIGN_CENTER; break;
case 'r': align = FL_ALIGN_RIGHT; break;
case 'B':
fl_color((Fl_Color)strtol(str, &str, 10));
fl_rectf(x, y, w1, h);
break;
case 'C':
lcol = (Fl_Color)strtol(str, &str, 10);
break;
case 'F':
font = (Fl_Font)strtol(str, &str, 10);
break;
case 'N':
lcol = FL_INACTIVE_COLOR;
break;
case 'S':
size = strtol(str, &str, 10);
break;
case '-':
fl_color(FL_DARK3);
fl_line(x+3, y+h/2, x+w1-3, y+h/2);
fl_color(FL_LIGHT3);
fl_line(x+3, y+h/2+1, x+w1-3, y+h/2+1);
break;
case 'u':
case '_':
fl_color(lcol);
fl_line(x+3, y+h-1, x+w1-3, y+h-1);
break;
case '.':
goto BREAK;
case '@':
str--; goto BREAK;
}
}
BREAK:
*/
fl_font(font, size);
#if FL_MAJOR_VERSION == 1
# if FL_MINOR_VERSION == 0
if (!active_r())
lcol = inactive(lcol);
# else
if (!active_r())
lcol = fl_inactive(lcol);
# endif
#endif
// if (((FL_BLINE*)v)->flags & SELECTED)
// lcol = contrast(lcol, selection_color());
fl_color(lcol);
fl_draw(str, x + indent, y + 1, w1 - indent, h + 1, align);
if (!e)
break; // no more fields...
*e = column_char(); // put the seperator back
x += w1;
w -= w1;
str = e + 1;
indent = 0;
}
}
void
Fl_Toggle_Tree::open(Fl_Toggle_Node * node)
{
if (node->opened_ == 1)
return;
int th = Fl_Toggle_Tree_Base::open(node);
damaged_ = node;
if (th) {
damage(FL_DAMAGE_TREE);
} else {
damage(FL_DAMAGE_CHILD);
}
if (th) {
resize(x(), y(), w(), h() + th);
parent()->damage(FL_DAMAGE_CHILD);
}
}
void
Fl_Toggle_Tree::close(Fl_Toggle_Node * node)
{
if (node->opened_ == 0)
return;
int th = Fl_Toggle_Tree_Base::close(node);
damaged_ = node;
if (th) {
damage(FL_DAMAGE_TREE);
resize(x(), y(), w(), h() - th);
parent()->damage(FL_DAMAGE_SCROLL);
} else {
damage(FL_DAMAGE_CHILD);
}
}
void
Fl_Toggle_Tree::edit(Fl_Toggle_Node * t, int cx, int cy)
{
// printf("edit\n");
if (!edit_input_->visible() && t) {
// printf("%d %d %d %d %s\n",cx, cy, w()-(cx-x()), height_(t), t->label());
edit_input_->resize(cx - 3, cy + 1, w() - (cx - 3 - x()),
height_(t) - 1);
edit_input_->value(t->label());
edit_input_->show();
edit_input_->take_focus();
}
}
void
Fl_Toggle_Tree::edit_default_callback(Fl_Input *, void *ptr)
{
// printf("default_edit_cb\n");
Fl_Toggle_Tree *tree = (Fl_Toggle_Tree *) ptr;
tree->end_edit();
}
void
Fl_Toggle_Tree::end_edit(void)
{
// printf("end_edit\n");
if (current_) {
((Fl_Toggle_Node *) current_)->label(strdup(edit_input_->value()));
}
edit_input_->hide();
damaged_ = current_;
damage(FL_DAMAGE_CHILD);
}
int
Fl_Toggle_Tree::handle(int event)
{
// printf("event: %d\n",event);
static Fl_Toggle_Node *prev = 0;
switch (event) {
case FL_ENTER:
return 1;
case FL_KEYBOARD:
return 0;
case FL_SHORTCUT:
return 0;
case FL_RELEASE:{
if (edit_input_->visible()) {
end_edit();
}
int depth;
int cy;
Fl_Toggle_Node *tnode =
(Fl_Toggle_Node *) Fl_Toggle_Tree_Base::find(Fl::event_y(),
depth, cy);
if (Fl::event_x() < x() + depth * 16 + 16) {
if (tnode->opened_) {
current_ = tnode;
state_ = FL_TOGGLE_OPENED;
do_callback();
close(tnode);
} else {
current_ = tnode;
state_ = FL_TOGGLE_CLOSED;
do_callback();
open(tnode);
}
} else {
if (Fl::event_state(FL_SHIFT)) {
if (prev == 0)
prev = tnode;
select_range(prev, tnode, 1);
//current_ = 0;
state_ = FL_TOGGLE_SELECT;
do_callback();
} else if (Fl::event_state(FL_CTRL)) {
//if (!tnode->selected_)
select_range(tnode, tnode, Fl::event_state(FL_CTRL));
/*
else {
selection_current_ = NULL;
tnode->selected_ = 0;
tnode->changed_ = 1;
tnode = 0;
}
current_ = 0;
*/
state_ = FL_TOGGLE_SELECT;
do_callback();
} else {
select_range(tnode, tnode, 0);
state_ =
Fl::event_clicks()? FL_TOGGLE_HIT : FL_TOGGLE_SELECT;
if (tnode == current_ && state_ == FL_TOGGLE_SELECT) {
state_ = FL_TOGGLE_RESELECT;
}
//current_ = tnode;
if (state_ == FL_TOGGLE_RESELECT && edit_on_reselect_) {
edit(tnode, x() + depth * 16 + label_offset_, cy);
}
do_callback();
}
damaged_ = 0;
damage(FL_DAMAGE_CHILD);
prev = tnode;
}
}
return 1;
}
return 1;
}
Fl_Toggle_Node *
Fl_Toggle_Tree::selection(void)
{
if (current_ == 0)
current_ = traverse_start();
else {
traverse_start(current_);
current_ = traverse_forward();
}
while (current_) {
if (((Fl_Toggle_Node *) current_)->selected_) {
return (Fl_Toggle_Node *) current_;
}
current_ = traverse_forward();
}
return 0;
}
int
Fl_Toggle_Tree::selection_count(void)
{
if (selection_current_ == 0)
selection_count_ = 0;
if (selection_count_)
return selection_count_;
Fl_Toggle_Node *t;
t = traverse_start();
while (t) {
if (t->selected_) {
selection_count_++;
}
t = traverse_forward();
}
return selection_count_;
}
Fl_Toggle_Node *
Fl_Toggle_Tree::selection(int i)
{
int backwards = 0;
if (selection_current_ == 0) {
selection_current_ = traverse_start();
selection_i_ = 0;
} else {
traverse_start(selection_current_);
if (i > selection_i_) {
selection_current_ = traverse_forward();
selection_i_++;
} else if (i < selection_i_) {
selection_current_ = traverse_backward();
selection_i_--;
backwards = 1;
}
}
if (backwards) {
while (selection_current_) {
//printf("traversed bw to:%s\n",selection_current_->label());
if (selection_current_->selected_) {
if (i == selection_i_) {
return selection_current_;
}
selection_i_--;
}
selection_current_ = traverse_backward();
}
} else {
while (selection_current_) {
if (selection_current_->selected_) {
if (i == selection_i_) {
return selection_current_;
}
selection_i_++;
}
selection_current_ = traverse_forward();
}
}
return 0;
}
void
Fl_Toggle_Tree::opened_pixmap(Fl_Pixmap * a)
{
if (opened_pixmap_ && opened_pixmap_ != s_opened_pixmap_) {
delete opened_pixmap_;
}
opened_pixmap_ = a;
}
void
Fl_Toggle_Tree::closed_pixmap(Fl_Pixmap * a)
{
if (closed_pixmap_ && closed_pixmap_ != s_closed_pixmap_) {
delete closed_pixmap_;
}
closed_pixmap_ = a;
}
int
Fl_Toggle_Tree::remove(char *a)
{
Fl_Toggle_Node *curr;
curr = find(a);
if (curr)
return remove(curr);
return 0;
}
int
Fl_Toggle_Tree::remove(void *a)
{
Fl_Toggle_Node *curr;
curr = find(a);
if (curr)
return remove(curr);
return 0;
}
Fl_Toggle_Node *
Fl_Toggle_Tree::find(char *a)
{
Fl_Toggle_Node *curr = traverse_start();
while (curr) {
if (curr->label()) {
if (!strcmp(curr->label(), a)) {
return curr;
}
}
curr = traverse_forward();
}
return 0;
}
Fl_Toggle_Node *
Fl_Toggle_Tree::find(void *a)
{
Fl_Toggle_Node *curr = traverse_start();
while (curr) {
if (curr->label()) {
if (curr->user_data() == a) {
return curr;
}
}
curr = traverse_forward();
}
return 0;
}
int
Fl_Toggle_Tree::sort_by_label(Fl_Toggle_Node_Base * a,
Fl_Toggle_Node_Base * b)
{
return strcmp(((Fl_Toggle_Node *) a)->label(),
((Fl_Toggle_Node *) b)->label());
}
void
Fl_Toggle_Tree::edit_callback(Fl_Callback * c, void *p)
{
edit_input_->callback((Fl_Callback *) c, p);
}
void
Fl_Toggle_Tree::edit_callback(Fl_Callback * c)
{
edit_input_->callback((Fl_Callback *) c);
}
void
Fl_Toggle_Tree::edit_callback(Fl_Callback0 * c)
{
edit_input_->callback(c);
}
void
Fl_Toggle_Tree::edit_callback(Fl_Callback1 * c, long p)
{
edit_input_->callback(c, p);
}
--- NEW FILE: Fl_Stock.cxx ---
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Pixmap.H>
#include <FL/fl_draw.H>
#include <Flek/Fl_Stock.H>
#include "pixmaps/stock_button_ok.xpm"
#include "pixmaps/stock_button_cancel.xpm"
#include "pixmaps/stock_button_yes.xpm"
#include "pixmaps/stock_button_no.xpm"
#include "pixmaps/stock_button_apply.xpm"
#include "pixmaps/stock_button_close.xpm"
#include "pixmaps/stock_add.xpm"
#include "pixmaps/stock_bottom.xpm"
#include "pixmaps/stock_top.xpm"
#include "pixmaps/stock_clear.xpm"
#include "pixmaps/stock_down_arrow.xpm"
#include "pixmaps/stock_up_arrow.xpm"
#include "pixmaps/stock_left_arrow.xpm"
#include "pixmaps/stock_right_arrow.xpm"
#include "pixmaps/stock_remove.xpm"
#include "pixmaps/stock_open.xpm"
#include "pixmaps/stock_new.xpm"
#include "pixmaps/stock_copy.xpm"
#include "pixmaps/stock_cut.xpm"
#include "pixmaps/stock_exec.xpm"
#include "pixmaps/stock_first.xpm"
#include "pixmaps/stock_help.xpm"
#include "pixmaps/stock_last.xpm"
#include "pixmaps/stock_save.xpm"
#include "pixmaps/stock_save_as.xpm"
#include "pixmaps/stock_search.xpm"
#include "pixmaps/stock_search_replace.xpm"
Fl_Stock_Button::Fl_Stock_Button(int x, int y, int w, int h, const char *l):
Fl_Button(x, y, w, h, l)
{
// Scheme this :
#if FL_MAJOR_VERSION == 2
label_size(10);
#else
labelsize(10);
#endif
//color (52);
box(FL_FLAT_BOX);
}
void
Fl_Stock_Button::draw()
{
if (type() == FL_HIDDEN_BUTTON)
return;
#if FL_MAJOR_VERSION == 2
Fl_Color col = draw_button(flags());
#else
Fl_Color col = value()? selection_color() : color();
# if FL_MINOR_VERSION == 0
draw_box(value()? (down_box()? down_box() : down(box())) : box(), col);
# else
draw_box(value()? (down_box()? down_box() : fl_down(box())) : box(), col);
# endif
#endif
draw_label(x(), y(), w(), h(), col, flags());
}
void
Fl_Stock_Button::draw_label(int X, int Y, int W, int H,
Fl_Color c, Fl_Flags f)
{
int tw = 0, th = 0;
int iw = 0, ih = 0;
int w, h;
Fl_Image *image_ = image();
const char *label_ = label();
if (image_)
#if FL_MAJOR_VERSION == 2
image_->measure(iw, ih);
#else
# if FL_MINOR_VERSION == 0
fl_measure_pixmap(image_->data, iw, ih);
# else
fl_measure_pixmap(image_->data(), iw, ih);
# endif
#endif
if (label_) {
// Note: should tw be turned into an int so soon? bdl
// Anyway, I added the (int) to quiet the compiler.
#if FL_MAJOR_VERSION == 2
fl_font(label_font(), label_size());
tw = (int) fl_width(label_);
th = label_size();
#else
fl_font(labelfont(), labelsize());
tw = (int) fl_width(label_);
th = labelsize();
#endif
}
int spacer = 5;
if ((f & FL_TEXT_ALIGN_TOP) || (f & FL_TEXT_ALIGN_BOTTOM)) {
h = th + ih + spacer;
w = ((tw > iw) ? tw : iw); // max
} else {
w = tw + iw + spacer;
h = ((th > ih) ? th : ih); // max
}
int dx, dy;
dx = X + (W / 2) - (w / 2);
dy = Y + (H / 2) - (h / 2);
if (f & FL_ALIGN_TOP) {
if (f & FL_ALIGN_INSIDE)
dy = Y;
else
dy = Y - h;
}
if (f & FL_ALIGN_BOTTOM) {
if (f & FL_ALIGN_INSIDE)
dy = Y + H - h;
else
dy = Y + H;
}
if (f & FL_ALIGN_LEFT) {
if (f & FL_ALIGN_INSIDE)
dx = X;
else
dx = X - dx;
}
if (f & FL_ALIGN_RIGHT) {
if (f & FL_ALIGN_INSIDE)
dx = X + W - w;
else
dx = X + W;
}
int tdx = dx, tdy = dy;
int idx = dx, idy = dy;
if (f & FL_TEXT_ALIGN_TOP) {
idy = dy + th + spacer;
idx += (w - iw) / 2;
tdx += (w - tw) / 2;
} else if (f & FL_TEXT_ALIGN_BOTTOM) {
tdy = dy + ih + spacer;
idx += (w - iw) / 2;
tdx += (w - tw) / 2;
} else if (f & FL_TEXT_ALIGN_LEFT) {
idx = dx + tw + spacer;
idy += (h - ih) / 2;
tdy += (h - th) / 2;
} else // (f & FL_TEXT_ALIGN_RIGHT) // default
{
tdx = dx + iw + spacer;
idy += (h - ih) / 2;
tdy += (h - th) / 2;
}
int a = 0;
if (!active_r())
a = FL_INACTIVE;
if (image_) {
#if FL_MAJOR_VERSION == 2
fl_color((f & FL_INACTIVE) ? fl_inactive(c) : c);
image_->draw(idx, idy, iw, ih, 0, 0);
#else
image_->draw(idx, idy, iw, ih, a);
#endif
//printf ("image = %d, %d, %d, %d\n", idx, idy, iw, ih);
}
if (label_ && *label_) {
#if FL_MAJOR_VERSION == 2
fl_font(label_font(), label_size());
//if (flags() & FL_SHORTCUT_LABEL) fl_draw_shortcut = 1;
//printf ("label = %d, %d, %d, %d\n", tdx, tdy, tw, th);
label_type()->draw(label_, tdx, tdy, tw, th, c, a);
//fl_draw_shortcut = 0;
#else
fl_font(labelfont(), labelsize());
Fl_Widget::draw_label(tdx, tdy, tw, th, (Fl_Align) a);
#endif
}
}
static Fl_Pixmap *Stock_Button_Ok_Image = 0;
Fl_Stock_Button_Ok::Fl_Stock_Button_Ok(int x, int y, int w, int h,
const char *l):
Fl_Stock_Button(x, y, w, h, l)
{
if (!Stock_Button_Ok_Image)
Stock_Button_Ok_Image = new Fl_Pixmap(stock_button_ok_xpm);
image(Stock_Button_Ok_Image);
box(FL_THIN_UP_BOX);
}
static Fl_Pixmap *Stock_Button_Cancel_Image = 0;
Fl_Stock_Button_Cancel::Fl_Stock_Button_Cancel(int x, int y, int w, int h,
const char *l):
Fl_Stock_Button(x, y, w, h, l)
{
if (!Stock_Button_Cancel_Image)
Stock_Button_Cancel_Image = new Fl_Pixmap(stock_button_cancel_xpm);
image(Stock_Button_Cancel_Image);
box(FL_THIN_UP_BOX);
}
static Fl_Pixmap *Stock_Button_Yes_Image = 0;
Fl_Stock_Button_Yes::Fl_Stock_Button_Yes(int x, int y, int w, int h,
const char *l):
Fl_Stock_Button(x, y, w, h, l)
{
if (!Stock_Button_Yes_Image)
Stock_Button_Yes_Image = new Fl_Pixmap(stock_button_yes_xpm);
image(Stock_Button_Yes_Image);
box(FL_THIN_UP_BOX);
}
static Fl_Pixmap *Stock_Button_No_Image = 0;
Fl_Stock_Button_No::Fl_Stock_Button_No(int x, int y, int w, int h,
const char *l):
Fl_Stock_Button(x, y, w, h, l)
{
if (!Stock_Button_No_Image)
Stock_Button_No_Image = new Fl_Pixmap(stock_button_no_xpm);
image(Stock_Button_No_Image);
box(FL_THIN_UP_BOX);
}
static Fl_Pixmap *Stock_Button_Close_Image = 0;
Fl_Stock_Button_Close::Fl_Stock_Button_Close(int x, int y, int w, int h,
const char *l):
Fl_Stock_Button(x, y, w, h, l)
{
if (!Stock_Button_Close_Image)
Stock_Button_Close_Image = new Fl_Pixmap(stock_button_close_xpm);
image(Stock_Button_Close_Image);
box(FL_THIN_UP_BOX);
}
static Fl_Pixmap *Stock_Button_Apply_Image = 0;
Fl_Stock_Button_Apply::Fl_Stock_Button_Apply(int x, int y, int w, int h,
const char *l):
Fl_Stock_Button(x, y, w, h, l)
{
if (!Stock_Button_Apply_Image)
Stock_Button_Apply_Image = new Fl_Pixmap(stock_button_apply_xpm);
image(Stock_Button_Apply_Image);
box(FL_THIN_UP_BOX);
}
static Fl_Pixmap *Stock_Button_Add_Image = 0;
Fl_Stock_Button_Add::Fl_Stock_Button_Add(int x, int y, int w, int h,
const char *l):
Fl_Stock_Button(x, y, w, h, l)
{
if (!Stock_Button_Add_Image)
Stock_Button_Add_Image = new Fl_Pixmap(stock_add_xpm);
image(Stock_Button_Add_Image);
set_flag(FL_TEXT_ALIGN_BOTTOM);
}
static Fl_Pixmap *Stock_Button_Bottom_Image = 0;
Fl_Stock_Button_Bottom::Fl_Stock_Button_Bottom(int x, int y, int w, int h,
const char *l):
Fl_Stock_Button(x, y, w, h, l)
{
if (!Stock_Button_Bottom_Image)
Stock_Button_Bottom_Image = new Fl_Pixmap(stock_bottom_xpm);
image(Stock_Button_Bottom_Image);
set_flag(FL_TEXT_ALIGN_BOTTOM);
}
static Fl_Pixmap *Stock_Button_Clear_Image = 0;
Fl_Stock_Button_Clear::Fl_Stock_Button_Clear(int x, int y, int w, int h,
const char *l):
Fl_Stock_Button(x, y, w, h, l)
{
if (!Stock_Button_Clear_Image)
Stock_Button_Clear_Image = new Fl_Pixmap(stock_clear_xpm);
image(Stock_Button_Clear_Image);
set_flag(FL_TEXT_ALIGN_BOTTOM);
}
static Fl_Pixmap *Stock_Button_Down_Image = 0;
Fl_Stock_Button_Down::Fl_Stock_Button_Down(int x, int y, int w, int h,
const char *l):
Fl_Stock_Button(x, y, w, h, l)
{
if (!Stock_Button_Down_Image)
Stock_Button_Down_Image = new Fl_Pixmap(stock_down_arrow_xpm);
image(Stock_Button_Down_Image);
set_flag(FL_TEXT_ALIGN_BOTTOM);
}
static Fl_Pixmap *Stock_Button_Up_Image = 0;
Fl_Stock_Button_Up::Fl_Stock_Button_Up(int x, int y, int w, int h,
const char *l):
Fl_Stock_Button(x, y, w, h, l)
{
if (!Stock_Button_Up_Image)
Stock_Button_Up_Image = new Fl_Pixmap(stock_up_arrow_xpm);
image(Stock_Button_Up_Image);
set_flag(FL_TEXT_ALIGN_BOTTOM);
}
static Fl_Pixmap *Stock_Button_Left_Image = 0;
Fl_Stock_Button_Left::Fl_Stock_Button_Left(int x, int y, int w, int h,
const char *l):
Fl_Stock_Button(x, y, w, h, l)
{
if (!Stock_Button_Left_Image)
Stock_Button_Left_Image = new Fl_Pixmap(stock_left_arrow_xpm);
image(Stock_Button_Left_Image);
set_flag(FL_TEXT_ALIGN_BOTTOM);
}
static Fl_Pixmap *Stock_Button_Right_Image = 0;
Fl_Stock_Button_Right::Fl_Stock_Button_Right(int x, int y, int w, int h,
const char *l):
Fl_Stock_Button(x, y, w, h, l)
{
if (!Stock_Button_Right_Image)
Stock_Button_Right_Image = new Fl_Pixmap(stock_right_arrow_xpm);
image(Stock_Button_Right_Image);
set_flag(FL_TEXT_ALIGN_BOTTOM);
}
static Fl_Pixmap *Stock_Button_Previous_Image = 0;
Fl_Stock_Button_Previous::Fl_Stock_Button_Previous(int x, int y, int w, int h,
const char *l):
Fl_Stock_Button(x, y, w, h, l)
{
if (!Stock_Button_Previous_Image)
Stock_Button_Previous_Image = new Fl_Pixmap(stock_left_arrow_xpm);
image(Stock_Button_Previous_Image);
set_flag(FL_TEXT_ALIGN_BOTTOM);
}
static Fl_Pixmap *Stock_Button_Next_Image = 0;
Fl_Stock_Button_Next::Fl_Stock_Button_Next(int x, int y, int w, int h,
const char *l):
Fl_Stock_Button(x, y, w, h, l)
{
if (!Stock_Button_Next_Image)
Stock_Button_Next_Image = new Fl_Pixmap(stock_right_arrow_xpm);
image(Stock_Button_Next_Image);
set_flag(FL_TEXT_ALIGN_BOTTOM);
}
static Fl_Pixmap *Stock_Button_New_Image = 0;
Fl_Stock_Button_New::Fl_Stock_Button_New(int x, int y, int w, int h,
const char *l):
Fl_Stock_Button(x, y, w, h, l)
{
if (!Stock_Button_New_Image)
Stock_Button_New_Image = new Fl_Pixmap(stock_new_xpm);
image(Stock_Button_New_Image);
set_flag(FL_TEXT_ALIGN_BOTTOM);
}
static Fl_Pixmap *Stock_Button_Open_Image = 0;
Fl_Stock_Button_Open::Fl_Stock_Button_Open(int x, int y, int w, int h,
const char *l):
Fl_Stock_Button(x, y, w, h, l)
{
if (!Stock_Button_Open_Image)
Stock_Button_Open_Image = new Fl_Pixmap(stock_open_xpm);
image(Stock_Button_Open_Image);
set_flag(FL_TEXT_ALIGN_BOTTOM);
}
static Fl_Pixmap *Stock_Button_Remove_Image = 0;
Fl_Stock_Button_Remove::Fl_Stock_Button_Remove(int x, int y, int w, int h,
const char *l):
Fl_Stock_Button(x, y, w, h, l)
{
if (!Stock_Button_Remove_Image)
Stock_Button_Remove_Image = new Fl_Pixmap(stock_remove_xpm);
image(Stock_Button_Remove_Image);
set_flag(FL_TEXT_ALIGN_BOTTOM);
}
static Fl_Pixmap *Stock_Button_Top_Image = 0;
Fl_Stock_Button_Top::Fl_Stock_Button_Top(int x, int y, int w, int h,
const char *l):
Fl_Stock_Button(x, y, w, h, l)
{
if (!Stock_Button_Top_Image)
Stock_Button_Top_Image = new Fl_Pixmap(stock_top_xpm);
image(Stock_Button_Top_Image);
set_flag(FL_TEXT_ALIGN_BOTTOM);
}
static Fl_Pixmap *Stock_Button_Copy_Image = 0;
Fl_Stock_Button_Copy::Fl_Stock_Button_Copy(int x, int y, int w, int h,
const char *l):
Fl_Stock_Button(x, y, w, h, l)
{
if (!Stock_Button_Copy_Image)
Stock_Button_Copy_Image = new Fl_Pixmap(stock_copy_xpm);
image(Stock_Button_Copy_Image);
set_flag(FL_TEXT_ALIGN_BOTTOM);
}
static Fl_Pixmap *Stock_Button_Cut_Image = 0;
Fl_Stock_Button_Cut::Fl_Stock_Button_Cut(int x, int y, int w, int h,
const char *l):
Fl_Stock_Button(x, y, w, h, l)
{
if (!Stock_Button_Cut_Image)
Stock_Button_Cut_Image = new Fl_Pixmap(stock_cut_xpm);
image(Stock_Button_Cut_Image);
set_flag(FL_TEXT_ALIGN_BOTTOM);
}
static Fl_Pixmap *Stock_Button_Exec_Image = 0;
Fl_Stock_Button_Exec::Fl_Stock_Button_Exec(int x, int y, int w, int h,
const char *l):
Fl_Stock_Button(x, y, w, h, l)
{
if (!Stock_Button_Exec_Image)
Stock_Button_Exec_Image = new Fl_Pixmap(stock_exec_xpm);
image(Stock_Button_Exec_Image);
set_flag(FL_TEXT_ALIGN_BOTTOM);
}
static Fl_Pixmap *Stock_Button_First_Image = 0;
Fl_Stock_Button_First::Fl_Stock_Button_First(int x, int y, int w, int h,
const char *l):
Fl_Stock_Button(x, y, w, h, l)
{
if (!Stock_Button_First_Image)
Stock_Button_First_Image = new Fl_Pixmap(stock_first_xpm);
image(Stock_Button_First_Image);
set_flag(FL_TEXT_ALIGN_BOTTOM);
}
static Fl_Pixmap *Stock_Button_Help_Image = 0;
Fl_Stock_Button_Help::Fl_Stock_Button_Help(int x, int y, int w, int h,
const char *l):
Fl_Stock_Button(x, y, w, h, l)
{
if (!Stock_Button_Help_Image)
Stock_Button_Help_Image = new Fl_Pixmap(stock_help_xpm);
image(Stock_Button_Help_Image);
set_flag(FL_TEXT_ALIGN_BOTTOM);
}
static Fl_Pixmap *Stock_Button_Last_Image = 0;
Fl_Stock_Button_Last::Fl_Stock_Button_Last(int x, int y, int w, int h,
const char *l):
Fl_Stock_Button(x, y, w, h, l)
{
if (!Stock_Button_Last_Image)
Stock_Button_Last_Image = new Fl_Pixmap(stock_last_xpm);
image(Stock_Button_Last_Image);
set_flag(FL_TEXT_ALIGN_BOTTOM);
}
static Fl_Pixmap *Stock_Button_Save_Image = 0;
Fl_Stock_Button_Save::Fl_Stock_Button_Save(int x, int y, int w, int h,
const char *l):
Fl_Stock_Button(x, y, w, h, l)
{
if (!Stock_Button_Save_Image)
Stock_Button_Save_Image = new Fl_Pixmap(stock_save_xpm);
image(Stock_Button_Save_Image);
set_flag(FL_TEXT_ALIGN_BOTTOM);
}
static Fl_Pixmap *Stock_Button_Save_As_Image = 0;
Fl_Stock_Button_Save_As::Fl_Stock_Button_Save_As(int x, int y, int w, int h,
const char *l):
Fl_Stock_Button(x, y, w, h, l)
{
if (!Stock_Button_Save_As_Image)
Stock_Button_Save_As_Image = new Fl_Pixmap(stock_save_as_xpm);
image(Stock_Button_Save_As_Image);
set_flag(FL_TEXT_ALIGN_BOTTOM);
}
static Fl_Pixmap *Stock_Button_Search_Image = 0;
Fl_Stock_Button_Search::Fl_Stock_Button_Search(int x, int y, int w, int h,
const char *l):
Fl_Stock_Button(x, y, w, h, l)
{
if (!Stock_Button_Search_Image)
Stock_Button_Search_Image = new Fl_Pixmap(stock_search_xpm);
image(Stock_Button_Search_Image);
set_flag(FL_TEXT_ALIGN_BOTTOM);
}
static Fl_Pixmap *Stock_Button_Search_Replace_Image = 0;
Fl_Stock_Button_Search_Replace::Fl_Stock_Button_Search_Replace(int x, int y,
int w, int h,
const char *l):
Fl_Stock_Button(x, y, w, h, l)
{
if (!Stock_Button_Search_Replace_Image)
Stock_Button_Search_Replace_Image =
new Fl_Pixmap(stock_search_replace_xpm);
image(Stock_Button_Search_Replace_Image);
set_flag(FL_TEXT_ALIGN_BOTTOM);
}
--- NEW FILE: Fl_Dockable_Window.cxx ---
#include <FL/Fl.H>
#include <FL/fl_draw.H>
#include <FL/Fl_Pack.H>
#include <Flek/Fl_Dockable_Window.H>
#include "pixmaps/dock_grip_tile.xpm"
#include <stdio.h>
long
Fl_Dockable_Window::gripper_width =
10;
Fl_Dockable_Window *
Fl_Dockable_Window::current =
0;
void
Fl_Gripper::draw()
{
if (_grippertype & FL_DRAGABLE) {
// Draw the Gnome style gripper:
#if FL_MAJOR_VERSION == 1
Fl_Color col = value()? selection_color() : color();
draw_box(box(), col);
#else
draw_box();
#endif
// draw_label();
#if FL_MAJOR_VERSION == 1
fl_push_clip(x() + 1, y() + 1, w() - 3, h() - 3);
#else
fl_clip(x() + 1, y() + 1, w() - 3, h() - 3);
#endif
for (int i = 0; i < w(); i += 6)
for (int j = 0; j < h(); j += 6)
fl_draw_pixmap(grip_tile_xpm, i + 2, j + 2);
fl_pop_clip();
} else if (_grippertype & FL_SHOVABLE)
Fl_Button::draw();
}
int
Fl_Gripper::handle(int event)
{
int rval = Fl_Button::handle(event);
int x_drag, y_drag;
Fl_Dockable_Window *group = (Fl_Dockable_Window *) parent();
Fl_Dockable_Window::current = group;
switch (event) {
case FL_PUSH:
// Set the Fl_Dockable_Window that may eventually get docked.
if (group->window() && (group->window()->modal()))
return 1;
if (_grippertype & FL_DRAGABLE) {
Fl_Dockable_Window::current = (Fl_Dockable_Window *) parent();
x_down = Fl::event_x_root();
y_down = Fl::event_y_root();
x_first = Fl_Dockable_Window::current->x_root();
y_first = Fl_Dockable_Window::current->y_root();
}
return 1;
case FL_DRAG:
case FL_RELEASE:{
int x_up = Fl::event_x();
int y_up = Fl::event_y();
Fl_Pack *parent = (Fl_Pack *) group->parent();
if ((_grippertype & FL_SHOVABLE) && (event & FL_RELEASE)
&& (group->parent()) && (x_up <= w() + 2)
&& (y_up <= h() + 2)) {
#if 0
int content_location = 0;
// Apparently there is a bug somewhere in this algorithm. bdl
for (int i = 0; i < parent->children(); i++) {
if (parent->child(i)->type() != FL_WINDOW) {
content_location = i;
}
}
int group_location = parent->find(group);
int new_location =
content_location + (content_location - group_location) +
1;
#else
// Simpler algorithm. bdl
// Shove it down until it hits the bottom, then shove it
// up to the top.
int new_location = parent->find(group) + 1;
if (new_location >= parent->children())
new_location = 0;
#endif
parent->insert(*((Fl_Widget *) group), new_location);
parent->redraw();
return 1;
}
if (!(_grippertype & FL_DRAGABLE))
return 1;
if (group->window() && group->window()->modal())
return 1;
x_drag = Fl::event_x_root();
y_drag = Fl::event_y_root();
int delta = ((x_drag + y_drag) - (x_down + y_down));
if (delta < 0)
delta *= -1;
if (group->parent()) {
if (delta > (FL_DOCK_DELTA * 2)) {
x_first = Fl_Dockable_Window::current->x_root();
y_first = Fl_Dockable_Window::current->y_root();
group->undock((x_first + (x_drag - x_down)),
(y_first + (y_drag - y_down)));
// Once undocked, give the window focus and continue dragging.
take_focus();
Fl::pushed(this);
}
} else {
// See if anyone want to dock with me..
for (Fl_Window * o = Fl::first_window(); o;
o = Fl::next_window(o)) {
int ex = o->x_root();
int ey = o->y_root();
int ew = o->w();
int eh = o->h();
int cx = Fl::event_x_root();
int cy = Fl::event_y_root();
if (o->visible() && (cx > ex) && (cy > ey)
&& (cx < (ew + ex)) && (cy < (eh + ey))) {
// Send the host window a message that we want to dock with it.
// printf ("Fl_Dockable_Window:: Attempting to dock.\n");
if (Fl::handle(FL_DOCK, o)) {
// printf ("Fl_Dockable_Window:: Docking.\n");
// redraw();
if (event != FL_RELEASE) {
// I want to send JUST the drag event. Not push!
// Right now it just stops dragging after a successful dock.
// take_focus();
// Fl::pushed(this);
}
break;
}
}
}
}
// Isn't it docked?
if (!group->docked())
// Move the window around following the pointer.
group->position((x_first + (x_drag - x_down)),
(y_first + (y_drag - y_down)));
}
return 1;
}
return rval;
}
void
Fl_Gripper::grippertype(unsigned char t)
{
_grippertype = t;
}
unsigned char
Fl_Gripper::grippertype()
{
return _grippertype;
}
Fl_Dockable_Window::Fl_Dockable_Window(int x, int y, int w, int h,
const char *l)
: Fl_Window(x, y, w, h, l)
{
create_dockable_window();
}
Fl_Dockable_Window::Fl_Dockable_Window(int w, int h, const char *l)
:
Fl_Window(w, h, l)
{
create_dockable_window();
}
void
Fl_Dockable_Window::create_dockable_window()
{
clear_border();
uw_ = w();
uh_ = h();
gripper = new Fl_Gripper(0, 0, gripper_width, h());
_docked = 0;
contents = new Fl_Window(gripper_width, 0, w(), h());
resizable(contents);
grippertype(FL_DRAGABLE);
begin();
}
void
Fl_Dockable_Window::show()
{
Fl_Window::show();
gripper->show();
}
int
Fl_Dockable_Window::handle(int event)
{
int rval;
switch (event) {
case FL_SHOW:
rval = Fl_Window::handle(event);
contents->show();
return rval;
case FL_HIDE:
contents->hide();
break;
}
return Fl_Window::handle(event);
}
void
Fl_Dockable_Window::undock(int x, int y)
{
_docked = 0;
// printf ("undocking..\n");
if (parent()) {
Fl_Group *group = (Fl_Group *) parent();
hide();
group->remove((Fl_Widget *) this);
// printf ("Let dock handle the event..\n");
// Give the dock an opportunity to handle the event.
Fl::handle(FL_UNDOCK, group->window());
// group->redraw();
if ((x > -1) && (y > -1))
position(x, y);
// printf("positioned x, y = %d,%d", x, y);
size(uw_, uh_);
// printf ("show me!!\n");
show();
// layout();
}
}
void
Fl_Dockable_Window::grippertype(unsigned char t)
{
// Set the type of the gripper.
gripper->grippertype(t);
if ((t & FL_DRAGABLE) || (t & FL_SHOVABLE)) {
contents->resize(gripper_width, 0, w(), h());
gripper->show();
} else {
contents->resize(0, 0, w(), h());
gripper->hide();
}
}
unsigned char
Fl_Dockable_Window::grippertype()
{
return gripper->grippertype();
}
--- NEW FILE: FJPEG.cxx ---
#include <Flek/math.H>
#include <Flek/FFile.H>
#include <Flek/FImage.H>
#include <Flek/FJPEG.H>
extern "C"
{
#include <jpeglib.h>
}
/*
* Code to read JPEG images. Boiler plate stuff snarfed from the
* libjpeg examples.
*/
FImage *
FJPEG::read(char *filename)
{
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
FILE *infile;
int row_stride;
if ((infile = fopen(filename, "rb")) == NULL) {
fprintf(stderr, "can't open %s\n", filename);
return 0;
}
// Step 1: allocate and initialize JPEG decompression object
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
// Step 2: specify data source (eg, a file)
jpeg_stdio_src(&cinfo, infile);
// Step 3: read file parameters with jpeg_read_header()
(void) jpeg_read_header(&cinfo, TRUE);
// Step 5: Start decompressor
(void) jpeg_start_decompress(&cinfo);
FImage *rval =
new FImage(cinfo.output_width, cinfo.output_height,
cinfo.output_components);
row_stride = cinfo.output_width * cinfo.output_components;
while (cinfo.output_scanline < cinfo.output_height) {
unsigned char *i[1];
i[0] =
*(rval->begin(cinfo.output_height - cinfo.output_scanline - 1));
(void) jpeg_read_scanlines(&cinfo, i, 1);
}
// Step 7: Finish decompression
(void) jpeg_finish_decompress(&cinfo);
// Step 8: Release JPEG decompression object and allocated memory
jpeg_destroy_decompress(&cinfo);
fclose(infile);
return rval;
}
int
FJPEG::write(char *filename, FImage * data, int quality)
{
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
if (data->channels() == 3)
cinfo.in_color_space = JCS_RGB;
else if (data->channels() == 1)
cinfo.in_color_space = JCS_GRAYSCALE;
else
return -1;
FILE *outfile;
int row_stride;
unsigned char *row_pointer[1];
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
if ((outfile = fopen(filename, "wb")) == NULL) {
fprintf(stderr, "can't open %s\n", filename);
return -1;
}
jpeg_stdio_dest(&cinfo, outfile);
cinfo.image_width = data->width();
cinfo.image_height = data->height();
if (data->channels() == 3)
cinfo.in_color_space = JCS_RGB;
else if (data->channels() == 1)
cinfo.in_color_space = JCS_GRAYSCALE;
else
return -1;
cinfo.input_components = data->channels();
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, quality, TRUE);
jpeg_start_compress(&cinfo, TRUE);
row_stride = data->width() * data->channels();
while (cinfo.next_scanline < cinfo.image_height) {
row_pointer[0] =
*(data->begin(cinfo.image_height - cinfo.next_scanline - 1));
(void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
jpeg_finish_compress(&cinfo);
fclose(outfile);
jpeg_destroy_compress(&cinfo);
return 0;
}
--- NEW FILE: FPNM.cxx ---
#include <Flek/FPNM.H>
// CET - FIXME - this shouldn't use libstdc++ if it can be avoided- libstdc++
// causes compatibility problems under linux. Maybe should use the regular
// stdio.h stuff?
#include <iostream.h>
#include <fstream.h>
static int
skip_comments(ifstream & input)
{
char c;
// Skip space up to first comment.
input.setf(ios::skipws);
input >> c;
input.unsetf(ios::skipws);
if (c != '#') {
input.putback(c);
//input.unget ();
input.setf(ios::skipws);
return 0;
}
while (c == '#') {
while (c != '\n') {
input >> c;
if (input.bad())
return 1;
}
input >> c;
if (input.bad())
return 1;
}
input.putback(c);
//input.unget ();
input.setf(ios::skipws);
return 0;
}
bool
FPNM::valid(char *filename)
{
ifstream input;
int type;
char c;
input.open(filename);
if (input.bad())
return false;
input.unsetf(ios::skipws);
// Check the magic number
input >> c;
if (!((c == 'P') || (c == 'p')))
return false;
input >> c;
type = c - 48;
if ((type < 1) || (type > 7))
return false;
input.close();
return true;
}
FImage *
FPNM::read(char *filename)
{
ifstream input;
int width, height;
int type;
int depth;
char c;
input.open(filename);
if (input.bad())
return 0;
// Check the magic number
input >> c;
if (!((c == 'P') || (c == 'p')))
return 0;
// the file type
input >> c;
type = c - 48;
// We support types 1-6 and nonstandard 7
if ((type < 1) || (type > 7))
return 0;
if (skip_comments(input))
return 0;
switch (type) {
case 2:
case 3:
case 5:
case 6:
case 7:
input >> width;
if (skip_comments(input))
return 0;
input >> height;
if (skip_comments(input))
return 0;
input >> depth;
break;
case 1:
case 4:
input >> width;
if (skip_comments(input))
return 0;
input >> height;
break;
}
input.unsetf(ios::skipws);
// Single whitespace before input.
input >> c;
FImage *img = new FImage(width, height);
FImage::iterator begin;
FImage::iterator end;
FImage::iterator i;
uchar *pixel;
int row;
switch (type) {
case 1: // ASCII B&W
for (row = height - 1; row >= 0; row--) {
begin = img->begin(row);
end = img->end(row);
int c;
for (i = begin; i != end; i++) {
pixel = *i;
input >> c;
if (input.bad())
return img; // return corrupt image.
if (c)
pixel[0] = 255;
else
pixel[0] = 0;
pixel[1] = pixel[2] = pixel[0];
pixel[3] = 255;
}
}
break;
case 2: // ASCII GRAY
input.unsetf(ios::skipws);
for (row = height - 1; row >= 0; row--) {
unsigned int g;
begin = img->begin(row);
end = img->end(row);
for (i = begin; i != end; i++) {
pixel = *i;
input >> g;
pixel[0] = g; // red
pixel[1] = pixel[2] = pixel[0]; // blue & green
pixel[3] = 255; // alpha
if (input.bad())
return img; // return corrupt image.
}
}
break;
case 3: // ASCII RGB
input.unsetf(ios::skipws);
for (row = height - 1; row >= 0; row--) {
unsigned int r;
unsigned int g;
unsigned int b;
begin = img->begin(row);
end = img->end(row);
for (i = begin; i != end; i++) {
pixel = *i;
input >> r;
pixel[0] = r; // red
input >> g;
pixel[1] = g; // green
input >> b;
pixel[2] = b; // blue
pixel[3] = 255; // alpha
if (input.bad())
return img; // return corrupt image.
}
}
break;
case 4: // RAW BITPACKED B&W
for (row = height - 1; row >= 0; row--) {
begin = img->begin(row);
end = img->end(row);
char c;
int cx = 0;
for (i = begin; i != end;) {
input >> c;
if (input.bad())
return img; // return corrupt image.
for (int j = 0; (j < 8) && (cx + j < width); j++) {
pixel = *i;
if (0x80 & (c << j))
pixel[0] = pixel[1] = pixel[2] = 0;
else
pixel[0] = pixel[1] = pixel[2] = 255;
pixel[3] = 255;
i++;
}
cx += 8;
}
}
break;
case 5: // RAW GRAY
for (row = height - 1; row >= 0; row--) {
begin = img->begin(row);
end = img->end(row);
for (i = begin; i != end; i++) {
pixel = *i;
input >> pixel[0]; // red
pixel[1] = pixel[2] = pixel[0]; // blue & green
pixel[3] = 255; // alpha
if (input.bad())
return img; // return corrupt image.
}
}
break;
case 6: // RAW RGB
for (row = height - 1; row >= 0; row--) {
begin = img->begin(row);
end = img->end(row);
for (i = begin; i != end; i++) {
pixel = *i;
input >> pixel[0]; // red
input >> pixel[1]; // green
input >> pixel[2]; // blue
pixel[3] = 255; // alpha
if (input.bad())
return img; // return corrupt image.
}
}
break;
case 7: // RAW RGBA (nonstandard)
for (row = height - 1; row >= 0; row--) {
begin = img->begin(row);
end = img->end(row);
for (i = begin; i != end; i++) {
pixel = *i;
input >> pixel[0]; // red
input >> pixel[1]; // green
input >> pixel[2]; // blue
input >> pixel[3]; // alpha
if (input.bad())
return img; // return corrupt image.
}
}
break;
}
input.close();
return img;
}
int
FPNM::write(char *filename, FImage * img)
{
ofstream output;
FImage::iterator begin;
FImage::iterator end;
FImage::iterator i;
uchar *pixel;
output.open(filename);
if (output.bad())
return 1;
output << "P6" << endl;
output << "# CREATOR: Flek's FPNM::write ()" << endl;
output << img->width() << " " << img->height() << endl;
output << "255 ";
int height = img->height();
for (int row = height - 1; row >= 0; row--) {
begin = img->begin(row);
end = img->end(row);
for (i = begin; i != end; i++) {
pixel = *i;
output << pixel[0]; // red
output << pixel[1]; // green
output << pixel[2]; // blue
}
}
output.close();
return 0;
}
--- NEW FILE: Fl_Better_Window.cxx ---
#include <Flek/Fl_Better_Window.H>
#ifdef NANOX
#include <FL/n_x.h>
#else
#include <FL/x.H>
#endif
// get_window_borders by "Jason Ertel" <jertel at simulation.com>
int
Fl_Better_Window::get_window_borders(Fl_Window * win, int &left, int &right,
int &top, int &bottom)
{
#if defined(_WIN32)
RECT myRect;
int result;
result = GetWindowRect(fl_xid(win), &myRect);
left = win->x() - myRect.left;
right = myRect.right - (win->x() + win->w());
top = win->y() - myRect.top;
bottom = myRect.bottom - (win->y() + win->h());
return result;
#else
/* JHC - this is incorrect - but I don't believe this function is used, so just something to hide our
shame */
#ifdef NANOX
GR_WINDOW_ID current = fl_xid(win);
GR_WINDOW_INFO wi;
GrGetWindowInfo(current, &wi);
left = win->x() - wi.x;
right = wi.width - win->w() - left;
top = win->y() - wi.y;
bottom = wi.height - win->h() - top;
return 1;
#else
Window root, parent, *children, current;
unsigned int childrenCount;
XWindowAttributes attrs;
int status = 1;
current = fl_xid(win);
while (status) {
status =
XQueryTree(fl_display, current, &root, &parent, &children,
&childrenCount);
if (parent == root)
break;
current = parent;
}
if (status) {
XGetWindowAttributes(fl_display, current, &attrs);
left = win->x() - attrs.x;
right = attrs.width - win->w() - left;
top = win->y() - attrs.y;
bottom = attrs.height - win->h() - top;
return 1;
} else {
left = 0;
right = 0;
top = 0;
bottom = 0;
return 0;
}
#endif
#endif
}
--- NEW FILE: Fl_Toggle_Tree_Base.cxx ---
#include <stdio.h> // printf
#include <stdlib.h> // qsort
#include <Flek/Fl_Toggle_Node_Base.H>
#include <Flek/Fl_Toggle_Tree_Base.H>
Fl_Toggle_Tree_Base::Fl_Toggle_Tree_Base(int x, int y, int w, int h):
Fl_Widget(x, y, w, h)
{
first_ = 0;
t_current_ = 0;
top_ = 0;
top_depth_ = 0;
damaged_ = 0;
}
void
Fl_Toggle_Tree_Base::draw_node(int depth, int cy, Fl_Toggle_Node_Base *)
{
fl_color(FL_BLACK);
fl_rectf(x(), cy, depth * 16, 16);
fl_color(FL_WHITE);
fl_rectf(x() + depth * 16, cy, w() - depth * 16, 16);
}
Fl_Toggle_Node_Base *
Fl_Toggle_Tree_Base::find(int fy, int &depth, int &ry)
{
int cy = parent()->y() + top_yoffset_;
int ey = parent()->y() + parent()->h();
if (fy < cy)
return 0;
depth = top_depth_;
Fl_Toggle_Node_Base *node = top_;
traverse_start(top_);
while (cy < ey && node) {
ry = cy;
cy += height(node);
if (cy > fy)
return node;
node = traverse_forward(1, depth);
}
return 0;
}
void
Fl_Toggle_Tree_Base::update_height(void)
{
resize(x(), y(), w(), total_height(first_));
}
void
Fl_Toggle_Tree_Base::draw(void)
{
// printf("Fl_Toggle_Tree_Base::draw %d %d\n",x(),y());
update_top();
int cy = parent()->y() + top_yoffset_;
int ey = parent()->y() + parent()->h();
int depth = top_depth_;
Fl_Toggle_Node_Base *node = top_;
int drawing = 0;
//printf("DAMAGE %d %d %d\n",damage(),FL_DAMAGE_ALL,FL_DAMAGE_CHILD);
if (damage() == FL_DAMAGE_ALL)
drawing = 1;
if (damage() == FL_DAMAGE_CHILD && damaged_ == 0)
drawing = 1;
while (cy < ey && node) {
if (damaged_ == node) {
if (damage() == FL_DAMAGE_CHILD) {
draw_node(depth, cy, node);
return;
}
drawing = 1;
}
//printf("%s %d\n",(char*) node->data(),drawing);
if (drawing)
draw_node(depth, cy, node);
cy += height(node);
if (node->vsub_) {
//printf("has sub\n");
node = node->vsub_;
depth++;
} else if (node->next_) {
//printf("has no sub\n");
node = node->next_;
} else {
while (node && !node->next_) {
node = node->up_;
depth--;
}
if (node)
node = node->next_;
}
}
fl_color(parent()->color());
fl_rectf(x(), cy, w(), ey - cy);
}
int (*s_node_compare_) (Fl_Toggle_Node_Base *, Fl_Toggle_Node_Base *) = 0;
int
Fl_Toggle_Tree_Base::s_compare_(void *a, void *b)
{
Fl_Toggle_Node_Base *nodeA = *(Fl_Toggle_Node_Base **) a;
Fl_Toggle_Node_Base *nodeB = *(Fl_Toggle_Node_Base **) b;
return s_node_compare_(nodeA, nodeB);
}
int
Fl_Toggle_Tree_Base::s_compare_reverse_(void *a, void *b)
{
Fl_Toggle_Node_Base *nodeA = *(Fl_Toggle_Node_Base **) a;
Fl_Toggle_Node_Base *nodeB = *(Fl_Toggle_Node_Base **) b;
return -s_node_compare_(nodeA, nodeB);
}
Fl_Toggle_Node_Base *
Fl_Toggle_Tree_Base::sort_(Fl_Toggle_Node_Base * start,
int (*compar) (Fl_Toggle_Node_Base *,
Fl_Toggle_Node_Base *), int down,
sort_order order)
{
int i;
Fl_Toggle_Node_Base *node;
i = 0;
node = start;
while (node) {
node = node->next_;
i++;
}
Fl_Toggle_Node_Base **array = new Fl_Toggle_Node_Base *[i];
i = 0;
node = start;
while (node) {
array[i] = node;
node = node->next_;
i++;
}
s_node_compare_ = compar;
if (order == REVERSE_SORT) {
qsort(array, i, sizeof(Fl_Toggle_Node_Base *),
(int (*)(const void *, const void *)) s_compare_reverse_);
} else {
qsort(array, i, sizeof(Fl_Toggle_Node_Base *),
(int (*)(const void *, const void *)) s_compare_);
}
start = array[0];
int j = 1;
node = start;
node->prev_ = 0; //james
while (j < i) {
node->next_ = array[j];
node->next_->prev_ = node;
node = node->next_;
j++;
}
node->next_ = 0;
if (down) {
node = start;
while (node) {
if (node->sub_)
node->sub_ = sort_tree(node->sub_, compar, order);
if (node->vsub_)
node->vsub_ = node->sub_;
node = node->next_;
}
}
delete[]array;
return start;
}
Fl_Toggle_Node_Base *
Fl_Toggle_Tree_Base::sort(Fl_Toggle_Node_Base * start,
int (*compar) (Fl_Toggle_Node_Base *,
Fl_Toggle_Node_Base *),
sort_order order)
{
if (first_)
return sort_(start, compar, 0, order);
return 0;
}
Fl_Toggle_Node_Base *
Fl_Toggle_Tree_Base::sort_tree(Fl_Toggle_Node_Base * start,
int (*compar) (Fl_Toggle_Node_Base *,
Fl_Toggle_Node_Base *),
sort_order order)
{
if (first_)
return sort_(start, compar, 1, order);
return 0;
}
void
Fl_Toggle_Tree_Base::
sort(int (*compar) (Fl_Toggle_Node_Base *, Fl_Toggle_Node_Base *),
sort_order order)
{
if (first_)
first_ = top_ = sort(first_, compar, order);
}
void
Fl_Toggle_Tree_Base::
sort_tree(int (*compar) (Fl_Toggle_Node_Base *, Fl_Toggle_Node_Base *),
sort_order order)
{
if (first_)
first_ = top_ = sort_tree(first_, compar, order);
}
void
Fl_Toggle_Tree_Base::update_top(void)
{
Fl_Toggle_Node_Base *node = first_;
int py = parent()->y();
int ly = y();
int h = 0;
int depth = 0;
while (node && ly + (h = height(node)) <= py) {
ly += h;
if (node->vsub_) {
node = node->vsub_;
depth++;
} else if (node->next_) {
node = node->next_;
} else {
while (node && !node->next_) {
node = node->up_;
depth--;
}
if (node)
node = node->next_;
}
}
top_ = node;
top_depth_ = depth;
top_yoffset_ = ly - py;
}
int
Fl_Toggle_Tree_Base::total_height(Fl_Toggle_Node_Base * node)
{
int ret = 0;
int depth = 1;
while (node) {
ret += height(node);
if (node->vsub_) {
node = node->vsub_;
depth++;
} else if (node->next_) {
node = node->next_;
} else {
while (node && !node->next_) {
node = node->up_;
depth--;
if (depth <= 0)
node = 0;
}
if (node)
node = node->next_;
}
}
return ret;
}
int
Fl_Toggle_Tree_Base::height(Fl_Toggle_Node_Base *)
{
return 17;
}
Fl_Toggle_Node_Base *
Fl_Toggle_Tree_Base::traverse_start()
{
t_current_ = first_;
return t_current_;
}
void
Fl_Toggle_Tree_Base::traverse_start(Fl_Toggle_Node_Base * a)
{
t_current_ = a;
}
void
Fl_Toggle_Tree_Base::traverse_up(void)
{
if (t_current_ && t_current_->up_)
t_current_ = t_current_->up_;
}
Fl_Toggle_Node_Base *
Fl_Toggle_Tree_Base::traverse_forward(int visible, int &depth)
{
if (visible) {
if (t_current_ && t_current_->vsub_ != 0) {
t_current_ = t_current_->vsub_;
depth++;
return t_current_;
}
} else {
if (t_current_ && t_current_->sub_ != 0) {
t_current_ = t_current_->sub_;
depth++;
return t_current_;
}
}
if (t_current_ && t_current_->next_ != 0) {
t_current_ = t_current_->next_;
return t_current_;
}
while (t_current_ && !t_current_->next_) {
t_current_ = t_current_->up_;
depth--;
}
if (t_current_)
t_current_ = t_current_->next_;
return t_current_;
}
Fl_Toggle_Node_Base *
Fl_Toggle_Tree_Base::traverse_forward()
{
int d;
return traverse_forward(0, d);
}
Fl_Toggle_Node_Base *
Fl_Toggle_Tree_Base::traverse_backward()
{
if (t_current_ && t_current_->prev_) {
t_current_ = t_current_->prev_;
while (t_current_->sub_) {
t_current_ = t_current_->sub_;
while (t_current_->next_) {
t_current_ = t_current_->next_;
if (t_current_->next_ == 0 && t_current_->sub_) {
t_current_ = t_current_->sub_;
}
}
}
} else {
t_current_ = t_current_->up_;
}
return t_current_;
}
void
Fl_Toggle_Tree_Base::add_next(Fl_Toggle_Node_Base * node)
{
if (!first_) {
first_ = node;
t_current_ = node;
} else {
if (t_current_ == 0)
t_current_ = first_;
node->next_ = t_current_->next_;
if (t_current_->next_) {
t_current_->next_->prev_ = node;
}
t_current_->next_ = node;
node->prev_ = t_current_;
node->up_ = t_current_->up_;
t_current_ = node;
}
update_height();
parent()->damage(FL_DAMAGE_CHILD);
redraw();
}
void
Fl_Toggle_Tree_Base::add_sub(Fl_Toggle_Node_Base * node)
{
if (!first_) {
first_ = node;
t_current_ = node;
} else {
if (t_current_ == 0)
t_current_ = first_;
node->next_ = t_current_->sub_;
if (t_current_->sub_)
t_current_->sub_->prev_ = node;
node->prev_ = 0;
t_current_->sub_ = node;
if (t_current_->opened_)
t_current_->vsub_ = node;
node->up_ = t_current_;
t_current_ = node;
}
update_height();
parent()->damage(FL_DAMAGE_CHILD);
redraw();
}
int
Fl_Toggle_Tree_Base::remove(Fl_Toggle_Node_Base * a)
{
Fl_Toggle_Node_Base *temp = a->sub_;
while (temp != 0) { // Remove all children
remove(temp);
temp = a->sub_;
}
if (a->prev_) {
a->prev_->next_ = a->next_;
if (a->next_)
a->next_->prev_ = a->prev_;
} else if (a->up_) {
Fl_Toggle_Node_Base *o = a->up_;
o->sub_ = a->next_;
if (o->opened_)
o->vsub_ = a->next_;
else
o->vsub_ = 0;
if (a->next_) {
a->next_->up_ = o;
a->next_->prev_ = a->prev_;
}
}
if (a == first_) {
if (a->next_) {
first_ = a->next_;
first_->up_ = 0;
first_->prev_ = 0;
} else {
first_ = 0;
top_ = 0;
}
}
if (a == current_) {
if (a->up_)
current_ = a->up_;
else if (a->prev_)
current_ = a->prev_;
else
current_ = 0;
}
if (a == t_current_) {
if (a->up_)
t_current_ = a->up_;
else if (a->prev_)
t_current_ = a->prev_;
else
t_current_ = 0;
}
update_height();
parent()->damage(FL_DAMAGE_CHILD);
redraw();
delete a;
a = 0;
return 1;
}
int
Fl_Toggle_Tree_Base::clear()
{
while (first_)
remove(first_);
return 1;
}
int
Fl_Toggle_Tree_Base::close(Fl_Toggle_Node_Base * node)
{
int th = total_height(node->vsub_);
node->opened_ = 0;
node->vsub_ = 0;
return th;
}
int
Fl_Toggle_Tree_Base::open(Fl_Toggle_Node_Base * node)
{
node->vsub_ = node->sub_;
int th = total_height(node->vsub_);
node->opened_ = 1;
return th;
}
--- NEW FILE: FVector.cxx ---
#include <Flek/FVector2.H>
#include <Flek/FVector3.H>
#include <Flek/FVector4.H>
#include <Flek/FMatrix3x3.H>
#include <Flek/FMatrix4x4.H>
void
FVector3::copy_from(FVector4 const &v)
{
elem[0] = v[0];
elem[1] = v[1];
elem[2] = v[2];
}
void
FVector3::copy_from(FVector2 const &v)
{
elem[0] = v[0];
elem[1] = v[1];
elem[0] = 0;
}
void
FVector2::copy_from(FVector4 const &v)
{
elem[0] = v[0];
elem[1] = v[1];
}
void
FVector2::copy_from(FVector3 const &v)
{
elem[0] = v[0];
elem[1] = v[1];
}
void
FVector4::copy_from(FVector3 const &v)
{
elem[0] = v[0];
elem[1] = v[1];
elem[2] = v[2];
}
void
FVector4::copy_from(FVector2 const &v)
{
elem[0] = v[0];
elem[1] = v[1];
}
/*
The following functions are defined outside the class so that they use the
friend versions of member functions instead of the member functions themselves
*/
FMatrix4x4
operator *(const FMatrix4x4 & mat1, const FMatrix4x4 & mat2)
{
FMatrix4x4 prod, trans;
// Find the transpose of the 2nd matrix
trans = transpose(mat2);
// The columns of mat2 are now the rows of trans
// Multiply appropriate rows and columns to get the product
prod.row[0].set(mat1.row[0] * trans.row[0],
mat1.row[0] * trans.row[1],
mat1.row[0] * trans.row[2], mat1.row[0] * trans.row[3]);
prod.row[1].set(mat1.row[1] * trans.row[0],
mat1.row[1] * trans.row[1],
mat1.row[1] * trans.row[2], mat1.row[1] * trans.row[3]);
prod.row[2].set(mat1.row[2] * trans.row[0],
mat1.row[2] * trans.row[1],
mat1.row[2] * trans.row[2], mat1.row[2] * trans.row[3]);
prod.row[3].set(mat1.row[3] * trans.row[0],
mat1.row[3] * trans.row[1],
mat1.row[3] * trans.row[2], mat1.row[3] * trans.row[3]);
return prod;
}
FVector4
operator *(const FVector4 & vec, const FMatrix4x4 & mat)
{
return (transpose(mat) * vec);
}
/*
The following functions are defined outside the class so that they use the
friend versions of member functions instead of the member functions themselves
*/
FMatrix3x3
operator *(const FMatrix3x3 & mat1, const FMatrix3x3 & mat2)
{
FMatrix3x3 prod, trans;
// Find the transpose of the 2nd matrix
trans = transpose(mat2);
// The columns of mat2 are now the rows of trans
// Multiply appropriate rows and columns to get the product
prod.row[0].set(mat1.row[0] * trans.row[0],
mat1.row[0] * trans.row[1], mat1.row[0] * trans.row[2]);
prod.row[1].set(mat1.row[1] * trans.row[0],
mat1.row[1] * trans.row[1], mat1.row[1] * trans.row[2]);
prod.row[2].set(mat1.row[2] * trans.row[0],
mat1.row[2] * trans.row[1], mat1.row[2] * trans.row[2]);
return prod;
}
FVector3
operator *(const FVector3 & vec, const FMatrix3x3 & mat)
{
return (transpose(mat) * vec);
}
More information about the dslinux-commit
mailing list