-- File: SVArtworkToolImpl.mesa
-- Last edited by Bier on December 18, 1982 1:42 am
-- Author: Eric Bier on March 22, 1983 2:04 pm
-- Contents: Viewer for Two dimensional artwork for mappings

DIRECTORY
 Buttons,
 Containers,
 Graphics,
 GraphicsColor,
 PadGraphics,
 Rope,
 SVArtwork,
 SVArtworkTool,
 SVArtworkUser,
 SVCoordSys2d,
 SV2d,
 TIPUser,
 VFonts,
 ViewerClasses,
 ViewerOps,
 ViewerTools;

SVArtworkToolImpl: PROGRAM
IMPORTS Buttons, Containers, PadGraphics, SVArtwork, SVArtworkUser, SVCoordSys2d, TIPUser, VFonts, ViewerOps, ViewerTools
EXPORTS SVArtworkTool =
BEGIN

-- declare the standard distances between menu lines.
entryHeight: CARDINAL = 15; -- height of a line of items
entryVSpace: CARDINAL = 1; -- vertical leading between lines
entryHSpace: CARDINAL = 4; -- horizontal space between items on a line
column0: CARDINAL = 0; -- horizontal space between margin and column 0;
column1: CARDINAL = 80; -- horizontal space between margin and column 1;
column2: CARDINAL = 160; -- horizontal space between margin and column 2.
column3: CARDINAL = 290; -- horizontal space between margin and column 3;

ArtworkToolData: TYPE = REF ArtworkToolDataObj;
ArtworkToolDataObj: TYPE = SVArtworkUser.ArtworkToolDataObj;
Point2d: TYPE = SV2d.Point2d;
Viewer: TYPE = ViewerClasses.Viewer;

ArtworkPadPaint: SAFE PROC [self: Viewer, context: Graphics.Context,
 whatChanged: REF ANY, clear: BOOL] = TRUSTED {
-- whatChanged is a ArtworkToolData
-- self is a $Artwork
 artworkToolData: ArtworkToolData;
IF whatChanged = NIL THEN {--we are being called by Window Manager
  artworkToolData ← NARROW[self.data];
  SVArtworkUser.PlaceOrigin[self, artworkToolData, red, FALSE, FALSE];
  SVArtwork.DrawArtwork[context, artworkToolData.artwork, artworkToolData.origin, artworkToolData.scalar];
  }
ELSE {proc: PROC [Graphics.Context];
     artworkToolData ← NARROW[whatChanged];
      proc ← artworkToolData.proc;
     proc[context];
     RETURN};
 };

Init: PROC = {

artworkPadClass: ViewerClasses.ViewerClass;

artworkPadClass ←
NEW[ViewerClasses.ViewerClassRec ← [
   paint: ArtworkPadPaint,
   notify: InputNotify,
   tipTable: TIPUser.InstantiateNewTIPTable["ArtworkPad.TIP"]
   ]];

ViewerOps.RegisterViewerClass[$ArtworkPad, artworkPadClass];
};


Create: PUBLIC PROC [paint: BOOL] RETURNS [viewer: Viewer] = {
-- Has no menu
  
 artworkToolData: ArtworkToolData ← NEW[ArtworkToolDataObj];

 artworkToolData.height ← 0;
 artworkToolData.artwork ← SVArtwork.CreateColorArtwork[GraphicsColor.blue, plastic];
 artworkToolData.origin ← [0,0]; -- will be updated by PlaceOrigin
 artworkToolData.scalar ← 1.0;

 artworkToolData.outer ← Containers.Create[[
  name: "Artwork: ",
  iconic: TRUE,
  column: left,
  scrollable: FALSE
  ]];
  
 AddTextSection[artworkToolData];
  
 artworkToolData.picture ← ViewerOps.CreateViewer[
  flavor: $ArtworkPad,
  info: [
   parent: artworkToolData.outer,
   wx: 0, wy: artworkToolData.height,
   ww: artworkToolData.outer.ww,
   wh: artworkToolData.outer.wh, -- only initial values for ww and wh. They are constrained below
   data: artworkToolData, -- contains the current scene
   scrollable: FALSE
   ]
  ];
  
 Containers.ChildXBound[artworkToolData.outer, artworkToolData.picture];
 Containers.ChildYBound[artworkToolData.outer, artworkToolData.picture];

 artworkToolData.height ← artworkToolData.height + artworkToolData.picture.wh;

IF paint THEN ViewerOps.PaintViewer[artworkToolData.outer, all];

 viewer ← artworkToolData.picture;

 }; -- end of Create

