cegui 4
建立CEGUI視窗入門 講述如何建立一個簡單的CEGUI視窗.
所有的控制項都是視窗
這是最重要的概念。所有的控制項類都是從Window這個基類派生出來的,所以,在此教程中,每當我提到一個視窗的時候,它可以是一個按鈕也可以是一個捲軸控制項。
很多的設定都會被繼承下去
CEGUI中,視窗的很多的設定和屬性都會按視窗父子等級向下傳遞。比如:如果你將一個視窗的alpha透明度設定為0.5,那麼,預設情況下,所有附屬於那個視窗的子視窗/組件都將受到影響。同時要注意:子視窗的實際設定並沒有改變 ---- 最終的屬性值通常是由最頂層到當前視窗所有屬性值組合而成的。好多東西都有這個規律,比如視窗的銷毀:預設情況下,一個視窗在銷毀的時候將銷毀它的所有子視窗。這一機制最大的優點是:通過改變根視窗的alpha透明度、顯示/隱藏、啟用/禁用狀態等可以很輕易的控制整個GUI;通過簡單的銷毀根視窗就可以輕鬆的清空整個GUI。當個別視窗需要更精確的控制或有更好的管理技術用的時候,可以更改這一預設繼承機制。
建立視窗
有兩種方法來建立視窗:通過C++寫入程式碼實現和通過XML布局檔案實現。下面將討論這兩種方法。
CEGUI的所有視窗都是被WindowManager這一對象建立的。你可以通過getSingleton函數獲得這個對象,代碼如下:
using namespace CEGUI;
WindowManager& wmgr = WindowManager::getSingleton();
一般情況,你將用DefaultWindow(或者它的老名字:DefaultGUISheet)作為GUI的“root”視窗。這點並不是必須的,但它是使用CEGUI很好的習慣,而且可以協助簡化布局。下一步,我們將建立一個DefaultWindow作為GUI的根視窗(這裡sheet是root的意思)。
Window* myRoot = wmgr.createWindow( "DefaultWindow", "root" );
System::getSingleton().setGUISheet( myRoot );
indowManager::createWindow函數有兩個string類型的參數。第一個參數,本例中為“DefaultWindow”,告訴系統你要建立的視窗類別型或類。通常,你可以使用的視窗類別型是那些當你載入scheme檔案的時候註冊的視窗類別。而有些像DefaultWindow這樣的是全域類型,它們總是可用的。第二個參數,本例中為“root”,是一個將要賦予這個視窗的獨一無二的名字。以後可以通過這個名字擷取指向這個視窗的指標。注意:並不是一定要給你的根視窗命名為“root”,但這是通常的命名規範。
System::setGUISheet函數用來指定一個視窗作為GUI的根視窗。這將替換掉當前的根視窗,但是要注意:之前的一系列視窗/控制項並沒有被銷毀,只是從當前的顯示鏈中摘除 ---- 通過使用setGUISheet函數,你可以輕鬆的在多個GUI中切換。
現在,你已經建立了第一個視窗並把它附著在GUI系統上,當系統畫GUI的時候,它將把這個視窗作為GUI的根。但是,如果你編譯運行這些代碼,你依然不會看到任何東西。怎麼了?你的程式沒有任何問題,問題在:我們剛才建立的DefaultWindow是隱藏的!這就是為什麼DefaultWindow那麼適合做根視窗的原因:它僅僅被用作供其他的視窗和控制項依附的空畫布。那麼,我們再加把勁吧。。。現在,我們將要建立一個架構視窗:這個視窗和你案頭上的視窗很類似,它有一個標題列,也可以移動和改變大小。代碼如下:
FrameWindow* fWnd = (FrameWindow*)wmgr.createWindow(
"TaharezLook/FrameWindow", "testWindow" );
此代碼建立了一個“TaharezLook/FrameWindow”視窗。整個系統都使用這種命名規範:視窗類別型以組件組名做為首碼(假如你載入了WindowsLook scheme,你就可以建立一個“WindowsLook/FrameWindow”對象)。我們為這個新視窗命名為“testWindow”。需要注意的是:那個類型轉換的使用,由於createWindow函數總是返回Window基類指標,儘管對於此例以及其他情況,返回這個Window指標就足夠了,但是有時你需要訪問子類的方法,所以使用CEGUI的時候樣本中的類型轉換是很常見的。
為了讓系統能夠用我們的新視窗做一些有用的事情,我們還需要做一些事情。
首先,我們必須把這個新視窗附著到我們上面指定的根視窗上,代碼如下:
myRoot->addChildWindow( fWnd );
現在,我們可以設定它的位置和大小。CEGUI使用一個“統一的(unified)”座標系,使得可以同時使用相對部分和絕對部分 ---- 這就是為什麼你看到的每個座標都由兩個部分組成。
// 定位在其父視窗左上方開始的1/4位置
fWnd->setPosition(UVector2( UDim( 0.25f, 0 ), UDim( 0.25f, 0 ) ) );
// 設定其大小為其父視窗的一半
fWnd->setSize( UVector2( UDim( 0.5f, 0 ), UDim( 0.5f, 0 ) ) );
最後,我們為這個架構視窗的標題列設定一個標題:
fWnd->setText( "Hello World!" );
XML布局
上面的方法看起來很不錯,但是,它有一個很大的弊端:每次你想要調整GUI布局的時候,你就得去修改代碼,然後重新編譯。這樣還不累死了?你真正想要做的是能夠把布局儲存在檔案中,然後在代碼中調用那個布局檔案。
系統支援XML格式的布局檔案,可以通過WindowManager::loadWindowLayout函數載入此檔案。此函數為你建立所有的視窗並返回一個指向根視窗的指標。調用setGUISheet設定GUI的根視窗的時候用此指標再適合不過了。
所以,首先我們需要一個布局檔案。下面這個XML檔案所描述的視窗和我們上面用C++建立的視窗是一樣的:
<guilayout>
<window type="DefaultWindow" name="root">
<window type="TaharezLook/FrameWindow" name="testWindow">
<property name="UnifiedPosition" value="{{0.25,0},{0.25,0}}">
<property name="UnifiedSize" value="{{0.5,0},{0.5,0}}">
<property name="Text" value="Hello World!">
</property></property></property></window>
</window>
</guilayout>
Window元素的屬性和WindowManager::createWindow函數的參數是一一對應的。參見上面討論過的createWindow 函數。
鑲嵌的Window元素用來表明視窗的父子關係。注意:在一個布局檔案中,你僅可以擁有一個“根”層級的視窗,這也是通常情況下把DefaultWindow用作根視窗的另一個原因。
Property元素是用來設定當前視窗的屬性的。每種視窗/控制項類都有很多屬性,而且每個類都從它的父類中繼承所有的屬性。可以在這裡查看所有寫入程式碼屬性以及它們的格式。由於“Falagard”蒙皮('Falagard' skins)可以建立自己的屬性,你所使用的視窗可能會有更多的屬性 ---- 對於那些“軟編碼”屬性,你需要參閱你所使用的蒙皮的相關文檔(參看樣品蒙皮TaharezLook和WindowsLook)。
如果儲存此布局檔案為“test.layout”,你可以按如下方法載入並設定GUI根視窗:
using namespace CEGUI;
Window* myRoot = WindowManager::getSingleton().loadWindowLayout(
"test.layout" );
System::getSingleton().setGUISheet( myRoot );
編譯運行後得到的結果和前面用C++寫的程式是一樣的。不過,現在你可以輕鬆修改、增強GUI布局而不用修改、重新編譯代碼啦。
本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/bluekane/archive/2009/01/09/3738439.aspx