Merge with develop

--HG--
branch : compatibility-develop
This commit is contained in:
Nimetu 2017-03-14 23:42:52 +02:00
commit 88c81e8895
17 changed files with 452 additions and 136 deletions

View file

@ -206,12 +206,6 @@ namespace NLGUI
invalidateContent(); invalidateContent();
} }
// Set the HTML group used for links
void setBrowseGroup (CInterfaceElement *group)
{
_BrowseGroup = group;
}
/// \from CInterfaceElement /// \from CInterfaceElement
void onInvalidateContent(); void onInvalidateContent();
sint32 getMaxUsedW() const; sint32 getMaxUsedW() const;
@ -293,9 +287,6 @@ namespace NLGUI
// The links // The links
std::vector<CLink> _Links; std::vector<CLink> _Links;
// The HTML group used
CInterfaceElement *_BrowseGroup;
private: private:
std::string _HardText; std::string _HardText;
uint32 _TextId; uint32 _TextId;

View file

@ -50,10 +50,21 @@ namespace NLGUI
void setHTMLView( CGroupHTML *html); void setHTMLView( CGroupHTML *html);
bool getMouseOverShape(std::string &texName, uint8 &rot, NLMISC::CRGBA &col); bool getMouseOverShape(std::string &texName, uint8 &rot, NLMISC::CRGBA &col);
void setActionOnLeftClick(const std::string &actionHandler) { _AHOnLeftClick = actionHandler; };
void setParamsOnLeftClick(const std::string &actionParams) { _AHOnLeftClickParams = actionParams; };
const std::string &getActionOnLeftClick() const { return _AHOnLeftClick; }
const std::string &getParamsOnLeftClick() const { return _AHOnLeftClickParams; }
protected: protected:
// The main HTML group // The main HTML group
CGroupHTML *HTML; CGroupHTML *HTML;
// Left mouse click action
// Don't use CStringShared as URLs change past values would be permanently remembered.
std::string _AHOnLeftClick;
std::string _AHOnLeftClickParams;
}; };
} }

View file

@ -23,6 +23,7 @@
#include "nel/gui/db_manager.h" #include "nel/gui/db_manager.h"
#include "nel/gui/interface_link.h" #include "nel/gui/interface_link.h"
#include "nel/gui/widget_manager.h" #include "nel/gui/widget_manager.h"
#include "nel/gui/view_renderer.h"
using namespace std; using namespace std;
using namespace NLMISC; using namespace NLMISC;
@ -742,4 +743,14 @@ namespace NLGUI
}; };
REGISTER_ACTION_HANDLER (CAHUnlockAllContainer, "unlock_all_container"); REGISTER_ACTION_HANDLER (CAHUnlockAllContainer, "unlock_all_container");
// ------------------------------------------------------------------------------------------------
class CAHCopyToClipboard : public IActionHandler
{
virtual void execute (CCtrlBase *pCaller, const std::string &params)
{
if (!CViewRenderer::getInstance()->getDriver()->copyTextToClipboard(params))
nlwarning("Copy to clipboard failed: '%s'", params.c_str());
}
};
REGISTER_ACTION_HANDLER(CAHCopyToClipboard, "copy_to_clipboard");
} }

View file