AddTextSection: PRIVATE PROC [artworkToolData: ArtworkToolData] = {
-- creates a text section with buttons and text viewers as follows:
-- DrawArtwork! scalar: <real>

 drawButton, scalarSetPrompt, scalarPrompt, bandsButton: Buttons.Button;
 initialScalarRope: Rope.ROPE ← "1";

 drawButton ← Buttons.Create[
  info: [name: "DrawArtwork!", wy: artworkToolData.height, wh: entryHeight,
     parent: artworkToolData.outer, border: FALSE],
  proc: SVArtworkUser.DrawArtwork,
  clientData: artworkToolData
  ];
  
 scalarSetPrompt ← Buttons.Create[
  info: [name: " ← ",
     wx: drawButton.wx + drawButton.ww + entryHSpace,
     wy: artworkToolData.height, wh: entryHeight,
     parent: artworkToolData.outer, border: TRUE],
  proc: SVArtworkUser.ScalarSetPrompt,
  clientData: artworkToolData
  ];
   
 scalarPrompt ← Buttons.Create[
  info: [name: "scalar",
     wx: scalarSetPrompt.wx + scalarSetPrompt.ww + entryHSpace,
     wy: artworkToolData.height, wh: entryHeight,
     parent: artworkToolData.outer, border: FALSE],
  proc: SVArtworkUser.ScalarPrompt,
  clientData: artworkToolData
  ];
  
 artworkToolData.textSection.scalar ← ViewerTools.MakeNewTextViewer[[
  parent: artworkToolData.outer,
  wx: scalarPrompt.wx + scalarPrompt.ww + entryHSpace,
  wy: artworkToolData.height,
  ww: VFonts.StringWidth["188.88 "],
  wh: entryHeight,
  data: initialScalarRope,
  scrollable: FALSE, border: FALSE]];
  
 bandsButton ← Buttons.Create[
  info: [name: "MakeBands!",
     wx: artworkToolData.textSection.scalar.wx +
       artworkToolData.textSection.scalar.ww + entryHSpace,
     wy: artworkToolData.height, wh: entryHeight,
     parent: artworkToolData.outer, border: FALSE],
  proc: SVArtworkUser.MakeBands,
  clientData: artworkToolData
  ];
  
 artworkToolData.height ← artworkToolData.height + entryVSpace + entryHeight;
  
  }; -- end of AddTextSection


InputNotify: PUBLIC SAFE PROCEDURE [self: ViewerClasses.Viewer, input: LIST OF REF ANY] = TRUSTED {
-- self is a Scratchpad2d
 artworkToolData: ArtworkToolData ← NARROW[self.data];
IF ISTYPE[input.first, TIPUser.TIPScreenCoords] THEN {
 controlPoint: Point2d;
 mousePlace: TIPUser.TIPScreenCoords ← NARROW[input.first];
 controlPoint[1] ← mousePlace.mouseX; -- this is a fix to float conversion
 controlPoint[2] ← mousePlace.mouseY;

IF ISTYPE[input.rest.first, ATOM] THEN
  SELECT input.rest.first FROM
   $DRAW => {
    SELECT artworkToolData.mode FROM
     off => RETURN;
     tube =>{};
    ENDCASE => ERROR;
    };
   $MOVESTART => { -- Change mouse to a plus--};
   $MOVEEND => { -- Change mouse back and update displacement of artwork.
    controlPoint ← PadGraphics.ScreenToPad[controlPoint, artworkToolData.origin, artworkToolData.scalar];
    SVCoordSys2d.PlaceTranslationAwrtB[artworkToolData.artwork.artWRTPad, NIL, controlPoint];
    SVArtworkUser.DrawArtwork[NIL, artworkToolData, yellow, FALSE, FALSE];
    };
   ENDCASE => ERROR;
 }; -- end is a mouse point
}; -- end of InputNotify


Init[];


END.