reactos/rosapps/lib/dflat32/window.c
Steven Edwards 81345fd691 Still working on making dflat32 a dll. Alot of this will be cleaned up in the
next few weeks. I'm going through the DFLAT api doc and fixing the export
names and then going to try to build a simple hello dflat application.

svn path=/trunk/; revision=2844
2002-04-14 10:15:06 +00:00

522 lines
14 KiB
C

/* ---------- window.c ------------- */
#include "dflat32/dflat.h"
DFWINDOW inFocus = NULL;
int foreground, background; /* current video colors */
static void TopLine(DFWINDOW, int, DFRECT);
/* --------- create a window ------------ */
DFWINDOW DfCreateWindow(
DFCLASS class, /* class of this window */
char *ttl, /* title or NULL */
int left, int top, /* upper left coordinates */
int height, int width, /* dimensions */
void *extension, /* pointer to additional data */
DFWINDOW parent, /* parent of this window */
int (*wndproc)(struct window *,enum messages,PARAM,PARAM),
int attrib) /* window attribute */
{
DFWINDOW wnd = DFcalloc(1, sizeof(struct window));
if (wnd != NULL) {
int base;
/* ----- height, width = -1: fill the screen ------- */
if (height == -1)
height = sScreenHeight;
if (width == -1)
width = sScreenWidth;
/* ----- coordinates -1, -1 = center the window ---- */
if (left == -1)
wnd->rc.lf = (sScreenWidth-width)/2;
else
wnd->rc.lf = left;
if (top == -1)
wnd->rc.tp = (sScreenHeight-height)/2;
else
wnd->rc.tp = top;
wnd->attrib = attrib;
if (ttl != NULL)
AddAttribute(wnd, HASTITLEBAR);
if (wndproc == NULL)
wnd->wndproc = classdefs[class].wndproc;
else
wnd->wndproc = wndproc;
/* ---- derive attributes of base classes ---- */
base = class;
while (base != -1) {
AddAttribute(wnd, classdefs[base].attrib);
base = classdefs[base].base;
}
if (parent)
{
if (!TestAttribute(wnd, NOCLIP))
{
/* -- keep upper left within borders of parent - */
wnd->rc.lf = max(wnd->rc.lf,GetClientLeft(parent));
wnd->rc.tp = max(wnd->rc.tp,GetClientTop(parent));
}
}
else
parent = ApplicationWindow;
wnd->class = class;
wnd->extension = extension;
wnd->rc.rt = GetLeft(wnd)+width-1;
wnd->rc.bt = GetTop(wnd)+height-1;
wnd->ht = height;
wnd->wd = width;
if (ttl != NULL)
InsertTitle(wnd, ttl);
wnd->parent = parent;
wnd->oldcondition = wnd->condition = ISRESTORED;
wnd->RestoredRC = wnd->rc;
InitWindowColors(wnd);
DfSendMessage(wnd, CREATE_WINDOW, 0, 0);
if (isVisible(wnd))
DfSendMessage(wnd, SHOW_WINDOW, 0, 0);
}
return wnd;
}
/* -------- add a title to a window --------- */
void AddTitle(DFWINDOW wnd, char *ttl)
{
InsertTitle(wnd, ttl);
DfSendMessage(wnd, BORDER, 0, 0);
}
/* ----- insert a title into a window ---------- */
void InsertTitle(DFWINDOW wnd, char *ttl)
{
wnd->title=DFrealloc(wnd->title,strlen(ttl)+1);
strcpy(wnd->title, ttl);
}
static unsigned char line[300];
/* ------ write a line to video window client area ------ */
void writeline(DFWINDOW wnd, char *str, int x, int y, BOOL pad)
{
char *cp;
int len;
int dif;
char wline[200];
memset(wline, 0, 200);
len = LineLength(str);
dif = strlen(str) - len;
strncpy(wline, str, ClientWidth(wnd) + dif);
if (pad) {
cp = wline+strlen(wline);
while (len++ < ClientWidth(wnd)-x)
*cp++ = ' ';
}
wputs(wnd, wline, x, y);
}
DFRECT AdjustRectangle(DFWINDOW wnd, DFRECT rc)
{
/* -------- adjust the rectangle ------- */
if (TestAttribute(wnd, HASBORDER)) {
if (RectLeft(rc) == 0)
--rc.rt;
else if (RectLeft(rc) < RectRight(rc) &&
RectLeft(rc) < WindowWidth(wnd)+1)
--rc.lf;
}
if (TestAttribute(wnd, HASBORDER | HASTITLEBAR)) {
if (RectTop(rc) == 0)
--rc.bt;
else if (RectTop(rc) < RectBottom(rc) &&
RectTop(rc) < WindowHeight(wnd)+1)
--rc.tp;
}
RectRight(rc) = max(RectLeft(rc),
min(RectRight(rc),WindowWidth(wnd)));
RectBottom(rc) = max(RectTop(rc),
min(RectBottom(rc),WindowHeight(wnd)));
return rc;
}
/* -------- display a window's title --------- */
void DisplayTitle(DFWINDOW wnd, DFRECT *rcc)
{
if (GetTitle(wnd) != NULL)
{
int tlen = min((int)strlen(GetTitle(wnd)), (int)WindowWidth(wnd)-2);
int tend = WindowWidth(wnd)-3-BorderAdj(wnd);
DFRECT rc;
if (rcc == NULL)
rc = RelativeWindowRect(wnd, WindowRect(wnd));
else
rc = *rcc;
rc = AdjustRectangle(wnd, rc);
if (DfSendMessage(wnd, TITLE, (PARAM) rcc, 0))
{
if (wnd == inFocus)
{
foreground = cfg.clr[TITLEBAR] [HILITE_COLOR] [FG];
background = cfg.clr[TITLEBAR] [HILITE_COLOR] [BG];
}
else
{
foreground = cfg.clr[TITLEBAR] [STD_COLOR] [FG];
background = cfg.clr[TITLEBAR] [STD_COLOR] [BG];
}
memset(line,' ',WindowWidth(wnd));
#ifdef INCLUDE_MINIMIZE
if (wnd->condition != ISMINIMIZED)
#endif
strncpy (line + ((WindowWidth(wnd)-2 - tlen) / 2),
wnd->title, tlen);
if (TestAttribute(wnd, CONTROLBOX))
line[2-BorderAdj(wnd)] = CONTROLBOXCHAR;
if (TestAttribute(wnd, MINMAXBOX))
{
switch (wnd->condition)
{
case ISRESTORED:
#ifdef INCLUDE_MAXIMIZE
line[tend+1] = MAXPOINTER;
#endif
#ifdef INCLUDE_MINIMIZE
line[tend] = MINPOINTER;
#endif
break;
#ifdef INCLUDE_MINIMIZE
case ISMINIMIZED:
line[tend+1] = MAXPOINTER;
break;
#endif
#ifdef INCLUDE_MAXIMIZE
case ISMAXIMIZED:
#ifdef INCLUDE_MINIMIZE
line[tend] = MINPOINTER;
#endif
#ifdef INCLUDE_RESTORE
line[tend+1] = RESTOREPOINTER;
#endif
break;
#endif
default:
break;
}
}
line[RectRight(rc)+1] = line[tend+3] = '\0';
if (wnd != inFocus)
ClipString++;
writeline(wnd, line+RectLeft(rc),
RectLeft(rc)+BorderAdj(wnd),
0,
FALSE);
ClipString = 0;
}
}
}
/* --- display right border shadow character of a window --- */
static void shadow_char(DFWINDOW wnd, int y)
{
int fg = foreground;
int bg = background;
int x = WindowWidth(wnd);
char c = videochar(GetLeft(wnd)+x, GetTop(wnd)+y);
if (TestAttribute(wnd, SHADOW) == 0)
return;
foreground = DARKGRAY;
background = BLACK;
wputch(wnd, c, x, y);
foreground = fg;
background = bg;
}
/* --- display the bottom border shadow line for a window -- */
static void shadowline(DFWINDOW wnd, DFRECT rc)
{
int i;
int y = GetBottom(wnd)+1;
int fg = foreground;
int bg = background;
if ((TestAttribute(wnd, SHADOW)) == 0)
return;
for (i = 0; i < WindowWidth(wnd)+1; i++)
line[i] = videochar(GetLeft(wnd)+i, y);
line[i] = '\0';
foreground = DARKGRAY;
background = BLACK;
line[RectRight(rc)+1] = '\0';
if (RectLeft(rc) == 0)
rc.lf++;
ClipString++;
wputs(wnd, line+RectLeft(rc), RectLeft(rc),
WindowHeight(wnd));
--ClipString;
foreground = fg;
background = bg;
}
static DFRECT ParamRect(DFWINDOW wnd, DFRECT *rcc)
{
DFRECT rc;
if (rcc == NULL) {
rc = RelativeWindowRect(wnd, WindowRect(wnd));
if (TestAttribute(wnd, SHADOW)) {
rc.rt++;
rc.bt++;
}
}
else
rc = *rcc;
return rc;
}
void PaintShadow(DFWINDOW wnd)
{
int y;
DFRECT rc = ParamRect(wnd, NULL);
for (y = 1; y < WindowHeight(wnd); y++)
shadow_char(wnd, y);
shadowline(wnd, rc);
}
/* ------- display a window's border ----- */
void RepaintBorder(DFWINDOW wnd, DFRECT *rcc)
{
int y;
char lin, side, ne, nw, se, sw;
DFRECT rc, clrc;
if (!TestAttribute(wnd, HASBORDER))
return;
rc = ParamRect(wnd, rcc);
clrc = AdjustRectangle(wnd, rc);
if (wnd == inFocus) {
lin = FOCUS_LINE;
side = FOCUS_SIDE;
ne = FOCUS_NE;
nw = FOCUS_NW;
se = FOCUS_SE;
sw = FOCUS_SW;
}
else {
lin = LINE;
side = SIDE;
ne = NE;
nw = NW;
se = SE;
sw = SW;
}
line[WindowWidth(wnd)] = '\0';
/* ---------- window title ------------ */
if (TestAttribute(wnd, HASTITLEBAR))
if (RectTop(rc) == 0)
if (RectLeft(rc) < WindowWidth(wnd)-BorderAdj(wnd))
DisplayTitle(wnd, &rc);
foreground = FrameForeground(wnd);
background = FrameBackground(wnd);
/* -------- top frame corners --------- */
if (RectTop(rc) == 0) {
if (RectLeft(rc) == 0)
wputch(wnd, nw, 0, 0);
if (RectLeft(rc) < WindowWidth(wnd)) {
if (RectRight(rc) >= WindowWidth(wnd)-1)
wputch(wnd, ne, WindowWidth(wnd)-1, 0);
TopLine(wnd, lin, clrc);
}
}
/* ----------- window body ------------ */
for (y = RectTop(rc); y <= RectBottom(rc); y++) {
char ch;
if (y == 0 || y >= WindowHeight(wnd)-1)
continue;
if (RectLeft(rc) == 0)
wputch(wnd, side, 0, y);
if (RectLeft(rc) < WindowWidth(wnd) &&
RectRight(rc) >= WindowWidth(wnd)-1) {
if (TestAttribute(wnd, VSCROLLBAR))
ch = ( y == 1 ? UPSCROLLBOX :
y == WindowHeight(wnd)-2 ?
DOWNSCROLLBOX :
y-1 == wnd->VScrollBox ?
SCROLLBOXCHAR :
SCROLLBARCHAR );
else
ch = side;
wputch(wnd, ch, WindowWidth(wnd)-1, y);
}
if (RectRight(rc) == WindowWidth(wnd))
shadow_char(wnd, y);
}
if (RectTop(rc) <= WindowHeight(wnd)-1 &&
RectBottom(rc) >= WindowHeight(wnd)-1) {
/* -------- bottom frame corners ---------- */
if (RectLeft(rc) == 0)
wputch(wnd, sw, 0, WindowHeight(wnd)-1);
if (RectLeft(rc) < WindowWidth(wnd) &&
RectRight(rc) >= WindowWidth(wnd)-1)
wputch(wnd, se, WindowWidth(wnd)-1,
WindowHeight(wnd)-1);
if (wnd->StatusBar == NULL) {
/* ----------- bottom line ------------- */
memset(line,lin,WindowWidth(wnd)-1);
if (TestAttribute(wnd, HSCROLLBAR)) {
line[0] = LEFTSCROLLBOX;
line[WindowWidth(wnd)-3] = RIGHTSCROLLBOX;
memset(line+1, SCROLLBARCHAR, WindowWidth(wnd)-4);
line[wnd->HScrollBox] = SCROLLBOXCHAR;
}
line[WindowWidth(wnd)-2] = line[RectRight(rc)] = '\0';
if (RectLeft(rc) != RectRight(rc) ||
(RectLeft(rc) && RectLeft(rc) < WindowWidth(wnd)-1))
{
if (wnd != inFocus)
ClipString++;
writeline(wnd,
line+(RectLeft(clrc)),
RectLeft(clrc)+1,
WindowHeight(wnd)-1,
FALSE);
ClipString = 0;
}
}
if (RectRight(rc) == WindowWidth(wnd))
shadow_char(wnd, WindowHeight(wnd)-1);
}
if (RectBottom(rc) == WindowHeight(wnd))
/* ---------- bottom shadow ------------- */
shadowline(wnd, rc);
}
static void TopLine(DFWINDOW wnd, int lin, DFRECT rc)
{
if (TestAttribute(wnd, HASMENUBAR))
return;
if (TestAttribute(wnd, HASTITLEBAR) && GetTitle(wnd))
return;
if (RectLeft(rc) == 0) {
RectLeft(rc) += BorderAdj(wnd);
RectRight(rc) += BorderAdj(wnd);
}
if (RectRight(rc) < WindowWidth(wnd)-1)
RectRight(rc)++;
if (RectLeft(rc) < RectRight(rc)) {
/* ----------- top line ------------- */
memset(line,lin,WindowWidth(wnd)-1);
if (TestAttribute(wnd, CONTROLBOX)) {
strncpy(line+1, " ", 3);
*(line+2) = CONTROLBOXCHAR;
}
line[RectRight(rc)] = '\0';
writeline(wnd, line+RectLeft(rc),
RectLeft(rc), 0, FALSE);
}
}
/* ------ clear the data space of a window -------- */
void ClearWindow(DFWINDOW wnd, DFRECT *rcc, int clrchar)
{
if (isVisible(wnd)) {
int y;
DFRECT rc;
if (rcc == NULL)
rc = RelativeWindowRect(wnd, WindowRect(wnd));
else
rc = *rcc;
if (RectLeft(rc) == 0)
RectLeft(rc) = BorderAdj(wnd);
if (RectRight(rc) > WindowWidth(wnd)-1)
RectRight(rc) = WindowWidth(wnd)-1;
SetStandardColor(wnd);
memset(line, clrchar, sizeof line);
line[RectRight(rc)+1] = '\0';
for (y = RectTop(rc); y <= RectBottom(rc); y++)
{
if (y < TopBorderAdj(wnd) ||
y > ClientHeight(wnd)+
(TestAttribute(wnd, HASMENUBAR) ? 1 : 0))
continue;
writeline(wnd,
line+(RectLeft(rc)),
RectLeft(rc),
y,
FALSE);
}
}
}
/* ------ compute the logical line length of a window ------ */
int LineLength(char *ln)
{
int len = strlen(ln);
char *cp = ln;
while ((cp = strchr(cp, CHANGECOLOR)) != NULL)
{
cp++;
len -= 3;
}
cp = ln;
while ((cp = strchr(cp, RESETCOLOR)) != NULL)
{
cp++;
--len;
}
return len;
}
void InitWindowColors(DFWINDOW wnd)
{
int fbg,col;
int cls = GetClass(wnd);
/* window classes without assigned colors inherit parent's colors */
if (cfg.clr[cls][0][0] == 0xff && GetParent(wnd) != NULL)
cls = GetClass(GetParent(wnd));
/* ---------- set the colors ---------- */
for (fbg = 0; fbg < 2; fbg++)
for (col = 0; col < 4; col++)
wnd->WindowColors[col][fbg] = cfg.clr[cls][col][fbg];
}
void PutWindowChar(DFWINDOW wnd, char c, int x, int y)
{
if (x < ClientWidth(wnd) && y < ClientHeight(wnd))
wputch(wnd, c, x+BorderAdj(wnd), y+TopBorderAdj(wnd));
}
void PutWindowLine(DFWINDOW wnd, void *s, int x, int y)
{
int saved = FALSE;
int sv = 0;
if (x < ClientWidth(wnd) && y < ClientHeight(wnd))
{
char *en = (char *)s+ClientWidth(wnd)-x;
if ((int)(strlen(s)+x) > (int)ClientWidth(wnd))
{
sv = *en;
*en = '\0';
saved = TRUE;
}
ClipString++;
wputs(wnd, s, x+BorderAdj(wnd), y+TopBorderAdj(wnd));
--ClipString;
if (saved)
*en = sv;
}
}
/* EOF */