private void RevisionsCellPainting(object sender, DataGridViewCellPaintingEventArgs e) { // If our loading state has changed since the last paint, update it. if (Loading != null) { if (Loading.Visible != _isLoading) { Loading.Visible = _isLoading; } } var columnIndex = e.ColumnIndex; int graphColIndex = GraphDataGridViewColumn.Index; int messageColIndex = MessageDataGridViewColumn.Index; int authorColIndex = AuthorDataGridViewColumn.Index; int dateColIndex = DateDataGridViewColumn.Index; int isMsgMultilineColIndex = IsMessageMultilineDataGridViewColumn.Index; // The graph column is handled by the DvcsGraph if (e.ColumnIndex == graphColIndex) { return; } if (e.RowIndex < 0 || (e.State & DataGridViewElementStates.Visible) == 0) return; if (Revisions.RowCount <= e.RowIndex) return; var revision = GetRevision(e.RowIndex); if (revision == null) return; var spi = SuperprojectCurrentCheckout.IsCompleted ? SuperprojectCurrentCheckout.Result : null; var superprojectRefs = new List<GitRef>(); if (spi != null && spi.Refs != null && spi.Refs.ContainsKey(revision.Guid)) { superprojectRefs.AddRange(spi.Refs[revision.Guid].Where(ShowRemoteRef)); } e.Handled = true; var drawRefArgs = new DrawRefArgs(); drawRefArgs.Graphics = e.Graphics; drawRefArgs.CellBounds = e.CellBounds; drawRefArgs.IsRowSelected = ((e.State & DataGridViewElementStates.Selected) == DataGridViewElementStates.Selected); if (drawRefArgs.IsRowSelected /*&& !showRevisionCards*/) { e.Graphics.FillRectangle(_selectedItemBrush, e.CellBounds); } else if (ShouldHighlightRevisionByAuthor(revision)) { e.Graphics.FillRectangle(_authoredRevisionsBrush, e.CellBounds); } else { e.Graphics.FillRectangle(Brushes.White, e.CellBounds); } Color foreColor; if (!AppSettings.RevisionGraphDrawNonRelativesTextGray || Revisions.RowIsRelative(e.RowIndex)) { foreColor = drawRefArgs.IsRowSelected && IsFilledBranchesLayout() ? SystemColors.HighlightText : e.CellStyle.ForeColor; } else { foreColor = drawRefArgs.IsRowSelected ? SystemColors.HighlightText : Color.Gray; } using (Brush foreBrush = new SolidBrush(foreColor)) { var rowFont = NormalFont; if (revision.Guid == CurrentCheckout /*&& !showRevisionCards*/) rowFont = HeadFont; else if (spi != null && spi.CurrentBranch == revision.Guid) rowFont = SuperprojectFont; if (columnIndex == messageColIndex) { int baseOffset = 0; if (IsCardLayout()) { baseOffset = 5; Rectangle cellRectangle = new Rectangle(e.CellBounds.Left + baseOffset, e.CellBounds.Top + 1, e.CellBounds.Width - (baseOffset * 2), e.CellBounds.Height - 4); if (!AppSettings.RevisionGraphDrawNonRelativesGray || Revisions.RowIsRelative(e.RowIndex)) { e.Graphics.FillRectangle( new LinearGradientBrush(cellRectangle, Color.FromArgb(255, 220, 220, 231), Color.FromArgb(255, 240, 240, 250), 90, false), cellRectangle); using (var pen = new Pen(Color.FromArgb(255, 200, 200, 200), 1)) { e.Graphics.DrawRectangle(pen, cellRectangle); } } else { e.Graphics.FillRectangle( new LinearGradientBrush(cellRectangle, Color.FromArgb(255, 240, 240, 240), Color.FromArgb(255, 250, 250, 250), 90, false), cellRectangle); } if ((e.State & DataGridViewElementStates.Selected) == DataGridViewElementStates.Selected) { using (var penSelectionBackColor = new Pen(Revisions.RowTemplate.DefaultCellStyle.SelectionBackColor, 1)) e.Graphics.DrawRectangle(penSelectionBackColor, cellRectangle); } } float offset = baseOffset; var gitRefs = revision.Refs; drawRefArgs.RefsFont = IsFilledBranchesLayout() ? rowFont : RefsFont; if (spi != null) { if (spi.Conflict_Base == revision.Guid) offset = DrawRef(drawRefArgs, offset, "Base", Color.OrangeRed, ArrowType.NotFilled); if (spi.Conflict_Local == revision.Guid) offset = DrawRef(drawRefArgs, offset, "Local", Color.OrangeRed, ArrowType.NotFilled); if (spi.Conflict_Remote == revision.Guid) offset = DrawRef(drawRefArgs, offset, "Remote", Color.OrangeRed, ArrowType.NotFilled); } if (gitRefs.Any()) { gitRefs.Sort((left, right) => { if (left.IsTag != right.IsTag) return right.IsTag.CompareTo(left.IsTag); if (left.IsRemote != right.IsRemote) return left.IsRemote.CompareTo(right.IsRemote); return left.Name.CompareTo(right.Name); }); foreach (var gitRef in gitRefs.Where(head => (!head.IsRemote || AppSettings.ShowRemoteBranches))) { if (gitRef.IsTag) { if (!AppSettings.ShowTags) { continue; } } Color headColor = GetHeadColor(gitRef); ArrowType arrowType = gitRef.Selected ? ArrowType.Filled : gitRef.SelectedHeadMergeSource ? ArrowType.NotFilled : ArrowType.None; var superprojectRef = superprojectRefs.FirstOrDefault(spGitRef => gitRef.CompleteName == spGitRef.CompleteName); if (superprojectRef != null) superprojectRefs.Remove(superprojectRef); offset = DrawRef(drawRefArgs, offset, gitRef.Name, headColor, arrowType, superprojectRef != null, true); } } for (int i = 0; i < Math.Min(MaxSuperprojectRefs, superprojectRefs.Count); i++) { var gitRef = superprojectRefs[i]; Color headColor = GetHeadColor(gitRef); var gitRefName = i < (MaxSuperprojectRefs - 1) ? gitRef.Name : "…"; ArrowType arrowType = gitRef.Selected ? ArrowType.Filled : gitRef.SelectedHeadMergeSource ? ArrowType.NotFilled : ArrowType.None; offset = DrawRef(drawRefArgs, offset, gitRefName, headColor, arrowType, true, false); } if (IsCardLayout()) offset = baseOffset; var text = (string)e.FormattedValue; var bounds = AdjustCellBounds(e.CellBounds, offset); DrawColumnText(e.Graphics, text, rowFont, foreColor, bounds); if (IsCardLayout()) { int textHeight = (int)e.Graphics.MeasureString(text, rowFont).Height; int gravatarSize = _rowHeigth - textHeight - 12; int gravatarTop = e.CellBounds.Top + textHeight + 6; int gravatarLeft = e.CellBounds.Left + baseOffset + 2; Image gravatar = Gravatar.GravatarService.GetImageFromCache(revision.AuthorEmail + gravatarSize.ToString() + ".png", revision.AuthorEmail, AppSettings.AuthorImageCacheDays, gravatarSize, AppSettings.GravatarCachePath, FallBackService.MonsterId); if (gravatar == null && !string.IsNullOrEmpty(revision.AuthorEmail)) { ThreadPool.QueueUserWorkItem(o => Gravatar.GravatarService.LoadCachedImage(revision.AuthorEmail + gravatarSize.ToString() + ".png", revision.AuthorEmail, null, AppSettings.AuthorImageCacheDays, gravatarSize, AppSettings.GravatarCachePath, RefreshGravatar, FallBackService.MonsterId)); } if (gravatar != null) e.Graphics.DrawImage(gravatar, gravatarLeft + 1, gravatarTop + 1, gravatarSize, gravatarSize); e.Graphics.DrawRectangle(Pens.Black, gravatarLeft, gravatarTop, gravatarSize + 1, gravatarSize + 1); string authorText; string timeText; if (_rowHeigth >= 60) { authorText = revision.Author; timeText = TimeToString(AppSettings.ShowAuthorDate ? revision.AuthorDate : revision.CommitDate); } else { timeText = string.Concat(revision.Author, " (", TimeToString(AppSettings.ShowAuthorDate ? revision.AuthorDate : revision.CommitDate), ")"); authorText = string.Empty; } e.Graphics.DrawString(authorText, rowFont, foreBrush, new PointF(gravatarLeft + gravatarSize + 5, gravatarTop + 6)); e.Graphics.DrawString(timeText, rowFont, foreBrush, new PointF(gravatarLeft + gravatarSize + 5, e.CellBounds.Bottom - textHeight - 4)); } } else if (columnIndex == authorColIndex) { var text = (string)e.FormattedValue; e.Graphics.DrawString(text, rowFont, foreBrush, new PointF(e.CellBounds.Left, e.CellBounds.Top + 4)); } else if (columnIndex == dateColIndex) { var time = AppSettings.ShowAuthorDate ? revision.AuthorDate : revision.CommitDate; var text = TimeToString(time); e.Graphics.DrawString(text, rowFont, foreBrush, new PointF(e.CellBounds.Left, e.CellBounds.Top + 4)); } else if (columnIndex == BuildServerWatcher.BuildStatusImageColumnIndex) { BuildInfoDrawingLogic.BuildStatusImageColumnCellPainting(e, revision, foreBrush, rowFont); } else if (columnIndex == BuildServerWatcher.BuildStatusMessageColumnIndex) { BuildInfoDrawingLogic.BuildStatusMessageCellPainting(e, revision, foreBrush, rowFont); } else if (AppSettings.ShowIndicatorForMultilineMessage && columnIndex == isMsgMultilineColIndex) { var text = (string)e.FormattedValue; e.Graphics.DrawString(text, rowFont, foreBrush, new PointF(e.CellBounds.Left, e.CellBounds.Top + 4)); } } }
private float DrawRef(DrawRefArgs drawRefArgs, float offset, string name, Color headColor, ArrowType arrowType, bool dashedLine = false, bool fill = false) { var textColor = fill ? headColor : Lerp(headColor, Color.White, 0.5f); if (IsCardLayout()) { using (Brush textBrush = new SolidBrush(textColor)) { string headName = name; offset += drawRefArgs.Graphics.MeasureString(headName, drawRefArgs.RefsFont).Width + 6; var location = new PointF(drawRefArgs.CellBounds.Right - offset, drawRefArgs.CellBounds.Top + 4); var size = new SizeF(drawRefArgs.Graphics.MeasureString(headName, drawRefArgs.RefsFont).Width, drawRefArgs.Graphics.MeasureString(headName, drawRefArgs.RefsFont).Height); if (fill) drawRefArgs.Graphics.FillRectangle(SystemBrushes.Info, location.X - 1, location.Y - 1, size.Width + 3, size.Height + 2); drawRefArgs.Graphics.DrawRectangle(SystemPens.InfoText, location.X - 1, location.Y - 1, size.Width + 3, size.Height + 2); drawRefArgs.Graphics.DrawString(headName, drawRefArgs.RefsFont, textBrush, location); } } else { string headName = IsFilledBranchesLayout() ? name : string.Concat("[", name, "] "); var headBounds = AdjustCellBounds(drawRefArgs.CellBounds, offset); SizeF textSize = drawRefArgs.Graphics.MeasureString(headName, drawRefArgs.RefsFont); offset += textSize.Width; if (IsFilledBranchesLayout()) { offset += 9; float extraOffset = DrawHeadBackground(drawRefArgs.IsRowSelected, drawRefArgs.Graphics, headColor, headBounds.X, headBounds.Y, RoundToEven(textSize.Width + 3), RoundToEven(textSize.Height), 3, arrowType, dashedLine, fill); offset += extraOffset; headBounds.Offset((int)(extraOffset + 1), 0); } DrawColumnText(drawRefArgs.Graphics, headName, drawRefArgs.RefsFont, textColor, headBounds); } return offset; }