PDA

View Full Version : qml animated height in tableview row



motaito
22nd April 2015, 22:05
Hi,

I am trying to animate the height from a row in a tableview. I want the height to increase when the row is clicked. When a new row is selected, the previous row should go to the default height (close) and the new selected row should increase it's height (open).

So far I managed to open or close a single row as I would like but if I select a different row, the previously selected row keeps it's height and does not get closed.

I also had to programmatically select the row, because the mouse area does not pass the clicked signal to the row where the mouse area is inside. I have played with the "preventStealing: true" property and set "mouse.accepted = false;" but either the click event does not get fired or the row does not get selected.

Can someone help me figure out how to achieve the desired open/close effect and fix the mouse-click problem?
(If there is another way and I don't need the mouse area that would be perfect, but I will have to handle other mouse events in the opened up row when later more components will show up in the opened up row)

Here is the qml that I am using:

import QtQuick 2.4
import QtQuick.Window 2.2
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2

Window {
visible: true
width: 800
height:600

ListModel {
id: libraryModel
ListElement {
firstname: "Peter Benjamin"
surname: "Parker"
}
ListElement {
firstname: "Anthony Edward"
surname: "Stark"
}
ListElement {
firstname: "Wade Winston"
surname: "Wilson"
}
ListElement {
firstname: "Robert Bruce"
surname: "Banner"
}
ListElement {
firstname: "Elektra"
surname: "Natchios"
}
ListElement {
firstname: "Selina"
surname: "Kyle"
}
ListElement {
firstname: "Clark"
surname: "Kent"
}
ListElement {
firstname: "Natalia Alianovna"
surname: "Romanova"
}
ListElement {
firstname: "Bruce"
surname: "Wayne"
}
}

TableView {
id: tv
anchors.fill: parent
model: libraryModel

rowDelegate: Rectangle {

property bool isOpen: false
property int sizeOpen: 60
property int sizeClosed: 20;

id: rowDelegate
color: styleData.alternate ? "#666666" : "#555555"
height: sizeClosed // styleData.selected? sizeOpen : sizeClosed

function stopAllAnimation()
{
doOpen.stop();
doClose.stop();
}

MouseArea {
anchors.fill: parent
propagateComposedEvents: true
preventStealing: true
acceptedButtons: Qt.LeftButton | Qt.RightButton

onClicked: {
tv.selection.forEach( function(rowIndex) { doClose.start(); console.log(rowIndex); } )

tv.selection.clear();
tv.selection.select(styleData.row);

// stopAllAnimation();
(rowDelegate.sizeOpen == rowDelegate.height) ? doClose.start() : doOpen.start();

//mouse.accepted = false;
}

// onPressed: mouse.accepted = false;
// onReleased: mouse.accepted = false;
// onDoubleClicked: mouse.accepted = false;
// onPositionChanged: mouse.accepted = false;
// onPressAndHold: mouse.accepted = false;
}

ParallelAnimation {
id: doOpen
running: false
PropertyAnimation { target: rowDelegate; property: "isOpen"; to: true }
NumberAnimation { target: rowDelegate; easing.type: Easing.OutSine; property: "height"; to: sizeOpen; duration: 100 }


}
ParallelAnimation {
id: doClose
running: false
NumberAnimation { target: rowDelegate; easing.type: Easing.OutSine; property: "height"; to: sizeClosed; duration: 100; }
PropertyAnimation { target: rowDelegate; property: "isOpen"; to: false }
}
}

TableViewColumn {
id: icon
width: 50
delegate: Item{
anchors.fill: parent
clip: !styleData.selected
Rectangle {
clip:false
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.left: parent.left
//height: 60
width: tv.width
color: "blue"
}
}
}

TableViewColumn {
id: rowFirst
role: "firstname"
title: "Firstname"
width: 100
delegate: Item {
id: itemFirst
clip:true
anchors.fill: parent
Text{
id:txt
anchors.fill: parent
text: styleData.value
elide: Text.ElideRight
}
}
}
TableViewColumn {
id: rowSecond
role: "surname"
title: "Surname"
width: 200
delegate: Item {
id: itemSecond
anchors.fill: parent
clip: true
Text{
id:txt2
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
text: styleData.value
elide: Text.ElideRight
}
}
}

}
}

motaito
25th April 2015, 00:35
I finally figured it out. It only started working after I got my data from a QAbstractTableModel. I guess otherwise the rows were not redrawn.

In any case, here is what I ended up with:

import QtQuick 2.4
import QtQuick.Window 2.2
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2
import MoeFileModel 1.0

Window {
visible: true
width: 800
height:600


FileModelHandler {
id: fileModelHandler
}

TableView {
id: tv
anchors.fill: parent
model: fileModelHandler

rowDelegate: Rectangle {
property int sizeOpen: 60
property int sizeClosed: 20

id: rowDelegate
color: styleData.alternate ? "#666666" : "#555555"
height: getSize() // styleData.selected? sizeOpen : sizeClosed

function getSize()
{
if(!tv.selection.contains(styleData.row))
{
doClose.start();
return sizeClosed;
}

return sizeOpen;
}

MouseArea {
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
height: sizeClosed
propagateComposedEvents: true
preventStealing: true
acceptedButtons: Qt.LeftButton | Qt.RightButton

onClicked: {
if(rowDelegate.sizeOpen == rowDelegate.height)
{
tv.selection.deselect(styleData.row);
doClose.start()
}
else
{
tv.selection.clear();
tv.selection.select(styleData.row);
doOpen.start();
}
}
}

ParallelAnimation {
id: doOpen
running: false
NumberAnimation { target: rowDelegate; easing.type: Easing.OutSine; property: "height"; to: sizeOpen; duration: 100 }
}
ParallelAnimation {
id: doClose
running: false
NumberAnimation { target: rowDelegate; easing.type: Easing.OutSine; property: "height"; to: sizeClosed; duration: 100; }
}
}

// columns go here...
TableViewColumn {}
}
}