2020-03-08 13:32:32 +00:00
|
|
|
#include "ppsspp_config.h"
|
2020-03-08 14:16:32 +00:00
|
|
|
#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"
|
2016-10-22 16:06:07 +00:00
|
|
|
#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");
|
2016-10-22 16:06:07 +00:00
|
|
|
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)
|
2016-12-05 03:04:31 +00:00
|
|
|
//freeze the ui when using ctrl + C hotkey need workaround
|
2020-03-08 15:41:31 +00:00
|
|
|
if (g_Config.bBypassOSKWithKeyboard && !g_Config.bFullScreen) {
|
2020-03-09 01:59:17 +00:00
|
|
|
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-11 03:44:30 +00:00
|
|
|
|
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
|
|
|
}
|
2016-10-22 16:06:07 +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;
|
|
|
|
|
2016-12-05 03:04:31 +00:00
|
|
|
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
|
2016-12-05 03:04:31 +00:00
|
|
|
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));
|
2016-12-05 03:04:31 +00:00
|
|
|
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));
|
2016-12-05 03:04:31 +00:00
|
|
|
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));
|
2016-12-05 03:04:31 +00:00
|
|
|
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));
|
2016-12-05 03:04:31 +00:00
|
|
|
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));
|
2016-12-05 03:04:31 +00:00
|
|
|
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));
|
2016-12-05 03:04:31 +00:00
|
|
|
break;
|
2020-03-11 03:44:30 +00:00
|
|
|
default:
|
|
|
|
box_ = nullptr;
|
|
|
|
break;
|
2016-12-05 03:04:31 +00:00
|
|
|
}
|
2016-10-21 10:35:54 +00:00
|
|
|
|
2020-03-11 03:44:30 +00:00
|
|
|
if (box_) {
|
|
|
|
root_->Add(box_);
|
|
|
|
box_->SetBG(UI::Drawable(0x99303030));
|
|
|
|
box_->SetHasDropShadow(false);
|
2016-10-21 10:35:54 +00:00
|
|
|
|
2020-03-11 03:44:30 +00:00
|
|
|
View *title = new PopupHeader(n->T("Chat"));
|
|
|
|
box_->Add(title);
|
2016-10-21 10:35:54 +00:00
|
|
|
|
2020-03-11 03:44:30 +00:00
|
|
|
CreatePopupContents(box_);
|
2020-03-08 22:51:23 +00:00
|
|
|
#if PPSSPP_PLATFORM(WINDOWS) || defined(USING_QT_UI) || defined(SDL)
|
2020-03-11 03:44:30 +00:00
|
|
|
UI::EnableFocusMovement(true);
|
|
|
|
root_->SetDefaultFocusView(box_);
|
|
|
|
box_->SubviewFocused(chatEdit_);
|
|
|
|
root_->SetFocus();
|
2016-12-05 03:04:31 +00:00
|
|
|
#else
|
2020-03-11 03:44:30 +00:00
|
|
|
//root_->SetDefaultFocusView(box_);
|
|
|
|
//box_->SubviewFocused(scroll_);
|
|
|
|
//root_->SetFocus();
|
2016-12-05 03:04:31 +00:00
|
|
|
#endif
|
2020-03-11 03:44:30 +00:00
|
|
|
}
|
2016-10-31 14:22:57 +00:00
|
|
|
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)
|
2020-03-09 02:54:24 +00:00
|
|
|
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.
|
|
|
|
*/
|
2016-10-22 16:06:07 +00:00
|
|
|
std::vector<std::string> Split(const std::string& str)
|
2016-10-21 10:35:54 +00:00
|
|
|
{
|
|
|
|
std::vector<std::string> ret;
|
2016-10-22 16:06:07 +00:00
|
|
|
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++) {
|
2016-10-22 16:06:07 +00:00
|
|
|
if (isspace(str[i])) {
|
2017-07-08 10:08:33 +00:00
|
|
|
if (i < spliton) {
|
2016-10-22 16:06:07 +00:00
|
|
|
if(str[i-1]!=':')
|
|
|
|
firstSentenceEnd = i+1;
|
|
|
|
}
|
2017-07-08 10:08:33 +00:00
|
|
|
else if (i > spliton) {
|
|
|
|
firstSentenceEnd = spliton;
|
2016-10-22 16:06:07 +00:00
|
|
|
}
|
|
|
|
}
|
2016-10-21 10:35:54 +00:00
|
|
|
}
|
|
|
|
|
2016-10-22 16:06:07 +00:00
|
|
|
if (firstSentenceEnd == 0) {
|
2017-07-08 10:08:33 +00:00
|
|
|
firstSentenceEnd = spliton;
|
2016-10-22 16:06:07 +00:00
|
|
|
}
|
|
|
|
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;
|
2020-03-11 03:44:30 +00:00
|
|
|
if (chatVert_ != nullptr) {
|
2016-10-22 16:06:07 +00:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2020-03-11 03:44:30 +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);
|
2020-03-11 03:44:30 +00:00
|
|
|
} 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);
|
|
|
|
}
|
|
|
|
|
2016-10-22 16:06:07 +00:00
|
|
|
if (!box_->GetBounds().Contains(touch.x, touch.y)){
|
2016-10-21 10:35:54 +00:00
|
|
|
screenManager()->finishDialog(this, DR_BACK);
|
2016-10-22 16:06:07 +00:00
|
|
|
}
|
2016-10-21 10:35:54 +00:00
|
|
|
|
|
|
|
return UIDialogScreen::touch(touch);
|
2016-10-22 16:06:07 +00:00
|
|
|
}
|
|
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2016-10-31 14:22:57 +00:00
|
|
|
if (updateChatScreen) {
|
|
|
|
UpdateChat();
|
2017-07-08 10:08:33 +00:00
|
|
|
updateChatScreen = false;
|
2016-10-22 16:06:07 +00:00
|
|
|
}
|
2016-10-22 18:44:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ChatMenu::~ChatMenu() {
|
2016-10-31 14:22:57 +00:00
|
|
|
chatScreenVisible = false;
|
2016-10-22 18:44:28 +00:00
|
|
|
}
|