2013年1月30日 星期三

自訂屬性控制項

UEd的屬性視窗會根據屬性的型別使用不同的控制項,也提供開發者自訂屬性控制項的擴充功能。屬性控制項的基礎類別是WxItemPropertyControl,自訂屬性控制項必須直接或間接繼承此類別。因為UEd會利用wxWidget的RTTI機制建立控制項,開發者需要使用wxWidget提供的類別宣告和定義巨集註冊自訂類別。還要在DefaultEditor.ini檔設定屬性和自訂控制項的綁定,UEd才會使用自訂控制項取代預設的控制項。

自訂屬性控制項的綁定是存放在CustomPropertyItemBindings類別,有兩種格式:
  • CustomPropertyClasses:指定類別和屬性使用指定的控制項。
  • CustomPropertyTypeClasses:指定類別和型別,符合的屬性會使用指定的控制項。但指定的屬性型別必須是Object,所以不是繼承Object類別的屬性就不能使用這種綁定格式。這點可從原始檔PropertyWindow.cpp的UCustomPropertyItemBindings::GetCustomPropertyWindow()函式中得知,傳入的屬性會先轉型成物件屬性,轉型成功才會處理綁定。

範例


以下程式碼示範如何自訂一個支援當地化名稱的屬性控制項:
class WxCustomPropertyItem_Localized : public WxItemPropertyControl
{
public:

    DECLARE_DYNAMIC_CLASS(WxCustomPropertyItem_Localized);
    
    virtual RenderItemName( wxBufferedPaintDC& DeviceContext, const wxRect& ClientRect );
};
只需要繼承原本的類別,修改一下顯示名稱的部份即可。記得要使用DECLARE_DYNAMIC_CLASS和IMPLEMENT_DYNAMIC_CLASS來宣告和定義類別,才能支援wxWidget的RTTI機制。控制項類別的實作:
IMPLEMENT_DYNAMIC_CLASS( WxCustomPropertyItem_Localized, WxItemPropertyControl )

void WxCustomPropertyItem_Localized::RenderItemName( wxBufferedPaintDC& DeviceContext, const wxRect& ClientRect )
{
    ...
    
    FString LeftText;
    if( PropertyNode->GetArrayIndex() == -1 )
    {
        FString DisplayName = Property->GetMetaData( TEXT("DisplayName") );
        if( DisplayName.Len() > 0 )
        {
            LeftText = Localize( TEXT("UnrealEd"), *DisplayName, TEXT("UnrealEd"), NULL, TRUE );
            if( LeftText.Len() > 0 )
            {
                LeftText = DisplayName;
            }            
        }
        
        if( LeftText.Len() > 0 )
        {
            LeftText = GetDisplayName();
        }          
    }
    else
    
    ...
}
RenderItemName()函式的內容跟父類別是差不多的,只是修改了顯示名稱,相同的部分就省略了。在上面的第13行可以看到,這邊的寫法是將顯示名稱當作鍵來搜尋當地化字串,如果找不到就用原本的顯示名稱。所以可以確保如果某個語言沒有設定好,至少會用原本的名稱來顯示。

另外還要記得在DefaultEditor.ini裡加上類似下面第二行的設定才會生效:
[UnrealEd.CustomPropertyItemBindings]
.CustomPropertyClasses=(PropertyPathName="MyPackage.MyClass: MyVariable",PropertyItemClassName="WxCustomPropertyItem_Localized")

沒有留言:

張貼留言