~ubuntu-branches/ubuntu/oneiric/monodevelop/oneiric

« back to all changes in this revision

Viewing changes to src/addins/VersionControl/MonoDevelop.VersionControl/MonoDevelop.VersionControl.Views/CellRendererDiff.cs

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2011-06-27 17:03:13 UTC
  • mto: (1.8.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 54.
  • Revision ID: james.westby@ubuntu.com-20110627170313-6cvz3s19x6e9hqe9
Import upstream version 2.5.92+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
 
2
2
using System;
 
3
using System.Collections.Generic;
3
4
using Gtk;
4
5
using Gdk;
5
6
using MonoDevelop.Ide;
 
7
using MonoDevelop.Components;
 
8
using System.Text;
6
9
 
7
10
namespace MonoDevelop.VersionControl.Views
8
11
{
16
19
                int selectedLine = -1;
17
20
                TreePath selctedPath;
18
21
                TreePath path;
19
 
 
 
22
                int RightPadding = 4;
 
23
                
 
24
//              Gdk.Color baseAddColor = new Gdk.Color (133, 168, 133);
 
25
//              Gdk.Color baseRemoveColor = new Gdk.Color (178, 140, 140);
 
26
                Gdk.Color baseAddColor = new Gdk.Color (123, 200, 123).AddLight (0.1);
 
27
                Gdk.Color baseRemoveColor = new Gdk.Color (200, 140, 140).AddLight (0.1);
 
28
                
 
29
                int RoundedSectionRadius = 4;
 
30
                int LeftPaddingBlock = 19;
 
31
                
20
32
                public CellRendererDiff()
21
33
                {
22
34
                        font = Pango.FontDescription.FromString (DesktopService.DefaultMonospaceFont);
50
62
                {
51
63
                        if (isDisposed)
52
64
                                return;
 
65
                        if (lines == null)
 
66
                                throw new ArgumentNullException ("lines");
53
67
                        this.lines = lines;
54
68
                        this.diffMode = diffMode;
55
69
                        this.path = path;
59
73
                                        int maxlen = -1;
60
74
                                        int maxlin = -1;
61
75
                                        for (int n=0; n<lines.Length; n++) {
62
 
                                                if (lines [n].Length > maxlen) {
 
76
                                                string line = ProcessLine (lines [n]);
 
77
                                                if (line == null)
 
78
                                                        throw new Exception ("Line " + n + " from diff was null.");
 
79
                                                if (line.Length > maxlen) {
63
80
                                                        maxlen = lines [n].Length;
64
81
                                                        maxlin = n;
65
82
                                                }
68
85
                                        layout = CreateLayout (container, lines [maxlin]);
69
86
                                        layout.GetPixelSize (out width, out lineHeight);
70
87
                                        height = lineHeight * lines.Length;
 
88
                                        width += LeftPaddingBlock + RightPadding;
71
89
                                }
72
90
                                else
73
91
                                        width = height = 0;
91
109
                                layout.SetMarkup (text);
92
110
                        return layout;
93
111
                }
94
 
 
 
112
                
 
113
                string ProcessLine (string line)
 
114
                {
 
115
                        if (line == null)
 
116
                                return null;
 
117
                        return line.Replace ("\t","    ");
 
118
                }
 
119
                
 
120
                const int leftSpace = 16;
 
121
                public bool DrawLeft { get; set; }
 
122
                
95
123
                protected override void Render (Drawable window, Widget widget, Gdk.Rectangle background_area, Gdk.Rectangle cell_area, Gdk.Rectangle expose_area, CellRendererState flags)
96
124
                {
97
125
                        if (isDisposed)
105
133
                                
106
134
                                int w, maxy;
107
135
                                window.GetSize (out w, out maxy);
108
 
                                
 
136
                                if (DrawLeft) {
 
137
                                        cell_area.Width += cell_area.X - leftSpace;
 
138
                                        cell_area.X = leftSpace;
 
139
                                }
109
140
                                var treeview = widget as FileTreeView;
110
141
                                var p = treeview != null? treeview.CursorLocation : null;
111
142
                                
112
 
                                int recty = cell_area.Y;
113
 
                                int recth = cell_area.Height - 1;
114
 
                                if (recty < 0) {
115
 
                                        recth += recty + 1;
116
 
                                        recty = -1;
117
 
                                }
118
 
                                if (recth > maxy + 2)
119
 
                                        recth = maxy + 2;
120
 
                                
121
 
                                window.DrawRectangle (widget.Style.BaseGC (Gtk.StateType.Normal), true, cell_area.X, recty, cell_area.Width - 1, recth);
122
 
 
 
143
                                cell_area.Width -= RightPadding;
 
144
                                
 
145
                                window.DrawRectangle (widget.Style.BaseGC (Gtk.StateType.Normal), true, cell_area.X, cell_area.Y, cell_area.Width - 1, cell_area.Height);
 
146
                                
123
147
                                Gdk.GC normalGC = widget.Style.TextGC (StateType.Normal);
124
148
                                Gdk.GC removedGC = new Gdk.GC (window);
125
149
                                removedGC.Copy (normalGC);
126
 
                                removedGC.RgbFgColor = new Color (255, 0, 0);
 
150
                                removedGC.RgbFgColor = baseRemoveColor.AddLight (-0.3);
127
151
                                Gdk.GC addedGC = new Gdk.GC (window);
128
152
                                addedGC.Copy (normalGC);
129
 
                                addedGC.RgbFgColor = new Color (0, 0, 255);
 
153
                                addedGC.RgbFgColor = baseAddColor.AddLight (-0.3);
130
154
                                Gdk.GC infoGC = new Gdk.GC (window);
131
155
                                infoGC.Copy (normalGC);
132
 
                                infoGC.RgbFgColor = new Color (0xa5, 0x2a, 0x2a);
 
156
                                infoGC.RgbFgColor = widget.Style.Text (StateType.Normal).AddLight (0.2);
 
157
                                
 
158
                                Cairo.Context ctx = CairoHelper.Create (window);
 
159
                                
 
160
                                // Rendering is done in two steps:
 
161
                                // 1) Get a list of blocks to render
 
162
                                // 2) render the blocks
133
163
                                
134
164
                                int y = cell_area.Y + 2;
 
165
                                
 
166
                                // cline keeps track of the current source code line (the one to jump to when double clicking)
135
167
                                int cline = 1;
136
168
                                bool inHeader = true;
 
169
                                BlockInfo currentBlock = null;
 
170
                                
 
171
                                List<BlockInfo> blocks = new List<BlockInfo> ();
137
172
                                
138
173
                                for (int n=0; n<lines.Length; n++, y += lineHeight) {
139
174
                                        
140
175
                                        string line = lines [n];
141
 
                                        if (line.Length == 0)
 
176
                                        if (line.Length == 0) {
 
177
                                                currentBlock = null;
 
178
                                                y -= lineHeight;
142
179
                                                continue;
 
180
                                        }
143
181
                                        
144
182
                                        char tag = line [0];
145
 
 
146
 
                                        // Keep track of the real file line
147
 
                                        int thisLine = cline;
 
183
        
 
184
                                        if (line.StartsWith ("---") || line.StartsWith ("+++")) {
 
185
                                                // Ignore this part of the header.
 
186
                                                currentBlock = null;
 
187
                                                y -= lineHeight;
 
188
                                                continue;
 
189
                                        }
148
190
                                        if (tag == '@') {
149
191
                                                int l = ParseCurrentLine (line);
150
 
                                                if (l != -1) cline = thisLine = l;
 
192
                                                if (l != -1) cline = l - 1;
151
193
                                                inHeader = false;
152
194
                                        } else if (tag != '-' && !inHeader)
153
195
                                                cline++;
154
196
                                        
155
 
                                        if (y + lineHeight < 0)
156
 
                                                continue;
157
 
                                        if (y > maxy)
158
 
                                                break;
159
 
                                        
160
 
                                        Gdk.GC gc;
 
197
                                        BlockType type;
161
198
                                        switch (tag) {
162
 
                                                case '-': gc = removedGC; break;
163
 
                                                case '+': gc = addedGC; break;
164
 
                                                case '@': gc = infoGC; break;
165
 
                                                default: gc = normalGC; break;
166
 
                                        }
167
 
 
168
 
                                        if (p.HasValue && p.Value.X >= cell_area.X && p.Value.X <= cell_area.Right && p.Value.Y >= y && p.Value.Y < y + lineHeight) {
169
 
                                                window.DrawRectangle (widget.Style.BaseGC (Gtk.StateType.Prelight), true, cell_area.X, y, cell_area.Width - 1, lineHeight);
170
 
                                                selectedLine = thisLine;
 
199
                                                case '-': type = BlockType.Removed; break;
 
200
                                                case '+': type = BlockType.Added; break;
 
201
                                                case '@': type = BlockType.Info; break;
 
202
                                                default: type = BlockType.Unchanged; break;
 
203
                                        }
 
204
 
 
205
                                        if (currentBlock == null || type != currentBlock.Type) {
 
206
                                                if (y > maxy)
 
207
                                                        break;
 
208
                                        
 
209
                                                // Starting a new block. Mark section ends between a change block and a normal code block
 
210
                                                if (currentBlock != null && IsChangeBlock (currentBlock.Type) && !IsChangeBlock (type))
 
211
                                                        currentBlock.SectionEnd = true;
 
212
                                                
 
213
                                                currentBlock = new BlockInfo () {
 
214
                                                        YStart = y,
 
215
                                                        FirstLine = n,
 
216
                                                        Type = type,
 
217
                                                        SourceLineStart = cline,
 
218
                                                        SectionStart = (blocks.Count == 0 || !IsChangeBlock (blocks[blocks.Count - 1].Type)) && IsChangeBlock (type)
 
219
                                                };
 
220
                                                blocks.Add (currentBlock);
 
221
                                        }
 
222
                                        // Include the line in the current block
 
223
                                        currentBlock.YEnd = y + lineHeight;
 
224
                                        currentBlock.LastLine = n;
 
225
                                }
 
226
 
 
227
                                // Now render the blocks
 
228
 
 
229
                                // The y position of the highlighted line
 
230
                                int selectedLineRowTop = -1;
 
231
 
 
232
                                BlockInfo lastCodeSegmentStart = null;
 
233
                                BlockInfo lastCodeSegmentEnd = null;
 
234
                                
 
235
                                foreach (BlockInfo block in blocks)
 
236
                                {
 
237
                                        if (block.Type == BlockType.Info) {
 
238
                                                // Finished drawing the content of a code segment. Now draw the segment border and label.
 
239
                                                if (lastCodeSegmentStart != null)
 
240
                                                        DrawCodeSegmentBorder (infoGC, ctx, cell_area.X, cell_area.Width, lastCodeSegmentStart, lastCodeSegmentEnd, lines, widget, window);
 
241
                                                lastCodeSegmentStart = block;
 
242
                                        }
 
243
                                        
 
244
                                        lastCodeSegmentEnd = block;
 
245
                                        
 
246
                                        if (block.YEnd < 0)
 
247
                                                continue;
 
248
                                        
 
249
                                        // Draw the block background
 
250
                                        DrawBlockBg (ctx, cell_area.X + 1, cell_area.Width - 2, block);
 
251
                                        
 
252
                                        // Get all text for the current block
 
253
                                        StringBuilder sb = new StringBuilder ();
 
254
                                        for (int n=block.FirstLine; n <= block.LastLine; n++) {
 
255
                                                string s = ProcessLine (lines [n]);
 
256
                                                if (n > block.FirstLine)
 
257
                                                        sb.Append ('\n');
 
258
                                                if (block.Type != BlockType.Info && s.Length > 0)
 
259
                                                        sb.Append (s, 1, s.Length - 1);
 
260
                                                else
 
261
                                                        sb.Append (s);
 
262
                                        }
 
263
                                        
 
264
                                        // Draw a special background for the selected line
 
265
                                        
 
266
                                        if (block.Type != BlockType.Info && p.HasValue && p.Value.X >= cell_area.X && p.Value.X <= cell_area.Right && p.Value.Y >= block.YStart && p.Value.Y <= block.YEnd) {
 
267
                                                int row = (p.Value.Y - block.YStart) / lineHeight;
 
268
                                                double yrow = block.YStart + lineHeight * row + 0.5;
 
269
                                                double xrow = cell_area.X + LeftPaddingBlock + 0.5;
 
270
                                                int wrow = cell_area.Width - 1 - LeftPaddingBlock;
 
271
                                                if (block.Type == BlockType.Added)
 
272
                                                        ctx.Color = baseAddColor.AddLight (0.1).ToCairoColor ();
 
273
                                                else if (block.Type == BlockType.Removed)
 
274
                                                        ctx.Color = baseRemoveColor.AddLight (0.1).ToCairoColor ();
 
275
                                                else {
 
276
                                                        ctx.Color = widget.Style.Base (Gtk.StateType.Prelight).AddLight (0.1).ToCairoColor ();
 
277
                                                        xrow -= LeftPaddingBlock;
 
278
                                                        wrow += LeftPaddingBlock;
 
279
                                                }
 
280
                                                ctx.Rectangle (xrow, yrow, wrow, lineHeight);
 
281
                                                ctx.Fill ();
 
282
                                                selectedLine = block.SourceLineStart + row;
171
283
                                                selctedPath = path;
172
 
                                        }
173
 
                                        
174
 
                                        layout.SetText (line);
175
 
                                        window.DrawLayout (gc, cell_area.X + 2, y, layout);
 
284
                                                selectedLineRowTop = (int)yrow;
 
285
                                        }
 
286
                                        
 
287
                                        // Draw the line text. Ignore header blocks, since they are drawn as labels in DrawCodeSegmentBorder
 
288
                                        
 
289
                                        if (block.Type != BlockType.Info) {
 
290
                                                layout.SetMarkup ("");
 
291
                                                layout.SetText (sb.ToString ());
 
292
                                                Gdk.GC gc;
 
293
                                                switch (block.Type) {
 
294
                                                        case BlockType.Removed: gc = removedGC; break;
 
295
                                                        case BlockType.Added: gc = addedGC; break;
 
296
                                                        case BlockType.Info: gc = infoGC; break;
 
297
                                                        default: gc = normalGC; break;
 
298
                                                }
 
299
                                                window.DrawLayout (gc, cell_area.X + 2 + LeftPaddingBlock, block.YStart, layout);
 
300
                                        }
 
301
                                        
 
302
                                        // Finally draw the change symbol at the left margin
 
303
                                        
 
304
                                        DrawChangeSymbol (ctx, cell_area.X + 1, cell_area.Width - 2, block);
176
305
                                }
177
 
                                window.DrawRectangle (widget.Style.DarkGC (Gtk.StateType.Prelight), false, cell_area.X, recty, cell_area.Width - 1, recth);
 
306
                                
 
307
                                // Finish the drawing of the code segment
 
308
                                if (lastCodeSegmentStart != null)
 
309
                                        DrawCodeSegmentBorder (infoGC, ctx, cell_area.X, cell_area.Width, lastCodeSegmentStart, lastCodeSegmentEnd, lines, widget, window);
 
310
                                
 
311
                                // Draw the source line number at the current selected line. It must be done at the end because it must
 
312
                                // be drawn over the source code text and segment borders.
 
313
                                if (selectedLineRowTop != -1)
 
314
                                        DrawLineBox (normalGC, ctx, ((Gtk.TreeView)widget).VisibleRect.Right - 4, selectedLineRowTop, selectedLine, widget, window);
 
315
                                
 
316
                                ((IDisposable)ctx).Dispose ();
178
317
                                removedGC.Dispose ();
179
318
                                addedGC.Dispose ();
180
319
                                infoGC.Dispose ();
181
320
                        } else {
 
321
                                // Rendering a normal text row
182
322
                                int y = cell_area.Y + (cell_area.Height - height)/2;
183
323
                                window.DrawLayout (widget.Style.TextGC (GetState(flags)), cell_area.X, y, layout);
184
324
                        }
185
325
                }
186
326
                
 
327
                bool IsChangeBlock (BlockType t)
 
328
                {
 
329
                        return t == BlockType.Added || t == BlockType.Removed;
 
330
                }
 
331
                
 
332
                class BlockInfo
 
333
                {
 
334
                        public BlockType Type;
 
335
                        public int YEnd;
 
336
                        public int YStart;
 
337
                        public int FirstLine;
 
338
                        public int LastLine;
 
339
                        public bool SectionStart;
 
340
                        public bool SectionEnd;
 
341
                        public int SourceLineStart;
 
342
                }
 
343
                
 
344
                enum BlockType
 
345
                {
 
346
                        Info,
 
347
                        Added,
 
348
                        Removed,
 
349
                        Unchanged
 
350
                }
 
351
                
 
352
                void DrawCodeSegmentBorder (Gdk.GC gc, Cairo.Context ctx, double x, int width, BlockInfo firstBlock, BlockInfo lastBlock, string[] lines, Gtk.Widget widget, Gdk.Drawable window)
 
353
                {
 
354
                        int shadowSize = 2;
 
355
                        int spacing = 4;
 
356
                        int bottomSpacing = (lineHeight - spacing) / 2;
 
357
                        
 
358
                        ctx.Rectangle (x + shadowSize + 0.5, firstBlock.YStart + bottomSpacing + spacing - shadowSize + 0.5, width - shadowSize*2, shadowSize);
 
359
                        ctx.Color = new Cairo.Color (0.9, 0.9, 0.9);
 
360
                        ctx.LineWidth = 1;
 
361
                        ctx.Fill ();
 
362
                        
 
363
                        ctx.Rectangle (x + shadowSize + 0.5, lastBlock.YEnd + bottomSpacing + 0.5, width - shadowSize*2, shadowSize);
 
364
                        ctx.Color = new Cairo.Color (0.9, 0.9, 0.9);
 
365
                        ctx.Fill ();
 
366
                        
 
367
                        ctx.Rectangle (x + 0.5, firstBlock.YStart + bottomSpacing + spacing + 0.5, width, lastBlock.YEnd - firstBlock.YStart - spacing);
 
368
                        ctx.Color = new Cairo.Color (0.7,0.7,0.7);
 
369
                        ctx.Stroke ();
 
370
                        
 
371
                        string text = lines[firstBlock.FirstLine].Replace ("@","").Replace ("-","");
 
372
                        text = "<span size='x-small'>" + text.Replace ("+","</span><span size='small'>➜</span><span size='x-small'> ") + "</span>";
 
373
                        
 
374
                        layout.SetText ("");
 
375
                        layout.SetMarkup (text);
 
376
                        int tw,th;
 
377
                        layout.GetPixelSize (out tw, out th);
 
378
                        th--;
 
379
                        
 
380
                        int dy = (lineHeight - th) / 2;
 
381
                        
 
382
                        ctx.Rectangle (x + 2 + LeftPaddingBlock - 1 + 0.5, firstBlock.YStart + dy - 1 + 0.5, tw + 2, th + 2);
 
383
                        ctx.LineWidth = 1;
 
384
                        ctx.Color = widget.Style.Base (Gtk.StateType.Normal).ToCairoColor ();
 
385
                        ctx.FillPreserve ();
 
386
                        ctx.Color = new Cairo.Color (0.7, 0.7, 0.7);
 
387
                        ctx.Stroke ();
 
388
                                
 
389
                        window.DrawLayout (gc, (int)(x + 2 + LeftPaddingBlock), firstBlock.YStart + dy, layout);
 
390
                }
 
391
                
 
392
                void DrawLineBox (Gdk.GC gc, Cairo.Context ctx, int right, int top, int line, Gtk.Widget widget, Gdk.Drawable window)
 
393
                {
 
394
                        layout.SetText ("");
 
395
                        layout.SetMarkup ("<small>" + line.ToString () + "</small>");
 
396
                        int tw,th;
 
397
                        layout.GetPixelSize (out tw, out th);
 
398
                        th--;
 
399
                        
 
400
                        int dy = (lineHeight - th) / 2;
 
401
                        
 
402
                        ctx.Rectangle (right - tw - 2 + 0.5, top + dy - 1 + 0.5, tw + 2, th + 2);
 
403
                        ctx.LineWidth = 1;
 
404
                        ctx.Color = widget.Style.Base (Gtk.StateType.Normal).ToCairoColor ();
 
405
                        ctx.FillPreserve ();
 
406
                        ctx.Color = new Cairo.Color (0.7, 0.7, 0.7);
 
407
                        ctx.Stroke ();
 
408
 
 
409
                        window.DrawLayout (gc, right - tw - 1, top + dy, layout);
 
410
                }
 
411
                
 
412
                void DrawBlockBg (Cairo.Context ctx, double x, int width, BlockInfo block)
 
413
                {
 
414
                        if (!IsChangeBlock (block.Type))
 
415
                                return;
 
416
                        
 
417
                        x += 0.5;
 
418
                        Gdk.Color color = block.Type == BlockType.Added ? baseAddColor : baseRemoveColor;
 
419
                        double y = block.YStart + 0.5;
 
420
                        int height = block.YEnd - block.YStart;
 
421
                        
 
422
                        double markerx = x + LeftPaddingBlock - 0.5;
 
423
                        double rd = RoundedSectionRadius;
 
424
                        if (block.SectionStart) {
 
425
                                ctx.Arc (x + rd, y + rd, rd, 180 * (Math.PI / 180), 270 * (Math.PI / 180));
 
426
                                ctx.LineTo (markerx, y);
 
427
                        } else {
 
428
                                ctx.MoveTo (markerx, y);
 
429
                        }
 
430
                        
 
431
                        ctx.LineTo (markerx, y + height);
 
432
                        
 
433
                        if (block.SectionEnd) {
 
434
                                ctx.LineTo (x + rd, y + height);
 
435
                                ctx.Arc (x + rd, y + height - rd, rd, 90 * (Math.PI / 180), 180 * (Math.PI / 180));
 
436
                        } else {
 
437
                                ctx.LineTo (x, y + height);
 
438
                        }
 
439
                        if (block.SectionStart) {
 
440
                                ctx.LineTo (x, y + rd);
 
441
                        } else {
 
442
                                ctx.LineTo (x, y);
 
443
                        }
 
444
                        ctx.Color = color.AddLight (0.1).ToCairoColor ();
 
445
                        ctx.Fill ();
 
446
                        
 
447
                        ctx.Rectangle (markerx, y, width - markerx, height);
 
448
                        using (Cairo.Gradient pat = new Cairo.LinearGradient (x, y, x + width, y)) {
 
449
                                pat.AddColorStop (0, color.AddLight (0.21).ToCairoColor ());
 
450
                                pat.AddColorStop (1, color.AddLight (0.3).ToCairoColor ());
 
451
                                ctx.Pattern = pat;
 
452
                                ctx.Fill ();
 
453
                        }
 
454
                }
 
455
                
 
456
                void DrawChangeSymbol (Cairo.Context ctx, double x, int width, BlockInfo block)
 
457
                {
 
458
                        if (!IsChangeBlock (block.Type))
 
459
                                return;
 
460
                        
 
461
                        Gdk.Color color = block.Type == BlockType.Added ? baseAddColor : baseRemoveColor;
 
462
 
 
463
                        int ssize = 8;
 
464
                        int barSize = 3;
 
465
                        
 
466
                        if (ssize - 2 > lineHeight)
 
467
                                ssize = lineHeight - 2;
 
468
                        if (ssize <= 0)
 
469
                                return;
 
470
 
 
471
                        double inSize = (ssize / 2) - (barSize / 2);
 
472
                        double py = block.YStart + ((block.YEnd - block.YStart) / 2 - ssize / 2) + 0.5;
 
473
                        double px = x + (LeftPaddingBlock/2) - (ssize / 2) + 0.5;
 
474
                        
 
475
                        if (block.Type == BlockType.Added) {
 
476
                                ctx.MoveTo (px + inSize, py);
 
477
                                ctx.RelLineTo (barSize, 0);
 
478
                                ctx.RelLineTo (0, inSize);
 
479
                                ctx.RelLineTo (inSize, 0);
 
480
                                ctx.RelLineTo (0, barSize);
 
481
                                ctx.RelLineTo (-inSize, 0);
 
482
                                ctx.RelLineTo (0, inSize);
 
483
                                ctx.RelLineTo (-barSize, 0);
 
484
                                ctx.RelLineTo (0, -inSize);
 
485
                                ctx.RelLineTo (-inSize, 0);
 
486
                                ctx.RelLineTo (0, -barSize);
 
487
                                ctx.RelLineTo (inSize, 0);
 
488
                                ctx.RelLineTo (0, -inSize);
 
489
                                ctx.ClosePath ();
 
490
                        } else {
 
491
                                ctx.MoveTo (px, py + inSize);
 
492
                                ctx.RelLineTo (ssize, 0);
 
493
                                ctx.RelLineTo (0, barSize);
 
494
                                ctx.RelLineTo (-ssize, 0);
 
495
                                ctx.RelLineTo (0, -barSize);
 
496
                                ctx.ClosePath ();
 
497
                        }
 
498
                        
 
499
                        ctx.Color = color.ToCairoColor ();
 
500
                        ctx.FillPreserve ();
 
501
                        ctx.Color = color.AddLight (-0.2).ToCairoColor ();;
 
502
                        ctx.LineWidth = 1;
 
503
                        ctx.Stroke ();
 
504
                }
 
505
                
187
506
                public override void GetSize (Widget widget, ref Rectangle cell_area, out int x_offset, out int y_offset, out int c_width, out int c_height)
188
507
                {
189
508
                        x_offset = y_offset = 0;