CEGUI學習筆記二-- FalagardSkinning使用手冊第2章翻譯

CEGUI學習筆記二-- [翻譯]
FalagardSkinning使用手冊第2章
本文翻譯了FalagardSkinning使用手冊的第2章。

閱讀完本文,你將瞭解如何自定義一個控件外觀的方法,並且將看見自己剛剛的成果!


--------------------------------------------------------------------------------

首先需要說明的是,這個部分不是教你如何使用XML。因此我們假定讀者熟悉並知道如何使用XML。

2.1
開始前:一個空皮膚
在我們添加任何關於控件外觀的代碼之前,先讓我們寫一個XML文件的輪廓。這很簡單,如下格式:

 


<?xml version = "1.0"?>
<Falagard>
</Falagard>
我們會把自己定義的控件外觀加入到<Falagard>和</Falagard>之間。
因爲可以定義很多子節點(XML特性),因此我們可以把所有的外觀定義都寫在一個文件裏。

2.2
起步例子:Button
毫無疑問,按鈕是我們在任何UI中都可以看到的、使用最多的。所以我們從Button開始。
要定義任何控件皮膚,你需要使用WidgetLook元件,並且使用name屬性來給你定義的控件取一個名字。
因此開始的時候,我們會添加一個空的WidgetLook(控件外觀)到外觀初始化文件裏:

<WidgetLook name = "TaharezLook/Button">
</WidgetLook>

查詢手冊(FalagardSknning.pdf)可以知道,我們必須定義幾種指定特定的狀態外觀:
Normal
Hover
Pushed
Disabled

一旦我們查詢到了哪些狀態必須被定義,我們就把它們添加到外觀定義中去。雖然空的定義不會顯示任何東西,但最好這樣做,這樣至少我們的定義是完整可用的。

對於特定的顯示,我們使用外觀配置ImagerySection元素(節點)來描述。每一個外觀配置imagery sction都有一個名字,這個名字會在之後StateImagery的Layer定義中被引用。

對於我們的按鈕來說,每一個按鈕狀態都會有一個ImagerySection。我們把它們添加到正在製作的Button中。

  <WidgetLook name ="TaharezLook/Button">
    <ImagerySection name ="Normal_imagery">
    </ImagerySection>
    <ImagerySection name ="Hover_imagery">
    </ImagerySection>
    <ImagerySection name ="Pushed_imagery">
    </ImagerySection>
    <StateImagery name ="Normal">
    </StateImagery>
    <StateImagery name ="Hover">
    </StateImagery>
    <StateImagery name ="Pushed">
    </StateImagery>
    <StateImagery name ="Disabled">
    </StateImagery>
  </WidgetLook>
現在我們可以給每一個Section定義ImageryCommpnents。這個節點將告訴系統我們的按鈕顯示在屏幕上會是個什麼樣子。
TaharezLook給按鈕的每一種狀態都提供了3種Imagery。(除了Disabled,在這個狀態下,按鈕只使用了"normal_imagery",還用了一些不同的顏色)。可用的ImagerySections向我們提供了左、中、右3個組件。
有很多方法在控件上應用這些ImagerySection,雖然我們假定按鈕的繪製是 繪製兩頭(左、右),然後用中部件來填充這兩個之間的空缺。但實際上這些象素尺寸並沒有自動經過修正。之所以TaharezLook提供的圖片集沒出問題是因爲這個圖片集使用了自動縮放特性。因此如果你想使用自己所給定的外觀,注意尺寸的計算,這樣你才能得到預期的效果。

要指定如何繪製ImagerySection,我們需要使用ImageryCompnents。它作爲ImagerySection的子節點。好了,現在我們從添加一個空的ImageryCompnent到mormal_imagery節點開始。

    <ImagerySection name ="Normal_imagery">
      <ImageryComponent>
      </ImageryComponent>
    </ImagerySection>
首先加入到ImageryComponent的是一個Area節點定義,它會告訴系統應該在哪把圖象顯示出來。(控件座標)

      <ImageryComponent>
        <Area>
        </Area>
      </ImageryComponent>

       
我們從配置按鈕的左邊開始。這是最容易配置的組件,因爲我們知道一般都是(0,0)。設定這些絕對的值,我們使用AbsoluteDim。

我們使用Dim來描述需要自定義的圖象顯示區域。再使用子節點來給出它的值是多少:

      <ImageryComponent>
        <Area>
          <Dim type ="LeftEdge">
            <AbsoluteDim value="0"/>
          </Dim>
          <Dim type ="TopEdge">
            <AbsoluteDim value="0"/>
          </Dim>
        </Area>
      </ImageryComponent>
現在已經定義了(相對父窗口的)左間距和頂間距,接下來再定義顯示區域的大小。
我們希望使用圖片源自己的寬度大小,要這麼做的話,使用ImageDim來告訴這個元件應該訪問哪個圖片。

          <Dim type ="Width">
            <ImageDim imageset ="TaharezLook"
                      image ="ButtonLeftNormal"
                      dimension="Width"/>
          </Dim>
這段代碼就告訴系統 顯示區域寬度的大小和外觀了:
使用TaharezLook圖片集里名字叫ButtonLeftNormal的圖片區域,寬度爲圖片區域的默認值。

設置Area的最後一個部分是高度。一般來說我們希望顯示高度和我們定義的高度一直。因此我們可以使用UnifiedDim或者WidgetDim來做這個事。因爲不需要通過名字來查找控件,因此在這裏我們選擇使用更加簡潔的UnifiedDim來完成。

          <Dim type ="Height">
            <UnifiedDim scale ="1.0" type="Height"/>
          </Dim>

在這裏我們使用縮放值1.0來表示我們需要使顯示區域爲整個控件的高度。

現在我們已經完成了第一個外觀的Area設置。它整個的看起來是這個樣子:

      <ImageryComponent>
        <Area>
          <Dim type ="LeftEdge">
            <AbsoluteDim value="0"/>
          </Dim>
          <Dim type ="TopEdge">
            <AbsoluteDim value="0"/>
          </Dim>
          <Dim type ="Width">
            <ImageDim imageset ="TaharezLook" image ="ButtonLeftNormal" dimension="Width"/>
          </Dim>
          <Dim type ="Height">
            <UnifiedDim scale ="1.0" type="Height"/>
          </Dim>
          </Area>
      </ImageryComponent>
接下來,我們需要告訴系統顯示哪張圖片。我們用Image來完成這個事,它緊接着Area。

<Image imageset ="TaharezLook" image="ButtonLeftNormal"/>
在ImageryComponent中需要添加的最後一個元素是VertFormat。
通過設置這個元素,我們可以通知系統在顯示圖片的時候,在垂直方向上做拉伸,以完全覆蓋我們定義的Area顯示區域。

      <VertFormat type="Stretched"/>
現在我們完成了按鈕的左部件的設置,讓我們完整的來看一下:

      <ImageryComponent>
        <Area>
          <Dim type ="LeftEdge">
            <AbsoluteDim value="0"/>
          </Dim>
          <Dim type ="TopEdge">
            <AbsoluteDim value="0"/>
          </Dim>
          <Dim type ="Width">
            <ImageDim imageset ="TaharezLook" image ="ButtonLeftNormal" dimension="Width"/>
          </Dim>
          <Dim type ="Height">
            <UnifiedDim scale ="1.0" type="Height"/>
          </Dim>
        </Area>
        <Image imageset ="TaharezLook" image="ButtonLeftNormal"/>
        <VertFormat type ="Stretched"/>
      </ImageryComponent>
下一張需要設置的圖片是右部件。我們可以精確的把顯示區域設置爲整個圖象,但是有一個更好的辦法就是,我們使用對齊格式來指明需要在右邊顯示。

用這樣的方式來設置控件的部件也將是你使用的最多的手段,現在來看看代碼是如何寫的:

      <ImageryComponent>
        <Area>
          <Dim type ="LeftEdge"><AbsoluteDim value="0"/></Dim>
          <Dim type ="TopEdge"><AbsoluteDim value="0"/></Dim>
          <Dim type ="Width"><UnifiedDim scale ="1.0" type="Width"/></Dim>
          <Dim type ="Height"><UnifiedDim scale ="1.0" type="Height"/></Dim>
        </Area>
        <Image imageset ="TaharezLook" image="ButtonLeftNormal"/>
        <VertFormat type ="Stretched"/>
        <HorzFormat type ="RightAligned"/>
      </ImageryComponent>
對於normal_imagery,最後需要設置的是中間部件。記住我們希望這個圖象自動的填充另外2個部件之間的空白部分。
只需要正確的定義了圖片區域就可以正確的顯示了。

首先我們需要告訴系統左邊距,很明顯是左部件的寬度。因此我們可以通過ImageDim來得到。


        <Area>
          <Dim type ="LeftEdge">
            <ImageDim imageset ="TaharezLook"
                      image ="ButtonLeftNormal"
                      dimension ="Width"
            />
          </Dim>
        </Area>
現在有趣的事情來了,我們需要告訴系統中間部件的寬度。如果我們知道控件的實際大小,那我們可以自己計算出精確的座標信息。但是我們事先並不知道控件的整體寬度,因此我們需要另外的計算方法。幸運的是,我們可以通過XML語法來使系統在顯示之前進行預先計算。使用DimOperator就可以搞定這個事。
在展示代碼之前,讓我們來看看計算公式:

中間部件的寬度=控件寬度-(右部件寬度+左部件寬度)。

同時我們還需要計算右邊距:

