Details
-
Suggestion
-
Resolution: Unresolved
-
Not Evaluated
-
None
-
None
-
None
Description
A large number of modern (mostly HTML/Electron-based) applications nowadays feature smart WYSIWYG text input fields which are able to automatically highlight or link certain parts of the text and show buttons, tags, emojis or similar controls inlined in the text.
These kinds of controls get more and more important in UI development. As of yet, QtQuick lacks such a feature. Anything going beyond very basic hyperlink/image support requires developers to resort to the RichText mode which however requires you to use HTML rather than your own QtQuick Controls, causing a bad performance impact and more development effort.
I would like propose a new layout control in QML for laying out an arbitrary composition of text and other QtQuick elements. In a second iteration, it could support user selections and user editing (similar to contenteditable=true in HTML) and also attached properties which allow the QML elements inside the text to change behavior based on their current selection status. A strong JS/C++ API should offer to do all sorts of manipulations such as inserting/deleting new nodes, querying/manipulating the current cursor position, etc.
My suggested syntax would look like this:
TextLayout { alignment: Qt.AlignLeft editable: true selectionAllowed: true TextSpan { text: "Lorem ipsum dolor sit amet" } Button { label: "Click me" TextLayout.alignment: TextLayout.Center background: TextLayout.isSelected ? "blue" : "white" TextLayout.copyText: "textual representation of Button" } TextSpan { text: "Text after the button" TextLayout.allowSelection: false } TextSpan { lineBreakBefore: true color: "red" text: "more text" } }
See attachment for how the output should look like for the above example.
A different usage mode could look like this:
TextLayout { alignment: Qt.AlignLeft editable: true selectionAllowed: true model: myTextLayoutModel delegates: [ TextDelegate { name: "button" // delegate type identifier to be used from C++ delegate: Button { label: model.label // data object assigned from C++ } } ] }
where myTextLayoutModel could be a special C++ object describing the structure of the content. This would allow to query and manipulate the text dynamically from C++. We could declare a set of possible delegates which may appear in the text.
Usage from C++ could look like this:
QQuickTextStyle redText; redText.setColor(QColor("red")); redText.setTopMargin(5); ... auto* myModel = new QQuickTextLayoutModel(this); myModel->addTextSpan("Lorem ipsum dolor sit amet"); myModel->addDelegate("button", QVariantMap{{"label", "Click me"}}); // might also be a QObject with onXXXChanged signals myModel->addTextSpan("Text after the button"); myModel->addLineBreak(); myModel->addTextSpan("more text", redText); ... qmlContext->setContextProperty("myTextLayoutModel", myModel);
My suggestion is strongly inspired by the TextSpan and WidgetSpan controls in Flutter:
https://api.flutter.dev/flutter/widgets/WidgetSpan-class.html
https://api.flutter.dev/flutter/painting/TextSpan-class.html
Attachments
Issue Links
- relates to
-
QTBUG-39107 Images in text disappear if lineLaidOut signal is connected
- Open