// draw motor curve private void DrawMotorCurve(PaintEventArgs e, TrainDat.Motor Motor, string Text, PictureBox Box) { // prepare int width = Box.ClientRectangle.Width; int height = Box.ClientRectangle.Height; e.Graphics.CompositingQuality = CompositingQuality.HighQuality; e.Graphics.InterpolationMode = InterpolationMode.High; e.Graphics.SmoothingMode = SmoothingMode.AntiAlias; e.Graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit; e.Graphics.Clear(Color.Black); Font font = new Font(this.Font.FontFamily, 7.0f); Pen grayPen = new Pen(Color.FromArgb(64, 64, 64)); Brush grayBrush = Brushes.DimGray; float factorX = (float)width / (MotorMaximumX - MotorMinimumX); float factorYpitch = -(float)height / MotorMaximumYPitch; float factorYvolume = -(float)height / MotorMaximumYVolume; float offsetY = (float)height; bool selectedPitch = radiobuttonPitch.Checked; bool selectedVolume = radiobuttonVolume.Checked; const double huefactor = 0.785398163397448; CultureInfo culture = CultureInfo.InvariantCulture; // vertical grid for (float x = 0.0f; x < MotorMaximumX; x += 10.0f) { float a = (x - MotorMinimumX) * factorX; e.Graphics.DrawLine(grayPen, new PointF(a, 0.0f), new PointF(a, (float)height)); e.Graphics.DrawString(x.ToString("0", culture), font, grayBrush, new PointF(a, 1.0f)); } // horizontal base lines { float yp = offsetY + (float)100.0f * factorYpitch; float yv = offsetY + (float)128.0f * factorYvolume; e.Graphics.DrawLine(grayPen, new PointF(0.0f, yp), new PointF((float)width, yp)); e.Graphics.DrawLine(grayPen, new PointF(0.0f, yv), new PointF((float)width, yv)); e.Graphics.DrawString("p=100", font, grayBrush, new PointF(1.0f, yp)); e.Graphics.DrawString("v=128", font, grayBrush, new PointF(1.0f, yv)); } // hover { float x = (MotorHoverX - MotorMinimumX) * factorX; Pen p = new Pen(Color.DimGray); p.DashStyle = DashStyle.Dash; e.Graphics.DrawLine(p, new PointF(x, 0.0f), new PointF(x, (float)height)); p.Dispose(); } // pen if (Box == MotorSelectionBox) { if (radiobuttonSoundIndex.Checked) { float ax = (MotorSelectionStartX - MotorMinimumX) * factorX; float bx = (MotorHoverX - MotorMinimumX) * factorX; float x = Math.Min(ax, bx); float w = Math.Abs(bx - ax); if (w > 0.0f) { int s; if (!int.TryParse(comboboxSoundIndex.Text, NumberStyles.Integer, culture, out s)) { s = -1; } Color c; if (s >= 0) { double hue = huefactor * (double)s; hue -= Math.Floor(hue); c = GetColor(hue, true); } else { c = Color.DimGray; } e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(32, c)), new RectangleF(x, 0.0f, w, (float)height)); } } } // curves PointF[] pointsPitch = new PointF[Motor.Entries.Length + 1]; PointF[] pointsVolume = new PointF[Motor.Entries.Length + 1]; int length = 0; int soundIndex = -1; for (int i = 0; i < Motor.Entries.Length; i++) { float v = 0.2f * (float)i; float x = (v - MotorMinimumX) * factorX; float yPitch = offsetY + (float)Motor.Entries[i].Pitch * factorYpitch; float yVolume = offsetY + (float)Motor.Entries[i].Volume * factorYvolume; if (soundIndex != Motor.Entries[i].SoundIndex & length != 0) { pointsPitch[length] = new PointF(x, pointsPitch[length - 1].Y); pointsVolume[length] = new PointF(x, pointsVolume[length - 1].Y); length++; Array.Resize<PointF>(ref pointsPitch, length); Array.Resize<PointF>(ref pointsVolume, length); Color colorPitch, colorVolume; if (soundIndex >= 0) { double hue = huefactor * (double)soundIndex; hue -= Math.Floor(hue); colorPitch = GetColor(hue, selectedPitch); colorVolume = GetColor(hue, selectedVolume); } else { colorPitch = selectedPitch ? Color.DimGray : Color.FromArgb(64, 64, 64); colorVolume = selectedVolume ? Color.DimGray : Color.FromArgb(64, 64, 64); } e.Graphics.DrawLines(new Pen(colorPitch), pointsPitch); e.Graphics.DrawLines(new Pen(colorVolume), pointsVolume); pointsPitch = new PointF[Motor.Entries.Length + 1]; pointsVolume = new PointF[Motor.Entries.Length + 1]; soundIndex = Motor.Entries[i].SoundIndex; length = 0; } pointsPitch[length] = new PointF(x, yPitch); pointsVolume[length] = new PointF(x, yVolume); length++; } if (length != 0) { float v = 0.2f * (float)Motor.Entries.Length; float x = (v - MotorMinimumX) * factorX; pointsPitch[length] = new PointF(x, pointsPitch[length - 1].Y); pointsVolume[length] = new PointF(x, pointsVolume[length - 1].Y); length++; Array.Resize<PointF>(ref pointsPitch, length); Array.Resize<PointF>(ref pointsVolume, length); Color colorPitch, colorVolume; if (soundIndex >= 0) { double hue = huefactor * (double)soundIndex; hue -= Math.Floor(hue); colorPitch = GetColor(hue, selectedPitch); colorVolume = GetColor(hue, selectedVolume); } else { colorPitch = selectedPitch ? Color.DimGray : Color.FromArgb(64, 64, 64); colorVolume = selectedVolume ? Color.DimGray : Color.FromArgb(64, 64, 64); } e.Graphics.DrawLines(new Pen(colorPitch), pointsPitch); e.Graphics.DrawLines(new Pen(colorVolume), pointsVolume); } soundIndex = -1; for (int i = 0; i < Motor.Entries.Length; i++) { if (Motor.Entries[i].SoundIndex != soundIndex) { float v = 0.2f * (float)i; float x = (v - MotorMinimumX) * factorX; float yPitch = offsetY + (float)Motor.Entries[i].Pitch * factorYpitch; float yVolume = offsetY + (float)Motor.Entries[i].Volume * factorYvolume; Color colorPitch, colorVolume; if (Motor.Entries[i].SoundIndex >= 0) { double hue = huefactor * (double)Motor.Entries[i].SoundIndex; hue -= Math.Floor(hue); colorPitch = GetColor(hue, selectedPitch); colorVolume = GetColor(hue, selectedVolume); } else { colorPitch = selectedPitch ? Color.DimGray : Color.FromArgb(64, 64, 64); colorVolume = selectedVolume ? Color.DimGray : Color.FromArgb(64, 64, 64); } e.Graphics.FillEllipse(new SolidBrush(colorPitch), new RectangleF(x - 2.0f, yPitch - 2.0f, 5.0f, 5.0f)); e.Graphics.FillEllipse(new SolidBrush(colorVolume), new RectangleF(x - 2.0f, yVolume - 2.0f, 5.0f, 5.0f)); e.Graphics.DrawString(Motor.Entries[i].SoundIndex.ToString(CultureInfo.InvariantCulture) + "p", font, new SolidBrush(colorPitch), new PointF(x, yPitch - 16.0f)); e.Graphics.DrawString(Motor.Entries[i].SoundIndex.ToString(CultureInfo.InvariantCulture) + "v", font, new SolidBrush(colorVolume), new PointF(x, yVolume - 16.0f)); soundIndex = Motor.Entries[i].SoundIndex; } } // pen if (Box == MotorSelectionBox) { if (radiobuttonPitch.Checked) { float av = MotorSelectionStartX; float bv = MotorHoverX; float ax = (av - MotorMinimumX) * factorX; float bx = (bv - MotorMinimumX) * factorX; float ay = offsetY + MotorSelectionStartYPitch * factorYpitch; float by = offsetY + MotorHoverYPitch * factorYpitch; if (av > bv) { float t = ax; ax = bx; bx = t; t = ay; ay = by; by = t; } e.Graphics.DrawLine(Pens.White, new PointF(ax, ay), new PointF(bx, by)); } else if (radiobuttonVolume.Checked) { float av = MotorSelectionStartX; float bv = MotorHoverX; float ax = (av - MotorMinimumX) * factorX; float bx = (bv - MotorMinimumX) * factorX; float ay = offsetY + MotorSelectionStartYVolume * factorYvolume; float by = offsetY + MotorHoverYVolume * factorYvolume; if (av > bv) { float t = ax; ax = bx; bx = t; t = ay; ay = by; by = t; } e.Graphics.DrawLine(Pens.White, new PointF(ax, ay), new PointF(bx, by)); } } // text e.Graphics.DrawString(Text, this.Font, Brushes.White, new PointF(2.0f, 12.0f)); // border e.Graphics.DrawRectangle(new Pen(SystemColors.ButtonShadow), new Rectangle(0, 0, width - 1, height - 1)); // queue PictureBox b = MotorUpdateQueue.Next(); if (b != null) b.Invalidate(); }
private void MotorMouseUp(MouseEventArgs e, TrainDat.Motor Motor, PictureBox Box) { if (MotorSelectionBox != null) { float width = (float)Box.ClientRectangle.Width; float height = (float)Box.ClientRectangle.Height; float x = MotorMinimumX + (MotorMaximumX - MotorMinimumX) * (float)e.X / (float)width; x = 0.2f * (float)Math.Round(5.0 * (double)x); int ia = (int)Math.Round((double)(5.0 * MotorSelectionStartX)); int ib = (int)Math.Round((double)(5.0 * x)); bool swap; if (ia > ib) { int t = ia; ia = ib; ib = t; swap = true; } else { swap = false; } if (ia < 0) { ia = 0; } if (ib >= Motor.Entries.Length) { int n = Motor.Entries.Length; Array.Resize<TrainDat.Motor.Entry>(ref Motor.Entries, ib + 1); for (int i = n; i < Motor.Entries.Length; i++) { Motor.Entries[i].SoundIndex = -1; Motor.Entries[i].Pitch = 100.0; Motor.Entries[i].Volume = 128.0; } } if (ia <= ib) { if (radiobuttonSoundIndex.Checked) { if (ia < ib){ ib--; } int j; if (!int.TryParse(comboboxSoundIndex.Text, NumberStyles.Integer, CultureInfo.InvariantCulture, out j)) { j = -1; } else if (j < -1) { j = -1; } for (int i = ia ; i <= ib; i++) { Motor.Entries[i].SoundIndex = j; } } else if (radiobuttonPitch.Checked) { float yPitch = (1.0f - (float)e.Y / height) * MotorMaximumYPitch; float y = swap ? yPitch : MotorSelectionStartYPitch; float dy = 0.2f * (yPitch - MotorSelectionStartYPitch) / (x - MotorSelectionStartX); for (int i = ia ; i <= ib; i++) { Motor.Entries[i].Pitch = Math.Max(y, 1.0); y += dy; } } else if (radiobuttonVolume.Checked) { float yVolume = (1.0f - (float)e.Y / height) * MotorMaximumYVolume; float y = swap ? yVolume : MotorSelectionStartYVolume; float dy = 0.2f * (yVolume - MotorSelectionStartYVolume) / (x - MotorSelectionStartX); for (int i = ia ; i <= ib; i++) { Motor.Entries[i].Volume = Math.Max(y, 0.0); y += dy; } } } bool start = MotorUpdateQueue.Seek() == null; MotorUpdateQueue.Add(Box); MotorUpdateQueue.Add(pictureboxMotorP1); MotorUpdateQueue.Add(pictureboxMotorP2); MotorUpdateQueue.Add(pictureboxMotorB1); MotorUpdateQueue.Add(pictureboxMotorB2); if (start) { MotorUpdateQueue.Next().Invalidate(); } MotorSelectionBox = null; } }