home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: Graphics / Graphics.zip / xfitsvew.zip / XFITSview / scrolltext.c < prev    next >
C/C++ Source or Header  |  1997-06-06  |  14KB  |  417 lines

  1. /* ScrollText routines for XFITSview */
  2. /* Scrollable boxes displaying text */
  3. /*-----------------------------------------------------------------------
  4. *  Copyright (C) 1996
  5. *  Associated Universities, Inc. Washington DC, USA.
  6. *  This program is free software; you can redistribute it and/or
  7. *  modify it under the terms of the GNU General Public License as
  8. *  published by the Free Software Foundation; either version 2 of
  9. *  the License, or (at your option) any later version.
  10. *
  11. *  This program is distributed in the hope that it will be useful,
  12. *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. *  GNU General Public License for more details.
  15. *-----------------------------------------------------------------------*/
  16. #include <stdlib.h>
  17. #include <Xm/Xm.h> 
  18. #include <Xm/DialogS.h> 
  19. #include <Xm/DrawingA.h> 
  20. #include <Xm/MainW.h>
  21. #include <Xm/ScrollBar.h>
  22. #include <Xm/Form.h>
  23. #include <Xm/ScrolledW.h>
  24. #include <Xm/PushB.h>
  25. #include <X11/Intrinsic.h>
  26. #include "scrolltext.h"
  27. #include "messagebox.h"
  28.  
  29. #define SCROLLBOX_WIDTH  500  /* Width of scroll box */
  30. #define SCROLLBOX_HEIGHT 420  /* Height of scroll box */
  31. #define MAXCHAR_LINE     132  /* maximum number of characters in a line */
  32. /* internal function prototypes */
  33. /* resize event */
  34. void STextResizeCB (Widget w, XtPointer clientData, XtPointer callData);
  35. /* scrollbar changed */
  36. void STextScrollCB (Widget w, XtPointer clientData, XtPointer callData);
  37. /* Dismiss button hit */
  38. void STextDismissButCB (Widget w, XtPointer clientData, XtPointer callData);
  39.  
  40. /* public functions */
  41. /* create ScrollText and fill it with the contents of a TextFile */
  42. /* argument actually a TextFilePtr - which is destroyed*/
  43. void ScrollTextCopy (XPointer TFilePtr)
  44. {
  45.   ScrollTextPtr STextPtr;
  46.   TextFilePtr   TFile;
  47.   int rcode;
  48.  
  49. /* make it */
  50.   TFile = (TextFilePtr)TFilePtr;
  51.   STextPtr = ScrollTextMake (TFile->w, TFile->FileName);
  52.  
  53. /* copy text */
  54.   rcode = 0;
  55.   if (STextPtr) rcode = ScrollTextFill(STextPtr, TFile);
  56.  
  57. /* Error Message */
  58.   if (!rcode) MessageShow ("Error loading text file to scrolling window");
  59.  
  60. /* delete TextFile */
  61.   TextFileKill(TFile);
  62.  
  63. /* delete ScrollText if something went wrong */
  64.   if (!rcode) ScrollTextKill(STextPtr);
  65. } /* end ScrollTextCopy */
  66.  
  67. /* create/initialize ScrollText structures */
  68. ScrollTextPtr ScrollTextMake (Widget Parent, char* Title)
  69. {
  70.   ScrollTextPtr STextPtr;
  71.   int loop;
  72.   Dimension text_width, text_height, scrollbar_width, butt_height;
  73.   Widget form, DismissButton;
  74.   XFontStruct *XFont;
  75.   int value, increment, slider_size,page_increment;
  76.  
  77. /* allocate */
  78.   STextPtr = (ScrollTextPtr)malloc (sizeof(ScrollTextInfo));
  79.   if (!STextPtr) return NULL;
  80.  
  81. /* initialize */
  82.   STextPtr->Parent = Parent;
  83.   STextPtr->DismissProc = NULL;
  84.   STextPtr->num_lines = 0;
  85.   STextPtr->first = 0;
  86.   STextPtr->number = 0;
  87.   STextPtr->max_lines = 0;
  88.   STextPtr->Title = (char*)malloc(strlen(Title)+1);
  89.   strcpy (STextPtr->Title, Title);
  90.   for (loop=0; loop<MAX_LINE; loop++) STextPtr->lines[loop] = NULL;
  91.  
  92. /* create main widget */
  93.     STextPtr->ScrollBox = 
  94.       XtVaCreatePopupShell (STextPtr->Title,
  95.                 xmDialogShellWidgetClass, 
  96.                 STextPtr->Parent,
  97.                 XmNautoUnmanage, False,
  98.                 XmNwidth,  (Dimension)SCROLLBOX_WIDTH,
  99.                 XmNheight, (Dimension)SCROLLBOX_HEIGHT,
  100.                 XmNdeleteResponse, XmDESTROY,
  101.                 NULL);
  102.  
  103. /* make Form widget to stick things on */
  104.   form = XtVaCreateManagedWidget ("ScrollTextForm", xmFormWidgetClass,
  105.                   STextPtr->ScrollBox,
  106.                   XmNautoUnmanage, False,
  107.                   XmNwidth,  (Dimension)SCROLLBOX_WIDTH,
  108.                   XmNheight, (Dimension)SCROLLBOX_HEIGHT,
  109.                   XmNx,           0,
  110.                   XmNy,           0,
  111.                   NULL);
  112.  
  113. /* Play button */
  114.   DismissButton = 
  115.     XtVaCreateManagedWidget (" Dismiss ", 
  116.                  xmPushButtonWidgetClass, 
  117.                  form, 
  118.                  XmNbottomAttachment, XmATTACH_FORM,
  119.                  XmNrightAttachment, XmATTACH_FORM,
  120.                  XmNleftAttachment,  XmATTACH_FORM,
  121.                  NULL);
  122.   XtAddCallback (DismissButton, XmNactivateCallback, STextDismissButCB, 
  123.          (XtPointer)STextPtr);
  124.  
  125. /* drawing area */
  126.   scrollbar_width = 15;
  127.   text_width = SCROLLBOX_WIDTH - scrollbar_width;
  128.   XtVaGetValues (DismissButton, XmNheight, &butt_height, NULL);
  129.   text_height = SCROLLBOX_HEIGHT - butt_height;
  130.   STextPtr->TextDraw_wid = text_width;
  131.   STextPtr->TextDraw_hei = text_height;
  132.   value = 1;
  133.   slider_size = 20;
  134.   increment = 1;
  135.   page_increment = 20;
  136. /* plane scroll */
  137.   STextPtr->TextScrollBar = 
  138.     XtVaCreateManagedWidget ("TextScrollBar", 
  139.                  xmScrollBarWidgetClass, 
  140.                  form,
  141.                  XmNheight,       text_height,
  142.                  XmNwidth,        scrollbar_width,
  143.                  XmNmaximum,         200,
  144.                  XmNminimum,           1,
  145.                  XmNvalue,             1,
  146.                  XmNshowValue,       True,
  147.                  XmNorientation,   XmVERTICAL,
  148.                  XmNprocessingDirection, XmMAX_ON_BOTTOM,
  149.                  XmNrightAttachment,  XmATTACH_FORM,
  150.                  XmNtopAttachment, XmATTACH_FORM,
  151.                  XmNbottomAttachment,  XmATTACH_WIDGET,
  152.                  XmNbottomWidget,      DismissButton,
  153.                  NULL);
  154.   XmScrollBarSetValues (STextPtr->TextScrollBar, value, slider_size, 
  155.             increment, page_increment, False);
  156.   XtAddCallback(STextPtr->TextScrollBar, XmNvalueChangedCallback, 
  157.                 STextScrollCB, (XtPointer)STextPtr);
  158.   STextPtr->max_scroll = 200; /* maximum scroll value */
  159.  
  160.   STextPtr->TextDraw = 
  161.     XtVaCreateManagedWidget ("textdraw", xmDrawingAreaWidgetClass, 
  162.                  form, 
  163.                  XmNwidth,              text_width,
  164.                  XmNheight,             text_height,
  165.                  XmNtopAttachment,   XmATTACH_FORM,
  166.                  XmNleftAttachment,  XmATTACH_FORM,
  167.                  XmNrightAttachment,  XmATTACH_WIDGET,
  168.                  XmNrightWidget,  STextPtr->TextScrollBar,
  169.                  XmNbottomAttachment,  XmATTACH_WIDGET,
  170.                  XmNbottomWidget,      DismissButton,
  171.                  NULL); 
  172. /*   Add callbacks to handle exposures,resize.  */
  173.   XtAddCallback (STextPtr->TextDraw, XmNexposeCallback, STextExposeCB, 
  174.          (XtPointer)STextPtr);
  175.   XtAddCallback (STextPtr->TextDraw, XmNresizeCallback, STextResizeCB,
  176.          (XtPointer)STextPtr);
  177.  
  178. /* set it up */
  179.   XtManageChild (STextPtr->ScrollBox);
  180.  
  181. /* create graphics context for box */
  182.   STextPtr->gc = XCreateGC (XtDisplay (STextPtr->ScrollBox), 
  183.               DefaultRootWindow (XtDisplay(STextPtr->ScrollBox)),
  184.               0, NULL );
  185. /* how tall are the characters */
  186.   XFont = XQueryFont(XtDisplay (STextPtr->ScrollBox), 
  187.              XGContextFromGC(STextPtr->gc));
  188.   STextPtr->baseskip = XFont->ascent + XFont->descent + 2;
  189.   
  190. /* figure out how many lines will fit */
  191.   STextPtr->max_lines = ((int)text_height) / STextPtr->baseskip;
  192.  
  193.  
  194. return STextPtr; /* return structure */
  195. } /* end ScrollTextMake */
  196.  
  197. /* destroy ScrollText structures */
  198. /* returns 1 if OK */
  199. int ScrollTextKill( ScrollTextPtr STextPtr)
  200. {
  201.   int loop;
  202.  
  203.   if (!STextPtr) return 0; /* anybody home? */
  204.  
  205. /* free up text strings */
  206.   for (loop=0; loop<MAX_LINE; loop++) 
  207.     {if (STextPtr->lines[loop]) {free (STextPtr->lines[loop]);}}
  208.   if (STextPtr->Title) free (STextPtr->Title);
  209.  
  210.   /* release graphics context */
  211.   if (STextPtr->gc) XtReleaseGC (STextPtr->ScrollBox, STextPtr->gc);
  212.  
  213. /* kill da wabbit */
  214.   XtDestroyWidget (STextPtr->ScrollBox);
  215.   free(STextPtr); /* done with this */
  216.  
  217.   return 1;
  218. } /* end ScrollTextKill */
  219.  
  220. /* copy text from TextFile to ScrollText */
  221. /* returns 1 if OK */
  222. int ScrollTextFill (ScrollTextPtr STextPtr, TextFilePtr TFilePtr)
  223. {
  224.   int loop, rcode, ccode, HitEof, length, number, maxchar=MAXCHAR_LINE;
  225.   char line[MAXCHAR_LINE+1];
  226.  
  227.   if (!STextPtr) return 0; /* anybody home? */
  228.  
  229.   for (loop=0; loop<=MAXCHAR_LINE; loop++) line[loop] = 0; /* zero fill */
  230.  
  231.   rcode = TextFileOpen (TFilePtr, 1); /* open */
  232.   if (rcode!=1) return 0;
  233.   HitEof = 0; number = 0;
  234.   while (!HitEof && (number<MAX_LINE))
  235.     {rcode = TextFileRead (TFilePtr, line, maxchar); /* next line */
  236.       if (rcode==0) break;
  237.      /* swallow line */
  238.      length = strlen (line);
  239.      STextPtr->lines[number] = (char*)malloc (length+1);
  240.      strcpy (STextPtr->lines[number], line);
  241.      HitEof = rcode == -1; /* end of file */
  242.      number++;             /* count entries */
  243.    } /* end of loop reading text file */
  244.   STextPtr->num_lines = number;
  245.  
  246.   ccode = TextFileClose (TFilePtr); /* close */
  247.   if ((ccode!=1) || (rcode==0)) 
  248.     {MessageShow ("Error closing Text/FITS file ");
  249.      return 0;} /* error */
  250. /* final setup */
  251.   ScrollTextInit (STextPtr);
  252.   return 1;
  253. } /* end ScrollTextFill */
  254.  
  255. /* Initialization of ScrollText after text strings loaded */
  256. void ScrollTextInit (ScrollTextPtr STextPtr)
  257. {
  258.   Dimension cwid, chei;
  259.   int number;
  260.   int value, increment, slider_size,page_increment;
  261.  
  262.   if (!STextPtr) return; /* anybody home? */
  263.  
  264. /* find size */
  265.   XtVaGetValues (STextPtr->TextDraw, /* get new size */
  266.          XmNwidth, &cwid,
  267.          XmNheight, &chei,
  268.          NULL);
  269.   STextPtr->TextDraw_hei = chei;
  270.   STextPtr->TextDraw_wid = cwid;
  271.  
  272. /* number of lines shown*/
  273.   STextPtr->max_lines = (int)chei / STextPtr->baseskip;
  274.   STextPtr->number = STextPtr->max_lines;
  275.  
  276. /* set up for the expose callback to draw */
  277.   STextPtr->first = 1;
  278.   STextPtr->number = STextPtr->max_lines;
  279.   if (STextPtr->number > STextPtr->num_lines) 
  280.     STextPtr->number = STextPtr->num_lines;
  281.   
  282. /* need scroll bars? */
  283.   if (STextPtr->num_lines > STextPtr->max_lines)
  284. /* set scroll bar */
  285.     {number = STextPtr->num_lines + 5;
  286.      if (number<2) number = 2;
  287.      STextPtr->max_scroll = number; /* maximum scroll value */
  288.      if (STextPtr->first>STextPtr->max_scroll) 
  289.        STextPtr->first = STextPtr->max_scroll;
  290.      slider_size = STextPtr->number; 
  291.      value = STextPtr->first;
  292.      if (value>number-slider_size) value = number-slider_size;
  293.      STextPtr->first = value;
  294.      increment = 1;
  295.      page_increment = STextPtr->max_lines-1; 
  296.      if (page_increment<1) page_increment = 1;
  297.      XtVaSetValues(STextPtr->TextScrollBar, 
  298.            XmNminimum,           1,
  299.            XmNmaximum,       number,
  300.            NULL);
  301.      XmScrollBarSetValues (STextPtr->TextScrollBar, value, slider_size, 
  302.             increment, page_increment, False);
  303.     XtMapWidget (STextPtr->TextScrollBar);}
  304.   else
  305.     XtUnmapWidget (STextPtr->TextScrollBar);
  306. } /* end ScrollTextInit */
  307.  
  308. /* internal function prototypes */
  309. /* expose event */
  310. void STextExposeCB (Widget w, XtPointer clientData, XtPointer callData)
  311. {
  312.   int loop, start, end, x, y, inc;
  313.   ScrollTextPtr STextPtr = (ScrollTextPtr)clientData;
  314.   Display *display;
  315.   Drawable draw;
  316.   GC       gc;
  317.  
  318.   if (!STextPtr) return; /* anybody home? */
  319.   display = XtDisplay(STextPtr->ScrollBox); /* local copies of variables */
  320.   draw = (Drawable)XtWindow(STextPtr->TextDraw);
  321.   gc = STextPtr->gc;
  322.  
  323. /* blank it out first, draw in white on black background*/
  324.   XSetForeground (display, gc, 
  325.           BlackPixelOfScreen(XtScreen(STextPtr->TextDraw)));
  326.   XFillRectangle (display, draw, 
  327.           gc, 0, 0, STextPtr->TextDraw_wid, 
  328.           STextPtr->TextDraw_hei); 
  329.   XSetForeground (display, gc, 
  330.           WhitePixelOfScreen(XtScreen(STextPtr->TextDraw)));
  331.   
  332.   start = STextPtr->first-1;
  333.   end = start + STextPtr->number - 1;
  334.   if (end>=STextPtr->num_lines) end = STextPtr->num_lines - 1;
  335.   inc = STextPtr->baseskip;
  336.   x = 2; y = inc;
  337.   for (loop=start; loop<=end; loop++)
  338.     {XDrawString (display, draw, gc, x, y, STextPtr->lines[loop], 
  339.           strlen(STextPtr->lines[loop]));
  340.      y += inc;
  341.     } /* end loop loadling rows */
  342. } /* end STextExposeCB */
  343.  
  344. void STextScrollCB (Widget w, XtPointer clientData, XtPointer callData)
  345. /* scrollbar changed */
  346. {
  347.     ScrollTextPtr STextPtr = (ScrollTextPtr)clientData;
  348.     XmScrollBarCallbackStruct *call_data = 
  349.       (XmScrollBarCallbackStruct *)callData;
  350.  
  351. /* read value of scrollbar */
  352.     STextPtr->first = call_data->value; /* 0 rel */
  353.  
  354. /* redraw */
  355.     STextExposeCB (w, clientData, callData);
  356. } /* end STextScrollCB */
  357.  
  358. /* Dismiss button hit */
  359. void STextDismissButCB (Widget w, XtPointer clientData, XtPointer callData)
  360. {
  361.   ScrollTextPtr STextPtr = (ScrollTextPtr)clientData;
  362.   if (!STextPtr) return; /* anybody home? */
  363.  
  364. /* call any DismissProc */
  365.   if (STextPtr->DismissProc) STextPtr->DismissProc(clientData);
  366.  
  367.   ScrollTextKill (STextPtr);
  368. } /* end STextDismissButCB */
  369.  
  370. /* ScrollText resized */
  371. void STextResizeCB (Widget w, XtPointer clientData, XtPointer callData)
  372. {
  373.   Dimension cwid, chei;
  374.   int number;
  375.   int value, increment, slider_size,page_increment;
  376.   ScrollTextPtr STextPtr = (ScrollTextPtr)clientData;
  377.   if (!STextPtr) return; /* anybody home? */
  378.  
  379. /* find new size */
  380.   XtVaGetValues (STextPtr->TextDraw, /* get new size */
  381.          XmNwidth, &cwid,
  382.          XmNheight, &chei,
  383.          NULL);
  384.   STextPtr->TextDraw_hei = chei;
  385.   STextPtr->TextDraw_wid = cwid;
  386.  
  387. /* new number of lines shown*/
  388.   STextPtr->max_lines = (int)chei / STextPtr->baseskip;
  389.   STextPtr->number = STextPtr->max_lines;
  390.  
  391. /* need scroll bars? */
  392.   if (STextPtr->num_lines > STextPtr->max_lines)
  393.     /* reset Scroll Bar size, limits */
  394.     {number = STextPtr->num_lines + 5;
  395.      STextPtr->max_scroll = number; /* maximum scroll value */
  396.      if (STextPtr->first>STextPtr->max_scroll) 
  397.        STextPtr->first = STextPtr->max_scroll;
  398.      slider_size = STextPtr->number; 
  399.      value = STextPtr->first;
  400.      if (value>number-slider_size) value = number-slider_size;
  401.      STextPtr->first = value;
  402.      increment = 1;
  403.      page_increment = STextPtr->max_lines-1;
  404.      XtVaSetValues(STextPtr->TextScrollBar, XmNmaximum, number, NULL);
  405.      XmScrollBarSetValues (STextPtr->TextScrollBar, value, slider_size, 
  406.                increment, page_increment, False);
  407.  
  408.     XtMapWidget (STextPtr->TextScrollBar);}
  409.   else
  410.     XtUnmapWidget (STextPtr->TextScrollBar);
  411.  
  412. /* redraw */
  413.     STextExposeCB (w, clientData, callData);
  414. } /* end STextResizeCB */
  415.  
  416.  
  417.