中間部件的右邊距=控件寬度-右部件寬度

好,讓我們先從右邊距開始:


               <Dim type="RightEdge">
               </Dim>
首先我們得到控件的寬度:


               <Dim type="RightEdge">
                 <UnifiedDim scale = "1.0" type="Width">
                 </UnifiedDim>
               </Dim>
然後在添加進行減法運算的代碼


               <Dim type="RightEdge">
                 <UnifiedDim scale = "1.0" type="Width">
                   <DimOperator op="Subtract">
                   </DimOperator>
                 </UnifiedDim>
               </Dim>
我們再將得到右部件寬度的代碼添加到減法操作節點裏去


               <Dim type="RightEdge">
                 <UnifiedDim scale = "1.0" type="Width">
                   <DimOperator op="Subtract">
                      <ImageDim imageset ="TaharezLook"
                                image ="ButtonRightNormal"
                                dimension ="Width"
                       />
                   </DimOperator>
                 </UnifiedDim>
               </Dim>
這樣我們就得到了右邊距的大小。
在進行更加複雜的運算之前,先來看2個關於運算先後次序的規則:
1、每一對DimOperator定義了一個操作,順序是從最裏面的DimOperator定義開始計算,然後是外層的。
2、結合律不滿足實際運算,只按照DimOperator的順序從往外開始計算。
比如:(LineSpacing + 4)*2,如果我們寫成:


...
<FontDim type ="LineSpaceing">
  <DimOperator op="Add">
    <AbsoluteDim value="4">
      <DimOperator op="Multiply">
        <AbsoluteDim value="2">
      </DimOperator>
    </AbsoluteDim>
  </DimOperator>
</FontDim>
...
上面的計算公式是:4*2+LineSpacing。顯然這不是我們想要的

應該是:

<AbsoluteDim value="2">
  <DimOperator op="Multiply">
    <AbsoluteDim value="4">
      <DimOperator op="Add">
        <FontDim type ="LineSpaceing"/>
      </DimOperator>
    </AbsoluteDim>
  </DimOperator>
</AbsoluteDim>
首先計算了 temp = 4+LineSpaceing;
然後將臨時結果temp返回到上層,進行第2步計算 result = 2 * temp;

OK,我離題了。讓我們重新回到我們的按鈕顯示上來。
既然計算的問題解決了,那麼唯一的問題就是設置水平顯示模式HorzFormat了,在這裏我們將他設置爲拉伸。


        <HorzFormat Type="Stretched"/>

現在我們來看看完整的中間部件的代碼


      <ImageryComponent>
        <Area>
          <Dim type ="LeftEdge">
            <ImageDim imageset ="TaharezLook"
                      image ="ButtonLeftNormal"
                      dimension ="Width"
            />
          </Dim>
          <Dim type="RightEdge">
            <UnifiedDim scale = "1.0" type="Width"/>
            <DimOperator op="Subtract">
              <ImageDim imageset ="TaharezLook"
                      image ="ButtonRightNormal"
                      dimension ="Width"
              />
            </DimOperator>
          </Dim>
          <Dim type ="TopEdge"><AbsoluteDim value="0"/></Dim>
          <Dim type ="Height"><UnifiedDim scale ="1.0" type="Height"/></Dim>
        </Area>
        <Image imageset ="TaharezLook" image="ButtonLeftNormal"/>
        <VertFormat type ="Stretched"/>
        <HorzFormat Type="Stretched"/>
      </ImageryComponent>

現在我們已經完成了normal_imagery section的外觀設置。你可以用類似的方法將另外2個外觀搞定,實際上在這裏例子裏,你只需要根據按鈕Hover或者Pushed狀態來替換相關的圖片名字。一切都跟我們先前配置normal_imagery時一樣。

現在我們可以在各種狀態節點中添加對各種外觀的引用了。對外觀的引用需要在Layer節點中定義。很可能在每一個Layer中都包含多個外觀配置。雖然在大多數例子你,你只看到了一個Layer。
現在讓我們爲按鈕的Normal狀態來添加一個外觀。

    <StateImagery name ="Normal">
      <Layer>
        <Section section="normal_imagery"/>
      </Layer>
    </StateImagery>
Hover和Pushed狀態除了圖片和名字不一樣以外,其他沒什麼不同。

Disabled狀態稍微有些不同;我們不爲這個狀態重新編寫任何外觀,我們將複用normal_imagery。但是我們將指定一些顏色,使按鈕處於這種狀態時顯示爲灰色。這個工作在Section節點中的Colours節點中完成,先來看看範例:

    <StateImagery name ="Disabled">
      <Layer>
        <Section section="normal_imagery">
          <Colours
            topLeft="FF7F7F7F"
            topRight="FF7F7F7F"
            bottomLeft="FF7F7F7F"
            bottomRight="FF7F7F7F"
          />
        </Section>
      </Layer>
    </StateImagery>
