예제 #1
0
        /// <summary>
        /// Returns whether the specified note has adjacent black keys next to it
        /// </summary>
        /// <param name="note">The white note</param>
        private static HasBlackKeys CheckIfWhiteNoteHasBlackKeys(NoteEnum note)
        {
            HasBlackKeys flags = HasBlackKeys.None;

            if (note == NoteEnum.None || IsSharp(note))
            {
                return(flags);
            }
            if (IsSharp(note - 1))
            {
                flags |= HasBlackKeys.Flat;
            }
            if (IsSharp(note + 1))
            {
                flags |= HasBlackKeys.Sharp;
            }
            return(flags);
        }
예제 #2
0
        /// <summary>
        /// Calculates the note at the specified position
        /// </summary>
        /// <param name="point">The point on the keyboard canvas</param>
        private NoteEnum GetNoteAtPoint(Point point)
        {
            int  whiteKeyWidth = WhiteKeyWidth;
            Size clientSize    = ClientSize;
            int  x             = (clientSize.Width - PianoWidth) / 2;

            if (point.X < x || point.X >= x + PianoWidth)
            {
                return(NoteEnum.None);
            }
            int      xLoc           = point.X - x;
            NoteEnum whiteNote      = WhiteNoteIndexToNote(xLoc / whiteKeyWidth);
            int      height         = clientSize.Height - lineThickness;
            int      blackKeyHeight = (height * 4) / 7;

            if (point.Y < blackKeyHeight)
            {
                int          blackKeyWidth     = (whiteKeyWidth * 9) / 14;
                int          halfBlackKeyWidth = blackKeyWidth / 2;
                int          blackKeyOffset    = whiteKeyWidth - halfBlackKeyWidth;
                HasBlackKeys hasBlackKeys      = CheckIfWhiteNoteHasBlackKeys(whiteNote);
                int          locInNote         = xLoc % whiteKeyWidth;
                if (locInNote <= halfBlackKeyWidth && (hasBlackKeys & HasBlackKeys.Flat) == HasBlackKeys.Flat)
                {
                    return(whiteNote - 1);
                }
                else if (locInNote >= blackKeyOffset && (hasBlackKeys & HasBlackKeys.Sharp) == HasBlackKeys.Sharp)
                {
                    return(whiteNote + 1);
                }
                else
                {
                    return(whiteNote);
                }
            }
            else
            {
                return(whiteNote);
            }
        }
