- Timestamp:
- Mar 22, 2010, 3:41:51 PM (15 years ago)
- Location:
- code/branches/chat/src/orxonox/graphics
- Files:
-
- 1 added
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/chat/src/orxonox/graphics/ChatBox.h
r6596 r6597 6 6 #include "CEGUI/CEGUIXMLAttributes.h" 7 7 8 class DemoSample: public CEGuiSample8 class ChatBox : public CEGuiSample 9 9 { 10 public: 11 bool initialiseSample() 12 { 13 using namespace CEGUI; 14 try 15 { 16 // Retrieve the window manager 17 WindowManager& winMgr = WindowManager::getSingleton(); 10 public: 11 bool initialiseSample(); 12 void cleanupSample(void); 13 bool Event_HistorySizeChange(const CEGUI::EventArgs& args) 14 bool Event_ChatTextAdded(const CEGUI::EventArgs& args) 15 bool Event_FontChange(const CEGUI::EventArgs& args) 16 void setHistorySize(const size_t& pSize) 17 void addChatText(const CEGUI::String& pText) 18 void registerFont(const CEGUI::String& pLogicalName, const CEGUI::String& pFileName) 18 19 19 // Load the TaharezLook scheme and set up the default mouse cursor and font 20 SchemeManager::getSingleton().loadScheme("TaharezLook.scheme"); 21 System::getSingleton().setDefaultMouseCursor("TaharezLook", "MouseArrow"); 22 if(!FontManager::getSingleton().isFontPresent("Commonwealth-10")) 23 FontManager::getSingleton().createFont("Commonwealth-10.font"); 20 protected: 21 CEGUI::Font* makeFont(const CEGUI::String& pFontName, const CEGUI::String& pFileName, const CEGUI::String& pSize) 22 void changeFont(const CEGUI::String& pFontLogicalName, const CEGUI::String& pFontSize) 24 23 25 // Set the GUI Sheet 26 Window* sheet = winMgr.createWindow("DefaultWindow", "root_wnd"); 27 System::getSingleton().setGUISheet(sheet); 28 29 // Load a layout 30 Window* guiLayout = winMgr.loadWindowLayout("ChatBox.layout"); 31 sheet->addChildWindow(guiLayout); 32 33 // Obtain the handles of some widgets 34 Window* historySize = winMgr.getWindow("/ChatBox/History"); 35 Window* fontName = winMgr.getWindow("/ChatBox/FontName"); 36 Spinner* fontSize = static_cast<Spinner*>(winMgr.getWindow("/ChatBox/FontSize")); 37 Window* chatText = winMgr.getWindow("/ChatBox/Text"); 38 39 // Disable widgets until a valid font is registered 40 fontName->setEnabled(false); 41 fontSize->setEnabled(false); 42 chatText->setEnabled(false); 43 44 // Retrieve the design-specified values 45 mHistorySize = static_cast<size_t>(PropertyHelper::stringToUint(historySize->getText())); 46 mDefaultFontSize = fontSize->getText(); 47 mChatFontName = fontName->getText(); 48 setHistorySize(mHistorySize); 49 fontName->setText(""); 50 51 // Configure the history size 52 // Pressing <ENTER> changes the maximal number of entries within the history Listbox 53 historySize->subscribeEvent(Editbox::EventTextAccepted, Event::Subscriber(&DemoSample::Event_HistorySizeChange, this)); 54 55 // Configure the text Editbox 56 // Pressing <ENTER> puts the text into the history Listbox 57 chatText->subscribeEvent(Editbox::EventTextAccepted, Event::Subscriber(&DemoSample::Event_ChatTextAdded, this)); 58 59 // Configure the font name Combobox 60 // Selecting a name changes the font used in the history Listbox and the text Editbox 61 fontName->subscribeEvent(Combobox::EventTextChanged, Event::Subscriber(&DemoSample::Event_FontChange, this)); 62 63 // Configure the font size Spinner 64 // Selecting a size changes the font size used in the history Listbox and the text Editbox 65 fontSize->subscribeEvent(Spinner::EventValueChanged, Event::Subscriber(&DemoSample::Event_FontChange, this)); 66 fontSize->setTextInputMode(Spinner::Integer); 67 fontSize->setMinimumValue(4.0f); 68 fontSize->setMaximumValue(72.0f); 69 fontSize->setStepSize(1.0f); 70 fontSize->setCurrentValue(PropertyHelper::stringToFloat(mDefaultFontSize)); 71 72 // Initialize the list of fonts 73 // The first registered font becomes the active font 74 registerFont("Commonwealth", "Commonv2c.ttf"); 75 registerFont("DejaVuSans", "DejaVuSans.ttf"); 76 registerFont("Iconified", "Iconiv2.ttf"); 77 registerFont("MissingFile", "MissingFile.ttf"); // What happens if a font is missing? 78 registerFont("Pixmap Font", "FairChar-30.font"); // And what about a non-Freetype font? 79 } 80 catch(Exception &e) 81 { 82 #if defined( __WIN32__ ) || defined( _WIN32 ) 83 MessageBox(NULL, e.getMessage().c_str(), "Error initializing the demo", MB_OK | MB_ICONERROR | MB_TASKMODAL); 84 #else 85 //std::cout << "Error initializing the demo:" << e.getMessage().c_str() << "\n"; 86 #endif 87 } 88 89 return true; 90 } 91 92 void cleanupSample(void) 93 { 94 } 95 96 bool Event_HistorySizeChange(const CEGUI::EventArgs& args) 97 { 98 using namespace CEGUI; 99 100 WindowManager& winMgr = WindowManager::getSingleton(); 101 CEGUI::Window* historySize = winMgr.getWindow("/ChatBox/History"); 102 int size = PropertyHelper::stringToInt( historySize->getText() ); 103 setHistorySize(size); 104 return true; 105 } 106 107 bool Event_ChatTextAdded(const CEGUI::EventArgs& args) 108 { 109 using namespace CEGUI; 110 111 WindowManager& winMgr = WindowManager::getSingleton(); 112 Editbox* chatText = static_cast<Editbox*> (winMgr.getWindow("/ChatBox/Text")); 113 addChatText(chatText->getText()); 114 115 // Clear the text in the Editbox 116 chatText->setText(""); 117 return true; 118 } 119 120 bool Event_FontChange(const CEGUI::EventArgs& args) 121 { 122 using namespace CEGUI; 123 WindowManager& winMgr = WindowManager::getSingleton(); 124 Window* fontName = winMgr.getWindow("/ChatBox/FontName"); 125 String name = fontName->getText(); 126 127 Spinner* fontSize = static_cast<Spinner*>(winMgr.getWindow("/ChatBox/FontSize")); 128 String size = PropertyHelper::floatToString(fontSize->getCurrentValue()); 129 130 Window* chatText = winMgr.getWindow("/ChatBox/Text"); 131 chatText->setText(name + " - " + size); 132 133 changeFont(name, size); 134 return true; 135 } 136 137 void setHistorySize(const size_t& pSize) 138 { 139 using namespace CEGUI; 140 141 if(pSize > 0) 142 { 143 // A better validation would be to enforce a minimal and a maximal size 144 mHistorySize = pSize; 145 146 WindowManager& winMgr = WindowManager::getSingleton(); 147 Listbox* chatHistory = static_cast<Listbox*> (winMgr.getWindow("/ChatBox/List")); 148 ListboxItem* chatItem; 149 while(chatHistory->getItemCount() > mHistorySize) 150 { 151 // There are too many items within the history Listbox, purging them one at a time 152 chatItem = chatHistory->getListboxItemFromIndex(0); 153 chatHistory->removeItem(chatItem); 154 } 155 } 156 } 157 158 void addChatText(const CEGUI::String& pText) 159 { 160 using namespace CEGUI; 161 162 WindowManager& winMgr = WindowManager::getSingleton(); 163 Listbox* chatHistory = static_cast<Listbox*> (winMgr.getWindow("/ChatBox/List")); 164 165 // If there's text then add it 166 if(pText.size()) 167 { 168 // Add the Editbox text to the history Listbox 169 ListboxTextItem* chatItem; 170 if(chatHistory->getItemCount() == mHistorySize) 171 { 172 /* We have reached the capacity of the Listbox so re-use the first Listbox item. 173 This code is a little crafty. By default the ListboxTextItem is created with 174 the auto-delete flag set to true, which results in its automatic deletion when 175 removed from the Listbox. So we change that flag to false, extract the item 176 from the Listbox, change its text, put the auto-delete flag back to true, and 177 finally put the item back into the Listbox. */ 178 chatItem = static_cast<ListboxTextItem*>(chatHistory->getListboxItemFromIndex(0)); 179 chatItem->setAutoDeleted(false); 180 chatHistory->removeItem(chatItem); 181 chatItem->setAutoDeleted(true); 182 chatItem->setText(pText); 183 } 184 else 185 { 186 // Create a new listbox item 187 chatItem = new ListboxTextItem(pText); 188 } 189 chatHistory->addItem(chatItem); 190 chatHistory->ensureItemIsVisible(chatHistory->getItemCount()); 191 } 192 } 193 194 void registerFont(const CEGUI::String& pLogicalName, const CEGUI::String& pFileName) 195 { 196 using namespace CEGUI; 197 198 // Ensure that font names are registered only once 199 if(mFontList.find(pLogicalName) == mFontList.end()) 200 { 201 // Test the font so that only valid fonts are available 202 String testFont = mChatFontName; 203 if(mFontList.size() != 0) 204 { 205 // If the list is empty then attempt to create the font using the "real" font name 206 // Otherwise use a "test" font name so as not to corrupt the "real" one 207 testFont += "__test_font__"; 208 } 209 Font* font = makeFont(testFont, pFileName, mDefaultFontSize); 210 if(mFontList.size() != 0 211 && FontManager::getSingleton().isFontPresent(testFont)) 212 { 213 // Since this was only a test font we destroy it 214 FontManager::getSingleton().destroyFont(testFont); 215 } 216 if(!font) 217 { 218 // This font is invalid 219 if(FontManager::getSingleton().isFontPresent(testFont)) 220 return; 221 else 222 return; 223 } 224 225 WindowManager& winMgr = WindowManager::getSingleton(); 226 Combobox* fontName = static_cast<Combobox*>(winMgr.getWindow("/ChatBox/FontName")); 227 mFontList[pLogicalName] = pFileName; 228 ListboxTextItem* fontNameItem = new ListboxTextItem(pLogicalName); 229 fontNameItem->setSelectionBrushImage("TaharezLook", "MultiListSelectionBrush"); 230 fontName->addItem(fontNameItem); 231 if(fontName->getItemCount() == 1) 232 { 233 // Enable widgets now that at least one valid font has been found 234 Spinner* fontSize = static_cast<Spinner*>(winMgr.getWindow("/ChatBox/FontSize")); 235 Window* chatText = winMgr.getWindow("/ChatBox/Text"); 236 fontName->setEnabled(true); 237 fontSize->setEnabled(true); 238 chatText->setEnabled(true); 239 240 // The first registered font becomes the active font 241 fontName->setText(pLogicalName); // This triggers a call to changeFont 242 fontName->setItemSelectState(fontNameItem, true); 243 } 244 } 245 } 246 247 protected: 248 CEGUI::Font* makeFont(const CEGUI::String& pFontName, const CEGUI::String& pFileName, const CEGUI::String& pSize) 249 { 250 using namespace CEGUI; 251 252 Font* font; 253 try 254 { 255 if(FontManager::getSingleton().isFontPresent(pFontName)) 256 { 257 // The chat font is reused rather than deleted and recreated 258 // every time an attribute changes. For this reason it is 259 // important to use a unique logical name for the font. 260 font = FontManager::getSingleton().getFont(pFontName); 261 font->setProperty("FileName", pFileName); 262 font->setProperty("PointSize", pSize); 263 } 264 else 265 { 266 // This is the first time we make the chat font so we need to create it 267 XMLAttributes xmlAttributes; 268 269 // CEGUIFont.cpp 270 xmlAttributes.add("Name", pFontName); 271 xmlAttributes.add("Filename", pFileName); 272 xmlAttributes.add("ResourceGroup", ""); 273 xmlAttributes.add("AutoScaled", "true"); 274 xmlAttributes.add("NativeHorzRes", "800"); 275 xmlAttributes.add("NativeVertRes", "600"); 276 277 // CEGUIXMLAttributes.cpp 278 xmlAttributes.add("Size", pSize); 279 xmlAttributes.add("AntiAlias", "true"); 280 281 font = FontManager::getSingleton().createFont("FreeType", xmlAttributes); 282 } 283 font->load(); 284 } 285 catch(Exception& e) 286 { 287 // Display the error message in the chat window 288 addChatText(e.getMessage()); 289 font = 0; 290 } 291 292 return font; 293 } 294 295 void changeFont(const CEGUI::String& pFontLogicalName, const CEGUI::String& pFontSize) 296 { 297 using namespace CEGUI; 298 WindowManager& winMgr = WindowManager::getSingleton(); 299 300 if(!FontManager::getSingleton().isFontPresent(mChatFontName)) 301 { 302 addChatText("You must call registerFont() at least once with a valid font"); 303 return; 304 } 305 306 FontList::iterator itFontList = mFontList.find(pFontLogicalName); 307 if(itFontList == mFontList.end()) 308 { 309 addChatText(pFontLogicalName + " has not been registered"); 310 return; 311 } 312 313 // Measure the height of the selected font 314 Font* currentFont = makeFont(mChatFontName, (*itFontList).second, pFontSize); 315 float fontHeight = currentFont->getFontHeight(); 316 317 /* Alter the area of the Editbox. The original value is {{0.01,0},{1,-30},{0.99,0},{1,-5}} 318 The value we are altering is the "-30" within the second couplet, defining the position of 319 the upper y coordinate of the Editbox. We base the new value on the position of the lower 320 y coordinate, which is "-5", and the height of the font. To this we add some space "10" to 321 account for the Editbox's border. */ 322 Editbox* editBox = static_cast<Editbox*> (winMgr.getWindow("/ChatBox/Text")); 323 URect chatTextArea = editBox->getArea(); 324 chatTextArea.d_min.d_y.d_offset = chatTextArea.d_max.d_y.d_offset 325 - fontHeight 326 - 10; 327 editBox->setArea(chatTextArea); 328 editBox->setFont(currentFont); 329 330 /* Alther the area of the Listbox. Here we only need the lower y coordinate. Since this 331 value is the same as the upper y coordinate of the Editbox we do not need to calculate 332 it. We also change the font of the Listbox and call upon handleUpdatedItemData() to 333 update the current Listbox items. Finally we ensure that the last entry is still 334 visible. */ 335 Listbox* listBox = static_cast<Listbox*> (winMgr.getWindow("/ChatBox/List")); 336 URect listTextArea = listBox->getArea(); 337 listTextArea.d_max.d_y.d_offset = chatTextArea.d_min.d_y.d_offset; 338 listBox->setArea(listTextArea); 339 listBox->setFont(currentFont); 340 listBox->handleUpdatedItemData(); 341 size_t itemCount = listBox->getItemCount(); 342 if(itemCount) 343 { 344 ListboxItem* currentItem = listBox->getListboxItemFromIndex(itemCount - 1); 345 listBox->ensureItemIsVisible(currentItem); 346 } 347 } 348 349 private: 24 private: 350 25 // Type of list for registered fonts 351 26 typedef std::map<CEGUI::String, CEGUI::String> FontList; … … 364 39 CEGUI::String mDefaultFontSize; 365 40 }; 366 367 #endif // _ChatBox_h_
Note: See TracChangeset
for help on using the changeset viewer.