@@ -7,83 +7,64 @@ open System.Windows
7
7
open System.Windows .Controls
8
8
9
9
open Microsoft.VisualStudio .Text .Adornments
10
- open Microsoft.VisualStudio .Text .Editor
11
10
open Microsoft.VisualStudio .Utilities
12
11
13
- open Microsoft.VisualStudio .FSharp .Editor
14
- open Microsoft.VisualStudio .Text .Classification
12
+ open Microsoft.VisualStudio .FSharp
15
13
16
- type Separator =
17
- | Separator of visible : bool
18
- // preserve old behavior on mac
14
+ type internal FSharpStyle =
15
+ | Separator
16
+ | Paragraph
17
+ | CustomLinkStyle
18
+
19
+ // Render as strings for cross platform look.
19
20
override this.ToString () =
20
21
match this with
21
- | Separator true -> XmlDocumentation.separatorText
22
- | _ -> System.Environment.NewLine
22
+ | Separator -> Editor.XmlDocumentation.separatorText
23
+ | Paragraph -> System.Environment.NewLine
24
+ | CustomLinkStyle -> " "
23
25
26
+ // Provide nicer look for the QuickInfo on Windows.
24
27
[<Export( typeof< IViewElementFactory>) >]
25
- [<Name( " ClassifiedTextElement to UIElement" ) >]
26
- [<TypeConversion( typeof< ClassifiedTextElement>, typeof< UIElement>) >]
27
- type WpfClassifiedTextElementFactory [<ImportingConstructor>]
28
- (
29
- classificationformatMapService: IClassificationFormatMapService,
30
- classificationTypeRegistry: IClassificationTypeRegistryService,
31
- settings: EditorOptions
32
- ) =
33
- let resources = Microsoft.VisualStudio.FSharp.UIResources.NavStyles() .Resources
34
- let formatMap = classificationformatMapService.GetClassificationFormatMap( " tooltip" )
35
-
36
- interface IViewElementFactory with
37
- member _.CreateViewElement ( _textView : ITextView , model : obj ) =
38
- match model with
39
- | :? ClassifiedTextElement as text ->
40
- let tb = TextBlock()
41
- tb.FontSize <- formatMap.DefaultTextProperties.FontRenderingEmSize
42
- tb.FontFamily <- formatMap.DefaultTextProperties.Typeface.FontFamily
43
- tb.TextWrapping <- TextWrapping.Wrap
28
+ [<Name( " FSharpStyle to UIElement" ) >]
29
+ [<TypeConversion( typeof< FSharpStyle>, typeof< UIElement>) >]
30
+ type internal WpfFSharpStyleFactory [<ImportingConstructor>] ( settings : Editor.EditorOptions ) =
31
+ let linkStyleUpdater () =
32
+ let key =
33
+ if settings.QuickInfo.DisplayLinks then
34
+ $" {settings.QuickInfo.UnderlineStyle.ToString().ToLower()}_underline"
35
+ else
36
+ " no_underline"
44
37
45
- for run in text.Runs do
46
- let ctype =
47
- classificationTypeRegistry.GetClassificationType( run.ClassificationTypeName)
38
+ let style = UIResources.NavStyles() .Resources[ key] :?> Style
48
39
49
- let props = formatMap.GetTextProperties( ctype)
50
- let inl = Documents.Run( run.Text, Foreground = props.ForegroundBrush)
40
+ // Some assumptions are made here about the shape of QuickInfo visual tree rendered by VS.
41
+ // If some future VS update were to render QuickInfo with different WPF elements
42
+ // the links will still work, just without their custom styling.
43
+ let rec styleLinks ( element : DependencyObject ) =
44
+ match element with
45
+ | :? TextBlock as t ->
46
+ for run in t.Inlines do
47
+ if run :? Documents.Hyperlink then
48
+ run.Style <- style
49
+ | :? Panel as p ->
50
+ for e in p.Children do
51
+ styleLinks e
52
+ | _ -> ()
51
53
52
- match run.NavigationAction |> Option.ofObj with
53
- | Some action ->
54
- let link =
55
- { new Documents.Hyperlink( inl, ToolTip = run.Tooltip) with
56
- override _.OnClick () = action.Invoke()
57
- }
54
+ // Return an invisible FrameworkElement which will traverse it's siblings
55
+ // to find HyperLinks and update their style, when inserted into the visual tree.
56
+ { new FrameworkElement() with
57
+ override this.OnVisualParentChanged _ = styleLinks this.Parent
58
+ }
58
59
59
- let key =
60
- match settings.QuickInfo.UnderlineStyle with
61
- | QuickInfoUnderlineStyle.Solid -> " solid_underline"
62
- | QuickInfoUnderlineStyle.Dash -> " dash_underline"
63
- | QuickInfoUnderlineStyle.Dot -> " dot_underline"
64
-
65
- link.Style <- downcast resources[ key]
66
- link.Foreground <- props.ForegroundBrush
67
- tb.Inlines.Add( link)
68
- | _ -> tb.Inlines.Add( inl)
69
-
70
- box tb :?> _
71
- | _ ->
72
- failwith
73
- $" Invalid type conversion. Supported conversion is {typeof<ClassifiedTextElement>.Name} to {typeof<UIElement>.Name}."
74
-
75
- [<Export( typeof< IViewElementFactory>) >]
76
- [<Name( " Separator to UIElement" ) >]
77
- [<TypeConversion( typeof< Separator>, typeof< UIElement>) >]
78
- type WpfSeparatorFactory () =
79
60
interface IViewElementFactory with
80
61
member _.CreateViewElement ( _ , model : obj ) =
81
62
match model with
82
- | :? Separator as Separator visible ->
83
- if visible then
84
- Controls.Separator ( Opacity = 0.3 , Margin = Thickness ( 0 , 8 , 0 , 8 ) )
85
- else
86
- Controls.Separator( Opacity = 0 )
63
+ | :? FSharpStyle as fSharpStyle ->
64
+ match fSharpStyle with
65
+ | CustomLinkStyle -> linkStyleUpdater ( )
66
+ | Separator -> Controls.Separator ( Opacity = 0.3 , Margin = Thickness ( 0 , 8 , 0 , 8 ))
67
+ | Paragraph -> Controls.Separator( Opacity = 0 )
87
68
|> box
88
69
:?> _
89
- | _ -> failwith $" Invalid type conversion. Supported conversion is {typeof<Separator >.Name} to {typeof<UIElement>.Name}."
70
+ | _ -> failwith $" Invalid type conversion. Supported conversion is {typeof<FSharpStyle >.Name} to {typeof<UIElement>.Name}."
0 commit comments