IconEditorImplA.mesa
Copyright Ó 1987, 1992 by Xerox Corporation. All rights reserved.
Ken Pier, May 17, 1991 6:11 pm PDT
Mike Spreitzer July 29, 1986 9:18:59 am PDT
Russ Atkinson (RRA) March 9, 1987 5:25:51 pm PST
Tim Diebert: October 1, 1987 2:16:52 pm PDT
Bloomenthal, April 19, 1990 11:30:59 pm PDT
Willie-s, June 5, 1992 11:43 am PDT
DIRECTORY Basics, Containers, IconEditorDefs, IconRegistry, MBQueue, Menus, MessageWindow, Rope, ViewerClasses, ViewerOps, ViewerTools;
IconEditorImplA: CEDAR PROGRAM
IMPORTS Basics, IconEditorDefs, IconRegistry, MBQueue, Menus, MessageWindow, Rope, ViewerOps, ViewerTools
EXPORTS IconEditorDefs
~ BEGIN
IconProc:   TYPE ~ IconEditorDefs.IconProc;
IconHandle:  TYPE ~ IconEditorDefs.IconHandle;
IconInfoRef:  TYPE ~ IconEditorDefs.IconInfoRef;
IconFileFormat: TYPE ~ IconEditorDefs.IconFileFormat;
MouseButton: TYPE ~ ViewerClasses.MouseButton;
CreateMenu: PUBLIC PROC [handle: IconHandle] RETURNS [iconMenu: Menus.Menu] ~ {
AddEntry: PROC [name: Rope.ROPE, proc: Menus.MenuProc, line: Menus.MenuLine] ~ {
item: Menus.MenuEntry ¬ MBQueue.CreateMenuEntry[handle.queue, name, proc, handle];
Menus.InsertMenuEntry[iconMenu, item, line];
};
iconMenu ¬ Menus.CreateMenu[lines: 3];
AddEntry["ShowLabel", ShowLabelProc, 2];
AddEntry["DrawLine", LineProc, 2];
AddEntry["InvertColor", InvertProc, 2];
AddEntry["Black", BlackProc, 2];
AddEntry["DarkGray", DarkGrayProc, 2];
AddEntry["DeskTopGray", DeskTopGrayProc, 2];
AddEntry["DeskTopGrayIfWhite", DeskTopGrayIfWhiteProc, 2];
AddEntry["White", WhiteProc, 2];
AddEntry["BlackLabel", BlackLabelProc, 1];
AddEntry["WhiteLabel", WhiteLabelProc, 1];
AddEntry["UnSetLabel", UnLabelIconProc, 1];
AddEntry["SetLabel", LabelIconProc, 1];
AddEntry["Mirror", MirrorProc, 1];
AddEntry["Flip", FlipProc, 1];
AddEntry["Right", RightProc, 1];
AddEntry["Left", LeftProc, 1];
AddEntry["Down", DownProc, 1];
AddEntry["Up", UpProc, 1];
AddEntry["Register", RegisterIconProc, 1]; -- w.t.
AddEntry["CreateFilledIcon", FillIconProc, 0];
AddEntry["CreateIcon", CreateIconProc, 0];
AddEntry["KillAll", IconEditorDefs.KillAllIconsProc, 0]; -- j.b
AddEntry["DeleteIcon", IconEditorDefs.DeleteIconProc, 0];
AddEntry["RotateDisplay", RotateDisplayProc, 0];
AddEntry["Load", LoadIconProc, 0];
Menus.InsertMenuEntry[iconMenu, MBQueue.CreateMenuEntry[q: handle.queue, name: "Save", proc: SaveProc, clientData: handle, guarded: TRUE, documentation: "Confirm write to Icon file"], 0];
Menus.InsertMenuEntry[iconMenu, MBQueue.CreateMenuEntry[q: handle.queue, name: "Reset", proc: ResetProc, clientData: handle, guarded: TRUE,
documentation: "Confirm reloading of the icon file."], 0];
AddEntry["UNDO", IconEditorDefs.UndoProc, 0];
};
LoadIconProc: PUBLIC Menus.MenuProc ~ {
handle: IconEditorDefs.IconHandle ¬ NARROW[clientData];
IF handle.container.newVersion THEN
IF NOT MessageWindow.Confirm["Confirm discard of current icon edits..."] THEN RETURN;
handle.iconFileName ¬ IconEditorDefs.GetFileName[handle, handle.iconFileWindow];
IF Rope.Size[handle.iconFileName] = 0
THEN MessageWindow.Append[message: "Enter file name prior to Load.", clearFirst: TRUE]
ELSE ReloadIcons[handle, "loaded"];
};
ReloadIcons: PROC [h: IconEditorDefs.IconHandle, function: Rope.ROPE] ~ {
[h.numberReadIn, h.iconFile] ¬ IconEditorDefs.LoadIcons[h, h.iconFileName
! IconEditorDefs.CouldntLoadIcons => {
MessageWindow.Append[Rope.Cat["File ", h.iconFileName," can't be ", function], TRUE];
GOTO BadFile
}];
IF h.iconFile # NIL THEN {
h.numberOfIcons ¬ h.numberReadIn;
h.startDisplay ¬ 0;
h.currentIC ¬ FIRST[IconEditorDefs.IconFlavor];
h.container.newVersion ¬ FALSE;
h.drewLine ¬ FALSE;
h.drewRectangle ¬ FALSE;
ViewerOps.PaintViewer[viewer: h.container, hint: all];
};
EXITS BadFile => NULL;
};
RotateDisplayProc: PUBLIC Menus.MenuProc ~ {
Really rotate so icons will be ordered in a file as displayed -- Bloomenthal
rotates the display incrementally by moving up the starting position in the icons array
temp: ARRAY [0..IconEditorDefs.maxStorage) OF IconEditorDefs.IconRef;
handle: IconEditorDefs.IconHandle ¬ NARROW[clientData];
iconInfo: IconEditorDefs.IconInfoRef;
increment: INTEGER ¬ IF mouseButton=red THEN 1 ELSE 4;
IF shift THEN increment ¬ -increment;
FOR n: NAT IN [0..handle.numberOfIcons) DO temp[n] ¬ handle.icons[n]; ENDLOOP; -- easy
FOR n: NAT IN [0..handle.numberOfIcons) DO
handle.icons[n] ¬ temp[(n+increment) MOD handle.numberOfIcons];
ENDLOOP;
iconInfo ¬ NEW[IconEditorDefs.IconInfoRec ¬ [handle, screen, handle.currentIC]];
ViewerOps.SetNewVersion[handle.container];
ViewerOps.PaintViewer[handle.viewer, client, FALSE, iconInfo];
};
ProcessIcon: PROC [h: IconHandle, iconProc: IconProc, button: MouseButton ¬ red] ~ {
iconInfo: IconInfoRef ¬ NEW[IconEditorDefs.IconInfoRec ¬ [h, icon, h.currentIC]];
IF IconEditorDefs.PointsMarked[h, rect] THEN {
IconEditorDefs.SaveBitMap[h];
ViewerOps.SetNewVersion[h.container];
iconProc[h, h.currentIC, h.currentRectangle, h.currentLine, button = red];
ViewerOps.PaintViewer[h.viewer, client, FALSE, iconInfo];
};
};
BlackProc: PUBLIC Menus.MenuProc ~ {
Action: IconProc ~ {IconEditorDefs.SetBlack[handle, flavor, rect]};
ProcessIcon[NARROW[clientData], Action, mouseButton];
};
InvertProc: PUBLIC Menus.MenuProc ~ {
Action: IconProc ~ {IconEditorDefs.Invert[handle, flavor, rect]};
ProcessIcon[NARROW[clientData], Action, mouseButton];
};
FlipProc: PUBLIC Menus.MenuProc ~ {
Action: IconProc ~ {IconEditorDefs.FlipIcon[handle, flavor, rect]};
ProcessIcon[NARROW[clientData], Action, mouseButton];
};
MirrorProc: PUBLIC Menus.MenuProc ~ {
Action: IconProc ~ {IconEditorDefs.MirrorIcon[handle, flavor, rect]};
ProcessIcon[NARROW[clientData], Action, mouseButton];
};
DeskTopGrayProc: PUBLIC Menus.MenuProc ~ {DoDeskTopGray[clientData, TRUE]};
DeskTopGrayIfWhiteProc: PUBLIC Menus.MenuProc ~ {DoDeskTopGray[clientData, FALSE]};
DoDeskTopGray: PROC [clientData: REF ANY, clearToWhite: BOOL] ~ {
Action: IconProc ~ {IconEditorDefs.SetDeskTopGray[handle, flavor, rect, clearToWhite]};
ProcessIcon[NARROW[clientData], Action];
};
DarkGrayProc: PUBLIC Menus.MenuProc ~ {
Action: IconProc ~ {IconEditorDefs.SetDarkGray[handle, flavor, rect]};
ProcessIcon[NARROW[clientData], Action, mouseButton];
};
WhiteProc: PUBLIC Menus.MenuProc ~ {
Action: IconProc ~ {IconEditorDefs.SetWhite[handle, flavor, rect]};
ProcessIcon[NARROW[clientData], Action, mouseButton];
};
RightProc: PUBLIC Menus.MenuProc ~ {
Action: IconProc ~ {IconEditorDefs.MoveRight[handle, flavor, slowShift]};
ProcessIcon[NARROW[clientData], Action, mouseButton];
};
LeftProc: PUBLIC Menus.MenuProc ~ {
Action: IconProc ~ {IconEditorDefs.MoveLeft[handle, flavor, slowShift]};
ProcessIcon[NARROW[clientData], Action, mouseButton];
};
UpProc: PUBLIC Menus.MenuProc ~ {
Action: IconProc ~ {IconEditorDefs.MoveUp[handle, flavor, slowShift]};
ProcessIcon[NARROW[clientData], Action, mouseButton];
};
DownProc: PUBLIC Menus.MenuProc ~ {
Action: IconProc ~ {IconEditorDefs.MoveDown[handle, flavor, slowShift]};
ProcessIcon[NARROW[clientData], Action, mouseButton];
};
LineProc: PUBLIC Menus.MenuProc ~ { -- for DrawLine and mark1 and mark2.
Action: IconProc ~ {
IconEditorDefs.DrawLine[handle, line, flavor];
handle.drewLine ¬ FALSE;
};
ProcessIcon[NARROW[clientData], Action, mouseButton];
};
CreateIconProc: PUBLIC Menus.MenuProc ~ {
Create a new, completely blank icon that becomes the current icon.
handle: IconEditorDefs.IconHandle = NARROW[clientData];
newLastFlavor: IconEditorDefs.IconFlavor = IconEditorDefs.GetNewFlavor[handle];
insertAt: IconEditorDefs.IconFlavor = SELECT mouseButton FROM red, yellow => newLastFlavor, blue => handle.currentIC, ENDCASE => ERROR;
iaQuaNat: INT16 = LOOPHOLE[insertAt];
iconInfo: IconEditorDefs.IconInfoRef = IF insertAt = newLastFlavor THEN NEW[IconEditorDefs.IconInfoRec ¬ [handle, newIcon, insertAt]] ELSE NIL;
handle.currentIC ¬ insertAt;
FOR f: IconEditorDefs.IconFlavor DECREASING IN [insertAt .. newLastFlavor) DO
handle.icons[LOOPHOLE[f.SUCC]] ¬ handle.icons[LOOPHOLE[f]];
ENDLOOP;
handle.currentIconRep ¬ handle.icons[LOOPHOLE[insertAt]] ¬ NEW[IconFileFormat];
handle.numberOfIcons ¬ handle.numberOfIcons + 1;
ViewerOps.SetNewVersion[handle.container];
make sure the new icon is blank
IconEditorDefs.ClearIcon[handle, handle.currentIC];
before we paint the screen, make sure new icon is visible
handle.startDisplay ¬ MAX[iaQuaNat - IconEditorDefs.maxIconsOnDisplay + 1, MIN[iaQuaNat, handle.startDisplay]];
ViewerOps.PaintViewer[handle.viewer, client, FALSE, iconInfo];
};
FillIconProc: PUBLIC Menus.MenuProc ~ {
handle: IconEditorDefs.IconHandle ¬ NARROW[clientData];
IconEditorDefs.FillIcon[handle];
};
ShowLabelProc: PUBLIC Menus.MenuProc ~ {
h: IconEditorDefs.IconHandle ¬ NARROW[clientData];
iconInfo: IconInfoRef ¬ NEW[IconEditorDefs.IconInfoRec ¬ [h, rect, h.currentIC]];
ViewerOps.SetNewVersion[h.container];
IF NOT h.currentIconRep.label
THEN Blink["Current icon has no label."]
ELSE {
h.labelRect.x ¬ h.currentIconRep.lx;
h.labelRect.y ¬ IconEditorDefs.iconH-1-(h.currentIconRep.ly+h.currentIconRep.lh);
h.labelRect.w ¬ h.currentIconRep.lw;
h.labelRect.h ¬ h.currentIconRep.lh;
ViewerOps.PaintViewer[h.viewer, client, FALSE, iconInfo];
};
};
WhiteLabelProc: PUBLIC Menus.MenuProc ~ {
handle: IconHandle ¬ NARROW[clientData];
ViewerOps.SetNewVersion[handle.container];
IconEditorDefs.WhiteLabel[handle, handle.currentIC];
};
BlackLabelProc: PUBLIC Menus.MenuProc ~ {
handle: IconHandle ¬ NARROW[clientData];
ViewerOps.SetNewVersion[handle.container];
IconEditorDefs.BlackLabel[handle, handle.currentIC];
};
LabelIconProc: PUBLIC Menus.MenuProc ~ {
handle: IconHandle ¬ NARROW[clientData];
iconInfo: IconInfoRef ¬ NEW[IconEditorDefs.IconInfoRec ¬ [handle, rect, handle.currentIC]];
ViewerOps.SetNewVersion[handle.container];
IconEditorDefs.SetLabel[handle, handle.currentIC, handle.currentRectangle];
now erase the sketch
ViewerOps.PaintViewer[handle.viewer, client, FALSE, iconInfo];
};
UnLabelIconProc: PUBLIC Menus.MenuProc ~ {
handle: IconHandle ¬ NARROW[clientData];
ViewerOps.SetNewVersion[handle.container];
IconEditorDefs.UnSetLabel[handle, handle.currentIC];
};
Blink: PROC [message: Rope.ROPE] ~ {
MessageWindow.Append[message: message, clearFirst: TRUE];
MessageWindow.Blink[];
};
RegisterIconProc: Menus.MenuProc = TRUSTED {
handle: IconHandle ¬ NARROW[clientData];
IF NOT Basics.IsBound[LOOPHOLE[IconRegistry.RegisterIcon]]
THEN Blink["IconRegistryImpl.bcd has not been run"]
ELSE IconRegistry.RegisterIcon[ViewerTools.GetContents[handle.iconNameWindow], IconEditorDefs.GetFileName[handle, handle.iconFileWindow], LOOPHOLE[handle.currentIC, INT16], TRUE];
};
SaveProc: PUBLIC Menus.MenuProc ~ {
h: IconEditorDefs.IconHandle ¬ NARROW[clientData];
h.iconFileName ¬ IconEditorDefs.GetFileName[h, h.iconFileWindow];
IF Rope.Size[h.iconFileName] = 0 THEN {
MessageWindow.Append["Enter file name prior to Save.", TRUE];
RETURN
};
h.iconFile ¬ IconEditorDefs.SaveIcons[h, h.iconFileName, h.numberOfIcons
! IconEditorDefs.CouldntSaveIcons => {
MessageWindow.Append[Rope.Concat["Couldn't save ", h.iconFileName], TRUE];
GOTO BadFile
}];
IF h.iconFile # NIL
THEN MessageWindow.Append[Rope.Concat["Icons saved in ", h.iconFileName], TRUE];
h.container.newVersion ¬ FALSE;
ViewerOps.PaintViewer[h.container, caption];
EXITS BadFile => NULL;
};
ResetProc: PUBLIC Menus.MenuProc = TRUSTED {
handle: IconEditorDefs.IconHandle ¬ NARROW[clientData];
IF handle.container.newVersion THEN ReloadIcons[handle, "reset"];
};
END.
Edited on April 11, 1983 4:09 pm, by Teitelman
added Register button which calls IconRegistry to register an icon
changes to: CreateMenu, RegisterIconProc, SaveProc, DIRECTORY, CreateMenu, RegisterIconProc, SaveProc, IconEditorStorageOverflowInPass3, DIRECTORY, IconEditorStorageOverflowInPass3, handle (local of RegisterIconProc), RegisterIconProc
Edited on April 12, 1983 5:03 pm, by Teitelman
changes to: RegisterIconProc, handle (local of RegisterIconProc), DIRECTORY, IconEditorStorageOverflowInPass3
Edited on April 22, 1983 1:41 pm, by Wyatt
-- Removed redundant menu items: Close Grow --> <-- Destroy
Edited on April 23, 1983 1:35 pm, by Teitelman
Register command was getting name of file from fetchIconFileWindow rather than fetchFileWIndow
changes to: RegisterIconProc
Pier, May 9, 1985 converted to Cedar 6.0
Changed menu order slightly; added DeskTopGrayIfWhite.
Jules Bloomenthal, April 7, 1988 8:36:39 pm PDT
Modified IconEditorImplB.FillIcon so it would fill the selected rectangle of the current icon, if a selected rectangle existed; previous behavior (completely new icon) if no selected rectangle.
Jules Bloomenthal, March 6, 1989 8:46:14 am PST
Added Flip command; cleaned up some of this byzantine code.
Jules Bloomentha, April 11, 1990 1:00:05 pm PDT