Merge with develop
This commit is contained in:
commit
6adae34ad3
17 changed files with 452 additions and 136 deletions
|
@ -206,12 +206,6 @@ namespace NLGUI
|
|||
invalidateContent();
|
||||
}
|
||||
|
||||
// Set the HTML group used for links
|
||||
void setBrowseGroup (CInterfaceElement *group)
|
||||
{
|
||||
_BrowseGroup = group;
|
||||
}
|
||||
|
||||
/// \from CInterfaceElement
|
||||
void onInvalidateContent();
|
||||
sint32 getMaxUsedW() const;
|
||||
|
@ -293,9 +287,6 @@ namespace NLGUI
|
|||
// The links
|
||||
std::vector<CLink> _Links;
|
||||
|
||||
// The HTML group used
|
||||
CInterfaceElement *_BrowseGroup;
|
||||
|
||||
private:
|
||||
std::string _HardText;
|
||||
uint32 _TextId;
|
||||
|
|
|
@ -50,10 +50,21 @@ namespace NLGUI
|
|||
void setHTMLView( CGroupHTML *html);
|
||||
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:
|
||||
|
||||
// The main HTML group
|
||||
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;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "nel/gui/db_manager.h"
|
||||
#include "nel/gui/interface_link.h"
|
||||
#include "nel/gui/widget_manager.h"
|
||||
#include "nel/gui/view_renderer.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace NLMISC;
|
||||
|
@ -742,4 +743,14 @@ namespace NLGUI
|
|||
};
|
||||
REGISTER_ACTION_HANDLER (CAHUnlockAllContainer, "unlock_all_container");
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
class CAHCopyToClipboard : public IActionHandler
|
||||
{
|
||||
virtual void execute (CCtrlBase *pCaller, const std::string ¶ms)
|
||||
{
|
||||
if (!CViewRenderer::getInstance()->getDriver()->copyTextToClipboard(params))
|
||||
nlwarning("Copy to clipboard failed: '%s'", params.c_str());
|
||||
}
|
||||
};
|
||||
REGISTER_ACTION_HANDLER(CAHCopyToClipboard, "copy_to_clipboard");
|
||||
}
|
|
@ -497,7 +497,11 @@ namespace NLGUI
|
|||
|
||||
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
|
||||
if ((code >= 301 && code <= 303) || code == 307 || code == 308)
|
||||
|
@ -541,7 +545,7 @@ namespace NLGUI
|
|||
|
||||
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
|
||||
{
|
||||
|
@ -3769,7 +3773,6 @@ namespace NLGUI
|
|||
CGroupParagraph *newParagraph = new CGroupParagraph(CViewBase::TCtorParam());
|
||||
newParagraph->setResizeFromChildH(true);
|
||||
|
||||
newParagraph->setBrowseGroup (this);
|
||||
newParagraph->setIndent(_Indent);
|
||||
|
||||
// Add to the group
|
||||
|
@ -4123,6 +4126,9 @@ namespace NLGUI
|
|||
if (!newLink->Link.empty())
|
||||
{
|
||||
newLink->setHTMLView (this);
|
||||
|
||||
newLink->setActionOnLeftClick("browse");
|
||||
newLink->setParamsOnLeftClick("name=" + getId() + "|url=" + newLink->Link);
|
||||
}
|
||||
}
|
||||
newLink->setText(tmpStr);
|
||||
|
@ -5216,6 +5222,11 @@ namespace NLGUI
|
|||
|
||||
void CGroupHTML::doBrowseAnchor(const std::string &anchor)
|
||||
{
|
||||
if (_Anchors.count(anchor) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CInterfaceElement *pIE = _Anchors.find(anchor)->second;
|
||||
if (pIE)
|
||||
{
|
||||
|
|
|
@ -740,13 +740,11 @@ namespace NLGUI
|
|||
|
||||
CInterfaceGroup::updateCoords();
|
||||
|
||||
sint32 nCurrentX = 0; // Current offset of an element
|
||||
|
||||
EAlign addElt = _AddElt;
|
||||
if ((addElt == Top) || (addElt == Bottom))
|
||||
{
|
||||
// Calculate size
|
||||
sint32 newH = 0, newW = 0;
|
||||
sint32 newH = 0;
|
||||
bool bFirst = true;
|
||||
|
||||
for (uint32 i = 0; i < _Elements.size(); ++i)
|
||||
|
@ -756,10 +754,7 @@ namespace NLGUI
|
|||
if (!bFirst)
|
||||
newH += _Space;
|
||||
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);
|
||||
if (_DynamicDisplaySize)
|
||||
{
|
||||
|
@ -767,10 +762,13 @@ namespace NLGUI
|
|||
_MaxH = _H;
|
||||
}
|
||||
if (_H < _MaxH) setOfsY(0);
|
||||
|
||||
// if width is not from parent, then ensure minimum size
|
||||
if ((_SizeRef & 1) == 0) _W = max(_W, _MinW);
|
||||
}
|
||||
else
|
||||
{
|
||||
sint32 newW = 0, newH = 0;
|
||||
sint32 newW = 0;
|
||||
bool bFirst = true;
|
||||
|
||||
for (uint32 i = 0; i < _Elements.size(); ++i)
|
||||
|
@ -780,16 +778,17 @@ namespace NLGUI
|
|||
if (!bFirst)
|
||||
newW += _Space;
|
||||
bFirst = false;
|
||||
newH = max (newH, _Elements[i].Element->getH());
|
||||
}
|
||||
_W = max(newW, _MinW);
|
||||
_H = max(newH, _MinH);
|
||||
if (_DynamicDisplaySize)
|
||||
{
|
||||
_MaxW = _W;
|
||||
_MaxH = _H;
|
||||
}
|
||||
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();
|
||||
|
|
|
@ -240,6 +240,7 @@ namespace NLGUI
|
|||
_GroupList->setY (4);
|
||||
_GroupList->setSpace (_GroupMenu->_Space);
|
||||
_GroupList->setSerializable( false );
|
||||
_GroupList->setResizeFromChildW(true);
|
||||
addGroup (_GroupList);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,7 +59,6 @@ namespace NLGUI
|
|||
_TopSpace = 0;
|
||||
_Indent = 0;
|
||||
_FirstViewIndentView = false;
|
||||
_BrowseGroup = NULL;
|
||||
_TextId = 0;
|
||||
}
|
||||
|
||||
|
@ -868,11 +867,8 @@ namespace NLGUI
|
|||
ctrl->setParentPosRef (Hotspot_TL);
|
||||
ctrl->setPosRef (Hotspot_TL);
|
||||
ctrl->setActive(true);
|
||||
if (_BrowseGroup)
|
||||
{
|
||||
ctrl->setActionOnLeftClick("browse");
|
||||
ctrl->setParamsOnLeftClick("name="+_BrowseGroup->getId()+"|url="+link.Link->Link);
|
||||
}
|
||||
ctrl->setActionOnLeftClick(link.Link->getActionOnLeftClick());
|
||||
ctrl->setParamsOnLeftClick(link.Link->getParamsOnLeftClick());
|
||||
ctrl->setScale(true);
|
||||
addCtrl(ctrl);
|
||||
}
|
||||
|
|
|
@ -180,8 +180,8 @@ int main(int argc, char **argv)
|
|||
|
||||
for (uint j = 0; j < size; ++j)
|
||||
{
|
||||
// TODO: find what computation do
|
||||
// *(pRGBA++)-> = color;
|
||||
pRGBA->modulateFromColorRGBOnly(*pRGBA, color);
|
||||
++pRGBA;
|
||||
}
|
||||
|
||||
NLMISC::COFile out;
|
||||
|
|
|
@ -50,6 +50,24 @@
|
|||
<command name="re" 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="gu" action="enter_talk" params="mode=3" />
|
||||
<command name="g" action="enter_talk" params="mode=3" />
|
||||
|
|
|
@ -537,3 +537,17 @@ function game:openWebIGBrowserHeader()
|
|||
ui.w = ui_webig_browser_w;
|
||||
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
|
||||
|
||||
|
|
|
@ -3127,4 +3127,19 @@
|
|||
<action handler="set"
|
||||
params="dblink=UI:SAVE:ISDETACHED:DYNAMIC_CHAT@0|value=0" />
|
||||
</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>
|
||||
|
|
|
@ -2033,13 +2033,9 @@ void CClientConfig::release ()
|
|||
// Are we in window mode ?
|
||||
if (ClientCfg.Windowed /* && !isWindowMaximized() */)
|
||||
{
|
||||
// Save windows position
|
||||
// Save windows position. width/height are saved when leaving ingame.
|
||||
writeInt("PositionX", x);
|
||||
writeInt("PositionY", y);
|
||||
|
||||
// Save windows size
|
||||
writeInt("Width", std::max((sint)width, 800));
|
||||
writeInt("Height", std::max((sint)height, 600));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1374,12 +1374,28 @@ class CHandlerTalk : public IActionHandler
|
|||
}
|
||||
}
|
||||
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.chat(text, mode == CChatGroup::team);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
REGISTER_ACTION_HANDLER( CHandlerTalk, "talk");
|
||||
|
||||
|
@ -1391,9 +1407,21 @@ class CHandlerEnterTalk : public IActionHandler
|
|||
{
|
||||
// Param
|
||||
uint mode;
|
||||
uint channel = 0;
|
||||
|
||||
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");
|
||||
|
|
|
@ -1198,77 +1198,6 @@ NLMISC_COMMAND(db, "Modify Database","<Property> <Value>")
|
|||
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>")
|
||||
{
|
||||
if (args.size() < 2) return false;
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
// client
|
||||
#include "chat_text_manager.h"
|
||||
#include "nel/gui/view_text.h"
|
||||
#include "nel/gui/group_paragraph.h"
|
||||
#include "interface_manager.h"
|
||||
|
||||
using namespace std;
|
||||
|
@ -149,34 +150,165 @@ static CInterfaceGroup *buildLineWithCommand(CInterfaceGroup *commandGroup, CVie
|
|||
return group;
|
||||
}
|
||||
|
||||
//=================================================================================
|
||||
CViewBase *CChatTextManager::createMsgText(const ucstring &cstMsg, NLMISC::CRGBA col, bool justified /*=false*/)
|
||||
static inline bool isUrlTag(const ucstring &s, ucstring::size_type index, ucstring::size_type textSize)
|
||||
{
|
||||
ucstring msg = cstMsg;
|
||||
CInterfaceGroup *commandGroup = parseCommandTag(msg);
|
||||
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);
|
||||
|
||||
ucstring cur_time;
|
||||
if (showTimestamps())
|
||||
// Format http://, https://
|
||||
// or markdown style (title)[http://..]
|
||||
if(textSize > index+7)
|
||||
{
|
||||
bool markdown = false;
|
||||
ucstring::size_type i = index;
|
||||
// advance index to url section if markdown style link is detected
|
||||
if (s[i] == '(')
|
||||
{
|
||||
// scan for ')[http://'
|
||||
while(i < textSize-9)
|
||||
{
|
||||
if (s[i] == ')' && s[i+1] == '[')
|
||||
{
|
||||
i += 2;
|
||||
markdown = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
if (s[i] == ')')
|
||||
{
|
||||
i += 1;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if (textSize > i + 7)
|
||||
{
|
||||
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);
|
||||
if (node && node->getValueBool())
|
||||
cur_time = CInterfaceManager::getTimestampHuman("[%I:%M:%S %p] ");
|
||||
else
|
||||
cur_time = CInterfaceManager::getTimestampHuman();
|
||||
}
|
||||
|
||||
// if text contain any color code, set the text formated and white,
|
||||
// otherwise, set text normal and apply global color
|
||||
size_t codePos = msg.find(ucstring("@{"));
|
||||
ucstring::size_type codePos = msg.find(ucstring("@{"));
|
||||
if (codePos != ucstring::npos)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
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->setColor(NLMISC::CRGBA::White);
|
||||
}
|
||||
else
|
||||
{
|
||||
msg = cur_time + msg;
|
||||
vt->setText(msg);
|
||||
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()
|
||||
{
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
namespace NLGUI
|
||||
{
|
||||
class CViewBase;
|
||||
class CInterfaceGroup;
|
||||
}
|
||||
|
||||
class ucstring;
|
||||
|
@ -49,8 +50,9 @@ public:
|
|||
* \param msg the actual 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 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
|
||||
static CChatTextManager &getInstance();
|
||||
|
||||
|
@ -73,6 +75,9 @@ private:
|
|||
~CChatTextManager();
|
||||
|
||||
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
|
||||
|
|
|
@ -132,6 +132,19 @@ extern void selectTipsOfTheDay (uint tips);
|
|||
// 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()
|
||||
static void releaseMainLoopScenes()
|
||||
|
@ -209,6 +222,8 @@ void releaseMainLoopReselect()
|
|||
{
|
||||
ProgressBar.release();
|
||||
|
||||
saveIngameResolution();
|
||||
|
||||
CInterfaceManager *pIM= CInterfaceManager::getInstance();
|
||||
|
||||
// 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();
|
||||
|
||||
saveIngameResolution();
|
||||
|
||||
// Release R2 editor if applicable
|
||||
R2::getEditor().autoConfigRelease(IsInRingSession);
|
||||
|
||||
|
|
Loading…
Reference in a new issue