public void Render(IGraphicsContext context)
        {
            lock (_locker)
            {
                if (_brushBackground == null)
                {
                    _brushBackground = new BasicBrush(_backgroundColor);
                    _penTransparent = new BasicPen();
                    _penBorder = new BasicPen(new BasicBrush(_borderColor), 1);
                    _rectText = context.MeasureText("12345:678.90", new BasicRectangle(0, 0, Frame.Width, Frame.Height), "HelveticaNeue", 10);
                }
            }

            _density = context.Density;
            Frame = new BasicRectangle(0, 0, context.BoundsWidth, context.BoundsHeight);
            context.DrawRectangle(new BasicRectangle(0, 0, context.BoundsWidth, context.BoundsHeight), _brushBackground, _penTransparent);
            if (_audioFile == null || _audioFileLength == 0)
                return;

            // Check if scale type needs to be updated
            if (_lastWidth != ContentSize.Width)
            {
                _lastWidth = ContentSize.Width;
                CalculateScale(context.Density);
            }

            // Draw scale borders
            //Console.WriteLine("WaveFormScaleView - scaleType: {0} totalMinutes: {1} totalSeconds: {2} totalMinutesScaled: {3} totalSecondsScaled: {4}", scaleType.ToString(), totalMinutes, totalSeconds, totalMinutesScaled, totalSecondsScaled);
            context.SetPen(_penBorder);
            context.StrokeLine(new BasicPoint(0, ContentSize.Height - 1), new BasicPoint(ContentSize.Width, ContentSize.Height - 1));

            int firstVisibleIndex = (int)Math.Floor(ContentOffset.X / _tickWidth);
            int lastVisibleIndex = firstVisibleIndex + (int)Math.Floor(context.BoundsWidth / _tickWidth);
            float tickX = -ContentOffset.X + (firstVisibleIndex * _tickWidth);
            int majorTickIndex = (int)Math.Ceiling(firstVisibleIndex / 10f);
            //for (int a = firstVisibleIndex; a < _tickCount; a++)
            for (int a = firstVisibleIndex; a < lastVisibleIndex; a++)
            {
                // Ignore ticks out of bounds
                bool isMajorTick = ((a % 10) == 0);
                if (tickX >= 0 && tickX <= Frame.Width)
                {
                    //Console.WriteLine("####> WaveFormView - Scale - tick {0} x: {1} isMajorTick: {2} tickCount: {3}", a, tickX, isMajorTick, tickCount);

                    if(isMajorTick)
                        //    //context.DrawLine(new BasicPoint(tickX, context.BoundsHeight - (context.BoundsHeight / 1.25f)), new BasicPoint(tickX, context.BoundsHeight), _penMajorTick);
                        context.StrokeLine(new BasicPoint(tickX, 0), new BasicPoint(tickX, ContentSize.Height - 1));
                    else
                        context.StrokeLine(new BasicPoint(tickX, ContentSize.Height - (ContentSize.Height / 6) - 1), new BasicPoint(tickX, ContentSize.Height - 1));

                    if (isMajorTick)
                    {
                        // Draw dashed traversal line for major ticks
                        context.StrokeLine(new BasicPoint(tickX, ContentSize.Height - 1), new BasicPoint(tickX, ContentSize.Height - 1));

                        // Determine major scale text
                        int minutes = 0;
                        int seconds = 0;
                        switch (_scaleType)
                        {
                            case WaveFormScaleType._10minutes:
                                minutes = majorTickIndex * 10;
                                seconds = 0;
                                break;
                            case WaveFormScaleType._5minutes:
                                minutes = majorTickIndex * 5;
                                seconds = 0;
                                break;
                            case WaveFormScaleType._2minutes:
                                minutes = majorTickIndex * 2;
                                seconds = 0;
                                break;
                            case WaveFormScaleType._1minute:
                                minutes = majorTickIndex;
                                seconds = 0;
                                break;
                            case WaveFormScaleType._30seconds:
                                minutes = (int)Math.Floor(majorTickIndex / _scaleMultiplier);
                                seconds = (majorTickIndex % _scaleMultiplier == 0) ? 0 : 30;
                                break;
                            case WaveFormScaleType._10seconds:
                                minutes = (int)Math.Floor(majorTickIndex / _scaleMultiplier);
                                seconds = ((int)Math.Floor(majorTickIndex % _scaleMultiplier)) * 10;
                                break;
                            case WaveFormScaleType._5seconds:
                                minutes = (int)Math.Floor(majorTickIndex / _scaleMultiplier);
                                seconds = ((int)Math.Floor(majorTickIndex % _scaleMultiplier)) * 5;
                                break;
                            case WaveFormScaleType._1second:
                                minutes = (int)Math.Floor(majorTickIndex / _scaleMultiplier);
                                seconds = (int)Math.Floor(majorTickIndex % _scaleMultiplier);
                                break;
                        }

                        // Draw text at every major tick (minute count)
                        string scaleMajorTitle = string.Format("{0}:{1:00}", minutes, seconds);                    
                        //float y = ContentSize.Height - (ContentSize.Height/12f) - _rectText.Height - (0.5f * context.Density);                    
                        float y = 3 * context.Density;//ContentSize.Height - _rectText.Height - (10 * context.Density); 
						context.DrawText(scaleMajorTitle, new BasicPoint(tickX + (4 * context.Density), y), _textColor, FontFace, FontSize);
                    }
                }
                
                if(isMajorTick)
                    majorTickIndex++;

                tickX += _tickWidth;
            }
        }