@ -497,7 +497,11 @@ namespace NLGUI
if (res != CURLE_OK) if (res != CURLE_OK)
{ {
browseError(string("Connection failed with curl error " + string(curl_easy_strerror(res))).c_str()); std::string err;
err = "Connection failed with cURL error: ";
err += curl_easy_strerror(res);
err += "\nURL '" + _CurlWWW->Url + "'";
browseError(err.c_str());
} }
else else
if ((code >= 301 && code <= 303) || code == 307 || code == 308) if ((code >= 301 && code <= 303) || code == 307 || code == 308)
@ -541,7 +545,7 @@ namespace NLGUI
if ( (code < 200 || code >= 300) ) if ( (code < 200 || code >= 300) )
{ {
browseError(string("Connection failed (curl code " + toString((sint32)res) + "), http code " + toString((sint32)code) + ") : " + _CurlWWW->Url).c_str()); browseError(string("Connection failed (curl code " + toString((sint32)res) + ")\nhttp code " + toString((sint32)code) + ")\nURL '" + _CurlWWW->Url + "'").c_str());
} }
else else
{ {
@ -3769,7 +3773,6 @@ namespace NLGUI
CGroupParagraph *newParagraph = new CGroupParagraph(CViewBase::TCtorParam()); CGroupParagraph *newParagraph = new CGroupParagraph(CViewBase::TCtorParam());
newParagraph->setResizeFromChildH(true); newParagraph->setResizeFromChildH(true);
newParagraph->setBrowseGroup (this);
newParagraph->setIndent(_Indent); newParagraph->setIndent(_Indent);
// Add to the group // Add to the group
@ -4123,6 +4126,9 @@ namespace NLGUI
if (!newLink->Link.empty()) if (!newLink->Link.empty())
{ {
newLink->setHTMLView (this); newLink->setHTMLView (this);
newLink->setActionOnLeftClick("browse");
newLink->setParamsOnLeftClick("name=" + getId() + "|url=" + newLink->Link);
} }
} }
newLink->setText(tmpStr); newLink->setText(tmpStr);
@ -5216,6 +5222,11 @@ namespace NLGUI
void CGroupHTML::doBrowseAnchor(const std::string &anchor) void CGroupHTML::doBrowseAnchor(const std::string &anchor)
{ {
if (_Anchors.count(anchor) == 0)
{
return;
}
CInterfaceElement *pIE = _Anchors.find(anchor)->second; CInterfaceElement *pIE = _Anchors.find(anchor)->second;
if (pIE) if (pIE)
{ {

View file

@ -740,13 +740,11 @@ namespace NLGUI
CInterfaceGroup::updateCoords(); CInterfaceGroup::updateCoords();
sint32 nCurrentX = 0; // Current offset of an element
EAlign addElt = _AddElt; EAlign addElt = _AddElt;
if ((addElt == Top) || (addElt == Bottom)) if ((addElt == Top) || (addElt == Bottom))
{ {
// Calculate size // Calculate size
sint32 newH = 0, newW = 0; sint32 newH = 0;
bool bFirst = true; bool bFirst = true;
for (uint32 i = 0; i < _Elements.size(); ++i) for (uint32 i = 0; i < _Elements.size(); ++i)
@ -756,10 +754,7 @@ namespace NLGUI
if (!bFirst) if (!bFirst)
newH += _Space; newH += _Space;
bFirst = false; bFirst = false;
nCurrentX += _Elements[i].Element->getX();
newW = max (newW, _Elements[i].Element->getW()+(sint32)abs(nCurrentX));
} }
_W = max(newW, _MinW);
_H = max(newH, _MinH); _H = max(newH, _MinH);
if (_DynamicDisplaySize) if (_DynamicDisplaySize)
{ {
@ -767,10 +762,13 @@ namespace NLGUI
_MaxH = _H; _MaxH = _H;
} }
if (_H < _MaxH) setOfsY(0); if (_H < _MaxH) setOfsY(0);
// if width is not from parent, then ensure minimum size
if ((_SizeRef & 1) == 0) _W = max(_W, _MinW);
} }
else else
{ {
sint32 newW = 0, newH = 0; sint32 newW = 0;
bool bFirst = true; bool bFirst = true;
for (uint32 i = 0; i < _Elements.size(); ++i) for (uint32 i = 0; i < _Elements.size(); ++i)
@ -780,16 +778,17 @@ namespace NLGUI
if (!bFirst) if (!bFirst)
newW += _Space; newW += _Space;
bFirst = false; bFirst = false;
newH = max (newH, _Elements[i].Element->getH());
} }
_W = max(newW, _MinW); _W = max(newW, _MinW);
_H = max(newH, _MinH);
if (_DynamicDisplaySize) if (_DynamicDisplaySize)
{ {
_MaxW = _W; _MaxW = _W;
_MaxH = _H; _MaxH = _H;
} }
if (_W < _MaxW) setOfsX(0); if (_W < _MaxW) setOfsX(0);
// if height is not from parent, then ensure minimum size
if ((_SizeRef & 2) == 0) _H = max(_H, _MinH);
} }
CInterfaceElement::updateCoords(); CInterfaceElement::updateCoords();

