/// <summary> /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void OnPaint(object sender, PaintEventArgs e) { e.Graphics.FillRectangle(SystemBrushes.Window, 0, 0, Size.Width - 1, Size.Height - 1); ControlPaint.DrawBorder(e.Graphics, new Rectangle(0, 0, Size.Width, Size.Height), SystemColors.ControlLight, ButtonBorderStyle.Solid); // e.Graphics.DrawRectangle(SystemPens.ControlLight, 0, 0, Size.Width - 1, Size.Height - 1); if (State == null) { return; } ManifestDownloadState Downloader = Program.ManifestDownloadManager.GetDownload(State.ActiveManifestId); if (Downloader == null) { return; } if (Downloader.Manifest == null) { return; } int OuterPadding = 5; int CellSize = 7; int CellPadding = 3; int CellOveralSize = CellSize + CellPadding; int Rows = (int)Math.Floor((Size.Height - CellPadding * 2 - OuterPadding * 2) / (float)CellOveralSize); int Columns = (int)Math.Floor((Size.Width - CellPadding * 2 - OuterPadding * 2 - LegendWidth) / (float)CellOveralSize); int MaxCells = Rows * Columns; int CellCount = (int)Downloader.Manifest.BlockCount; int CellDivision = 1; while (CellCount > MaxCells) { CellDivision++; CellCount = ((int)Downloader.Manifest.BlockCount + (CellDivision - 1)) / CellDivision; } // Calculate states. Array.Resize(ref CellStates, CellCount); for (int Cell = 0; Cell < CellCount; Cell++) { CellStates[Cell] = CellState.NotDownloaded; int StartBlock = Cell * CellDivision; int EndBlock = StartBlock + (CellDivision - 1); // Has already been downloaded? for (int Block = StartBlock; Block <= EndBlock; Block++) { if (Downloader.BlockStates.Get(Block)) { CellStates[Cell] = CellState.Downloaded; } } } // Is in download queue. for (int i = 0; i < Program.ManifestDownloadManager.DownloadQueue.Count; i++) { ManifestPendingDownloadBlock Item = Program.ManifestDownloadManager.DownloadQueue[i]; if (Item.ManifestId == State.ActiveManifestId) { int CellIndex = Item.BlockIndex / CellDivision; if (CellIndex < CellStates.Length) { CellStates[CellIndex] = CellState.Downloading; } } } // Grab most recent downloads. lock (Program.ManifestDownloadManager.RecentBlockChanges) { for (int i = 0; i < Program.ManifestDownloadManager.RecentBlockChanges.Count; i++) { ManifestRecentBlockChange Item = Program.ManifestDownloadManager.RecentBlockChanges[i]; if (Item.ManifestId == State.ActiveManifestId) { int CellIndex = Item.BlockIndex / CellDivision; if (CellIndex < CellStates.Length) { if (Item.Type == ManifestBlockChangeType.Upload) { CellStates[CellIndex] = CellState.Uploading; } else if (Item.Type == ManifestBlockChangeType.Validate) { CellStates[CellIndex] = CellState.Validating; } } } } } for (int Cell = 0; Cell < CellCount; Cell++) { int RowIndex = Cell / Columns; int ColumnIndex = Cell % Columns; int CellX = ColumnIndex * CellOveralSize + CellPadding + OuterPadding; int CellY = RowIndex * CellOveralSize + CellPadding + OuterPadding; CellState State = CellStates[Cell]; Brush FillBrush = CellStateBrushes[(int)State]; e.Graphics.FillRectangle(FillBrush, CellX, CellY, CellSize, CellSize); e.Graphics.DrawRectangle(SystemPens.ActiveBorder, CellX, CellY, CellSize, CellSize); } // Draw the legend. int LegendX = Size.Width - LegendWidth - OuterPadding; int LegendY = OuterPadding + 5; //e.Graphics.DrawString("Legend", SystemFonts.DefaultFont, Brushes.Black, LegendX, LegendY); //LegendY += 20; for (int i = 0; i < (int)CellState.Max; i++) { Brush FillBrush = CellStateBrushes[i]; e.Graphics.FillRectangle(FillBrush, LegendX, LegendY, CellSize, CellSize); e.Graphics.DrawRectangle(SystemPens.ActiveBorder, LegendX, LegendY, CellSize, CellSize); e.Graphics.DrawString(CellStateNames[i], SystemFonts.DefaultFont, Brushes.Black, LegendX + CellSize + CellPadding, LegendY - 3); LegendY += 16; } }
/// <summary> /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void OnPaint(object sender, PaintEventArgs e) { if (!Active) { return; } if (UseOuterBorder) { e.Graphics.FillRectangle(SystemBrushes.Window, 0, 0, Size.Width - 1, Size.Height - 1); ControlPaint.DrawBorder(e.Graphics, new Rectangle(0, 0, Size.Width, Size.Height), SystemColors.ControlLight, ButtonBorderStyle.Solid); } long BlockCount = 0; SparseStateArray StateArray = null; if (State != null) { ManifestDownloadState Downloader = Program.ManifestDownloadManager.GetDownload(State.ActiveManifestId); if (Downloader == null) { return; } if (Downloader.Manifest == null) { return; } BlockCount = Downloader.Manifest.BlockCount; StateArray = Downloader.BlockStates; } else if (ManifestBlockState != null) { StateArray = ManifestBlockState.BlockState; BlockCount = StateArray.Size; } if (StateArray == null) { return; } int OuterPadding = UseOuterBorder ? 8 : 0; int BarX = OuterPadding; int BarY = OuterPadding; int BarWidth = Size.Width - (OuterPadding * 2); int BarHeight = Size.Height - (OuterPadding * 2); int MaxCells = BarWidth / 4; int CellCount = (int)BlockCount; int CellDivision = 1; while (CellCount > MaxCells) { CellDivision++; CellCount = ((int)BlockCount + (CellDivision - 1)) / CellDivision; } // Calculate states. Array.Resize(ref CellStates, CellCount); for (int Cell = 0; Cell < CellCount; Cell++) { CellStates[Cell] = CellState.NotDownloaded; } if (StateArray.Ranges != null) { foreach (SparseStateArray.Range Range in StateArray.Ranges) { if (Range.State) { for (int i = Range.Start; i <= Range.End; i++) { CellStates[i / CellDivision] = CellState.Downloaded; } } } } if (ApplyLocalStates) { // Is in download queue. for (int i = 0; i < Program.ManifestDownloadManager.DownloadQueue.Count; i++) { ManifestPendingDownloadBlock Item = Program.ManifestDownloadManager.DownloadQueue[i]; if (Item.ManifestId == State.ActiveManifestId) { int CellIndex = Item.BlockIndex / CellDivision; if (CellIndex < CellStates.Length) { CellStates[CellIndex] = CellState.Downloading; } } } // Grab most recent downloads. lock (Program.ManifestDownloadManager.RecentBlockChanges) { for (int i = 0; i < Program.ManifestDownloadManager.RecentBlockChanges.Count; i++) { ManifestRecentBlockChange Item = Program.ManifestDownloadManager.RecentBlockChanges[i]; if (Item.ManifestId == State.ActiveManifestId) { int CellIndex = Item.BlockIndex / CellDivision; if (CellIndex < CellStates.Length) { if (Item.Type == ManifestBlockChangeType.Upload) { CellStates[CellIndex] = CellState.Uploading; } else if (Item.Type == ManifestBlockChangeType.Validate) { CellStates[CellIndex] = CellState.Validating; } } } } } } float Spacing = BarWidth / (float)CellCount; for (int Cell = 0; Cell < CellCount; Cell++) { float CellX = BarX + (Cell * Spacing); float CellY = BarY; CellState State = CellStates[Cell]; Brush FillBrush = CellStateBrushes[(int)State]; e.Graphics.FillRectangle(FillBrush, CellX, CellY, Spacing, BarHeight); } ControlPaint.DrawBorder(e.Graphics, new Rectangle(BarX, BarY, BarWidth, BarHeight), SystemColors.ActiveBorder, ButtonBorderStyle.Solid); }