public static void Paint <TState, TParam>(Graphics graphics, Rectangle bounds, PaintAction <TState, TParam> paintAction, TState currentState, TParam data) { using (var g = new SafeDCHandle(graphics)) using (var bp = new BufferedPaintHandle(g, bounds)) paintAction(bp.Graphics, bounds, currentState, data); }
private void Control_Paint(object sender, PaintEventArgs e) { if (BufferedPaintSupported) { var stateChanged = !Equals(currentState, newState); using (var hdc = new SafeDCHandle(e.Graphics)) { if (!hdc.IsInvalid) { // see if this paint was generated by a soft-fade animation if (!BufferedPaintRenderAnimation(new HandleRef(Control, Control.Handle), hdc)) { var animParams = new BP_ANIMATIONPARAMS(BP_ANIMATIONSTYLE.BPAS_LINEAR); // get appropriate animation time depending on state transition (or 0 if unchanged) if (stateChanged) { var transition = Transitions.SingleOrDefault(x => Equals(x.FromState, currentState) && Equals(x.ToState, newState)); animParams.Duration = transition?.Duration ?? DefaultDuration; } using (var h = new BufferedPaintHandle(Control, hdc, Control.ClientRectangle, animParams, BP_PAINTPARAMS.NoClip)) { if (!h.IsInvalid) { if (h.SourceGraphics != null) { OnPaintVisualState(new BufferedPaintEventArgs <TState>(currentState, h.SourceGraphics)); } if (h.Graphics != null) { OnPaintVisualState(new BufferedPaintEventArgs <TState>(newState, h.Graphics)); } } else { currentState = newState; OnPaintVisualState(new BufferedPaintEventArgs <TState>(currentState, e.Graphics)); } } } } } } else { // buffered painting not supported, just paint using the current state currentState = newState; OnPaintVisualState(new BufferedPaintEventArgs <TState>(currentState, e.Graphics)); } }
public static void PaintAnimation <TState, TParam>(Graphics graphics, IWin32Window ctrl, Rectangle bounds, PaintAction <TState, TParam> paintAction, TState currentState, TState newState, GetDuration <TState> getDuration, TParam data) { try { if (System.Environment.OSVersion.Version.Major >= 6) { // If this handle is running with a different state, stop the animations Tuple <object, object> val; if (paintAnimationInstances.TryGetValue(ctrl.Handle, out val)) { if (!Equals(val.Item1, currentState) || !Equals(val.Item2, newState)) { BufferedPaintStopAllAnimations(new HandleRef(ctrl, ctrl.Handle)); System.Diagnostics.Debug.WriteLine("BufferedPaintStop."); paintAnimationInstances[ctrl.Handle] = new Tuple <object, object>(currentState, newState); } } else { paintAnimationInstances.Add(ctrl.Handle, new Tuple <object, object>(currentState, newState)); } using (var hdc = new SafeDCHandle(graphics)) { if (hdc.IsInvalid) { return; } // see if this paint was generated by a soft-fade animation if (BufferedPaintRenderAnimation(new HandleRef(ctrl, ctrl.Handle), hdc)) { paintAnimationInstances.Remove(ctrl.Handle); return; } var animParams = new BP_ANIMATIONPARAMS(BP_ANIMATIONSTYLE.BPAS_LINEAR, getDuration?.Invoke(currentState, newState) ?? 0); using (var h = new BufferedPaintHandle(ctrl, hdc, bounds, animParams, BP_PAINTPARAMS.NoClip)) { if (!h.IsInvalid) { if (h.SourceGraphics != null) { paintAction(h.SourceGraphics, bounds, currentState, data); } if (h.Graphics != null) { paintAction(h.Graphics, bounds, newState, data); } } else { // hdc.Dispose(); paintAction(graphics, bounds, newState, data); } } } } else { paintAction(graphics, bounds, newState, data); } } catch { } System.Diagnostics.Debug.WriteLine($"BufferedPaint state items = {paintAnimationInstances.Count}."); }