Advertisement
Gnitry

ListViewAdvanced

Mar 20th, 2014
168
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // import QtQuick 1.0 // to target S60 5th Edition or Maemo 5
  2. import QtQuick 1.1
  3.  
  4. ListView {
  5.     id: container
  6.     property bool handleKey_Home: true
  7.     property bool numberKeyNavigation: true
  8.     property string skipProperty: ""
  9.     property string hideProperty: ""
  10.     property bool keyInteractive: true
  11.     property bool overloaded: container.contentHeight > container.height
  12.  
  13.     signal currentIndexChangedByNumberKey()
  14.     signal upKeyLimit()
  15.     signal downKeyLimit()
  16.     signal topKeyLimit()
  17.     signal bottomKeyLimit()
  18.  
  19.     interactive: false
  20.  
  21.     function getNextAvailable(ind, forward) {
  22.         var i = ind
  23.         while (true) {
  24.             if (forward) {
  25.                 if (i >= count-1)
  26.                     break
  27.                 ++i
  28.             } else {
  29.                 if (i <= 0)
  30.                     break
  31.                 --i
  32.             }
  33.  
  34.             if (getIsItemAvailable(i))
  35.                 return i
  36.         }
  37.  
  38.         return ind
  39.     }
  40.  
  41.     function getIsItemAvailable(ind) {
  42.         if (ind < 0 || ind > count-1)
  43.             return false
  44.  
  45.         if (skipProperty === "" || model.children[ind][skipProperty] === undefined)
  46.             return true
  47.  
  48.         return !model.children[ind][skipProperty]
  49.     }
  50.  
  51.     function getIsItemVisible(ind) {
  52.         if (ind < 0 || ind > count-1)
  53.             return false
  54.  
  55.         if (hideProperty === "" || model.children[ind][hideProperty] === undefined)
  56.             return true
  57.  
  58.         return !model.children[ind][hideProperty]
  59.     }
  60.  
  61.     Keys.onPressed: {
  62.         if (!keyInteractive)
  63.             return
  64.  
  65.         switch (event.key) {
  66.         case Qt.Key_Up:
  67.             if (orientation !== Qt.Vertical) return;
  68.             if (!tryNavigateUp()) return;
  69.             break;
  70.         case Qt.Key_Left:
  71.             if (orientation !== Qt.Horizontal) return;
  72.             if (!tryNavigateUp()) return;
  73.             break;
  74.         case Qt.Key_PageUp:
  75.             if (!tryNavigateTop()) return;
  76.             break;
  77.         case Qt.Key_Home:
  78.             if (!handleKey_Home) return
  79.             // in any case we stop "Home" propagation
  80.             event.accepted = true;
  81.             if (!tryNavigateTop()) return;
  82.             break;
  83.         case Qt.Key_Down:
  84.             if (orientation !== Qt.Vertical) return;
  85.             if (!tryNavigateDown()) return;
  86.             break;
  87.         case Qt.Key_Right:
  88.             if (orientation !== Qt.Horizontal) return;
  89.             if (!tryNavigateDown()) return;
  90.             break;
  91.         case Qt.Key_PageDown:
  92.         case Qt.Key_End:
  93.         case Qt.Key_Tab:
  94.             if (!tryNavigateBottom()) return;
  95.             break;
  96.         case Qt.Key_1:
  97.         case Qt.Key_2:
  98.         case Qt.Key_3:
  99.         case Qt.Key_4:
  100.         case Qt.Key_5:
  101.         case Qt.Key_6:
  102.         case Qt.Key_7:
  103.         case Qt.Key_8:
  104.         case Qt.Key_9:
  105.             if (!numberKeyNavigation)
  106.                 return
  107.             if (event.key < Qt.Key_1 || event.key >= Qt.Key_1 + count)
  108.                 return
  109.             var needPageIndex = event.key - Qt.Key_1
  110.             needPageIndex = getIndexAvailable(needPageIndex)
  111.  
  112.             if (!getIsItemAvailable(needPageIndex))
  113.                 return
  114.  
  115.             positionViewAtIndex(needPageIndex, ListView.Contain)
  116.             currentIndex = needPageIndex
  117.             currentIndexChangedByNumberKey()
  118.             break;
  119.         default:
  120.             return
  121.         }
  122.         event.accepted = true;
  123.     }
  124.  
  125.     function tryNavigateUp() {
  126.         if (currentIndex <= 0) return false
  127.  
  128.         var newIndex = getNextAvailable(currentIndex, false)
  129.  
  130.         if (newIndex === currentIndex) {
  131.             upKeyLimit()
  132.             return false
  133.         }
  134.  
  135.         currentIndex = newIndex
  136.  
  137.         return true
  138.     }
  139.  
  140.     function tryNavigateDown() {
  141.         if (currentIndex >= count-1) return false
  142.  
  143.         var newIndex = getNextAvailable(currentIndex, true)
  144.  
  145.         if (newIndex === currentIndex) {
  146.             downKeyLimit()
  147.             return false
  148.         }
  149.  
  150.         currentIndex = newIndex
  151.         return true
  152.     }
  153.  
  154.     function tryNavigateTop() {
  155. //        if (currentIndex <= 0) return false
  156.  
  157.         var newIndex = getNextAvailable(-1, true)
  158.  
  159. //        if (newIndex === currentIndex)
  160.             topKeyLimit()
  161.  
  162.         currentIndex = newIndex
  163.  
  164.         return true
  165.     }
  166.  
  167.     function tryNavigateBottom() {
  168. //        if (currentIndex >= count-1) return false
  169.  
  170.         var newIndex = getNextAvailable(count, false)
  171.  
  172.  
  173. //        if (newIndex === currentIndex)
  174.             bottomKeyLimit()
  175.  
  176.         currentIndex = newIndex
  177.         return true
  178.     }
  179.  
  180.     function getIndexAvailable(ind) {
  181.         var i = -1
  182.         var result = -1
  183.  
  184.         while (i < ind) {
  185.             ++result
  186.             while (!getIsItemVisible(result) && result < count) {
  187.                 ++result
  188.             }
  189.             if (result >= count)
  190.                 break
  191.             ++i
  192.         }
  193.  
  194.         if (result >= count)
  195.             result = -1
  196.  
  197.         return result
  198.     }
  199.  
  200.     Component.onCompleted: {
  201.         if (!getIsItemAvailable(currentIndex)) {
  202.             currentIndex = getNextAvailable(currentIndex, true)
  203.         }
  204.     }
  205. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement