-
-
Notifications
You must be signed in to change notification settings - Fork 42
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #180 from tonyhallett/colour-improvements
fix #179
- Loading branch information
Showing
14 changed files
with
299 additions
and
96 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
using System; | ||
using System.ComponentModel.Composition; | ||
using FineCodeCoverage.Options; | ||
using Microsoft; | ||
using Microsoft.VisualStudio; | ||
using Microsoft.VisualStudio.Shell; | ||
using Microsoft.VisualStudio.Shell.Interop; | ||
|
||
namespace FineCodeCoverage.Impl | ||
{ | ||
[Export(typeof(ICoverageColoursProvider))] | ||
[Export(typeof(ICoverageColours))] | ||
internal class CoverageColorProvider : ICoverageColoursProvider, ICoverageColours | ||
{ | ||
private readonly IVsFontAndColorStorage fontAndColorStorage; | ||
private Guid categoryWithCoverage = Guid.Parse("ff349800-ea43-46c1-8c98-878e78f46501"); | ||
private uint storeFlags = (uint)(__FCSTORAGEFLAGS.FCSF_READONLY | __FCSTORAGEFLAGS.FCSF_LOADDEFAULTS | __FCSTORAGEFLAGS.FCSF_NOAUTOCOLORS | __FCSTORAGEFLAGS.FCSF_PROPAGATECHANGES); | ||
private System.Windows.Media.Color defaultCoverageTouchedArea = System.Windows.Media.Colors.Green; | ||
private System.Windows.Media.Color defaultCoverageNotTouchedArea = System.Windows.Media.Colors.Red; | ||
private System.Windows.Media.Color defaultCoveragePartiallyTouchedArea = System.Windows.Media.Color.FromRgb(255, 165, 0); | ||
private System.Windows.Media.Color coverageTouchedArea; | ||
private System.Windows.Media.Color coverageNotTouchedArea; | ||
private System.Windows.Media.Color coveragePartiallyTouchedArea; | ||
public System.Windows.Media.Color CoverageTouchedArea { | ||
get { | ||
UpdateFromFontsAndColorsIfNecessary(); | ||
return coverageTouchedArea; | ||
} | ||
private set | ||
{ | ||
coverageTouchedArea = value; | ||
} | ||
} | ||
|
||
public System.Windows.Media.Color CoverageNotTouchedArea { | ||
get | ||
{ | ||
UpdateFromFontsAndColorsIfNecessary(); | ||
return coverageNotTouchedArea; | ||
} | ||
private set | ||
{ | ||
coverageNotTouchedArea = value; | ||
} | ||
} | ||
|
||
public System.Windows.Media.Color CoveragePartiallyTouchedArea { | ||
get | ||
{ | ||
UpdateFromFontsAndColorsIfNecessary(); | ||
return coveragePartiallyTouchedArea; | ||
} | ||
private set | ||
{ | ||
coveragePartiallyTouchedArea = value; | ||
} | ||
|
||
} | ||
|
||
private bool coverageColoursFromFontsAndColours; | ||
private bool requiresFromFontsAndColours; | ||
|
||
[ImportingConstructor] | ||
public CoverageColorProvider([Import(typeof(SVsServiceProvider))] IServiceProvider serviceProvider, IAppOptionsProvider appOptionsProvider) | ||
{ | ||
ThreadHelper.ThrowIfNotOnUIThread(); | ||
fontAndColorStorage = (IVsFontAndColorStorage)serviceProvider.GetService(typeof(IVsFontAndColorStorage)); | ||
Assumes.Present(fontAndColorStorage); | ||
coverageColoursFromFontsAndColours = appOptionsProvider.Get().CoverageColoursFromFontsAndColours; | ||
UseDefaultColoursIfNotFontsAndColours(); | ||
appOptionsProvider.OptionsChanged += AppOptionsProvider_OptionsChanged; | ||
} | ||
|
||
private void AppOptionsProvider_OptionsChanged(IAppOptions appOptions) | ||
{ | ||
coverageColoursFromFontsAndColours = appOptions.CoverageColoursFromFontsAndColours; | ||
UseDefaultColoursIfNotFontsAndColours(); | ||
} | ||
|
||
private void UseDefaultColoursIfNotFontsAndColours() | ||
{ | ||
if (!coverageColoursFromFontsAndColours) | ||
{ | ||
CoverageTouchedArea = defaultCoverageTouchedArea; | ||
CoverageNotTouchedArea = defaultCoverageNotTouchedArea; | ||
CoveragePartiallyTouchedArea = defaultCoveragePartiallyTouchedArea; | ||
} | ||
} | ||
|
||
public void UpdateRequired() | ||
{ | ||
requiresFromFontsAndColours = true; | ||
} | ||
|
||
private void UpdateFromFontsAndColorsIfNecessary() | ||
{ | ||
if(coverageColoursFromFontsAndColours && requiresFromFontsAndColours) | ||
{ | ||
UpdateColoursFromFontsAndColors(); | ||
} | ||
} | ||
|
||
private void UpdateColoursFromFontsAndColors() | ||
{ | ||
ThreadHelper.ThrowIfNotOnUIThread(); | ||
var success = fontAndColorStorage.OpenCategory(ref categoryWithCoverage, storeFlags); | ||
if (success == VSConstants.S_OK) | ||
{ | ||
CoverageTouchedArea = GetColor("Coverage Touched Area"); | ||
CoverageNotTouchedArea = GetColor("Coverage Not Touched Area"); | ||
CoveragePartiallyTouchedArea = GetColor("Coverage Partially Touched Area"); | ||
} | ||
fontAndColorStorage.CloseCategory(); | ||
//throw ? | ||
requiresFromFontsAndColours = false; | ||
} | ||
|
||
private System.Windows.Media.Color GetColor(string displayName) | ||
{ | ||
ThreadHelper.ThrowIfNotOnUIThread(); | ||
var touchAreaInfo = new ColorableItemInfo[1]; | ||
var getItemSuccess = fontAndColorStorage.GetItem(displayName, touchAreaInfo); | ||
if (getItemSuccess == VSConstants.S_OK) | ||
{ | ||
return ParseColor(touchAreaInfo[0].crBackground); | ||
} | ||
throw new Exception("Failed to get color"); | ||
} | ||
|
||
private System.Windows.Media.Color ParseColor(uint color) | ||
{ | ||
var dcolor = System.Drawing.ColorTranslator.FromOle(Convert.ToInt32(color)); | ||
return System.Windows.Media.Color.FromArgb(dcolor.A, dcolor.R, dcolor.G, dcolor.B); | ||
} | ||
|
||
|
||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
using System.Windows; | ||
using System.Windows.Media; | ||
using System.Windows.Shapes; | ||
using Microsoft.VisualStudio.Text.Editor; | ||
using Microsoft.VisualStudio.Text.Formatting; | ||
|
||
namespace FineCodeCoverage.Impl | ||
{ | ||
internal class CoverageLineGlyphFactory : IGlyphFactory | ||
{ | ||
private enum CoverageType { Covered, Partial, NotCovered} | ||
private ICoverageColours coverageColours; | ||
|
||
public CoverageLineGlyphFactory(ICoverageColours coverageColours) | ||
{ | ||
this.coverageColours = coverageColours; | ||
} | ||
|
||
public UIElement GenerateGlyph(IWpfTextViewLine textViewLine, IGlyphTag glyphTag) | ||
{ | ||
if (!(glyphTag is CoverageLineGlyphTag tag)) | ||
{ | ||
return null; | ||
} | ||
|
||
// vars | ||
|
||
var line = tag?.CoverageLine?.Line; | ||
var lineHitCount = line?.Hits ?? 0; | ||
var lineConditionCoverage = line?.ConditionCoverage?.Trim(); | ||
|
||
var coverageType = CoverageType.NotCovered; | ||
|
||
if (lineHitCount > 0) | ||
{ | ||
coverageType = CoverageType.Covered; | ||
|
||
if (!string.IsNullOrWhiteSpace(lineConditionCoverage) && !lineConditionCoverage.StartsWith("100")) | ||
{ | ||
coverageType = CoverageType.Partial; | ||
} | ||
} | ||
|
||
// result | ||
|
||
var result = new Rectangle(); | ||
result.Width = 3; | ||
result.Height = 16; | ||
result.Fill = GetBrush(coverageType); | ||
// return | ||
|
||
return result; | ||
} | ||
|
||
private Brush GetBrush(CoverageType coverageType) | ||
{ | ||
Color color = default; | ||
switch (coverageType) | ||
{ | ||
case CoverageType.Partial: | ||
color = coverageColours.CoveragePartiallyTouchedArea; | ||
break; | ||
case CoverageType.NotCovered: | ||
color = coverageColours.CoverageNotTouchedArea; | ||
break; | ||
case CoverageType.Covered: | ||
color = coverageColours.CoverageTouchedArea; | ||
break; | ||
} | ||
return new SolidColorBrush(color); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.