10#include <Wt/WApplication.h>
11#include <Wt/WContainerWidget.h>
12#include <Wt/WEnvironment.h>
13#include <Wt/WInPlaceEdit.h>
14#include <Wt/WHBoxLayout.h>
15#include <Wt/WVBoxLayout.h>
17#include <Wt/WLineEdit.h>
18#include <Wt/WTemplate.h>
20#include <Wt/WTextArea.h>
21#include <Wt/WPushButton.h>
22#include <Wt/WCheckBox.h>
47 Wt::WApplication::instance()->enableUpdates(
true);
53 Wt::WApplication::instance()->enableUpdates(
false);
60 auto vLayout = setLayout(std::make_unique<Wt::WVBoxLayout>());
62 auto hLayout_(std::make_unique<Wt::WHBoxLayout>());
63 auto hLayout = hLayout_.get();
64 vLayout->addLayout(std::move(hLayout_), 0,
65 Wt::AlignmentFlag::Top | Wt::AlignmentFlag::Left);
67 hLayout->addWidget(std::make_unique<Wt::WLabel>(
"User name:"),
68 0, Wt::AlignmentFlag::Middle);
71 0, Wt::AlignmentFlag::Middle);
74 auto button = hLayout->addWidget(std::make_unique<Wt::WPushButton>(
"Login"),
75 0, Wt::AlignmentFlag::Middle);
80 statusMsg_ = vLayout->addWidget(std::make_unique<Wt::WText>());
81 statusMsg_->setTextFormat(Wt::TextFormat::Plain);
90 messageReceived_ = std::make_unique<Wt::WSound>(
"sounds/message_received.mp3");
93 statusMsg_->setText(
"Sorry, name '" + escapeText(name) +
94 "' is already taken.");
110 std::unique_ptr<WWidget> messageEdit,
111 std::unique_ptr<WWidget> sendButton, std::unique_ptr<WWidget> logoutButton)
131 auto vLayout = std::make_unique<Wt::WVBoxLayout>();
134 auto hLayout = std::make_unique<Wt::WHBoxLayout>();
137 hLayout->setPreferredImplementation(Wt::LayoutImplementation::JavaScript);
140 messages->setStyleClass(
"chat-msgs");
141 hLayout->addWidget(std::move(messages), 1);
144 userList->setStyleClass(
"chat-users");
145 hLayout->addWidget(std::move(userList));
147 hLayout->setResizable(0,
true);
150 vLayout->addLayout(std::move(hLayout), 1);
153 messageEdit->setStyleClass(
"chat-noedit");
154 vLayout->addWidget(std::move(messageEdit));
157 hLayout = std::make_unique<Wt::WHBoxLayout>();
160 hLayout->addWidget(std::move(sendButton));
163 hLayout->addWidget(std::move(logoutButton));
166 vLayout->addLayout(std::move(hLayout), 0, Wt::AlignmentFlag::Left);
168 this->setLayout(std::move(vLayout));
178 if (flags.test(Wt::RenderFlag::Full)) {
182 doJavaScript(
"setTimeout(function() { "
184 +
messages_->jsRef() +
".scrollHeight;}, 0);");
188 WContainerWidget::render(flags);
206 auto messagesPtr = std::make_unique<WContainerWidget>();
207 auto userListPtr = std::make_unique<WContainerWidget>();
208 auto messageEditPtr = std::make_unique<Wt::WTextArea>();
209 auto sendButtonPtr = std::make_unique<Wt::WPushButton>(
"Send");
210 auto logoutButtonPtr = std::make_unique<Wt::WPushButton>(
"Logout");
216 Wt::Core::observing_ptr<Wt::WPushButton> logoutButton = logoutButtonPtr.get();
222 messages_->setOverflow(Wt::Overflow::Auto);
223 userList_->setOverflow(Wt::Overflow::Auto);
225 createLayout(std::move(messagesPtr), std::move(userListPtr),
226 std::move(messageEditPtr),
227 std::move(sendButtonPtr), std::move(logoutButtonPtr));
242 (
"function(o, e) { setTimeout(function() {"
255 Wt::WApplication::instance()->setConnectionMonitor(
257 "'onChange':function(type, newV) {"
258 "var connected = window.monitor.status.connectionStatus != 0;"
264 +
messageEdit_->jsRef() +
".placeholder='connection lost';"
289 auto nameEdit = std::make_unique<Wt::WInPlaceEdit>();
290 nameEdit->addStyleClass(
"name-edit");
291 nameEdit->setButtonsEnabled(
false);
292 nameEdit->setText(
user_);
295 Wt::WTemplate *joinMsg =
messages_->addWidget(std::make_unique<Wt::WTemplate>(tr(
"join-msg.template")));
296 joinMsg->bindWidget(
"name", std::move(nameEdit));
297 joinMsg->setStyleClass(
"chat-msg");
330 for (SimpleChatServer::UserSet::iterator i = users.begin();
331 i != users.end(); ++i) {
332 Wt::WCheckBox *w =
userList_->addWidget(std::make_unique<Wt::WCheckBox>(escapeText(*i)));
335 UserMap::const_iterator j = oldUsers.find(*i);
336 if (j != oldUsers.end())
337 w->setChecked(j->second);
341 users_[*i] = w->isChecked();
345 w->setStyleClass(
"chat-self");
355 users_[b->text()] = b->isChecked();
360 Wt::WApplication *app = Wt::WApplication::instance();
381 user_ =
event.data();
392 app->triggerUpdate();
407 Wt::WText *w =
messages_->addWidget(std::make_unique<Wt::WText>());
414 w->setTextFormat(Wt::TextFormat::XHTML);
418 w->setStyleClass(
"chat-msg");
429 app->doJavaScript(
messages_->jsRef() +
".scrollTop += "
430 +
messages_->jsRef() +
".scrollHeight;");
Encapsulate a chat event.
const Wt::WString formattedHTML(const Wt::WString &user, Wt::TextFormat format) const
Get the message formatted as HTML, rendered for the given user.
Type type() const
Get the event type.
const Wt::WString & user() const
Get the user who caused the event.
std::set< Wt::WString > UserSet
Typedef for a collection of user names.