Exemple #2
0
        private void DrawDebugInformation(IGraphicsContext context)
        {
            // Display debug information if enabled
            if (_displayDebugInformation)
            {
                // Build debug string
                var sbDebug = new StringBuilder();
                sbDebug.AppendLine("Line Count: " + _items.Count.ToString());
                sbDebug.AppendLine("Line Height: " + _songCache.LineHeight.ToString());
                sbDebug.AppendLine("Lines Fit In Height: " + _songCache.NumberOfLinesFittingInControl.ToString());
                sbDebug.AppendLine("Total Width: " + _songCache.TotalWidth);
                sbDebug.AppendLine("Total Height: " + _songCache.TotalHeight);
                sbDebug.AppendLine("Scrollbar Offset Y: " + _songCache.ScrollBarOffsetY);
                sbDebug.AppendLine("HScrollbar Maximum: " + HorizontalScrollBar.Maximum.ToString());
                sbDebug.AppendLine("HScrollbar LargeChange: " + HorizontalScrollBar.LargeChange.ToString());
                sbDebug.AppendLine("HScrollbar Value: " + HorizontalScrollBar.Value.ToString());
                sbDebug.AppendLine("VScrollbar Maximum: " + VerticalScrollBar.Maximum.ToString());
                sbDebug.AppendLine("VScrollbar LargeChange: " + VerticalScrollBar.LargeChange.ToString());
                sbDebug.AppendLine("VScrollbar Value: " + VerticalScrollBar.Value.ToString());

                // Measure string
                //stringFormat.Trimming = StringTrimming.Word;
                //stringFormat.LineAlignment = StringAlignment.Near;
                //SizeF sizeDebugText = g.MeasureString(sbDebug.ToString(), fontDefault, _columns[0].Width - 1, stringFormat);
                var sizeDebugText = context.MeasureText(sbDebug.ToString(), new BasicRectangle(0, 0, _columns[0].Width, 40), _theme.FontName, _theme.FontSize);
                var rect = new BasicRectangle(0, 0, _columns[0].Width - 1, sizeDebugText.Height);

                // Draw background
                var brush = new BasicBrush(new BasicColor(200, 0, 0));
                var penTransparent = new BasicPen();
                context.DrawRectangle(rect, brush, penTransparent);

                // Draw string
                context.DrawText(sbDebug.ToString(), rect, new BasicColor(255, 255, 255), _theme.FontName, _theme.FontSize);
            }
        }
Exemple #3
0
        private void DrawStatus(IGraphicsContext context, string status)
        {
            //Console.WriteLine("WaveFormControl - DrawStatus - status: {0}", status);
            context.DrawRectangle(Frame, new BasicBrush(_backgroundColor), new BasicPen());            
			var rectText = context.MeasureText(status, new BasicRectangle(0, 0, Frame.Width, 30), FontFace, FontSize);                
            float x = (context.BoundsWidth - rectText.Width) / 2;
            float y = context.BoundsHeight / 2;
            context.DrawText(status, new BasicPoint(x, y), _textColor, FontFace, FontSize);
        }
Exemple #4
0
        private void DrawAlbumCoverZone(IGraphicsContext context, int row, AudioFile audioFile2, DrawCellState state)
        {
            var pen = new BasicPen();
            var penTransparent = new BasicPen();
            var brushGradient = new BasicGradientBrush();
            var item = _items[row];
            //string albumTitle = audioFile != null ? audioFile.AlbumTitle : state.CurrentAlbumTitle; // if this is an empty row, keep last album title

            // Check for an album title change (or the last item of the grid)
            if (state.CurrentAlbumArtKey == item.AlbumArtKey)
                return;

            state.CurrentAlbumArtKey = item.AlbumArtKey;

            int albumCoverStartIndex = 0;
            int albumCoverEndIndex = 0;

            // For displaying the album cover, we need to know how many songs of the same album are bundled together
            // Start by getting the start index
            for (int c = row; c > 0; c--)
            {
                var previousItem = _items[c];
                if (previousItem.AlbumArtKey != item.AlbumArtKey)
                {
                    albumCoverStartIndex = c + 1;
                    break;
                }
            }

            // Find the end index
            for (int c = row + 1; c < _items.Count; c++)
            {
                var nextItem = _items[c];

                // If the album title is different, this means we found the next album title
                if (nextItem.AlbumArtKey != item.AlbumArtKey)
                {
                    albumCoverEndIndex = c - 1;
                    break;
                }
                // If this is the last item of the grid...
                else if (c == _items.Count - 1)
                {
                    albumCoverEndIndex = c;
                    break;
                }
            }

            var audioFile = _items[albumCoverStartIndex].AudioFile;

            // Calculate y and height
            int scrollbarOffsetY = (_startLineNumber * _songCache.LineHeight) - VerticalScrollBar.Value;
            int y = ((albumCoverStartIndex - _startLineNumber) * _songCache.LineHeight) + _songCache.LineHeight + scrollbarOffsetY;

            // Calculate the height of the album cover zone (+1 on end index because the array is zero-based)
            int linesToCover = Math.Min(MinimumRowsPerAlbum, (albumCoverEndIndex + 1 - albumCoverStartIndex));
            int albumCoverZoneHeight = linesToCover * _songCache.LineHeight;
            int heightWithPadding = Math.Min(albumCoverZoneHeight - (_theme.Padding * 2), _songCache.ActiveColumns[0].Width - (_theme.Padding * 2));

            // Make sure the height is at least zero (not necessary to draw anything!)
            if (albumCoverZoneHeight > 0)
            {
                // Draw album cover background
                var rectAlbumCover = new BasicRectangle(0 - HorizontalScrollBar.Value, y, _songCache.ActiveColumns[0].Width, albumCoverZoneHeight);
                brushGradient = new BasicGradientBrush(_theme.AlbumCoverBackgroundColor, _theme.AlbumCoverBackgroundColor, 90);
                context.DrawRectangle(rectAlbumCover, brushGradient, penTransparent);

                // Measure available width for text
                int widthAvailableForText = _columns[0].Width - (_theme.Padding * 2);

                // Display titles depending on if an album art was found
                var rectAlbumCoverArt = new BasicRectangle();
                var rectAlbumTitleText = new BasicRectangle();
                var rectArtistNameText = new BasicRectangle();
                var sizeAlbumTitle = new BasicRectangle();
                var sizeArtistName = new BasicRectangle();
                bool useAlbumArtOverlay = false;
                bool displayArtistNameAndAlbumTitle = false;

                // Try to extract image from cache
                IBasicImage imageAlbumCover = null;
                SongGridViewImageCache cachedImage = null;
                try
                {
                    cachedImage = _imageCache.FirstOrDefault(x => x.Key == item.AlbumArtKey);
                }
                catch (Exception ex)
                {
                    Tracing.Log(ex);
                }

                if (cachedImage != null)
                    imageAlbumCover = cachedImage.Image;

                // Album art not found in cache; try to find an album cover in one of the file
                if (cachedImage == null)
                {
                    try
                    {
                        // Check if the album cover is already in the pile
                        bool albumCoverFound = false;
                        foreach (var arg in _workerUpdateAlbumArtPile)
                        {
                            // Match by file path
                            if (arg.AudioFile.FilePath.ToUpper() == audioFile.FilePath.ToUpper())
                            {
                                albumCoverFound = true;
                            }
                        }

                        // Add to the pile only if the album cover isn't already in it
                        if (!albumCoverFound)
                        {
                            // Add item to update album art worker pile
                            var arg = new SongGridViewBackgroundWorkerArgument();
                            arg.AudioFile = audioFile;
                            arg.LineIndex = row;
                            arg.RectAlbumArt = new BasicRectangle(0, 0, heightWithPadding, heightWithPadding);
                            _workerUpdateAlbumArtPile.Add(arg);
                        }
                    }
                    catch(Exception ex)
                    {
                        Console.WriteLine("SongGridViewControl - Failed to load cache image: {0}" , ex);
                    }
                }

                // There are at least two lines; is there an album cover to display?
                if (imageAlbumCover == null)
                {
                    // There is no album cover to display; display only text.
                    // Set string format
                    //stringFormat.Alignment = StringAlignment.Center;
                    //stringFormat.Trimming = StringTrimming.EllipsisWord;

                    sizeArtistName = context.MeasureText(audioFile.ArtistName, new BasicRectangle(0, 0, widthAvailableForText, heightWithPadding), _theme.FontNameAlbumArtTitle, _theme.FontSize + 2);
                    sizeAlbumTitle = context.MeasureText(audioFile.AlbumTitle, new BasicRectangle(0, 0, widthAvailableForText, heightWithPadding), _theme.FontNameAlbumArtSubtitle, _theme.FontSize);

                    // Display the album title at the top of the zome
                    rectArtistNameText = new BasicRectangle(_theme.Padding - HorizontalScrollBar.Value, y + _theme.Padding, widthAvailableForText, heightWithPadding);
                    rectAlbumTitleText = new BasicRectangle(_theme.Padding - HorizontalScrollBar.Value, y + _theme.Padding + sizeArtistName.Height, widthAvailableForText, heightWithPadding);
                    displayArtistNameAndAlbumTitle = true;
                    useAlbumArtOverlay = true;
                }
                else
                {
                    // There is an album cover to display with more than 2 lines.
                    // Set string format
                    //stringFormat.Alignment = StringAlignment.Near;
                    //stringFormat.Trimming = StringTrimming.EllipsisWord;

                    float widthRemainingForText = _columns[0].Width - (_theme.Padding * 3) - heightWithPadding;
                    sizeArtistName = context.MeasureText(audioFile.ArtistName, new BasicRectangle(0, 0, widthRemainingForText, heightWithPadding), _theme.FontNameAlbumArtTitle, _theme.FontSize + 2);
                    sizeAlbumTitle = context.MeasureText(audioFile.AlbumTitle, new BasicRectangle(0, 0, widthRemainingForText, heightWithPadding), _theme.FontNameAlbumArtSubtitle, _theme.FontSize);

                    // Try to center the cover art + padding + max text width
                    //float maxWidth = Math.Max(sizeArtistName.Width, sizeAlbumTitle.Width);
                    float albumCoverX = _theme.Padding - 2; // (_columns[0].Width - heightWithPadding - _theme.Padding - _theme.Padding - maxWidth) / 2;
                    float artistNameY = _theme.Padding + 1; // (albumCoverZoneHeight - sizeArtistName.Height - sizeAlbumTitle.Height) / 2;

                    // Display the album title at the top of the zome
                    rectArtistNameText = new BasicRectangle(albumCoverX + heightWithPadding + _theme.Padding - HorizontalScrollBar.Value, y + artistNameY, widthRemainingForText, heightWithPadding);
                    rectAlbumTitleText = new BasicRectangle(albumCoverX + heightWithPadding + _theme.Padding - HorizontalScrollBar.Value, y + artistNameY + sizeArtistName.Height + (_theme.Padding / 8f), widthRemainingForText, heightWithPadding);
                    rectAlbumCoverArt = new BasicRectangle(albumCoverX - HorizontalScrollBar.Value, y + _theme.Padding, heightWithPadding, heightWithPadding);
                    displayArtistNameAndAlbumTitle = widthRemainingForText > 20;
                    useAlbumArtOverlay = true;
                }

                // Display album cover
                if (imageAlbumCover != null)
                    context.DrawImage(rectAlbumCoverArt, new BasicRectangle(0, 0, imageAlbumCover.ImageSize.Width, imageAlbumCover.ImageSize.Height), imageAlbumCover.Image);
                    //context.DrawImage(rectAlbumCoverArt, new BasicRectangle(0, 0, rectAlbumCoverArt.Width, rectAlbumCoverArt.Height), imageAlbumCover.Image);

//                if (useAlbumArtOverlay)
//                {
//                    // Draw artist name and album title background
//                    var rectArtistNameBackground = new BasicRectangle(rectArtistNameText.X - (_theme.Padding / 2), rectArtistNameText.Y - (_theme.Padding / 4), sizeArtistName.Width + _theme.Padding, sizeArtistName.Height + (_theme.Padding / 2));
//                    var rectAlbumTitleBackground = new BasicRectangle(rectAlbumTitleText.X - (_theme.Padding / 2), rectAlbumTitleText.Y - (_theme.Padding / 4), sizeAlbumTitle.Width + _theme.Padding, sizeAlbumTitle.Height + (_theme.Padding / 2));
//                    var brushTextBackground = new BasicBrush(new BasicColor(0, 0, 0, 30));
//                    context.DrawRectangle(rectArtistNameBackground, brushTextBackground, penTransparent);
//                    context.DrawRectangle(rectAlbumTitleBackground, brushTextBackground, penTransparent);
//                }

                if (displayArtistNameAndAlbumTitle)
                {
                    context.DrawText(audioFile.ArtistName, rectArtistNameText, _theme.HeaderTextColor, _theme.FontNameAlbumArtTitle, _theme.FontSize + 2);
                    context.DrawText(audioFile.AlbumTitle, rectAlbumTitleText, _theme.HeaderTextColor, _theme.FontNameAlbumArtSubtitle, _theme.FontSize);
                }

                // Draw horizontal line to distinguish albums
                // Part 1: Draw line over grid
                pen = new BasicPen(new BasicBrush(new BasicColor(180, 180, 180)), 1);
                context.DrawLine(new BasicPoint(_columns[0].Width, y), new BasicPoint(Frame.Width, y), pen);

                // Part 2: Draw line over album art zone, in a lighter color
                pen = new BasicPen(new BasicBrush(new BasicColor(115, 115, 115)), 1);
                context.DrawLine(new BasicPoint(0, y), new BasicPoint(_columns[0].Width, y), pen);
            }
        }