PageRenderTime 49ms CodeModel.GetById 2ms app.highlight 41ms RepoModel.GetById 1ms app.codeStats 0ms

/src/NUnit/UiException/Controls/DefaultErrorListRenderer.cs

#
C# | 337 lines | 253 code | 69 blank | 15 comment | 24 complexity | a41ae21a17bd022e8aba7ddfbda29c06 MD5 | raw file
  1// ****************************************************************
  2// This is free software licensed under the NUnit license. You may
  3// obtain a copy of the license at http://nunit.org
  4// ****************************************************************
  5
  6using System;
  7using System.Collections.Generic;
  8using System.Text;
  9using System.Drawing;
 10using NUnit.UiException.Properties;
 11using System.Diagnostics;
 12
 13namespace NUnit.UiException.Controls
 14{
 15    /// <summary>
 16    /// Implements IErrorListRenderer.
 17    /// </summary>
 18    public class DefaultErrorListRenderer :
 19        IErrorListRenderer
 20    {
 21        //private static readonly int ITEM_HEIGHT = 54;
 22        private static readonly int TEXT_MARGIN_X = 16;
 23
 24        private Font _font;
 25        private Font _fontUnderlined;
 26        private int _itemHeight;
 27        private Brush _brushBlue;
 28        private Brush _brushGray;
 29        private float _offsetLine;
 30        
 31        private Rectangle _rectListShadow;
 32        private Rectangle _rectListBackground;
 33        private Rectangle _rectItemGray;
 34        private Rectangle _rectItemWhite;
 35        private Rectangle _rectSelectionMiddle;
 36        private Rectangle _rectIconDll;
 37        private Rectangle _rectIconCSharp;
 38        private Rectangle _rectIconArrow;
 39//        private Rectangle _rectShadow;
 40
 41        private PaintData _paintData;
 42
 43        public DefaultErrorListRenderer()
 44        {
 45            this.Font = new Font(FontFamily.GenericSansSerif, 8.25f);
 46            //_fontUnderlined = new Font(_font, FontStyle.Underline);
 47            //_itemHeight = _font.Height * 4 + 6;
 48
 49            _brushBlue = new SolidBrush(Color.FromArgb(0, 43, 114));
 50            _brushGray = new SolidBrush(Color.FromArgb(64, 64, 64));
 51
 52            _rectListShadow = new Rectangle(0, 0, 48, 9);
 53            _rectListBackground = new Rectangle(0, 10, 48, 48);
 54            _rectItemGray = new Rectangle(71, 0, 9, 54);
 55            _rectItemWhite = new Rectangle(60, 0, 9, 54);
 56            _rectSelectionMiddle = new Rectangle(49, 0, 9, 54);
 57            _rectIconDll = new Rectangle(1, 59, 16, 15);
 58            _rectIconCSharp = new Rectangle(18, 59, 14, 15);
 59            _rectIconArrow = new Rectangle(35, 60, 9, 5);
 60//            _rectShadow = new Rectangle(49, 60, 4, 8);
 61
 62            _paintData = new PaintData();
 63
 64            return;
 65        }
 66
 67        public Font Font
 68        {
 69            get { return (_font); }
 70            set 
 71            { 
 72                _fontUnderlined = _font = value;
 73                if (_font.FontFamily.IsStyleAvailable(FontStyle.Underline))
 74                    _fontUnderlined = new Font(_font, FontStyle.Underline);
 75                _itemHeight = _font.Height * 4 + 6;
 76            }
 77        }
 78
 79        #region IErrorListRenderer Membres
 80
 81        public void DrawToGraphics(ErrorItemCollection items,
 82            ErrorItem selected, Graphics g, Rectangle viewport)
 83        {
 84            SizeF sizeLineSource;
 85            int last;
 86            int i;
 87
 88            UiExceptionHelper.CheckNotNull(items, "items");
 89            UiExceptionHelper.CheckNotNull(g, "g");
 90
 91            if (!_paintData.Equals(items, selected, viewport))
 92            {
 93                _paintData.Dispose();
 94                _paintData = new PaintData(items, selected, viewport, g);
 95
 96                PaintBackground(Resources.ImageErrorList, _paintData.WorkingGraphics,
 97                    _rectListBackground, viewport);
 98
 99                sizeLineSource = g.MeasureString("Line 9999", _font);
100                _offsetLine = viewport.Width - sizeLineSource.Width;
101
102                last = LastIndexVisible(items.Count, viewport);
103                for (i = FirstIndexVisible(items.Count, viewport); i <= last; ++i)
104                    DrawItem(items[i], i, selected == items[i], i == items.Count - 1, false, 
105                        _paintData.WorkingGraphics, viewport);
106
107                //_paintData.WorkingGraphics.DrawImage(Resources.ErrorList,
108                //new Rectangle(0, 0, viewport.Width, _rectShadow.Height),
109                //_rectShadow, GraphicsUnit.Pixel);
110            }
111            
112            _paintData.PaintTo(g);           
113
114            return;
115        }
116
117        public void DrawItem(ErrorItem item, int index, bool hovered, bool selected, Graphics g, Rectangle viewport)
118        {
119            DrawItem(item, index, selected, false, hovered, g, viewport);
120        }
121
122        public Size GetDocumentSize(ErrorItemCollection items, Graphics g)
123        {
124            SizeF current;
125            float w;
126
127            _paintData = new PaintData();
128
129            if (items.Count == 0)
130                return (new Size());
131
132            w = 0;
133            foreach (ErrorItem item in items)
134            {
135                current = MeasureItem(g, item);
136                w = Math.Max(w, current.Width);
137            }            
138
139            return (new Size((int)w, items.Count * _itemHeight));
140        }
141
142        public ErrorItem ItemAt(ErrorItemCollection items, Graphics g, Point point)
143        {
144            int idx = point.Y / _itemHeight;
145
146            if (items == null || point.Y < 0 || idx >= items.Count)
147                return (null);
148
149            return (items[idx]);
150        }
151
152        #endregion
153
154        protected bool IsDirty(ErrorItemCollection items, ErrorItem selection, Rectangle viewport)
155        {
156            return (!_paintData.Equals(items, selection, viewport));
157        }
158
159        protected SizeF MeasureItem(Graphics g, ErrorItem item)
160        {
161            SizeF sizeMethod;
162            SizeF sizeClass;
163            SizeF sizeFile;
164
165            UiExceptionHelper.CheckNotNull(g, "g");
166            UiExceptionHelper.CheckNotNull(item, "item");
167
168            sizeClass = g.MeasureString(item.ClassName, _font);
169            sizeMethod = g.MeasureString(item.MethodName, _font);
170            sizeFile = g.MeasureString(item.FileName, _font);
171
172            return (new SizeF(
173                Math.Max(sizeClass.Width, Math.Max(sizeMethod.Width, sizeFile.Width)) + TEXT_MARGIN_X,
174                _itemHeight));
175        }
176
177        private void DrawItem(ErrorItem item, int index, bool selected, bool last, bool hover, Graphics g, Rectangle viewport)
178        {
179            Rectangle src;
180            Font font;
181
182            int x = -viewport.X;
183            int y = _itemHeight * index - viewport.Y;
184
185            src = (index % 2 == 0) ? _rectItemWhite : _rectItemGray ;
186            font = (hover == true) ? _fontUnderlined : _font;
187
188            g.DrawImage(Resources.ImageErrorList,
189                new Rectangle(0, y, viewport.Width, _itemHeight), src,
190                GraphicsUnit.Pixel);
191
192            if (selected)
193            {
194                g.DrawImage(Resources.ImageErrorList,
195                    new Rectangle(0, y + 1, viewport.Width, _itemHeight ),
196                    _rectSelectionMiddle, GraphicsUnit.Pixel);
197            }
198
199            if (item.HasSourceAttachment)
200            {
201                g.DrawImage(Resources.ImageErrorList, new Rectangle(x + 1, y + 2 + font.Height, 14, 15),
202                   _rectIconCSharp, GraphicsUnit.Pixel);
203                g.DrawImage(Resources.ImageErrorList, 
204                    new Rectangle(TEXT_MARGIN_X - 3 + x, y + 5 + 2 * font.Height, 9, 5),
205                    _rectIconArrow, GraphicsUnit.Pixel);
206
207                g.DrawString(String.Format("Line {0}", item.LineNumber),
208                    font, _brushGray, _offsetLine, y + 2);
209                g.DrawString(item.ClassName, font, _brushBlue, x + TEXT_MARGIN_X, y + 2 + font.Height);
210                g.DrawString(item.BaseMethodName + "()", font, _brushBlue,
211                    x + TEXT_MARGIN_X + 5, y + 2 + 2 * font.Height);
212                g.DrawString(item.FileName, font, _brushGray,
213                    x + TEXT_MARGIN_X, y + 2 + 3 * _font.Height);
214            }
215            else
216            {
217                g.DrawImage(Resources.ImageErrorList, new Rectangle(x + 1, y + 2 + font.Height, 16, 15),
218                   _rectIconDll, GraphicsUnit.Pixel);
219
220                g.DrawString("N/A", font, _brushGray, _offsetLine, y + 2);
221                g.DrawString(item.ClassName, font, _brushGray, 
222                    x + TEXT_MARGIN_X, y + 2 + font.Height);
223                g.DrawString(item.BaseMethodName + "()", font, _brushGray,
224                    x + TEXT_MARGIN_X, y + 2 + 2 * font.Height);                
225            }
226
227            if (!last)
228                return;
229
230            PaintTile(Resources.ImageErrorList, g, _rectListShadow,
231                new Rectangle(0, y + _itemHeight, viewport.Width, 9));
232
233            return;
234        }
235
236        private static void PaintBackground(Image img, Graphics g, Rectangle bkg, Rectangle viewport)
237        {
238            Rectangle destTile;
239            int x;
240            int y;
241            int startY;
242            int startX;
243
244            startY = -viewport.Y % viewport.Height;
245            startX = -viewport.X % viewport.Width;
246
247            for (y = startY; y < viewport.Height; y += bkg.Height)
248                for (x = startX; x < viewport.Width; x += bkg.Width)
249                {
250                    destTile = new Rectangle(x, y, bkg.Width, bkg.Height);
251                    g.DrawImage(img, destTile, bkg, GraphicsUnit.Pixel);
252                }
253
254            return;
255        }
256
257        private static void PaintTile(Image tile, Graphics g, Rectangle src, Rectangle dst)
258        {
259            Rectangle destTile;
260            int x;
261            int y;
262
263            for (y = dst.Top; y < dst.Bottom; y += src.Height)
264                for (x = dst.Left; x < dst.Right; x += src.Width)
265                {
266                    destTile = new Rectangle(x, y, src.Width, src.Height);
267                    g.DrawImage(tile, destTile, src, GraphicsUnit.Pixel);
268                }
269
270            return;
271        }
272
273        private int FirstIndexVisible(int count, Rectangle viewport)
274        {
275            return (Math.Max(0, viewport.Y / _itemHeight));
276        }
277
278        private int LastIndexVisible(int count, Rectangle viewport)
279        {
280            return (Math.Min(count - 1,
281                FirstIndexVisible(count, viewport) + 1 + viewport.Height / _itemHeight));
282        }
283
284        class PaintData
285        {
286            public Graphics WorkingGraphics;
287
288            private ErrorItem _firstItem;
289            private ErrorItem selection;
290            private Rectangle viewport;
291            private Image _workingImage;
292
293            public PaintData() { }
294
295            public PaintData(ErrorItemCollection items, ErrorItem item, Rectangle rectangle, Graphics g)
296            {
297                if (item == null)
298                    item = new ErrorItem();
299                selection = item;
300
301                _firstItem = ((items.Count > 0) ? items[0] : null);
302
303                viewport = rectangle;
304
305                _workingImage = new Bitmap(rectangle.Width, rectangle.Height, g);
306                WorkingGraphics = Graphics.FromImage(_workingImage);
307
308                return;
309            }
310
311            public void Dispose()
312            {
313                if (_workingImage != null)
314                {
315                    _workingImage.Dispose();
316                    WorkingGraphics.Dispose();
317                }
318
319                return;
320            }
321
322            public void PaintTo(Graphics g)
323            {
324                g.DrawImage(_workingImage, 0, 0);
325            }
326
327            public bool Equals(ErrorItemCollection items, ErrorItem item, Rectangle rectangle)
328            {               
329                ErrorItem first = ((items.Count > 0) ? items[0] : null);
330
331                return (viewport.Equals(rectangle) &&
332                        object.ReferenceEquals(item, selection) &&
333                        object.ReferenceEquals(first, _firstItem));
334            }
335        }
336    }
337}