diff options
| author | J-P Nurmi <jpnurmi@digia.com> | 2013-05-14 10:39:43 +0200 |
|---|---|---|
| committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-05-23 18:13:41 +0200 |
| commit | efd0fed4dec904b6d0257dffe5ea3e2939650f44 (patch) | |
| tree | 86ca753ac7945e13b2809083d173f0103c4dce57 /src/controls/TextArea.qml | |
| parent | fd15ea5e4a45b1173023d7afcde6ab3c2e5538c6 (diff) | |
| download | qtquickcontrols-efd0fed4dec904b6d0257dffe5ea3e2939650f44.tar.gz | |
TextArea: fix word wrap layout
Since scrollbars affect the document/viewport size and vice versa, we
must allow the layout loop to recurse twice until the sizes stabilize.
Furthermore, avoid nasty content size binding loops (from ScrollView)
by providing a specialized Flickable item that TextArea has full
control over.
Task-number: QTBUG-30832
Change-Id: I74fe6c5017e75aa411fdbb64087afa18e1221ce9
Reviewed-by: Jens Bache-Wiig <jens.bache-wiig@digia.com>
Diffstat (limited to 'src/controls/TextArea.qml')
| -rw-r--r-- | src/controls/TextArea.qml | 161 |
1 files changed, 88 insertions, 73 deletions
diff --git a/src/controls/TextArea.qml b/src/controls/TextArea.qml index a818779a..6dab90fd 100644 --- a/src/controls/TextArea.qml +++ b/src/controls/TextArea.qml @@ -609,12 +609,11 @@ ScrollView { property alias backgroundColor: colorRect.color /*! \internal */ - property int documentMargins: 4 + property int __documentMargin: 4 width: 280 height: 120 - flickableItem.contentWidth: edit.paintedWidth + (2 * documentMargins) frameVisible: true activeFocusOnTab: true @@ -629,84 +628,100 @@ ScrollView { */ property alias textDocument: edit.textDocument - TextEdit { - id: edit - focus: true + Flickable { + id: flickable - SystemPalette { - id: palette - colorGroup: enabled ? SystemPalette.Active : SystemPalette.Disabled - } + interactive: false + anchors.fill: parent - Rectangle { - id: colorRect - parent: viewport - anchors.fill: parent - color: palette.base - z: -1 - } + TextEdit { + id: edit + focus: true + + SystemPalette { + id: palette + colorGroup: enabled ? SystemPalette.Active : SystemPalette.Disabled + } + + Rectangle { + id: colorRect + parent: viewport + anchors.fill: parent + color: palette.base + z: -1 + } + + property int layoutRecursionDepth: 0 + + function doLayout() { + // scrollbars affect the document/viewport size and vice versa, so we + // must allow the layout loop to recurse twice until the sizes stabilize + if (layoutRecursionDepth <= 2) { + layoutRecursionDepth++ + + var margins = 2 * __documentMargin - property bool recursionGuard: false - - function doLayout() { - if (!recursionGuard) { - recursionGuard = true - if (wrapMode == TextEdit.NoWrap) { - __horizontalScrollBar.visible = edit.paintedWidth + (2 * documentMargins) > area.viewport.width - edit.width = edit.paintedWidth + (2 * documentMargins) - } else { - __horizontalScrollBar.visible = false - edit.width = area.viewport.width - (2 * documentMargins) + if (wrapMode == TextEdit.NoWrap) { + __horizontalScrollBar.visible = edit.contentWidth > viewport.width - margins + edit.width = Math.max(viewport.width - margins, edit.contentWidth) + } else { + __horizontalScrollBar.visible = false + edit.width = viewport.width - margins + } + edit.height = Math.max(viewport.height - margins, edit.contentHeight) + + flickable.contentWidth = edit.contentWidth + margins + flickable.contentHeight = edit.contentHeight + margins + + layoutRecursionDepth-- } - edit.height = Math.max(area.viewport.height - (2 * documentMargins), paintedHeight + (2 * documentMargins)) - recursionGuard = false } - } - Connections { - target: area.viewport - onWidthChanged: edit.doLayout() - onHeightChanged: edit.doLayout() - } - onPaintedWidthChanged: edit.doLayout() - onPaintedHeightChanged: edit.doLayout() - onWrapModeChanged: edit.doLayout() - - renderType: Text.NativeRendering - - color: palette.text - selectionColor: palette.highlight - selectedTextColor: palette.highlightedText - wrapMode: TextEdit.WordWrap - x: documentMargins - y: documentMargins - - selectByMouse: true - readOnly: false - - KeyNavigation.priority: KeyNavigation.BeforeItem - KeyNavigation.tab: area.tabChangesFocus ? area.KeyNavigation.tab : null - KeyNavigation.backtab: area.tabChangesFocus ? area.KeyNavigation.backtab : null - - // keep textcursor within scroll view - onCursorPositionChanged: { - if (cursorRectangle.y >= flickableItem.contentY + viewport.height - 1.5*cursorRectangle.height - documentMargins) - flickableItem.contentY = cursorRectangle.y - viewport.height + 1.5*cursorRectangle.height + documentMargins - else if (cursorRectangle.y < flickableItem.contentY) - flickableItem.contentY = cursorRectangle.y - - if (cursorRectangle.x >= flickableItem.contentX + viewport.width - documentMargins) { - flickableItem.contentX = cursorRectangle.x - viewport.width + documentMargins - } else if (cursorRectangle.x < flickableItem.contentX) - flickableItem.contentX = cursorRectangle.x - } - onLinkActivated: area.linkActivated(link) + Connections { + target: area.viewport + onWidthChanged: edit.doLayout() + onHeightChanged: edit.doLayout() + } + onContentWidthChanged: edit.doLayout() + onContentHeightChanged: edit.doLayout() + onWrapModeChanged: edit.doLayout() + + renderType: Text.NativeRendering + + color: palette.text + selectionColor: palette.highlight + selectedTextColor: palette.highlightedText + wrapMode: TextEdit.WordWrap + x: __documentMargin + y: __documentMargin + + selectByMouse: true + readOnly: false + + KeyNavigation.priority: KeyNavigation.BeforeItem + KeyNavigation.tab: area.tabChangesFocus ? area.KeyNavigation.tab : null + KeyNavigation.backtab: area.tabChangesFocus ? area.KeyNavigation.backtab : null + + // keep textcursor within scroll view + onCursorPositionChanged: { + if (cursorRectangle.y >= flickableItem.contentY + viewport.height - 1.5*cursorRectangle.height - __documentMargin) + flickableItem.contentY = cursorRectangle.y - viewport.height + 1.5*cursorRectangle.height + __documentMargin + else if (cursorRectangle.y < flickableItem.contentY) + flickableItem.contentY = cursorRectangle.y + + if (cursorRectangle.x >= flickableItem.contentX + viewport.width - __documentMargin) { + flickableItem.contentX = cursorRectangle.x - viewport.width + __documentMargin + } else if (cursorRectangle.x < flickableItem.contentX) + flickableItem.contentX = cursorRectangle.x + } + onLinkActivated: area.linkActivated(link) - MouseArea { - parent: area.viewport - anchors.fill: parent - cursorShape: Qt.IBeamCursor - acceptedButtons: Qt.NoButton + MouseArea { + parent: area.viewport + anchors.fill: parent + cursorShape: Qt.IBeamCursor + acceptedButtons: Qt.NoButton + } } } |
