3

Is there a way to know when TextArea scroll has reached the top or bottom? I want to implement dynamic text loading in a chat client: when the user scrolls to the top, more text is added to the document. Something like this (pseudo-code):

import QtQuick 2.4
import QtQuick.Controls 1.2

TextArea {
      id: chat
      onScrolledToTop: text = loadMoreText() + text
}
BaCaRoZzo
  • 7,502
  • 6
  • 51
  • 82
psyched
  • 1,859
  • 1
  • 21
  • 28

2 Answers2

4

Textarea inherits from ScrollView which has a Flickable item to control the visible area. Such an item is available as the (readonly) property flickableItem. Among the other properties Flickable provides the contentY:

These properties hold the surface coordinate currently at the top-left corner of the Flickable. For example, if you flick an image up 100 pixels, contentY will be 100.

Hence you can check this property change and, once a certain threshold is reached, update your text. Mind that you should adjust the contentY after setting the text, to simulate the addition. Otherwise the text shown will be exactly the one just added. A nice approach, as proposed by the OP, would be to save the original contentHeight and set the contentY to the difference between the updated contentHeight and the saved one - also considering the applied threshold.

import QtQuick 2.4
import QtQuick.Window 2.2
import QtQuick.Controls 1.3

Window {
    visible: true
    width: 400
    height: 200

    TextArea {
        id: chat
        anchors.fill: parent
        property int threshold: 10

        text: "Current\ntext\n\\to\nmove\ndown\ndown\ndown
               \ndown\ndown\ndown\ndown\ndown\ndown\ndown"
        Component.onCompleted: cursorPosition = text.length


        flickableItem.onContentYChanged: {
            if(flickableItem.contentY <= threshold) {
                var oldHeight = flickableItem.contentHeight
                text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit,
                            sed do eiusmod tempor incididunt ut labore et dolore magna
                            aliqua." + text
                flickableItem.contentY = threshold + flickableItem.contentHeight - oldHeight  // leave flickable in old position
            }
        }
    }
}
BaCaRoZzo
  • 7,502
  • 6
  • 51
  • 82
  • 1
    Thanks, it works great. I edited your code to leave flickable at the exact same position as it was before adding text (to have smooth scrolling) – psyched Apr 09 '15 at 20:11
  • Yup, nice idea. You surely improved my trivial example in a nice and smart way, thanks @beemaster! By the way, I think you don't need the `threshold` in the `contentY` recalculation. – BaCaRoZzo Apr 09 '15 at 20:38
0
ScrollView {
        width: root.width - ((root.width/10) * 2) - (root.width/15)*2
        x:  (root.width/10) + root.width/15
        height: root.height - (root.height/5)
        clip: true

        TextArea {
            id: textArea
            clip: true
            width: root.width - ((root.width/10) * 2) - (root.width/15)*2
            height: root.height - (root.height/5)
            wrapMode: "WrapAtWordBoundaryOrAnywhere"
            placeholderText: "inter description"
        }
    }
milad
  • 84
  • 5
  • 1
    You should include some explanation of your code. Code-only answers are generally frowned upon. – wpercy Nov 14 '17 at 19:52