SimpleChatWidget Class Reference
[Chat example]

A self-contained chat widget. More...

#include <SimpleChatWidget.h>

Inheritance diagram for SimpleChatWidget:

Inheritance graph
[legend]

List of all members.

Public Member Functions

 SimpleChatWidget (SimpleChatServer &server, Wt::WContainerWidget *parent=0)
 Create a chat widget that will connect to the given server.
 ~SimpleChatWidget ()
 Delete a chat widget.
void letLogin ()
 Show a simple login screen.
bool startChat (const Wt::WString &user)
 Start a chat for the given user.

Private Member Functions

void login ()
void logout ()
void send ()
void updateUsers ()
void processChatEvent (const ChatEvent &event)
void onEditBlur ()
void onEditFocus ()

Private Attributes

SimpleChatServerserver_
Wt::WApplicationapp_
Wt::WString user_
Wt::WLineEdituserNameEdit_
Wt::WTextstatusMsg_
Wt::WContainerWidgetmessages_
Wt::WContainerWidgetmessageEditArea_
Wt::WTextAreamessageEdit_
Wt::WPushButtonsendButton_
Wt::WContainerWidgetuserList_
boost::signals::connection eventConnection_


Detailed Description

A self-contained chat widget.

Definition at line 31 of file SimpleChatWidget.h.


Constructor & Destructor Documentation

SimpleChatWidget::SimpleChatWidget ( SimpleChatServer server,
Wt::WContainerWidget parent = 0 
)

Create a chat widget that will connect to the given server.

Definition at line 24 of file SimpleChatWidget.C.

00026   : WContainerWidget(parent),
00027     server_(server),
00028     app_(WApplication::instance())
00029 {
00030   user_ = server_.suggestGuest();
00031   letLogin();
00032 
00033   app_->enableUpdates();
00034 }

SimpleChatWidget::~SimpleChatWidget (  ) 

Delete a chat widget.

Definition at line 36 of file SimpleChatWidget.C.

00037 {
00038   logout();
00039 }


Member Function Documentation

void SimpleChatWidget::letLogin (  ) 

Show a simple login screen.

Definition at line 41 of file SimpleChatWidget.C.

00042 {
00043   clear();
00044 
00045   WVBoxLayout *vLayout = new WVBoxLayout();
00046   setLayout(vLayout, AlignLeft | AlignTop);
00047 
00048   WHBoxLayout *hLayout = new WHBoxLayout();
00049   vLayout->addLayout(hLayout);
00050 
00051   hLayout->addWidget(new WLabel("User name:"), 0, AlignMiddle);
00052   hLayout->addWidget(userNameEdit_ = new WLineEdit(user_), 0, AlignMiddle);
00053   userNameEdit_->setFocus();
00054 
00055   WPushButton *b = new WPushButton("Login");
00056   hLayout->addWidget(b, 0, AlignMiddle);
00057   hLayout->addStretch(1);
00058 
00059   b->clicked().connect(SLOT(this, SimpleChatWidget::login));
00060   userNameEdit_->enterPressed().connect(SLOT(this, SimpleChatWidget::login));
00061 
00062   vLayout->addWidget(statusMsg_ = new WText());
00063   statusMsg_->setTextFormat(PlainText);
00064 }

bool SimpleChatWidget::startChat ( const Wt::WString user  ) 

Start a chat for the given user.

Returns false if the user could not login.

Definition at line 84 of file SimpleChatWidget.C.

00085 {
00086   if (server_.login(user)) {
00087     eventConnection_
00088       = server_.chatEvent().connect(SLOT(this,
00089                                        SimpleChatWidget::processChatEvent));
00090     user_ = user;    
00091 
00092     clear();
00093 
00094     /*
00095      * Create a vertical layout, which will hold 3 rows,
00096      * organized like this:
00097      *
00098      * WVBoxLayout
00099      * --------------------------------------------
00100      * | nested WHBoxLayout (vertical stretch=1)  |
00101      * |                              |           |
00102      * |  messages                    | userslist |
00103      * |   (horizontal stretch=1)     |           |
00104      * |                              |           |
00105      * --------------------------------------------
00106      * | message edit area                        |
00107      * --------------------------------------------
00108      * | WHBoxLayout                              |
00109      * | send | logout |       stretch = 1        |
00110      * --------------------------------------------
00111      */
00112     WVBoxLayout *vLayout = new WVBoxLayout();
00113 
00114     // Create a horizontal layout for the messages | userslist.
00115     WHBoxLayout *hLayout = new WHBoxLayout();
00116 
00117     // Add widget to horizontal layout with stretch = 1
00118     hLayout->addWidget(messages_ = new WContainerWidget(), 1);
00119     messages_->setStyleClass("chat-msgs");
00120     // Display scroll bars if contents overflows
00121     messages_->setOverflow(WContainerWidget::OverflowAuto);
00122 
00123     // Add another widget to hirozontal layout with stretch = 0
00124     hLayout->addWidget(userList_ = new WContainerWidget());
00125     userList_->setStyleClass("chat-users");
00126     userList_->setOverflow(WContainerWidget::OverflowAuto);
00127 
00128     // Add nested layout to vertical layout with stretch = 1
00129     vLayout->addLayout(hLayout, 1);
00130 
00131     // Add widget to vertical layout with stretch = 0
00132     vLayout->addWidget(messageEdit_ = new WTextArea());
00133     messageEdit_->setStyleClass("chat-noedit");
00134     messageEdit_->setRows(2);
00135     messageEdit_->setFocus();
00136 
00137     // Create a horizontal layout for the buttons.
00138     hLayout = new WHBoxLayout();
00139 
00140     // Add button to horizontal layout with stretch = 0
00141     hLayout->addWidget(sendButton_ = new WPushButton("Send"));
00142     WPushButton *b;
00143 
00144     // Add button to horizontal layout with stretch = 0
00145     hLayout->addWidget(b = new WPushButton("Logout"));
00146 
00147     // Add stretching spacer to horizontal layout
00148     hLayout->addStretch(1);
00149 
00150     // Add nested layout to vertical layout with stretch = 0
00151     vLayout->addLayout(hLayout);
00152 
00153     setLayout(vLayout);
00154 
00155     /*
00156      * Connect event handlers
00157      */
00158     sendButton_->clicked().connect(SLOT(sendButton_, WPushButton::disable));
00159     sendButton_->clicked().connect(SLOT(messageEdit_, WTextArea::disable));
00160     sendButton_->clicked().connect(SLOT(this, SimpleChatWidget::send));
00161 
00162     messageEdit_->enterPressed().connect
00163       (SLOT(sendButton_, WPushButton::disable));
00164     messageEdit_->enterPressed().connect
00165       (SLOT(messageEdit_, WTextArea::disable));
00166     messageEdit_->enterPressed().connect
00167       (SLOT(this, SimpleChatWidget::send));
00168 
00169     b->clicked().connect(SLOT(this, SimpleChatWidget::logout));
00170 
00171     WText *msg = new WText
00172       ("<div><span class='chat-info'>You are joining the conversation as "
00173        + user_ + "</span></div>", messages_);
00174     msg->setStyleClass("chat-msg");
00175 
00176     updateUsers();
00177     
00178     return true;
00179   } else
00180     return false;
00181 }

