Friday, June 22, 2012

[QML] Detect mouse hover to change hover effect on ListView item

How can we do it ?

There are lots of trick to achieve this goal :
First, we use the onEntered, onExited signal of MouseArea to change the hover's opacity :

ListView {
    id: viewer
    width: 100
    height: 300
    model: 10
    delegate : viewerDelegate
}

Component {
   id: viewerDelegate
   Item {
      width: 100
      height: 30
     
      Rectangle {
         id: hoverFocusLightRect
         anchors.fill: parent
         color: "#lalala"
         opacity: 0
      }
     
      MouseArea {
            anchors.fill: parent
            hoverEnabled: true
            onEntered: {
                hoverFocusLightRect.opacity = 0.6;
            }
            onExited: {
                hoverFocusLightRect.opacity = 0;
            }
      }

      Text {
         anchors.fill: parent
         verticalAlignment: Text.AlignVCenter
         horizontalAlignment: Text.AlignHCenter
         text: index
      }
   }
}

Second, we use onPositionChanged instead of onEntered :

MouseArea {
            anchors.fill: parent
            hoverEnabled: true
            onPositionChanged: {
                hoverFocusLightRect.opacity = 0.6;
            }
            onExited: {
                hoverFocusLightRect.opacity = 0;
            }
      }

Both of these are ok, but if we press on one item , and leave the click on the other one, the onExited signal on pressed item won't be trigger, so the hover won't disappear.

The better method is to just use one boolean variant to enabled the hover effect :

ListView {
    id: viewer
    property bool enabledHover: false
    width: 100
    height: 300
    model: 10
    delegate : viewerDelegate
}

Component {
   id: viewerDelegate
   Item {
      width: 100
      height: 30
     
      Rectangle {
         id: hoverFocusLightRect
         anchors.fill: parent
         color: "#lalala"
         opacity: viewer.enabledHover ? 0.6 : 0
      }
     
      MouseArea {
            anchors.fill: parent
            hoverEnabled: true
            onPositionChanged: {                          (or onEntered)
                    viewer.enabledHover = true;
            }
      }

      Text {
         anchors.fill: parent
         verticalAlignment: Text.AlignVCenter
         horizontalAlignment: Text.AlignHCenter
         text: index
      }
   }
}

So the hover effect will display correctly, and the weird thing that show more than one hover will be disappear.

Build NSS & NSPR

1. 首先 download mozilla-build 並執行安裝 exe
2. 點選安裝目錄下 (C:\mozilla-build) 的 start-msvc9.bat
3. Download NSS (Network Security Services) src 與 NSPR (Netscape Portable Runtime) library :
a. Latest release for nss with nspr : https://ftp.mozilla.org/pub/mozilla.org/security/nss/releases/
b. NSS release note : http://www.mozilla.org/projects/security/pki/nss/release_notes.html
c. Build instruction : 你可以利用 CVS (Concurrent Versioning System)來 download nss 與 nspr 的 src 與 library, 並且按照 instruction 來 build nss, 不過用上面說的 gmake 來 compiler 需要先下載 gmake, 但有嘗試用 gmake 來 build 但會有些 c file 無法 include 到其需要的 header path, 所以可以用 make build, 這樣就可以成功了
1) export CVSROOT=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot"
2) cvs login
3) 看你要 donwload 哪一版的 version 打上
cvs co -r NSPR_X_X_X_RTM NSPR
cvs co -r NSS_X_X_X_RTM NSS

另外一個比較清楚的安裝與 build 的步驟如下
1. 將 nss 與 nspr 的 zip 解壓所到 c:\Temp 下
2. 點選 start-msvc9.bat
3. 打上 export OS_TARGET="WINNT"
4. 打上 export BUILD_OPT="1"
5. 打上 export HOME="/c/Temp" (or another folder with read / write access)
6. 改面目錄位置到 /c/Temp/nss-3.x.x/mozilla/security/nss
7. 打上 make nss_build_all
8. 大約等上幾分鐘後, 你 build 出來的目路會放在 C:\Temp\nss-3.x.x\mozilla\dist\WINNT5.1_OPT.OBJ\bin 下

Reference : http://support.mozilla.com/en-US/questions/687296#answer-112220