1
// DockArea_Rendering.cs
3
// Copyright (C) 2009 GNOME Do
5
// This program is free software: you can redistribute it and/or modify
6
// it under the terms of the GNU General Public License as published by
7
// the Free Software Foundation, either version 3 of the License, or
8
// (at your option) any later version.
10
// This program is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
// GNU General Public License for more details.
15
// You should have received a copy of the GNU General Public License
16
// along with this program. If not, see <http://www.gnu.org/licenses/>.
20
using System.Collections.Generic;
29
using Do.Interface.CairoUtils;
30
using Do.Interface.Wink;
33
using Docky.Utilities;
34
using Docky.Interface.Painters;
36
namespace Docky.Interface
40
internal partial class DockArea
42
class PreviousRenderData {
43
public bool ForceFullRender { get; set; }
44
public Gdk.Point LastCursor { get; set; }
45
public double ZoomIn { get; set; }
46
public List<AbstractDockItem> RenderItems { get; private set; }
48
public PreviousRenderData ()
50
RenderItems = new List<AbstractDockItem> ();
54
public static DateTime RenderTime { get; private set; }
56
const int IndicatorSize = 9;
57
const int UrgentIndicatorSize = 12;
59
Dictionary<IDockPainter, Surface> painter_surfaces;
60
bool next_fast_render, first_render_set, last_no_render, rendering;
61
double? zoom_in_buffer;
63
Surface backbuffer, input_area_buffer, dock_icon_buffer;
64
Surface indicator, urgent_indicator;
65
IDockPainter painter, last_painter;
67
DateTime LastOverlapCheck { get; set; }
69
DateTime ActiveIconChangeTime { get; set; }
71
DateTime FirstRenderTime { get; set; }
73
PreviousRenderData RenderData { get; set; }
76
/// Determines if the current rendering state allows for a fast render
80
bool result = next_fast_render && !RenderData.ForceFullRender && RenderData.RenderItems.Count == 0;
81
next_fast_render = RenderData.ZoomIn == 1 && ZoomIn == 1 && !DnDTracker.DragResizing;
87
/// Determines if the current rendering state allows for a "no" render
91
bool result = DockPreferences.ZoomEnabled &&
92
!RenderData.ForceFullRender &&
93
RenderData.RenderItems.Count == 0 &&
94
RenderData.ZoomIn == 0 &&
95
!DnDTracker.GtkDragging &&
96
!DnDTracker.DragResizing &&
98
bool tmp = last_no_render;
99
last_no_render = result;
100
return result && tmp;
105
/// Determins if a single item only needs to be redrawn and updated (usually caused by an update request)
107
bool SingleItemRender {
109
return !RenderData.ForceFullRender &&
110
RenderData.ZoomIn == 0 &&
112
RenderData.RenderItems.Count == 1;
116
bool AnimationRequiresRender {
118
return AnimationState [Animations.IconInsert] ||
119
AnimationState [Animations.UrgencyChanged] ||
120
AnimationState [Animations.Bounce] ||
121
AnimationState [Animations.InputModeChanged];
126
/// Determins the opacity of the icons on the normal dock
128
double DockIconOpacity {
130
if (SummonTime < RenderTime - interface_change_time) {
131
if (PainterOverlayVisible)
136
double total_time = (RenderTime - interface_change_time).TotalMilliseconds;
137
if (PainterOverlayVisible) {
138
return 1 - (total_time / SummonTime.TotalMilliseconds);
140
return total_time / SummonTime.TotalMilliseconds;
146
/// Get autohide state
151
switch (DockPreferences.AutohideType) {
152
case AutohideType.Autohide:
153
hidden = !CursorIsOverDockArea;
155
case AutohideType.Intellihide:
156
hidden = !CursorIsOverDockArea && WindowIntersectingOther;
164
/// Icon Size used for the dock
167
get { return DockPreferences.IconSize; }
170
IDockPainter LastPainter {
175
if (last_painter == value)
177
if (last_painter != null)
178
last_painter.PaintNeeded -= HandlePaintNeeded;
179
last_painter = value;
183
IDockPainter Painter {
188
if (painter == value)
190
LastPainter = painter;
193
painter.PaintNeeded += HandlePaintNeeded;
198
/// The opacity of the painter surface
200
double PainterOpacity {
201
get { return 1 - DockIconOpacity; }
205
/// The overall offset of the dock as a whole
210
// we never hide in these conditions
211
if (DockPreferences.AutohideType == AutohideType.None || DnDTracker.DragResizing || PainterOpacity == 1) {
212
if ((RenderTime - FirstRenderTime) > SummonTime)
214
offset = 1 - Math.Min (1, (DateTime.UtcNow - FirstRenderTime).TotalMilliseconds / SummonTime.TotalMilliseconds);
215
return (int) (offset * PositionProvider.DockHeight * 1.5);
218
if (PainterOpacity > 0) {
222
offset = Math.Min (1, (RenderTime - showhide_time).TotalMilliseconds /
223
SummonTime.TotalMilliseconds);
224
offset = Math.Min (offset, Math.Min (1,
225
(RenderTime - interface_change_time)
226
.TotalMilliseconds / SummonTime.TotalMilliseconds));
229
if (PainterOverlayVisible)
232
offset = Math.Min (1, (RenderTime - showhide_time).TotalMilliseconds /
233
SummonTime.TotalMilliseconds);
237
return (int) (offset * PositionProvider.DockHeight * 1.5);
242
/// Returns the zoom in percentage (0 through 1)
246
if (DnDTracker.InternalDragActive)
249
// we buffer this value during renders since it will be checked many times and we dont need to
250
// recalculate it each time
251
if (zoom_in_buffer.HasValue && rendering) {
252
return zoom_in_buffer.Value;
255
double zoom = Math.Min (1, (RenderTime - enter_time).TotalMilliseconds /
256
BaseAnimationTime.TotalMilliseconds);
257
if (CursorIsOverDockArea) {
258
if (DockPreferences.AutohideType == AutohideType.Autohide ||
259
(DockPreferences.AutohideType == AutohideType.Intellihide && WindowIntersectingOther))
265
if (PainterOverlayVisible)
266
zoom = zoom * DockIconOpacity;
269
zoom_in_buffer = zoom;
275
void BuildRendering ()
277
RenderData = new PreviousRenderData ();
278
painter_surfaces = new Dictionary<IDockPainter, Surface> ();
281
void HandleActiveWindowChanged (object o, ActiveWindowChangedArgs args)
283
RequestFullRender ();
287
void HandleIntersectionChanged (object sender, EventArgs e)
289
if (DockPreferences.AutohideType == AutohideType.Intellihide && !CursorIsOverDockArea) {
290
showhide_time = UpdateTimeStamp (showhide_time, SummonTime);
295
void DrawDock (Context cr)
297
Gdk.Rectangle dockArea = GetDockArea ();
298
window.SetBackgroundBlur (dockArea);
300
DockBackgroundRenderer.RenderDockBackground (cr, dockArea);
302
IDockPainter dpaint = (Painter == null) ? LastPainter : Painter;
304
if (PainterOpacity > 0 && dpaint != null) {
305
Surface overlay_surface = GetOverlaySurface (cr);
307
using (Context input_cr = new Context (overlay_surface)) {
308
if (!dpaint.DoubleBuffer)
309
input_cr.AlphaFill ();
310
dpaint.Paint (input_cr, dockArea, Cursor);
313
cr.SetSource (overlay_surface);
314
cr.PaintWithAlpha (PainterOpacity);
317
bool isNotSummonTransition = PainterOpacity == 0 || !IsHidden || !DockPreferences.AutoHide;
318
if (DockIconOpacity > 0 && isNotSummonTransition) {
319
if (dock_icon_buffer == null)
320
dock_icon_buffer = cr.Target.CreateSimilar (cr.Target.Content, Width, Height);
322
using (Context input_cr = new Context (dock_icon_buffer)) {
323
DrawIcons (input_cr, dockArea);
326
int offset = (int) (IconSize * (1 - DockIconOpacity));
327
Gdk.Point iconBufferLocation = new Gdk.Point (0, 0).RelativeMovePoint (offset, RelativeMove.Outward);
328
cr.SetSource (dock_icon_buffer, iconBufferLocation.X, iconBufferLocation.Y);
329
cr.PaintWithAlpha (DockIconOpacity);
333
void DrawIcons (Context cr, Gdk.Rectangle dockArea)
335
bool animationRequired = AnimationRequiresRender;
336
int index = PositionProvider.IndexAtPosition (Cursor);
338
if (CanFastRender && !animationRequired) {
339
// We are in a zoomed in state where we can render only those icons which are moving around
340
// on screen. This only happens when zoom is enabled
341
Gdk.Rectangle renderArea = Gdk.Rectangle.Zero;
343
int startItemPosition;
344
startItemPosition = Math.Min (Cursor.X, RenderData.LastCursor.X) -
345
(DockPreferences.ZoomSize / 2 + DockPreferences.IconSize);
348
endItemPosition = Math.Max (Cursor.X, RenderData.LastCursor.X) +
349
(DockPreferences.ZoomSize / 2 + DockPreferences.IconSize);
351
int startItem = PositionProvider.IndexAtPosition (startItemPosition, Cursor.Y);
352
int endItem = PositionProvider.IndexAtPosition (endItemPosition, Cursor.Y);
354
int maxClamp = DockItems.Count - 1;
356
startItem = startItem == -1 ? 0 : startItem;
357
endItem = endItem == -1 ? maxClamp : endItem;
359
// these are special cases that we dont want to fall on edges (unless they are the clamps... clamps)
360
if (startItem > 0 && DockItems [startItem - 1].ContainsFocusedWindow)
361
startItem = Math.Max (0, startItem - 1);
363
if (DockItems [endItem].ContainsFocusedWindow)
364
endItem = Math.Min (maxClamp, endItem + 1);
366
PointD firstPosition, lastPosition;
367
double firstZoom, lastZoom;
369
// set up our X value
370
if (startItem == 0) {
371
renderArea.X = dockArea.X;
373
IconZoomedPosition (startItem, out firstPosition, out firstZoom);
374
renderArea.X = (int) (firstPosition.X - (DockItems [startItem].Width * firstZoom) / 2) - 2;
377
if (endItem == maxClamp) {
378
renderArea.Width = dockArea.Width - (renderArea.X - dockArea.X);
380
IconZoomedPosition (endItem, out lastPosition, out lastZoom);
382
// Add/Sub 2 to provide a good "buffer" into the dead zone between icons
383
renderArea.Width = (int) (lastPosition.X + (DockItems [endItem].Width * lastZoom) / 2) + 2 - renderArea.X;
386
renderArea.Height = Height;
388
cr.Rectangle (renderArea.X, renderArea.Y, renderArea.Width, renderArea.Height);
390
// clear the areas outside the dock area
391
cr.Rectangle (0, dockArea.Y, dockArea.X, dockArea.Height);
392
cr.Rectangle (dockArea.X + dockArea.Width, dockArea.Y, Width - (dockArea.X + dockArea.Width), dockArea.Height);
393
switch (DockPreferences.Orientation) {
394
case DockOrientation.Bottom:
395
cr.Rectangle (0, 0, Width, Height - dockArea.Height);
397
case DockOrientation.Top:
398
cr.Rectangle (0, dockArea.Height, Width, Height - dockArea.Height);
401
cr.Operator = Operator.Clear;
403
cr.Operator = Operator.Over;
405
for (int i = startItem; i <= endItem; i++) {
408
DrawIcon (cr, i, false);
410
// draw hovered item last, for the sake of making sure its on top in certain animations
411
if (index >= startItem && index <= endItem)
412
DrawIcon (cr, index, true);
414
} else if (SingleItemRender && !animationRequired) {
415
// A single icon for some reason needs to be drawn again. This is more or less
416
// a special case of a fast render
417
Gdk.Rectangle renderArea = Gdk.Rectangle.Zero;
418
PointD firstPosition;
421
AbstractDockItem single = RenderData.RenderItems [0];
422
int singleIndex = DockItems.IndexOf (single);
424
// set up our X value
425
IconZoomedPosition (singleIndex, out firstPosition, out firstZoom);
426
renderArea.X = (int) (firstPosition.X - (single.Width * firstZoom) / 2) - 2;
427
renderArea.Width = (int) (firstPosition.X + (single.Width * firstZoom) / 2) + 2 - renderArea.X;
429
renderArea.Height = Height;
431
cr.Rectangle (renderArea.X, renderArea.Y, renderArea.Width, renderArea.Height);
433
// clear the areas outside the dock area
434
cr.Rectangle (0, dockArea.Y, dockArea.X, dockArea.Height);
435
cr.Rectangle (dockArea.X + dockArea.Width, dockArea.Y, Width - (dockArea.X + dockArea.Width), dockArea.Height);
436
switch (DockPreferences.Orientation) {
437
case DockOrientation.Bottom:
438
cr.Rectangle (0, 0, Width, Height - dockArea.Height);
440
case DockOrientation.Top:
441
cr.Rectangle (0, dockArea.Height, Width, Height - dockArea.Height);
444
cr.Operator = Operator.Clear;
446
cr.Operator = Operator.Over;
448
DrawIcon (cr, singleIndex, index == singleIndex);
449
} else if (animationRequired || !CanNoRender) {
450
// we didn't fast render or single icon render, but we can't not render, so we have to do it the slow way
453
for (int i = 0; i < DockItems.Count; i++) {
456
DrawIcon (cr, i, false);
458
// draw hovered item last, for the sake of making sure its on top in certain animations
459
if (index >= 0 && index < DockItems.Count)
460
DrawIcon (cr, index, true);
463
RenderData.LastCursor = Cursor;
464
RenderData.ZoomIn = ZoomIn;
465
RenderData.ForceFullRender = false;
466
RenderData.RenderItems.Clear ();
469
void DrawIcon (Context cr, int icon, bool hovered)
471
// Don't draw the icon we are dragging around
472
if (DnDTracker.GtkDragging && !DnDTracker.DragState.IsFinished) {
473
int item = DockItems.IndexOf (DnDTracker.DragState.DragItem);
474
if (item == icon && DockServices.ItemsService.ItemCanBeMoved (item))
478
AbstractDockItem dockItem = DockItems [icon];
479
if (dockItem == null) return; //happens?
483
IconZoomedPosition (icon, out center, out zoom);
485
// This gives the actual x,y coordinates of the icon
486
PointD iconPosition = new PointD (center.X - zoom * (dockItem.Width >> 1),
487
center.Y - zoom * (dockItem.Width >> 1));
489
ClickAnimationType animationType = IconAnimation (icon);
491
// we will set this flag now
492
if (animationType == ClickAnimationType.Bounce) {
494
double delta = Math.Abs (LaunchBounceHeight * Math.Sin
495
(dockItem.TimeSinceClick.TotalMilliseconds * Math.PI /
496
(BounceTime.TotalMilliseconds / 2)));
498
iconPosition = iconPosition.RelativeMovePoint (delta, RelativeMove.Inward);
500
if (RenderTime - dockItem.AttentionRequestStartTime < BounceTime) {
501
double urgentMs = (RenderTime - dockItem.AttentionRequestStartTime)
504
double delta = UrgentBounceHeight * Math.Sin (urgentMs * Math.PI / (BounceTime.TotalMilliseconds));
505
iconPosition = iconPosition.RelativeMovePoint (delta, RelativeMove.Inward);
510
Surface iconSurface = dockItem.GetIconSurface (cr.Target, (int) (IconSize * zoom), out size);
512
if (dockItem.ScalingType != ScalingType.None) {
515
if (size == DockPreferences.FullIconSize) {
516
scale = zoom / DockPreferences.IconQuality;
517
} else if (size == DockPreferences.IconSize) {
520
Do.Platform.Log<DockArea>.Error ("Icon provided in unexpected size");
524
if (dockItem.ContainsFocusedWindow) {
525
double intenseS = 0.8;
527
double xHigh = iconPosition.X - 1.5;
528
double yHigh = MinimumDockArea.Y;
529
double widthHigh = dockItem.Width * zoom + 3;
530
cr.Rectangle (xHigh, yHigh, widthHigh, DockHeight);
533
if (DockPreferences.Orientation == DockOrientation.Bottom) {
534
lg = new LinearGradient (0, yHigh + DockHeight, 0, yHigh);
536
lg = new LinearGradient (0, yHigh, 0, yHigh + DockHeight);
539
Cairo.Color average = dockItem.AverageColor ();
540
lg.AddColorStop (0, new Cairo.Color (average.R, average.G, average.B, .3));
541
lg.AddColorStop (1, new Cairo.Color (average.R, average.G, average.B, 0));
546
if (DockPreferences.Orientation == DockOrientation.Bottom)
549
cr.MoveTo (xHigh, yHigh);
550
cr.LineTo (xHigh, yHigh + DockHeight - 2);
551
cr.MoveTo (xHigh + widthHigh, yHigh);
552
cr.LineTo (xHigh + widthHigh, yHigh + DockHeight - 2);
554
if (DockPreferences.Orientation == DockOrientation.Bottom)
555
cr.Translate (0, -2);
557
cr.Color = new Cairo.Color (intenseS, intenseS, intenseS, .3);
563
cr.Scale (scale, scale);
564
// we need to multiply x and y by 1 / scale to undo the scaling of the context. We only want to zoom
565
// the icon, not move it around.
567
double fadeInOpacity = Math.Min (dockItem.TimeSinceAdd.TotalMilliseconds /
568
InsertAnimationTime.TotalMilliseconds, 1);
569
cr.SetSource (iconSurface,
570
iconPosition.X / scale, iconPosition.Y / scale);
571
cr.PaintWithAlpha (fadeInOpacity);
573
bool shade_light = DnDTracker.GtkDragging && !DnDTracker.PreviewIsDesktopFile && CursorIsOverDockArea &&
574
dockItem.IsAcceptingDrops && icon == PositionProvider.IndexAtPosition (Cursor);
576
bool shade_dark = animationType == ClickAnimationType.Darken;
577
if (shade_dark || shade_light) {
578
cr.Rectangle (iconPosition.X / scale, iconPosition.Y / scale,
579
DockPreferences.FullIconSize, DockPreferences.FullIconSize);
582
cr.Color = new Cairo.Color (.9, .95, 1, .5);
584
double opacity = (BounceTime - dockItem.TimeSinceClick).TotalMilliseconds /
585
BounceTime.TotalMilliseconds - .7;
587
cr.Color = new Cairo.Color (0, 0, 0, opacity);
590
cr.Operator = Operator.Atop;
592
cr.Operator = Operator.Over;
596
cr.IdentityMatrix ();
598
// since these dont scale, we have some extra work to do to keep them
600
cr.SetSource (iconSurface,
601
(int) iconPosition.X, (int) center.Y - (dockItem.Height >> 1));
605
if (0 < dockItem.WindowCount || dockItem.NeedsAttention) {
607
switch (DockPreferences.Orientation) {
608
case DockOrientation.Bottom:
609
location = new Gdk.Point ((int) center.X, Height - 1);
611
case DockOrientation.Top:
613
location = new Gdk.Point ((int) center.X, 1);
616
DrawGlowIndicator (cr, location, dockItem.NeedsAttention, dockItem.WindowCount);
619
// we do a null check here to allow things like separator items to supply
620
// a null. This allows us to draw nothing at all instead of rendering a
621
// blank surface (which is slow)
622
if (!PopupMenu.Visible && hovered &&
623
CursorIsOverDockArea && dockItem.GetTextSurface (cr.Target) != null &&
624
!DnDTracker.GtkDragging && !DnDTracker.DragResizing) {
627
Surface textSurface = dockItem.GetTextSurface (cr.Target);
628
textPoint.X = PositionProvider.IconUnzoomedPosition (icon).X - (dockItem.TextSurfaceSize.Width >> 1);
629
textPoint.X = Math.Max (0, Math.Min (Width - dockItem.TextSurfaceSize.Width, textPoint.X));
631
if (DockPreferences.Orientation == DockOrientation.Top)
632
textPoint.Y = (int) (DockPreferences.ZoomPercent * IconSize) + 10;
634
textPoint.Y = Height - (int) (DockPreferences.ZoomPercent * IconSize) - 38;
636
textSurface.Show (cr, textPoint.X, textPoint.Y);
640
void DrawGlowIndicator (Context cr, Gdk.Point location, bool urgent, int numberOfWindows)
642
if (DockPreferences.IndicateMultipleWindows && 1 < numberOfWindows) {
643
DrawSingleIndicator (cr, location.RelativeMovePoint (3, RelativeMove.RelativeLeft), urgent);
644
DrawSingleIndicator (cr, location.RelativeMovePoint (3, RelativeMove.RelativeRight), urgent);
645
} else if (0 < numberOfWindows || urgent) {
646
DrawSingleIndicator (cr, location, urgent);
650
void DrawSingleIndicator (Context cr, Gdk.Point location, bool urgent)
653
cr.SetSource (GetUrgentIndicator (cr.Target), location.X - UrgentIndicatorSize, location.Y - UrgentIndicatorSize);
655
cr.SetSource (GetIndicator (cr.Target), location.X - IndicatorSize, location.Y - IndicatorSize);
661
Gdk.Rectangle GetDockArea ()
665
// this method is more than somewhat slow on the complexity scale, we want to avoid doing it
666
// more than we have to. Further, when we do call it, we should always check for this shortcut.
667
if (DockIconOpacity == 0 || ZoomIn == 0)
668
rect = MinimumDockArea;
670
rect = PositionProvider.DockArea (ZoomIn, Cursor);
672
int minWidth = 10 * rect.Height;
673
int maxWidth = LayoutUtils.MonitorGeometry ().Width;
676
if (PainterOverlayVisible && Painter != null) {
677
dockWidth = Math.Min (Painter.Width, maxWidth);
678
} else if (!PainterOverlayVisible && LastPainter != null) {
679
dockWidth = Math.Min (LastPainter.Width, maxWidth);
681
dockWidth = Math.Max (rect.Width, minWidth);
684
if (rect.Width != dockWidth && DockIconOpacity < 1) {
685
int difference = dockWidth - rect.Width;
686
int alpha = (int) (difference * PainterOpacity);
694
Surface GetIndicator (Surface similar)
696
if (indicator == null) {
697
Style style = window.Style;
698
Gdk.Color color = style.Backgrounds [(int) StateType.Selected].SetMinimumValue (100);
700
indicator = similar.CreateSimilar (similar.Content, IndicatorSize * 2, IndicatorSize * 2);
701
Context cr = new Context (indicator);
703
double x = IndicatorSize;
707
cr.Arc (x, y, IndicatorSize, 0, Math.PI * 2);
709
RadialGradient rg = new RadialGradient (x, y, 0, x, y, IndicatorSize);
710
rg.AddColorStop (0, new Cairo.Color (1, 1, 1, 1));
711
rg.AddColorStop (.10, color.ConvertToCairo (1.0));
712
rg.AddColorStop (.20, color.ConvertToCairo (.60));
713
rg.AddColorStop (.25, color.ConvertToCairo (.25));
714
rg.AddColorStop (.50, color.ConvertToCairo (.15));
715
rg.AddColorStop (1.0, color.ConvertToCairo (0.0));
721
(cr as IDisposable).Dispose ();
726
Surface GetUrgentIndicator (Surface similar)
728
if (urgent_indicator == null) {
729
Style style = Docky.Interface.DockWindow.Window.Style;
730
Gdk.Color color = style.Backgrounds [(int) StateType.Selected];
734
r = (byte) ((color.Red) >> 8);
735
g = (byte) ((color.Green) >> 8);
736
b = (byte) ((color.Blue) >> 8);
737
Do.Interface.Util.Appearance.RGBToHSV (r, g, b, out h, out s, out v);
739
// see if the theme color is too close to red and if so use
741
if (h <= 45 || h >= 315)
742
color = new Cairo.Color (0.5, 0.6, 1.0, 1.0).ConvertToGdk ();
744
color = new Cairo.Color (1.0, 0.3, 0.3, 1.0).ConvertToGdk ();
746
urgent_indicator = similar.CreateSimilar (similar.Content, UrgentIndicatorSize * 2, UrgentIndicatorSize * 2);
747
Context cr = new Context (urgent_indicator);
749
double x = UrgentIndicatorSize;
753
cr.Arc (x, y, UrgentIndicatorSize, 0, Math.PI * 2);
755
RadialGradient rg = new RadialGradient (x, y, 0, x, y, UrgentIndicatorSize);
756
rg.AddColorStop (0, new Cairo.Color (1, 1, 1, 1));
757
rg.AddColorStop (.10, color.ConvertToCairo (1.0));
758
rg.AddColorStop (.20, color.ConvertToCairo (.60));
759
rg.AddColorStop (.35, color.ConvertToCairo (.35));
760
rg.AddColorStop (.50, color.ConvertToCairo (.25));
761
rg.AddColorStop (1.0, color.ConvertToCairo (0.0));
767
(cr as IDisposable).Dispose ();
769
return urgent_indicator;
772
ClickAnimationType IconAnimation (int icon)
774
return (DockItems [icon].TimeSinceClick < BounceTime) ?
775
DockItems [icon].AnimationType : ClickAnimationType.None;
778
void IconZoomedPosition (int icon, out PointD center, out double zoom)
780
PositionProvider.IconZoomedPosition (icon, ZoomIn, Cursor, out center, out zoom);
783
Surface GetOverlaySurface (Context similar)
785
if (Painter != null && Painter.DoubleBuffer) {
786
if (!painter_surfaces.ContainsKey (Painter))
787
painter_surfaces [Painter] = similar.Target.CreateSimilar (similar.Target.Content,
789
return painter_surfaces [Painter];
791
if (input_area_buffer == null)
792
input_area_buffer = similar.Target.CreateSimilar (similar.Target.Content,
794
return input_area_buffer;
798
protected override bool OnExposeEvent(EventExpose evnt)
804
zoom_in_buffer = null;
805
RenderTime = DateTime.UtcNow;
807
if (backbuffer == null) {
808
cr = Gdk.CairoHelper.Create (GdkWindow);
809
backbuffer = cr.Target.CreateSimilar (cr.Target.Content, Width, Height);
811
cr.Target.Destroy ();
812
(cr.Target as IDisposable).Dispose ();
813
(cr as IDisposable).Dispose ();
816
cr = new Cairo.Context (backbuffer);
819
if (DockServices.ItemsService.UpdatesEnabled) {
820
if (!first_render_set) {
821
FirstRenderTime = DateTime.UtcNow;
822
first_render_set = true;
826
(cr as IDisposable).Dispose ();
828
cr = Gdk.CairoHelper.Create (GdkWindow);
830
int vert = VerticalOffset;
831
Gdk.Point finalTarget = new Gdk.Point (0, 0).RelativeMovePoint (vert, RelativeMove.Outward);
833
cr.SetSource (backbuffer, finalTarget.X, finalTarget.Y);
835
cr.Operator = Operator.Source;
838
cr.Target.Destroy ();
839
((IDisposable)cr.Target).Dispose ();
840
((IDisposable)cr).Dispose ();
846
protected override void OnStyleSet (Gtk.Style previous_style)
848
if (indicator != null) {
849
indicator.Destroy ();
853
if (urgent_indicator != null) {
854
urgent_indicator.Destroy ();
855
urgent_indicator = null;
858
RequestFullRender ();
860
base.OnStyleSet (previous_style);
863
void RequestIconRender (AbstractDockItem item)
865
if (RenderData != null) {
866
RenderData.RenderItems.Add (item);
870
void RequestFullRender ()
872
if (RenderData != null) {
873
RenderData.ForceFullRender = true;
879
if (backbuffer != null) {
880
backbuffer.Destroy ();
884
if (dock_icon_buffer != null) {
885
dock_icon_buffer.Destroy ();
886
dock_icon_buffer = null;
889
if (input_area_buffer != null) {
890
input_area_buffer.Destroy ();
891
input_area_buffer = null;
894
if (painter_surfaces != null) {
895
foreach (Surface sr in painter_surfaces.Values) {
898
painter_surfaces.Clear ();
901
RequestFullRender ();