(*************************************************************************

:Program.    EdGadgets.mod
:Contents.   Gadget-Routines for AmokEd (Datas in EdGlobalVars)
:Author.     Hartmut Goebel
:Copyright.  Copyright © 1989 by Thomas Siemens and Volker Rudolph
:Copyright.  Oberon-Implementation Copyright © 1991 by Hartmut Goebel
:Language.   Oberon
:Translator. AmigaOberon V2.00
:History.    V1.0, 19 Feb 1991 Hartmut Goebel
:Bugs.       PropGad funktioniert noch nicht richtig
:Date.       17 Oct 1991 21:14:04

*************************************************************************)

MODULE EdGadgets;

IMPORT
  edD: EdDisplay,
  edG: EdGlobalVars,
  I  : Intuition,
  g  : Graphics,
  lst: EdLists,
  sys: SYSTEM;

VAR
  KnobModified: BOOLEAN;

PROCEDURE SetProp*; (* bei Änderungen Def. in edG. korrigieren!! *)
VAR
  newPot,newBody: LONGINT;
  i: LONGINT;
BEGIN
  IF edG.Text.numberOfLines-edG.Rows > 1 THEN
    i := edG.Text.numberOfLines-edG.Rows - 1;
    newPot := 0FFFFH DIV i * edG.Text.topLine;
    IF newPot > 0FFFFH THEN newPot := 0FFFFH; END;
  ELSE
    newPot := 0;
  END;
  IF edG.Rows < edG.Text.numberOfLines THEN
    newBody := 0FFFFH DIV edG.Text.numberOfLines * edG.Rows;
  ELSE
    newBody := 0FFFFH;
  END;

  IF KnobModified OR (edG.Text.propInfo.vertPot # newPot)
  OR (edG.Text.propInfo.vertBody # newBody) THEN
    I.NewModifyProp(edG.Text.propGadget,edG.Text.window,NIL,
                    edG.Text.propInfo.flags,0,newPot,0,newBody,1);
    KnobModified := FALSE;
  END;
END SetProp;


(* setzt PropGadget entsprechend up/down arrow *)
PROCEDURE DrawKnob*(num: INTEGER);
BEGIN
  IF (num = 2) OR (num = 3) THEN
    KnobModified := TRUE;
    SetProp;
  END;
END DrawKnob;


(* Verschiebt den ScrollBar entsprechend             *)
(* edG.Text.topLine und Berechnet die Größe des Body *)
(* muß von jeder Prozedur aufgerufen werden, die     *)
(* die Zeilenanzahl ändert oder Zeilen verschiebt    *)

PROCEDURE SetPropKnob*; (* bei Änderungen Def. in edG. korrigieren!! *)
CONST
  py = 12;
VAR
  px,
  kyStart,kyEnd,
  kHeight,cHeight: INTEGER; (*USHORT*)
  i: LONGINT;
  newPot: LONGINT; (*ULONG*)
BEGIN
  IF edG.kick20 IN edG.Status THEN SetProp; RETURN; END;

  cHeight := edG.Text.propInfo.cHeight-5;
  px := edG.Text.window.width-12;

  IF edG.Text.numberOfLines-1 > edG.Rows THEN
    i := edG.Text.numberOfLines-edG.Rows-1;
    newPot := 0FFFFH DIV i * edG.Text.topLine;
    IF newPot >= 0FFFFH THEN newPot := 0FFFFH; END;
  ELSE
    newPot :=  0;
  END;
  (* $RangeChk- *)
  edG.Text.propInfo.vertPot := SHORT(newPot);
  (* $RangeChk= *)

  IF edG.Rows <= edG.Text.numberOfLines THEN
    (* $RangeChk- *)
    edG.Text.propInfo.vertBody :=
      SHORT(0FFFFH DIV edG.Text.numberOfLines * edG.Rows);
    kHeight :=  SHORT(cHeight * edG.Rows DIV edG.Text.numberOfLines);
    (* $RangeChk= *)
  ELSE
    edG.Text.propInfo.vertBody := I.maxBody;
    kHeight := cHeight;
  END;

  IF kHeight < 3 THEN kHeight := 3; END;
  IF kHeight >= cHeight THEN kHeight := cHeight - 1; END;

  (* $RangeChk- *)
  kyStart := py + SHORT(newPot * (cHeight-kHeight) DIV 0FFFFH);
  (* $RangeChk= *)
  kyEnd := kyStart + kHeight;
  IF kyStart > kyEnd THEN kyEnd := kyStart; END;

  g.SetAPen(edG.RPort,0);
  g.RectFill(edG.RPort,px-2,py,px+9,py+cHeight);
  g.SetAPen(edG.RPort,1);
  g.RectFill(edG.RPort,px,kyStart,px+7,kyEnd);

  KnobModified := TRUE;
END SetPropKnob;


PROCEDURE MovePropKnob*;
VAR
  n: LONGINT;
  diff: INTEGER;
BEGIN
  n := (edG.Text.numberOfLines-edG.Rows) * edG.Text.propInfo.vertPot DIV 0FFFFH;
  IF n <= 0 THEN
    n := 0;
  ELSIF n >= edG.Text.numberOfLines-edG.Rows THEN
    IF edG.Text.numberOfLines-edG.Rows < 1 THEN
      n := 1;
    ELSE
      n := edG.Text.numberOfLines-edG.Rows - 1;
    END;
  END;
  diff := SHORT(edG.Text.topLine - n);
  IF diff # 0 THEN
    edD.TextCursor(FALSE);
    edD.PutBackLine;
    edG.Text.line := n + (edG.Text.line - edG.Text.topLine);
    edG.Text.topLine := n;
    IF diff > 0 THEN
      lst.GoForwardNil(edG.Text.actLinePtr,diff);
      lst.GoForwardNil(edG.Text.topLinePtr,diff);
      IF diff < (edG.Rows * 2 DIV 3)  THEN
        g.ScrollRaster(edG.RPort,0,-edG.YSize*diff,edD.Col(0),edD.Row(0),
                       edD.Col(edG.Columns)-1,edD.Row(edG.Rows)-1);
        edD.TextDisplaySeg(0,diff);
      END;
    ELSE
      diff := -diff;
      lst.GoBackwardNil(edG.Text.actLinePtr,diff);
      lst.GoBackwardNil(edG.Text.topLinePtr,diff);
      IF diff < (edG.Rows * 2 DIV 3)  THEN
        g.ScrollRaster(edG.RPort,0,edG.YSize*diff,edD.Col(0),edD.Row(0),
                       edD.Col(edG.Columns)-1,edD.Row(edG.Rows)-1);
        edD.TextDisplaySeg(edG.Rows-diff,diff);
      END;
    END;
    edD.TextLoad;
    edD.TextSync;
    IF NOT(edG.alreadyRedrawn IN edG.Status) THEN edD.TextRedisplay; END;
    edD.TextCursor(TRUE);
  ELSIF NOT KnobModified THEN
    SetProp;
  END; (* IF diff # 0 *)
END MovePropKnob;

END EdGadgets.

