1. 兩者都是MVC的模式,但是Shutter的model是二維數組,Blind的model是樹型的,它和JFace的TreeViewer是類似的
2. 兩者都是一些常見組件和自定義組件的合成。Shutter用了CoolButton和ScrollList。Blind用了Slat和QTree。實際上,Slat是CoolButton的精簡版本(刪了一些不常用的功能和少量的修改),只是名字不同。并且Blind在這方面比Shutter靈活,因為Shutter的內容區域只能是ScrollList,Blind的內容區可以是Composite。
3. Shutter沒有Item的概念,Blind參照了TreeViewer的實現,使用了Item來對應model,也就是在QTree中使用了自定義的Item對象QItem。
4. Shutter把model直接映射為一個CoolButton,所以好友一多,效率就低。QTree則是純繪制的。所以當時看了SWT的一些代碼,設計了QTree的重繪算法。在繪畫事件的時候,QTree會檢查哪些Item需要重畫(當然不是最優的,基本上湊合了一下),然后把繪畫事件轉發給QItem,由QItem自己來重繪自己。所以Blind的速度自然就快了。
5. 在布局上,Shutter使用的是自定義的SortLayout,Blind用的是SWT自帶的GridLayout。從3.0的時候開始,GridData有了一個exclude屬性,Blind就利用這個實現內容區的顯示和隱藏
6. QQ里面,好友頭像旁邊可以顯示攝像頭圖標,顯示手機圖標,等等。Shutter不支持這些小特性。所以QTree在設計的時候考慮了這些,主要反映在QItem的實現中。主要有這么幾個概念需要說明一下:
a) 攝像頭圖標,手機圖標,這些東西都是顯示在頭像旁邊的,我把它叫做附件(Attachment)。附件有最大個數限制,目前代碼里面是最多4個附件,你可以修改源代碼調整最大個數。附件放在什么地方,是在重畫算法里面計算的,保證了附件按一定規律擺放,不會重疊
b) 離開狀態的圖標,就是那個N/A字樣的圖標,它是顯示在頭像的右下角,和頭像是重疊的,我把這種叫做裝飾(Decoration)。裝飾最多4個,可以分別裝飾在頭像的4個角
所以呢,QTree就可以支持這些小特性了,你看我自己添加了一個QQ沒有的“好友置頂”的功能,置頂的好友會添加一個大頭針的附件圖標,就是這樣的來由了。
7. Shutter和Blind都有標簽編輯的功能,但是由于Shutter把model映射為CoolButton,所以編輯功能是在CoolButton里面提供的,實現起來輕易一些。QTree是一個純繪制的組件,為了實現Item的標簽編輯,我實現了一個ControlEditor的子類。具體細節就不說了,反正也就是看看SWT的代碼,琢磨了一下,如今細節也不太記得了。大致的原理很簡單,你要編輯Item標簽的時候,就新建一個Text控件,然后把Text定位到標簽的位置,然后要監視Text的FocusEvent和KeyEvent,同時要注重在卷滾條滾動的時候調整Text的位置,編輯完了就釋放這個Text。像這樣的功能,可能不實踐一下你覺得它很神奇,做過之后就發現原來就是這么簡單。
8. 頭像的跳動和閃爍這樣的功能,CoolButton和QTree都有,但是QTree更靈活一些,QTree的動畫實現很簡單,用一個列表保存哪些Item正在顯示動畫,然后在重畫的時候就畫下一幀就可以了。不過下一幀到底畫什么是可以自定義的,可以通過實現IEffect接口來自定義動畫方式,所以說QTree比CoolButton靈活一些。
9. 由于Blind是樹型的,所以還考慮了最大層數,每層的縮進量,每層的圖標大小等功能。本來開始想能夠設置每個Item的這些細節,但是太煩,后來想了想,覺得也沒什么意義,還是針對每層設置算了。
新聞熱點
疑難解答