home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 24 / CD_ASCQ_24_0995.iso / vrac / dflt20.zip / WINDOW.C < prev   
Text File  |  1995-03-20  |  16KB  |  528 lines

  1. /* ---------- window.c ------------- */
  2.  
  3. #include "dflat.h"
  4.  
  5. WINDOW inFocus = NULL;
  6.  
  7. int foreground, background;   /* current video colors */
  8.  
  9. static void TopLine(WINDOW, int, RECT);
  10.  
  11. /* --------- create a window ------------ */
  12. WINDOW CreateWindow(
  13.     CLASS Class,              /* class of this window       */
  14.     const char *ttl,          /* title or NULL              */
  15.     int left, int top,        /* upper left coordinates     */
  16.     int height, int width,    /* dimensions                 */
  17.     void *extension,          /* pointer to additional data */
  18.     WINDOW parent,            /* parent of this window      */
  19.     int (*wndproc)(struct window *,enum messages,PARAM,PARAM),
  20.     int attrib)               /* window attribute           */
  21. {
  22.     WINDOW wnd = DFcalloc(1, sizeof(struct window));
  23.     get_videomode();
  24.     if (wnd != NULL)    {
  25.         int base;
  26.         /* ----- height, width = -1: fill the screen ------- */
  27.         if (height == -1)
  28.             height = SCREENHEIGHT;
  29.         if (width == -1)
  30.             width = SCREENWIDTH;
  31.         /* ----- coordinates -1, -1 = center the window ---- */
  32.         if (left == -1)
  33.             wnd->rc.lf = (SCREENWIDTH-width)/2;
  34.         else
  35.             wnd->rc.lf = left;
  36.         if (top == -1)
  37.             wnd->rc.tp = (SCREENHEIGHT-height)/2;
  38.         else
  39.             wnd->rc.tp = top;
  40.         wnd->attrib = attrib;
  41.         if (ttl != NULL)
  42.             if (*ttl != '\0')
  43.                 AddAttribute(wnd, HASTITLEBAR);
  44.         if (wndproc == NULL)
  45.             wnd->wndproc = classdefs[Class].wndproc;
  46.         else
  47.             wnd->wndproc = wndproc;
  48.         /* ---- derive attributes of base classes ---- */
  49.         base = Class;
  50.         while (base != -1)    {
  51.             AddAttribute(wnd, classdefs[base].attrib);
  52.             base = classdefs[base].base;
  53.         }
  54.         if (parent)    {
  55.             if (!TestAttribute(wnd, NOCLIP))    {
  56.                 /* -- keep upper left within borders of parent - */
  57.                 wnd->rc.lf = max(wnd->rc.lf,GetClientLeft(parent));
  58.                 wnd->rc.tp = max(wnd->rc.tp,GetClientTop(parent));
  59.             }
  60.         }
  61.         else
  62.             parent = ApplicationWindow;
  63.         wnd->Class = Class;
  64.         wnd->extension = extension;
  65.         wnd->rc.rt = GetLeft(wnd)+width-1;
  66.         wnd->rc.bt = GetTop(wnd)+height-1;
  67.         wnd->ht = height;
  68.         wnd->wd = width;
  69.         if (ttl != NULL)
  70.             InsertTitle(wnd, ttl);
  71.         wnd->parent = parent;
  72.         wnd->oldcondition = wnd->condition = ISRESTORED;
  73.         wnd->RestoredRC = wnd->rc;
  74.         InitWindowColors(wnd);
  75.         SendMessage(wnd, CREATE_WINDOW, 0, 0);
  76.         if (isVisible(wnd))
  77.             SendMessage(wnd, SHOW_WINDOW, 0, 0);
  78.     }
  79.     return wnd;
  80. }
  81.  
  82. /* -------- add a title to a window --------- */
  83. void AddTitle(WINDOW wnd, const char *ttl)
  84. {
  85.     InsertTitle(wnd, ttl);
  86.     SendMessage(wnd, BORDER, 0, 0);
  87. }
  88.  
  89. /* ----- insert a title into a window ---------- */
  90. void InsertTitle(WINDOW wnd, const char *ttl)
  91. {
  92.     wnd->title=DFrealloc(wnd->title,strlen(ttl)+1);
  93.     strcpy(wnd->title, ttl);
  94. }
  95.  
  96. static unsigned char line[300];
  97.  
  98. /* ------ write a line to video window client area ------ */
  99. void writeline(WINDOW wnd, char *str, int x, int y, BOOL pad)
  100. {
  101.     char *cp;
  102.     int len;
  103.     int dif;
  104.     char wline[200];
  105.  
  106.     memset(wline, 0, 200);
  107.     len = LineLength(str);
  108.     dif = strlen(str) - len;
  109.     strncpy(wline, str, ClientWidth(wnd) + dif);
  110.     if (pad)    {
  111.         cp = wline+strlen(wline);
  112.         while (len++ < ClientWidth(wnd)-x)
  113.             *cp++ = ' ';
  114.     }
  115.     wputs(wnd, wline, x, y);
  116. }
  117.  
  118. RECT AdjustRectangle(WINDOW wnd, RECT rc)
  119. {
  120.     /* -------- adjust the rectangle ------- */
  121.     if (TestAttribute(wnd, HASBORDER))    {
  122.         if (RectLeft(rc) == 0)
  123.             --rc.rt;
  124.         else if (RectLeft(rc) < RectRight(rc) &&
  125.                 RectLeft(rc) < WindowWidth(wnd)+1)
  126.             --rc.lf;
  127.     }
  128.     if (TestAttribute(wnd, HASBORDER | HASTITLEBAR))    {
  129.         if (RectTop(rc) == 0)
  130.             --rc.bt;
  131.         else if (RectTop(rc) < RectBottom(rc) &&
  132.                 RectTop(rc) < WindowHeight(wnd)+1)
  133.             --rc.tp;
  134.     }
  135.     RectRight(rc) = max(RectLeft(rc),
  136.                         min(RectRight(rc),WindowWidth(wnd)));
  137.     RectBottom(rc) = max(RectTop(rc),
  138.                         min(RectBottom(rc),WindowHeight(wnd)));
  139.     return rc;
  140. }
  141.  
  142. /* -------- display a window's title --------- */
  143. void DisplayTitle(WINDOW wnd, RECT *rcc)
  144. {
  145.     if (GetTitle(wnd) != NULL)    {
  146.         int tlen = min(strlen(GetTitle(wnd)), WindowWidth(wnd)-2);
  147.         int tend = WindowWidth(wnd)-3-BorderAdj(wnd);
  148.         RECT rc;
  149.  
  150.         if (rcc == NULL)
  151.             rc = RelativeWindowRect(wnd, WindowRect(wnd));
  152.         else
  153.             rc = *rcc;
  154.         rc = AdjustRectangle(wnd, rc);
  155.  
  156.         if (SendMessage(wnd, TITLE, (PARAM) rcc, 0))    {
  157.             if (wnd == inFocus)    {
  158.                 foreground = cfg.clr[TITLEBAR] [HILITE_COLOR] [FG];
  159.                 background = cfg.clr[TITLEBAR] [HILITE_COLOR] [BG];
  160.             }
  161.             else    {
  162.                 foreground = cfg.clr[TITLEBAR] [STD_COLOR] [FG];
  163.                 background = cfg.clr[TITLEBAR] [STD_COLOR] [BG];
  164.             }
  165.             memset(line,' ',WindowWidth(wnd));
  166. #ifdef INCLUDE_MINIMIZE
  167.             if (wnd->condition != ISMINIMIZED)
  168. #endif
  169.                 strncpy(line + ((WindowWidth(wnd)-2 - tlen) / 2),
  170.                     wnd->title, tlen);
  171.             if (TestAttribute(wnd, CONTROLBOX))
  172.                 line[2-BorderAdj(wnd)] = CONTROLBOXCHAR;
  173.             if (TestAttribute(wnd, MINMAXBOX))    {
  174.                 switch (wnd->condition)    {
  175.                     case ISRESTORED:
  176. #ifdef INCLUDE_MAXIMIZE
  177.                         line[tend+1] = MAXPOINTER;
  178. #endif
  179. #ifdef INCLUDE_MINIMIZE
  180.                         line[tend]   = MINPOINTER;
  181. #endif
  182.                         break;
  183. #ifdef INCLUDE_MINIMIZE
  184.                     case ISMINIMIZED:
  185.                         line[tend+1] = MAXPOINTER;
  186.                         break;
  187. #endif
  188. #ifdef INCLUDE_MAXIMIZE
  189.                     case ISMAXIMIZED:
  190. #ifdef INCLUDE_MINIMIZE
  191.                         line[tend]   = MINPOINTER;
  192. #endif
  193. #ifdef INCLUDE_RESTORE
  194.                         line[tend+1] = RESTOREPOINTER;
  195. #endif
  196.                         break;
  197. #endif
  198.                     default:
  199.                         break;
  200.                 }
  201.             }
  202.             line[RectRight(rc)+1] = line[tend+3] = '\0';
  203.             if (wnd != inFocus)
  204.                 ClipString++;
  205.             writeline(wnd, line+RectLeft(rc),
  206.                            RectLeft(rc)+BorderAdj(wnd),
  207.                            0,
  208.                            FALSE);
  209.             ClipString = 0;
  210.         }
  211.     }
  212. }
  213.  
  214. #ifdef INCLUDE_MINIMIZE
  215. #define MinTest() (wnd->condition == ISMINIMIZED) ||
  216. #else
  217. #define MinTest() /**/
  218. #endif
  219.  
  220. #ifdef INCLUDE_MAXIMIZE
  221. #define MaxTest() (wnd->condition == ISMAXIMIZED) ||
  222. #else
  223. #define MaxTest() /**/
  224. #endif
  225.  
  226. #define NoShadow(wnd)                    \
  227.      (TestAttribute(wnd, SHADOW) == 0 || \
  228.       MinTest()                          \
  229.       MaxTest()                          \
  230.       cfg.mono)
  231.  
  232. /* --- display right border shadow character of a window --- */
  233. static void near shadow_char(WINDOW wnd, int y)
  234. {
  235.     int fg = foreground;
  236.     int bg = background;
  237.     int x = WindowWidth(wnd);
  238.     int c = videochar(GetLeft(wnd)+x, GetTop(wnd)+y);
  239.  
  240.     if (NoShadow(wnd))
  241.         return;
  242.     foreground = DARKGRAY;
  243.     background = BLACK;
  244.     wputch(wnd, c, x, y);
  245.     foreground = fg;
  246.     background = bg;
  247. }
  248.  
  249. /* --- display the bottom border shadow line for a window -- */
  250. static void near shadowline(WINDOW wnd, RECT rc)
  251. {
  252.     int i;
  253.     int y = GetBottom(wnd)+1;
  254.     int fg = foreground;
  255.     int bg = background;
  256.  
  257.     if (NoShadow(wnd))
  258.         return;
  259.     for (i = 0; i < WindowWidth(wnd)+1; i++)
  260.         line[i] = videochar(GetLeft(wnd)+i, y);
  261.     line[i] = '\0';
  262.     foreground = DARKGRAY;
  263.     background = BLACK;
  264.     line[RectRight(rc)+1] = '\0';
  265.     if (RectLeft(rc) == 0)
  266.         rc.lf++;
  267.     ClipString++;
  268.     wputs(wnd, line+RectLeft(rc), RectLeft(rc),
  269.         WindowHeight(wnd));
  270.     --ClipString;
  271.     foreground = fg;
  272.     background = bg;
  273. }
  274.  
  275. static RECT ParamRect(WINDOW wnd, RECT *rcc)
  276. {
  277.     RECT rc;
  278.     if (rcc == NULL)    {
  279.         rc = RelativeWindowRect(wnd, WindowRect(wnd));
  280.         if (TestAttribute(wnd, SHADOW))    {
  281.             rc.rt++;
  282.             rc.bt++;
  283.         }
  284.     }
  285.     else
  286.         rc = *rcc;
  287.     return rc;
  288. }
  289.  
  290. void PaintShadow(WINDOW wnd)
  291. {
  292.     int y;
  293.     RECT rc = ParamRect(wnd, NULL);
  294.     for (y = 1; y < WindowHeight(wnd); y++)
  295.         shadow_char(wnd, y);
  296.     shadowline(wnd, rc);
  297. }
  298.  
  299. static unsigned int SeCorner(WINDOW wnd, unsigned int stdse)
  300. {
  301.     if (TestAttribute(wnd, SIZEABLE) && wnd->condition == ISRESTORED)
  302.         return SIZETOKEN;
  303.     return stdse;
  304. }
  305.  
  306. /* ------- display a window's border ----- */
  307. void RepaintBorder(WINDOW wnd, RECT *rcc)
  308. {
  309.     int y;
  310.     unsigned int lin, side, ne, nw, se, sw;
  311.     RECT rc, clrc;
  312.  
  313.     if (!TestAttribute(wnd, HASBORDER))
  314.         return;
  315.     rc = ParamRect(wnd, rcc);
  316.     clrc = AdjustRectangle(wnd, rc);
  317.  
  318.     if (wnd == inFocus)    {
  319.         lin  = FOCUS_LINE;
  320.         side = FOCUS_SIDE;
  321.         ne   = FOCUS_NE;
  322.         nw   = FOCUS_NW;
  323.         se   = SeCorner(wnd, FOCUS_SE);
  324.         sw   = FOCUS_SW;
  325.     }
  326.     else    {
  327.         lin  = LINE;
  328.         side = SIDE;
  329.         ne   = NE;
  330.         nw   = NW;
  331.         se   = SeCorner(wnd, SE);
  332.         sw   = SW;
  333.     }
  334.     line[WindowWidth(wnd)] = '\0';
  335.     /* ---------- window title ------------ */
  336.     if (TestAttribute(wnd, HASTITLEBAR))
  337.         if (RectTop(rc) == 0)
  338.             if (RectLeft(rc) < WindowWidth(wnd)-BorderAdj(wnd))
  339.                 DisplayTitle(wnd, &rc);
  340.     foreground = FrameForeground(wnd);
  341.     background = FrameBackground(wnd);
  342.     /* -------- top frame corners --------- */
  343.     if (RectTop(rc) == 0)    {
  344.         if (RectLeft(rc) == 0)
  345.             wputch(wnd, nw, 0, 0);
  346.         if (RectLeft(rc) < WindowWidth(wnd))    {
  347.             if (RectRight(rc) >= WindowWidth(wnd)-1)
  348.                 wputch(wnd, ne, WindowWidth(wnd)-1, 0);
  349.             TopLine(wnd, lin, clrc);
  350.         }
  351.     }
  352.  
  353.     /* ----------- window body ------------ */
  354.     for (y = RectTop(rc); y <= RectBottom(rc); y++)    {
  355.         int ch;
  356.         if (y == 0 || y >= WindowHeight(wnd)-1)
  357.             continue;
  358.         if (RectLeft(rc) == 0)
  359.             wputch(wnd, side, 0, y);
  360.         if (RectLeft(rc) < WindowWidth(wnd) &&
  361.                 RectRight(rc) >= WindowWidth(wnd)-1)    {
  362.             if (TestAttribute(wnd, VSCROLLBAR))
  363.                 ch = (    y == 1 ? UPSCROLLBOX      :
  364.                           y == WindowHeight(wnd)-2  ?
  365.                                 DOWNSCROLLBOX       :
  366.                           y-1 == wnd->VScrollBox    ?
  367.                                 SCROLLBOXCHAR       :
  368.                           SCROLLBARCHAR );
  369.             else
  370.                 ch = side;
  371.             wputch(wnd, ch, WindowWidth(wnd)-1, y);
  372.         }
  373.         if (RectRight(rc) == WindowWidth(wnd))
  374.             shadow_char(wnd, y);
  375.     }
  376.  
  377.     if (RectTop(rc) <= WindowHeight(wnd)-1 &&
  378.             RectBottom(rc) >= WindowHeight(wnd)-1)    {
  379.         /* -------- bottom frame corners ---------- */
  380.         if (RectLeft(rc) == 0)
  381.             wputch(wnd, sw, 0, WindowHeight(wnd)-1);
  382.         if (RectLeft(rc) < WindowWidth(wnd) &&
  383.                 RectRight(rc) >= WindowWidth(wnd)-1)
  384.             wputch(wnd, se, WindowWidth(wnd)-1,
  385.                 WindowHeight(wnd)-1);
  386.  
  387.  
  388.         if (wnd->StatusBar == NULL)    {
  389.             /* ----------- bottom line ------------- */
  390.             memset(line,lin,WindowWidth(wnd)-1);
  391.             if (TestAttribute(wnd, HSCROLLBAR))    {
  392.                 line[0] = LEFTSCROLLBOX;
  393.                 line[WindowWidth(wnd)-3] = RIGHTSCROLLBOX;
  394.                 memset(line+1, SCROLLBARCHAR, WindowWidth(wnd)-4);
  395.                 line[wnd->HScrollBox] = SCROLLBOXCHAR;
  396.             }
  397.             line[WindowWidth(wnd)-2] = line[RectRight(rc)] = '\0';
  398.             if (RectLeft(rc) != RectRight(rc) ||
  399.                 (RectLeft(rc) && RectLeft(rc) < WindowWidth(wnd)-1))    {
  400.                 if (wnd != inFocus)
  401.                     ClipString++;
  402.                 writeline(wnd,
  403.                             line+(RectLeft(clrc)),
  404.                             RectLeft(clrc)+1,
  405.                             WindowHeight(wnd)-1,
  406.                             FALSE);
  407.                 ClipString = 0;
  408.             }
  409.         }
  410.         if (RectRight(rc) == WindowWidth(wnd))
  411.             shadow_char(wnd, WindowHeight(wnd)-1);
  412.     }
  413.     if (RectBottom(rc) == WindowHeight(wnd))
  414.         /* ---------- bottom shadow ------------- */
  415.         shadowline(wnd, rc);
  416. }
  417.  
  418. static void TopLine(WINDOW wnd, int lin, RECT rc)
  419. {
  420.     if (TestAttribute(wnd, HASMENUBAR))
  421.         return;
  422.     if (TestAttribute(wnd, HASTITLEBAR) && GetTitle(wnd))
  423.         return;
  424.     if (RectLeft(rc) == 0)    {
  425.         RectLeft(rc) += BorderAdj(wnd);
  426.         RectRight(rc) += BorderAdj(wnd);
  427.     }
  428.     if (RectRight(rc) < WindowWidth(wnd)-1)
  429.         RectRight(rc)++;
  430.  
  431.     if (RectLeft(rc) < RectRight(rc))    {
  432.         /* ----------- top line ------------- */
  433.         memset(line,lin,WindowWidth(wnd)-1);
  434.         if (TestAttribute(wnd, CONTROLBOX))    {
  435.             strncpy(line+1, "   ", 3);
  436.             *(line+2) = CONTROLBOXCHAR;
  437.         }
  438.         line[RectRight(rc)] = '\0';
  439.         writeline(wnd, line+RectLeft(rc),
  440.             RectLeft(rc), 0, FALSE);
  441.     }
  442. }
  443.  
  444. /* ------ clear the data space of a window -------- */
  445. void ClearWindow(WINDOW wnd, RECT *rcc, int clrchar)
  446. {
  447.     if (isVisible(wnd))    {
  448.         int y;
  449.         RECT rc = rcc ? *rcc : RelativeWindowRect(wnd, WindowRect(wnd));
  450.  
  451.         int top = TopBorderAdj(wnd);
  452.         int bot = WindowHeight(wnd)-1-BottomBorderAdj(wnd);
  453.  
  454.         if (RectLeft(rc) == 0)
  455.             RectLeft(rc) = BorderAdj(wnd);
  456.         if (RectRight(rc) > WindowWidth(wnd)-1)
  457.             RectRight(rc) = WindowWidth(wnd)-1;
  458.         SetStandardColor(wnd);
  459.         memset(line, clrchar, sizeof line);
  460.         line[RectRight(rc)+1] = '\0';
  461.         for (y = RectTop(rc); y <= RectBottom(rc); y++)    {
  462.             if (y < top || y > bot)
  463.                 continue;
  464.             writeline(wnd,
  465.                 line+(RectLeft(rc)),
  466.                 RectLeft(rc),
  467.                 y,
  468.                 FALSE);
  469.         }
  470.     }
  471. }
  472.  
  473. /* ------ compute the logical line length of a window ------ */
  474. int LineLength(char *ln)
  475. {
  476.     int len = strlen(ln);
  477.     char *cp = ln;
  478.     while ((cp = strchr(cp, CHANGECOLOR)) != NULL)    {
  479.         cp++;
  480.         len -= 3;
  481.     }
  482.     cp = ln;
  483.     while ((cp = strchr(cp, RESETCOLOR)) != NULL)    {
  484.         cp++;
  485.         --len;
  486.     }
  487.     return len;
  488. }
  489.  
  490. void InitWindowColors(WINDOW wnd)
  491. {
  492.     int fbg,col;
  493.     int cls = GetClass(wnd);
  494.     /* window classes without assigned colors inherit parent's colors */
  495.     if (cfg.clr[cls][0][0] == 0xff && GetParent(wnd) != NULL)
  496.         cls = GetClass(GetParent(wnd));
  497.     /* ---------- set the colors ---------- */
  498.     for (fbg = 0; fbg < 2; fbg++)
  499.         for (col = 0; col < 4; col++)
  500.             wnd->WindowColors[col][fbg] = cfg.clr[cls][col][fbg];
  501. }
  502.  
  503. void PutWindowChar(WINDOW wnd, int c, int x, int y)
  504. {
  505.     if (x < ClientWidth(wnd) && y < ClientHeight(wnd))
  506.         wputch(wnd, c, x+BorderAdj(wnd), y+TopBorderAdj(wnd));
  507. }
  508.  
  509. void PutWindowLine(WINDOW wnd, void *s, int x, int y)
  510. {
  511.     int saved = FALSE, sv;
  512.     if (x < ClientWidth(wnd) && y < ClientHeight(wnd))    {
  513.         char *en = (char *)s+ClientWidth(wnd)-x;
  514.         if (strlen(s)+x > ClientWidth(wnd))    {
  515.             sv = *en;
  516.             *en = '\0';
  517.             saved = TRUE;
  518.         }
  519.         ClipString++;
  520.         wputs(wnd, s, x+BorderAdj(wnd), y+TopBorderAdj(wnd));
  521.         --ClipString;
  522.         if (saved)
  523.             *en = sv;
  524.     }
  525. }
  526.  
  527. 
  528.