ListViewPage.qml 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. /**
  2. * Copyright (c) 2012 Nokia Corporation.
  3. */
  4. import QtQuick 1.1
  5. import com.nokia.symbian 1.1
  6. import "../Constants.js" as Constants
  7. Page {
  8. id: page
  9. property bool deleteMode: false
  10. tools: SharedToolBar{id: sharedToolBar}
  11. state: "NORMAL"
  12. Component {
  13. id: itemDelegate
  14. Item {
  15. id: main
  16. height: Constants.ARRANGE_LIST_ITEM_HEIGHT
  17. width: parent.width
  18. Rectangle{
  19. id: backgroundRect
  20. anchors.fill: parent
  21. anchors.leftMargin: platformStyle.paddingLarge
  22. anchors.rightMargin: scrollBar.visible ? platformStyle.paddingMedium * 2 : platformStyle.paddingLarge
  23. visible: page.state == "SORTING"
  24. color: mouseArea.draggedItemId == itemId ? ( window.platformInverted ? "black" :"white" ) : "transparent"
  25. border.color: window.platformInverted ? "black" :"white"
  26. opacity: 0.3
  27. border.width: 1
  28. }
  29. Item {
  30. id: item;
  31. property bool isDragged: mouseArea.draggedItemId == itemId
  32. property real dragStartX
  33. parent: mouseArea
  34. x: isDragged ? mouseArea.mouseX - dragStartX : main.x
  35. y: {
  36. if (isDragged) {
  37. if (mouseArea.mouseY > flickableView.height)
  38. return flickableView.height - height/2
  39. if (mouseArea.mouseY < 0)
  40. return - height/2
  41. return mouseArea.mouseY - height/2
  42. }
  43. else {
  44. return index * Constants.ARRANGE_LIST_ITEM_HEIGHT - flickableView.contentY
  45. }
  46. }
  47. width: main.width
  48. height: main.height
  49. Image{
  50. id: thumbnail
  51. anchors.left: parent.left
  52. anchors.leftMargin: platformStyle.paddingLarge
  53. anchors.verticalCenter: parent.verticalCenter
  54. height: backgroundRect.height
  55. width: height
  56. source: "../Images/Icons/list_" + itemId + ".svg"
  57. }
  58. Item{
  59. id: deleteCheckboxExtendedArea
  60. height: parent.height
  61. width: deleteCheckbox.width + 2 * platformStyle.paddingMedium
  62. anchors.right: parent.right
  63. anchors.rightMargin: scrollBar.visible ? platformStyle.paddingMedium * 2 : platformStyle.paddingLarge
  64. anchors.verticalCenter: parent.verticalCenter
  65. Image{
  66. id: deleteCheckbox
  67. property bool checked: isChecked
  68. anchors.right: parent.right
  69. anchors.rightMargin: platformStyle.paddingMedium
  70. anchors.verticalCenter: parent.verticalCenter
  71. width: height
  72. height: parent.height - 2 * platformStyle.paddingMedium
  73. visible: deleteMode && page.state == "SORTING"
  74. source: {
  75. if (checkboxMouseArea.pressed)
  76. return "../Images/Icons/x-pressed.svg"
  77. return checked ? "../Images/Icons/x-marked.svg" :
  78. "../Images/Icons/qgn_prop_checkbox_off.svg"
  79. }
  80. onVisibleChanged: {
  81. checked = isChecked
  82. }
  83. onCheckedChanged: {
  84. dataModel.setProperty(index, "isChecked", checked);
  85. }
  86. }
  87. MouseArea{
  88. id: checkboxMouseArea
  89. anchors.fill: parent
  90. onClicked: {
  91. deleteCheckbox.checked = !deleteCheckbox.checked
  92. }
  93. }
  94. }
  95. ListItemText {
  96. id: itemText
  97. anchors.verticalCenter: parent.verticalCenter
  98. anchors.left: thumbnail.right
  99. anchors.leftMargin: 10
  100. platformInverted: window.platformInverted
  101. role: "Title"
  102. text: "Item " + itemId
  103. width: parent.width
  104. }
  105. Behavior on y {
  106. enabled: (mouseArea.isAnyItemDragged && !item.isDragged)
  107. NumberAnimation {id: yAnimation; duration: 200; easing.type: Easing.OutQuart }
  108. }
  109. onIsDraggedChanged: {
  110. if (isDragged) {
  111. dragStartX = mouseArea.mouseX
  112. item.z = 10
  113. if (yAnimation.running)
  114. yAnimation.complete()
  115. }
  116. else {
  117. item.z = 1
  118. }
  119. }
  120. }
  121. }
  122. }
  123. Component{
  124. id: headerDelegate
  125. ListHeading {
  126. width: parent.width
  127. Label{
  128. anchors.verticalCenter: parent.verticalCenter
  129. anchors.right: parent.right
  130. anchors.rightMargin: platformStyle.paddingLarge
  131. text: page.state == "NORMAL" ? "List header" : (deleteMode ? "Sort and remove" : "Sort")
  132. }
  133. }
  134. }
  135. ListHeading {
  136. id: header
  137. anchors.top: parent.top
  138. width: parent.width
  139. platformInverted: window.platformInverted
  140. z: 3
  141. Label{
  142. anchors.verticalCenter: parent.verticalCenter
  143. anchors.right: parent.right
  144. anchors.rightMargin: 2 * platformStyle.paddingMedium
  145. platformInverted: window.platformInverted
  146. text: page.state == "NORMAL" ? "List header" : (deleteMode ? "Sort and remove" : "Sort")
  147. }
  148. }
  149. ListView {
  150. id: flickableView
  151. function deleteCheckedItems() {
  152. var tempContentY = flickableView.contentY
  153. dataModel.deleteCheckedElements()
  154. if (tempContentY + flickableView.height > flickableView.contentHeight)
  155. flickableView.positionViewAtEnd()
  156. else
  157. flickableView.contentY = tempContentY
  158. }
  159. anchors.top: header.bottom
  160. anchors.topMargin: platformStyle.paddingSmall
  161. anchors.bottom: parent.bottom
  162. anchors.bottomMargin: platformStyle.paddingSmall
  163. width: parent.width
  164. delegate: itemDelegate
  165. interactive: page.state == "NORMAL"
  166. model: DataModel { id: dataModel }
  167. ScrollBar{
  168. id: scrollBar
  169. anchors.right: parent.right
  170. flickableItem: flickableView
  171. interactive: true
  172. opacity: 1
  173. policy: Symbian.ScrollBarWhenNeeded
  174. visible: flickableView.contentHeight > flickableView.height ? 1 : 0
  175. width: 15
  176. z: 11
  177. }
  178. MouseArea {
  179. id: mouseArea
  180. property int draggedItemId: -1
  181. property int draggedItemIndex: -1
  182. property bool isAnyItemDragged: draggedItemId != -1 && draggedItemIndex != -1
  183. property int index: flickableView.indexAt(mouseX + flickableView.contentX, mouseY + flickableView.contentY)
  184. property bool draggedBelowBottom: isAnyItemDragged && mouseY > flickableView.height - 30
  185. property bool draggedAboveTop: isAnyItemDragged && mouseY < 30
  186. anchors.fill: parent
  187. enabled: page.state == "SORTING"
  188. Binding{
  189. id: yBinding
  190. target: mouseArea
  191. property: "index"
  192. value: flickableView.indexAt(mouseArea.mouseX + flickableView.contentX, mouseArea.mouseY + flickableView.contentY)
  193. when: mouseArea.draggedItemId != -1 && !mouseArea.draggedBelowBottom && !mouseArea.draggedAboveTop
  194. }
  195. onPressed: {
  196. var pressedItemIndex = flickableView.indexAt(mouseX + flickableView.contentX, mouseY + flickableView.contentY)
  197. if (pressedItemIndex != -1) {
  198. draggedItemId = flickableView.model.get(pressedItemIndex).itemId
  199. index = pressedItemIndex
  200. draggedItemIndex = index
  201. }
  202. }
  203. onReleased: {
  204. draggedItemId = -1
  205. draggedItemIndex = -1
  206. }
  207. onIndexChanged: {
  208. if (isAnyItemDragged && index != -1) {
  209. dataModel.replaceItems(draggedItemIndex, index)
  210. draggedItemIndex = index
  211. }
  212. }
  213. onDraggedBelowBottomChanged: {
  214. if (draggedBelowBottom && index != -1) {
  215. automaticScrollTimer.start()
  216. }
  217. else{
  218. automaticScrollTimer.stop()
  219. }
  220. }
  221. onDraggedAboveTopChanged: {
  222. if (draggedAboveTop) {
  223. automaticScrollTimer.start()
  224. }
  225. else{
  226. automaticScrollTimer.stop()
  227. }
  228. }
  229. Timer{
  230. id: automaticScrollTimer
  231. interval: 400
  232. repeat: true
  233. onTriggered: {
  234. var mY = mouseArea.mouseY > flickableView.height ? flickableView.height : mouseArea.mouseY
  235. var moveY
  236. // if mouse at flickableView boundries can't scroll more so scrolling stopped
  237. if (mY > flickableView.contentHeight - flickableView.contentY - Constants.ARRANGE_LIST_ITEM_HEIGHT ||
  238. mY < Constants.ARRANGE_LIST_ITEM_HEIGHT && flickableView.contentY < Constants.ARRANGE_LIST_ITEM_HEIGHT) {
  239. automaticScrollTimer.stop()
  240. }
  241. else {
  242. // scroll down if dragged item at the top
  243. if (mouseArea.draggedAboveTop) {
  244. moveY = flickableView.contentY - (Constants.ARRANGE_LIST_ITEM_HEIGHT * (mouseArea.index - 1))
  245. if (flickableView.contentY >= moveY)
  246. flickableView.contentY -= moveY
  247. mouseArea.index = flickableView.indexAt(mouseArea.mouseX + flickableView.contentX, flickableView.contentY + 30)
  248. }
  249. // scroll up if dragged item at the bottom
  250. if (mouseArea.draggedBelowBottom) {
  251. moveY = Constants.ARRANGE_LIST_ITEM_HEIGHT +
  252. ((Constants.ARRANGE_LIST_ITEM_HEIGHT*(mouseArea.index + 1))
  253. - (flickableView.contentY + flickableView.height))
  254. if (flickableView.contentY + flickableView.height <= flickableView.contentHeight - moveY)
  255. flickableView.contentY += moveY
  256. mouseArea.index = flickableView.indexAt(mouseArea.mouseX + flickableView.contentX,
  257. flickableView.contentY + flickableView.height - 30)
  258. }
  259. }
  260. }
  261. }
  262. }
  263. Component.onCompleted: {
  264. //model = dataModel
  265. }
  266. }
  267. states: [
  268. State {
  269. name: "NORMAL"
  270. },
  271. State {
  272. name: "SORTING"
  273. }
  274. ]
  275. onStateChanged: {
  276. if (state == "NORMAL")
  277. sharedToolBar.setNormalToolbar()
  278. else {
  279. if (deleteMode)
  280. sharedToolBar.setSortAndRemoveToolbar()
  281. else
  282. sharedToolBar.setSortToolbar()
  283. }
  284. }
  285. }