View file

@ -240,6 +240,7 @@ namespace NLGUI
_GroupList->setY (4); _GroupList->setY (4);
_GroupList->setSpace (_GroupMenu->_Space); _GroupList->setSpace (_GroupMenu->_Space);
_GroupList->setSerializable( false ); _GroupList->setSerializable( false );
_GroupList->setResizeFromChildW(true);
addGroup (_GroupList); addGroup (_GroupList);
} }
} }

View file

@ -59,7 +59,6 @@ namespace NLGUI
_TopSpace = 0; _TopSpace = 0;
_Indent = 0; _Indent = 0;
_FirstViewIndentView = false; _FirstViewIndentView = false;
_BrowseGroup = NULL;
_TextId = 0; _TextId = 0;
} }
@ -868,11 +867,8 @@ namespace NLGUI
ctrl->setParentPosRef (Hotspot_TL); ctrl->setParentPosRef (Hotspot_TL);
ctrl->setPosRef (Hotspot_TL); ctrl->setPosRef (Hotspot_TL);
ctrl->setActive(true); ctrl->setActive(true);
if (_BrowseGroup) ctrl->setActionOnLeftClick(link.Link->getActionOnLeftClick());
{ ctrl->setParamsOnLeftClick(link.Link->getParamsOnLeftClick());
ctrl->setActionOnLeftClick("browse");
ctrl->setParamsOnLeftClick("name="+_BrowseGroup->getId()+"|url="+link.Link->Link);
}
ctrl->setScale(true); ctrl->setScale(true);
addCtrl(ctrl); addCtrl(ctrl);
} }

View file

@ -180,8 +180,8 @@ int main(int argc, char **argv)
for (uint j = 0; j < size; ++j) for (uint j = 0; j < size; ++j)
{ {
// TODO: find what computation do pRGBA->modulateFromColorRGBOnly(*pRGBA, color);
// *(pRGBA++)-> = color; ++pRGBA;
} }
NLMISC::COFile out; NLMISC::COFile out;

View file

@ -50,6 +50,24 @@
<command name="re" action="talk" params="mode=11|text=+" ctrlchar="false" /> <command name="re" action="talk" params="mode=11|text=+" ctrlchar="false" />
<command name="r" action="talk" params="mode=11|text=+" ctrlchar="false" /> <command name="r" action="talk" params="mode=11|text=+" ctrlchar="false" />
<command name="0" action="enter_talk" params="mode=12|channel=0" />
<command name="1" action="enter_talk" params="mode=12|channel=1" />
<command name="2" action="enter_talk" params="mode=12|channel=2" />
<command name="3" action="enter_talk" params="mode=12|channel=3" />
<command name="4" action="enter_talk" params="mode=12|channel=4" />
<command name="5" action="enter_talk" params="mode=12|channel=5" />
<command name="6" action="enter_talk" params="mode=12|channel=6" />
<command name="7" action="enter_talk" params="mode=12|channel=7" />
<command name="0" action="talk" params="mode=12|channel=0|text=+" ctrlchar="false" />
<command name="1" action="talk" params="mode=12|channel=1|text=+" ctrlchar="false" />
<command name="2" action="talk" params="mode=12|channel=2|text=+" ctrlchar="false" />
<command name="3" action="talk" params="mode=12|channel=3|text=+" ctrlchar="false" />
<command name="4" action="talk" params="mode=12|channel=4|text=+" ctrlchar="false" />
<command name="5" action="talk" params="mode=12|channel=5|text=+" ctrlchar="false" />
<command name="6" action="talk" params="mode=12|channel=6|text=+" ctrlchar="false" />
<command name="7" action="talk" params="mode=12|channel=7|text=+" ctrlchar="false" />
<command name="guild" action="enter_talk" params="mode=3" /> <command name="guild" action="enter_talk" params="mode=3" />
<command name="gu" action="enter_talk" params="mode=3" /> <command name="gu" action="enter_talk" params="mode=3" />
<command name="g" action="enter_talk" params="mode=3" /> <command name="g" action="enter_talk" params="mode=3" />