void SimpleChatWidget::login (  )  [private]

Definition at line 66 of file SimpleChatWidget.C.

00067 {
00068   WString name = WWebWidget::escapeText(userNameEdit_->text());
00069 
00070   if (!startChat(name))
00071     statusMsg_->setText("Sorry, name '" + name + "' is already taken.");
00072 }

void SimpleChatWidget::logout (  )  [private]

Definition at line 74 of file SimpleChatWidget.C.

00075 {
00076   if (eventConnection_.connected()) {
00077     eventConnection_.disconnect(); // do not listen for more events
00078     server_.logout(user_);
00079 
00080     letLogin();
00081   }
00082 }

void SimpleChatWidget::send (  )  [private]

Definition at line 183 of file SimpleChatWidget.C.

00184 {
00185   if (!messageEdit_->text().empty()) {
00186     server_.sendMessage(user_, messageEdit_->text());
00187     messageEdit_->setText("");
00188   }
00189 
00190   messageEdit_->enable();
00191   messageEdit_->setFocus();
00192   sendButton_->enable();
00193 }

void SimpleChatWidget::updateUsers (  )  [private]

Definition at line 195 of file SimpleChatWidget.C.

00196 {
00197   userList_->clear();
00198 
00199   SimpleChatServer::UserSet users = server_.users();
00200 
00201   WString usersStr;
00202 
00203   for (SimpleChatServer::UserSet::iterator i = users.begin();
00204        i != users.end(); ++i) {
00205     if (*i == user_)
00206       usersStr += "<div><span class='chat-self'>" + *i + "</span></div>";
00207     else
00208       usersStr += "<div>" + *i + "</div>";
00209   }
00210 
00211   userList_->addWidget(new WText(usersStr));
00212 }

void SimpleChatWidget::processChatEvent ( const ChatEvent event  )  [private]

Definition at line 214 of file SimpleChatWidget.C.

00215 {
00216   /*
00217    * This is where the "server-push" happens. This method is called
00218    * when a new event or message needs to be notified to the user. In
00219    * general, it is called from another session.
00220    *
00221    * First, we take the lock to safely manipulate the UI outside of the
00222    * normal event loop.
00223    */
00224 
00225   WApplication::UpdateLock lock = app_->getUpdateLock();
00226 
00227   WText *w = new WText(event.formattedHTML(user_), messages_);
00228   w->setInline(false);
00229   w->setStyleClass("chat-msg");
00230 
00231   /* no more than 100 messages back-log */
00232   if (messages_->count() > 100)
00233     delete messages_->children()[0];
00234 
00235   if (event.type() != ChatEvent::Message)
00236     updateUsers();
00237 
00238   /*
00239    * little javascript trick to make sure we scroll along with new content
00240    */
00241   app_->doJavaScript(messages_->jsRef() + ".scrollTop += "
00242                      + messages_->jsRef() + ".scrollHeight;");
00243 
00244   app_->triggerUpdate();
00245 }

void SimpleChatWidget::onEditBlur (  )  [private]

void SimpleChatWidget::onEditFocus (  )  [private]


Member Data Documentation

Definition at line 53 of file SimpleChatWidget.h.

Definition at line 54 of file SimpleChatWidget.h.

Definition at line 56 of file SimpleChatWidget.h.

Definition at line 58 of file SimpleChatWidget.h.

Definition at line 59 of file SimpleChatWidget.h.

Definition at line 61 of file SimpleChatWidget.h.

Definition at line 62 of file SimpleChatWidget.h.

Definition at line 63 of file SimpleChatWidget.h.

Definition at line 64 of file SimpleChatWidget.h.

Definition at line 65 of file SimpleChatWidget.h.

boost::signals::connection SimpleChatWidget::eventConnection_ [private]

Definition at line 67 of file SimpleChatWidget.h.


The documentation for this class was generated from the following files:

Generated on Mon Mar 9 08:28:57 2009 for Wt by doxygen 1.5.6