public void Render (Cairo.Context context, StatusArea.RenderArg arg) { context.CachedDraw (surface: ref backgroundSurface, region: arg.Allocation, draw: (c, o) => DrawBackground (c, new Gdk.Rectangle (0, 0, arg.Allocation.Width, arg.Allocation.Height))); if (arg.BuildAnimationOpacity > 0.001f) DrawBuildEffect (context, arg.Allocation, arg.BuildAnimationProgress, arg.BuildAnimationOpacity); if (arg.ErrorAnimationProgress > 0.001 && arg.ErrorAnimationProgress < .999) { DrawErrorAnimation (context, arg); } DrawBorder (context, arg.Allocation); if (arg.HoverProgress > 0.001f) { context.Clip (); int x1 = arg.Allocation.X + arg.MousePosition.X - 200; int x2 = x1 + 400; using (Cairo.LinearGradient gradient = new LinearGradient (x1, 0, x2, 0)) { Cairo.Color targetColor = Styles.StatusBarFill1Color; Cairo.Color transparentColor = targetColor; targetColor.A = .7; transparentColor.A = 0; targetColor.A = .7 * arg.HoverProgress; gradient.AddColorStop (0.0, transparentColor); gradient.AddColorStop (0.5, targetColor); gradient.AddColorStop (1.0, transparentColor); context.Pattern = gradient; context.Rectangle (x1, arg.Allocation.Y, x2 - x1, arg.Allocation.Height); context.Fill (); } context.ResetClip (); } else { context.NewPath (); } int progress_bar_x = arg.ChildAllocation.X; int progress_bar_width = arg.ChildAllocation.Width; if (arg.CurrentPixbuf != null) { int y = arg.Allocation.Y + (arg.Allocation.Height - arg.CurrentPixbuf.Height) / 2; Gdk.CairoHelper.SetSourcePixbuf (context, arg.CurrentPixbuf, arg.ChildAllocation.X, y); context.Paint (); progress_bar_x += arg.CurrentPixbuf.Width + Styles.ProgressBarOuterPadding; progress_bar_width -= arg.CurrentPixbuf.Width + Styles.ProgressBarOuterPadding; } int center = arg.Allocation.Y + arg.Allocation.Height / 2; Gdk.Rectangle progressArea = new Gdk.Rectangle (progress_bar_x, center - Styles.ProgressBarHeight / 2, progress_bar_width, Styles.ProgressBarHeight); if (arg.ShowProgressBar || arg.ProgressBarAlpha > 0) { DrawProgressBar (context, arg.ProgressBarFraction, progressArea, arg); ClipProgressBar (context, progressArea); } int text_x = progress_bar_x + Styles.ProgressBarInnerPadding; int text_width = progress_bar_width - (Styles.ProgressBarInnerPadding * 2); double textTweenValue = arg.TextAnimationProgress; if (arg.LastText != null) { double opacity = Math.Max (0.0f, 1.0f - textTweenValue); DrawString (arg.LastText, arg.LastTextIsMarkup, context, text_x, center - (int)(textTweenValue * arg.Allocation.Height * 0.3), text_width, opacity, arg.Pango, arg); } if (arg.CurrentText != null) { DrawString (arg.CurrentText, arg.CurrentTextIsMarkup, context, text_x, center + (int)((1.0f - textTweenValue) * arg.Allocation.Height * 0.3), text_width, Math.Min (textTweenValue, 1.0), arg.Pango, arg); } if (arg.ShowProgressBar || arg.ProgressBarAlpha > 0) context.ResetClip (); }
void DrawErrorAnimation (Cairo.Context context, StatusArea.RenderArg arg) { const int surfaceWidth = 2000; double opacity; int progress; if (arg.ErrorAnimationProgress < .5f) { progress = (int) (arg.ErrorAnimationProgress * arg.Allocation.Width * 2.4); opacity = 1.0d; } else { progress = (int) (arg.ErrorAnimationProgress * arg.Allocation.Width * 2.4); opacity = 1.0d - (arg.ErrorAnimationProgress - .5d) * 2; } LayoutRoundedRectangle (context, arg.Allocation); context.Clip (); context.CachedDraw (surface: ref errorSurface, position: new Gdk.Point (arg.Allocation.X - surfaceWidth + progress, arg.Allocation.Y), size: new Gdk.Size (surfaceWidth, arg.Allocation.Height), opacity: (float)opacity, draw: (c, o) => { // The smaller the pixel range of our gradient the less error there will be in it. using (var lg = new LinearGradient (surfaceWidth - 250, 0, surfaceWidth, 0)) { lg.AddColorStop (0.00, Styles.WithAlpha (Styles.StatusBarErrorColor, 0.15 * o)); lg.AddColorStop (0.10, Styles.WithAlpha (Styles.StatusBarErrorColor, 0.15 * o)); lg.AddColorStop (0.88, Styles.WithAlpha (Styles.StatusBarErrorColor, 0.30 * o)); lg.AddColorStop (1.00, Styles.WithAlpha (Styles.StatusBarErrorColor, 0.00 * o)); c.Pattern = lg; c.Paint (); } }); context.ResetClip (); }