DIRECTORY CursorDefs, Graphics USING [DrawChar, Context, DrawRope, Map, SetCP, WorldToUser, SetDefaultFont, SetPaintMode, SetStipple], Heuristic USING [MakeBeams, MakeChords, MakeSyncs, SetNoteValues], Interface USING [count, DeleteGraphical, Flash, MoveNote, MoveGraphical, Object, Wait], MusicDefs, Piece USING [AddEvent, CleanUpNotes, Copy, Merge, NearestNote, New, Overflow, Replace], Real USING [Fix, FixI], Score USING [ Draw, FileIn, FileOut, Initialize, Look, Print, Redraw, SetKey, SetMetrenome, SetStyle, SetTimeSignature, ShowLogical, StartListening, StartPlaying, StopListening, StopPlaying, Test], Screen USING [CommandProcs, DisplayMessage, screen], Selection, -- USING everything Sheet USING [ FindLine, LineNumber, Map, NearestTime, Reset, ScreenPoint, Scroll, SetBegin], String USING [AppendString, UpperCase], TTY USING [Create, GetChar, GetDecimal, GetID, Handle, Rubout], UserTerminal USING [cursor, GetCursorPattern, SetCursorPattern], Utility, -- USING everything Voice USING [Check, Set]; InterfaceImplA: CEDAR MONITOR IMPORTS Graphics, Heuristic, Interface, MusicDefs, Piece, Real, Score, Screen, Selection, Sheet, String, TTY, UserTerminal, Utility, Voice EXPORTS Screen = BEGIN OPEN Graphics, MusicDefs, UserTerminal; keyboard: TTY.Handle; Error: SIGNAL; test: BOOL _ FALSE; commands: PUBLIC Screen.CommandProcs _ [Play, Listen, HandleRed, HandleYellow, HandleBlue, HandleKeyboard, Scroll, Thumb, Score.Draw, Score.FileIn, FileOut, Hardcopy, Initialize, 0]; Initialize: PROC[context: Graphics.Context] RETURNS[score: ScorePTR] = { keyboard _ TTY.Create[NIL]; score _ Piece.New[1000, TRUE]; score.beamHeap _ Utility.NewSegment[SIZE[BeamHeapRec[100]], 100, SIZE[BeamHeapRec[0]]-1]; IF score.beamHeap.max # 100 THEN ERROR; score.chordHeap _ Utility.NewSegment[SIZE[ChordHeapRec[100]], 100, SIZE[ChordHeapRec[0]]-1]; IF score.chordHeap.max # 100 THEN ERROR; Score.Initialize[score, context]; }; HandleKeyboard: PROC[score: ScorePTR] = { ENABLE Piece.Overflow => IF score = old THEN score _ new; ClearDirty[score]; Do[score, TTY.GetChar[keyboard]]; IF test AND Score.Test[score] THEN Error; -- you may proceed, but you cannot file out }; HandleBlue: PROC[score: ScorePTR] = { OPEN Interface; ENABLE Piece.Overflow => IF score = old THEN score _ new; ClearDirty[score]; count _ FALSE; SELECT TRUE FROM Control[] => {HandleMenu[]; count _ FALSE}; Shift[] => {Selection.Clear[]; WHILE BlueBug[] DO Interface.MoveNote[score, Piece.NearestNote[score]]; ENDLOOP}; ENDCASE => Interface.MoveGraphical[score, defaultObject]; IF test AND Score.Test[score] THEN Error; -- you may proceed, but you cannot file out IF count THEN commands.count _ commands.count+1; }; HandleYellow: PROC[score: ScorePTR] = { OPEN CursorDefs, Interface; temp: Cursor _ GetCursorPattern[]; SetCursorPattern[textCursor]; ClearDirty[score]; count _ FALSE; SELECT TRUE FROM score.sheet.scale > 3 => ChangeLook[score, 'O]; Shift[] AND Control[] => NULL; Control[] => NULL; ENDCASE => Interface.DeleteGraphical[score]; SetCursorPattern[temp]; WHILE YellowBug[] DO NULL; ENDLOOP; IF test AND Score.Test[score] THEN Error; -- you may proceed, but you cannot file out IF count THEN commands.count _ commands.count+1; }; HandleRed: PROC[score: ScorePTR] = { OPEN CursorDefs; x, y: INTEGER; i, click: CARDINAL _ 0; temp: Cursor _ GetCursorPattern[]; SetCursorPattern[textCursor]; ClearDirty[score]; WHILE RedBug[] DO [x, y] _ Sheet.ScreenPoint[score.sheet]; SELECT TRUE FROM Control[] => { FOR i IN [0..5) DO Interface.Wait[1]; IF ~RedBug[] THEN {click _ 1; EXIT}; ENDLOOP; IF click = 1 THEN FOR i IN [0..5) DO Interface.Wait[1]; IF RedBug[] THEN {click _ 2; EXIT}; ENDLOOP; SELECT click FROM 0 => ChooseLine[score, Sheet.NearestTime[score.sheet, x, y].time]; 1 => EXIT; 2 => ExtendLine[score]; ENDCASE => ERROR}; Shift[] => Selection.AddNote[score, Piece.NearestNote[score, x, y]]; ENDCASE => {IF score.command THEN Selection.Clear[]; Selection.AddNote[score, Piece.NearestNote[score, x, y]]}; score.command _ FALSE; ENDLOOP; SetCursorPattern[temp]; IF test AND Score.Test[score] THEN Error; -- you may proceed, but you cannot file out }; ClearDirty: PROC[score: ScorePTR] = INLINE { score.sheet.dirty1 _ 100000; score.sheet.dirty2 _ -1}; ExtendLine: PROC[score: ScorePTR] = { time: Time; temp, gTemp: ScorePTR; grey: BOOL _ FALSE; switch: BOOL _ TRUE; beginning: BOOL _ FALSE; temp1, temp2, gTemp1, gTemp2: Time; temp _ Selection.selection.score; gTemp _ Selection.selection.score2; temp1 _ Selection.selection.select1; temp2 _ Selection.selection.select2; gTemp1 _ Selection.selection.greySelect1; gTemp2 _ Selection.selection.greySelect2; WHILE RedBug[] DO IF Shift[] AND NOT grey THEN { grey _ TRUE; switch _ TRUE; Selection.AddLine[temp, temp1, temp2]; }; IF NOT Shift[] AND grey THEN { grey _ FALSE; switch _ TRUE; Selection.AddGreyLine[gTemp, gTemp1, gTemp2]; }; [time] _ Sheet.NearestTime[score.sheet]; IF switch THEN IF grey THEN beginning _ Beginning[time, Selection.selection.greySelect1, Selection.selection.greySelect2] ELSE beginning _ Beginning[time, Selection.selection.select1, Selection.selection.select2]; switch _ FALSE; IF grey THEN IF beginning THEN Selection.AddGreyLine[score, time, Selection.selection.greySelect2] ELSE Selection.AddGreyLine[score, Selection.selection.greySelect1, time] ELSE IF beginning THEN Selection.AddLine[score, time, Selection.selection.select2] ELSE Selection.AddLine[score, Selection.selection.select1, time] ENDLOOP; }; Beginning: PROC[time, begin, end: Time] RETURNS[BOOL] = INLINE { IF time <= begin THEN RETURN[TRUE]; IF time >= end THEN RETURN[FALSE]; RETURN[ABS[time-begin] < ABS[time-end]]; }; ChooseLine: PROC[score: ScorePTR, time: Time] = { time2: Time; temp, gTemp: ScorePTR; temp1, temp2, gTemp1, gTemp2: Time; grey: BOOL _ FALSE; temp _ Selection.selection.score; temp1 _ Selection.selection.select1; temp2 _ Selection.selection.select2; gTemp _ Selection.selection.score2; gTemp1 _ Selection.selection.greySelect1; gTemp2 _ Selection.selection.greySelect2; WHILE RedBug[] DO IF Shift[] AND NOT grey THEN { grey _ TRUE; Selection.AddLine[temp, temp1, temp2]; }; IF NOT Shift[] AND grey THEN { grey _ FALSE; Selection.AddGreyLine[gTemp, gTemp1, gTemp2]; }; [time2] _ Sheet.NearestTime[score.sheet]; IF grey THEN Selection.AddGreyLine[score, time, time2] ELSE Selection.AddLine[score, time, time2]; ENDLOOP; }; Do: PROC[score: ScorePTR, c: CHARACTER] = { ENABLE Piece.Overflow => IF score = old THEN score _ new; a, b: INTEGER; SELECT c FROM 'b => IF Selection.selection.lineSelect THEN Heuristic.MakeBeams[score, Selection.selection.select1, Selection.selection.select2] ELSE Selection.MakeBeam[]; 'B => Selection.ClearBeam[]; 002C => Selection.MakeBeamOfBeams[]; 'c => IF Selection.selection.lineSelect THEN Heuristic.MakeChords[score, Selection.selection.select1, Selection.selection.select2] ELSE Selection.MakeChord[]; 'C => Selection.ClearChord[]; 'd => Selection.Delete[]; 'e => {Selection.AddLine[score, 0, EndOfScore[score]]; RETURN}; 'g => Selection.SetGrace[TRUE]; 'G => Selection.SetGrace[FALSE]; 007C => Heuristic.SetNoteValues[score, Selection.selection.select1, Selection.selection.select2]; 'k => Score.SetKey[score, Selection.selection.select1, Selection.selection.select2, ReadKey[score]]; 'l => {ChangeLook[score, TTY.GetChar[keyboard]]; RETURN}; 014C => {Score.ShowLogical[score, 0, score.length-1]; Sheet.Reset[score]}; -- debugging aid 'm => Score.SetMetrenome[score, Selection.selection.select1, Selection.selection.select2, MAX[16, ReadNumbers["metrenome: < m > CR"].a]]; 'n => {[a, b] _ ReadNumbers["n-tuplet: < n > CR < m > CR", TRUE]; Selection.MakeNTuplet[b, a]}; 'N => Selection.HideNTuplets[TRUE]; 016C => {[a, b] _ ReadNumbers["n-tuplet: < n > CR < m > CR", TRUE]; Selection.MakeNTupletOfBeams[b, a]}; 'p => Selection.Transpose[ReadNumbers["transpose: +/- < n > CR"].a]; 'r => IF Selection.selection.lineSelect THEN Piece.Replace[Selection.selection.score, Piece.Copy[Selection.selection.score2, Selection.selection.greySelect1, Selection.selection.greySelect2], Selection.selection.select1, Selection.selection.select2] ELSE Selection.SetRest[TRUE]; 'R => IF ~Selection.selection.lineSelect THEN Selection.SetRest[FALSE] ELSE score.flash _ TRUE; 's => IF Selection.selection.lineSelect THEN Heuristic.MakeSyncs[score, Selection.selection.select1, Selection.selection.select2] ELSE Selection.MakeSync[]; 'S => Selection.ClearSync[]; 't => Selection.MakeTie[]; 'T => Selection.ClearTie[]; 'x => {Voice.Check[score]; RETURN}; 'v => Voice.Set[score, ReadDigit[score]]; ' => {insertMeasure _ TRUE; RETURN}; '0 => Selection.SetNoteValue[unknown, 0]; '1 => Selection.SetNoteValue[whole, 0]; '! => Selection.SetNoteValue[whole, 1]; '2 => Selection.SetNoteValue[half, 0]; '@ => Selection.SetNoteValue[half, 1]; '4 => Selection.SetNoteValue[quarter, 0]; '$ => Selection.SetNoteValue[quarter, 1]; '8 => Selection.SetNoteValue[eighth, 0]; '* => Selection.SetNoteValue[eighth, 1]; '6 => Selection.SetNoteValue[sixteenth, 0]; '~ => Selection.SetNoteValue[sixteenth, 1]; '3 => Selection.SetNoteValue[thirtysecond, 0]; '# => Selection.SetNoteValue[thirtysecond, 1]; '7 => Selection.SetNoteValue[sixtyfourth, 0]; '& => Selection.SetNoteValue[sixtyfourth, 1]; '[ => Selection.SetStaff[ReadDigit[score]]; '^ => Selection.SetStem[TRUE]; '_ => Selection.SetStem[FALSE]; '/ => {[a, b] _ ReadNumbers["time signature: < a > CR < b > CR", TRUE]; Score.SetTimeSignature[score, [a, b], Selection.selection.select1, Selection.selection.select2]}; 033C => {Selection.Clear[]; RETURN}; ENDCASE => RETURN; score.command _ TRUE; IF score.flash THEN {Interface.Flash[score]; RETURN}; commands.count _ commands.count+1; IF Selection.selection.lineSelect AND score.sheet.dirty1 > score.sheet.dirty2 THEN Score.Redraw[score, Selection.selection.select1, Selection.selection.select2] ELSE Score.Redraw[score, score.sheet.dirty1, score.sheet.dirty2]; }; ChangeLook: PROC[score: ScorePTR, c: CHARACTER] = { ENABLE Piece.Overflow => IF score = old THEN score _ new; count: BOOL _ FALSE; repaint: BOOL _ TRUE; SELECT c FROM 'a => Score.Look[score, accidental, TRUE]; 'A => Score.Look[score, accidental, FALSE]; 'c => Score.Look[score, noCarry, FALSE]; 'C => Score.Look[score, noCarry, TRUE]; 'g => score.flash _ TRUE; 'h => Score.Look[score, hardcopy, TRUE]; 'H => Score.Look[score, hardcopy, FALSE]; 'j => {Score.Look[score, justified, , ReadDigit[score]]; count _ TRUE}; 'l => {Score.Look[score, logical]; count _ TRUE}; 'n => Score.Look[score, notehead, TRUE]; 'N => Score.Look[score, notehead, FALSE]; 'o => Score.Look[score, overview, TRUE]; 'O => Score.Look[score, overview, FALSE]; 'p => {Score.Look[score, physical, , ReadDigit[score]]; count _ TRUE}; 's => {Score.Look[score, sync, TRUE]; repaint _ FALSE}; 'S => Score.Look[score, sync, FALSE]; 'v => Score.Look[score, voice, TRUE, ReadDigit[score]]; 'V => {Score.Look[score, voice, FALSE]; repaint _ FALSE}; 177C => TTY.Rubout; ENDCASE => {Score.SetStyle[score, Digit[score, c], Selection.selection.select1, Selection.selection.select2]; count _ TRUE}; score.command _ TRUE; IF score.flash THEN {Interface.Flash[score]; RETURN}; Score.Draw[score, repaint]; IF count THEN commands.count _ commands.count+1; }; ReadKey: PROC[score: ScorePTR] RETURNS[k: INTEGER] = { key, c: CHARACTER; accidental: Accidental _ inKey; CR: CHARACTER = 015C; Major: BOOL _ TRUE; negative: BOOL _ FALSE; Screen.DisplayMessage["Please enter key name (A, Bb, C # m...) or number."]; key _ TTY.GetChar[keyboard]; IF key = '- THEN { key _ TTY.GetChar[keyboard]; Screen.DisplayMessage[NIL]; RETURN[-Digit[score, key]]}; IF key IN ['0..'9] THEN { Screen.DisplayMessage[NIL]; RETURN[Digit[score, key]]}; key _ String.UpperCase[key]; IF key = 177C THEN TTY.Rubout; WHILE (c _ TTY.GetChar[keyboard]) # CR DO SELECT c FROM 'm => Major _ FALSE; 'b => accidental _ flat; '# => accidental _ sharp; 177C => TTY.Rubout; ENDCASE; ENDLOOP; Screen.DisplayMessage[NIL]; SELECT key FROM 'C => k _ 0; 'D => k _ 2; 'E => k _ 4; 'F => k _ -1; 'G => k _ 1; 'A => k _ 3; 'B => k _ 5; ENDCASE => {Interface.Flash[score]; RETURN[-100]}; IF accidental = flat THEN k _ k- 7; IF accidental = sharp THEN k _ k+ 7; IF NOT Major THEN k _ k- 3; RETURN[k]; }; ReadFileName: PROC[s: STRING] = { TTY.GetID[keyboard, fileName ! TTY.Rubout => RETRY]; String.AppendString[fileName, s]; RETURN; }; fileName: STRING _ [50]; ReadNumbers: PROC[s: STRING, two: BOOL _ FALSE] RETURNS[a, b: INTEGER] = { a _ b _ 0; Screen.DisplayMessage[s]; a _ TTY.GetDecimal[keyboard]; Screen.DisplayMessage[NIL]; IF NOT two THEN RETURN; Screen.DisplayMessage["and the second number..."]; b _ TTY.GetDecimal[keyboard]; Screen.DisplayMessage[NIL]; }; ReadDigit: PROC[score: ScorePTR] RETURNS[d: CARDINAL] = { Screen.DisplayMessage["Please enter a digit"]; d _ Digit[score, TTY.GetChar[keyboard]]; Screen.DisplayMessage[NIL]; }; Digit: PROC[score: ScorePTR, c: CHARACTER] RETURNS[CARDINAL] = { SELECT c FROM '0 => RETURN[0]; '1 => RETURN[1]; '2 => RETURN[2]; '3 => RETURN[3]; '4 => RETURN[4]; '5 => RETURN[5]; '6 => RETURN[6]; '7 => RETURN[7]; '8 => RETURN[8]; '9 => RETURN[9]; ') => RETURN[10]; '! => RETURN[11]; '@ => RETURN[12]; '# => RETURN[13]; '$ => RETURN[14]; '% => RETURN[15]; '~ => RETURN[16]; '& => RETURN[17]; '* => RETURN[18]; '( => RETURN[19]; 033C => RETURN[score.sheet.justification]; -- default for justify ENDCASE => TTY.Rubout; RETURN[0]; }; defaultObject: Interface.Object _ none; HandleMenu: PROC = { OPEN CursorDefs, Interface; x, y, i, j, newI, newJ: CARDINAL _ 0; x _ UserTerminal.cursor.x; y _ UserTerminal.cursor.y; DisplayMenu[x+4, y+4]; CursorGetsMenu[0, 0]; WHILE BlueBug[] DO newI _ (UserTerminal.cursor.x-x)/16; newJ _ (UserTerminal.cursor.y-y+8)/16; IF i = newI AND j = newJ THEN LOOP; i _ newI; j _ newJ; CursorGetsMenu[i, j]; ENDLOOP; DisplayMenu[x+4, y+4]; SELECT j FROM 0 => SELECT i FROM 0 => defaultObject _ note; 1 => defaultObject _ rest; 2 => defaultObject _ staves; 3 => defaultObject _ measure; 4 => defaultObject _ doubleMeasure; 5 => defaultObject _ repeat1; 6 => defaultObject _ repeat2; 7 => defaultObject _ endMeasure; 8 => defaultObject _ treble; 9 => defaultObject _ bass; 10 => defaultObject _ octava; ENDCASE => defaultObject _ none; 1 => SELECT i FROM 0 => defaultObject _ doubleFlat; 1 => defaultObject _ flat; 2 => defaultObject _ natural; 3 => defaultObject _ inKey; 4 => defaultObject _ sharp; 5 => defaultObject _ doubleSharp; 6 => defaultObject _ trill; 7 => defaultObject _ mordent1; 8 => defaultObject _ mordent2; ENDCASE => defaultObject _ none; ENDCASE => defaultObject _ none; }; CursorGetsMenu: PROC[i, j: CARDINAL] = { OPEN CursorDefs; SELECT j FROM 0 => SELECT i FROM 0 => SetCursorPattern[quarter]; 1 => SetCursorPattern[rest]; 2 => SetCursorPattern[measure]; 3 => SetCursorPattern[measure]; 4 => SetCursorPattern[doubleMeasure]; 5 => SetCursorPattern[repeat1]; 6 => SetCursorPattern[repeat2]; 7 => SetCursorPattern[endMeasure]; 8 => SetCursorPattern[trebleClef]; 9 => SetCursorPattern[bassClef]; 10 => SetCursorPattern[octava]; ENDCASE => SetCursorPattern[textCursor]; 1 => SELECT i FROM 0 => SetCursorPattern[doubleFlat]; 1 => SetCursorPattern[flat]; 2 => SetCursorPattern[natural]; 3 => SetCursorPattern[inKey]; 4 => SetCursorPattern[sharp]; 5 => SetCursorPattern[doubleSharp]; 6 => SetCursorPattern[trill]; 7 => SetCursorPattern[mordent1]; 8 => SetCursorPattern[mordent2]; ENDCASE => SetCursorPattern[textCursor]; ENDCASE => SetCursorPattern[textCursor]; }; DisplayMenu: PROC[x, y: INTEGER] = { OPEN Screen; newX, newY: REAL; [newX, newY] _ Graphics.WorldToUser[screen, x, 808 - y]; Graphics.SetCP[screen, newX, newY]; [] _ Graphics.SetPaintMode[screen, invert]; Graphics.SetStipple[screen, black]; Graphics.SetDefaultFont[screen, music]; Graphics.DrawRope[screen, "tzffghopRS"]; -- note, rest, measures, clefs Utility.SetFont[screen, text, 12]; Graphics.DrawChar[screen, '8]; Utility.SetFont[screen, music, 8]; newY _ newY-16; Graphics.SetCP[screen, newX, newY]; Graphics.DrawRope[screen, "EFG.MOUVW"]; -- accidentals, embellishments Graphics.SetDefaultFont[screen, text]; }; Hardcopy: PROC[score: ScorePTR, s: STRING] = {Score.Print[score: score, splines: ~score.sheet.hardcopy OR BlueBug[]]}; FileOut: PROC[score: ScorePTR, fileName: STRING] = { IF NOT Score.FileOut[score, fileName] THEN { Screen.DisplayMessage["FileOut aborted-- see mesa.typescript"]; Interface.Flash[score]}; }; Play: PROC[score: ScorePTR] = { ENABLE Piece.Overflow => IF score = old THEN score _ new; start: CARDINAL; IF playing THEN {Score.StopPlaying[score]; RETURN}; start _ score.length; insertMeasure _ FALSE; IF Selection.selection.select1 < Selection.selection.select2 THEN FOR i: CARDINAL IN [0..score.length) DO IF start # score.length OR score[i].time < Selection.selection.select1 THEN LOOP; start _ i; EXIT; ENDLOOP ELSE {start _ 0}; IF score.sheet.display = physical AND ~listening THEN { IF temp = NIL THEN temp _ Piece.New[1000]; Score.StartListening[temp]; merge _ TRUE}; Score.StartPlaying[score, start, score.sheet.display = physical, DisplayCursor]; IF score.flash THEN Interface.Flash[score]; }; temp: ScorePTR _ NIL; merge: BOOL _ FALSE; Listen: PROC[score: ScorePTR] = { ENABLE Piece.Overflow => IF score = old THEN score _ new; IF listening THEN { -- TURN THE LISTENER OFF Score.StopListening[score]; IF temp[0] = NIL THEN RETURN; -- nothing recorded IF merge THEN Piece.Merge[score, temp, Selection.selection.select1, LAST[Time]] ELSE { portion: ScorePortionPTR _ zone.NEW[ScorePortionRec]; portion.score _ temp; portion.duration _ 0; -- indicates a score from the synthesizer Piece.Replace[score, portion, Selection.selection.select1, Selection.selection.select2]}; temp _ NIL; Piece.CleanUpNotes[score]; Score.Look[score, voice, FALSE]; WHILE AnyBug[] DO NULL; ENDLOOP; Score.Draw[score: score, erase: ~merge]; commands.count _ 100; -- force a backup RETURN}; IF temp = NIL THEN temp _ Piece.New[1000]; IF score.sheet.justification < 64 THEN score.sheet.justification _ 256; Score.StartListening[temp]; IF score.flash THEN Interface.Flash[score]; merge _ FALSE; }; DisplayCursor: PROC[score: ScorePTR, time: Time] = { sx, sy: REAL; sync: SyncPTR; px, py: INTEGER; IF score.sheet.display = physical THEN time _ time/score.sheet.justification; IF time < score.sheet.begin THEN RETURN; [px, py] _ Sheet.Map[score.sheet, time, , 2]; py _ py+64; [sx, sy] _ Graphics.Map[score.sheet.context, Screen.screen, px, py]; cursor.x _ Real.FixI[sx]; cursor.y _ MAX[808 - Real.FixI[sy], 0]; IF NOT insertMeasure THEN RETURN; insertMeasure _ FALSE; sync _ zone.NEW[EventRec.sync]; sync.time _ time-8; score _ Piece.AddEvent[score, sync]; Score.Redraw[score, time-8, time-8]; }; insertMeasure: BOOL _ FALSE; Scroll: PROC[score: ScorePTR, by: INTEGER] = { time: Time; x, y: INTEGER; [x, y] _ Sheet.ScreenPoint[score.sheet]; time _ Sheet.NearestTime[score.sheet, x, y-40].time; IF by > 0 THEN Sheet.Scroll[score.sheet, MAX[Lines[score, score.sheet.begin, time], 1]] ELSE Sheet.Scroll[score.sheet, -MAX[Lines[score, score.sheet.begin, time], 1]]; Score.Draw[score]; }; Thumb: PROC[score: ScorePTR] = { sx, sy: REAL; endOfScore: Time; px, py: INTEGER; oldBegin: Time = score.sheet.begin; height: INTEGER _ 680; endOfScore _ EndOfScore[score]; SELECT score.sheet.scale FROM 1 => height _ height; 2 => height _ (3*height)/2; 4 => height _ 4*height; ENDCASE => ERROR; WHILE YellowBug[] DO [px, py] _ Sheet.ScreenPoint[score.sheet]; IF px > -10 THEN RETURN; py _ -(height*score.sheet.begin)/endOfScore; [sx, sy] _ Graphics.Map[score.sheet.context, Screen.screen, px, py]; Interface.Wait[1]; cursor.y _ MAX[808 - Real.FixI[sy], 0]; ENDLOOP; [px, py] _ Sheet.ScreenPoint[score.sheet]; score.sheet.begin _ (Real.Fix[score.sheet.top-py]*endOfScore)/height; score.sheet.begin _ MIN[score.sheet.begin, endOfScore-60]; score.sheet.begin _ MAX[score.sheet.begin, 0]; Sheet.SetBegin[score.sheet, score.sheet.begin]; IF score.sheet.begin # oldBegin THEN Score.Draw[score]; }; Lines: PROC[score: ScorePTR, time1, time2: Time] RETURNS[CARDINAL] = INLINE { line, topLine: INTEGER; line _ Sheet.LineNumber[score.sheet, Sheet.FindLine[score.sheet, time2]]; topLine _ Sheet.LineNumber[score.sheet, Sheet.FindLine[score.sheet, time1]]; RETURN[line-topLine]; }; END. Thumb: PROC[score: ScorePTR] = { time: Time; x, y: INTEGER; lines: INTEGER; [x, y] _ Sheet.ScreenPoint[score.sheet]; time _ Sheet.NearestTime[score.sheet, x, y].time; lines _ Lines[score, score.sheet.begin, time]; SELECT TRUE FROM lines = 0 AND x < 0 => {Sheet.SetBegin[score.sheet, 0]}; score.sheet.scale = 1 => {Sheet.Scale[4]; Sheet.SetBegin[score.sheet, 0]}; score.sheet.scale = 2 => {Sheet.Scale[4]; Sheet.SetBegin[score.sheet, 0]}; score.sheet.scale = 4 => { Sheet.Scale[IF score.sheet.hardcopy THEN 2 ELSE 1]; Sheet.SetBegin[score.sheet, time]}; ENDCASE; Score.Draw[score]; }; ¢InterfaceImplA.mesa Copyright (C) 1983, 1984 Xerox Corporation. All rights reserved. Author: John Maxwell Last Edited by: Maxwell, November 22, 1983 10:14 am Edited by Doug Wyatt, June 15, 1984 10:32:50 am PDT ****************************************************************** Initialization ****************************************************************** ****************************************************************** Command parser ****************************************************************** used to delete objects or unselect notes Only used to change the selection is the user switching between colors? if the user is switching, then which end does he want? draw the appropriate line ************************************************************************ commands from the keyboard ************************************************************************ 'f => {ReadFileName[".logical"]; Score.FileInOld[fileName]}; 'F => {ReadFileName[".logical"]; Score.FileOutOld[fileName]}; 'g => GuessNoteValues[select1, Selection.selection.select2]; values, dotted values, doubly dotted values, triply dotted values key may be expressed as [-7..7] key must have been named (Am, C # , DM, e, etc.) shifted number keys ****************************************************************** The menu: change attributes, insertion ****************************************************************** ****************************************************************** Utility procedures ****************************************************************** ELSE TURN THE PLAYER ON find the indices of the selection should we record any keystrokes? start the player ELSE TURN THE LISTENER ON ʘšœ™Jšœ@™@Jšœ™Jšœ3™3J™3J˜—šÏk ˜ J˜ Jšœ œc˜qJšœ œ4˜CJšœ œI˜XJ˜ JšœœM˜XJšœœ˜šœœ˜ J˜8J˜?J˜A—Jšœœ)˜5Jšœ Ïc˜šœœ˜ J˜(J˜'—Jšœœ#˜/Jšœœ7˜@Jšœ œ/˜AJšœ ž˜$Jšœœ˜!J˜J˜—šœœœ˜šœ˜J˜8Jšœ)œ˜J—Jšœ ˜—Jšœ˜Jšœ#˜'Jšœ œ˜J˜Jšœœ˜Jšœœœ˜J˜Jšœ œ¦˜¶J˜JšœB™BJšœ™JšœB™BJ˜šÏn œœœ˜HJšœ œœ˜Jšœœ˜Jšœ$œœ˜YJšœœœ˜'Jšœ%œœ˜\Jšœœœ˜(J˜!Jšœ˜—J˜JšœB™BJšœ™JšœB™BJ˜šŸœœ˜*Jšœœ œ ˜9J˜Jšœ œ˜!Jšœœœž+˜UJšœ˜—J˜šŸ œœœ ˜6Jšœœ œ ˜9J˜Jšœœ˜šœœ˜Jšœ$œ˜+˜ Jšœ œ6œ˜Q—Jšœ2˜9—Jšœœœž+˜UJšœœ#˜0Jšœ˜—J˜šŸ œœ˜'Jšœ(™(Jšœ˜J˜"J˜J˜Jšœœ˜šœœ˜J˜/Jšœœœ˜Jšœ œ˜Jšœ%˜,—J˜Jšœ œœœ˜#Jšœœœž+˜UJšœœ#˜0Jšœ˜—J˜šŸ œœ˜%Jšœ!™!Jšœ ˜Jšœœ˜Jšœ œ˜J˜"J˜J˜šœ ˜J˜(šœœ˜˜šœœœ˜&Jšœ œ œ˜$Jšœ˜—š œ œœœœ˜8Jšœ œ œ˜#Jšœ˜—šœ˜J˜BJšœœ˜ J˜Jšœœ˜—J˜D—šœœœ˜5J˜:——Jšœœ˜Jšœ˜—J˜Jšœœœž+˜UJšœ˜—J˜šŸ œœœ˜,J˜J˜J˜—šŸ œœ˜&J˜ J˜Jšœœœ˜Jšœœœ˜Jšœ œœ˜J˜#J˜!J˜#J˜$J˜$J˜)J˜)šœ ˜Jšœ%™%šœ œœœ˜Jšœ˜Jšœœ˜ Jšœ œ˜J˜&Jšœ˜—šœœ œœ˜Jšœ˜Jšœœ˜ Jšœ œ˜J˜-Jšœ˜—J˜(Jšœ6™6šœœœ˜Jšœ^˜bJšœW˜[—Jšœ œ˜Jšœ™šœ˜šœœ ˜JšœE˜IJšœE˜I—šœœ ˜Jšœ=˜AJšœ=˜A——Jšœ˜—Jšœ˜—J˜š Ÿ œœœœœ˜@Jšœœœœ˜#Jšœ œœœ˜"Jšœœœ ˜(Jšœ˜—J˜šŸ œœ"˜2J˜ J˜J˜#Jšœœœ˜J˜!J˜$J˜$J˜#J˜)J˜)šœ ˜šœ œœœ˜Jšœ˜Jšœœ˜ J˜&Jšœ˜—šœœ œœ˜Jšœ˜Jšœœ˜ J˜-Jšœ˜—J˜)Jšœœ+œ'˜bJšœ˜—Jšœ˜—J˜JšœH™HJšœ™JšœH™HJ˜šŸœœ œ˜,Jšœœ œ ˜9Jšœœ˜šœ˜ šœœ ˜*JšœV˜ZJšœ˜—J˜J˜$šœœ œ˜/JšœVœ˜[J˜—J˜J˜Jšœ9œ˜B—Jšœ>™>Jšœ?™?šœ>™>Jšœœ˜!Jšœœ˜"J˜cJ˜fJšœœœ˜;JšœKž˜[Jšœ\œ,˜‹Jšœ=œ ˜aJšœœ˜%šœ=œ˜DJ˜$—J˜Fšœœ ˜*JšœÎ˜ÒJšœœ˜—Jš œœ!œœœœ˜bšœœ œ˜/JšœUœ˜ZJ˜—J˜J˜J˜Jšœœ˜%J˜+Jšœœœ˜'JšœA™AJ˜+J˜SJ˜OJ˜VJ˜TJ˜ZJ˜`J˜^J˜-Jšœœ˜ Jšœœ˜!šœCœ˜JJ˜a—Jšœœ˜$Jšœœ˜—Jšœœ˜Jšœ œœ˜5J˜"šœ œ)˜NJšœO˜SJšœ=˜A—Jšœ˜—J˜šŸ œœ œ˜4Jšœœ œ ˜9Jšœœœ˜Jšœ œœ˜šœ˜ Jšœ$œ˜*Jšœ$œ˜+Jšœ!œ˜(Jšœ!œ˜'Jšœœ˜Jšœ"œ˜(Jšœ"œ˜)JšœAœ˜GJšœ+œ˜1Jšœ"œ˜(Jšœ"œ˜)Jšœ"œ˜(Jšœ"œ˜)Jšœ@œ˜FJšœœ œ˜7Jšœœ˜%Jšœœ˜7Jšœ œ œ˜9Jšœœ˜Jšœoœ˜|—Jšœœ˜Jšœ œœ˜5J˜Jšœœ#˜0Jšœ˜—J˜šŸœœœœ˜7Jšœ œ˜J˜Jšœ œ˜Jšœœœ˜Jšœ œœ˜Jšœ™J˜LJšœœ˜šœ œ˜Jšœœ˜Jšœœ˜Jšœ˜—šœœ œ˜Jšœœ˜Jšœ˜—Jšœ0™0J˜Jšœ œœ˜šœœœ˜)šœ˜ Jšœœ˜J˜J˜Jšœœ˜Jšœ˜—Jšœ˜—Jšœœ˜šœ˜J˜=J˜,Jšœœ˜2—Jšœœ ˜#Jšœœ ˜$Jšœœœ ˜Jšœ˜ Jšœ˜—J˜šŸ œœœ˜"Jšœœ œ˜4J˜!Jšœ˜Jšœ˜—J˜Jšœ œ˜J˜šŸ œœœœœœœ˜KJ˜ J˜Jšœœ˜Jšœœ˜Jšœœœœ˜J˜2Jšœœ˜Jšœœ˜Jšœ˜—J˜šŸ œœœœ˜:J˜.Jšœœ˜(Jšœœ˜Jšœ˜—J˜š Ÿœœ œœœ˜Ašœ˜ šœœ˜Jšœœ œ œ˜2Jšœœ œ œ˜3—šœœ œ œ˜2Jšœ™—šœœ˜Jšœœ œ œ˜5Jšœœ œ œ˜6—šœœ œ œ˜5Jšœœž˜AJšœœ˜——Jšœ˜ Jšœ˜—J˜JšœB™BJšœ&™&JšœB™BJ˜J˜'J˜šŸ œœ˜Jšœ˜Jšœœ˜%J˜J˜J˜J˜šœ ˜J˜$J˜&Jšœ œ œœ˜#J˜ J˜ J˜Jšœ˜—J˜šœ˜ šœœ˜J˜J˜J˜J˜J˜#J˜J˜J˜ J˜J˜J˜Jšœ˜ šœœ˜J˜ J˜J˜J˜J˜J˜!J˜J˜J˜Jšœ˜ ——Jšœ˜ —Jšœ˜—J˜šŸœœœ˜)Jšœ ˜šœ˜ šœœ˜J˜J˜J˜J˜J˜%J˜J˜J˜"J˜"J˜ J˜Jšœ!˜(—šœœ˜J˜"J˜J˜J˜J˜J˜#J˜J˜ J˜ Jšœ!˜(—Jšœ!˜(—Jšœ˜—J˜šŸ œœœ˜%Jšœ˜ Jšœ œ˜J˜8J˜#J˜+J˜#J˜'Jšœ)ž˜GJ˜"J˜J˜"J˜J˜#Jšœ)ž˜GJ˜&Jšœ˜—J˜JšœB™BJšœ™JšœB™BJ˜JšŸœœœ>œ ˜vJ˜šŸœœœ˜5šœœ œ˜,J˜@J˜—Jšœ˜—J˜šŸœœ˜Jšœœ œ ˜9Jšœœ˜Jšœ œœ˜3Jšœ™J˜Jšœœ˜Jšœ!™!šœ;˜=š œœœœ˜,Jšœœ-œœ˜QJ˜ Jšœ˜ —Jšœ ˜—Jšœ ™ šœ œ œ˜7Jšœœœ˜*J˜Jšœœ˜—Jšœ™J˜PJšœ œ˜+Jšœ˜—J˜Jšœœ˜Jšœœœ˜J˜šŸœœ˜!Jšœœ œ ˜9šœ œž˜,J˜Jš œ œœœž˜1Jšœœ7œ˜Pšœ˜Jšœ œ˜5J˜Jšœž)˜?J˜Y—Jšœœ˜ J˜Jšœœ˜ Jšœ œœœ˜ J˜(Jšœž˜'Jšœ˜—Jšœ™Jšœœœ˜*Jšœ œ!˜GJ˜Jšœ œ˜+Jšœœ˜Jšœ˜—J˜šŸ œœ!˜4Jšœœ˜ J˜Jšœœ˜Jšœ œ'˜MJšœœœ˜(J˜-J˜ J˜DJ˜Jšœ œ˜'Jšœœœœ˜!Jšœœ˜Jšœ œ˜J˜J˜$J˜$Jšœ˜—J˜Jšœœœ˜J˜šŸœœœ˜.J˜ Jšœœ˜J˜(J˜4šœ˜ Jšœœ+˜NJšœœ,˜P—J˜Jšœ˜—J˜šŸœœ˜ Jšœœ˜ J˜Jšœœ˜J˜#Jšœœ˜J˜šœ˜J˜J˜J˜Jšœœ˜—šœ œ˜J˜*Jšœ œœ˜J˜,J˜DJ˜Jšœ œ˜'Jšœ˜—J˜*J˜EJšœœ#˜:Jšœœ˜.J˜0Jšœœ˜7Jšœ˜—J˜š Ÿœœ&œœœ˜MJšœœ˜J˜IJ˜LJšœ˜Jšœ˜—J˜Jšœ˜J˜šŸœœ˜ J˜ Jšœœ˜Jšœœ˜J˜(J˜1J˜.šœœ˜Jšœ œ-˜:J˜KJ˜K˜Jšœ œœœ˜4J˜$—Jšœ˜—J˜Jšœ˜—J˜J˜—…—R:nã