UnrealRichTextDialogueBox
UnrealRichTextDialogueBox copied to clipboard
Alternate approach - custom decorator/run
My use-case for this code needed to support dynamically-sized layouts, so after some research settled on this alternate implementation. You are welcome to disregard this pull request as it's quite a divergence from the original implementation, but if you wouldn't mind reviewing briefly and letting me know if I'm in the weeds on this I'd appreciate it! I'm fairly new to UE, so I may have committed some grave error here I'm not otherwise aware of.
My initial attempt at allowing for a dynamic widget transform was to duplicate the implementation of URichTextBlock/SRichTextBlock and signal back to the parent when new geometry is calculated. I wasn't happy with this approach because it:
- Duplicated hundreds of lines of engine code whereas I just wanted to modify a few private/non-virtual methods.
- Duplicated a lot of work that the engine was doing automatically when text was added to the layout.
- Broke compatibility with various existing Rich Text tools (custom decorators/etc would be incompatible. ... so I ditched that implementation.
This new approach uses a custom decorator to intercept the segment which is currently being "typed out". Once this segment is identified, a custom text run overrides the Measure() method to return full size of the block in order to force the correct line break to be generated. Because this approach is layout-agnostic, the widget's transform can be modified freely without needing to re-calculate line breaks.
Additionally, I believe this new implementation fixes the issue you were having with image/custom decorators behaving strangely - they will have their sizes calculated dynamically per-layout so anything crazy they do should automatically inform the rest of the layout without intervention.
Either way thank you for your original implementation, I have learnt a lot from it :)
I haven't taken a close look at the code (I'm not in a state to do so right now) but from a quick skim this is an interesting approach. Not something I'll likely merge but it does seem like another interesting solution to the problem that's worth looking at (and I'm sure there are plenty of other ones... maybe one day I'll get back around to patching the engine to let the break iterator method work).
My initial thought for dynamically sized text blocks would be to just refresh the layout on-demand which is something I just haven't gotten around to (and fwiw probably won't anytime remotely soon as I'm not actively working on any projects that need it right now).
From that quick skim, I think my concern would be that using a custom decorator would mean that you wouldn't be able to use other decorators - does your change support, for example, embedding images or other formatting decorators in the text? That was one of the requirements I had for my use-case.
Yep refreshing the layout on-demand was something I looked into also, but couldn't really find an appropriate place to do so. Either you go low (clone the rich text implementation and notify when that changes) or go high (explicitly notify the widget when this would happen). Although now that I'm typing this out, I'm almost certain I've missed some obvious callback to layout rebuilds somehere....
I tested with combinations of inline images, bold and italics. Everything I threw at it seemed to work well. Perhaps there's some more exotic combinations that will trip it up though, I'm not sure.
Glad to hear my concern seems to be unfounded, will have to take a closer look when I have a chance.