View file

@ -537,3 +537,17 @@ function game:openWebIGBrowserHeader()
ui.w = ui_webig_browser_w; ui.w = ui_webig_browser_w;
end end
end end
------------------------------------------------------------------------------------------------------------
local SavedUrl = "";
function game:chatUrl(url)
SavedUrl = url
runAH(nil, "active_menu", "menu=ui:interface:chat_uri_action_menu");
end
function game:chatUrlCopy()
runAH(nil, "copy_to_clipboard", SavedUrl)
end
function game:chatUrlBrowse()
runAH(nil, "browse", "name=ui:interface:webig:content:html|url=" .. SavedUrl)
end

View file

@ -3127,4 +3127,19 @@
<action handler="set" <action handler="set"
params="dblink=UI:SAVE:ISDETACHED:DYNAMIC_CHAT@0|value=0" /> params="dblink=UI:SAVE:ISDETACHED:DYNAMIC_CHAT@0|value=0" />
</proc> </proc>
<!-- there seems to be no way to pass url to menu, use lua script for middleman -->
<group type="menu"
id="chat_uri_action_menu"
extends="base_menu">
<action id="copy"
name="uiCopy"
handler="lua"
params="game:chatUrlCopy()" />
<action id="openig"
name="uiBrowse"
handler="lua"
params="game:chatUrlBrowse()" />
</group>
</interface_config> </interface_config>

View file

@ -2033,13 +2033,9 @@ void CClientConfig::release ()
// Are we in window mode ? // Are we in window mode ?
if (ClientCfg.Windowed /* && !isWindowMaximized() */) if (ClientCfg.Windowed /* && !isWindowMaximized() */)
{ {
// Save windows position // Save windows position. width/height are saved when leaving ingame.
writeInt("PositionX", x); writeInt("PositionX", x);
writeInt("PositionY", y); writeInt("PositionY", y);
// Save windows size
writeInt("Width", std::max((sint)width, 800));
writeInt("Height", std::max((sint)height, 600));
} }
} }

View file

@ -1374,12 +1374,28 @@ class CHandlerTalk : public IActionHandler
} }
} }
else else
{
if (mode == CChatGroup::dyn_chat)
{
uint channel;
fromString(getParam (sParams, "channel"), channel);
if (channel < CChatGroup::MaxDynChanPerPlayer)
{
PeopleInterraction.talkInDynamicChannel(channel, text);
}
else
{
nlwarning("/ah talk: invalid dyn_chat channel %d\n", channel);
}
}
else
{ {
ChatMngr.setChatMode((CChatGroup::TGroupType)mode); ChatMngr.setChatMode((CChatGroup::TGroupType)mode);
ChatMngr.chat(text, mode == CChatGroup::team); ChatMngr.chat(text, mode == CChatGroup::team);
} }
} }
} }
}
}; };
REGISTER_ACTION_HANDLER( CHandlerTalk, "talk"); REGISTER_ACTION_HANDLER( CHandlerTalk, "talk");
@ -1391,9 +1407,21 @@ class CHandlerEnterTalk : public IActionHandler
{ {
// Param // Param
uint mode; uint mode;
uint channel = 0;
fromString(getParam (sParams, "mode"), mode); fromString(getParam (sParams, "mode"), mode);
ChatMngr.updateChatModeAndButton(mode); if (mode == CChatGroup::dyn_chat)
{
fromString(getParam(sParams, "channel"), channel);
if (channel >= CChatGroup::MaxDynChanPerPlayer)
{
channel = 0;
}
}
ChatMngr.updateChatModeAndButton(mode, channel);
} }
}; };
REGISTER_ACTION_HANDLER( CHandlerEnterTalk, "enter_talk"); REGISTER_ACTION_HANDLER( CHandlerEnterTalk, "enter_talk");

