<> -- Last Edited by: Plass, March 28, 1983 3:03 pm DIRECTORY Buttons USING [Button, ButtonProc, Create, SetDisplayStyle], ChoiceButtons USING [BuildEnumTypeSelection, BuildTextPrompt, GetSelectedButton, PromptDataRef, SelectionNotifierProc, UpdateChoiceButtons], Containers USING [ChildXBound, Create], Graphics USING [Box, Color], MessageWindow USING [Append, Blink], Rope USING [Cat, Equal, ROPE], Rules USING [Rule, Create], StyleToolBuilders USING [DisplayRealInViewer], StyleToolConvert USING [ConvertUnits, GetRealFromViewer], StyleToolDefs USING [MarginType, PageBoundaryType, StyleToolHandle, unitsList, ValueAndUnitsRef], StyleToolGraphicsMisc, VFonts USING [CharWidth, EstablishFont, Font], ViewerClasses USING [Viewer], ViewerOps USING [CreateViewer, EstablishViewerPosition, PaintViewer], ViewerTools USING [GetContents, SetContents]; StyleToolGraphicsMiscImpl: CEDAR PROGRAM IMPORTS Buttons, ChoiceButtons, Containers, MessageWindow, Rope, Rules, StyleToolBuilders, StyleToolConvert, StyleToolDefs, VFonts, ViewerOps, ViewerTools EXPORTS StyleToolGraphicsMisc = BEGIN OPEN StyleToolDefs, StyleToolGraphicsMisc; <> <<>> defaultUnits: PUBLIC Rope.ROPE _ "inches"; numbersContainerFont: PUBLIC VFonts.Font _ VFonts.EstablishFont[family: "Helvetica", size: 10, bold: TRUE, italic: FALSE, defaultOnFailure: TRUE]; setButtonFont: PUBLIC VFonts.Font _ VFonts.EstablishFont[family: "Helvetica", size: 14, bold: TRUE, italic: FALSE, defaultOnFailure: TRUE]; realWidth: PUBLIC INTEGER _ 6*VFonts.CharWidth['0]; -- width of text viewer for real #'s CreateNumbersContainer: PUBLIC PROCEDURE [handle: StyleToolHandle] RETURNS [INTEGER] = { OPEN handle.layoutGraphics; -- for numbersContainer, container, etc height: INTEGER _ 0; -- the height of this container rule: Rules.Rule; y1, y2: INTEGER; -- the y positions of the 1st and 2nd rows of items numbersContainer _ Containers.Create[[iconic: FALSE, scrollable: FALSE, border: FALSE, parent: container, wx: 0, wy: 0]]; Containers.ChildXBound[container, numbersContainer]; << now create all the individual information viewers.>> y1 _ 0; units.ref _ ChoiceButtons.BuildEnumTypeSelection[viewer: numbersContainer, x: 0, y: y1, title: "Units", buttonNames: unitsList, default: defaultUnits, borderOnButtons: FALSE, notifyClientProc: ChangeUnits, clientdata: handle, style: flipThru]; units.prev _ defaultUnits; y2 _ units.ref.nexty; setButton _ Buttons.Create[info: [wx: 0, wy: y2, name: "Set", border: TRUE, parent: numbersContainer], proc: SetProc, clientData: handle, fork: TRUE, font: setButtonFont]; pageWidth _ ChoiceButtons.BuildTextPrompt[viewer: numbersContainer, x: units.ref.nextx+6, y: y1, title: "Page Width:", font: numbersContainerFont, textViewerWidth: realWidth]; pageLength _ ChoiceButtons.BuildTextPrompt[viewer: numbersContainer, x: units.ref.nextx+6, y: y2, title: "Page Length:", font: numbersContainerFont, textViewerWidth: realWidth]; leftMargin _ ChoiceButtons.BuildTextPrompt[viewer: numbersContainer, x: pageLength.newx+6, y: y1, title: "Left Margin:", font: numbersContainerFont, textViewerWidth: realWidth]; rightMargin _ChoiceButtons.BuildTextPrompt[viewer: numbersContainer, x: pageLength.newx+6, y: y2, title: "Right Margin:", font: numbersContainerFont, textViewerWidth: realWidth]; topMargin _ ChoiceButtons.BuildTextPrompt[viewer: numbersContainer, x: rightMargin.newx+6, y: y1, title: "Top Margin:", font: numbersContainerFont, textViewerWidth: realWidth]; bottomMargin_ChoiceButtons.BuildTextPrompt[viewer: numbersContainer, x:rightMargin.newx+6, y: y2, title: "Bottom Margin:", font: numbersContainerFont, textViewerWidth: realWidth]; bindingMargin _ ChoiceButtons.BuildTextPrompt[viewer: numbersContainer, x: topMargin.newx + 6, y: y1, title: "Binding Margin:", font: numbersContainerFont, textViewerWidth: realWidth]; height _ bottomMargin.newy + 3; ViewerOps.EstablishViewerPosition[numbersContainer, numbersContainer.wx, numbersContainer.wy, numbersContainer.ww, height]; << create the divider>> rule _ Rules.Create[[wx: 0, wy: height, wh: 2, scrollable: FALSE, iconic: FALSE, parent: container]]; Containers.ChildXBound[container, rule]; RETURN[height + 4]; }; SetProc: Buttons.ButtonProc = { <> handle: StyleToolHandle _ NARROW[clientData]; theButton: Buttons.Button _ NARROW[parent]; units: Rope.ROPE; Buttons.SetDisplayStyle[theButton, $WhiteOnBlack]; << First determine the units>> units _ ChoiceButtons.GetSelectedButton[handle.layoutGraphics.units.ref]; DetermineInterval[handle, units]; ViewerOps.PaintViewer[handle.layoutGraphics.container, client]; << Also make sure that the proper values get set for the original page layout parameters>> SetOriginals[handle, handle.swap.layout.pageWidth, handle.layoutGraphics.pageWidth, units]; SetOriginals[handle, handle.swap.layout.pageLength, handle.layoutGraphics.pageLength, units]; SetOriginals[handle, handle.swap.layout.leftMargin, handle.layoutGraphics.leftMargin, units]; SetOriginals[handle, handle.swap.layout.rightMargin, handle.layoutGraphics.rightMargin, units]; SetOriginals[handle, handle.swap.layout.topMargin, handle.layoutGraphics.topMargin, units]; SetOriginals[handle, handle.swap.layout.bottomMargin, handle.layoutGraphics.bottomMargin, units]; SetOriginals[handle, handle.swap.layout.bindingMargin, handle.layoutGraphics.bindingMargin, units]; Buttons.SetDisplayStyle[theButton, $BlackOnWhite]; }; SetOriginals: PROCEDURE [handle: StyleToolHandle, origRef: ValueAndUnitsRef, curRef: ChoiceButtons.PromptDataRef, units: Rope.ROPE] = { ViewerTools.SetContents[origRef.valueData.textViewer, ViewerTools.GetContents[curRef.textViewer]]; ChoiceButtons.UpdateChoiceButtons[handle.swap.layout.outer, origRef.units, units]; }; ChangeUnits: ChoiceButtons.SelectionNotifierProc = { handle: StyleToolHandle _ NARROW[clientdata]; << determine what the old units were>> oldunits: Rope.ROPE _ handle.layoutGraphics.units.prev; << now update the previous units IFF the new units are not ems, ens or spaces. This is a kludge to get around not having conversions for ems, ens and spaces. (They are font dependent)>> IF ~(Rope.Equal[name, "ems", FALSE]) AND ~(Rope.Equal[name, "ens",FALSE]) AND ~(Rope.Equal[name, "spaces", FALSE]) THEN { handle.layoutGraphics.units.prev _ name; ChangeValuesInViewers[handle, oldunits, name]; }; }; ChangeValuesInViewers: PROCEDURE [handle: StyleToolHandle, oldUnits, newUnits: Rope.ROPE] = { ChangeViewerValue[handle.layoutGraphics.pageWidth, newUnits, oldUnits]; ChangeViewerValue[handle.layoutGraphics.pageLength, newUnits, oldUnits]; ChangeViewerValue[handle.layoutGraphics.rightMargin, newUnits, oldUnits]; ChangeViewerValue[handle.layoutGraphics.leftMargin, newUnits, oldUnits]; ChangeViewerValue[handle.layoutGraphics.topMargin, newUnits, oldUnits]; ChangeViewerValue[handle.layoutGraphics.bottomMargin, newUnits, oldUnits]; ChangeViewerValue[handle.layoutGraphics.bindingMargin, newUnits, oldUnits]; }; ChangeViewerValue: PROCEDURE [ref: ChoiceButtons.PromptDataRef, newUnits, oldUnits: Rope.ROPE] = { value: REAL _ StyleToolConvert.GetRealFromViewer[ref.textViewer]; value _ StyleToolConvert.ConvertUnits[value, oldUnits, newUnits]; StyleToolBuilders.DisplayRealInViewer[value, ref.textViewer]; }; DetermineInterval: PROCEDURE [handle: StyleToolHandle, units: Rope.ROPE] = { ChangeToDefault: PROCEDURE = { MessageWindow.Append[Rope.Cat["Sorry, not implemented. Using ", defaultUnits], TRUE]; MessageWindow.Blink[]; ChoiceButtons.UpdateChoiceButtons[handle.layoutGraphics.numbersContainer, handle.layoutGraphics.units.ref, defaultUnits]; handle.layoutGraphics.interval _ defaultInterval; -- convert all the margins, etc back to default units ChangeValuesInViewers[handle, handle.layoutGraphics.units.prev, defaultUnits]; handle.layoutGraphics.units.prev _ defaultUnits; }; SELECT TRUE FROM Rope.Equal[units, "points", FALSE] => handle.layoutGraphics.interval _ 20; Rope.Equal[units, "picas", FALSE] => handle.layoutGraphics.interval _ 20; Rope.Equal[units, "inches", FALSE] => handle.layoutGraphics.interval _ 40; Rope.Equal[units, "centimeters", FALSE] => handle.layoutGraphics.interval _ 16; Rope.Equal[units, "millimeters", FALSE] => handle.layoutGraphics.interval _ 16; Rope.Equal[units, "didot points", FALSE] => handle.layoutGraphics.interval _ 16; Rope.Equal[units, "ems", FALSE] => ChangeToDefault[]; Rope.Equal[units, "ens", FALSE] => ChangeToDefault[]; Rope.Equal[units, "spaces", FALSE] => ChangeToDefault[]; ENDCASE; }; ConvertAndDisplay: PROCEDURE [ref: ValueAndUnitsRef, defaultValue: REAL, displayInfo: ChoiceButtons.PromptDataRef] = { << takes the value currently on display in the StyleTool (that is, in the ValueAndUnitsRef provided), converts it to inches and returns converted value in form of rope. If the value currently on display in the StyleTool was zero, the default value provided is used>> value: REAL; value _ StyleToolConvert.GetRealFromViewer[ref.valueData.textViewer]; IF (value = 0.0) THEN value _ defaultValue ELSE value _ StyleToolConvert.ConvertUnits[value, ChoiceButtons.GetSelectedButton[ref.units], defaultUnits]; StyleToolBuilders.DisplayRealInViewer[value, displayInfo.textViewer]; }; SetUpNumbers: PUBLIC PROCEDURE [handle: StyleToolHandle] = { << initially we will default to inches. The user can change the units later>> ConvertAndDisplay[handle.swap.layout.pageWidth, defaultPageWidth, handle.layoutGraphics.pageWidth]; ConvertAndDisplay[handle.swap.layout.pageLength, defaultPageLength, handle.layoutGraphics.pageLength]; ConvertAndDisplay[handle.swap.layout.leftMargin, defaultLeftMargin, handle.layoutGraphics.leftMargin]; ConvertAndDisplay[handle.swap.layout.rightMargin, defaultRightMargin, handle.layoutGraphics.rightMargin]; ConvertAndDisplay[handle.swap.layout.topMargin, defaultTopMargin, handle.layoutGraphics.topMargin]; ConvertAndDisplay[handle.swap.layout.bottomMargin, defaultBottomMargin, handle.layoutGraphics.bottomMargin]; ConvertAndDisplay[handle.swap.layout.bindingMargin, defaultBindingMargin, handle.layoutGraphics.bindingMargin]; }; InsidePage: PUBLIC PROCEDURE [handle: StyleToolHandle, x, y: REAL] RETURNS [BOOLEAN] = { << We check for less than or equal or greater than or equal so that the user can bring the margins right up to the page boundaries if desired.>> IF (x <= handle.layoutGraphics.screenPage.xmax) AND (x >= handle.layoutGraphics.screenPage.xmin) AND (y <= handle.layoutGraphics.screenPage.ymax) AND (y >= handle.layoutGraphics.screenPage.ymin) THEN RETURN [TRUE] ELSE RETURN [FALSE]; }; HitAMargin: PUBLIC PROCEDURE [handle: StyleToolHandle, x,y: REAL] RETURNS [MarginType] = { << check vertical margins first (left and right). This is so that when there is an equally likely chance of choosing one of two margins (eg - the top margin or the left margin) the vertical margin will be chosen. This would happen if the mouse was on or very near to an intersection point. This situation will not happen with 2 vertical margins>> epsilon: REAL _ 1.0; IF (handle.layoutGraphics.screenLeftMargin <= x + epsilon) AND (handle.layoutGraphics.screenLeftMargin >= x - epsilon) THEN RETURN [left] ELSE IF (handle.layoutGraphics.screenBindingMargin <= x + epsilon) AND (handle.layoutGraphics.screenBindingMargin >= x - epsilon) THEN RETURN [binding] ELSE IF (handle.layoutGraphics.screenRightMargin <= x + epsilon) AND (handle.layoutGraphics.screenRightMargin >= x - epsilon) THEN RETURN [right] ELSE IF (handle.layoutGraphics.screenTopMargin <= y + epsilon) AND (handle.layoutGraphics.screenTopMargin >= y - epsilon) THEN RETURN [top] ELSE IF (handle.layoutGraphics.screenBottomMargin <= y+epsilon) AND (handle.layoutGraphics.screenBottomMargin >= y - epsilon) THEN RETURN [bottom] ELSE RETURN [none]; }; HitAPage: PUBLIC PROCEDURE [handle: StyleToolHandle, x,y: REAL] RETURNS [PageBoundaryType] = { << check vertical page boundaries first (left and right). This is so that when there is an equally likely chance of choosing one of two page boundaries (eg - the top page boundary or the right page boundary) the vertical page boundary will be chosen. This would happen if the mouse was on or very near to an intersection point. >> epsilon: REAL _ 3.0; IF (handle.layoutGraphics.screenPage.xmin <= x + epsilon) AND (handle.layoutGraphics.screenPage.xmin >= x - epsilon) THEN { OPEN MessageWindow; -- for Append and Blink Append["You cannot move the left page boundary to change the page width", TRUE]; Blink[]; RETURN [none]; } ELSE IF (handle.layoutGraphics.screenPage.xmax <= x + epsilon) AND (handle.layoutGraphics.screenPage.xmax >= x - epsilon) THEN RETURN [side] ELSE IF (handle.layoutGraphics.screenPage.ymax <= y + epsilon) AND (handle.layoutGraphics.screenPage.ymax >= y - epsilon) THEN RETURN [top] ELSE IF (handle.layoutGraphics.screenPage.ymin <= y+epsilon) AND (handle.layoutGraphics.screenPage.ymin >= y - epsilon) THEN { OPEN MessageWindow; -- for Append and Blink Append["You cannot move the bottom page boundary to change the page length", TRUE]; Blink[]; RETURN [none] } ELSE RETURN [none]; }; ScreenToLeftMargin: PUBLIC PROCEDURE [handle: StyleToolHandle] RETURNS [REAL] = { OPEN handle.layoutGraphics; -- for screenLeftMargin, screenPage, interval, increment RETURN[((screenLeftMargin - screenPage.xmin)/ interval) * (increment/skip)]; }; ScreenToRightMargin: PUBLIC PROCEDURE [handle: StyleToolHandle] RETURNS [REAL] = { OPEN handle.layoutGraphics; -- for screenRightMargin, screenPage, interval, increment RETURN[((screenPage.xmax - screenRightMargin)/ interval) * (increment/skip)]; }; ScreenToBindingMargin: PUBLIC PROCEDURE [handle: StyleToolHandle] RETURNS [REAL] = { OPEN handle.layoutGraphics; -- for screenBindingMargin, screenLeftMargin, interval, increment RETURN[((screenBindingMargin - screenLeftMargin)/ interval) * (increment/skip)]; }; ScreenToTopMargin: PUBLIC PROCEDURE [handle: StyleToolHandle] RETURNS [REAL] = { OPEN handle.layoutGraphics; -- for screenTopMargin, screenPage, interval, increment RETURN[((screenPage.ymax - screenTopMargin)/ interval) * (increment/skip)]; }; ScreenToBottomMargin: PUBLIC PROCEDURE [handle: StyleToolHandle] RETURNS [REAL] = { OPEN handle.layoutGraphics; -- for screenBottomMargin, screenPage, interval, increment RETURN[((screenBottomMargin - screenPage.ymin)/ interval) * (increment/skip)]; }; ScreenToPageWidth: PUBLIC PROCEDURE [handle: StyleToolHandle] RETURNS [REAL] = { OPEN handle.layoutGraphics; -- for screenPage, interval, increment RETURN[((screenPage.xmax - screenPage.xmin)/ interval) * (increment/skip)]; }; ScreenToPageLength: PUBLIC PROCEDURE [handle: StyleToolHandle] RETURNS [REAL] = { OPEN handle.layoutGraphics; -- for screenPage, interval, increment RETURN[((screenPage.ymax - screenPage.ymin)/ interval) * (increment/skip)]; }; END.