public static void ShowWithOptions(this DockySurface self, DockySurface target, PointD point, double zoom, double rotation, double opacity) { if (target == null) { throw new ArgumentNullException("target"); } Cairo.Context cr = target.Context; double cos, sin; cos = Math.Cos(rotation); sin = Math.Sin(rotation); Matrix m = new Matrix(cos, sin, -sin, cos, point.X, point.Y); cr.Transform(m); if (zoom != 1) { cr.Scale(zoom, zoom); } cr.SetSource(self.Internal, -self.Width / 2, -self.Height / 2); cr.PaintWithAlpha(opacity); cr.IdentityMatrix(); }
public static void ShowAsReflection(this DockySurface self, DockySurface target, PointD point, double zoom, double rotation, double opacity, double height, DockPosition position) { if (target == null) { throw new ArgumentNullException("target"); } Cairo.Context cr = target.Context; switch (position) { case DockPosition.Left: point.X -= self.Width * zoom + height; break; case DockPosition.Top: point.Y -= self.Height * zoom + height; break; case DockPosition.Right: point.X += self.Width * zoom + height; break; case DockPosition.Bottom: point.Y += self.Height * zoom + height; break; } double cos, sin; cos = Math.Cos(rotation); sin = Math.Sin(rotation); Matrix m = new Matrix(cos, sin, -sin, cos, point.X, point.Y); cr.Transform(m); if (zoom != 1) { cr.Scale(zoom, zoom); } if (position == DockPosition.Left || position == DockPosition.Right) { cr.Scale(-1, 1); } else { cr.Scale(1, -1); } cr.SetSource(self.Internal, -self.Width / 2, -self.Height / 2); cr.PaintWithAlpha(opacity * .3); cr.IdentityMatrix(); }
public static void TileOntoSurface(this DockySurface self, DockySurface target, Gdk.Rectangle area, int edgeBuffer, double tilt, DockPosition orientation) { if (orientation == DockPosition.Left || orientation == DockPosition.Right) { int x = area.X; if (orientation == DockPosition.Left) { x -= self.Width - area.Width; } Cairo.Context cr = target.Context; // draw left edge cr.Rectangle(area.X, area.Y, area.Width, edgeBuffer); cr.SetSource(self.Internal, x, area.Y); cr.Fill(); int maxMiddleMove = self.Height - 2 * edgeBuffer; int position = area.Y + edgeBuffer; int edgeTarget = area.Y + area.Height - edgeBuffer; while (position < edgeTarget) { int height = Math.Min(edgeTarget - position, maxMiddleMove); cr.Rectangle(area.X, position, area.Width, height); cr.SetSource(self.Internal, x, position - edgeBuffer); cr.Fill(); position += height; } cr.Rectangle(area.X, position, area.Width, edgeBuffer); cr.SetSource(self.Internal, x, area.Y + area.Height - self.Height); cr.Fill(); } else { if (tilt != 1) { area.Y += (int)(area.Height * tilt); area.Height -= (int)(area.Height * tilt); } int y = area.Y; if (orientation == DockPosition.Top) { y -= self.Height - area.Height; } Cairo.Context cr = target.Context; cr.Rectangle(area.X - 100, area.Y, edgeBuffer + 100, area.Height); Matrix m = new Matrix(1, 0, -tilt, 1, 0, y); cr.Transform(m); // draw left edge cr.SetSource(self.Internal, area.X, 0); cr.Fill(); cr.IdentityMatrix(); int maxMiddleMove = self.Width - 2 * edgeBuffer; int position = area.X + edgeBuffer; int edgeTarget = area.X + area.Width - edgeBuffer; while (position < edgeTarget) { int width = Math.Min(edgeTarget - position, maxMiddleMove); cr.Rectangle(position, area.Y, width, area.Height); cr.SetSource(self.Internal, position - edgeBuffer, y); cr.Fill(); position += width; } cr.Rectangle(position, area.Y, edgeBuffer + 100, area.Height); m = new Matrix(1, 0, tilt, 1, 0, y); cr.Transform(m); cr.SetSource(self.Internal, area.X + area.Width - self.Width, 0); cr.Fill(); cr.IdentityMatrix(); } }
/** FAST */ public static bool CheckTextExtents(Context cr, TextExtents te, double x, double y) { bool retval = false; cr.Save (); PointD pt = cr.CurrentPoint; cr.NewPath (); cr.Rectangle (pt.X, pt.Y, te.Width, te.Height); cr.IdentityMatrix (); retval = cr.InFill (x, y); if (ShowTextExtents) { cr.Operator = Operator.Over; cr.Color = new Color (1,0.5,1,0.5); cr.LineWidth = 0.5; cr.Stroke (); } cr.Restore (); cr.MoveTo (pt.X, pt.Y); return retval; }
/* Rectangle drawing helpers */ /** FAST */ public static void DrawRectangle(Context cr, double x, double y, double w, double h, Rectangle target) { Matrix matrix = cr.Matrix; double x_a = matrix.X0+x*matrix.Xx; double y_a = matrix.Y0+y*matrix.Yy; double w_a = matrix.Xx*w; double h_a = matrix.Yy*h; double y2_a = y_a + h_a; double x2_a = x_a + w_a; x_a = Clamp(x_a, -1, target.X+target.Width+1); x2_a = Clamp(x2_a, -1, target.X+target.Width+1); y_a = Clamp(y_a, -1, target.Y+target.Height+1); y2_a = Clamp(y2_a, -1, target.Y+target.Height+1); w_a = Math.Max(0.5, x2_a - x_a); if (h_a < 0.25 && (Math.Floor(y*4) == Math.Floor((y+h)*4))) return; h_a = Math.Max(0.5, y2_a - y_a); // return; cr.Save (); cr.IdentityMatrix (); cr.Rectangle (x_a, y_a, w_a, h_a); cr.Restore (); }
/** BLOCKING */ void ClickCurrentDir(Context cr, uint width, uint height, double x, double y) { Rectangle box = Transform (cr, width, height); if (x < box.X || x > box.X+box.Width || y < box.Y || y > box.Y+box.Height) return; cr.Scale (1, Zoomer.Z); cr.Translate (0.0, Zoomer.Y); List<ClickHit> hits = Renderer.Click (CurrentDirEntry, Prefixes, cr, box, x, y); foreach (ClickHit c in hits) { if (c.Height < 15.9) { if (c.Target.ParentDir == CurrentDirEntry) { double nz = (c.Target.IsDirectory ? 24 : 18) / c.Height; // Helpers.LogDebug("ZoomIn {0}x", nz); cr.Save (); cr.IdentityMatrix (); ZoomBy(cr, width, height, x, y, nz); cr.Restore (); break; } } else if (DoubleClick) { break; } else { if (AltKeyDown) { ClearSelection (); } else if (CtrlKeyDown) { ToggleSelection(c.Target.FullName); spanStart = c.Target; spanEnd = null; } else if (ShiftKeyDown) { if (spanStart != null) { if (spanEnd != null) { ToggleSpan(spanStart, spanEnd); } spanEnd = c.Target; ToggleSpan(spanStart, spanEnd); } else { ToggleSelection(c.Target.FullName); spanStart = c.Target; spanEnd = null; } } else { if (c.Target.IsDirectory) { // Helpers.LogDebug("Navigate {0}", c.Target.FullName); SetCurrentDir (c.Target.FullName); } else { // Helpers.LogDebug("Open {0}", c.Target.FullName); OpenFile(c.Target.FullName); } } UpdateLayout (); break; } } }
private ImageSurface GenerateStub() { ImageSurface stub = new ImageSurface (Format.ARGB32, 600, 300); Context cairo = new Context(stub); cairo.IdentityMatrix (); cairo.Scale (600,300); cairo.Rectangle (0, 0, 1, 1); cairo.SetSourceRGB (1,1,1); cairo.Fill (); cairo.MoveTo (0.14, 0.5); cairo.SetFontSize (0.08); cairo.SetSourceRGB (0, 0, 0); cairo.ShowText ("Загрузите подложку"); cairo.Dispose (); return stub; }
/** 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; }
/** FAST */ bool ClickBreadcrumb(Context cr, uint width, double x, double y) { if (CurrentDirPath == Helpers.RootDir) return false; TextExtents te1 = Helpers.GetTextExtents (cr, BreadcrumbFontFamily, BreadcrumbFontSize, String.Join(dirSep, CurrentDirPath.Split(Helpers.DirSepC)) + dirSep); cr.Save (); double areaWidth = width-BreadcrumbMarginLeft-BreadcrumbMarginRight; cr.Rectangle (0,0,areaWidth, te1.Height); cr.Clip (); cr.Translate (Math.Min(0,areaWidth-te1.Width), -BreadcrumbMarginTop); if (areaWidth - te1.Width >= 0) cr.Translate(-(BreadcrumbMarginLeft+1), 0); cr.MoveTo (0.0, 0.0); int hitIndex = 0; string[] segments = CurrentDirPath.Split(Helpers.DirSepC); foreach (string s in segments) { string name = (s == "") ? rootChar : s+dirSep; TextExtents te = Helpers.GetTextExtents (cr, BreadcrumbFontFamily, BreadcrumbFontSize, name); te.Height += BreadcrumbMarginTop; if (s == "" && (areaWidth - te1.Width >= 0)) te.Width += BreadcrumbMarginLeft+1; if (Helpers.CheckTextExtents(cr, te, x, y)) { string newDir = String.Join(Helpers.DirSepS, segments, 0, hitIndex+1); if (newDir == "") newDir = Helpers.RootDir; if (newDir != CurrentDirPath) { SetCurrentDir (newDir); } else { ResetZoom (); UpdateLayout (); } cr.Restore (); return true; } cr.RelMoveTo( te.Width, 0 ); hitIndex += 1; } cr.IdentityMatrix (); cr.Rectangle (0,-1,width,2); if (cr.InFill(x,y)) { ResetZoom (); UpdateLayout (); } cr.Restore (); return false; }
/** 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; }
/** ASYNC */ void PreDrawCallback() { Thread.CurrentThread.Priority = ThreadPriority.BelowNormal; while (true) { PreDrawInProgress = PreDrawInProgress || PreDrawRequested; if (PreDrawInProgress) { // even if PreDrawRequested is set to true here, we still do the predraw // (and CancelPreDraw only affects an already running PreDraw) PreDrawRequested = false; try { if (FSCache.Measurer != null && SizeField != null) if (!SizeField.Measurer.DependsOnTotals && FSCache.Measurer.DependsOnTotals) clearTraversal = true; FSCache.Measurer = SizeField.Measurer; FSCache.SortDirection = SortDirection; FSCache.Comparer = SortField.Comparer; if (!FSCache.Measurer.DependsOnTotals) FSCache.CancelTraversal (); if (clearTraversal) { clearTraversal = false; FSCache.ClearTraversalCache (); } FSCache.PruneCache (1); FSCache.CancelThumbnailing (); using (Context cr = new Context (PreDrawSurface)) { cr.IdentityMatrix (); Rectangle target = Transform (cr, Width, Height); cr.Scale (1, Zoomer.Z); cr.Translate (0.0, Zoomer.Y); PreDrawComplete = Renderer.PreDraw (CurrentDirEntry, cr, target, 0); if (PreDrawComplete) NeedRedraw = true; } } finally { PreDrawInProgress = !PreDrawComplete; } } else { Thread.Sleep (10); } } }
/* Draw main view */ /** BLOCKING */ void DrawMainView(Context cr, uint width, uint height) { cr.Save (); cr.NewPath (); cr.IdentityMatrix (); DrawToolbars (cr, width, height); cr.NewPath (); cr.IdentityMatrix (); Rectangle targetBox = Transform (cr, width, height); DrawCurrentDir(cr, targetBox); cr.Restore (); dirLatencyProfiler.Stop (); if (FirstFrameOfDir) { dirLatencyProfiler.Time ("Directory latency"); FirstFrameOfDir = false; } if (Helpers.StartupProfiler.Watch.IsRunning) { Helpers.StartupProfiler.Time ("Draw complete"); Helpers.StartupProfiler.Total ("Startup complete"); Helpers.StartupProfiler.Stop (); if (QuitAfterFirstFrame) Application.Quit (); } }
/** FAST */ void DrawBackground(Context cr, uint width, uint height) { cr.Save (); DrawClear (cr, width, height); double t = DateTime.Now.ToFileTime() / 1e7; cr.Save (); Color ca = Renderer.DirectoryFGColor; ca.A = 0.3; cr.Color = ca; cr.LineWidth = 0.5; cr.Translate (270, -50); cr.Rotate (0.15); for (double y=0; y<6; y++) { for (double i=0; i<6-y; i++) { cr.Save (); double hr = 45; double iscale = Math.Sin(-i/20 * Math.PI*2 + CylinderRotation); double xscale = Math.Cos(-i/20 * Math.PI*2 + 0.1 + CylinderRotation); cr.Translate (iscale * hr * 3, -100 + y*hr*(2*1.732) + hr*(i%2)*1.732); hr = 45; cr.Scale (xscale, 1); cr.NewPath (); cr.MoveTo (0, -hr); cr.LineTo (0.866*hr, -0.5*hr); cr.LineTo (0.866*hr, 0.5*hr); cr.LineTo (0, hr); cr.LineTo (-0.866*hr, 0.5*hr); cr.LineTo (-0.866*hr, -0.5*hr); cr.ClosePath (); cr.Color = ca; cr.Stroke (); cr.Color = Renderer.SocketColor; cr.Translate (0.75 * -0.866*hr, 0.75 * -0.5*hr); double x2 = cr.Matrix.X0, y2 = cr.Matrix.Y0; cr.IdentityMatrix (); cr.Arc (x2,y2, 1, 0, Math.PI*2); cr.Fill (); cr.Restore (); } } CylinderRotation += 0.02; cr.Restore (); if (CurrentDirEntry.InProgress || (t - LastProgress < 3)) { if (FirstProgress == 0) { FirstProgress = LastProgress = t; } if (CurrentDirEntry.InProgress) LastProgress = t; double opacity = Math.Min(3, t-FirstProgress) - Math.Max(0, t-LastProgress); t = (t * 0.1) % Math.PI*2; Color c = Renderer.RegularFileColor; c.A = 0.1*opacity; cr.Color = c; cr.LineWidth = 1; double n = 6; double af = Math.PI*2/n; double r = 400*(4.4+0.3*cosScale(opacity/3)); for (double i=0; i<n; i++) { cr.Arc (-400*4, 1000/4, r, t+i*af, t+(i+0.7)*af); cr.Stroke (); } for (double i=0; i<n; i++) { cr.Arc (-400*4, 1000/4, r+5, -t+i*af, -t+(i+0.7)*af); cr.Stroke (); } if (CurrentDirEntry.InProgress) { cr.NewPath (); // find FSCache.LastTraversed [or ancestor] y position from model // draw line there cr.NewPath (); } LimitedRedraw = true; } else { FirstProgress = 0; LastProgress = 0; } cr.Restore (); }
public override void Paint(Context ctx) { PointD siz = this.MeasureSize(ctx); this.PaintContour(ctx,siz); PointD l = new PointD(0.5d*siz.X,0.5d*siz.Y); ctx.Arc(l.X,l.Y,2.0d,0.0d,2.0d*Math.PI); ctx.Color = KnownColors.LinkColor; ctx.Fill(); ctx.MoveTo(l.X,l.Y); ctx.IdentityMatrix(); siz = this.piece.OuterLocation(ctx); PointD siza = this.piece.MeasureSize(ctx); ctx.LineTo(siz.X+0.5d*siza.X,siz.Y+0.5d*siza.Y); ctx.Stroke(); ctx.Color = KnownColors.Black; }