View file

@ -1198,77 +1198,6 @@ NLMISC_COMMAND(db, "Modify Database","<Property> <Value>")
return true; return true;
} }
static bool talkInChan(uint32 nb,std::vector<std::string>args)
{
uint32 maxChans = CChatGroup::MaxDynChanPerPlayer;
if (nb>=maxChans)
{
return false;
}
if(!args.empty())
{
std::string tmp;
std::vector<std::string>::const_iterator first(args.begin()),last(args.end());
for(;first!=last;++first)
{
tmp = tmp + (*first);
tmp = tmp+" ";
}
ucstring uctmp;
uctmp.fromUtf8(tmp);
PeopleInterraction.talkInDynamicChannel(nb, uctmp);
return true;
}
else
{
ChatMngr.updateChatModeAndButton(CChatGroup::dyn_chat, nb);
}
return false;
}
NLMISC_COMMAND(0,"talk in 0th dynamic chat channel","<channel_nb> <sentence>")
{
return talkInChan(0,args);
}
NLMISC_COMMAND(1,"talk in first dynamic chat channel","<channel_nb> <sentence>")
{
return talkInChan(1,args);
}
NLMISC_COMMAND(2,"talk in 2nd dynamic chat channel","<channel_nb> <sentence>")
{
return talkInChan(2,args);
}
NLMISC_COMMAND(3,"talk in 3rd dynamic chat channel","<channel_nb> <sentence>")
{
return talkInChan(3,args);
}
NLMISC_COMMAND(4,"talk in 4th dynamic chat channel","<channel_nb> <sentence>")
{
return talkInChan(4,args);
}
NLMISC_COMMAND(5,"talk in 5th dynamic chat channel","<channel_nb> <sentence>")
{
return talkInChan(5,args);
}
NLMISC_COMMAND(6,"talk in 6th dynamic chat channel","<channel_nb> <sentence>")
{
return talkInChan(6,args);
}
NLMISC_COMMAND(7,"talk in 7th dynamic chat channel","<channel_nb> <sentence>")
{
return talkInChan(7,args);
}
NLMISC_COMMAND(setItemName, "set name of items, sbrick, etc..","<sheet_id> <name> <desc> <desc2>") NLMISC_COMMAND(setItemName, "set name of items, sbrick, etc..","<sheet_id> <name> <desc> <desc2>")
{ {
if (args.size() < 2) return false; if (args.size() < 2) return false;

View file

@ -20,6 +20,7 @@
// client // client
#include "chat_text_manager.h" #include "chat_text_manager.h"
#include "nel/gui/view_text.h" #include "nel/gui/view_text.h"
#include "nel/gui/group_paragraph.h"
#include "interface_manager.h" #include "interface_manager.h"
using namespace std; using namespace std;
@ -149,34 +150,165 @@ static CInterfaceGroup *buildLineWithCommand(CInterfaceGroup *commandGroup, CVie
return group; return group;
} }
//================================================================================= static inline bool isUrlTag(const ucstring &s, ucstring::size_type index, ucstring::size_type textSize)
CViewBase *CChatTextManager::createMsgText(const ucstring &cstMsg, NLMISC::CRGBA col, bool justified /*=false*/)
{ {
ucstring msg = cstMsg; // Format http://, https://
CInterfaceGroup *commandGroup = parseCommandTag(msg); // or markdown style (title)[http://..]
CViewText *vt = new CViewText(CViewText::TCtorParam()); if(textSize > index+7)
// get parameters from config.xml {
vt->setShadow(isTextShadowed()); bool markdown = false;
vt->setShadowOutline(false); ucstring::size_type i = index;
vt->setFontSize(getTextFontSize()); // advance index to url section if markdown style link is detected
vt->setMultiLine(true); if (s[i] == '(')
vt->setTextMode(justified ? CViewText::Justified : CViewText::DontClipWord); {
vt->setMultiLineSpace(getTextMultiLineSpace()); // scan for ')[http://'
vt->setModulateGlobalColor(false); while(i < textSize-9)
{
if (s[i] == ')' && s[i+1] == '[')
{
i += 2;
markdown = true;
break;
}
else
if (s[i] == ')')
{
i += 1;
break;
}
i++;
}
}
ucstring cur_time; if (textSize > i + 7)
if (showTimestamps())
{ {
bool isUrl = (toLower(s.substr(i, 7)) == ucstring("http://") || toLower(s.substr(i, 8)) == ucstring("https://"));
// match "text http://" and not "texthttp://"
if (isUrl && i > 0 && !markdown)
{
// '}' is in the list because of color tags, ie "@{FFFF}http://..."
const ucchar chars[] = {' ', '"', '\'', '(', '[', '}'};
isUrl = std::find(std::begin(chars), std::end(chars), s[i - 1]) != std::end(chars);
}
return isUrl;
}
}
return false;
}
// ***************************************************************************
// isUrlTag must match
static inline void getUrlTag(const ucstring &s, ucstring::size_type &index, ucstring &url, ucstring &title)
{
bool isMarkdown = false;
ucstring::size_type textSize = s.size();
ucstring::size_type pos;
// see if we have markdown format
if (s[index] == '(')
{
index++;
pos = index;
while(pos < textSize-9)
{
if (s[pos] == ')' && s[pos + 1] == '[')
{
isMarkdown = true;
title = s.substr(index, pos - index);
index = pos + 2;
break;
}
else if (s[pos] == ')')
{
break;
}
pos++;
}
}
ucchar chOpen = ' ';
ucchar chClose = ' ';
if (isMarkdown)
{
chOpen = '[';
chClose = ']';
}
else if (index > 0)
{
chOpen = s[index - 1];
if (chOpen == '\'') chClose = '\'';
else if (chOpen == '"') chClose = '"';
else if (chOpen == '(') chClose = ')';
else if (chOpen == '[') chClose = ']';
else chClose = ' ';
}
if (chOpen == chClose)
{
pos = s.find_first_of(chClose, index);
// handle common special case: 'text http://.../, text'
if (pos != ucstring::npos && index > 0)
{
if (s[index-1] == ' ' && (s[pos-1] == ',' || s[pos-1] == '.'))
{
pos--;
}
}
}
else
{
// scan for nested open/close tags
pos = index;
sint nested = 0;
while(pos < textSize)
{
if (s[pos] == chOpen)
{
nested++;
}
else if (s[pos] == chClose)
{
if (nested == 0)
{
break;
}
else
{
nested--;
}
}
pos++;
}
}
// fallback to full string length as we did match http:// already and url spans to the end probably
if (pos == ucstring::npos)
{
pos = textSize;
}
url = s.substr(index, pos - index);
index = pos;
// skip ']' closing char
if (isMarkdown) index++;
}
//=================================================================================
static void prependTimestamp(ucstring &msg)
{
ucstring cur_time;
CCDBNodeLeaf *node = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:SHOW_CLOCK_12H", false); CCDBNodeLeaf *node = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:SHOW_CLOCK_12H", false);
if (node && node->getValueBool()) if (node && node->getValueBool())
cur_time = CInterfaceManager::getTimestampHuman("[%I:%M:%S %p] "); cur_time = CInterfaceManager::getTimestampHuman("[%I:%M:%S %p] ");
else else
cur_time = CInterfaceManager::getTimestampHuman(); cur_time = CInterfaceManager::getTimestampHuman();
}
// if text contain any color code, set the text formated and white, ucstring::size_type codePos = msg.find(ucstring("@{"));
// otherwise, set text normal and apply global color
size_t codePos = msg.find(ucstring("@{"));
if (codePos != ucstring::npos) if (codePos != ucstring::npos)
{ {
// Prepend the current time (do it after the color if the color at first position. // Prepend the current time (do it after the color if the color at first position.
@ -189,13 +321,49 @@ CViewBase *CChatTextManager::createMsgText(const ucstring &cstMsg, NLMISC::CRGBA
{ {
msg = cur_time + msg; msg = cur_time + msg;
} }
}
else
{
msg = cur_time + msg;
}
}
//=================================================================================
CViewBase *CChatTextManager::createMsgText(const ucstring &cstMsg, NLMISC::CRGBA col, bool justified /*=false*/, bool plaintext /*=false*/)
{
ucstring msg = cstMsg;
CInterfaceGroup *commandGroup = parseCommandTag(msg);
if (showTimestamps())
prependTimestamp(msg);
// must wrap all lines to CGroupParagraph because CGroupList will calculate
// width from previous line which ends up as CViewText otherwise
return createMsgTextComplex(msg, col, justified, plaintext, commandGroup);
}
//=================================================================================
CViewBase *CChatTextManager::createMsgTextSimple(const ucstring &msg, NLMISC::CRGBA col, bool justified, CInterfaceGroup *commandGroup)
{
CViewText *vt = new CViewText(CViewText::TCtorParam());
// get parameters from config.xml
vt->setShadow(isTextShadowed());
vt->setShadowOutline(false);
vt->setFontSize(getTextFontSize());
vt->setMultiLine(true);
vt->setTextMode(justified ? CViewText::Justified : CViewText::DontClipWord);
vt->setMultiLineSpace(getTextMultiLineSpace());
vt->setModulateGlobalColor(false);
// if text contain any color code, set the text formated and white,
// otherwise, set text normal and apply global color
if (msg.find(ucstring("@{")) != ucstring::npos)
{
vt->setTextFormatTaged(msg); vt->setTextFormatTaged(msg);
vt->setColor(NLMISC::CRGBA::White); vt->setColor(NLMISC::CRGBA::White);
} }
else else
{ {
msg = cur_time + msg;
vt->setText(msg); vt->setText(msg);
vt->setColor(col); vt->setColor(col);
} }
@ -210,6 +378,112 @@ CViewBase *CChatTextManager::createMsgText(const ucstring &cstMsg, NLMISC::CRGBA
} }
} }
//=================================================================================
CViewBase *CChatTextManager::createMsgTextComplex(const ucstring &msg, NLMISC::CRGBA col, bool justified, bool plaintext, CInterfaceGroup *commandGroup)
{
ucstring::size_type textSize = msg.size();
CGroupParagraph *para = new CGroupParagraph(CViewBase::TCtorParam());
para->setId("line");
para->setSizeRef("w");
para->setResizeFromChildH(true);
if (plaintext)
{
CViewBase *vt = createMsgTextSimple(msg, col, justified, NULL);
vt->setId("text");
para->addChild(vt);
return para;
}
// quickly check if text has links or not
bool hasUrl;
{
ucstring s = toLower(msg);
hasUrl = (s.find(ucstring("http://")) || s.find(ucstring("https://")));
}
ucstring::size_type pos = 0;
for (ucstring::size_type i = 0; i< textSize;)
{
if (hasUrl && isUrlTag(msg, i, textSize))
{
if (pos != i)
{
CViewBase *vt = createMsgTextSimple(msg.substr(pos, i - pos), col, justified, NULL);
para->addChild(vt);
}
ucstring url;
ucstring title;
getUrlTag(msg, i, url, title);
if (url.size() > 0)
{
CViewLink *vt = new CViewLink(CViewBase::TCtorParam());
vt->setId("link");
vt->setUnderlined(true);
vt->setShadow(isTextShadowed());
vt->setShadowOutline(false);
vt->setFontSize(getTextFontSize());
vt->setMultiLine(true);
vt->setTextMode(justified ? CViewText::Justified : CViewText::DontClipWord);
vt->setMultiLineSpace(getTextMultiLineSpace());
vt->setModulateGlobalColor(false);
//NLMISC::CRGBA color;
//color.blendFromui(col, CRGBA(255, 153, 0, 255), 100);
//vt->setColor(color);
vt->setColor(col);
if (title.size() > 0)
{
vt->LinkTitle = title.toUtf8();
vt->setText(title);
}
else
{
vt->LinkTitle = url.toUtf8();
vt->setText(url);
}
if (url.find_first_of('\'') != string::npos)
{
ucstring clean;
for(string::size_type i = 0; i< url.size(); ++i)
{
if (url[i] == '\'')
clean += ucstring("%27");
else
clean += url[i];
}
url = clean;
}
vt->setActionOnLeftClick("lua");
vt->setParamsOnLeftClick("game:chatUrl('" + url.toUtf8() + "')");
para->addChildLink(vt);
pos = i;
}
}
else
{
++i;
}
}
if (pos < textSize)
{
CViewBase *vt = createMsgTextSimple(msg.substr(pos, textSize - pos), col, justified, NULL);
vt->setId("text");
para->addChild(vt);
}
return para;
}
//================================================================================= //=================================================================================
CChatTextManager &CChatTextManager::getInstance() CChatTextManager &CChatTextManager::getInstance()
{ {

View file

@ -24,6 +24,7 @@
namespace NLGUI namespace NLGUI
{ {
class CViewBase; class CViewBase;
class CInterfaceGroup;
} }
class ucstring; class ucstring;
@ -49,8 +50,9 @@ public:
* \param msg the actual text * \param msg the actual text
* \param col the color of the text * \param col the color of the text
* \param justified Should be true for justified text (stretch spaces of line to fill the full width) * \param justified Should be true for justified text (stretch spaces of line to fill the full width)
* \param plaintext Text will not be parsed for uri markup links
*/ */
NLGUI::CViewBase *createMsgText(const ucstring &msg, NLMISC::CRGBA col, bool justified = false); NLGUI::CViewBase *createMsgText(const ucstring &msg, NLMISC::CRGBA col, bool justified = false, bool plaintext = false);
// Singleton access // Singleton access
static CChatTextManager &getInstance(); static CChatTextManager &getInstance();
@ -73,6 +75,9 @@ private:
~CChatTextManager(); ~CChatTextManager();
bool showTimestamps() const; bool showTimestamps() const;
NLGUI::CViewBase *createMsgTextSimple(const ucstring &msg, NLMISC::CRGBA col, bool justified, NLGUI::CInterfaceGroup *commandGroup);
NLGUI::CViewBase *createMsgTextComplex(const ucstring &msg, NLMISC::CRGBA col, bool justified, bool plaintext, NLGUI::CInterfaceGroup *commandGroup);
}; };
// shortcut to get text manager instance // shortcut to get text manager instance

