ppsspp/UI/ChatScreen.cpp

269 lines
8.7 KiB
C++
Raw Normal View History

2020-03-08 13:32:32 +00:00
#include "ppsspp_config.h"
#include "ui/root.h"
2016-10-21 10:35:54 +00:00
#include "ui/ui_context.h"
#include "ui/view.h"
#include "ui/viewgroup.h"
#include "ui/ui.h"
#include "ChatScreen.h"
#include "Core/Config.h"
2016-10-23 17:49:12 +00:00
#include "Core/Host.h"
2016-10-21 10:35:54 +00:00
#include "Core/System.h"
#include "Common/LogManager.h"
#include "Core/HLE/proAdhoc.h"
2016-10-21 13:12:57 +00:00
#include "i18n/i18n.h"
#include <ctype.h>
2016-10-27 13:40:19 +00:00
#include "util/text/utf8.h"
2016-10-21 10:35:54 +00:00
void ChatMenu::CreatePopupContents(UI::ViewGroup *parent) {
using namespace UI;
2020-03-02 17:23:12 +00:00
auto n = GetI18NCategory("Networking");
LinearLayout *outer = new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT,400));
scroll_ = outer->Add(new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0)));
2016-10-21 10:35:54 +00:00
LinearLayout *bottom = outer->Add(new LinearLayout(ORIENT_HORIZONTAL, new LayoutParams(FILL_PARENT, WRAP_CONTENT)));
2020-03-08 22:51:23 +00:00
#if PPSSPP_PLATFORM(WINDOWS) || defined(USING_QT_UI) || defined(SDL)
2016-10-21 13:12:57 +00:00
chatEdit_ = bottom->Add(new TextEdit("", n->T("Chat Here"), new LinearLayoutParams(1.0)));
2016-10-27 21:11:05 +00:00
#if defined(USING_WIN_UI)
//freeze the ui when using ctrl + C hotkey need workaround
if (g_Config.bBypassOSKWithKeyboard && !g_Config.bFullScreen) {
System_InputBoxGetString(n->T("Chat"), n->T("Chat Here"), [](bool result, const std::string &value) {
if (result) {
sendChat(value);
}
});
2016-10-27 13:40:19 +00:00
}
2016-10-27 21:11:05 +00:00
#endif
2016-10-21 10:35:54 +00:00
chatEdit_->OnEnter.Handle(this, &ChatMenu::OnSubmit);
2020-03-08 13:32:32 +00:00
#elif PPSSPP_PLATFORM(ANDROID)
2016-10-23 17:49:12 +00:00
bottom->Add(new Button(n->T("Chat Here"),new LayoutParams(FILL_PARENT, WRAP_CONTENT)))->OnClick.Handle(this, &ChatMenu::OnSubmit);
2017-08-08 20:19:28 +00:00
bottom->Add(new Button(n->T("Send")))->OnClick.Handle(this, &ChatMenu::OnSubmit);
2016-10-23 17:49:12 +00:00
#endif
2017-07-06 13:43:39 +00:00
if (g_Config.bEnableQuickChat) {
LinearLayout *quickChat = outer->Add(new LinearLayout(ORIENT_HORIZONTAL, new LayoutParams(FILL_PARENT, WRAP_CONTENT)));
2020-03-23 21:39:09 +00:00
quickChat->Add(new Button("1", new LinearLayoutParams(1.0)))->OnClick.Handle(this, &ChatMenu::OnQuickChat1);
quickChat->Add(new Button("2", new LinearLayoutParams(1.0)))->OnClick.Handle(this, &ChatMenu::OnQuickChat2);
quickChat->Add(new Button("3", new LinearLayoutParams(1.0)))->OnClick.Handle(this, &ChatMenu::OnQuickChat3);
quickChat->Add(new Button("4", new LinearLayoutParams(1.0)))->OnClick.Handle(this, &ChatMenu::OnQuickChat4);
quickChat->Add(new Button("5", new LinearLayoutParams(1.0)))->OnClick.Handle(this, &ChatMenu::OnQuickChat5);
2017-07-06 13:43:39 +00:00
}
chatVert_ = scroll_->Add(new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)));
chatVert_->SetSpacing(0);
2016-10-21 10:35:54 +00:00
parent->Add(outer);
}
void ChatMenu::CreateViews() {
using namespace UI;
2020-03-02 17:23:12 +00:00
auto n = GetI18NCategory("Networking");
2016-10-21 10:35:54 +00:00
UIContext &dc = *screenManager()->getUIContext();
AnchorLayout *anchor = new AnchorLayout(new LayoutParams(FILL_PARENT, FILL_PARENT));
anchor->Overflow(false);
root_ = anchor;
float yres = screenManager()->getUIContext()->GetBounds().h;
switch (g_Config.iChatScreenPosition) {
2020-03-02 18:52:31 +00:00
// the chat screen size is still static 280x240 need a dynamic size based on device resolution
case 0:
2020-03-02 18:52:31 +00:00
box_ = new LinearLayout(ORIENT_VERTICAL, new AnchorLayoutParams(PopupWidth(), FillVertical() ? yres - 30 : WRAP_CONTENT, 280, NONE, NONE, 240, true));
break;
case 1:
2020-03-02 18:52:31 +00:00
box_ = new LinearLayout(ORIENT_VERTICAL, new AnchorLayoutParams(PopupWidth(), FillVertical() ? yres - 30 : WRAP_CONTENT, dc.GetBounds().centerX(), NONE, NONE, 240, true));
break;
case 2:
2020-03-02 18:52:31 +00:00
box_ = new LinearLayout(ORIENT_VERTICAL, new AnchorLayoutParams(PopupWidth(), FillVertical() ? yres - 30 : WRAP_CONTENT, NONE, NONE, 280, 240, true));
break;
case 3:
2020-03-02 18:52:31 +00:00
box_ = new LinearLayout(ORIENT_VERTICAL, new AnchorLayoutParams(PopupWidth(), FillVertical() ? yres - 30 : WRAP_CONTENT, 280, 240, NONE, NONE, true));
break;
case 4:
2020-03-02 18:52:31 +00:00
box_ = new LinearLayout(ORIENT_VERTICAL, new AnchorLayoutParams(PopupWidth(), FillVertical() ? yres - 30 : WRAP_CONTENT, dc.GetBounds().centerX(), 240, NONE, NONE, true));
break;
case 5:
2020-03-02 18:52:31 +00:00
box_ = new LinearLayout(ORIENT_VERTICAL, new AnchorLayoutParams(PopupWidth(), FillVertical() ? yres - 30 : WRAP_CONTENT, NONE, 240, 280, NONE, true));
break;
default:
box_ = nullptr;
break;
}
2016-10-21 10:35:54 +00:00
if (box_) {
root_->Add(box_);
box_->SetBG(UI::Drawable(0x99303030));
box_->SetHasDropShadow(false);
2016-10-21 10:35:54 +00:00
View *title = new PopupHeader(n->T("Chat"));
box_->Add(title);
2016-10-21 10:35:54 +00:00
CreatePopupContents(box_);
2020-03-08 22:51:23 +00:00
#if PPSSPP_PLATFORM(WINDOWS) || defined(USING_QT_UI) || defined(SDL)
UI::EnableFocusMovement(true);
root_->SetDefaultFocusView(box_);
box_->SubviewFocused(chatEdit_);
root_->SetFocus();
#else
//root_->SetDefaultFocusView(box_);
//box_->SubviewFocused(scroll_);
//root_->SetFocus();
#endif
}
chatScreenVisible = true;
newChat = 0;
2017-07-08 10:08:33 +00:00
2017-06-07 18:18:45 +00:00
UpdateChat();
2016-10-21 10:35:54 +00:00
}
void ChatMenu::dialogFinished(const Screen *dialog, DialogResult result) {
UpdateUIState(UISTATE_INGAME);
}
UI::EventReturn ChatMenu::OnSubmit(UI::EventParams &e) {
2020-03-08 22:51:23 +00:00
#if PPSSPP_PLATFORM(WINDOWS) || defined(USING_QT_UI) || defined(SDL)
2016-10-21 10:35:54 +00:00
std::string chat = chatEdit_->GetText();
chatEdit_->SetText("");
chatEdit_->SetFocus();
sendChat(chat);
2020-03-08 13:32:32 +00:00
#elif PPSSPP_PLATFORM(ANDROID)
auto n = GetI18NCategory("Networking");
System_InputBoxGetString(n->T("Chat"), "", [](bool result, const std::string &value) {
sendChat(value);
});
2016-10-23 17:49:12 +00:00
#endif
2016-10-21 10:35:54 +00:00
return UI::EVENT_DONE;
}
2017-07-06 13:43:39 +00:00
UI::EventReturn ChatMenu::OnQuickChat1(UI::EventParams &e) {
sendChat(g_Config.sQuickChat0);
return UI::EVENT_DONE;
}
UI::EventReturn ChatMenu::OnQuickChat2(UI::EventParams &e) {
sendChat(g_Config.sQuickChat1);
return UI::EVENT_DONE;
}
UI::EventReturn ChatMenu::OnQuickChat3(UI::EventParams &e) {
sendChat(g_Config.sQuickChat2);
return UI::EVENT_DONE;
}
UI::EventReturn ChatMenu::OnQuickChat4(UI::EventParams &e) {
sendChat(g_Config.sQuickChat3);
return UI::EVENT_DONE;
}
UI::EventReturn ChatMenu::OnQuickChat5(UI::EventParams &e) {
sendChat(g_Config.sQuickChat4);
return UI::EVENT_DONE;
}
2017-06-07 18:18:45 +00:00
/*
maximum chat length in one message from server is only 64 character
need to split the chat to fit the static chat screen size
if the chat screen size become dynamic from device resolution
we need to change split function logic also.
*/
std::vector<std::string> Split(const std::string& str)
2016-10-21 10:35:54 +00:00
{
std::vector<std::string> ret;
int counter = 0;
int firstSentenceEnd = 0;
int secondSentenceEnd = 0;
2017-07-08 10:08:33 +00:00
int spliton = 45;
2020-03-02 18:52:31 +00:00
for (int i = 0; i<(int)str.length(); i++) {
if (isspace(str[i])) {
2017-07-08 10:08:33 +00:00
if (i < spliton) {
if(str[i-1]!=':')
firstSentenceEnd = i+1;
}
2017-07-08 10:08:33 +00:00
else if (i > spliton) {
firstSentenceEnd = spliton;
}
}
2016-10-21 10:35:54 +00:00
}
if (firstSentenceEnd == 0) {
2017-07-08 10:08:33 +00:00
firstSentenceEnd = spliton;
}
ret.push_back(str.substr(0, firstSentenceEnd));
2017-07-08 10:08:33 +00:00
ret.push_back(str.substr(firstSentenceEnd));
2016-10-21 10:35:54 +00:00
return ret;
}
void ChatMenu::UpdateChat() {
using namespace UI;
if (chatVert_ != nullptr) {
chatVert_->Clear(); //read Access violation is proadhoc.cpp use NULL_->Clear() pointer?
2016-10-21 10:35:54 +00:00
std::vector<std::string> chatLog = getChatLog();
for (auto i : chatLog) {
2017-06-07 18:18:45 +00:00
//split long text
2020-03-02 17:59:20 +00:00
uint32_t namecolor = 0x29B6F6;
2017-07-08 10:08:33 +00:00
uint32_t textcolor = 0xFFFFFF;
2020-03-02 17:59:20 +00:00
uint32_t infocolor = 0xFDD835;
2017-07-08 10:08:33 +00:00
std::string name = g_Config.sNickName.c_str();
std::string displayname = i.substr(0, i.find(':'));
std::string chattext = i.substr(displayname.length());
if (name.substr(0, 8) == displayname) {
2020-03-02 17:59:20 +00:00
namecolor = 0xE53935;
2017-07-08 10:08:33 +00:00
}
if (i.length() <= displayname.length() || i[displayname.length()] != ':') {
2017-07-08 10:08:33 +00:00
TextView *v = chatVert_->Add(new TextView(i, FLAG_DYNAMIC_ASCII, true));
v->SetTextColor(0xFF000000 | infocolor);
} else {
2017-07-08 10:08:33 +00:00
LinearLayout *line = chatVert_->Add(new LinearLayout(ORIENT_HORIZONTAL, new LayoutParams(FILL_PARENT, FILL_PARENT)));
TextView *nameView = line->Add(new TextView(displayname, FLAG_DYNAMIC_ASCII, true));
nameView->SetTextColor(0xFF000000 | namecolor);
if (chattext.length() > 45) {
std::vector<std::string> splitted = Split(chattext);
std::string one = splitted[0];
std::string two = splitted[1];
TextView *oneview = line->Add(new TextView(one, FLAG_DYNAMIC_ASCII, true));
oneview->SetTextColor(0xFF000000 | textcolor);
TextView *twoview = chatVert_->Add(new TextView(two, FLAG_DYNAMIC_ASCII, true));
twoview->SetTextColor(0xFF000000 | textcolor);
}
else {
TextView *chatView = line->Add(new TextView(chattext, FLAG_DYNAMIC_ASCII, true));
chatView->SetTextColor(0xFF000000 | textcolor);
}
2016-10-21 10:35:54 +00:00
}
}
2016-10-26 21:21:07 +00:00
toBottom_ = true;
2016-10-21 10:35:54 +00:00
}
}
bool ChatMenu::touch(const TouchInput &touch) {
if (!box_ || (touch.flags & TOUCH_DOWN) == 0 || touch.id != 0) {
return UIDialogScreen::touch(touch);
}
if (!box_->GetBounds().Contains(touch.x, touch.y)){
2016-10-21 10:35:54 +00:00
screenManager()->finishDialog(this, DR_BACK);
}
2016-10-21 10:35:54 +00:00
return UIDialogScreen::touch(touch);
}
2017-06-07 18:18:45 +00:00
void ChatMenu::update() {
PopupScreen::update();
2017-07-08 10:08:33 +00:00
if (scroll_ && toBottom_) {
toBottom_ = false;
scroll_->ScrollToBottom();
}
if (updateChatScreen) {
UpdateChat();
2017-07-08 10:08:33 +00:00
updateChatScreen = false;
}
}
ChatMenu::~ChatMenu() {
chatScreenVisible = false;
}