現在我們的按鈕在各種默認狀態下都有外觀了。但是我們少做了一件事情:我們需要在按鈕上顯示一些文字。

爲了指定文字,你需要使用TextComponent節點,當然可以象在ImagerySection中加入ImageryComponent節點一樣,在每一個外觀配置里加入TextComponent,但是這樣實在是太羅嗦了。一個更好的方法是定義一個包含文本的ImagerySection,然後我們就可以在所有狀態下複用了。
這樣我們就從定義包含文本元件的ImagerySection開始吧:


    <ImagerySection name ="label">
      <TextComponent>
      </TextComponent>
    </ImagerySection>
定義一個文本元件TextComponent和定義外觀元件ImageryComponent很相似,我們指定一個區域的大小和它的顯示格式,用來顯示文本。我們也可以通過使用Text節點來明確指示出字體和(或)字符串。如果不做這些設置,元件也可以通過控件的設置來得到這些設置。
我們希望Area居中顯示,因此我們需要將文本元件的顯示區域設置爲整個控件。
同樣我們需要爲文本設置居中,因此垂直格式就象這樣:
 

       <VertFormat type ="CentreAligned"/>

水平格式就象這樣:


        <HorzFormat type ="WordWrapCentreAligned"/>

最後整個Label外觀設置的定義就象這樣:


    <ImagerySection name ="label">
      <TextComponent>
        <Area>
          <Dim type="LeftEdge"><AbsoluteDim value="0"/></Dim>
          <Dim type="TopEdge"><AbsoluteDim value="0"/></Dim>
          <Dim type="Width"><UnifiedDim scale="1" type="Width"/></Dim>
          <Dim type="Height"><UnifiedDim scale="1" type="Height"/></Dim>
        </Area>
        <VertFormat type ="CentreAligned"/>
        <HorzFormat type ="WordWrapCentreAligned"/>
      </TextComponent>
    </ImagerySection>

現在就差往各個Layer添加這個外觀了,Normal狀態的代碼如下:


    <StateImagery name ="Normal">
      <Layer>
        <Section section="normal_imagery"/>
        <Section section="label"/>
      </Layer>
    </StateImagery>

至於Disabled狀態,則需要添加另外一些指定的顏色。


    <StateImagery name ="Disabled">
      <Layer>
        <Section section="normal_imagery">
          <Colours
            topLeft="FF7F7F7F"
            topRight="FF7F7F7F"
            bottomLeft="FF7F7F7F"
            bottomRight="FF7F7F7F"
          />
        </Section>
        <Section section="label">
          <Colours
            topLeft="FF7F7F7F"
            topRight="FF7F7F7F"
            bottomLeft="FF7F7F7F"
            bottomRight="FF7F7F7F"
          />
        </Section>
      </Layer>
    </StateImagery>

關於介紹就到這裏了。需要完整的例子,以及全部其他的控件定義,可以參看CEGUI發行版的looknfeel文件夾裏的文件。目錄爲:"cegui_mk2/Samples/datafiles/looknfeel"

--------------------------------------------------------------------
1、一定要按照文檔的介紹,自己寫一寫這些代碼,注意不要抄錯了,否則你無法真正瞭解作者在說什麼。當然,如果你不明白我那些翻譯在說什麼,一定要去看英文的。

2、編寫XML文檔的時候容易出錯,最好導入xsd文件以驗證正確性。方法爲:視圖-其他窗口-屬性窗口-架構,將looknfeel文件夾裏的falagard.xsd添加進來。這樣就有語法和規則檢測了。

3、我們寫了這麼一個Button外觀配置,如果能直接看到它那該多好~
最好的途徑是自己寫例子來驗證,比如上次我留下的作業,如果你已經實現了通過Layout文件來創建窗口,那就好驗證了。不過沒關係,我們也可以使用CELayoutEditor.exe來驗證我們的成果。首先,這個軟件是直接加載TaharezLook.scheme的,所以我們直接去對應的TaharezLook.looknfeel裏,將我們的按鈕添加進去,爲了防止重複命名,我們把剛纔寫的Button外觀改成Button1,或者任何你想要叫的名字。

4、現在視感文件裏已經有Button1的外觀了,我們再來設置falagard映射。這個很簡單,到TaharezLook.scheme文件裏照着Button複製一下,然後修改WindowType = "TaharezLook/Button1", LookNFeel = "TaharezLook/Button1"。

5、啓動CELayoutEditor.exe,添加我們剛剛寫的按鈕看看?

6、現在我可以完全理解Imageset,知道looknfeel,大概知道scheme文件都是些什麼東西了,不過在我完全理解以前,不會自以爲是的去向大家傳遞錯誤的信息:)

 

本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/kun1234567/archive/2008/04/10/2279124.aspx

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章