Difference between revisions of "Game chat box"

From CEGUI Wiki - Crazy Eddie's GUI System (Open Source)
Jump to: navigation, search
Line 1: Line 1:
The following .layout defines a FrameWindow containing two widgets; a Listbox in the upper region for chat history and an Editbox at the lower region for text input.
+
=== Introduction ===
 +
This snippet presents a .layout and sample code to implement a chat box.
  
'''chat.layout'''
+
The layout definition is deceptively simple.  It defines a FrameWindow containing two widgets; a Listbox in the upper region for chat history and an Editbox at the lower region for text input.
  
<pre>
+
What is not apparent is how the bottom portion of the Listbox and the entire Editbox are defined; they specify a proportion of 100% of their parent but with a negative offset. Essentially the bottom of the Listbox extends to the bottom of the FrameWindow (the parent) and is then moved "up" to make room for the Editbox. And the Editbox follows the same pattern. This allows the Editbox to retain its height as the parent FrameWindow is resized.
<?xml version="1.0" ?>
+
<GUILayout>
+
<Window Type="TaharezLook/FrameWindow" Name="/Chat">
+
<Property Name="Position" Value="x:0.0 y:0.0" />
+
<Property Name="Size" Value="w:0.25 h:0.25" />
+
<Property Name="Alpha" Value="0.8" />
+
<Window Type="DefaultWindow" Name="/Chat/Wnd">
+
<Property Name="Alpha" Value="0.8" />
+
<Property Name="Position" Value="x:0.0 y:0.00" />
+
<Property Name="Size" Value="w:1 h:1" />
+
<Window Type="TaharezLook/Listbox" Name="/Chat/Wnd/List">
+
<Property Name="Position" Value="x:0.0 y:0.1" />
+
<Property Name="Size" Value="w:1 h:0.77" />
+
</Window>
+
<Window Type="TaharezLook/Editbox" Name="/Chat/Wnd/Edit" >
+
<Property Name="Position" Value="x:0.01 y:0.87" />
+
<Property Name="Size" Value="w:0.98 h:0.12" />
+
  </Window>
+
</Window>
+
</Window>
+
</GUILayout>
+
</pre>
+
  
 
+
=== Files ===
'''InitialiseChatBox()'''
+
==== ChatBox_demo.h ====
 
<code><cpp/>
 
<code><cpp/>
// A helper variable
+
#ifndef _ChatBox_h_
CEGUI::WindowManager& winMgr = CEGUI::WindowManager::getSingleton();
+
#define _ChatBox_h_
  
// Load the chat layout and add it to the GUI sheet
+
#include "CEGuiSample.h"
mMainWindow = winMgr.loadWindowLayout("chat.layout");
+
#include "CEGUI.h"
if (mMainWindow)
+
    CEGUI::System::getSingleton().getGUISheet()->addChildWindow(mMainWindow);
+
  
// The only event we're interested is when the <ENTER> key is pressed
+
class DemoSample : public CEGuiSample
// This will call upon the EditTextAccepted() function to add the text to the Listbox
+
CEGUI::Window* editBox = winMgr.getWindow("/Chat/Wnd/Edit");
+
editBox->subscribeEvent(CEGUI::Editbox::EventTextAccepted, CEGUI::Event::Subscriber(&ChatWidget::EditTextAccepted, this));
+
</code>
+
 
+
'''EditTextAccepted()'''
+
<code><cpp/>
+
bool ChatWidget::EditTextAccepted(const CEGUI::EventArgs& args)
+
 
