internal void Update(SortedBufferedDeletes @in) { numTerms += @in.numTerms; bytesUsed += @in.bytesUsed; terms.AddRange(@in.terms); terms.Sort(ref sorter); foreach (var term in @in.queries) { queries[term.Key] = term.Value; } docIDs.AddRange(@in.docIDs); @in.Clear(); }
//public override void UpdateResource(GameTime gameTime) //{ // //开采资源 // //if (this.nearResource.Count > 0) // //{ // // float take = nearResource[resourceIndex].Exploit(10); // // if (take < 10) // // { // // FindNewNaturalResource(); // // } // // resourceBuffer += take; // //} // harvester.Update(gameTime); //} //public override bool CanProduceRBall() //{ // return this.resourceBuffer > RulesTable.RBallProduceBall; //} ////产生小球 //public override void ProduceBall() //{ // this.battleField.CreateResourceBall(this); // resourceBuffer -= RulesTable.RBallProduceBall; //} //周围资源资源 /// <summary> /// Finds the nearby resources /// </summary> /// <param name="resList"></param> public void FindResources(NaturalResource[] resList) { nearResource.Clear(); for (int i = 0; i < resList.Length; i++) { if (Type == CityType.Green) { if (resList[i].Type == NaturalResourceType.Wood) { ForestObject forest = (ForestObject)resList[i]; float d = Vector3.Distance(forest.ForestCenter, this.Position); if (d < gatherDistance) { nearResource.Add(resList[i]); } } } else if (Type == CityType.Oil) { if (resList[i].Type == NaturalResourceType.Oil) { float d = Vector3.Distance(resList[i].Position, this.Position); if (d < gatherDistance) { nearResource.Add(resList[i]); } } } } if (Type == CityType.Green) { nearResource.Sort(CamparisionForest); } else { nearResource.Sort(Camparision); } }
public override void Update(GameTime time) { subElements.Sort(Comparision); bool canInteract = true; for (int i = 0; i < subElements.Count; i++) { subElements[i].Update(time); if (canInteract && subElements[i].HitTest(MouseInput.X, MouseInput.Y)) { subElements[i].UpdateInteract(time); canInteract = false; } } }
/// <inheritdoc/> public bool UpdateChanges() { if (!HasChanged()) { return(false); } sortedKeys.Clear(); sortedKeys.AddRange(KeyFrames.ToArray()); sortedKeys.Sort(this); framesCount = KeyFrames.Count; for (var i = 0; i < framesCount; i++) { KeyFrames[i].HasChanged = false; } return(true); }
public override void DoLayout() { var sr = (ScoreBarRenderer)Renderer; _infos.Sort((a, b) => a.Line.CompareTo(b.Line)); GhostParenthesisGlyph previousGlyph = null; var sizePerLine = sr.GetScoreY(1); for (int i = 0, j = _infos.Count; i < j; i++) { GhostParenthesisGlyph g; if (!_infos[i].IsGhost) { previousGlyph = null; } else if (previousGlyph == null) { g = new GhostParenthesisGlyph(_isOpen); g.Renderer = Renderer; g.Y = sr.GetScoreY(_infos[i].Line) - sizePerLine; g.Height = sizePerLine * 2; g.DoLayout(); _glyphs.Add(g); previousGlyph = g; } else { var y = sr.GetScoreY(_infos[i].Line) + sizePerLine; previousGlyph.Height = y - previousGlyph.Y; } } Width = _glyphs.Count > 0 ? _glyphs[0].Width : 0; }
public override void DoLayout() { _infos.Sort((a, b) => a.Line.CompareTo(b.Line)); const int padding = 0; // Std.int(4 * getScale()); var displacedX = 0f; var lastDisplaced = false; var lastLine = 0; var anyDisplaced = false; var direction = Direction; var w = 0f; for (int i = 0, j = _infos.Count; i < j; i++) { var g = _infos[i].Glyph; g.Renderer = Renderer; g.DoLayout(); var displace = false; if (i == 0) { displacedX = g.Width + padding; } else { // check if note needs to be repositioned if (Math.Abs(lastLine - _infos[i].Line) <= 1) { // reposition if needed if (!lastDisplaced) { displace = true; g.X = displacedX - (Scale); anyDisplaced = true; lastDisplaced = true; // let next iteration know we are displace now } else { lastDisplaced = false; // let next iteration know that we weren't displaced now } } else // offset is big enough? no displacing needed { lastDisplaced = false; } } // for beat direction down we invert the displacement. // this means: displaced is on the left side of the stem and not displaced is right if (direction == BeamDirection.Down) { g.X = displace ? padding : displacedX; } else { g.X = displace ? displacedX : padding; } lastLine = _infos[i].Line; w = Math.Max(w, g.X + g.Width); } if (anyDisplaced) { _noteHeadPadding = 0; UpLineX = displacedX; DownLineX = displacedX; } else { _noteHeadPadding = direction == BeamDirection.Down ? -displacedX : 0; w += _noteHeadPadding; UpLineX = w; DownLineX = padding; } foreach (var effectKey in BeatEffects) { var effect = BeatEffects[effectKey]; effect.Renderer = Renderer; effect.DoLayout(); } if (Beat.IsTremolo) { int offset; var baseNote = direction == BeamDirection.Up ? MinNote : MaxNote; var tremoloX = direction == BeamDirection.Up ? displacedX : 0; var speed = Beat.TremoloSpeed.Value; switch (speed) { case Duration.ThirtySecond: offset = direction == BeamDirection.Up ? -15 : 15; break; case Duration.Sixteenth: offset = direction == BeamDirection.Up ? -12 : 15; break; case Duration.Eighth: offset = direction == BeamDirection.Up ? -10 : 10; break; default: offset = direction == BeamDirection.Up ? -10 : 15; break; } _tremoloPicking = new TremoloPickingGlyph(tremoloX, baseNote.Glyph.Y + offset * Scale, Beat.TremoloSpeed.Value); _tremoloPicking.Renderer = Renderer; _tremoloPicking.DoLayout(); } Width = w + padding; }
public void LoadMidi(MidiFile midiFile) { _tempoChanges = new FastList <MidiFileSequencerTempoChange>(); // Combine all tracks into 1 track that is organized from lowest to highest absolute time if (midiFile.Tracks.Length > 1 || midiFile.Tracks[0].EndTime == 0) { midiFile.CombineTracks(); } _division = midiFile.Division; _eventIndex = 0; _currentTime = 0; // build synth events. _synthData = new FastList <SynthEvent>(); // Converts midi to milliseconds for easy sequencing double bpm = 120; var absTick = 0; var absTime = 0.0; var metronomeLength = 0; var metronomeTick = 0; var metronomeTime = 0.0; for (int x = 0; x < midiFile.Tracks[0].MidiEvents.Length; x++) { var mEvent = midiFile.Tracks[0].MidiEvents[x]; var synthData = new SynthEvent(mEvent); _synthData.Add(synthData); absTick += mEvent.DeltaTime; absTime += mEvent.DeltaTime * (60000.0 / (bpm * midiFile.Division)); synthData.Delta = absTime; if (mEvent.Command == MidiEventTypeEnum.Meta && mEvent.Data1 == (int)MetaEventTypeEnum.Tempo) { var meta = (MetaNumberEvent)mEvent; bpm = MidiHelper.MicroSecondsPerMinute / (double)meta.Value; _tempoChanges.Add(new MidiFileSequencerTempoChange(bpm, absTick, (int)(absTime))); } else if (mEvent.Command == MidiEventTypeEnum.Meta && mEvent.Data1 == (int)MetaEventTypeEnum.TimeSignature) { var meta = (MetaDataEvent)mEvent; var timeSignatureDenominator = (int)Math.Pow(2, meta.Data[1]); metronomeLength = (int)(_division * (4.0 / timeSignatureDenominator)); } else if (mEvent.Command == MidiEventTypeEnum.ProgramChange) { var channel = mEvent.Channel; if (!_firstProgramEventPerChannel.ContainsKey(channel)) { _firstProgramEventPerChannel[channel] = synthData; } } if (metronomeLength > 0) { while (metronomeTick < absTick) { var metronome = SynthEvent.NewMetronomeEvent(metronomeLength); _synthData.Add(metronome); metronome.Delta = metronomeTime; metronomeTick += metronomeLength; metronomeTime += metronomeLength * (60000.0 / (bpm * midiFile.Division)); } } } _synthData.Sort((a, b) => (int)(a.Delta - b.Delta)); _endTime = absTime; EndTick = absTick; }
private void DefaultSort(RenderContext context, FastList <RenderMesh> meshes) { // Sort based on ModelComponent.DrawOrder meshes.Sort(ModelComponentSorter.Default); }
private void UnlikelySortProperties(FastList <BlittableJsonDocumentBuilder.PropertyTag> properties) { _hasDuplicates = false; var index = GetPropertiesHashedIndex(properties); if (_cachedSorts[index] == null) { _cachedSorts[index] = new CachedSort(); } _cachedSorts[index].Sorting.Clear(); for (int i = 0; i < properties.Count; i++) { _cachedSorts[index].Sorting.Add(new PropertyPosition { Property = properties[i].Property, SortedPosition = -1 }); } _cachedSorts[index].FinalCount = properties.Count; properties.Sort(ref _sorter); // The item comparison method has a side effect, which can modify the _hasDuplicates field. // This can either be true or false at any given time. if (_hasDuplicates) { // leave just the latest for (int i = 0; i < properties.Count - 1; i++) { if (properties[i].Property.Equals(properties[i + 1].Property)) { _cachedSorts[index].FinalCount--; _cachedSorts[index].Sorting[i + 1] = new PropertyPosition { Property = properties[i + 1].Property, // set it to the previous value, so it'll just overwrite // this saves us a check and more complex code SortedPosition = i }; properties.RemoveAt(i + 1); i--; } } } for (int i = 0; i < _cachedSorts[index].Sorting.Count; i++) { var propPos = _cachedSorts[index].Sorting[i]; propPos.SortedPosition = -1; for (int j = 0; j < properties.Count; j++) { if (properties[j].Property == propPos.Property) { propPos.SortedPosition = j; break; } } } }
/* * ----------------------- * DrawCategories() * ----------------------- */ void DrawCategories(Event e) { // do any housework before we start drawing if (moveQueued) { // make a temp copy List <SoundFX> origSoundList = new List <SoundFX>(audioManager.soundGroupings[origGroup].soundList); SoundFX temp = origSoundList[origIndex]; List <SoundFX> moveToSoundList = new List <SoundFX>(audioManager.soundGroupings[moveToGroup].soundList); // add it to the move to group moveToSoundList.Add(temp); audioManager.soundGroupings[moveToGroup].soundList = moveToSoundList.ToArray(); // and finally, remove it from the original group origSoundList.RemoveAt(origIndex); audioManager.soundGroupings[origGroup].soundList = origSoundList.ToArray(); Debug.Log("> Moved '" + temp.name + "' from " + "'" + audioManager.soundGroupings[origGroup].name + "' to '" + audioManager.soundGroupings[moveToGroup].name); MarkDirty(); moveQueued = false; } // switch to the next group if (nextGroup > -1) { selectedGroup = nextGroup; nextGroup = -1; } // add a sound if (addSound) { List <SoundFX> soundList = new List <SoundFX>(audioManager.soundGroupings[selectedGroup].soundList); SoundFX soundFX = new SoundFX(); soundFX.name = audioManager.soundGroupings[selectedGroup].name.ToLower() + "_new_unnamed_sound_fx"; soundList.Add(soundFX); audioManager.soundGroupings[selectedGroup].soundList = soundList.ToArray(); MarkDirty(); addSound = false; } // sort the sounds if (sortSounds) { List <SoundFX> soundList = new List <SoundFX>(audioManager.soundGroupings[selectedGroup].soundList); soundList.Sort(delegate(SoundFX sfx1, SoundFX sfx2) { return(string.Compare(sfx1.name, sfx2.name)); }); audioManager.soundGroupings[selectedGroup].soundList = soundList.ToArray(); MarkDirty(); sortSounds = false; } // delete a sound if (deleteSoundIdx > -1) { List <SoundFX> soundList = new List <SoundFX>(audioManager.soundGroupings[selectedGroup].soundList); soundList.RemoveAt(deleteSoundIdx); audioManager.soundGroupings[selectedGroup].soundList = soundList.ToArray(); MarkDirty(); deleteSoundIdx = -1; } // duplicate a sound if (dupeSoundIdx > -1) { List <SoundFX> soundList = new List <SoundFX>(audioManager.soundGroupings[selectedGroup].soundList); SoundFX origSoundFX = soundList[dupeSoundIdx]; // clone this soundFX string json = JsonUtility.ToJson(origSoundFX); SoundFX soundFX = JsonUtility.FromJson <SoundFX>(json); soundFX.name += "_duplicated"; soundList.Insert(dupeSoundIdx + 1, soundFX); audioManager.soundGroupings[selectedGroup].soundList = soundList.ToArray(); MarkDirty(); dupeSoundIdx = -1; } if (e.type == EventType.Repaint) { groups.Clear(); } GUILayout.Space(6f); Color defaultColor = GUI.contentColor; BeginContents(); if (DrawHeader("Sound FX Groups", true)) { EditorGUILayout.BeginVertical(GUI.skin.box); soundGroups.Clear(); for (int i = 0; i < audioManager.soundGroupings.Length; i++) { soundGroups.Add(audioManager.soundGroupings[i]); } for (int i = 0; i < soundGroups.size; i++) { EditorGUILayout.BeginHorizontal(); { if (i == selectedGroup) { GUI.contentColor = (i == editGroup) ? Color.white : Color.yellow; } else { GUI.contentColor = defaultColor; } if ((e.type == EventType.KeyDown) && ((e.keyCode == KeyCode.Return) || (e.keyCode == KeyCode.KeypadEnter))) { // toggle editing if (editGroup >= 0) { editGroup = -1; } Event.current.Use(); } if (i == editGroup) { soundGroups[i].name = GUILayout.TextField(soundGroups[i].name, GUILayout.MinWidth(Screen.width - 80f)); } else { GUILayout.Label(soundGroups[i].name, (i == selectedGroup) ? EditorStyles.whiteLabel : EditorStyles.label, GUILayout.ExpandWidth(true)); } GUILayout.FlexibleSpace(); if (GUILayout.Button(GUIContent.none, "OL Minus", GUILayout.Width(17f))) // minus button { if (EditorUtility.DisplayDialog("Delete '" + soundGroups[i].name + "'", "Are you sure you want to delete the selected sound group?", "Continue", "Cancel")) { soundGroups.RemoveAt(i); MarkDirty(); } } } EditorGUILayout.EndHorizontal(); // build a list of items Rect lastRect = GUILayoutUtility.GetLastRect(); if (e.type == EventType.Repaint) { groups.Add(new ItemRect(i, lastRect, null)); } if ((e.type == EventType.MouseDown) && lastRect.Contains(e.mousePosition)) { if ((i != selectedGroup) || (e.clickCount == 2)) { nextGroup = i; if (e.clickCount == 2) { editGroup = i; } else if (editGroup != nextGroup) { editGroup = -1; } Repaint(); } } } // add the final plus button EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); if (GUILayout.Button(GUIContent.none, "OL Plus", GUILayout.Width(17f))) // plus button { soundGroups.Add(new SoundGroup("unnamed sound group")); selectedGroup = editGroup = soundGroups.size - 1; MarkDirty(); } EditorGUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); // reset the color GUI.contentColor = defaultColor; // the sort and import buttons EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); if (GUILayout.Button("Sort", GUILayout.Width(70f))) { soundGroups.Sort(delegate(SoundGroup sg1, SoundGroup sg2) { return(string.Compare(sg1.name, sg2.name)); }); MarkDirty(); } EditorGUILayout.EndHorizontal(); // draw a rect around the selected item if ((selectedGroup >= 0) && (selectedGroup < groups.size)) { EditorGUI.DrawRect(groups[selectedGroup].rect, new Color(1f, 1f, 1f, 0.06f)); } // finally move the sound groups back into the audio manager if (soundGroups.size > 0) { audioManager.soundGroupings = soundGroups.ToArray(); } // calculate the drop area rect if ((e.type == EventType.Repaint) && (groups.size > 0)) { dropArea.x = groups[0].rect.x; dropArea.y = groups[0].rect.y; dropArea.width = groups[0].rect.width; dropArea.height = (groups[groups.size - 1].rect.y - groups[0].rect.y) + groups[groups.size - 1].rect.height; } } // draw the sound group properties now DrawSoundGroupProperties(); EndContents(); EditorGUILayout.HelpBox("Create and delete sound groups by clicking + and - respectively. Double click to rename sound groups. Drag and drop sounds from below to the groups above to move them.", MessageType.Info); }
public void LoadMidi(MidiFile midiFile) { _tempoChanges = new FastList <MidiFileSequencerTempoChange>(); _division = midiFile.Division; _eventIndex = 0; _currentTime = 0; // build synth events. _synthData = new FastList <SynthEvent>(); // Converts midi to milliseconds for easy sequencing double bpm = 120; var absTick = 0; var absTime = 0.0; var metronomeLength = 0; var metronomeTick = 0; var metronomeTime = 0.0; var previousTick = 0; foreach (var mEvent in midiFile.Events) { var synthData = new SynthEvent(_synthData.Count, mEvent); _synthData.Add(synthData); var deltaTick = mEvent.Tick - previousTick; absTick += deltaTick; absTime += deltaTick * (60000.0 / (bpm * midiFile.Division)); synthData.Time = absTime; previousTick = mEvent.Tick; if (mEvent.Command == MidiEventType.Meta && mEvent.Data1 == (int)MetaEventTypeEnum.Tempo) { var meta = (MetaNumberEvent)mEvent; bpm = MidiHelper.MicroSecondsPerMinute / (double)meta.Value; _tempoChanges.Add(new MidiFileSequencerTempoChange(bpm, absTick, (int)(absTime))); } else if (mEvent.Command == MidiEventType.Meta && mEvent.Data1 == (int)MetaEventTypeEnum.TimeSignature) { var meta = (MetaDataEvent)mEvent; var timeSignatureDenominator = (int)Math.Pow(2, meta.Data[1]); metronomeLength = (int)(_division * (4.0 / timeSignatureDenominator)); } else if (mEvent.Command == MidiEventType.ProgramChange) { var channel = mEvent.Channel; if (!_firstProgramEventPerChannel.ContainsKey(channel)) { _firstProgramEventPerChannel[channel] = synthData; } } if (metronomeLength > 0) { while (metronomeTick < absTick) { var metronome = SynthEvent.NewMetronomeEvent(_synthData.Count, metronomeLength); _synthData.Add(metronome); metronome.Time = metronomeTime; metronomeTick += metronomeLength; metronomeTime += metronomeLength * (60000.0 / (bpm * midiFile.Division)); } } } _synthData.Sort((a, b) => { if (a.Time > b.Time) { return(1); } else if (a.Time < b.Time) { return(-1); } return(a.EventIndex - b.EventIndex); }); _endTime = absTime; EndTick = absTick; }
public override void DoLayout() { _infos.Sort((a, b) => a.Line.CompareTo(b.Line)); const int padding = 0; // Std.int(4 * getScale()); var displacedX = 0f; var lastDisplaced = false; var lastLine = 0; var anyDisplaced = false; var w = 0f; for (int i = 0, j = _infos.Count; i < j; i++) { var g = _infos[i].Glyph; g.Renderer = Renderer; g.DoLayout(); g.X = padding; if (i == 0) { displacedX = g.Width + padding; } else { // check if note needs to be repositioned if (Math.Abs(lastLine - _infos[i].Line) <= 1) { // reposition if needed if (!lastDisplaced) { g.X = displacedX - (Scale); anyDisplaced = true; lastDisplaced = true; // let next iteration know we are displace now } else { lastDisplaced = false; // let next iteration know that we weren't displaced now } } else // offset is big enough? no displacing needed { lastDisplaced = false; } } lastLine = _infos[i].Line; w = Math.Max(w, g.X + g.Width); } if (anyDisplaced) { UpLineX = displacedX; DownLineX = displacedX; } else { UpLineX = w; DownLineX = padding; } Std.Foreach(BeatEffects.Values, e => { e.Renderer = Renderer; e.DoLayout(); }); if (Beat.IsTremolo) { var direction = BeamingHelper.Direction; int offset; var baseNote = direction == BeamDirection.Up ? MinNote : MaxNote; var tremoloX = direction == BeamDirection.Up ? displacedX : 0; if (Beat.TremoloSpeed != null) { var speed = Beat.TremoloSpeed.Value; switch (speed) { case Duration.ThirtySecond: offset = direction == BeamDirection.Up ? -15 : 10; break; case Duration.Sixteenth: offset = direction == BeamDirection.Up ? -12 : 10; break; case Duration.Eighth: offset = direction == BeamDirection.Up ? -10 : 10; break; default: offset = direction == BeamDirection.Up ? -15 : 15; break; } } else { offset = direction == BeamDirection.Up ? -15 : 15; } _tremoloPicking = new TremoloPickingGlyph(tremoloX, baseNote.Glyph.Y + offset * Scale, Beat.TremoloSpeed.Value); _tremoloPicking.Renderer = Renderer; _tremoloPicking.DoLayout(); } Width = w + padding; }
public override void DoLayout() { _infos.Sort((a, b) => b.Line.CompareTo(a.Line)); var displacedX = 0f; var lastDisplaced = false; var lastLine = 0; var anyDisplaced = false; var direction = Direction; var w = 0f; for (int i = 0, j = _infos.Count; i < j; i++) { var g = _infos[i].Glyph; g.Renderer = Renderer; g.DoLayout(); var displace = false; if (i == 0) { displacedX = g.Width; } else { // check if note needs to be repositioned if (Math.Abs(lastLine - _infos[i].Line) <= 1) { // reposition if needed if (!lastDisplaced) { displace = true; g.X = displacedX - (Scale); anyDisplaced = true; lastDisplaced = true; // let next iteration know we are displace now } else { lastDisplaced = false; // let next iteration know that we weren't displaced now } } else // offset is big enough? no displacing needed { lastDisplaced = false; } } // for beat direction down we invert the displacement. // this means: displaced is on the left side of the stem and not displaced is right if (direction == BeamDirection.Down) { g.X = displace ? 0 : displacedX; } else { g.X = displace ? displacedX : 0; } g.X += NoteStartX; lastLine = _infos[i].Line; w = Math.Max(w, g.X + g.Width); } if (anyDisplaced) { _noteHeadPadding = 0; UpLineX = displacedX; DownLineX = displacedX; } else { _noteHeadPadding = direction == BeamDirection.Down ? -displacedX : 0; w += _noteHeadPadding; UpLineX = w; DownLineX = 0; } DisplacedX = displacedX; Width = w; }
public override void Paint(float cx, float cy, ICanvas canvas) { // Draw note heads var startNoteRenderer = Renderer.ScoreRenderer.Layout.GetRendererForBar <ScoreBarRenderer>(Renderer.Staff.StaveId, _beat.Voice.Bar); var startX = cx + startNoteRenderer.X + startNoteRenderer.GetBeatX(_beat, BeatXPosition.MiddleNotes); var endBeatX = cx + startNoteRenderer.X; if (_beat.IsLastOfVoice) { endBeatX += startNoteRenderer.PostBeatGlyphsStart; } else { endBeatX += startNoteRenderer.GetBeatX(_beat.NextBeat, BeatXPosition.PreNotes); } endBeatX -= EndPadding * Scale; var middleX = (startX + endBeatX) / 2; if (_middleNoteGlyph != null) { _middleNoteGlyph.X = middleX - _middleNoteGlyph.NoteHeadOffset; _middleNoteGlyph.Y = cy + startNoteRenderer.Y; _middleNoteGlyph.Paint(0, 0, canvas); } if (_endNoteGlyph != null) { _endNoteGlyph.X = endBeatX - _endNoteGlyph.NoteHeadOffset; _endNoteGlyph.Y = cy + startNoteRenderer.Y; _endNoteGlyph.Paint(0, 0, canvas); } _notes.Sort((a, b) => b.DisplayValue - a.DisplayValue); var directionBeat = _beat.GraceType == GraceType.BendGrace ? _beat.NextBeat : _beat; var direction = _notes.Count == 1 ? GetBeamDirection(directionBeat, startNoteRenderer) : BeamDirection.Up; // draw slurs for (var i = 0; i < _notes.Count; i++) { var note = _notes[i]; if (i > 0 && i >= _notes.Count / 2) { direction = BeamDirection.Down; } var startY = cy + startNoteRenderer.Y + startNoteRenderer.GetNoteY(note, true); var heightOffset = (NoteHeadGlyph.NoteHeadHeight * Scale * NoteHeadGlyph.GraceScale) * 0.5f; if (direction == BeamDirection.Down) { startY += NoteHeadGlyph.NoteHeadHeight * Scale; } var slurText = note.BendStyle == BendStyle.Gradual ? "grad." : ""; if (note.IsTieOrigin) { var endNote = note.TieDestination; var endNoteRenderer = endNote == null ? null : Renderer.ScoreRenderer.Layout.GetRendererForBar <ScoreBarRenderer>(Renderer.Staff.StaveId, endNote.Beat.Voice.Bar); // if we have a line break we draw only a line until the end if (endNoteRenderer == null || endNoteRenderer.Staff != startNoteRenderer.Staff) { var endX = cx + startNoteRenderer.X + startNoteRenderer.Width; var noteValueToDraw = note.TieDestination.RealValue; var accidental = startNoteRenderer.AccidentalHelper.ApplyAccidentalForValue(note.Beat, noteValueToDraw, false); var endY = cy + startNoteRenderer.Y + startNoteRenderer.GetScoreY( startNoteRenderer.AccidentalHelper.GetNoteLineForValue(noteValueToDraw)); if (note.BendType == BendType.Hold || note.BendType == BendType.Prebend) { TieGlyph.PaintTie(canvas, Scale, startX, startY, endX, endY, direction == BeamDirection.Down); canvas.Fill(); } else { DrawBendSlur(canvas, startX, startY, endX, endY, direction == BeamDirection.Down, Scale, slurText); } } // otherwise we draw a line to the target note else { var endX = cx + endNoteRenderer.X + endNoteRenderer.GetBeatX(endNote.Beat, BeatXPosition.MiddleNotes); var endY = cy + endNoteRenderer.Y + endNoteRenderer.GetNoteY(endNote, true); if (direction == BeamDirection.Down) { endY += NoteHeadGlyph.NoteHeadHeight * Scale; } if (note.BendType == BendType.Hold || note.BendType == BendType.Prebend) { TieGlyph.PaintTie(canvas, Scale, startX, startY, endX, endY, direction == BeamDirection.Down); canvas.Fill(); } else { DrawBendSlur(canvas, startX, startY, endX, endY, direction == BeamDirection.Down, Scale, slurText); } } switch (note.BendType) { case BendType.Prebend: case BendType.PrebendBend: case BendType.PrebendRelease: var preX = cx + startNoteRenderer.X + startNoteRenderer.GetBeatX(note.Beat, BeatXPosition.PreNotes); preX += ((ScoreBeatPreNotesGlyph)startNoteRenderer.GetBeatContainer(note.Beat).PreNotes) .PrebendNoteHeadOffset; var preY = cy + startNoteRenderer.Y + startNoteRenderer.GetScoreY( startNoteRenderer.AccidentalHelper.GetNoteLineForValue(note.DisplayValue - note.BendPoints[0].Value / 2)) + heightOffset; DrawBendSlur(canvas, preX, preY, startX, startY, direction == BeamDirection.Down, Scale); break; } } else { if (direction == BeamDirection.Up) { heightOffset = -heightOffset; } int endValue; float endY; switch (note.BendType) { case BendType.Bend: endValue = GetBendNoteValue(note, note.BendPoints[note.BendPoints.Count - 1]); endY = _endNoteGlyph.GetNoteValueY(endValue) + heightOffset; DrawBendSlur(canvas, startX, startY, endBeatX, endY, direction == BeamDirection.Down, Scale, slurText); break; case BendType.BendRelease: var middleValue = GetBendNoteValue(note, note.BendPoints[1]); var middleY = _middleNoteGlyph.GetNoteValueY(middleValue) + heightOffset; DrawBendSlur(canvas, startX, startY, middleX, middleY, direction == BeamDirection.Down, Scale, slurText); endValue = GetBendNoteValue(note, note.BendPoints[note.BendPoints.Count - 1]); endY = _endNoteGlyph.GetNoteValueY(endValue) + heightOffset; DrawBendSlur(canvas, middleX, middleY, endBeatX, endY, direction == BeamDirection.Down, Scale, slurText); break; case BendType.Release: if (_bendNoteHeads.Count > 0) { endValue = GetBendNoteValue(note, note.BendPoints[note.BendPoints.Count - 1]); endY = _bendNoteHeads[0].GetNoteValueY(endValue) + heightOffset; DrawBendSlur(canvas, startX, startY, endBeatX, endY, direction == BeamDirection.Down, Scale, slurText); } break; case BendType.Prebend: case BendType.PrebendBend: case BendType.PrebendRelease: var preX = cx + startNoteRenderer.X + startNoteRenderer.GetBeatX(note.Beat, BeatXPosition.PreNotes); preX += ((ScoreBeatPreNotesGlyph)startNoteRenderer.GetBeatContainer(note.Beat).PreNotes) .PrebendNoteHeadOffset; var preY = cy + startNoteRenderer.Y + startNoteRenderer.GetScoreY( startNoteRenderer.AccidentalHelper.GetNoteLineForValue(note.DisplayValue - note.BendPoints[0].Value / 2)) + heightOffset; DrawBendSlur(canvas, preX, preY, startX, startY, direction == BeamDirection.Down, Scale); if (_bendNoteHeads.Count > 0) { endValue = GetBendNoteValue(note, note.BendPoints[note.BendPoints.Count - 1]); endY = _bendNoteHeads[0].GetNoteValueY(endValue) + heightOffset; DrawBendSlur(canvas, startX, startY, endBeatX, endY, direction == BeamDirection.Down, Scale, slurText); } break; } } } }
public override void DoLayout() { base.DoLayout(); var bendHeight = _maxBendValue * BendValueHeight * Scale; Renderer.RegisterOverflowTop(bendHeight); int value; foreach (var note in _notes) { var renderPoints = _renderPoints[note.Id]; switch (note.BendType) { case BendType.Bend: renderPoints[1].LineValue = note.IsTieOrigin ? _bendEndContinuedMinValue : _bendEndMinValue; break; case BendType.Release: value = note.IsTieOrigin ? _releaseContinuedMinValue : _releaseMinValue; if (value >= 0) { renderPoints[1].LineValue = value; } break; case BendType.BendRelease: renderPoints[1].LineValue = _bendMiddleMinValue; value = note.IsTieOrigin ? _releaseContinuedMinValue : _releaseMinValue; if (value >= 0) { renderPoints[2].LineValue = value; } break; case BendType.Prebend: renderPoints[0].LineValue = _preBendMinValue; break; case BendType.PrebendBend: renderPoints[0].LineValue = _preBendMinValue; renderPoints[1].LineValue = note.IsTieOrigin ? _bendEndContinuedMinValue : _bendEndMinValue; break; case BendType.PrebendRelease: renderPoints[0].LineValue = _preBendMinValue; value = note.IsTieOrigin ? _releaseContinuedMinValue : _releaseMinValue; if (value >= 0) { renderPoints[1].LineValue = value; } break; } } Width = 0; _notes.Sort((a, b) => { if (a.IsStringed) { return(a.String - b.String); } return(a.RealValue - b.RealValue); }); }