summaryrefslogtreecommitdiffstats
path: root/maccaml/scroll.c
diff options
context:
space:
mode:
Diffstat (limited to 'maccaml/scroll.c')
-rw-r--r--maccaml/scroll.c325
1 files changed, 325 insertions, 0 deletions
diff --git a/maccaml/scroll.c b/maccaml/scroll.c
new file mode 100644
index 000000000..65a717d40
--- /dev/null
+++ b/maccaml/scroll.c
@@ -0,0 +1,325 @@
+/***********************************************************************/
+/* */
+/* Objective Caml */
+/* */
+/* Damien Doligez, projet Para, INRIA Rocquencourt */
+/* */
+/* Copyright 1998 Institut National de Recherche en Informatique et */
+/* en Automatique. Distributed only by permission. */
+/* */
+/***********************************************************************/
+
+/* $Id$ */
+
+#include "main.h"
+
+WEScrollUPP scrollFollowUPP;
+static ControlActionUPP scrollUPP, scrollGraphUPP;
+
+static long scroll_step = 1;
+
+/* Bring destRect in sync with the scroll bars. */
+static void AdjustView (WStatusH st)
+{
+ WEReference we = (*st)->we;
+ ControlHandle hbar = (*st)->scrollbars[H];
+ ControlHandle vbar = (*st)->scrollbars[V];
+ LongRect view, dest;
+ long dx, dy;
+
+ Assert (hbar != NULL && vbar != NULL);
+ if ((*st)->kind != kWinGraphics){
+ Assert (we != NULL);
+ WEGetViewRect (&view, we);
+ WEGetDestRect (&dest, we);
+ dx = view.left - dest.left - LCGetValue (hbar);
+ dy = view.top - dest.top - LCGetValue (vbar);
+ WEScroll (dx, dy, we);
+ }else{
+ dx = (*st)->viewrect.left - (*st)->destrect.left - LCGetValue (hbar);
+ dy = (*st)->viewrect.top - (*st)->destrect.top - LCGetValue (vbar);
+ GraphScroll (dx, dy);
+ }
+}
+
+/* Recompute the max values and the thumb positions. */
+void AdjustScrollBars (WindowPtr w)
+{
+ GrafPtr saveport;
+ WStatusH st;
+ LongRect view, dest;
+ long xmax, xval, ymax, yval;
+ long h;
+
+ GetPort (&saveport);
+ SetPort (w);
+
+ st = WinGetStatus (w);
+ Assert (st != NULL);
+ if ((*st)->kind == kWinGraphics){
+ view = (*st)->viewrect;
+ dest = (*st)->destrect;
+ }else{
+ WEGetViewRect (&view, (*st)->we);
+ WEGetDestRect (&dest, (*st)->we);
+ }
+
+ yval = view.top - dest.top;
+ ymax = yval + (dest.bottom - view.bottom);
+ if (ymax < 0) ymax = 0;
+
+ /* round up to nearest line_height */
+ h = (*st)->line_height;
+ ymax = (ymax + h - 1) / h * h;
+
+ LCSetMax ((*st)->scrollbars[V], ymax);
+ LCSetValue ((*st)->scrollbars[V], yval);
+
+ xval = view.left - dest.left;
+ xmax = xval + (dest.right - view.right);
+ if (xmax < 0) xmax = 0;
+ LCSetMax ((*st)->scrollbars[H], xmax);
+ LCSetValue ((*st)->scrollbars[H], xval);
+
+ if (xval > xmax || yval > ymax) AdjustView (st);
+
+ SetPort (saveport);
+}
+
+/* Callback procedure for auto-scrolling the text. (called by WASTE) */
+static pascal void Follow (WEReference we)
+{
+ WindowPtr w;
+ OSErr err;
+
+ err = WEGetInfo (weRefCon, &w, we);
+ Assert (err == noErr);
+ AdjustScrollBars (w);
+}
+
+/* Callback procedure for scrolling the text. (called by the Control Manager) */
+static pascal void Scroll (ControlHandle bar, ControlPartCode partcode)
+{
+ long value;
+
+ if (partcode == kControlNoPart) return;
+ value = LCGetValue (bar);
+ if (value < LCGetMax (bar) && scroll_step > 0
+ || value > 0 && scroll_step < 0){
+ LCSetValue (bar, value + scroll_step);
+ AdjustView (WinGetStatus (FrontWindow ()));
+ }
+}
+
+/* Callback procedure for scrolling the graphics. */
+static pascal void ScrollGraph (ControlHandle bar, ControlPartCode partcode)
+{
+ long value;
+
+ if (partcode == kControlNoPart) return;
+ value = LCGetValue (bar);
+ if (value < LCGetMax (bar) && scroll_step > 0
+ || value > 0 && scroll_step < 0){
+ LCSetValue (bar, value + scroll_step);
+ AdjustView (WinGetStatus (FrontWindow ()));
+ }
+}
+
+OSErr InitialiseScroll (void)
+{
+ scrollFollowUPP = NewWEScrollProc (Follow);
+ scrollUPP = NewControlActionProc (Scroll);
+ scrollGraphUPP = NewControlActionProc (ScrollGraph);
+ return noErr;
+}
+
+/* Calculate the contents rectangle for a text window with scrollbars. */
+void ScrollCalcText (WindowPtr w, Rect *r)
+{
+ *r = w->portRect;
+ r->bottom -= kScrollBarWidth;
+ r->right -= kScrollBarWidth;
+ InsetRect (r, kTextMarginH, kTextMarginV);
+}
+
+/* Calculate the contents rectangle for the graphics window. */
+void ScrollCalcGraph (WindowPtr w, Rect *r)
+{
+ *r = w->portRect;
+ r->bottom -= kScrollBarWidth;
+ r->right -= kScrollBarWidth;
+}
+
+void ScrollDoClick (WindowPtr w, Point where, EventModifiers mods)
+{
+ switch (WinGetKind (w)){
+ case kWinToplevel:
+ case kWinDocument: {
+ WEReference we = WinGetWE (w);
+ WStatusH st = WinGetStatus (w);
+ LongRect view;
+ ControlPartCode partcode;
+ ControlHandle bar;
+ long scrolldelta, pagesize;
+
+ Assert (we != NULL && st != NULL);
+ WEGetViewRect (&view, we);
+ partcode = FindControl (where, w, &bar);
+ if (bar == (*st)->scrollbars[V]){
+ pagesize = view.bottom - view.top;
+ scrolldelta = (*st)->line_height;
+ }else if (bar == (*st)->scrollbars [H]){
+ pagesize = view.right - view.left;
+ scrolldelta = kHorizScrollDelta;
+ }else{
+ return;
+ }
+ switch (partcode){
+ case kControlIndicatorPart:
+ TrackControl (bar, where, NULL);
+ LCSynch (bar);
+ AdjustView (st);
+ return;
+ case kControlUpButtonPart:
+ scroll_step = - (mods & optionKey ? 1 : scrolldelta);
+ break;
+ case kControlDownButtonPart:
+ scroll_step = + (mods & optionKey ? 1 : scrolldelta);
+ break;
+ case kControlPageUpPart:
+ scroll_step = - (pagesize - scrolldelta) / scrolldelta * scrolldelta;
+ break;
+ case kControlPageDownPart:
+ scroll_step = + (pagesize - scrolldelta) / scrolldelta * scrolldelta;
+ break;
+ }
+ TrackControl (bar, where, scrollUPP);
+ break;
+ }
+ case kWinGraphics: {
+ WStatusH st = WinGetStatus (w);
+ ControlPartCode partcode;
+ ControlHandle bar;
+ long scrolldelta, pagesize;
+
+ Assert (st != NULL);
+ partcode = FindControl (where, w, &bar);
+ scrolldelta = kGraphScrollDelta;
+ if (bar == (*st)->scrollbars[V]){
+ pagesize = (*st)->viewrect.bottom - (*st)->viewrect.top;
+ }else if (bar == (*st)->scrollbars [H]){
+ pagesize = (*st)->viewrect.right - (*st)->viewrect.left;
+ }else{
+ return;
+ }
+ switch (partcode){
+ case kControlIndicatorPart:
+ TrackControl (bar, where, NULL);
+ LCSynch (bar);
+ AdjustView (st);
+ return;
+ case kControlUpButtonPart:
+ scroll_step = - (mods & optionKey ? 1 : scrolldelta);
+ break;
+ case kControlDownButtonPart:
+ scroll_step = + (mods & optionKey ? 1 : scrolldelta);
+ break;
+ case kControlPageUpPart:
+ scroll_step = - (pagesize - scrolldelta) / scrolldelta * scrolldelta;
+ break;
+ case kControlPageDownPart:
+ scroll_step = + (pagesize - scrolldelta) / scrolldelta * scrolldelta;
+ break;
+ }
+ TrackControl (bar, where, scrollGraphUPP);
+ break;
+ }
+ case kWinPrefs:
+ case kWinAbout:
+ case kWinClipboard:
+ default:
+ Assert (0); /* These windows have no scroll bars. */
+ break;
+ }
+}
+
+/* Calculate and set the position of the scroll bars for w.
+ Draw the scroll bars and the grow icon, and validate their region.
+ Where applicable, this function must be called after WinWEResize or
+ WinGraphResize.
+ */
+void ScrollNewSize (WindowPtr w)
+{
+ Rect port = w->portRect;
+ WStatusH st = WinGetStatus (w);
+ Rect r;
+ ControlHandle bar;
+ GrafPtr saveport;
+
+ Assert (st != NULL);
+
+ GetPort (&saveport);
+ SetPort (w);
+
+ bar = (*st)->scrollbars[H];
+ r.left = port.left - 1;
+ r.right = port.right - kScrollBarWidth + 1;
+ r.top = port.bottom - kScrollBarWidth;
+ r.bottom = port.bottom + 1;
+ HideControl (bar); /* Invalidates the rectangle */
+ MoveControl (bar, r.left, r.top);
+ SizeControl (bar, r.right - r.left, r.bottom - r.top);
+ /* Only show the scrollbar if the window is active. */
+ if (FrontWindow () == w){
+ ValidRect (&r);
+ ShowControl (bar);
+ }
+
+ bar = (*st)->scrollbars[V];
+ r.left = port.right - kScrollBarWidth;
+ r.right = port.right + 1;
+ r.top = port.top - 1;
+ r.bottom = port.bottom - kScrollBarWidth + 1;
+ HideControl (bar); /* Invalidates the rectangle */
+ MoveControl (bar, r.left, r.top);
+ SizeControl (bar, r.right - r.left, r.bottom - r.top);
+ /* Only show the scrollbar if the window is active. */
+ if (FrontWindow () == w){
+ ValidRect (&r);
+ ShowControl (bar);
+ }
+
+ r = w->portRect;
+ r.left = r.right - kScrollBarWidth;
+ r.top = r.bottom - kScrollBarWidth;
+ ValidRect (&r);
+ DrawGrowIcon (w);
+
+ AdjustScrollBars (w);
+
+ SetPort (saveport);
+}
+
+/* Return 1 if the vertical scroll bar is at its max setting, 0 otherwise.
+ (With 1/2 line fudge factor.)
+*/
+int ScrollAtEnd (WindowPtr w)
+{
+ WStatusH st = WinGetStatus (w);
+ long val, max;
+
+ Assert (st != NULL);
+ val = LCGetValue ((*st)->scrollbars[V]);
+ max = LCGetMax ((*st)->scrollbars[V]);
+ return (val >= max - (*st)->line_height / 2);
+}
+
+/* Scroll to the bottom of the document. */
+void ScrollToEnd (WindowPtr w)
+{
+ WStatusH st = WinGetStatus (w);
+
+ Assert (st != NULL);
+ LCSetValue ((*st)->scrollbars[V], LCGetMax ((*st)->scrollbars[V]));
+ AdjustView (st);
+}