{
 
{
// Variables for the Listbox and the Editbox
+
public:
mEditBox = static_cast<CEGUI::Editbox*> (winMgr.getWindow("/Chat/Wnd/Edit"));
+
    bool initialiseSample()
mListBox = static_cast<CEGUI::Listbox*> (winMgr.getWindow("/Chat/Wnd/List"));
+
{
 +
using namespace CEGUI;
 +
try
 +
{
 +
// Retrieve the window manager
 +
WindowManager& winMgr = WindowManager::getSingleton();
  
// Add the Editbox text to the Listbox
+
// Load the TaharezLook scheme and set up the default mouse cursor and font
CEGUI::ListboxTextItem* item = new CEGUI::ListboxTextItem(mEditBox->getText());
+
SchemeManager::getSingleton().loadScheme("TaharezLook.scheme");
mListBox->addItem ( item );
+
System::getSingleton().setDefaultMouseCursor("TaharezLook", "MouseArrow");
 +
FontManager::getSingleton().createFont("Commonwealth-10.font");
  
// Scroll the Listbox entries such that the new text is visible
+
// Set the GUI Sheet
mListBox->ensureItemIsVisible(mListBox->getItemCount());
+
Window* sheet = winMgr.createWindow("DefaultWindow", "root_wnd");
 +
System::getSingleton().setGUISheet(sheet);
  
// Clear the text in the Editbox
+
// Load a layout
mEditBox->setText("");
+
Window* guiLayout = winMgr.loadWindowLayout("ChatBox.layout");
 +
sheet->addChildWindow(guiLayout);
  
return true;
+
// The only event we're interested is when the <ENTER> key is pressed
 +
// This will call upon the EditTextAccepted() function to add the text to the Listbox
 +
CEGUI::Window* editBox = winMgr.getWindow("/ChatBox/Text");
 +
editBox->subscribeEvent(CEGUI::Editbox::EventTextAccepted, CEGUI::Event::Subscriber(&DemoSample::EditTextAccepted, this));
 +
}
 +
catch(Exception &e)
 +
{
 +
#if defined( __WIN32__ ) || defined( _WIN32 )
 +
MessageBox(NULL, e.getMessage().c_str(), "Error initializing the demo", MB_OK | MB_ICONERROR | MB_TASKMODAL);
 +
#else
 +
std::cerr << "Error initializing the demo:" << e.getMessage().c_str() << "\n";
 +
#endif
 +
}
 +
 
 +
return true;
 +
}
 +
 
 +
    void cleanupSample(void)
 +
{
 +
}
 +
 
 +
bool EditTextAccepted(const CEGUI::EventArgs& args)
 +
{
 +
using namespace CEGUI;
 +
 
 +
// Variables for the Listbox and the Editbox
 +
WindowManager& winMgr = WindowManager::getSingleton();
 +
Editbox* editBox = static_cast<Editbox*> (winMgr.getWindow("/ChatBox/Text"));
 +
Listbox* listBox = static_cast<Listbox*> (winMgr.getWindow("/ChatBox/List"));
 +
 
 +
// Add the Editbox text to the Listbox
 +
ListboxTextItem* item = new ListboxTextItem(editBox->getText());
 +
listBox->addItem ( item );
 +
 
 +
// Scroll the Listbox entries such that the new text is visible
 +
listBox->ensureItemIsVisible(listBox->getItemCount());
 +
 
 +
// Clear the text in the Editbox
 +
editBox->setText("");
 +
 
 +
return true;
 +
}
 +
};
 +
 
 +
#endif // _ChatBox_h_
 +
</code>
 +
 
 +
==== Main.cpp ====
 +
<code><cpp/>
 +
#if defined( __WIN32__ ) || defined( _WIN32 )
 +
#define WIN32_LEAN_AND_MEAN
 +
#define NOMINMAX
 +
#include "windows.h"
 +
#endif
 +
 
 +
#include "ChatBox_demo.h"
 +
 
 +
#if defined( __WIN32__ ) || defined( _WIN32 )
 +
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,int nCmdShow)
 +
#else
 +
int main(int argc, char *argv[])
 +
#endif
 +
{
 +
    DemoSample app;
 +
    int i = app.run();
 +
    return i;
 
}
 
}
 
</code>
 
</code>
 +
 +
==== ChatBox.layout ====
 +
<pre>
 +
<?xml version="1.0" encoding="UTF-8"?>
 +
<GUILayout >
 +
    <Window Type="TaharezLook/FrameWindow" Name="/ChatBox" >
 +
        <Property Name="Text" Value="Chat" />
 +
        <Property Name="TitlebarFont" Value="Commonwealth-10" />
 +
        <Property Name="InheritsAlpha" Value="False" />
 +
        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
 +
        <Property Name="TitlebarEnabled" Value="True" />
 +
        <Property Name="UnifiedAreaRect" Value="{{0.15,0},{0.03,0},{0.7,0},{0.7,0}}" />
 +
        <Window Type="TaharezLook/Listbox" Name="/ChatBox/List" >
 +
            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
 +
            <Property Name="UnifiedAreaRect" Value="{{0.01,0},{0.078,0},{0.99,0},{1,-30}}" />
 +
        </Window>
 +
        <Window Type="TaharezLook/Editbox" Name="/ChatBox/Text" >
 +
            <Property Name="MaxTextLength" Value="1073741823" />
 +
            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
 +
            <Property Name="UnifiedAreaRect" Value="{{0.01,0},{1,-30},{0.99,0},{1,-5}}" />
 +
        </Window>
 +
    </Window>
 +
</GUILayout>
 +
</pre>
 +
 +
  
  
 
TODO: Create a new version that handles different fonts, both font names (such as Arial, Times New Roman) and font sizes (such as 8, 10, 12).  This will be done by adding a new widget within a looknfeel (such as TaharezLook.looknfeel).  The main feature will be that the Editbox's height will rely on the LineSpacing value of the font.
 
TODO: Create a new version that handles different fonts, both font names (such as Arial, Times New Roman) and font sizes (such as 8, 10, 12).  This will be done by adding a new widget within a looknfeel (such as TaharezLook.looknfeel).  The main feature will be that the Editbox's height will rely on the LineSpacing value of the font.

Revision as of 16:12, 29 January 2008

Introduction

This snippet presents a .layout and sample code to implement a chat box.