View file

@ -132,6 +132,19 @@ extern void selectTipsOfTheDay (uint tips);
// FUNCTIONS // // FUNCTIONS //
/////////////// ///////////////
// ***************************************************************************
// Saving ingame resolution when in windowed mode
static void saveIngameResolution()
{
if (ClientCfg.Windowed)
{
uint32 width, height;
Driver->getWindowSize(width, height);
ClientCfg.writeInt("Width", std::max((sint)width, 800));
ClientCfg.writeInt("Height", std::max((sint)height, 600));
}
}
// *************************************************************************** // ***************************************************************************
// 3D element release, called from both releaseMainLoopReselect() and releaseMainLoop() // 3D element release, called from both releaseMainLoopReselect() and releaseMainLoop()
static void releaseMainLoopScenes() static void releaseMainLoopScenes()
@ -209,6 +222,8 @@ void releaseMainLoopReselect()
{ {
ProgressBar.release(); ProgressBar.release();
saveIngameResolution();
CInterfaceManager *pIM= CInterfaceManager::getInstance(); CInterfaceManager *pIM= CInterfaceManager::getInstance();
// save keys loaded and interface cfg (not done in releaseMainLoop() because done at end of mainLoop()...) // save keys loaded and interface cfg (not done in releaseMainLoop() because done at end of mainLoop()...)
@ -364,6 +379,8 @@ void releaseMainLoop(bool closeConnection)
{ {
ProgressBar.release(); ProgressBar.release();
saveIngameResolution();
// Release R2 editor if applicable // Release R2 editor if applicable
R2::getEditor().autoConfigRelease(IsInRingSession); R2::getEditor().autoConfigRelease(IsInRingSession);