~
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"];
};
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