public override void Draw(GameTime time) { base.Draw(time); // FPS DrawFPS(time); // World neu zeichnen beim nächsten Draw ()-Aufruf world.Redraw = true; // Hier könnte man die Zeit von world.Draw () messen Action drawWorldAction = () => { world.Draw(time); world.SubComponents(time).OfType <DrawableScreenComponent> ().ForEach(comp => comp.Draw(time)); }; TimeSpan drawWorldTime = Profiler.Time(drawWorldAction); // und itemDisplayTime.InputText zuweisen zum darstellen itemDisplayTime.InputText = drawWorldTime.Milliseconds + " ms"; itemFPS.InputText = FPS.ToString(); }
/** DESTRUCTIVE, ASYNC */ public static ImageSurface GetThumbnail(string path) { try { Profiler pr = new Profiler ("GetThumbnail", 500); ImageSurface thumb = null; string thumbPath; if (path.StartsWith(ThumbDir)) { thumbPath = path; } else { thumbPath = NormalThumbDir + DirSepS + ThumbnailHash (path) + ".png"; if (FileExists (thumbPath) && (LastModified(path) >= LastModified(thumbPath))) Trash(thumbPath); } pr.Time ("ThumbnailHash"); if (!FileExists(thumbPath)) { if (!FileExists(ThumbDir)) new UnixDirectoryInfo(ThumbDir).Create (); if (!FileExists(NormalThumbDir)) new UnixDirectoryInfo(NormalThumbDir).Create (); if (CreateThumbnail(path, thumbPath, thumbSize)) { pr.Time ("create thumbnail"); thumb = new ImageSurface (thumbPath); } } else { thumb = new ImageSurface (thumbPath); if (thumb.Width > thumbSize || thumb.Height > thumbSize) { ImageSurface nthumb = ScaleDownSurface (thumb, thumbSize); thumb.Destroy (); thumb.Destroy (); thumb = nthumb; } } if (thumb == null || thumb.Width < 1 || thumb.Height < 1) { if (FileExists(thumbPath)) Trash(thumbPath); throw new ArgumentException (String.Format("Failed to thumbnail {0}",path), "path"); } pr.Time ("load as ImageSurface"); return thumb; } catch (Exception e) { LogError ("Thumbnailing failed for {0}: {1}", path, e); ImageSurface thumb = new ImageSurface (Format.ARGB32, 1, 1); using (Context cr = new Context(thumb)) { cr.Color = new Color (1,0,0); cr.Rectangle (0,0,2,2); cr.Fill (); } return thumb; } }
public static void DrawText(Context cr, string family, double fontSize, string text, Pango.Alignment alignment) { // return; lock (FontCache) { // LogError("DrawText {0}", text); Profiler p = new Profiler ("DrawText"); double w,h; Pango.Layout layout = GetLayout (cr, family, QuantizeFontSize(fontSize)); layout.SetText (text); layout.Alignment = alignment; layout.GetExtents(out pe, out le); p.Time ("GetExtents {0}", pe); w = (double)le.Width / (double)Pango.Scale.PangoScale; h = (double)le.Height / (double)Pango.Scale.PangoScale; if (alignment == Pango.Alignment.Right) { cr.RelMoveTo (-w, 0); } else if (alignment == Pango.Alignment.Center) { cr.RelMoveTo (-w/2, 0); } Pango.CairoHelper.ShowLayout (cr, layout); p.Time ("ShowLayout"); if (ShowTextExtents) { cr.Save (); PointD pt = cr.CurrentPoint; cr.MoveTo (pt.X, pt.Y); cr.RelLineTo(w, 0); cr.RelLineTo(0, h); cr.Operator = Operator.Over; cr.Color = new Color (1,0.5,1,0.5); cr.LineWidth = 0.5; cr.Stroke (); cr.MoveTo (pt.X, pt.Y); cr.Restore (); } cr.RelMoveTo (w, 0); } }
/** BLOCKING */ static Pango.Layout GetLayout(Context cr, string family, uint fontSize) { Profiler p = new Profiler ("GetFont"); if (layout == null) layout = Pango.CairoHelper.CreateLayout (cr); Pango.CairoHelper.UpdateLayout (cr, layout); layout.FontDescription = CreateFont (family, fontSize); p.Time ("Got font and created layout"); return layout; }
/** BLOCKING */ void CheckZoomNavigation(Context cr, uint width, uint height) { Profiler p = new Profiler ("CheckZoomNavigation"); cr.Save (); Rectangle r = Transform (cr, width, height); cr.Scale (1, Zoomer.Z); cr.Translate (0.0, Zoomer.Y); Covering c = Renderer.FindCovering(CurrentDirEntry, cr, r, 0); if (c.Directory.FullName != CurrentDirPath) { SetCurrentDir(c.Directory.FullName, false); Zoomer.SetZoom (0.0, c.Pan, c.Zoom); } cr.Restore (); p.Time ("Checked"); }
/** FAST */ protected override bool OnMotionNotifyEvent(Gdk.EventMotion e) { Profiler p = new Profiler ("OnMotionNotifyEvent", 10); SetCursor (e.State); p.Time("SetCursor"); bool left = (e.State & Gdk.ModifierType.Button1Mask) == Gdk.ModifierType.Button1Mask; bool middle = (e.State & Gdk.ModifierType.Button2Mask) == Gdk.ModifierType.Button2Mask; if (!left && !middle) panning = dragging = false; if (!Cancelled) { if (left || middle) { LastMotionTime = DateTime.Now; ThrowFrames.Add (new ThrowFrame(e.X, e.Y)); } if (middle) { dragging = true; panning = true; } if (left) { bool ctrl = (e.State & Gdk.ModifierType.ControlMask) == Gdk.ModifierType.ControlMask; dragging = dragging || ((Math.Abs(dragX - dragStartX) + Math.Abs(dragY - dragStartY)) > 4); panning = panning || !ctrl || (DragSourceEntry == CurrentDirEntry); if (!dragInProgress && !panning && dragging) { Gdk.DragAction action = Gdk.DragAction.Move; if ((e.State & Gdk.ModifierType.ShiftMask) == Gdk.ModifierType.ShiftMask) action = Gdk.DragAction.Copy; if ((e.State & Gdk.ModifierType.Mod1Mask) == Gdk.ModifierType.Mod1Mask) action = Gdk.DragAction.Ask; dragInProgress = true; Drag.Begin (this, new TargetList(targets), action, 1, e); SetCursor (e.State); Cancelled = true; ThrowVelocity = 0; ThrowFrames.Clear (); } } if (panning) { InteractionProfiler.Restart (); double dx = e.X - dragX; double dy = e.Y - dragY; using ( Context cr = new Context (EtcSurface) ) { if (middle) { ControlLineVisible = true; double z = Math.Pow((dx < 0 ? ZoomInSpeed : (1 / ZoomOutSpeed)), (Math.Abs(dx) / 50)); if (Height - e.Y < 50) ThrowVelocity = -(50 - (Height - e.Y)) / 2; else if (e.Y < 50 + FilesMarginTop) ThrowVelocity = (50 + FilesMarginTop - e.Y) / 2; else ThrowVelocity = 0; /* if (Width - e.X < 50) ZoomVelocity = Math.Pow((1/ZoomOutSpeed), (50 - (Width - e.X)) / 250); else if (e.X < 50) ZoomVelocity = Math.Pow(ZoomInSpeed, (50 - e.X) / 250); else*/ ZoomVelocity = 1; ZoomBy (cr, Width, Height, e.X, e.Y, z); PanBy (cr, Width, Height, dx, -dy); } else { ControlLineVisible = false; ThrowVelocity = 0; PanBy (cr, Width, Height, dx, dy); } } } } else { panning = false; } if (SillyFlare) { LimitedRedraw = true; } dragX = e.X; dragY = e.Y; flareTargetX = Width/2; flareTargetY = -100; p.Time("Handled"); return true; }
/** FAST */ protected override bool OnScrollEvent(Gdk.EventScroll e) { InteractionProfiler.Start (); Profiler p = new Profiler ("ScrollEvent", 10); if (e.Direction == Gdk.ScrollDirection.Up) { using (Context cr = new Context (EtcSurface)) ZoomToward (cr, Width, Height, e.X, e.Y); } if (e.Direction == Gdk.ScrollDirection.Down) { using (Context cr = new Context (EtcSurface)) ZoomAway (cr, Width, Height, e.X, e.Y); } p.Time("Handled"); return true; }
/** FAST */ protected override bool OnButtonPressEvent(Gdk.EventButton e) { Profiler p = new Profiler ("OnButtonPressEvent", 10); GrabFocus (); SetCursor (e.State); p.Time ("SetCursor"); dragStartX = dragX = e.X; dragStartY = dragY = e.Y; ZoomVelocity = 1; ThrowFrames.Clear (); ClickCancelled = Cancelled = false; if (ThrowVelocity != 0) ClickCancelled = true; ThrowVelocity = 0; if (e.Button == 1 || e.Button == 2) ThrowFrames.Add (new ThrowFrame(e.X, e.Y)); dragging = false; if (e.Button == 3) { int w, h; e.Window.GetSize (out w, out h); ContextClick ((uint)w, (uint)h, e.X, e.Y); } else if (e.Button == 1 && !dragging) { DoubleClick = (e.Type == Gdk.EventType.TwoButtonPress); } if (e.Button == 1) { int w, h; e.Window.GetSize (out w, out h); DragSourceEntry = FindHit((uint)w, (uint)h, e.X, e.Y, 8).Target; DragSourcePath = DragSourceEntry.FullName; } p.Time ("Handled"); return true; }
/** BLOCKING */ protected override bool OnButtonReleaseEvent(Gdk.EventButton e) { Profiler p = new Profiler ("OnButtonReleaseEvent", 10); GrabFocus (); SetCursor (e.State); p.Time ("SetCursor"); ZoomVelocity = 1; if (Cancelled) { Cancelled = DoubleClick = false; } else { if (e.Button == 1 && !dragging && !ClickCancelled) { InteractionProfiler.Start (); int w, h; e.Window.GetSize (out w, out h); AltKeyDown = (e.State & Gdk.ModifierType.Mod1Mask) == Gdk.ModifierType.Mod1Mask; CtrlKeyDown = (e.State & Gdk.ModifierType.ControlMask) == Gdk.ModifierType.ControlMask; ShiftKeyDown = (e.State & Gdk.ModifierType.ShiftMask) == Gdk.ModifierType.ShiftMask; if (AltKeyDown) ClearSelection (); using (Context scr = new Context (CachedSurface)) { scr.IdentityMatrix (); Click (scr, (uint)w, (uint)h, e.X, e.Y); } DoubleClick = false; } if (e.Button == 1 && ThrowFrames.Count > 0) { ThrowVelocity = 0; if (DateTime.Now.Subtract(LastMotionTime).TotalMilliseconds < 100) { ThrowFrames.Add (new ThrowFrame(e.X, e.Y)); int len = Math.Min(10, ThrowFrames.Count-1); double vy = 0; for (int i=ThrowFrames.Count-len; i<ThrowFrames.Count; i++) { vy += ThrowFrames[i].Y - ThrowFrames[i-1].Y; } vy /= len; // Helpers.LogDebug("ThrowFrames.Count: {0}, vy: {1}", ThrowFrames.Count, vy); if (Math.Abs(vy) > 5) { ThrowVelocity = vy*2; NeedRedraw = true; } } ThrowFrames.Clear (); } } if (e.Button == 1) { if (!dragInProgress) { DragSourceEntry = null; DragSourcePath = null; } dragInProgress = false; } if (e.Button == 2) { ControlLineVisible = false; NeedRedraw = true; } dragging = false; panning = panning && dragInProgress; p.Time ("Handled"); return true; }
public void SetCurrentDir(string dirname, bool resetZoom) { Profiler p = new Profiler (); dirLatencyProfiler.Restart (); FirstFrameOfDir = true; if (dirname != Helpers.RootDir) dirname = dirname.TrimEnd(Helpers.DirSepC); UnixDirectoryInfo d = new UnixDirectoryInfo (dirname); string odp = CurrentDirPath; CurrentDirPath = d.FullName; if (odp != CurrentDirPath) { if (CurrentDirEntry != null && CurrentDirEntry.InProgress) FSCache.CancelTraversal (); CurrentDirEntry = FSCache.FastGet (CurrentDirPath); FSCache.Watch (CurrentDirPath); } FSNeedRedraw = true; if (resetZoom) ResetZoom (); UpdateLayout (); p.Time("SetCurrentDir"); }
/** BLOCKING */ public List<ClickHit> FindHits(uint width, uint height, double x, double y) { Profiler p = new Profiler ("FindHits", 10); List<ClickHit> hits; using (Context cr = new Context (CachedSurface)) { cr.IdentityMatrix (); cr.Save(); Rectangle box = Transform (cr, width, height); cr.Scale (1, Zoomer.Z); cr.Translate (0.0, Zoomer.Y); hits = Renderer.Click (CurrentDirEntry, Prefixes, cr, box, x, y); hits.Add (new ClickHit(CurrentDirEntry, cr.Matrix.Yy)); cr.Restore (); } p.Time ("Found {0} hits", hits.Count); return hits; }
/* Drawing */ void DrawFrame(Context cr) { var fp = new Profiler ("DrawFrame"); int w, h; GdkWindow.GetSize (out w, out h); fp.Time ("Window.GetSize"); double x = dragX, y = dragY; bool sizeChanged = false; fp.Time ("GetPointer"); if (InteractionProfiler.Watch.IsRunning) InteractionProfiler.Time ("From UI action to expose"); if (Width != (uint)w || Height != (uint)h || CachedSurface == null) { if (CachedSurface != null) CachedSurface.Destroy (); CachedSurface = new ImageSurface(Format.ARGB32, w, h); sizeChanged = true; Width = (uint) w; Height = (uint) h; UpdateLayout (); fp.Time ("Recreate CachedSurface"); } if (Cancelled) { ThrowFrames.Clear (); ThrowVelocity = 0; } if (ThrowVelocity != 0) { using ( Context ecr = new Context (EtcSurface) ) PanBy (ecr, Width, Height, 0, ThrowVelocity); ThrowVelocity *= 0.98; if (Math.Abs(ThrowVelocity) < 1) ThrowVelocity = 0; } if (ZoomVelocity != 1) { using ( Context ecr = new Context (EtcSurface) ) ZoomBy (ecr, Width, Height, x, y, ZoomVelocity); ZoomVelocity = Math.Pow(ZoomVelocity, 0.8); if (Math.Abs(1 - ZoomVelocity) < 0.001) ZoomVelocity = 1; } if (NeedZoomCheck) using ( Context ecr = new Context (EtcSurface) ) CheckZoomNavigation(ecr, Width, Height); fp.Time ("Throw and zoom"); if (sizeChanged || (!EffectInProgress && FSNeedRedraw)) { FSNeedRedraw = false; using (Context scr = new Context (CachedSurface)) { scr.Save (); scr.Operator = Operator.Source; scr.SetSourceRGBA (0,0,0,0); scr.Paint (); scr.Restore (); DrawMainView (scr, Width, Height); if (scr.Status != Status.Success) Helpers.LogError("Cairo error: {0}", scr.Status); } fp.Time ("FS Draw"); } cr.Operator = Operator.Over; DrawBackground (cr, Width, Height); fp.Time ("DrawBackground"); if (ControlLineVisible && panning) { cr.Save (); cr.Color = Renderer.DirectoryFGColor; cr.Rectangle (0, dragY, Width, 1); cr.Fill (); cr.Restore (); } using (SurfacePattern p = new SurfacePattern (CachedSurface)) { cr.Source = p; cr.Paint (); cr.Operator = Operator.Over; fp.Time ("Composite"); if (DrawEffects (cr, Width, Height)) { LimitedRedraw = true; fp.Time ("Effects"); } } if (InteractionProfiler.Watch.IsRunning) { InteractionProfiler.Total ("Interaction latency"); InteractionProfiler.Stop (); InteractionProfiler.Reset (); InteractionProfiler.TotalElapsed = 0; } // fp.Total ("Frame"); }
/** BLOCKING */ void DrawCurrentDir(Context cr, Rectangle targetBox) { Profiler p = new Profiler (); uint c; cr.Save (); cr.Scale (1, Zoomer.Z); cr.Translate (0.0, Zoomer.Y); Renderer.FileNameFontFamily = FileNameFontFamily; Renderer.FileInfoFontFamily = FileInfoFontFamily; c = Renderer.Draw(CurrentDirEntry, Prefixes, Selection, cr, targetBox); cr.Restore (); p.Time (String.Format("DrawCurrentDir: {0} entries", c)); }
/** FAST */ void DrawBreadcrumb(Context cr, uint width) { cr.NewPath (); cr.MoveTo (0.0, 0.0); Profiler p = new Profiler (); p.Time("In breadcrumb"); TextExtents te = Helpers.GetTextExtents (cr, BreadcrumbFontFamily, BreadcrumbFontSize, String.Join(dirSep, CurrentDirPath.Split(Helpers.DirSepC)) + dirSep); p.Time("GetTextExtents"); cr.Color = Renderer.DirectoryFGColor; cr.Save (); double areaWidth = width-BreadcrumbMarginLeft-BreadcrumbMarginRight; cr.Rectangle (0,0,areaWidth, te.Height); cr.Clip (); cr.Translate (Math.Min(0,areaWidth-te.Width), 0); cr.MoveTo (0.0, 0.0); if (CurrentDirPath == Helpers.RootDir) { Helpers.DrawText (cr, BreadcrumbFontFamily, BreadcrumbFontSize, rootChar); } else { p.Time("start DrawText"); foreach (string s in CurrentDirPath.Split(Helpers.DirSepC)) { Helpers.DrawText (cr, BreadcrumbFontFamily, BreadcrumbFontSize, s == "" ? rootChar : (s+dirSep)); } p.Time("DrawText"); } cr.Restore (); }