From 1701b535a392c1c601faf31cb414b710700bb179 Mon Sep 17 00:00:00 2001 From: Andrew den Exter Date: Wed, 22 Jun 2011 16:11:49 +1000 Subject: VisualDataModel conversation example improvements. --- .../dragtarget/launcher/IconDelegate.qml | 16 +-- .../declarative/dragtarget/launcher/Shadow.qml | 44 ++++++ .../declarative/dragtarget/launcher/launcher.qml | 12 +- .../modelviews/visualdatamodel/Bubble.qml | 66 ++++++--- .../modelviews/visualdatamodel/ComposerBubble.qml | 150 ++++++++++++++++----- .../modelviews/visualdatamodel/Conversation.qml | 4 +- .../visualdatamodel/images/face-smile.png | Bin 0 -> 15408 bytes .../modelviews/visualdatamodel/visualdatamodel.qml | 78 ++++------- 8 files changed, 251 insertions(+), 119 deletions(-) create mode 100644 examples/declarative/dragtarget/launcher/Shadow.qml create mode 100644 examples/declarative/modelviews/visualdatamodel/images/face-smile.png diff --git a/examples/declarative/dragtarget/launcher/IconDelegate.qml b/examples/declarative/dragtarget/launcher/IconDelegate.qml index 360ca8a946..2e56632c25 100644 --- a/examples/declarative/dragtarget/launcher/IconDelegate.qml +++ b/examples/declarative/dragtarget/launcher/IconDelegate.qml @@ -7,13 +7,11 @@ Item { width: 64; height: 64 - Rectangle { - anchors.fill: parent - opacity: dragArea.drag.active ? 0.5 : 0.0 - color: "lightgrey" - radius: 12 - - Behavior on opacity { NumberAnimation { duration: 300 } } + Shadow { + anchors.centerIn: parent + sourceItem: iconImage + width: iconImage.width + height: iconImage.height } MouseArea { @@ -57,10 +55,6 @@ Item { anchors { horizontalCenter: undefined; verticalCenter: undefined } } ParentChange { target: dragArea; parent: root; x: dragArea.rootX; y:dragArea.rootY } - AnchorChanges { - target: iconImage; - anchors { verticalCenter: undefined; bottom: dragArea.verticalCenter } - } } transitions: Transition { diff --git a/examples/declarative/dragtarget/launcher/Shadow.qml b/examples/declarative/dragtarget/launcher/Shadow.qml new file mode 100644 index 0000000000..8095d626c8 --- /dev/null +++ b/examples/declarative/dragtarget/launcher/Shadow.qml @@ -0,0 +1,44 @@ +import QtQuick 2.0 + +ShaderEffectItem { + id: shadow + + property Item sourceItem + + property variant delta: Qt.size(0.0, 1.0 / height) + property variant source: ShaderEffectSource { + smooth: true + sourceItem: ShaderEffectItem { + width: shadow.width + height: shadow.height + property variant delta: Qt.size(1.0 / width, 0.0) + property variant source: ShaderEffectSource { + id: shadowSource + sourceItem: shadow.sourceItem + smooth: true + } + fragmentShader: " + uniform sampler2D source; + uniform highp vec2 delta; + varying highp vec2 qt_TexCoord0; + void main() { + gl_FragColor = 0.0538 * texture2D(source, qt_TexCoord0 - 3.182 * delta) + + 0.3229 * texture2D(source, qt_TexCoord0 - 1.364 * delta) + + 0.2466 * texture2D(source, qt_TexCoord0) + + 0.3229 * texture2D(source, qt_TexCoord0 + 1.364 * delta) + + 0.0538 * texture2D(source, qt_TexCoord0 + 3.182 * delta); + }" + } + } + fragmentShader: " + uniform sampler2D source; + uniform highp vec2 delta; + varying highp vec2 qt_TexCoord0; + void main() { + gl_FragColor = 0.0538 * texture2D(source, qt_TexCoord0 - 3.182 * delta) + + 0.3229 * texture2D(source, qt_TexCoord0 - 1.364 * delta) + + 0.2466 * texture2D(source, qt_TexCoord0) + + 0.3229 * texture2D(source, qt_TexCoord0 + 1.364 * delta) + + 0.0538 * texture2D(source, qt_TexCoord0 + 3.182 * delta); + }" +} diff --git a/examples/declarative/dragtarget/launcher/launcher.qml b/examples/declarative/dragtarget/launcher/launcher.qml index f1188b85b3..5062e26c7a 100644 --- a/examples/declarative/dragtarget/launcher/launcher.qml +++ b/examples/declarative/dragtarget/launcher/launcher.qml @@ -71,8 +71,8 @@ Rectangle { destinationIndex = index } } - onDropped: applicationsModel.move(sourceIndex, destinationIndex, 1) - onExited: applicationsModel.move(destinationIndex, sourceIndex, 1) +// onDropped: applicationsModel.move(sourceIndex, destinationIndex, 1) +// onExited: applicationsModel.move(destinationIndex, sourceIndex, 1) } DragTarget { @@ -171,8 +171,8 @@ Rectangle { destinationIndex = index } } - onDropped: favoritesModel.move(sourceIndex, destinationIndex, 1) - onExited: favoritesVisualModel.move(destinationIndex, sourceIndex, 1) +// onDropped: favoritesModel.move(sourceIndex, destinationIndex, 1) +// onExited: favoritesVisualModel.move(destinationIndex, sourceIndex, 1) } DragTarget { @@ -200,8 +200,8 @@ Rectangle { destinationIndex = index } } - // onDropped: favoritesModel.move(sourceIndex, destinationIndex, 1) - // onExited: favoritesModel.move(destinationIndex, sourceIndex, 1) +// onDropped: favoritesModel.move(sourceIndex, destinationIndex, 1) +// onExited: favoritesModel.move(destinationIndex, sourceIndex, 1) } } } diff --git a/examples/declarative/modelviews/visualdatamodel/Bubble.qml b/examples/declarative/modelviews/visualdatamodel/Bubble.qml index f112b494e4..2506139aeb 100644 --- a/examples/declarative/modelviews/visualdatamodel/Bubble.qml +++ b/examples/declarative/modelviews/visualdatamodel/Bubble.qml @@ -1,31 +1,61 @@ import QtQuick 2.0 Rectangle { - property string message - property string sender - property bool outbound: false - - width: 400 - height: messageText.implicitHeight + 4 - anchors { - left: outbound ? parent.left : undefined - right: outbound ? undefined : parent.right - } + x: 1 + width: 477 + height: Math.max(messageText.implicitHeight, 48) + senderText.implicitHeight + 6 + + border.width: 1 + border.color: "#404040" + color: outbound ? "#202020" : "#313131" + + Item { + id: avatarItem - radius: 6 - color: outbound ? "white" : "black" + width: 48; height: 48 - gradient: Gradient { - GradientStop { position: 0.0; color: outbound ? "#FFFFFE" : "#696969" } - GradientStop { position: 1.0; color: outbound ? "#FEF0C9" : "#708090" } + anchors { + left: outbound ? undefined : parent.left; right: outbound ? parent.right: undefined + top: parent.top + leftMargin: 3; topMargin: 3; rightMargin: 2 + } + + Image { + id: avatarImage + height: 48 + anchors.centerIn: parent + sourceSize.width: 48 + + source: avatar != "" ? avatar : "images/face-smile.png" + } } Text { id: messageText - anchors { fill: parent; margins: 3 } - color: outbound ? "black" : "white" + + anchors { + left: outbound ? parent.left : avatarItem.right; top: parent.top + right: outbound ? avatarItem.left : parent.right; margins: 2 + } + color: "#FFFFFF" font.pixelSize: 18 wrapMode: Text.WordWrap - text: sender + ": " + message + text: message + } + + Text { + id: senderText + anchors { left: parent.left; bottom: parent.bottom; margins: 2 } + color: "#DDDDDD" + font.pixelSize: 12 + text: sender + } + + Text { + id: timeText + anchors { right: parent.right; bottom: parent.bottom; margins: 2 } + color: "#DDDDDD" + font.pixelSize: 12 + text: time } } diff --git a/examples/declarative/modelviews/visualdatamodel/ComposerBubble.qml b/examples/declarative/modelviews/visualdatamodel/ComposerBubble.qml index ed77d5d53c..ee988e8531 100644 --- a/examples/declarative/modelviews/visualdatamodel/ComposerBubble.qml +++ b/examples/declarative/modelviews/visualdatamodel/ComposerBubble.qml @@ -1,54 +1,138 @@ import QtQuick 2.0 -Bubble { - id: composerBubble +Rectangle { + id: composer property bool sending: false - property int messageId - property bool composing: true + property bool sent: false + property int margin: senderText.height + 1 + property int messageId; + property string sender + property url avatar - signal sent; + function send() { + timeText.text = Qt.formatTime(Date.now()) + sending = true + sendText.visible = false + sendArea.enabled = false + messageText.focus = false + messageText.activeFocusOnPress = false - outbound: true - message: messageInput.text + root.send() + } - gradient: Gradient { - GradientStop { position: 0.0; color: "#C1CDCD" } - GradientStop { - position: 1.0 - SequentialAnimation on position { - running: sending - alwaysRunToEnd: true - loops: Animation.Infinite - NumberAnimation { duration: 1000; from: 1.0; to: 0.1 } - NumberAnimation { duration: 1000; from: 0.1; to: 1.0 } - } - color: "#F8F8FF" - } - GradientStop { position: 1.0; color: "#F8F8FF" } + border.width: 1 + border.color: "#404040" + color: "#202020" + + x: 1 + width: 477 + height: Math.max(messageText.implicitHeight, 48) + senderText.implicitHeight + 6 + + Behavior on height { + NumberAnimation { duration: 500 } } Timer { interval: Math.random() * 20000 - running: composerBubble.sending + running: composer.sending onTriggered: { - composerBubble.sending = false - composerBubble.sent() + composer.sending = false + composer.sent = true + messageModel.append({ + "messageId": messageId, + "sender": sender, + "message": messageText.text, + "time": timeText.text, + "outbound": true, + "avatar": avatar + }) + } + } + + Item { + id: avatarItem + + width: 48; height: 48 + anchors { right: parent.right; top: parent.top; topMargin: 3; rightMargin: 2 } + Image { + id: avatarImage + height: 48 + anchors.centerIn: parent + sourceSize.width: 48 + + source: avatar != "" ? avatar : "images/face-smile.png" + + SequentialAnimation on opacity { + loops: Animation.Infinite + running: composer.sending + alwaysRunToEnd: true + NumberAnimation { + from: 1.0; to: 0.0 + duration: 5000 + } + NumberAnimation { + from: 0.0; to: 1.0 + duration: 5000 + } + } + + } + Rectangle { + anchors { fill: parent; rightMargin: 1; bottomMargin: 1 } + + color: "#000000" + + opacity: sendArea.pressed ? 0.5 : (composer.sending || composer.sent ? 0.0 : 1.0) + + Behavior on opacity { NumberAnimation { duration: 150 } } + + Text { + id: sendText + anchors.fill: parent + text: "Send" + + color: "#FFFFFF" + font.pixelSize: 16 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + + MouseArea { + id: sendArea + + anchors.fill: parent + + onClicked: composer.send() + } } } - TextInput { - id: messageInput + TextEdit { + id: messageText - anchors.fill: parent + anchors { left: parent.left; top: parent.top; right: avatarItem.left; margins: 2 } + color: "#FFFFFF" + font.pixelSize: 18 + wrapMode: Text.WordWrap + focus: true - focus: composing - activeFocusOnPress: composing - opacity: 0.0 - selectByMouse: false + Keys.onReturnPressed: composer.send() + Keys.onEnterPressed: composer.send() + } - onAccepted: root.send() + Text { + id: senderText + anchors { left: parent.left; bottom: parent.bottom; margins: 2 } + color: "#DDDDDD" + font.pixelSize: 12 + text: root.sender } - onSent: messageModel.append({ "messageId": messageId, "outbound": outbound, "sender": sender, "message": message }) + Text { + id: timeText + anchors { right: parent.right; bottom: parent.bottom; margins: 2 } + color: "#DDDDDD" + font.pixelSize: 12 + } } diff --git a/examples/declarative/modelviews/visualdatamodel/Conversation.qml b/examples/declarative/modelviews/visualdatamodel/Conversation.qml index 3967245b31..b36ea3620e 100644 --- a/examples/declarative/modelviews/visualdatamodel/Conversation.qml +++ b/examples/declarative/modelviews/visualdatamodel/Conversation.qml @@ -1,6 +1,6 @@ import QtQuick 2.0 ListModel { - ListElement { messageId: -1; outbound: false; sender: "Jack"; message: "Hello" } - ListElement { messageId: -1; outbound: false; sender: "Jill"; message: "Hi" } + ListElement { sender: "Jack"; message: "Hello"; avatar: "" } + ListElement { sender: "Jill"; message: "Hi"; avatar: "" } } diff --git a/examples/declarative/modelviews/visualdatamodel/images/face-smile.png b/examples/declarative/modelviews/visualdatamodel/images/face-smile.png new file mode 100644 index 0000000000..3d66d72578 Binary files /dev/null and b/examples/declarative/modelviews/visualdatamodel/images/face-smile.png differ diff --git a/examples/declarative/modelviews/visualdatamodel/visualdatamodel.qml b/examples/declarative/modelviews/visualdatamodel/visualdatamodel.qml index 528f89cb79..2049fbd3ba 100644 --- a/examples/declarative/modelviews/visualdatamodel/visualdatamodel.qml +++ b/examples/declarative/modelviews/visualdatamodel/visualdatamodel.qml @@ -1,6 +1,5 @@ import QtQuick 2.0 - Rectangle { id: root @@ -11,16 +10,17 @@ Rectangle { property int messageCounter: 0 function send() { - messageBubble.sending = true + messageView.positionViewAtEnd() visualModel.insert(visualModel.count, messageBubble) messageBubble = bubbleComponent.createObject(composer, { "messageId": ++messageCounter } ) + messageView.positionViewAtEnd() } width: 480; height: 640 gradient: Gradient { - GradientStop { position: 0.0; color: "#B0E2FF" } - GradientStop { position: 1.0; color: "#87CEFA" } + GradientStop { position: 0.0; color: "#000000" } + GradientStop { position: 1.0; color: "#080808" } } Component { @@ -33,8 +33,11 @@ Rectangle { ListView { id: messageView - anchors { left: parent.left; top: parent.top; right: parent.right; bottom: composer.top; margins: 2 } - spacing: 5 + anchors { + left: parent.left; top: parent.top; right: parent.right; bottom: composer.top + topMargin: 1; bottomMargin: 2 + } + spacing: 2 add: Transition { ParentAnimation { @@ -43,6 +46,8 @@ Rectangle { } } + cacheBuffer: 256 + model: VisualItemModel { id: visualModel @@ -53,15 +58,12 @@ Rectangle { delegate: Bubble { y: -height - outbound: model.outbound - sender: model.sender - message: model.message } } - onItemDataInserted: { - for (var i = 0; i < indexes.length; ++i) { - for (var j = indexes[i].start; j < indexes[i].end; ++j) { + onUpdated: { + for (var i = 0; i < inserts.length; ++i) { + for (var j = inserts[i].start; j < inserts[i].end; ++j) { var message = messageModel.get(visualModel.getItemInfo(j).index) if (!message.outbound) continue @@ -70,13 +72,13 @@ Rectangle { if (item.messageId != message.messageId) continue visualModel.replace(j, item) + // visualModel.move(item.visualIndex, j + 1 + // visualModel.replace(j + 1, j) break } } - } } - } } @@ -85,7 +87,17 @@ Rectangle { repeat: true running: true onTriggered: { - messageModel.append(script.get(scriptIndex)) + var message = script.get(scriptIndex); + + messageModel.append({ + "sender": message.sender, + "message": message.message, + "avatar": message.avatar, + "outbound": false, + "messageId": -1, + "time": Qt.formatTime(Date.now()) + }) + scriptIndex = (scriptIndex + 1) % script.count interval = Math.random() * 30000 } @@ -94,12 +106,8 @@ Rectangle { Item { id: composer - height: messageBubble.height - anchors { left: parent.left; right: parent.right; bottom: parent.bottom; margins: 2 } - - Behavior on height { - NumberAnimation { duration: 500 } - } + height: messageBubble.height - messageBubble.margin + anchors { left: parent.left; right: parent.right; bottom: parent.bottom } ComposerBubble { id: initialBubble @@ -107,33 +115,5 @@ Rectangle { sender: root.sender messageId: 0 } - - Rectangle { - id: sendButton - - anchors { - left: messageBubble.right; right: parent.right; top: parent.top; bottom: parent.bottom - leftMargin: 2; rightMargin: 1; bottomMargin: 1 - } - radius: 6 - - gradient: Gradient { - GradientStop { position: 0.0; color: "#A2CD5A" } - GradientStop { position: 1.0; color: sendArea.pressed ? "#556B2F" : "#6E8B3D" } - } - - Text { - anchors.centerIn: parent - color: "white" - font.pixelSize: 14 - text: "Send" - } - - MouseArea { - id: sendArea - anchors.fill: parent - onClicked: root.send() - } - } } } -- cgit v1.2.3