예제 #3
0
        /// <summary>
        /// Draws the interactive keyboard
        /// </summary>
        protected override void OnPaint(PaintEventArgs e)
        {
            Graphics g = e.Graphics;

            g.CompositingMode    = CompositingMode.SourceCopy;
            g.CompositingQuality = CompositingQuality.HighSpeed;
            g.PixelOffsetMode    = PixelOffsetMode.HighSpeed;
            g.SmoothingMode      = SmoothingMode.HighSpeed;
            //calculate metrics
            int       whiteKeyWidth     = WhiteKeyWidth;
            int       blackKeyWidth     = (whiteKeyWidth * 9) / 14;
            int       halfBlackKeyWidth = blackKeyWidth / 2;
            int       blackKeyOffset    = whiteKeyWidth - halfBlackKeyWidth;
            int       pianoWidth        = PianoWidth;
            Size      clientSize        = ClientSize;
            int       x                 = (clientSize.Width - pianoWidth) / 2;
            int       pianoEnd          = x + pianoWidth;
            const int halfLineThickness = lineThickness / 2;
            int       height            = clientSize.Height - lineThickness;
            Rectangle clipRect          = e.ClipRectangle;

            //fill piano background
            FillRectangle(g, WhiteKeyBrush, new Rectangle(x, halfLineThickness, pianoWidth, height), clipRect);
            int i, keyStart;
            //draw white keys
            List <Rectangle> pressedWhite = new List <Rectangle>();
            Rectangle        currentRect;
            NoteEnum         currentNote;

            for (i = 0; i < WhiteKeyCount; ++i)
            {
                keyStart    = x + i * whiteKeyWidth;
                currentNote = WhiteNoteIndexToNote(i);
                currentRect = new Rectangle(keyStart, halfLineThickness, whiteKeyWidth, height);
                if ((leftMouseDown && keyStart <= lastCursorLocation.X && keyStart + whiteKeyWidth > lastCursorLocation.X && !IsSharp(GetNoteAtPoint(lastCursorLocation))) ||
                    pressedNotes.ContainsKey(currentNote))
                {
                    pressedWhite.Add(currentRect);
                }
                if (i == MiddleCPos)
                {
                    FillRectangle(g, MiddleCBrush, currentRect, clipRect);
                }
                g.DrawRectangle(KeyOutline, currentRect);
            }
            List <Rectangle> pressedBlack = new List <Rectangle>();
            int temp;
            int blackKeyHeight = (height * 4) / 7;

            //draw black keys
            for (i = 0; i < WhiteKeyCount; ++i)
            {
                temp = i % 7;
                if (!(temp == 2 || temp == 6))                   //skip every 2nd and 6th key
                {
                    keyStart    = x + i * whiteKeyWidth + blackKeyOffset;
                    currentRect = new Rectangle(keyStart, lineThickness, blackKeyWidth, blackKeyHeight);
                    if ((leftMouseDown && lastCursorLocation.Y < blackKeyHeight && keyStart <= lastCursorLocation.X && Math.Min(keyStart + blackKeyWidth, pianoEnd) > lastCursorLocation.X) ||
                        pressedNotes.ContainsKey(WhiteNoteIndexToNote(i) + 1))
                    {
                        pressedBlack.Add(currentRect);
                    }
                    else
                    {
                        FillRectangle(g, BlackKeyBrush, currentRect, clipRect);
                    }
                }
            }
            //draw pressed white keys
            Rectangle rect;

            for (i = 0; i < pressedWhite.Count; i++)
            {
                rect = pressedWhite[i];
                FillRectangle(g, PressedKeyBrush, new Rectangle(rect.X + halfLineThickness, rect.Y + halfLineThickness, rect.Width - lineThickness, rect.Height - lineThickness), clipRect);
                NoteEnum     note         = WhiteNoteIndexToNote((rect.X - x) / whiteKeyWidth);
                HasBlackKeys hasBlackKeys = CheckIfWhiteNoteHasBlackKeys(note);
                if ((hasBlackKeys & HasBlackKeys.Flat) == HasBlackKeys.Flat && !pressedNotes.ContainsKey((NoteEnum)((int)note - 1)))
                {
                    FillRectangle(g, BlackKeyBrush, new Rectangle(rect.X - halfBlackKeyWidth, lineThickness, blackKeyWidth, blackKeyHeight), clipRect);
                }
                if ((hasBlackKeys & HasBlackKeys.Sharp) == HasBlackKeys.Sharp && !pressedNotes.ContainsKey((NoteEnum)((int)note + 1)))
                {
                    FillRectangle(g, BlackKeyBrush, new Rectangle(rect.X + blackKeyOffset, lineThickness, blackKeyWidth, blackKeyHeight), clipRect);
                }
            }
            //draw pressed black keys
            for (i = 0; i < pressedBlack.Count; i++)
            {
                rect = pressedBlack[i];
                FillRectangle(g, PressedKeyBrush, rect, clipRect);
                rect.X     += halfLineThickness;
                rect.Y     -= halfLineThickness;
                rect.Width -= lineThickness;
                g.DrawRectangle(KeyOutline, rect);
            }
            if (backgroundBrush == null)
            {
                backgroundBrush = new SolidBrush(BackColor);
            }
            //draw outside piano background
            FillRectangle(g, backgroundBrush, new Rectangle(0, 0, x - 1, clientSize.Height), clipRect);
            FillRectangle(g, backgroundBrush, new Rectangle(x + pianoWidth + halfLineThickness, 0, clientSize.Width - (x + pianoWidth + halfLineThickness), clientSize.Height), clipRect);
            if (showHint)
            {
                //draw render text
                e.Graphics.TextRenderingHint  = TextRenderingHint.AntiAliasGridFit;
                e.Graphics.CompositingMode    = CompositingMode.SourceOver;
                e.Graphics.CompositingQuality = CompositingQuality.HighQuality;
                e.Graphics.PixelOffsetMode    = PixelOffsetMode.HighQuality;
                e.Graphics.SmoothingMode      = SmoothingMode.HighQuality;
                using (GraphicsPath path = new GraphicsPath()) {
                    Rectangle bounds = Bounds;
                    bounds.X      -= (Parent.Controls[0] == this ? Parent.Controls[1] : Parent.Controls[0]).Width;
                    bounds.Y       = blackKeyHeight;
                    bounds.Height -= blackKeyHeight;
                    path.AddString(Text, Font.FontFamily, (int)Font.Style, Font.Size, bounds, textFormat);
                    e.Graphics.FillPath(TextBrush, path);
                    e.Graphics.DrawPath(TextOutline, path);
                }
            }
            base.OnPaint(e);
        }