source: trunk/athena/bin/xmore/ScrollByLine.c @ 2969

Revision 2969, 24.9 KB checked in by epeisach, 34 years ago (diff)
Coverted to X11R4
Line 
1/*
2 * xman - X window system manual page display program.
3 *
4 * $XConsortium: ScrollByL.c,v 1.5 89/01/06 18:41:40 kit Exp $
5 * $Header: /afs/dev.mit.edu/source/repository/athena/bin/xmore/ScrollByLine.c,v 1.4 1990-05-01 14:49:05 epeisach Exp $
6 *
7 * Copyright 1987, 1988 Massachusetts Institute of Technology
8 *
9 * Permission to use, copy, modify, and distribute this software and its
10 * documentation for any purpose and without fee is hereby granted, provided
11 * that the above copyright notice appear in all copies and that both that
12 * copyright notice and this permission notice appear in supporting
13 * documentation, and that the name of M.I.T. not be used in advertising or
14 * publicity pertaining to distribution of the software without specific,
15 * written prior permission.  M.I.T. makes no representations about the
16 * suitability of this software for any purpose.  It is provided "as is"
17 * without express or implied warranty.
18 *
19 * Author:    Chris D. Peterson, MIT Project Athena
20 * Created:   December 5, 1987
21 */
22
23#if ( !defined(lint) && !defined(SABER))
24  static char rcs_version[] = "$Athena: ScrollByL.c,v 4.5 88/12/19 13:46:04 kit Exp $";
25#endif
26
27/*
28 * I wrote this widget before I knew what form did, and it shows, since
29 * the "right" way to do this widget would be to subclass it to form,
30 * and do it much more like the Viewport widget in the Athena widget set.
31 * But this works and time is short, so here it is.
32 *
33 *                                     Chris D. Peterson 1/30/88
34 *
35 * I removed all the code for horizontal scrolling here, since is was a crock
36 * anyway.
37 *
38 *                                     Chris D. Peterson 11/13/88
39 */
40
41#include        <X11/IntrinsicP.h>
42#include        "ScrollByLine.h"
43#include        "ScrollByLineP.h"
44#include        <X11/StringDefs.h>
45#if XtSpecificationRelease < 4
46#include        <X11/Scroll.h>
47#include        <X11/XawMisc.h>
48#else
49#include        <X11/Xaw/Scrollbar.h>
50#define   XtScrollBarSetThumb XawScrollbarSetThumb
51#endif
52
53/* Default Translation Table */
54
55static char defaultTranslations[] =
56  "<Btn1Down>:  Page(Forward) \n\
57   <Btn3Down>:  Page(Back) \n\
58   <Key>f:      Page(Forward) \n\
59   <Key>b:      Page(Back) \n\
60   <Key>\\ :    Page(Forward)";
61
62     
63/****************************************************************
64 *
65 * ScrollByLine Resources
66 *
67 ****************************************************************/
68
69static XtResource resources[] = {
70    {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
71         XtOffset(ScrollByLineWidget, scroll_by_line.foreground),
72         XtRString, "XtDefaultForeground"},
73    {XtNinnerWidth, XtCWidth, XtRInt, sizeof(int),
74         XtOffset(ScrollByLineWidget, scroll_by_line.inner_width),
75         XtRString, "100"},
76    {XtNinnerHeight, XtCHeight, XtRInt, sizeof(int),
77         XtOffset(ScrollByLineWidget, scroll_by_line.inner_height),
78         XtRString, "100"},
79    {XtNforceBars, XtCBoolean, XtRBoolean, sizeof(Boolean),
80         XtOffset(ScrollByLineWidget, scroll_by_line.force_bars),
81         XtRString, "FALSE"},
82    {XtNallowVert, XtCBoolean, XtRBoolean, sizeof(Boolean),
83         XtOffset(ScrollByLineWidget, scroll_by_line.allow_vert),
84         XtRString, "FALSE"},
85    {XtNuseRight, XtCBoolean, XtRBoolean, sizeof(Boolean),
86         XtOffset(ScrollByLineWidget, scroll_by_line.use_right),
87         XtRString, "FALSE"},
88    {XtNlines, XtCLine, XtRInt, sizeof(int),
89         XtOffset(ScrollByLineWidget, scroll_by_line.lines),
90         XtRString, "1"},
91    {XtNfontHeight, XtCHeight,XtRInt, sizeof(int),
92         XtOffset(ScrollByLineWidget, scroll_by_line.font_height),
93         XtRString, "0"},
94    {XtNcallback, XtCCallback, XtRCallback, sizeof(caddr_t),
95       XtOffset(ScrollByLineWidget, scroll_by_line.callbacks),
96       XtRCallback, (caddr_t) NULL},
97    {XtNformOnInner, XtCBoolean, XtRBoolean, sizeof(Boolean),
98       XtOffset(ScrollByLineWidget, scroll_by_line.key),
99       XtRString, "FALSE"},
100};
101
102/****************************************************************
103 *
104 * Full class record constant
105 *
106 ****************************************************************/
107
108static Boolean ScrollVerticalText();
109static void VerticalThumb();
110static void VerticalScroll();
111static void Page();
112static void InitializeHook();
113static void Initialize();
114static void Realize();
115static void Resize();
116static void ResetThumb();
117static void Redisplay();
118static void ChildExpose();
119static Boolean SetValues();
120static Boolean Layout();
121static XtGeometryResult GeometryManager();
122static void ChangeManaged();
123
124static XtActionsRec actions[] = {
125  { "Page",   Page},
126  { NULL, NULL},
127};
128
129ScrollByLineClassRec scrollByLineClassRec = {
130  {
131/* core_class fields      */
132    /* superclass         */    (WidgetClass) &compositeClassRec,
133    /* class_name         */    "ScrollByLine",
134    /* widget_size        */    sizeof(ScrollByLineRec),
135    /* class_initialize   */    NULL,
136    /* class_part_init    */    NULL,
137    /* class_inited       */    FALSE,
138    /* initialize         */    Initialize,
139    /* initialize_hook    */    InitializeHook,
140    /* realize            */    Realize,
141    /* actions            */    actions,
142    /* num_actions        */    XtNumber(actions),
143    /* resources          */    resources,
144    /* num_resources      */    XtNumber(resources),
145    /* xrm_class          */    NULLQUARK,
146    /* compress_motion    */    TRUE,
147    /* compress_exposure  */    FALSE,
148    /* compress_enterleave*/    TRUE,
149    /* visible_interest   */    FALSE,
150    /* destroy            */    NULL,
151    /* resize             */    Resize,
152    /* expose             */    Redisplay,
153    /* set_values         */    SetValues,
154    /* set_values_hook    */    NULL,
155    /* set_values_almost  */    XtInheritSetValuesAlmost,
156    /* get_values_hook    */    NULL,
157    /* accept_focus       */    NULL,
158    /* version            */    XtVersion,
159    /* callback_private   */    NULL,
160    /* tm_table           */    defaultTranslations,
161    /* query_geometry     */    XtInheritQueryGeometry,
162    /* display_accelerator*/    XtInheritDisplayAccelerator,
163    /* extension          */    NULL,
164  },{
165/* composite_class fields */
166    /* geometry_manager   */    GeometryManager,
167    /* change_managed     */    ChangeManaged,
168    /* insert_child       */    XtInheritInsertChild,
169    /* delete_child       */    XtInheritDeleteChild,
170    /* extension          */    NULL,
171  },{
172    /* mumble             */    0       /* Make C compiler happy   */
173  }
174};
175
176WidgetClass scrollByLineWidgetClass =
177            (WidgetClass) &scrollByLineClassRec;
178
179
180/****************************************************************
181 *
182 * Private Routines
183 *
184 ****************************************************************/
185
186
187/*      Function Name: Layout
188 *      Description: This function lays out the scroll_by_line widget.
189 *      Arguments: w - the scroll_by_line widget.
190 *                 key - a boolean: if true then resize the widget to the child
191 *                                  if false the resize children to fit widget.
192 *      Returns: TRUE if successful.
193 */
194
195static Boolean
196Layout(w,key)
197Widget w;
198int key;
199{   
200  ScrollByLineWidget sblw = (ScrollByLineWidget) w;
201  Dimension width,height;       /* The size that the widget would like to be */
202  XtGeometryResult answer;      /* the answer from the parent. */
203  Widget vbar,child;            /* The two children of this scrolled widget. */
204  int vbar_x,vbar_y;            /* The locations of the various elements. */
205  int child_x;
206  int c_width;
207  Boolean make_bar;
208
209  vbar = sblw->composite.children[0];
210  child = sblw->composite.children[1];
211  height = sblw->core.height;
212  width = sblw->core.width;
213
214/* set the initial scroll bar positions. */
215
216  vbar_x = vbar_y = - vbar->core.border_width;
217
218/* Should I allow the vertical scrollbar to be seen */
219
220   make_bar = FALSE; 
221   if ( (!key) && (sblw->scroll_by_line.lines *
222        sblw->scroll_by_line.font_height > height) )
223     make_bar = TRUE;
224
225   else if ( (key) && (sblw->scroll_by_line.lines *
226             sblw->scroll_by_line.font_height > child->core.height) )
227     make_bar = TRUE;
228
229   if (sblw->scroll_by_line.allow_vert && (sblw->scroll_by_line.force_bars ||
230                                       make_bar) ) {
231 /*
232  * Resize the outer window to fit the child, or visa versa.  Also make scroll
233  * bar become placed in the correct location.
234  */
235     if (key)                   
236       width = child->core.width + vbar->core.width +
237               2 * vbar->core.border_width;
238     else
239       c_width = width - vbar->core.width -2 * vbar->core.border_width;
240
241     /* Put Scrollbar on right side if scrolled window? */
242
243     if (sblw->scroll_by_line.use_right) {
244       vbar_x = width - vbar->core.width - 2 * vbar->core.border_width;
245       child_x = 0;
246     }
247     else
248       child_x = vbar->core.width + vbar->core.border_width;
249   }
250   else {
251     /* Make the scroll bar dissappear, note how scroll bar is always there,
252        sometimes it is just that we cannot see them. */
253     vbar_x = - vbar->core.width - 2 * vbar->core.border_width - 10;
254     child_x = 0;
255     if (key)
256       width = child->core.width;
257     else
258       c_width = width;
259   }
260
261 /* Move child and v_bar to correct location. */
262
263  XtMoveWidget(vbar, vbar_x, vbar_y);
264  XtMoveWidget(child, child_x, 0);
265
266  /* resize the children to be the correct height or width. */
267
268  XtResizeWidget(vbar, vbar->core.width, height, vbar->core.border_width);
269
270  if (!key)
271    XtResizeWidget(child, (Cardinal) (c_width - 20), (Cardinal) height,
272                   child->core.border_width);
273
274  /* set the thumb size to be correct. */
275
276  ResetThumb( (Widget) sblw);
277
278  answer = XtMakeResizeRequest( (Widget) sblw, width, height, &width, &height);
279
280  switch(answer) {
281  case XtGeometryYes:
282    break;
283  case XtGeometryNo:
284    return(FALSE);
285  case XtGeometryAlmost:
286    (void) Layout( (Widget) sblw,FALSE);
287  }
288  return(TRUE);
289}
290
291/*      Function Name: ResetThumb
292 *      Description: This function resets the thumb's shown percentage only.
293 *      Arguments: w - the ScrollByLineWidget.
294 *      Returns: none;
295 */
296
297static void
298ResetThumb(w)
299Widget w;
300{
301  float shown;
302  ScrollByLineWidget sblw = (ScrollByLineWidget) w;
303  Widget child,vbar;
304
305  vbar = sblw->composite.children[0];
306  child = sblw->composite.children[1];
307
308/* vertical */
309
310  shown = (float) child->core.height /(float) (sblw->scroll_by_line.lines *
311                                  sblw->scroll_by_line.font_height);
312  if (shown > 1.0)
313    shown = 1.0;
314
315  XtScrollBarSetThumb( vbar, (float) -1, shown );
316}
317
318/*
319 *
320 * Geometry Manager - If the height of width is changed then try a new layout.
321 *                    else dissallow the requwest.
322 *
323 */
324
325/*ARGSUSED*/
326static XtGeometryResult GeometryManager(w, request, reply)
327    Widget              w;
328    XtWidgetGeometry    *request;
329    XtWidgetGeometry    *reply; /* RETURN */
330
331{
332  ScrollByLineWidget sblw;
333
334  sblw = (ScrollByLineWidget) w->core.parent;
335  if ( request->width != 0 && request->height != 0 &&
336      (request->request_mode && (CWWidth || CWHeight)) ) {
337    w->core.height = request->height;
338    w->core.width = request->width;
339    (void) Layout( (Widget) sblw,TRUE);
340    return(XtGeometryYes);
341  }
342  return(XtGeometryNo);
343
344} /* Geometery Manager */
345
346/* ARGSUSED */
347static void ChildExpose(w,junk,event)
348Widget w;
349caddr_t junk;
350XEvent *event;
351{
352
353/*
354 * since we are realy concerned with the expose events that happen
355 * to the child, we have selected expose events on this window, and
356 * then I call the redisplay routine.
357 */
358
359  if ((event->type == Expose) || (event->type == GraphicsExpose))
360    Redisplay(w->core.parent, event, NULL);
361
362} /* ChildExpose */
363
364/*
365 * Repaint the widget's child Window Widget.
366 */
367
368/* ARGSUSED */
369static void Redisplay(w, event, region)
370Widget w;
371XEvent *event;
372Region region;
373{
374  ScrollByLineWidget sblw = (ScrollByLineWidget) w;
375
376  int top,bottom;               /* the locations of the top and
377                          bottom of the region that needs to be
378                          repainted. */
379  ScrollByLineStruct sblw_struct;
380
381/*
382 * This routine tells the client which sections of the window to
383 * repaint in his callback function which does the actual repainting.
384 */
385
386  if (event->type == Expose) {
387    top = event->xexpose.y;
388    bottom = event->xexpose.height + top;
389  }
390  else {
391    top = event->xgraphicsexpose.y;
392    bottom  = event->xgraphicsexpose.height + top;
393  }
394 
395  sblw_struct.start_line = top / sblw->scroll_by_line.font_height +
396                            sblw->scroll_by_line.line_pointer;
397/*
398 * If an expose event is called on a region that has no text assoicated
399 * with it then do not redisplay. Only nescessary for very short file.
400 */
401  if (sblw_struct.start_line > sblw->scroll_by_line.lines)
402    return;
403  sblw_struct.num_lines = (bottom - top) /
404                            sblw->scroll_by_line.font_height + 1;
405  sblw_struct.location =  top / sblw->scroll_by_line.font_height *
406                            sblw->scroll_by_line.font_height;
407
408  XtCallCallbacks( (Widget) sblw, XtNcallback, (caddr_t) &sblw_struct);
409
410} /* redisplay (expose) */
411
412static void
413Resize(w)
414Widget w;
415{
416
417  (void) Layout(w,FALSE);
418
419} /* Resize */
420
421static void ChangeManaged(w)
422Widget w;
423{
424  /* note how we ignore bonus children, but since we control all children,
425   there should never be a problem anyway. */
426  ScrollByLineWidget sblw = (ScrollByLineWidget) w;;
427
428  if (sblw->composite.num_children == 3) {
429    (void) Layout( w,sblw->scroll_by_line.key);
430  }
431
432} /* Change Managed */
433
434/*      Function Name: Page
435 *      Description: This function pages the widget, by the amount it recieves
436 *                   from the translation Manager.
437 *      Arguments: w - the ScrollByLineWidget.
438 *                 event - the event that caused this return.
439 *                 params - the parameters passed to it.
440 *                 num_params - the number of parameters.
441 *      Returns: none.
442 */
443
444static void
445Page(w, event, params, num_params)
446Widget w;
447XEvent * event;
448String * params;
449Cardinal *num_params;
450{
451   ScrollByLineWidget sblw = (ScrollByLineWidget) w;
452   Widget vbar = sblw->composite.children[0];
453   char direction;
454
455   if (*num_params > 0)
456     direction = *params[0];
457   else
458     return;
459
460/*
461 * If no scroll bar is visible then do not page, as the entire window is shown,
462 * of scrolling has been turned off.
463 */
464
465   if (vbar->core.x < - vbar->core.border_width)
466     return;
467
468   switch ( direction ) {
469   case 'f':
470   case 'F':
471     /* move one page forward */
472     VerticalScroll(vbar,NULL, (int) vbar->core.height);
473     break;
474   case 'b':
475   case 'B':
476     /* move one page backward */
477     VerticalScroll(vbar,NULL,  - (int) vbar->core.height);
478     break;
479   case 'L':
480   case 'l':
481     /* move one line forward */
482     VerticalScroll(vbar,NULL, (int) sblw->scroll_by_line.font_height);
483     break;
484   default:
485     return;
486   }
487}
488
489/*      Function Name: ScrollVerticalText
490 *      Description: This accomplished the actual movement of the text.
491 *      Arguments: w - the ScrollByLine Widget.
492 *                 new_line - the new location for the line pointer
493 *                 force_redisplay - should we force this window to get
494 *                                   redisplayed?
495 *      Returns: True if the thumb needs to be moved.
496 */
497
498static Boolean
499ScrollVerticalText(w,new_line,force_redisp)
500Widget w;
501int new_line;
502Boolean force_redisp;
503{
504  ScrollByLineWidget sblw = (ScrollByLineWidget) w;
505  int max_lines,                /* The location of top of the last screen. */
506    num_lines,                  /* The number of lines in one screen of text */
507    y_pos,                      /* The location to start displaying text. */
508    num_lines_disp,             /* The number of lines to display. */
509    start_line,                 /* The line to start displaying text. */
510    y_location,                 /* The y_location to for storing copy area. */
511    lines_to_move;              /* The number of lines to copy. */
512  GC gc;
513  Widget child,vbar;    /* Widgets. */
514  ScrollByLineStruct sblw_struct;
515  Boolean move_thumb = FALSE;
516
517  vbar =  sblw->composite.children[0];
518  child = sblw->composite.children[1];
519
520  num_lines =  child->core.height / sblw->scroll_by_line.font_height;
521
522  gc = XCreateGC(XtDisplay( (Widget) sblw),XtWindow(child),NULL,0);
523  XSetGraphicsExposures(XtDisplay( (Widget) sblw),gc,TRUE);
524
525 /* do not let the window extend out of bounds */
526
527  if ( new_line < 0) {
528    move_thumb = TRUE;
529    new_line = 0;
530  }
531  else {
532    max_lines = sblw->scroll_by_line.lines -
533     child->core.height / sblw->scroll_by_line.font_height;
534
535    if (max_lines < 0) max_lines = 0;
536
537    if ( new_line > max_lines ) {
538      new_line = max_lines;
539      move_thumb = TRUE;
540    }
541  }
542
543  if ( new_line == sblw->scroll_by_line.line_pointer && !force_redisp)
544/* No change in postion, and no action is nescessary */
545    return(move_thumb);
546  else if ( new_line <= sblw->scroll_by_line.line_pointer) { /* scroll back. */
547    if ( sblw->scroll_by_line.line_pointer - new_line >= num_lines
548        || force_redisp) {
549/*
550 * We have moved so far that no text that is currently on the screen can
551 * be saved thus there is no need to be clever just clear
552 * the window and display a full screen of text.
553 */
554      XClearWindow(XtDisplay(child),XtWindow(child));
555      y_pos = 0;
556      start_line = new_line;
557      num_lines_disp = num_lines;
558    }
559    else {
560/*
561 * Move text that is to remain on the screen to its new location, and then
562 * set up the proper callback values to display the rest of the text.
563 */
564      lines_to_move = num_lines - sblw->scroll_by_line.line_pointer + new_line;
565      y_location = sblw->scroll_by_line.line_pointer - new_line;
566      XCopyArea(XtDisplay(vbar),XtWindow(child),XtWindow(child),
567         gc,0,0,child->core.width,
568         (lines_to_move + 1) * sblw->scroll_by_line.font_height,
569         0,y_location * sblw->scroll_by_line.font_height);
570      XClearArea( XtDisplay(vbar),XtWindow(child),0,0,0,
571          (num_lines - lines_to_move)
572          * sblw->scroll_by_line.font_height,
573          FALSE );
574      y_pos = 0;
575      start_line = new_line;
576      num_lines_disp = num_lines - lines_to_move;
577    }
578  }
579  else {     /* scrolling forward */
580    if ( new_line - sblw->scroll_by_line.line_pointer >= num_lines
581        || force_redisp) {
582/*
583 * We have moved so far that no text that is currently on the screen can
584 * be saved thus there is no need to be clever just clear
585 * the window and display a full screen of text.
586 */
587      XClearWindow(XtDisplay(child),XtWindow(child));
588      y_pos = 0;
589      start_line = new_line;
590      num_lines_disp = num_lines;
591    }
592    else {
593/*
594 * Move text that is to remain on the screen to its new location, and then
595 * set up the proper callback values to display the rest of the text.
596 */
597      lines_to_move = num_lines - new_line + sblw->scroll_by_line.line_pointer;
598      y_location = new_line - sblw->scroll_by_line.line_pointer;
599      XCopyArea(XtDisplay(vbar),XtWindow(child),XtWindow(child),gc,0,
600                y_location * sblw->scroll_by_line.font_height,
601                child->core.width,
602                (lines_to_move)* sblw->scroll_by_line.font_height,0,0);
603
604      lines_to_move--;          /* make sure that we get the last,
605                                    (possibly) partial line, fully painted. */
606
607      /* we add 10% of a font height here to the vertical position
608       because some characters extend a little bit below the fontheight */
609
610      XClearArea(XtDisplay(vbar),XtWindow(child),0,lines_to_move *
611                 sblw->scroll_by_line.font_height + (int)
612                 (.1 * (float) sblw->scroll_by_line.font_height),0,0,FALSE);
613
614      y_pos = lines_to_move * sblw->scroll_by_line.font_height;
615      start_line = new_line + lines_to_move;
616      num_lines_disp = num_lines - lines_to_move;
617    }
618  }
619 
620  sblw->scroll_by_line.line_pointer = new_line;
621
622/*
623 * call the callbacks, this is the callback to the application to do the
624 * actual painting of the text.
625 */
626
627  sblw_struct.location = y_pos;
628  sblw_struct.start_line = start_line;
629  sblw_struct.num_lines = num_lines_disp;
630
631  XtCallCallbacks( (Widget) sblw,XtNcallback, (caddr_t) &sblw_struct);
632
633/* Save that memory */
634
635  XFreeGC(XtDisplay( (Widget) sblw), gc);
636
637  return(move_thumb);
638}
639
640/*      Function Name: VerticalThumb
641 *      Description: This function moves the postition of the interior window
642 *                   as the vertical scroll bar is moved.
643 *      Arguments: w - the scrollbar widget.
644 *                 junk - not used.
645 *                 percent - the position of the scrollbar.
646 *      Returns: none.
647 */
648
649static void
650VerticalThumb(w,junk,percent)
651Widget w;
652caddr_t junk;
653float *percent;
654{
655  int new_line;                 /* The new location for the line pointer. */
656  float location;               /* The location of the thumb. */
657  Widget vbar;
658
659  ScrollByLineWidget sblw = (ScrollByLineWidget) w->core.parent;
660
661  vbar =  sblw->composite.children[0];
662
663  new_line = (int) ((float) sblw->scroll_by_line.lines * (*percent));
664
665  if (ScrollVerticalText( (Widget) sblw, new_line, FALSE)) {
666/* reposition the thumb */
667    location = (float) sblw->scroll_by_line.line_pointer /
668               (float) sblw->scroll_by_line.lines;
669    XtScrollBarSetThumb( vbar, location , (float) -1 );
670  }
671
672}
673
674/*      Function Name: VerticalScroll
675 *      Description: This function moves the postition of the interior window
676 *                   as the vertical scroll bar is moved.
677 *      Arguments: w - the scrollbar widget.
678 *                 junk - not used.
679 *                 pos - the position of the cursor.
680 *      Returns: none.
681 */
682
683static void
684VerticalScroll(w,junk,pos)
685Widget w;
686caddr_t junk;
687int pos;
688{
689  int new_line;                 /* The new location for the line pointer. */
690  float location;               /* The new location of the thumb. */
691  Widget vbar;
692
693  ScrollByLineWidget sblw = (ScrollByLineWidget) w->core.parent;
694
695  vbar =  sblw->composite.children[0];
696
697  new_line = sblw->scroll_by_line.line_pointer;
698  new_line += (int) pos / sblw->scroll_by_line.font_height;
699
700  (void) ScrollVerticalText( (Widget) sblw,new_line,FALSE);
701
702/* reposition the thumb */
703
704  location = (float) sblw->scroll_by_line.line_pointer /
705             (float) sblw->scroll_by_line.lines;
706  XtScrollBarSetThumb( vbar, location , (float) -1 );
707}
708
709static void
710Initialize(req, new)
711Widget req, new;
712{
713  ScrollByLineWidget sblw = (ScrollByLineWidget) new;
714 
715  sblw->scroll_by_line.line_pointer = 0; /* initially point to line 0. */
716
717  if (sblw->core.height <= 0)
718    sblw->core.height = DEFAULT_HEIGHT;
719  if (sblw->core.width <= 0)
720    sblw->core.width = DEFAULT_WIDTH;
721} /* Initialize. */
722
723static void
724InitializeHook(new, args, num_args)
725ScrollByLineWidget new;
726ArgList args;
727Cardinal *num_args;
728{
729  ScrollByLineWidget sblw = (ScrollByLineWidget) new;
730  Widget window, s_bar;         /* Window widget, and scollbar. */
731  Arg arglist[10];              /* an arglist. */
732  ArgList merged_list, XtMergeArgLists(); /* The merged arglist. */
733  Cardinal window_num, merged_num; /* The number of window args. */
734
735  s_bar = XtCreateManagedWidget("verticalScrollBar", scrollbarWidgetClass,
736                                (Widget) sblw, args, *num_args);
737  XtAddCallback(s_bar, XtNjumpProc, VerticalThumb, NULL);
738  XtAddCallback(s_bar, XtNscrollProc, VerticalScroll, NULL);
739
740  window_num = 0; 
741  XtSetArg(arglist[window_num], XtNwidth, sblw->scroll_by_line.inner_width);
742  window_num++;
743  XtSetArg(arglist[window_num], XtNheight, sblw->scroll_by_line.inner_height);
744  window_num++;
745  XtSetArg(arglist[window_num], XtNborderWidth, 0);
746  window_num++; 
747
748/*
749 * I hope this will cause my args to override those passed to the SBL widget.
750 */
751 
752  merged_list = XtMergeArgLists(args, *num_args, arglist, window_num);
753  merged_num = *num_args + window_num;
754
755  window = XtCreateWidget("windowWithFile",widgetClass,(Widget) sblw,
756                          merged_list, merged_num);
757  XtManageChild(window);
758  XtFree(merged_list);          /* done, free it. */
759
760/*
761 * We want expose (and graphic exposuer) events for this window also.
762 */
763
764  XtAddEventHandler(window, (Cardinal) ExposureMask, TRUE, ChildExpose, NULL);
765 
766} /* InitializeHook */
767
768static void Realize(w, valueMask, attributes)
769    register Widget w;
770    Mask *valueMask;
771    XSetWindowAttributes *attributes;
772{
773    XtCreateWindow( w, (Cardinal) InputOutput, (Visual *)CopyFromParent,
774        *valueMask, attributes);
775} /* Realize */
776
777/*
778 *
779 * Set Values
780 *
781 */
782
783static Boolean SetValues (current, request, new)
784    Widget current, request, new;
785{
786  ScrollByLineWidget sblw_new, sblw_current;
787  Boolean ret = FALSE;
788
789  sblw_current = (ScrollByLineWidget) current;
790  sblw_new = (ScrollByLineWidget) new;
791
792  if (sblw_current->scroll_by_line.lines != sblw_new->scroll_by_line.lines) {
793    ResetThumb(new);
794    ret = TRUE;
795  }
796  if (sblw_current->scroll_by_line.font_height !=
797      sblw_new->scroll_by_line.font_height) {
798    ResetThumb(new);
799    ret = TRUE;
800  }
801  return(ret);
802
803} /* Set Values */
804
805/* Public Routines. */
806
807/*      Function Name: XtScrollByLineWidget()
808 *      Description: This function returns the window widget that the
809 *                   ScrollByLine widget uses to display its text.
810 *      Arguments: w - the ScrollByLine Widget.
811 *      Returns: the widget to display the text into.
812 */
813
814extern Widget XtScrollByLineWidget(w)
815Widget w;
816{
817  ScrollByLineWidget sblw = (ScrollByLineWidget) w; /* the sblw widget. */
818 
819  return(sblw->composite.children[1]);
820}
821
822/*      Function Name: XtResetScrollByLine
823 *      Description: This function resets the scroll by line widget.
824 *      Arguments: w - the sblw widget.
825 *      Returns: none.
826 */
827
828extern void
829XtResetScrollByLine(w)
830Widget w;
831{
832  float location;               /* the location of the thumb. */
833  ScrollByLineWidget sblw = (ScrollByLineWidget) w; /* the sblw widget. */
834  Widget vbar;
835
836  vbar =  sblw->composite.children[0];
837
838  (void) ScrollVerticalText( w, 0, TRUE);
839 
840  /* reposition the thumb */
841
842  location = (float) sblw->scroll_by_line.line_pointer /
843             (float) sblw->scroll_by_line.lines;
844  XtScrollBarSetThumb( vbar, location , (float) -1 );
845
846  Layout(w, FALSE);             /* see if new layout is required. */
847}
Note: See TracBrowser for help on using the repository browser.