天天看點

Duilib 源碼分析之 CButtonUI 篇

Duilib 中的

CButtonUI

繼承自

CLabelUI

, 在可以顯示文字的基礎上可以顯示不同狀态下的圖檔,不同狀态的文字也可能顯示不同。 但由于重寫了

void PaintText(HDC hDC)

方法,

CButtonUI

繪制文字的功能并沒有

CLabelUI

關于

CButtonUI

設定不同的圖檔、文字顔色等相關的代碼就不一一介紹了,現在所一下比較重要的成員方法和成員變量。 在介紹具體的代碼之前,首先說明一下不同的 Duilib 版本的不同。 我這裡有兩個不同的版本,分别來自 “Duilib 開源項目圈2群” 和 “https://github.com/duilib/duilib“. 前者包含了一個綁定特定

CTabLayout

控件的功能,後者多了一個背景圖 HOVER 和 NORMAL 狀态切換時的漸隐漸現的效果。 在這個文章中都會予以介紹

CButtonUI

中重中之重的兩個方法:

DoEvent

DoPaint

。 其實對于所有的控件都是,一個控制行為,一個控制顯示,是核心方法。

  • void DoEvent(TEventUI& event)
    if( event.Type == UIEVENT_SETFOCUS ) 
    {
        Invalidate();
    }
    if( event.Type == UIEVENT_KILLFOCUS ) 
    {
        Invalidate();
    }
               
    焦點相關的處理。 因為我們有可能對按鈕在有焦點和無焦點的情況下設定不同的背景圖或者文字顔色,是以需要在焦點狀态改變的時候調用

    Invalidate()

    。 但若沒有這樣的需求,可以不處理以上 2 個事件
    • UIEVENT_BUTTONDOWN

    • UIEVENT_DBLCLICK

    • UIEVENT_MOUSEMOVE

    • UIEVENT_MOUSEENTER

    • UIEVENT_MOUSELEAVE

    以上事件的處理,主要是對于

    m_uButtonState

    的控制,代表按鈕目前不同的狀态,進而顯示不同的圖檔。在

    DoPaint

    時正是通過對

    m_uButtonState

    值的不同繪制不同的圖檔的
    • UIEVENT_BUTTONUP

    這個事件也會修改

    m_uButtonState

    ,但不同的是在滑鼠松開的時候若在目前控件内部,則會觸發 Click 事件
    • UIEVENT_CONTEXTMENU

    右鍵菜單事件,在按鈕支援此事件的情況下,我們可以在收到

    DUI_MSGTYPE_MENU

    時進行需要的處理

    接下來,我介紹一下上文提到的“漸隐漸現”的功能。請關注以下幾個定義:

    • FADE_TIMERID

      用來調整透明度的 Timer 的 ID
    • FADE_ELLAPSE

      Timer 的間隔時間, 30ms,這個我建議也做成可以通過參數配置的
    • m_uFadeAlpha

      圖檔的透明度,代表 Normal 狀态下的圖檔, 相應的 Hot 狀态下的透明度為

      255 - m_uFadeAlpha

    • m_uFadeAlphaDelta

      每經過

      FADE_ELLAPSE

      的時間後,透明度變化的大小
    在滑鼠進入和滑鼠離開的事件觸發時,也就是透明度開始需要變化的時刻,此時啟動 Timer。 在 Timer 的響應中,通過判斷按鈕的狀态,來決定

    m_uFadeAlpha

    值是需要不斷減小還是不斷增大。當到 0 或者 255 時結束 Timer。 而

    m_uFadeAlpha

    值的使用就在

    DoPaint

    中了

    剩下的功能就是所謂的綁定

    CTabLayout

    了,這個功能在實際的使用中很友善又很簡單。一般來說,如果我們要實作一個點選不同的按鈕來切換标簽頁中不同的顯示内容時,一般都是在

    Notify

    中對于的按鈕點選事件中做處理。 而現在是直接将該功能封裝到控件内部了。

    請關注以下兩個成員變量:

    • int m_iBindTabIndex

      目前按鈕對應于

      CTabLayout

      的第幾個标簽頁
    • CDuiString m_sBindTabLayoutName

      目前按鈕所綁定的

      CTabLayout

      的 name
    之後,在

    Active()

    的進行中,我們根據

    m_sBindTabLayoutName

    找到對應的

    CTabLayout

    控件,然後調用

    SelectItem

    選擇第

    m_iBindTabIndex

    個子标簽頁即可
  • void PaintStatusImage(HDC hDC)

    這個函數相當重要,但是邏輯又很簡單,主要就是判斷的目前按鈕不同的狀态來繪制不同的圖檔。大家稍微需要關注一點的就是,繪制的順序,大體來說,就是哪個狀态決定性最強,就先執行哪個狀态對應的 if 語句。詳細内容暫不贅述了。

  • void PaintText(HDC hDC)

    這個方法,每個 Duilib 版本又有不同,有的版本完全繼承了

    CLableUI

    的強大的文字繪制能力,有的隻是提供了簡單的文字繪制,例如隻支援了以下幾種狀态不同的文字顔色而已,大家了解一下就可以了,詳細的可以參考自己所使用的 Duilib
    • Normal
    • Disable
    • Pushed
    • Hot
    • Focused

繼續閱讀