Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

InlineUIContainer dosen't correctly render with TextProperty=Wrap #17183

Closed
Danich27rus opened this issue Oct 3, 2024 · 2 comments · Fixed by #17194
Closed

InlineUIContainer dosen't correctly render with TextProperty=Wrap #17183

Danich27rus opened this issue Oct 3, 2024 · 2 comments · Fixed by #17194

Comments

@Danich27rus
Copy link
Contributor

Danich27rus commented Oct 3, 2024

Describe the bug

Right now if Inlines have InlineUIContainer inside and we have TextProperty=Wrap on TextBlock, everything is fine until InlineUIContainer renders.
image
image

After that, if i back to smaller width, InlineUiContainer will be rendered incorrectly, on top of my text.
image

I don't know what to do right now. I thought about using WrapPanel, but that means i need to rewrote whole system in my App.

To Reproduce

  1. Create inline.
  2. Add runs and InlineUIContainer.
  3. Set inlines on some TextBlock with changable width.
  4. Try to change size on TextBlock
  5. InlineUIContainer will show and never hide.

Expected behavior

  1. Create inline.
  2. Add runs and InlineUIContainer.
  3. Set inlines on some TextBlock with changable width.
  4. Try to change size on TextBlock
  5. InlineUIContainer will proper show and hide as width changes.

Avalonia version

11.1.3

OS

Windows

Additional context

No response

@Danich27rus
Copy link
Contributor Author

Danich27rus commented Oct 3, 2024

Looks like this code

                            if (drawable is EmbeddedControlRun controlRun
                                && controlRun.Control is Control control)
                            {
                                control.Arrange(
                                    new Rect(new Point(currentX, currentY),
                                    new Size(control.DesiredSize.Width, textLine.Height)));
                            }

in ArrangeOverride dosen't rearrange control when it calls again because it dosen't store it anywhere. I think it can be solved if there will be some kind of pool of all controls. I can do a PR, but i don't think store list of controls is a good thing.

@Danich27rus
Copy link
Contributor Author

Danich27rus commented Oct 3, 2024

Created super simple fix that was written in 2 minutes:

        List<Control> _aabb = new();

        protected override Size ArrangeOverride(Size finalSize)
        {
            var scale = LayoutHelper.GetLayoutScale(this);
            var padding = LayoutHelper.RoundLayoutThickness(Padding, scale, scale);

            //Fixes: #11019
            if (finalSize.Width < _constraint.Width)
            {
                _textLayout?.Dispose();
                _textLayout = null;
                _constraint = finalSize.Deflate(padding);
            }

            if (HasComplexContent)
            {
                var currentY = padding.Top;

                foreach (var cont in _aabb)
                {
                    cont.Arrange(
                       new Rect(-cont.Bounds.Width, -cont.Bounds.Height, cont.Bounds.Width, cont.Bounds.Height));
                }

                foreach (var textLine in TextLayout.TextLines)
                {
                    var currentX = padding.Left + textLine.Start;

                    foreach (var run in textLine.TextRuns)
                    {
                        if (run is DrawableTextRun drawable)
                        {
                            if (drawable is EmbeddedControlRun controlRun
                                && controlRun.Control is Control control)
                            {
                                control.Arrange(
                                    new Rect(new Point(currentX, currentY),
                                    new Size(control.DesiredSize.Width, textLine.Height)));
                                if (!_aabb.Contains(control))
                                    _aabb.Add(control);
                            }

                            currentX += drawable.Size.Width;
                        }
                    }

                    currentY += textLine.Height;
                }
            }

            return finalSize;
        }

Works as i wanted.

github-merge-queue bot pushed a commit that referenced this issue Oct 30, 2024
…17183) (#17194)

* InlineUiContainer clip fix

* Removed LINQ, redo check

* bugfix/InlineUiContainer-clip-in-text: redo everything

* fixes by Gillibald

---------

Co-authored-by: Benedikt Stebner <Gillibald@users.noreply.github.com>
Gillibald added a commit to Gillibald/Avalonia that referenced this issue Nov 14, 2024
…valoniaUI#17183) (AvaloniaUI#17194)

* InlineUiContainer clip fix

* Removed LINQ, redo check

* bugfix/InlineUiContainer-clip-in-text: redo everything

* fixes by Gillibald

---------

Co-authored-by: Benedikt Stebner <Gillibald@users.noreply.github.com>
maxkatz6 pushed a commit that referenced this issue Nov 14, 2024
…17183) (#17194)

* InlineUiContainer clip fix

* Removed LINQ, redo check

* bugfix/InlineUiContainer-clip-in-text: redo everything

* fixes by Gillibald

---------

Co-authored-by: Benedikt Stebner <Gillibald@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants