home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 110 / EnigmaAmiga110CD.iso / indispensabili / utility / apdf / xpdf-0.80 / ltk / ltkscrollingcanvas.cc < prev    next >
C/C++ Source or Header  |  1998-11-27  |  5KB  |  218 lines

  1. //========================================================================
  2. //
  3. // LTKScrollingCanvas.cc
  4. //
  5. // Copyright 1996 Derek B. Noonburg
  6. //
  7. //========================================================================
  8.  
  9. #ifdef __GNUC__
  10. #pragma implementation
  11. #endif
  12.  
  13. #include <stdlib.h>
  14. #include <stdarg.h>
  15. #include <stddef.h>
  16. #include <X11/Xlib.h>
  17. #include <X11/Xutil.h>
  18. #include "LTKWindow.h"
  19. #include "LTKScrollingCanvas.h"
  20.  
  21. LTKScrollingCanvas::LTKScrollingCanvas(char *name1, int widgetNum1,
  22.                        int realWidth1, int realHeight1,
  23.                        int minWidth1, int minHeight1):
  24.     LTKWidget(name1, widgetNum1) {
  25.   realWidth = realWidth1;
  26.   realHeight = realHeight1;
  27.   minWidth = minWidth1;
  28.   minHeight = minHeight1;
  29.   left = top = 0;
  30.   pixmap = None;
  31. }
  32.  
  33. LTKScrollingCanvas::~LTKScrollingCanvas() {
  34.   if (pixmap != None)
  35.     XFreePixmap(getDisplay(), pixmap);
  36. }
  37.  
  38. void LTKScrollingCanvas::layout1() {
  39.   width = minWidth;
  40.   height = minHeight;
  41. }
  42.  
  43. void LTKScrollingCanvas::layout3() {
  44.   LTKWidget::layout3();
  45.   if (pixmap == None) {
  46.     pixmap = XCreatePixmap(getDisplay(), getXWindow(), realWidth, realHeight,
  47.                DefaultDepth(getDisplay(), getScreenNum()));
  48.     XFillRectangle(getDisplay(), pixmap, getBgGC(),
  49.            0, 0, realWidth, realHeight);
  50.   }
  51. }
  52.  
  53. void LTKScrollingCanvas::redraw() {
  54.   int w, h;
  55.  
  56.   if (pixmap != None) {
  57.     w = width;
  58.     if (left + width > realWidth) {
  59.       if ((left = realWidth - width) < 0) {
  60.     left = 0;
  61.     w = realWidth;
  62.       }
  63.     }
  64.     h = height;
  65.     if (top + height > realHeight) {
  66.       if ((top = realHeight - height) < 0) {
  67.     top = 0;
  68.     h = realHeight;
  69.       }
  70.     }
  71.     XCopyArea(getDisplay(), pixmap, getXWindow(), getFgGC(),
  72.           left, top, w, h, 0, 0);
  73.   }
  74. }
  75.  
  76. void LTKScrollingCanvas::buttonPress(int mx, int my, int button,
  77.                      GBool dblClick) {
  78.   LTKWidget::buttonPress(left + mx, top + my, button, dblClick);
  79. }
  80.  
  81. void LTKScrollingCanvas::buttonRelease(int mx, int my, int button,
  82.                        GBool click) {
  83.   LTKWidget::buttonRelease(left + mx, top + my, button, click);
  84. }
  85.  
  86. void LTKScrollingCanvas::mouseMove(int mx, int my, int btn) {
  87.   LTKWidget::mouseMove(left + mx, top + my, btn);
  88. }
  89.  
  90. void LTKScrollingCanvas::resize(int realWidth1, int realHeight1) {
  91.   if (realWidth1 != realWidth || realHeight1 != realHeight) {
  92.     if (pixmap != None)
  93.       XFreePixmap(getDisplay(), pixmap);
  94.     realWidth = realWidth1;
  95.     realHeight = realHeight1;
  96.     pixmap = XCreatePixmap(getDisplay(), getXWindow(), realWidth, realHeight,
  97.                DefaultDepth(getDisplay(), getScreenNum()));
  98.     XFillRectangle(getDisplay(), pixmap, getBgGC(),
  99.            0, 0, realWidth, realHeight);
  100.     XClearWindow(getDisplay(), getXWindow());
  101.   }
  102. }
  103.  
  104. void LTKScrollingCanvas::scroll(int x, int y) {
  105.   int newLeft, newTop;
  106.   int x1, y1, x2, y2, w, h;
  107.  
  108.   // compute new position
  109.   newLeft = x;
  110.   if (newLeft + width > realWidth) {
  111.     newLeft = realWidth - width;
  112.     if (newLeft < 0)
  113.       newLeft = 0;
  114.   }
  115.   newTop = y;
  116.   if (newTop + height > realHeight) {
  117.     newTop = realHeight - height;
  118.     if (newTop < 0)
  119.       newTop = 0;
  120.   }
  121.  
  122.   // check for no scrolling
  123.   if (newLeft == left && newTop == top)
  124.     return;
  125.  
  126.   // complete redraw
  127.   if (left + width < newLeft || newLeft + width < left ||
  128.       top + height < newTop || newTop + height < top) {
  129.     w = (newLeft + width <= realWidth) ? width : realWidth;
  130.     h = (newTop + height <= realHeight) ? height : realHeight;
  131.     XCopyArea(getDisplay(), pixmap, getXWindow(), getFgGC(),
  132.           newLeft, newTop, w, h, 0, 0);
  133.  
  134.   // scroll window, then redraw edges
  135.   } else {
  136.  
  137.     // copy as much as possible directly from window
  138.     if (newLeft < left) {
  139.       x1 = 0;
  140.       x2 = left - newLeft;
  141.       w = width - x2;
  142.     } else {
  143.       x1 = newLeft - left;
  144.       x2 = 0;
  145.       w = width - x1;
  146.     }
  147.     if (newTop < top) {
  148.       y1 = 0;
  149.       y2 = top - newTop;
  150.       h = height - y2;
  151.     } else {
  152.       y1 = newTop - top;
  153.       y2 = 0;
  154.       h = height - y1;
  155.     }
  156.     XCopyArea(getDisplay(), getXWindow(), getXWindow(), getFgGC(),
  157.           x1, y1, w, h, x2, y2);
  158.  
  159.     // copy edges from pixmap
  160.     h = (newTop + height <= realHeight) ? height : realHeight;
  161.     if (newLeft < left) {
  162.       w = left - newLeft;
  163.       x1 = newLeft;
  164.       x2 = 0;
  165.     } else {
  166.       w = newLeft - left;
  167.       x1 = left + width;
  168.       x2 = width - w;
  169.     }
  170.     if (w > 0) {
  171.       XCopyArea(getDisplay(), pixmap, getXWindow(), getFgGC(),
  172.         x1, newTop, w, h, x2, 0);
  173.     }
  174.     w = (newLeft + width <= realWidth) ? width : realWidth;
  175.     if (newTop < top) {
  176.       h = top - newTop;
  177.       y1 = newTop;
  178.       y2 = 0;
  179.     } else {
  180.       h = newTop - top;
  181.       y1 = top + height;
  182.       y2 = height - h;
  183.     }
  184.     if (h > 0) {
  185.       XCopyArea(getDisplay(), pixmap, getXWindow(), getFgGC(),
  186.         newLeft, y1, w, h, 0, y2);
  187.     }
  188.   }
  189.  
  190.   // update left and top
  191.   left = newLeft;
  192.   top = newTop;
  193. }
  194.  
  195. void LTKScrollingCanvas::redrawRect(int x1, int y1, int x2, int y2) {
  196.   int sx1, sy1, sx2, sy2;
  197.  
  198.   if (pixmap != None) {
  199.     sx1 = x1 - left;
  200.     sy1 = y1 - top;
  201.     sx2 = x2 - left;
  202.     sy2 = y2 - top;
  203.     if (sx1 < width && sx2 >= 0 && sy1 < height && sy2 >= 0) {
  204.       if (sx1 < 0)
  205.     sx1 = 0;
  206.       if (sy1 < 0)
  207.     sy1 = 0;
  208.       if (sx2 >= width)
  209.     sx2 = width - 1;
  210.       if (sy2 >= height)
  211.     sy2 = height - 1;
  212.       XCopyArea(getDisplay(), pixmap, getXWindow(), getFgGC(),
  213.         left + sx1, top + sy1, sx2 - sx1 + 1, sy2 - sy1 + 1,
  214.         sx1, sy1);
  215.     }
  216.   }
  217. }
  218.