The layout definition is deceptively simple. It defines a FrameWindow containing two widgets; a Listbox in the upper region for chat history and an Editbox at the lower region for text input.

What is not apparent is how the bottom portion of the Listbox and the entire Editbox are defined; they specify a proportion of 100% of their parent but with a negative offset. Essentially the bottom of the Listbox extends to the bottom of the FrameWindow (the parent) and is then moved "up" to make room for the Editbox. And the Editbox follows the same pattern. This allows the Editbox to retain its height as the parent FrameWindow is resized.

Files

ChatBox_demo.h

<cpp/>

  1. ifndef _ChatBox_h_
  2. define _ChatBox_h_
  1. include "CEGuiSample.h"
  2. include "CEGUI.h"

class DemoSample : public CEGuiSample { public:

   bool initialiseSample()

{ using namespace CEGUI; try { // Retrieve the window manager WindowManager& winMgr = WindowManager::getSingleton();

// Load the TaharezLook scheme and set up the default mouse cursor and font SchemeManager::getSingleton().loadScheme("TaharezLook.scheme"); System::getSingleton().setDefaultMouseCursor("TaharezLook", "MouseArrow"); FontManager::getSingleton().createFont("Commonwealth-10.font");

// Set the GUI Sheet Window* sheet = winMgr.createWindow("DefaultWindow", "root_wnd"); System::getSingleton().setGUISheet(sheet);

// Load a layout Window* guiLayout = winMgr.loadWindowLayout("ChatBox.layout"); sheet->addChildWindow(guiLayout);

// The only event we're interested is when the <ENTER> key is pressed // This will call upon the EditTextAccepted() function to add the text to the Listbox CEGUI::Window* editBox = winMgr.getWindow("/ChatBox/Text"); editBox->subscribeEvent(CEGUI::Editbox::EventTextAccepted, CEGUI::Event::Subscriber(&DemoSample::EditTextAccepted, this)); } catch(Exception &e) { #if defined( __WIN32__ ) || defined( _WIN32 ) MessageBox(NULL, e.getMessage().c_str(), "Error initializing the demo", MB_OK | MB_ICONERROR | MB_TASKMODAL); #else std::cerr << "Error initializing the demo:" << e.getMessage().c_str() << "\n"; #endif }

return true; }

   void cleanupSample(void)

{ }

bool EditTextAccepted(const CEGUI::EventArgs& args) { using namespace CEGUI;

// Variables for the Listbox and the Editbox WindowManager& winMgr = WindowManager::getSingleton(); Editbox* editBox = static_cast<Editbox*> (winMgr.getWindow("/ChatBox/Text")); Listbox* listBox = static_cast<Listbox*> (winMgr.getWindow("/ChatBox/List"));

// Add the Editbox text to the Listbox ListboxTextItem* item = new ListboxTextItem(editBox->getText()); listBox->addItem ( item );

// Scroll the Listbox entries such that the new text is visible listBox->ensureItemIsVisible(listBox->getItemCount());

// Clear the text in the Editbox editBox->setText("");

return true; } };

  1. endif // _ChatBox_h_

Main.cpp

<cpp/>

  1. if defined( __WIN32__ ) || defined( _WIN32 )

#define WIN32_LEAN_AND_MEAN #define NOMINMAX #include "windows.h"

  1. endif
  1. include "ChatBox_demo.h"
  1. if defined( __WIN32__ ) || defined( _WIN32 )

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,int nCmdShow)

  1. else

int main(int argc, char *argv[])

  1. endif

{

   DemoSample app;
   int i = app.run();
   return i;

}

ChatBox.layout

<?xml version="1.0" encoding="UTF-8"?>
<GUILayout >
    <Window Type="TaharezLook/FrameWindow" Name="/ChatBox" >
        <Property Name="Text" Value="Chat" />
        <Property Name="TitlebarFont" Value="Commonwealth-10" />
        <Property Name="InheritsAlpha" Value="False" />
        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
        <Property Name="TitlebarEnabled" Value="True" />
        <Property Name="UnifiedAreaRect" Value="{{0.15,0},{0.03,0},{0.7,0},{0.7,0}}" />
        <Window Type="TaharezLook/Listbox" Name="/ChatBox/List" >
            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
            <Property Name="UnifiedAreaRect" Value="{{0.01,0},{0.078,0},{0.99,0},{1,-30}}" />
        </Window>
        <Window Type="TaharezLook/Editbox" Name="/ChatBox/Text" >
            <Property Name="MaxTextLength" Value="1073741823" />
            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
            <Property Name="UnifiedAreaRect" Value="{{0.01,0},{1,-30},{0.99,0},{1,-5}}" />
        </Window>
    </Window>
</GUILayout>



TODO: Create a new version that handles different fonts, both font names (such as Arial, Times New Roman) and font sizes (such as 8, 10, 12). This will be done by adding a new widget within a looknfeel (such as TaharezLook.looknfeel). The main feature will be that the Editbox's height will rely on the LineSpacing value of the font.