From a08929b22ac6b6371585beec221c3efebc3b8a71 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jean-Philippe=20Bruy=C3=A8re?= Date: Tue, 13 Apr 2021 22:06:56 +0200 Subject: [PATCH] discard registerLayouting for group onChildLayoutChange when not needed --- Crow/src/DebugUtils/DbgEvtType.cs | 4 +- Crow/src/DebugUtils/DbgWidgetEvent.cs | 2 + Crow/src/Widgets/Group.cs | 14 +- Crow/src/Widgets/PrivateContainer.cs | 8 +- Samples/common/Editor.cs | 346 +++++++++++++------------- 5 files changed, 199 insertions(+), 175 deletions(-) diff --git a/Crow/src/DebugUtils/DbgEvtType.cs b/Crow/src/DebugUtils/DbgEvtType.cs index 99cf1539..b7f16acb 100644 --- a/Crow/src/DebugUtils/DbgEvtType.cs +++ b/Crow/src/DebugUtils/DbgEvtType.cs @@ -64,13 +64,15 @@ namespace Crow GOClippingRegistration = Widget | Clipping | 0x01, GORegisterClip = Widget | Clipping | 0x02, + GOResetClip = Widget | Clipping | 0x03, GORegisterLayouting = Widget | Layouting | 0x01, GOProcessLayouting = Widget | Layouting | 0x02, GOProcessLayoutingWithNoParent = Widget | Layouting | Warning | 0x01, GODraw = Widget | Drawing | 0x01, GORecreateCache = Widget | Drawing | 0x02, GOUpdateCache = Widget | Drawing | 0x03, - GOPaint = Widget | Drawing | 0x04, + GOPaintCache = Widget | Drawing | 0x04, + GOPaint = Widget | Drawing | 0x05, GOLockUpdate = Widget | Lock | 0x01, GOLockClipping = Widget | Lock | 0x02, diff --git a/Crow/src/DebugUtils/DbgWidgetEvent.cs b/Crow/src/DebugUtils/DbgWidgetEvent.cs index 3ec58df7..ae363999 100644 --- a/Crow/src/DebugUtils/DbgWidgetEvent.cs +++ b/Crow/src/DebugUtils/DbgWidgetEvent.cs @@ -31,6 +31,8 @@ namespace Crow.DebugLogger return Colors.MediumTurquoise; case DbgEvtType.GORegisterClip: return Colors.Turquoise; + case DbgEvtType.GOResetClip: + return Colors.DarkRed; case DbgEvtType.GORegisterForGraphicUpdate: return Colors.LightPink; case DbgEvtType.GOEnqueueForRepaint: diff --git a/Crow/src/Widgets/Group.cs b/Crow/src/Widgets/Group.cs index 0500d129..d5e3d5e0 100644 --- a/Crow/src/Widgets/Group.cs +++ b/Crow/src/Widgets/Group.cs @@ -307,6 +307,7 @@ namespace Crow } protected override void UpdateCache (Context ctx) { + DbgLogger.StartEvent(DbgEvtType.GOUpdateCache, this); if (!Clipping.IsEmpty) { using (Context gr = new Context (bmp)) { for (int i = 0; i < Clipping.NumRectangles; i++) @@ -343,10 +344,12 @@ namespace Crow gr.Stroke ();*/ #endif } - Clipping.Reset (); + DbgLogger.AddEvent (DbgEvtType.GOResetClip, this); + Clipping.Reset (); }/*else Console.WriteLine("GROUP REPAINT WITH EMPTY CLIPPING");*/ paintCache (ctx, Slot + Parent.ClientRectangle.Position); + DbgLogger.EndEvent(DbgEvtType.GOUpdateCache); } #endregion @@ -367,6 +370,10 @@ namespace Crow contentSize.Width = g.Slot.Width; } else if (g == largestChild) searchLargestChild (); + else { + DbgLogger.EndEvent(DbgEvtType.GOOnChildLayoutChange); + return; + } this.RegisterForLayouting (LayoutingType.Width); break; @@ -380,6 +387,10 @@ namespace Crow contentSize.Height = g.Slot.Height; } else if (g == tallestChild) searchTallestChild (); + else { + DbgLogger.EndEvent(DbgEvtType.GOOnChildLayoutChange); + return; + } this.RegisterForLayouting (LayoutingType.Height); break; @@ -437,6 +448,7 @@ namespace Crow tallestChild = Children [i]; } } + DbgLogger.EndEvent (DbgEvtType.GOSearchTallestChild); } diff --git a/Crow/src/Widgets/PrivateContainer.cs b/Crow/src/Widgets/PrivateContainer.cs index 6bdff7da..22a34f1c 100644 --- a/Crow/src/Widgets/PrivateContainer.cs +++ b/Crow/src/Widgets/PrivateContainer.cs @@ -195,7 +195,7 @@ namespace Crow } if (child != null) { - if (child.Visible) + if (child.IsVisible) child.Paint (gr); } @@ -206,6 +206,8 @@ namespace Crow } protected override void UpdateCache (Context ctx) { + DbgLogger.StartEvent(DbgEvtType.GOUpdateCache, this); + Rectangle rb = Slot + Parent.ClientRectangle.Position; Context gr = new Context (bmp); @@ -224,7 +226,9 @@ namespace Crow ctx.SetSource (bmp, rb.X, rb.Y); ctx.Paint (); - Clipping.Reset (); + DbgLogger.AddEvent (DbgEvtType.GOResetClip, this); + Clipping.Reset (); + DbgLogger.EndEvent(DbgEvtType.GOUpdateCache); } #endregion diff --git a/Samples/common/Editor.cs b/Samples/common/Editor.cs index 44168b69..1b5d337b 100644 --- a/Samples/common/Editor.cs +++ b/Samples/common/Editor.cs @@ -336,205 +336,209 @@ namespace Crow int tabSize = 4; protected override void drawContent (Context gr) { - lock(TokenMutex) { - if (source == null || source.Tokens.Length == 0) { - base.drawContent (gr); - return; - } - - Rectangle cb = ClientRectangle; - fe = gr.FontExtents; - double lineHeight = fe.Ascent + fe.Descent; - - CharLocation selStart = default, selEnd = default; - bool selectionNotEmpty = false; - - if (HasFocus) { - if (currentLoc?.Column < 0) { - updateLocation (gr, cb.Width, ref currentLoc); - NotifyValueChanged ("CurrentColumn", CurrentColumn); - } else - updateLocation (gr, cb.Width, ref currentLoc); - - if (overlay != null) { - Point p = new Point((int)currentLoc.Value.VisualCharXPosition, (int)(lineHeight * (currentLoc.Value.Line + 1))); - p += ScreenCoordinates (Slot).TopLeft; - overlay.Left = p.X; - overlay.Top = p.Y; + try { + lock(TokenMutex) { + if (source == null || source.Tokens.Length == 0) { + base.drawContent (gr); + return; } - if (selectionStart.HasValue) { - updateLocation (gr, cb.Width, ref selectionStart); - if (CurrentLoc.Value != selectionStart.Value) - selectionNotEmpty = true; - } - if (selectionNotEmpty) { - if (CurrentLoc.Value.Line < selectionStart.Value.Line) { - selStart = CurrentLoc.Value; - selEnd = selectionStart.Value; - } else if (CurrentLoc.Value.Line > selectionStart.Value.Line) { - selStart = selectionStart.Value; - selEnd = CurrentLoc.Value; - } else if (CurrentLoc.Value.Column < selectionStart.Value.Column) { - selStart = CurrentLoc.Value; - selEnd = selectionStart.Value; - } else { - selStart = selectionStart.Value; - selEnd = CurrentLoc.Value; - } - } else - IFace.forceTextCursor = true; - } - - double spacePixelWidth = gr.TextExtents (" ").XAdvance; - int x = 0, y = 0; - double pixX = cb.Left; - + + Rectangle cb = ClientRectangle; + fe = gr.FontExtents; + double lineHeight = fe.Ascent + fe.Descent; - Foreground.SetAsSource (IFace, gr); - gr.Translate (-ScrollX, -ScrollY); + CharLocation selStart = default, selEnd = default; + bool selectionNotEmpty = false; + if (HasFocus) { + if (currentLoc?.Column < 0) { + updateLocation (gr, cb.Width, ref currentLoc); + NotifyValueChanged ("CurrentColumn", CurrentColumn); + } else + updateLocation (gr, cb.Width, ref currentLoc); - ReadOnlySpan sourceBytes = source.Source.AsSpan(); - Span bytes = stackalloc byte[128]; - TextExtents extents; - int tokPtr = 0; - Token tok = source.Tokens[tokPtr]; - bool multilineToken = false; + if (overlay != null) { + Point p = new Point((int)currentLoc.Value.VisualCharXPosition, (int)(lineHeight * (currentLoc.Value.Line + 1))); + p += ScreenCoordinates (Slot).TopLeft; + overlay.Left = p.X; + overlay.Top = p.Y; + } + if (selectionStart.HasValue) { + updateLocation (gr, cb.Width, ref selectionStart); + if (CurrentLoc.Value != selectionStart.Value) + selectionNotEmpty = true; + } + if (selectionNotEmpty) { + if (CurrentLoc.Value.Line < selectionStart.Value.Line) { + selStart = CurrentLoc.Value; + selEnd = selectionStart.Value; + } else if (CurrentLoc.Value.Line > selectionStart.Value.Line) { + selStart = selectionStart.Value; + selEnd = CurrentLoc.Value; + } else if (CurrentLoc.Value.Column < selectionStart.Value.Column) { + selStart = CurrentLoc.Value; + selEnd = selectionStart.Value; + } else { + selStart = selectionStart.Value; + selEnd = CurrentLoc.Value; + } + } else + IFace.forceTextCursor = true; + } - ReadOnlySpan buff = sourceBytes; + double spacePixelWidth = gr.TextExtents (" ").XAdvance; + int x = 0, y = 0; + double pixX = cb.Left; - for (int i = 0; i < lines.Count; i++) { - //if (!cancelLinePrint (lineHeight, lineHeight * y, cb.Height)) { + Foreground.SetAsSource (IFace, gr); + gr.Translate (-ScrollX, -ScrollY); - if (multilineToken) { - if (tok.End < lines[i].End) {//last incomplete line of multiline token - buff = sourceBytes.Slice (lines[i].Start, tok.End - lines[i].Start); - } else {//print full line - buff = sourceBytes.Slice (lines[i].Start, lines[i].Length); - } - } - while (tok.Start < lines[i].End) { - if (!multilineToken) { - if (tok.End > lines[i].End) {//first line of multiline - multilineToken = true; - buff = sourceBytes.Slice (tok.Start, lines[i].End - tok.Start); - } else - buff = sourceBytes.Slice (tok.Start, tok.Length); - - if (tok.Type.HasFlag (TokenType.Punctuation)) - gr.SetSource(Colors.DarkGrey); - else if (tok.Type.HasFlag (TokenType.Trivia)) - gr.SetSource(Colors.DimGrey); - else if (tok.Type == TokenType.ElementName) { - gr.SetSource(Colors.Green); - }else if (tok.Type == TokenType.AttributeName) { - gr.SetSource(Colors.Blue); - }else if (tok.Type == TokenType.AttributeValue) { - gr.SetSource(Colors.OrangeRed); - }else if (tok.Type == TokenType.EqualSign) { - gr.SetSource(Colors.Black); - }else if (tok.Type == TokenType.PI_Target) { - gr.SetSource(Colors.DarkSlateBlue); - }else { - gr.SetSource(Colors.Red); - } - } + ReadOnlySpan sourceBytes = source.Source.AsSpan(); + Span bytes = stackalloc byte[128]; + TextExtents extents; + int tokPtr = 0; + Token tok = source.Tokens[tokPtr]; + bool multilineToken = false; - int size = buff.Length * 4 + 1; - if (bytes.Length < size) - bytes = size > 512 ? new byte[size] : stackalloc byte[size]; + ReadOnlySpan buff = sourceBytes; - int encodedBytes = Crow.Text.Encoding.ToUtf8 (buff, bytes); - if (encodedBytes > 0) { - bytes[encodedBytes++] = 0; - gr.TextExtents (bytes.Slice (0, encodedBytes), out extents); - gr.MoveTo (pixX, lineHeight * y + fe.Ascent); - gr.ShowText (bytes.Slice (0, encodedBytes)); - pixX += extents.XAdvance; - x += buff.Length; - } + for (int i = 0; i < lines.Count; i++) { + //if (!cancelLinePrint (lineHeight, lineHeight * y, cb.Height)) { if (multilineToken) { - if (tok.End < lines[i].End)//last incomplete line of multiline token - multilineToken = false; - else - break; + if (tok.End < lines[i].End) {//last incomplete line of multiline token + buff = sourceBytes.Slice (lines[i].Start, tok.End - lines[i].Start); + } else {//print full line + buff = sourceBytes.Slice (lines[i].Start, lines[i].Length); + } } - if (++tokPtr >= source.Tokens.Length) - break; - tok = source.Tokens[tokPtr]; - } - - if (HasFocus && selectionNotEmpty) { - RectangleD lineRect = new RectangleD (cb.X, lineHeight * y + cb.Top, pixX, lineHeight); - RectangleD selRect = lineRect; - - if (i >= selStart.Line && i <= selEnd.Line) { - if (selStart.Line == selEnd.Line) { - selRect.X = selStart.VisualCharXPosition + cb.X; - selRect.Width = selEnd.VisualCharXPosition - selStart.VisualCharXPosition; - } else if (i == selStart.Line) { - double newX = selStart.VisualCharXPosition + cb.X; - selRect.Width -= (newX - selRect.X) - 10.0; - selRect.X = newX; - } else if (i == selEnd.Line) - selRect.Width = selEnd.VisualCharXPosition - selRect.X + cb.X; - else - selRect.Width += 10.0; + while (tok.Start < lines[i].End) { + if (!multilineToken) { + if (tok.End > lines[i].End) {//first line of multiline + multilineToken = true; + buff = sourceBytes.Slice (tok.Start, lines[i].End - tok.Start); + } else + buff = sourceBytes.Slice (tok.Start, tok.Length); + + if (tok.Type.HasFlag (TokenType.Punctuation)) + gr.SetSource(Colors.DarkGrey); + else if (tok.Type.HasFlag (TokenType.Trivia)) + gr.SetSource(Colors.DimGrey); + else if (tok.Type == TokenType.ElementName) { + gr.SetSource(Colors.Green); + }else if (tok.Type == TokenType.AttributeName) { + gr.SetSource(Colors.Blue); + }else if (tok.Type == TokenType.AttributeValue) { + gr.SetSource(Colors.OrangeRed); + }else if (tok.Type == TokenType.EqualSign) { + gr.SetSource(Colors.Black); + }else if (tok.Type == TokenType.PI_Target) { + gr.SetSource(Colors.DarkSlateBlue); + }else { + gr.SetSource(Colors.Red); + } + } - buff = sourceBytes.Slice(lines[i].Start, lines[i].Length); int size = buff.Length * 4 + 1; if (bytes.Length < size) bytes = size > 512 ? new byte[size] : stackalloc byte[size]; int encodedBytes = Crow.Text.Encoding.ToUtf8 (buff, bytes); - gr.SetSource (SelectionBackground); - gr.Rectangle (selRect); - if (encodedBytes < 0) - gr.Fill (); - else { - gr.FillPreserve (); - gr.Save (); - gr.Clip (); - gr.SetSource (SelectionForeground); - gr.MoveTo (lineRect.X, lineRect.Y + fe.Ascent); + if (encodedBytes > 0) { + bytes[encodedBytes++] = 0; + gr.TextExtents (bytes.Slice (0, encodedBytes), out extents); + gr.MoveTo (pixX, lineHeight * y + fe.Ascent); gr.ShowText (bytes.Slice (0, encodedBytes)); - gr.Restore (); + pixX += extents.XAdvance; + x += buff.Length; } - Foreground.SetAsSource (IFace, gr); + + if (multilineToken) { + if (tok.End < lines[i].End)//last incomplete line of multiline token + multilineToken = false; + else + break; + } + + if (++tokPtr >= source.Tokens.Length) + break; + tok = source.Tokens[tokPtr]; } - } - if (!multilineToken) { - if (++tokPtr >= source.Tokens.Length) - break; - tok = source.Tokens[tokPtr]; - } + if (HasFocus && selectionNotEmpty) { + RectangleD lineRect = new RectangleD (cb.X, lineHeight * y + cb.Top, pixX, lineHeight); + RectangleD selRect = lineRect; + + if (i >= selStart.Line && i <= selEnd.Line) { + if (selStart.Line == selEnd.Line) { + selRect.X = selStart.VisualCharXPosition + cb.X; + selRect.Width = selEnd.VisualCharXPosition - selStart.VisualCharXPosition; + } else if (i == selStart.Line) { + double newX = selStart.VisualCharXPosition + cb.X; + selRect.Width -= (newX - selRect.X) - 10.0; + selRect.X = newX; + } else if (i == selEnd.Line) + selRect.Width = selEnd.VisualCharXPosition - selRect.X + cb.X; + else + selRect.Width += 10.0; + + buff = sourceBytes.Slice(lines[i].Start, lines[i].Length); + int size = buff.Length * 4 + 1; + if (bytes.Length < size) + bytes = size > 512 ? new byte[size] : stackalloc byte[size]; + + int encodedBytes = Crow.Text.Encoding.ToUtf8 (buff, bytes); + + gr.SetSource (SelectionBackground); + gr.Rectangle (selRect); + if (encodedBytes < 0) + gr.Fill (); + else { + gr.FillPreserve (); + gr.Save (); + gr.Clip (); + gr.SetSource (SelectionForeground); + gr.MoveTo (lineRect.X, lineRect.Y + fe.Ascent); + gr.ShowText (bytes.Slice (0, encodedBytes)); + gr.Restore (); + } + Foreground.SetAsSource (IFace, gr); + } + } - x = 0; - pixX = 0; - - y++; - - - /* } else if (tok2.Type == TokenType.Tabulation) { - int spaceRounding = x % tabSize; - int spaces = spaceRounding == 0 ? - tabSize * tok2.Length : - spaceRounding + tabSize * (tok2.Length - 1); - x += spaces; - pixX += spacePixelWidth * spaces; - continue; - } else if (tok2.Type == TokenType.WhiteSpace) { - x += tok2.Length; - pixX += spacePixelWidth * tok2.Length;*/ - } - gr.Translate (ScrollX, ScrollY); + if (!multilineToken) { + if (++tokPtr >= source.Tokens.Length) + break; + tok = source.Tokens[tokPtr]; + } + + x = 0; + pixX = 0; + + y++; + + + /* } else if (tok2.Type == TokenType.Tabulation) { + int spaceRounding = x % tabSize; + int spaces = spaceRounding == 0 ? + tabSize * tok2.Length : + spaceRounding + tabSize * (tok2.Length - 1); + x += spaces; + pixX += spacePixelWidth * spaces; + continue; + } else if (tok2.Type == TokenType.WhiteSpace) { + x += tok2.Length; + pixX += spacePixelWidth * tok2.Length;*/ + } + gr.Translate (ScrollX, ScrollY); + } + } catch { + } } } -- 2.47.3