source: branches/CodeEditor/HeuristicLab.CodeEditor/3.4/LanguageFeatures/CodeCompletion/CSharp/CompletionData/Images/CompletionImage.cs @ 11700

Last change on this file since 11700 was 11700, checked in by jkarder, 6 years ago

#2077: created branch and added first version

File size: 14.4 KB
Line 
1#region License
2// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
3// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
4#endregion
5
6#region License Information
7/* HeuristicLab
8 * Copyright (C) 2002-2014 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
9 *
10 * This file is part of HeuristicLab.
11 *
12 * HeuristicLab is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation, either version 3 of the License, or
15 * (at your option) any later version.
16 *
17 * HeuristicLab is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
24 */
25#endregion
26
27using System;
28using System.Threading;
29using System.Windows;
30using System.Windows.Media;
31using System.Windows.Media.Imaging;
32using ICSharpCode.NRefactory.TypeSystem;
33
34namespace ICSharpCode.AvalonEdit.CodeCompletion {
35  /// <summary>
36  /// Provides icons for code-completion.
37  /// </summary>
38  public class CompletionImage {
39    #region Non-Entity Images
40    static readonly BitmapImage namespaceImage = LoadBitmap("NameSpace");
41
42    /// <summary>
43    /// Gets the image for namespaces.
44    /// </summary>
45    public static ImageSource NamespaceImage {
46      get { return namespaceImage; }
47    }
48
49    static BitmapImage LoadBitmap(string name) {
50      BitmapImage image = new BitmapImage(new Uri("pack://application:,,,/HeuristicLab.CodeEditor-3.4;component/LanguageFeatures/CodeCompletion/CSharp/CompletionData/Images/" + name + ".png"));
51      image.Freeze();
52      return image;
53    }
54    #endregion
55
56    #region Entity Images
57    static readonly CompletionImage imageClass = new CompletionImage("Class", false);
58    static readonly CompletionImage imageStruct = new CompletionImage("Struct", false);
59    static readonly CompletionImage imageInterface = new CompletionImage("Interface", false);
60    static readonly CompletionImage imageDelegate = new CompletionImage("Delegate", false);
61    static readonly CompletionImage imageEnum = new CompletionImage("Enum", false);
62    static readonly CompletionImage imageStaticClass = new CompletionImage("StaticClass", false);
63
64    /// <summary>Gets the image used for non-static classes.</summary>
65    public static CompletionImage Class { get { return imageClass; } }
66
67    /// <summary>Gets the image used for structs.</summary>
68    public static CompletionImage Struct { get { return imageStruct; } }
69
70    /// <summary>Gets the image used for interfaces.</summary>
71    public static CompletionImage Interface { get { return imageInterface; } }
72
73    /// <summary>Gets the image used for delegates.</summary>
74    public static CompletionImage Delegate { get { return imageDelegate; } }
75
76    /// <summary>Gets the image used for enums.</summary>
77    public static CompletionImage Enum { get { return imageEnum; } }
78
79    /// <summary>Gets the image used for modules/static classes.</summary>
80    public static CompletionImage StaticClass { get { return imageStaticClass; } }
81
82    static readonly CompletionImage imageField = new CompletionImage("Field", true);
83    static readonly CompletionImage imageFieldReadOnly = new CompletionImage("FieldReadOnly", true);
84    static readonly CompletionImage imageLiteral = new CompletionImage("Literal", false);
85    static readonly CompletionImage imageEnumValue = new CompletionImage("EnumValue", false);
86
87    /// <summary>Gets the image used for non-static classes.</summary>
88    public static CompletionImage Field { get { return imageField; } }
89
90    /// <summary>Gets the image used for structs.</summary>
91    public static CompletionImage ReadOnlyField { get { return imageFieldReadOnly; } }
92
93    /// <summary>Gets the image used for constants.</summary>
94    public static CompletionImage Literal { get { return imageLiteral; } }
95
96    /// <summary>Gets the image used for enum values.</summary>
97    public static CompletionImage EnumValue { get { return imageEnumValue; } }
98
99    static readonly CompletionImage imageMethod = new CompletionImage("Method", true);
100    static readonly CompletionImage imageConstructor = new CompletionImage("Constructor", true);
101    static readonly CompletionImage imageVirtualMethod = new CompletionImage("VirtualMethod", true);
102    static readonly CompletionImage imageOperator = new CompletionImage("Operator", false);
103    static readonly CompletionImage imageExtensionMethod = new CompletionImage("ExtensionMethod", true);
104    static readonly CompletionImage imagePInvokeMethod = new CompletionImage("PInvokeMethod", true);
105    static readonly CompletionImage imageProperty = new CompletionImage("Property", true);
106    static readonly CompletionImage imageIndexer = new CompletionImage("Indexer", true);
107    static readonly CompletionImage imageEvent = new CompletionImage("Event", true);
108
109    /// <summary>Gets the image used for methods.</summary>
110    public static CompletionImage Method { get { return imageMethod; } }
111
112    /// <summary>Gets the image used for constructos.</summary>
113    public static CompletionImage Constructor { get { return imageConstructor; } }
114
115    /// <summary>Gets the image used for virtual methods.</summary>
116    public static CompletionImage VirtualMethod { get { return imageVirtualMethod; } }
117
118    /// <summary>Gets the image used for operators.</summary>
119    public static CompletionImage Operator { get { return imageOperator; } }
120
121    /// <summary>Gets the image used for extension methods.</summary>
122    public static CompletionImage ExtensionMethod { get { return imageExtensionMethod; } }
123
124    /// <summary>Gets the image used for P/Invoke methods.</summary>
125    public static CompletionImage PInvokeMethod { get { return imagePInvokeMethod; } }
126
127    /// <summary>Gets the image used for properties.</summary>
128    public static CompletionImage Property { get { return imageProperty; } }
129
130    /// <summary>Gets the image used for indexers.</summary>
131    public static CompletionImage Indexer { get { return imageIndexer; } }
132
133    /// <summary>Gets the image used for events.</summary>
134    public static CompletionImage Event { get { return imageEvent; } }
135
136    /// <summary>
137    /// Gets the CompletionImage instance for the specified entity.
138    /// Returns null when no image is available for the entity type.
139    /// </summary>
140    public static CompletionImage GetCompletionImage(IEntity entity) {
141      if (entity == null)
142        throw new ArgumentNullException("entity");
143      switch (entity.SymbolKind) {
144        case SymbolKind.TypeDefinition:
145          return GetCompletionImageForType(((ITypeDefinition)entity).Kind, entity.IsStatic);
146        case SymbolKind.Field:
147          IField field = (IField)entity;
148          if (field.IsConst) {
149            if (field.DeclaringTypeDefinition != null && field.DeclaringTypeDefinition.Kind == TypeKind.Enum)
150              return imageEnumValue;
151            else
152              return imageLiteral;
153          }
154          return field.IsReadOnly ? imageFieldReadOnly : imageField;
155        case SymbolKind.Method:
156          IMethod method = (IMethod)entity;
157          if (method.IsExtensionMethod)
158            return imageExtensionMethod;
159          else
160            return method.IsOverridable ? imageVirtualMethod : imageMethod;
161        case SymbolKind.Property:
162          return imageProperty;
163        case SymbolKind.Indexer:
164          return imageIndexer;
165        case SymbolKind.Event:
166          return imageEvent;
167        case SymbolKind.Operator:
168        case SymbolKind.Destructor:
169          return imageOperator;
170        case SymbolKind.Constructor:
171          return imageConstructor;
172        default:
173          return null;
174      }
175    }
176
177    /// <summary>
178    /// Gets the CompletionImage instance for the specified entity.
179    /// Returns null when no image is available for the entity type.
180    /// </summary>
181    public static CompletionImage GetCompletionImage(IUnresolvedEntity entity) {
182      if (entity == null)
183        throw new ArgumentNullException("entity");
184      switch (entity.SymbolKind) {
185        case SymbolKind.TypeDefinition:
186          return GetCompletionImageForType(((IUnresolvedTypeDefinition)entity).Kind, entity.IsStatic);
187        case SymbolKind.Field:
188          IUnresolvedField field = (IUnresolvedField)entity;
189          if (field.IsConst) {
190            if (field.DeclaringTypeDefinition != null && field.DeclaringTypeDefinition.Kind == TypeKind.Enum)
191              return imageEnumValue;
192            else
193              return imageLiteral;
194          }
195          return field.IsReadOnly ? imageFieldReadOnly : imageField;
196        case SymbolKind.Method:
197          IUnresolvedMethod method = (IUnresolvedMethod)entity;
198          return method.IsOverridable ? imageVirtualMethod : imageMethod;
199        case SymbolKind.Property:
200          return imageProperty;
201        case SymbolKind.Indexer:
202          return imageIndexer;
203        case SymbolKind.Event:
204          return imageEvent;
205        case SymbolKind.Operator:
206        case SymbolKind.Destructor:
207          return imageOperator;
208        case SymbolKind.Constructor:
209          return imageConstructor;
210        default:
211          return null;
212      }
213    }
214
215    static CompletionImage GetCompletionImageForType(TypeKind typeKind, bool isStatic) {
216      switch (typeKind) {
217        case TypeKind.Interface:
218          return imageInterface;
219        case TypeKind.Struct:
220        case TypeKind.Void:
221          return imageStruct;
222        case TypeKind.Delegate:
223          return imageDelegate;
224        case TypeKind.Enum:
225          return imageEnum;
226        case TypeKind.Class:
227          return isStatic ? imageStaticClass : imageClass;
228        case TypeKind.Module:
229          return imageStaticClass;
230        default:
231          return null;
232      }
233    }
234
235    /// <summary>
236    /// Gets the image for the specified entity.
237    /// Returns null when no image is available for the entity type.
238    /// </summary>
239    public static ImageSource GetImage(IEntity entity) {
240      CompletionImage image = GetCompletionImage(entity);
241      if (image != null)
242        return image.GetImage(entity.Accessibility, entity.IsStatic);
243      else
244        return null;
245    }
246
247    /// <summary>
248    /// Gets the image for the specified entity.
249    /// Returns null when no image is available for the entity type.
250    /// </summary>
251    public static ImageSource GetImage(IUnresolvedEntity entity) {
252      CompletionImage image = GetCompletionImage(entity);
253      if (image != null)
254        return image.GetImage(entity.Accessibility, entity.IsStatic);
255      else
256        return null;
257    }
258    #endregion
259
260    #region Overlays
261    static readonly BitmapImage overlayStatic = LoadBitmap("OverlayStatic");
262
263    /// <summary>
264    /// Gets the overlay image for the static modifier.
265    /// </summary>
266    public ImageSource StaticOverlay { get { return overlayStatic; } }
267
268    const int AccessibilityOverlaysLength = 5;
269
270    static readonly BitmapImage[] accessibilityOverlays = new BitmapImage[AccessibilityOverlaysLength] {
271      null,
272      LoadBitmap("OverlayPrivate"),
273      LoadBitmap("OverlayProtected"),
274      LoadBitmap("OverlayInternal"),
275      LoadBitmap("OverlayProtectedInternal")
276    };
277
278    /// <summary>
279    /// Gets an overlay image for the specified accessibility.
280    /// Returns null if no overlay exists (for example, public members don't use overlays).
281    /// </summary>
282    public static ImageSource GetAccessibilityOverlay(Accessibility accessibility) {
283      return accessibilityOverlays[GetAccessibilityOverlayIndex(accessibility)];
284    }
285
286    static int GetAccessibilityOverlayIndex(Accessibility accessibility) {
287      switch (accessibility) {
288        case Accessibility.Private:
289          return 1;
290        case Accessibility.Protected:
291          return 2;
292        case Accessibility.Internal:
293          return 3;
294        case Accessibility.ProtectedOrInternal:
295        case Accessibility.ProtectedAndInternal:
296          return 4;
297        default:
298          return 0;
299      }
300    }
301    #endregion
302
303    #region Instance Members (add overlay to entity image)
304    readonly string imageName;
305    readonly bool showStaticOverlay;
306
307    private CompletionImage(string imageName, bool showStaticOverlay) {
308      this.imageName = imageName;
309      this.showStaticOverlay = showStaticOverlay;
310    }
311
312    ImageSource[] images = new ImageSource[2 * AccessibilityOverlaysLength];
313    // 0..N-1  = base image + accessibility overlay
314    // N..2N-1 = base image + static overlay + accessibility overlay
315
316    /// <summary>
317    /// Gets the image without any overlays.
318    /// </summary>
319    public ImageSource BaseImage {
320      get {
321        ImageSource image = images[0];
322        if (image == null) {
323          image = LoadBitmap(imageName);
324          Thread.MemoryBarrier();
325          images[0] = image;
326        }
327        return image;
328      }
329    }
330
331    /// <summary>
332    /// Gets this image combined with the specified accessibility overlay.
333    /// </summary>
334    public ImageSource GetImage(Accessibility accessibility, bool isStatic = false) {
335      int accessibilityIndex = GetAccessibilityOverlayIndex(accessibility);
336      int index;
337      if (isStatic && showStaticOverlay)
338        index = accessibilityOverlays.Length + accessibilityIndex;
339      else
340        index = accessibilityIndex;
341
342      if (index == 0)
343        return this.BaseImage;
344
345      ImageSource image = images[index];
346      if (image == null) {
347        DrawingGroup g = new DrawingGroup();
348        Rect iconRect = new Rect(0, 0, 16, 16);
349        g.Children.Add(new ImageDrawing(this.BaseImage, iconRect));
350
351        if (accessibilityOverlays[accessibilityIndex] != null)
352          g.Children.Add(new ImageDrawing(accessibilityOverlays[accessibilityIndex], iconRect));
353
354        image = new DrawingImage(g);
355        image.Freeze();
356        Thread.MemoryBarrier();
357        images[index] = image;
358      }
359      return image;
360    }
361
362    /// <inheritdoc/>
363    public override string ToString() {
364      return "[CompletionImage " + imageName + "]";
365    }
366    #endregion
367  }
368}
Note: See TracBrowser for help on using the repository browser.