diff --git a/code/nel/include/nel/gui/group_editbox.h b/code/nel/include/nel/gui/group_editbox.h
new file mode 100644
index 000000000..38d362589
--- /dev/null
+++ b/code/nel/include/nel/gui/group_editbox.h
@@ -0,0 +1,364 @@
+// Ryzom - MMORPG Framework
+// Copyright (C) 2010 Winch Gate Property Limited
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+
+
+#ifndef RZ_CTRL_EDITBOX_H
+#define RZ_CTRL_EDITBOX_H
+
+#include "nel/gui/interface_group.h"
+#include "nel/gui/group_editbox_base.h"
+#include "nel/3d/u_texture.h"
+
+namespace NLGUI
+{
+ class CEventDescriptor;
+ class CViewText;
+
+ // ----------------------------------------------------------------------------
+ class CGroupEditBox : public CGroupEditBoxBase
+ {
+ public:
+
+ class IComboKeyHandler
+ {
+ public:
+ virtual ~IComboKeyHandler(){}
+ virtual bool isComboKeyChat( const NLGUI::CEventDescriptorKey &edk ) const = 0;
+ };
+
+ enum TEntryType { Text, Integer, PositiveInteger, Float, PositiveFloat, Alpha, AlphaNum, AlphaNumSpace, Password, Filename, PlayerName }; // the type of entry this edit bot can deal with
+
+ DECLARE_UI_CLASS( CGroupEditBox )
+ /// Constructor
+ CGroupEditBox(const TCtorParam ¶m);
+ /// Dtor
+ ~CGroupEditBox();
+
+ bool parse(xmlNodePtr cur,CInterfaceGroup * parentGroup);
+ virtual uint32 getMemory() { return (uint32)(sizeof(*this)+_Id.size()); }
+
+ virtual void draw();
+
+ virtual bool handleEvent (const NLGUI::CEventDescriptor& eventDesc);
+
+ /// Accessors
+ ucstring getInputString() const { return _InputString; }
+ const ucstring &getInputStringRef() const { return _InputString; }
+ const ucstring &getPrompt() const { return _Prompt; }
+
+ /** Set the prompt
+ * NB : line returns are encoded as '\n', not '\r\n'
+ */
+ void setPrompt(const ucstring &s) { _Prompt = s; }
+ void setInputString(const ucstring &str);
+ void setInputStringRef(const ucstring &str) {_InputString = str; };
+ void setInputStringAsInt(sint32 val);
+ sint32 getInputStringAsInt() const;
+ void setInputStringAsInt64(sint64 val);
+ sint64 getInputStringAsInt64() const;
+ void setInputStringAsFloat(float val);
+ float getInputStringAsFloat() const;
+ void setInputStringAsStdString(const std::string &str);
+ std::string getInputStringAsStdString() const;
+ void setInputStringAsUtf8(const std::string &str);
+ std::string getInputStringAsUtf8() const;
+ void setColor(NLMISC::CRGBA col);
+
+
+ /// force the selection of all the text
+ void setSelectionAll();
+
+ virtual void checkCoords();
+ virtual void updateCoords();
+ virtual void clearViews ();
+
+ virtual void setActive (bool state);
+
+ static CGroupEditBox *getMenuFather() { return _MenuFather; }
+
+ void setCommand(const ucstring &command, bool execute);
+
+ // Stop parent from blinking
+ void stopParentBlink() { if (_Parent) _Parent->disableBlink(); }
+
+ // Get / set cursor position
+ sint32 getCursorPos () const {return _CursorPos;}
+ void setCursorPos (sint32 pos) {_CursorPos=pos;}
+
+ // Get / set cursor at previous line end
+ bool isCursorAtPreviousLineEnd () const {return _CursorAtPreviousLineEnd;}
+ void setCursorAtPreviousLineEnd (bool setCursor) {_CursorAtPreviousLineEnd=setCursor;}
+
+ // Get / set current selection position
+ static sint32 getSelectCursorPos () {return _SelectCursorPos;}
+ static void setSelectCursorPos (sint32 pos) {_SelectCursorPos=pos;}
+
+ // Get the view text
+ const CViewText *getViewText () const {return _ViewText;}
+
+ // Get the historic information
+ sint32 getMaxHistoric() const {return _MaxHistoric;}
+ sint32 getCurrentHistoricIndex () const {return _CurrentHistoricIndex;}
+ void setCurrentHistoricIndex (sint32 index) {_CurrentHistoricIndex=index;}
+ const ucstring &getHistoric(uint32 index) const {return _Historic[index];}
+ uint32 getNumHistoric() const {return (uint32)_Historic.size ();}
+
+ // Get on change action handler
+ const std::string &getAHOnChange() const {return _AHOnChange;}
+ const std::string &getParamsOnChange() const {return _ParamsOnChange;}
+
+ void cutSelection();
+
+ /// From CInterfaceElement
+ sint32 getMaxUsedW() const;
+ sint32 getMinUsedW() const;
+
+ // Copy the selection into buffer
+ void copy();
+ // Paste the selection into buffer
+ void paste();
+ // Write the string into buffer
+ void writeString(const ucstring &str, bool replace = true, bool atEnd = true);
+
+ // Expand the expression (true if there was a '/' at the start of the line)
+ bool expand();
+
+ // Back space
+ void back();
+
+ // ignore the next char/key event -> useful when a key set the focus on an editbox (keydown is received, the focus, then keychar is received by the editbox again, but is irrelevant)
+ void bypassNextKey() { _BypassNextKey = true; }
+
+ // True if the editBox loose the focus on enter
+ bool getLooseFocusOnEnter() const {return _LooseFocusOnEnter;}
+ //
+ virtual void clearAllEditBox();
+ // From CInterfaceElement
+ virtual bool wantSerialConfig() const;
+ // From CInterfaceElement
+ virtual void serialConfig(NLMISC::IStream &f);
+ // From CInterfaceElement
+ virtual void onQuit();
+ // From CInterfaceElement
+ virtual void onLoadConfig();
+
+ // from CCtrlBase
+ virtual void elementCaptured(CCtrlBase *capturedElement);
+
+ // from CCtrlBase
+ virtual void onKeyboardCaptureLost();
+
+ // set the input string as "default". will be reseted at first click (used for user information)
+ void setDefaultInputString(const ucstring &str);
+
+ // For Interger and PositiveInteger, can specify min and max values
+ void setIntegerMinValue(sint32 minValue) {_IntegerMinValue=minValue;}
+ void setIntegerMaxValue(sint32 maxValue) {_IntegerMaxValue=maxValue;}
+ void setPositiveIntegerMinValue(uint32 minValue) {_PositiveIntegerMinValue=minValue;}
+ void setPositiveIntegerMaxValue(uint32 maxValue) {_PositiveIntegerMaxValue=maxValue;}
+
+ void setFocusOnText();
+
+ int luaSetSelectionAll(CLuaState &ls);
+ int luaSetupDisplayText(CLuaState &ls);
+ int luaSetFocusOnText(CLuaState &ls);
+ int luaCancelFocusOnText(CLuaState &ls);
+ REFLECT_EXPORT_START(CGroupEditBox, CGroupEditBoxBase)
+ REFLECT_LUA_METHOD("setupDisplayText", luaSetupDisplayText);
+ REFLECT_LUA_METHOD("setSelectionAll", luaSetSelectionAll);
+ REFLECT_LUA_METHOD("setFocusOnText", luaSetFocusOnText);
+ REFLECT_LUA_METHOD("cancelFocusOnText", luaCancelFocusOnText);
+ REFLECT_STRING("input_string", getInputStringAsStdString, setInputStringAsStdString);
+ REFLECT_UCSTRING("uc_input_string", getInputString, setInputString);
+ REFLECT_EXPORT_END
+
+ /** Restore the original value of the edit box.
+ * This value is captured when the edit box get focus
+ * (return true if no undo was available)
+ * Will always fails ifthe edito box do not have the focus
+ */
+ bool undo();
+
+ /** Cancel last undo operation
+ * Return true if redo operation is available
+ */
+ bool redo();
+
+ /// freeze the control (loose focus, and cannot edit)
+ void setFrozen (bool state);
+ bool getFrozen () const { return _Frozen; }
+
+ protected:
+
+ // Cursor infos
+ float _BlinkTime;
+ sint32 _CursorPos;
+ uint32 _MaxNumChar;
+ uint32 _MaxNumReturn;
+ uint32 _MaxFloatPrec; // used in setInputStringAsFloat() only
+ sint32 _MaxCharsSize;
+ sint32 _FirstVisibleChar;
+ sint32 _LastVisibleChar;
+
+ // Text selection
+ static sint32 _SelectCursorPos;
+ bool _SelectingText;
+ NLMISC::CRGBA _TextSelectColor;
+ NLMISC::CRGBA _BackSelectColor;
+
+ // Text info
+ ucstring _Prompt;
+ ucstring _InputString;
+ CViewText *_ViewText;
+
+ // undo / redo
+ ucstring _StartInputString; // value of the input string when focus was acuired first
+ ucstring _ModifiedInputString;
+
+
+ // Historic info
+ typedef std::deque THistoric;
+ THistoric _Historic;
+ uint32 _MaxHistoric;
+ sint32 _CurrentHistoricIndex;
+ sint32 _PrevNumLine;
+
+ // Action Handler
+ std::string _AHOnChange;
+ std::string _ParamsOnChange;
+ std::string _ListMenuRight;
+
+ std::string _AHOnFocusLost;
+ std::string _AHOnFocusLostParams;
+
+ // entry type
+ TEntryType _EntryType;
+
+
+ bool _Setupped : 1; // setup
+ bool _BypassNextKey : 1;
+ bool _BlinkState : 1;
+ bool _CursorAtPreviousLineEnd : 1; // force the cursor to be displayed at the end of the previous line end (if END has beeen pressed while in a string split accross 2 lines)
+ bool _LooseFocusOnEnter : 1;
+ bool _ResetFocusOnHide : 1;
+ bool _BackupFatherContainerPos : 1; // Backup father container position when characters are typed.
+ // If the edit box is at the bottom of the screen and if it expands on y
+ // because of multiline, thz parent container will be moved to top
+ // The good position can be restored by a press on enter then
+ bool _WantReturn : 1; // Want return char, don't call the enter action handler
+ bool _Savable : 1; // should content be saved ?
+ bool _DefaultInputString : 1; // Is the current input string the default one (should not be edited)
+ bool _Frozen : 1; // is the control frozen? (cannot edit in it)
+
+ bool _CanRedo : 1;
+ bool _CanUndo : 1;
+
+ std::vector _NegativeFilter;
+
+ sint _CursorTexID;
+ sint32 _CursorWidth;
+
+ sint32 _IntegerMinValue;
+ sint32 _IntegerMaxValue;
+ uint32 _PositiveIntegerMinValue;
+ uint32 _PositiveIntegerMaxValue;
+
+ sint32 _ViewTextDeltaX;
+
+ private:
+ void setupDisplayText();
+ void makeTopWindow();
+ void handleEventChar(const NLGUI::CEventDescriptorKey &event);
+ void handleEventString(const NLGUI::CEventDescriptorKey &event);
+ void setup();
+ void triggerOnChangeAH();
+ void appendStringFromClipboard(const ucstring &str);
+
+ ucstring getSelection();
+
+ static CGroupEditBox *_MenuFather;
+
+ static bool isValidAlphaNumSpace(ucchar c)
+ {
+ if (c > 255) return false;
+ char ac = (char) c;
+ return (ac >= '0' && ac <= '9') ||
+ (ac >= 'a' && ac <= 'z') ||
+ (ac >= 'A' && ac <= 'Z') ||
+ ac==' ';
+ }
+
+ static bool isValidAlphaNum(ucchar c)
+ {
+ if (c > 255) return false;
+ char ac = (char) c;
+ return (ac >= '0' && ac <= '9') ||
+ (ac >= 'a' && ac <= 'z') ||
+ (ac >= 'A' && ac <= 'Z');
+ }
+
+ static bool isValidAlpha(ucchar c)
+ {
+ if (c > 255) return false;
+ char ac = (char) c;
+ return (ac >= 'a' && ac <= 'z') ||
+ (ac >= 'A' && ac <= 'Z');
+ }
+
+ static bool isValidPlayerNameChar(ucchar c)
+ {
+ // valid player name (with possible shard prefix / suffix format
+ return isValidAlpha(c) || c=='.' || c=='(' || c==')';
+ }
+
+ static bool isValidFilenameChar(ucchar c)
+ {
+ if (c == '\\' ||
+ c == '/' ||
+ c == ':' ||
+ c == '*' ||
+ c == '?' ||
+ c == '\"' ||
+ c == '<' ||
+ c == '>' ||
+ c == '|') return false;
+ return true;
+ }
+ //
+ bool isFiltered(ucchar c)
+ {
+ uint length = (uint)_NegativeFilter.size();
+ for (uint k = 0; k < length; ++k)
+ {
+ if ((ucchar) _NegativeFilter[k] == c) return true;
+ }
+ return false;
+ }
+
+ static IComboKeyHandler *comboKeyHandler;
+
+ public:
+ static void setComboKeyHandler( IComboKeyHandler *handler ){ comboKeyHandler = handler; }
+
+ };
+
+
+}
+
+#endif // RZ_CTRL_EDITBOX_H
+
+/* End of ctrl_editbox.h */
diff --git a/code/nel/src/gui/group_editbox.cpp b/code/nel/src/gui/group_editbox.cpp
new file mode 100644
index 000000000..062981568
--- /dev/null
+++ b/code/nel/src/gui/group_editbox.cpp
@@ -0,0 +1,1486 @@
+// Ryzom - MMORPG Framework
+// Copyright (C) 2010 Winch Gate Property Limited
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+#include "nel/gui/group_editbox.h"
+#include "nel/misc/command.h"
+#include "nel/gui/view_text.h"
+#include "nel/misc/xml_auto_ptr.h"
+#include "nel/gui/interface_options.h"
+#include "nel/gui/ctrl_draggable.h"
+#include "nel/gui/group_container_base.h"
+#include "nel/gui/lua_ihm.h"
+#include "nel/gui/widget_manager.h"
+#include "nel/gui/view_renderer.h"
+#include "nel/gui/db_manager.h"
+
+using namespace std;
+using namespace NLMISC;
+using namespace NL3D;
+
+
+namespace NLGUI
+{
+
+
+ /////////////
+ // STATICS //
+ /////////////
+
+ sint32 CGroupEditBox::_SelectCursorPos = 0;
+ CGroupEditBox *CGroupEditBox::_MenuFather = NULL;
+ CGroupEditBox::IComboKeyHandler* CGroupEditBox::comboKeyHandler = NULL;
+
+
+ // ----------------------------------------------------------------------------
+ NLMISC_REGISTER_OBJECT(CViewBase, CGroupEditBox, std::string, "edit_box");
+
+ CGroupEditBox::CGroupEditBox(const TCtorParam ¶m) :
+ CGroupEditBoxBase(param),
+ _BlinkTime(0.f),
+ _CursorPos(0),
+ _MaxNumChar(std::numeric_limits::max()),
+ _MaxNumReturn(std::numeric_limits::max()),
+ _MaxFloatPrec(20),
+ _MaxCharsSize(32768),
+ _FirstVisibleChar(0),
+ _LastVisibleChar(0),
+ _SelectingText(false),
+ _ViewText(NULL),
+ _MaxHistoric(0),
+ _CurrentHistoricIndex(-1),
+ _PrevNumLine(1),
+ _EntryType(Text),
+ _Setupped(false),
+ _BypassNextKey(false),
+ _BlinkState(false),
+ _CursorAtPreviousLineEnd(false),
+ _LooseFocusOnEnter(true),
+ _ResetFocusOnHide(false),
+ _BackupFatherContainerPos(false),
+ _WantReturn(false),
+ _Savable(true),
+ _DefaultInputString(false),
+ _Frozen(false),
+ _CanRedo(false),
+ _CanUndo(false),
+ _CursorTexID(-1),
+ _CursorWidth(0),
+ _IntegerMinValue(INT_MIN),
+ _IntegerMaxValue(INT_MAX),
+ _PositiveIntegerMinValue(0),
+ _PositiveIntegerMaxValue(UINT_MAX),
+ _ViewTextDeltaX(0)
+
+ {
+ _Prompt = ">";
+ _BackSelectColor= CRGBA::White;
+ _TextSelectColor= CRGBA::Black;
+ }
+
+ // ----------------------------------------------------------------------------
+ CGroupEditBox::~CGroupEditBox()
+ {
+ if (this == _CurrSelection) _CurrSelection = NULL;
+ if (CWidgetManager::getInstance()->getCaptureKeyboard() == this || CWidgetManager::getInstance()->getOldCaptureKeyboard() == this)
+ {
+ CWidgetManager::getInstance()->resetCaptureKeyboard();
+ }
+ }
+
+ // ----------------------------------------------------------------------------
+ bool CGroupEditBox::parse(xmlNodePtr cur, CInterfaceGroup * parentGroup)
+ {
+ if(!CInterfaceGroup::parse(cur, parentGroup))
+ return false;
+ CXMLAutoPtr prop;
+
+ if (! CInterfaceGroup::parse(cur,parentGroup) )
+ {
+ string tmp = "cannot parse view:"+getId()+", parent:"+parentGroup->getId();
+ nlinfo(tmp.c_str());
+ return false;
+ }
+
+ // NB: use InterfaceGroup "OnEnter" data. Different script params for an historic reason
+ CAHManager::getInstance()->parseAH(cur, "onenter", "params", _AHOnEnter, _AHOnEnterParams);
+
+ prop = (char*) xmlGetProp( cur, (xmlChar*)"onchange" );
+ if (prop) _AHOnChange = (const char *) prop;
+ prop = (char*) xmlGetProp( cur, (xmlChar*)"onchange_params" );
+ if (prop) _ParamsOnChange = (const char *) prop;
+
+ prop = (char*) xmlGetProp( cur, (xmlChar*)"on_focus_lost" );
+ if (prop) _AHOnFocusLost = (const char *) prop;
+ prop = (char*) xmlGetProp( cur, (xmlChar*)"on_focus_lost_params" );
+ if (prop) _AHOnFocusLostParams = (const char *) prop;
+
+ prop = (char*) xmlGetProp( cur, (xmlChar*)"on_focus" );
+ if (prop) _AHOnFocus = (const char *) prop;
+ prop = (char*) xmlGetProp( cur, (xmlChar*)"on_focus_params" );
+ if (prop) _AHOnFocusParams = (const char *) prop;
+
+ prop = (char*) xmlGetProp( cur, (xmlChar*)"max_num_chars" );
+ if (prop) fromString((const char*)prop, _MaxNumChar);
+
+ prop = (char*) xmlGetProp( cur, (xmlChar*)"max_num_return" );
+ if (prop) fromString((const char*)prop, _MaxNumReturn);
+
+ prop = (char*) xmlGetProp( cur, (xmlChar*)"max_chars_size" );
+ if (prop) fromString((const char*)prop, _MaxCharsSize);
+
+ prop = (char*) xmlGetProp( cur, (xmlChar*)"enter_loose_focus" );
+ if (prop) _LooseFocusOnEnter = convertBool(prop);
+
+ prop = (char*) xmlGetProp( cur, (xmlChar*)"enter_recover_focus" );
+ if (prop) _RecoverFocusOnEnter = convertBool(prop);
+
+ prop = (char*) xmlGetProp( cur, (xmlChar*)"reset_focus_on_hide" );
+ if (prop) _ResetFocusOnHide = convertBool(prop);
+
+ prop = (char*) xmlGetProp( cur, (xmlChar*)"prompt" );
+ if (prop) _Prompt = (const char*)prop;
+
+ prop = (char*) xmlGetProp( cur, (xmlChar*)"entry_type" );
+ _EntryType = Text;
+ if (prop)
+ {
+ if (stricmp(prop, "text") == 0) _EntryType = Text;
+ else if (stricmp(prop, "integer") == 0) _EntryType = Integer;
+ else if (stricmp(prop, "positive_integer") == 0) _EntryType = PositiveInteger;
+ else if (stricmp(prop, "float") == 0) _EntryType = Float;
+ else if (stricmp(prop, "positive_float") == 0) _EntryType = PositiveFloat;
+ else if (stricmp(prop, "alpha") == 0) _EntryType = Alpha;
+ else if (stricmp(prop, "alpha_num") == 0) _EntryType = AlphaNum;
+ else if (stricmp(prop, "alpha_num_space") == 0) _EntryType = AlphaNumSpace;
+ else if (stricmp(prop, "password") == 0) _EntryType = Password;
+ else if (stricmp(prop, "filename") == 0) _EntryType = Filename;
+ else if (stricmp(prop, "playername") == 0) _EntryType = PlayerName;
+ else nlwarning(" Unknown entry type %s", (const char *) prop);
+ }
+
+ prop = (char*) xmlGetProp( cur, (xmlChar*)"menu_r" );
+ if (prop)
+ {
+ string tmp = (const char *) prop;
+ _ListMenuRight = strlwr(tmp);
+ }
+
+ prop = (char*) xmlGetProp( cur, (xmlChar*)"max_historic" );
+ if (prop) fromString((const char*)prop, _MaxHistoric);
+
+ prop = (char*) xmlGetProp( cur, (xmlChar*)"backup_father_container_pos" );
+ if (prop) _BackupFatherContainerPos = convertBool(prop);
+
+ prop = (char*) xmlGetProp( cur, (xmlChar*)"want_return" );
+ if (prop) _WantReturn = convertBool(prop);
+
+ prop = (char*) xmlGetProp( cur, (xmlChar*)"savable" );
+ if (prop) _Savable = convertBool(prop);
+
+ // For float conversion only
+ prop = (char*) xmlGetProp( cur, (xmlChar*)"max_float_prec" );
+ if (prop)
+ {
+ fromString((const char*)prop, _MaxFloatPrec);
+ _MaxFloatPrec = min((uint32)20, _MaxFloatPrec);
+ }
+
+ // negative characters filter
+ prop = (char*) xmlGetProp( cur, (xmlChar*)"negative_filter" );
+ if (prop)
+ {
+ uint length = (uint)strlen(prop);
+ _NegativeFilter.resize(length);
+ std::copy((const char *) prop, (const char *) prop + length, _NegativeFilter.begin());
+ }
+
+ return true;
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupEditBox::draw ()
+ {
+ //
+ CViewRenderer &rVR = *CViewRenderer::getInstance();
+ //
+ /*CRGBA col;
+ col.modulateFromColor(CRGBA(64,64,64,255), pIM->getGlobalColorForContent());
+ rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal, _WReal, _HReal, 0, false, rVR.getBlankTextureId(), col );
+ */
+
+ // Frozen? display text in "grayed"
+ CRGBA bkupTextColor;
+ if(_Frozen && _ViewText)
+ {
+ bkupTextColor= _ViewText->getColor();
+ CRGBA grayed= bkupTextColor;
+ grayed.A>>=2;
+ _ViewText->setColor(grayed);
+ }
+
+ // draw the group and thus the text
+ CInterfaceGroup::draw();
+
+ // restore the text color if changed
+ if(_Frozen && _ViewText)
+ _ViewText->setColor(bkupTextColor);
+
+ // no text setuped? abort
+ if (!_ViewText) return;
+
+ // Display the selection if needed
+ if (_CurrSelection == this && _SelectCursorPos!=_CursorPos)
+ {
+ sint32 blankTextId= rVR.getBlankTextureId();
+ CRGBA col= _BackSelectColor;
+ col.A= CWidgetManager::getInstance()->getGlobalColorForContent().A;
+ sint32 minPos= min(_CursorPos, _SelectCursorPos) + (sint32)_Prompt.length();
+ sint32 maxPos= max(_CursorPos, _SelectCursorPos) + (sint32)_Prompt.length();
+
+ // get its position on screen
+ sint cxMinPos, cyMinPos;
+ sint cxMaxPos, cyMaxPos;
+ sint height;
+ _ViewText->getCharacterPositionFromIndex(minPos, false, cxMinPos, cyMinPos, height);
+ _ViewText->getCharacterPositionFromIndex(maxPos, false, cxMaxPos, cyMaxPos, height);
+
+ // Multiline selection if cy different!
+ if(cyMinPos!=cyMaxPos)
+ {
+ nlassert(cyMaxPosgetXReal() + cxMinPos, _ViewText->getYReal() + cyMinPos, _ViewText->getW()-cxMinPos, height, 0, 0, blankTextId, col);
+
+ // Draw One quad for all lines into the big selection (if any)
+ sint32 cyBigQuad= cyMaxPos+height;
+ if(cyBigQuadgetXReal(), _ViewText->getYReal() + cyBigQuad, _ViewText->getW(), cyMinPos-cyBigQuad, 0, 0, blankTextId, col);
+ }
+
+ // draw the 3rd quad from the last line from start of line to max pos
+ rVR.drawRotFlipBitmap(_RenderLayer, _ViewText->getXReal(), _ViewText->getYReal() + cyMaxPos, cxMaxPos, height, 0, 0, blankTextId, col);
+ }
+ else
+ {
+ rVR.drawRotFlipBitmap(_RenderLayer, _ViewText->getXReal() + cxMinPos, _ViewText->getYReal() + cyMinPos, cxMaxPos-cxMinPos, height, 0, 0, blankTextId, col);
+ }
+
+ // Draw The Selection String in black
+ CRGBA bkup= _ViewText->getColor();
+ _ViewText->setColor(_TextSelectColor);
+ _ViewText->enableStringSelection(minPos, maxPos);
+ // redraw just this string,clipped by the group
+ CInterfaceGroup::drawElement(_ViewText);
+ // bkup
+ _ViewText->setColor(bkup);
+ _ViewText->disableStringSelection();
+ }
+
+ // Display the cursor if needed
+ if (CWidgetManager::getInstance()->getCaptureKeyboard () == this)
+ {
+ _BlinkTime += 0.0025f;
+ if (_BlinkTime > 0.25f)
+ {
+ _BlinkTime = fmodf(_BlinkTime, 0.25f);
+ _BlinkState = !_BlinkState;
+ }
+ if (_BlinkState) // is the cursor shown ?
+ {
+ // get its position on screen
+ sint cx, cy;
+ sint height;
+ _ViewText->getCharacterPositionFromIndex(_CursorPos + (sint)_Prompt.length(), _CursorAtPreviousLineEnd, cx, cy, height);
+ // display the cursor
+ // get the texture for the cursor
+ if (_CursorTexID == -1)
+ {
+ _CursorTexID = rVR.getTextureIdFromName("text_cursor.tga");
+ sint32 dummyCursorHeight;
+ rVR.getTextureSizeFromId(_CursorTexID, _CursorWidth, dummyCursorHeight);
+ }
+ // draw in a layer after to be on TOP of the text
+ sint32 cursorx = std::max((sint) 0, (sint)(cx - (_CursorWidth >> 1)));
+ rVR.drawRotFlipBitmap(_RenderLayer+1, _ViewText->getXReal() + cursorx, _ViewText->getYReal() + cy, 3, height, 0, 0, _CursorTexID);
+ }
+ }
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupEditBox::copy()
+ {
+ if (_CurrSelection != this)
+ {
+ nlwarning("Selection can only be on focus");
+ }
+ stopParentBlink();
+
+ // get the selection and copy it
+ if (CViewRenderer::getInstance()->getDriver()->copyTextToClipboard(getSelection()))
+ nlinfo ("Chat input was copied in the clipboard");
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupEditBox::paste()
+ {
+ if(_CurrSelection != NULL)
+ {
+ if (_CurrSelection != this)
+ {
+ nlwarning("Selection can only be on focus");
+ }
+ cutSelection();
+ }
+
+ ucstring sString;
+
+ if (CViewRenderer::getInstance()->getDriver()->pasteTextFromClipboard(sString))
+ {
+ // append string now
+ appendStringFromClipboard(sString);
+ }
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupEditBox::appendStringFromClipboard(const ucstring &str)
+ {
+ stopParentBlink();
+ makeTopWindow();
+
+ writeString(str, true, false);
+ nlinfo ("Chat input was pasted from the clipboard");
+
+ triggerOnChangeAH();
+
+ _CursorAtPreviousLineEnd = false;
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupEditBox::writeString(const ucstring &str, bool replace, bool atEnd)
+ {
+ sint length = (sint)str.length();
+
+ ucstring toAppend;
+ // filter character depending on the entry type
+ switch (_EntryType)
+ {
+ case Text:
+ case Password:
+ {
+ if (_NegativeFilter.empty())
+ {
+ toAppend = str;
+ }
+ else
+ {
+ for (sint k = 0; k < length; ++k)
+ {
+ if (!isFiltered(str[k]))
+ {
+ toAppend += str[k];
+ }
+ }
+ }
+ // remove '\r' characters
+ toAppend.erase(std::remove(toAppend.begin(), toAppend.end(), (ucchar) '\r'), toAppend.end());
+
+ }
+ break;
+ case PositiveInteger:
+ case PositiveFloat:
+ {
+ for (sint k = 0; k < length; ++k)
+ {
+ if (isdigit(str[k]) || str[k]== ' ' ||
+ (_EntryType==PositiveFloat && str[k]=='.') )
+ {
+ if (!isFiltered(str[k]))
+ {
+ toAppend += str[k];
+ }
+ }
+ }
+ }
+ break;
+ case Integer:
+ case Float:
+ {
+ for (sint k = 0; k < length; ++k)
+ {
+ if (isdigit(str[k]) || str[k]== ' ' || str[k]== '-' ||
+ (_EntryType==Float && str[k]=='.') )
+ {
+ if (!isFiltered(str[k]))
+ {
+ toAppend += str[k];
+ }
+ }
+ }
+ }
+ break;
+ case AlphaNumSpace:
+ {
+ for (sint k = 0; k < length; ++k)
+ {
+ if (isValidAlphaNumSpace(str[k]))
+ {
+ if (!isFiltered(str[k]))
+ {
+ toAppend += str[k];
+ }
+ }
+ }
+ }
+ break;
+ case AlphaNum:
+ {
+ for (sint k = 0; k < length; ++k)
+ {
+ if (isValidAlphaNum(str[k]))
+ {
+ if (!isFiltered(str[k]))
+ {
+ toAppend += str[k];
+ }
+ }
+ }
+ }
+ break;
+ case Alpha:
+ {
+ for (sint k = 0; k < length; ++k)
+ {
+ if (isValidAlpha(str[k]))
+ {
+ if (!isFiltered(str[k]))
+ {
+ toAppend += str[k];
+ }
+ }
+ }
+ }
+ break;
+ case Filename:
+ {
+ for (sint k = 0; k < length; ++k)
+ {
+ if (isValidFilenameChar(str[k]))
+ {
+ if (!isFiltered(str[k]))
+ {
+ toAppend += str[k];
+ }
+ }
+ }
+ }
+ break;
+ case PlayerName:
+ {
+ for (sint k = 0; k < length; ++k)
+ {
+ if (isValidPlayerNameChar(str[k]))
+ {
+ if (!isFiltered(str[k]))
+ {
+ toAppend += str[k];
+ }
+ }
+ }
+ }
+ }
+ length = (sint)toAppend.size();
+ if ((uint) (_InputString.length() + length) > _MaxNumChar)
+ {
+ length = _MaxNumChar - (sint)_InputString.length();
+ }
+ ucstring toAdd = toAppend.substr(0, length);
+ sint32 minPos;
+ sint32 maxPos;
+ if (_CurrSelection == this)
+ {
+ minPos = min(_CursorPos, _SelectCursorPos);
+ maxPos = max(_CursorPos, _SelectCursorPos);
+ }
+ else
+ {
+ minPos = _CursorPos;
+ maxPos = _CursorPos;
+ }
+
+ nlinfo("%d, %d", minPos, maxPos);
+ if (replace)
+ {
+ _InputString = _InputString.substr(0, minPos) + toAdd + _InputString.substr(maxPos);
+ _CursorPos = minPos+(sint32)toAdd.length();
+ }
+ else
+ {
+ if (atEnd)
+ {
+ _InputString = _InputString.substr(0, maxPos) + toAdd + _InputString.substr(maxPos);
+ _CursorPos = maxPos;
+ _SelectCursorPos = _CursorPos;
+
+ }
+ else
+ {
+ _InputString = _InputString.substr(0, minPos) + toAdd + _InputString.substr(minPos);
+ _CursorPos = minPos+(sint32)toAdd.length();
+ _SelectCursorPos = maxPos+(sint32)toAdd.length();
+ }
+ }
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupEditBox::handleEventChar(const NLGUI::CEventDescriptorKey &rEDK)
+ {
+ stopParentBlink();
+ switch(rEDK.getChar())
+ {
+ case KeyESCAPE:
+ _CurrentHistoricIndex= -1;
+ CWidgetManager::getInstance()->setCaptureKeyboard(NULL);
+ // stop selection
+ _CurrSelection = NULL;
+ _CursorAtPreviousLineEnd = false;
+ break;
+ case KeyTAB:
+ makeTopWindow();
+ break;
+ // OTHER
+ default:
+ if ((rEDK.getChar() == KeyRETURN) && !_WantReturn)
+ {
+ // update historic.
+ if(_MaxHistoric)
+ {
+ if( !_InputString.empty() )
+ {
+ _Historic.push_front(_InputString);
+ if(_Historic.size()>_MaxHistoric)
+ _Historic.pop_back();
+ }
+ _CurrentHistoricIndex= -1;
+ }
+
+ _CursorPos = 0;
+ // loose the keyboard focus
+ if (NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:CHAT:ENTER_DONT_QUIT_CB")->getValue32() == 0)
+ {
+ if(_LooseFocusOnEnter)
+ CWidgetManager::getInstance()->setCaptureKeyboard(NULL);
+ }
+ // stop selection
+ _CurrSelection = NULL;
+ _CursorAtPreviousLineEnd = false;
+ CAHManager::getInstance()->runActionHandler(_AHOnEnter, this, _AHOnEnterParams);
+ }
+ else
+ {
+ // If the char is not alphanumeric -> return.
+ // if(!isalnum(ec.Char))
+ // return
+ if( (rEDK.getChar()>=32) || (rEDK.getChar() == KeyRETURN) )
+ {
+ if (rEDK.getChar() == KeyRETURN)
+ {
+ ucstring copyStr= _InputString;
+ if ((uint) std::count(copyStr.begin(), copyStr.end(), '\n') >= _MaxNumReturn)
+ break;
+ }
+
+ // if selection is activated, then cut the selection
+ if(_CurrSelection != NULL)
+ {
+ if (_CurrSelection != this)
+ {
+ nlwarning("Selection can only be on focus");
+ }
+ cutSelection();
+ }
+
+ ucchar c = (rEDK.getChar() == KeyRETURN)?'\n':rEDK.getChar();
+ if (isFiltered(c)) return;
+ switch(_EntryType)
+ {
+ case Integer:
+ if (c > 255 || !(c =='-' || c==' ' || isdigit((int) c)))
+ return;
+ break;
+ case PositiveInteger:
+ if (c > 255 || !(c == ' ' || isdigit((int) c)))
+ return;
+ break;
+ case Float:
+ if (c > 255 || !(c =='-' || c==' ' || c=='.' || isdigit((int) c)))
+ return;
+ break;
+ case PositiveFloat:
+ if (c > 255 || !(c == ' ' || c=='.' || isdigit((int) c)))
+ return;
+ break;
+ case AlphaNumSpace:
+ if (!isValidAlphaNumSpace(c))
+ return;
+ break;
+ case AlphaNum:
+ if (!isValidAlphaNum(c))
+ return;
+ break;
+ case Alpha:
+ if (!isValidAlpha(c))
+ return;
+ break;
+ case Filename:
+ if (!isValidFilenameChar(c))
+ return;
+ break;
+ case PlayerName:
+ if (!isValidPlayerNameChar(c))
+ return;
+ break;
+ default:
+ break;
+ }
+ // verify integer bounds
+ if(_EntryType==Integer && (_IntegerMinValue!=INT_MIN || _IntegerMaxValue!=INT_MAX))
+ {
+ // estimate new string
+ ucstring copyStr= _InputString;
+ ucstring::iterator it = copyStr.begin() + _CursorPos;
+ copyStr.insert(it, c);
+ sint32 value;
+ fromString(copyStr.toString(), value);
+ // if out of bounds, abort char
+ if(value<_IntegerMinValue || value>_IntegerMaxValue)
+ return;
+ }
+ // verify integer bounds
+ if(_EntryType==PositiveInteger && (_PositiveIntegerMinValue!=0 || _PositiveIntegerMaxValue!=UINT_MAX))
+ {
+ // estimate new string
+ ucstring copyStr= _InputString;
+ ucstring::iterator it = copyStr.begin() + _CursorPos;
+ copyStr.insert(it, c);
+ // \todo yoyo: this doesn't really work i think....
+ uint32 value;
+ fromString(copyStr.toString(), value);
+ // if out of bounds, abort char
+ if(value<_PositiveIntegerMinValue || value>_PositiveIntegerMaxValue)
+ return;
+ }
+ // verify max num char
+ if ((uint) _InputString.length() < _MaxNumChar)
+ {
+ makeTopWindow();
+ ucstring::iterator it = _InputString.begin() + _CursorPos;
+ _InputString.insert(it, c);
+ ++ _CursorPos;
+ triggerOnChangeAH();
+ }
+ if (rEDK.getChar() == KeyRETURN)
+ {
+ CAHManager::getInstance()->runActionHandler(_AHOnEnter, this, _AHOnEnterParams);
+ }
+ }
+ _CursorAtPreviousLineEnd = false;
+ }
+ break;
+ }
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupEditBox::handleEventString(const NLGUI::CEventDescriptorKey &rEDK)
+ {
+ appendStringFromClipboard(rEDK.getString());
+ }
+
+ // ----------------------------------------------------------------------------
+ bool CGroupEditBox::undo()
+ {
+ if (CWidgetManager::getInstance()->getCaptureKeyboard() != this) return false;
+ if (!_CanUndo) return false;
+ _ModifiedInputString = _InputString;
+ setInputString(_StartInputString);
+ _CanUndo = false;
+ _CanRedo = true;
+ setCursorPos((sint32)_InputString.length());
+ setSelectionAll();
+ return true;
+ }
+
+ // ----------------------------------------------------------------------------
+ bool CGroupEditBox::redo()
+ {
+ if (CWidgetManager::getInstance()->getCaptureKeyboard() != this) return false;
+ if (!_CanRedo) return false;
+ setInputString(_ModifiedInputString);
+ _CanUndo = true;
+ _CanRedo = false;
+ setCursorPos((sint32)_InputString.length());
+ setSelectionAll();
+ return true;
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupEditBox::triggerOnChangeAH()
+ {
+ _CanUndo = true;
+ _CanRedo = false;
+
+ if (!_AHOnChange.empty())
+ CAHManager::getInstance()->runActionHandler(_AHOnChange, this, _ParamsOnChange);
+
+ }
+
+ // ----------------------------------------------------------------------------
+ bool CGroupEditBox::expand()
+ {
+ if ((_EntryType == Integer) ||
+ (_EntryType == PositiveInteger) ||
+ (_EntryType == Float) ||
+ (_EntryType == PositiveFloat) ||
+ (_EntryType == AlphaNumSpace) ||
+ (_EntryType == AlphaNum) ||
+ (_EntryType == Alpha) ||
+ (_EntryType == Filename) ||
+ (_EntryType == PlayerName)
+ )
+ return false;
+
+ if(!_InputString.empty())
+ {
+ if (_InputString[0] == '/')
+ {
+ makeTopWindow();
+ // for french, deutsch and russian, be aware of unicode
+ std::string command = ucstring(_InputString.substr(1)).toUtf8();
+ ICommand::expand(command);
+ // then back to ucstring
+ _InputString.fromUtf8(command);
+ _InputString = '/' + _InputString;
+ _CursorPos = (sint32)_InputString.length();
+ _CursorAtPreviousLineEnd = false;
+ triggerOnChangeAH();
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupEditBox::back()
+ {
+ makeTopWindow();
+ // if selection is activated and not same cursors pos, then cut the selection
+ if(_CurrSelection != NULL && _CursorPos != _SelectCursorPos)
+ {
+ if (_CurrSelection != this)
+ {
+ nlwarning("Selection can only be on focus");
+ }
+ cutSelection();
+ _CursorAtPreviousLineEnd = false;
+ }
+ // else delete last character
+ else if(_InputString.size () > 0 && _CursorPos != 0)
+ {
+ ucstring::iterator it = _InputString.begin() + (_CursorPos - 1);
+ _InputString.erase(it);
+ -- _CursorPos;
+ _CursorAtPreviousLineEnd = false;
+ triggerOnChangeAH();
+ }
+ // must stop selection in all case
+ if (_CurrSelection)
+ {
+ if (_CurrSelection != this)
+ {
+ nlwarning("Selection can only be on focus");
+ }
+ _CurrSelection = NULL;
+ }
+ }
+
+ // ----------------------------------------------------------------------------
+ bool CGroupEditBox::handleEvent (const NLGUI::CEventDescriptor& event)
+ {
+ if (!_Active || !_ViewText)
+ return false;
+ if (event.getType() == NLGUI::CEventDescriptor::key)
+ {
+ if (_BypassNextKey)
+ {
+ _BypassNextKey = false;
+ return true;
+ }
+ ///////////////
+ // KEY EVENT //
+ ///////////////
+ const NLGUI::CEventDescriptorKey &rEDK = (const NLGUI::CEventDescriptorKey&)event;
+ switch(rEDK.getKeyEventType())
+ {
+ case NLGUI::CEventDescriptorKey::keychar: handleEventChar(rEDK); break;
+ case NLGUI::CEventDescriptorKey::keystring: handleEventString(rEDK); break;
+ default: break;
+ }
+ // update the text
+ setInputString(_InputString);
+
+ // if event of type char or string, consider handle all of them
+ if( rEDK.getKeyEventType()==NLGUI::CEventDescriptorKey::keychar || rEDK.getKeyEventType()==NLGUI::CEventDescriptorKey::keystring )
+ return true;
+ // Else filter the EventKeyDown AND EventKeyUp.
+ else
+ {
+ // Look into the input handler Manager if the key combo has to be considered as handled
+ if( ( CGroupEditBox::comboKeyHandler != NULL ) && comboKeyHandler->isComboKeyChat(rEDK) )
+ return true;
+ else
+ return false;
+ }
+ }
+ else
+ if (event.getType() == NLGUI::CEventDescriptor::mouse)
+ {
+ /////////////////
+ // MOUSE EVENT //
+ /////////////////
+ const NLGUI::CEventDescriptorMouse &eventDesc = (const NLGUI::CEventDescriptorMouse &)event;
+
+ if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouserightup)
+ {
+ if (CWidgetManager::getInstance()->getCapturePointerRight() == this)
+ {
+ CWidgetManager::getInstance()->setCapturePointerRight(NULL);
+ if (!_ListMenuRight.empty())
+ {
+ if (CCtrlDraggable::getDraggedSheet() == NULL)
+ {
+ _MenuFather = this;
+ CWidgetManager::getInstance()->enableModalWindow (this, _ListMenuRight);
+ stopParentBlink();
+ }
+ }
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ if (!isIn(eventDesc.getX(), eventDesc.getY()))
+ return false;
+
+ // if click, and not frozen, then get the focus
+ if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftdown && !_Frozen)
+ {
+ _SelectingText = true;
+ stopParentBlink();
+ CWidgetManager::getInstance()->setCaptureKeyboard (this);
+ // set the right cursor position
+ uint newCurPos;
+ bool cursorAtPreviousLineEnd;
+ _ViewText->getCharacterIndexFromPosition(eventDesc.getX() - _ViewText->getXReal(), eventDesc.getY() - _ViewText->getYReal(), newCurPos, cursorAtPreviousLineEnd);
+ _CursorAtPreviousLineEnd = cursorAtPreviousLineEnd;
+ _CursorPos = newCurPos;
+ _CursorPos -= (sint32)_Prompt.length();
+ _CursorPos = std::max(_CursorPos, sint32(0));
+ _SelectCursorPos = _CursorPos;
+ _CurrSelection = NULL;
+
+ return true;
+ }
+ // if click, and not frozen, then get the focus
+ if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mousemove && !_Frozen && _SelectingText)
+ {
+ // set the right cursor position
+ uint newCurPos;
+ bool cursorAtPreviousLineEnd;
+ _CurrSelection = this;
+ _ViewText->getCharacterIndexFromPosition(eventDesc.getX() - _ViewText->getXReal(), eventDesc.getY() - _ViewText->getYReal(), newCurPos, cursorAtPreviousLineEnd);
+ _SelectCursorPos = newCurPos;
+ _SelectCursorPos -= (sint32)_Prompt.length();
+ _SelectCursorPos = std::max(_SelectCursorPos, sint32(0));
+ return true;
+ }
+
+ // if click, and not frozen, then get the focus
+ if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftup && !_Frozen)
+ {
+ _SelectingText = false;
+ if (_SelectCursorPos == _CursorPos)
+ _CurrSelection = NULL;
+
+ return true;
+ }
+
+ if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouserightdown)
+ {
+ CWidgetManager::getInstance()->setCapturePointerRight(this);
+ return true;
+ }
+ }
+ else
+ {
+ //////////////////
+ // SYSTEM EVENT //
+ //////////////////
+ const NLGUI::CEventDescriptorSystem &eventDesc = (const NLGUI::CEventDescriptorSystem &)event;
+ if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorSystem::activecalledonparent)
+ {
+ NLGUI::CEventDescriptorActiveCalledOnParent &activeEvent = (NLGUI::CEventDescriptorActiveCalledOnParent &) eventDesc;
+ if (activeEvent.getActive() == false && _ResetFocusOnHide)
+ {
+ CWidgetManager::getInstance()->resetCaptureKeyboard();
+ // If a selection was shown, reset it
+ if (_CurrSelection == this) _CurrSelection = NULL;
+ }
+ CInterfaceGroup::handleEvent(activeEvent);
+ }
+
+ }
+ return false;
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupEditBox::setupDisplayText()
+ {
+ if (_ViewText)
+ {
+ ucstring usTmp;
+ if (_EntryType == Password)
+ {
+ usTmp = _Prompt;
+ for (uint32 i = 0; i < _InputString.size(); ++i)
+ usTmp += "*";
+ }
+ else
+ {
+ usTmp = _Prompt + _InputString;
+ }
+ _ViewText->setText (usTmp);
+ }
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupEditBox::checkCoords()
+ {
+ setupDisplayText();
+
+ CInterfaceGroup::checkCoords();
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupEditBox::updateCoords()
+ {
+ if (!_Setupped)
+ {
+ setup();
+ _Setupped = true;
+ }
+ CInterfaceGroup::updateCoords();
+
+ if (_ViewText)
+ {
+ bool bRecalc = false;
+
+ // if the length of the view text exceed the max w we allow, cut it
+ while (_ViewText->getWReal() > _MaxCharsSize)
+ {
+ // Suppr last char
+ _InputString = _InputString.substr(0, _InputString.size()-1);
+
+ setupDisplayText();
+
+ _ViewText->updateCoords();
+ bRecalc = true;
+ }
+
+ // if the length of the view text exceed our real size, ensure the Cursor position is at least visible
+ sint32 viewTextNewX = _ViewText->getX();
+ if (_ViewText->getWReal() > _WReal)
+ {
+ // Check if cursor visible
+ sint xCursVT, xCurs, yTmp, hTmp;
+ // Get the cursor pos from the BL of the viewtext
+ _ViewText->getCharacterPositionFromIndex(_CursorPos+(sint)_Prompt.size(), false, xCursVT, yTmp, hTmp);
+ // Get the cursor pos from the BL of the edit box
+ xCurs = xCursVT - (_XReal - _ViewText->getXReal());
+ // If the cursor is outside the edit box move the view text to show the cursor
+ if (xCurs > _WReal)
+ {
+ viewTextNewX = _ViewTextDeltaX - (xCursVT - _WReal);
+ }
+ if (xCurs < 0)
+ {
+ if ((xCursVT + xCurs) < 0)
+ viewTextNewX = _ViewTextDeltaX;
+ else
+ viewTextNewX = _ViewTextDeltaX - (xCursVT + xCurs);
+ }
+ if (_CursorPos == 0)
+ {
+ viewTextNewX = _ViewTextDeltaX;
+ }
+ }
+ else
+ {
+ viewTextNewX = _ViewTextDeltaX;
+ }
+
+ // if X position changed, must recompute
+ if (viewTextNewX != _ViewText->getX())
+ {
+ _ViewText->setX(viewTextNewX);
+ bRecalc = true;
+ }
+
+ // recompute position
+ if (bRecalc)
+ CInterfaceGroup::updateCoords();
+ }
+
+ if (_BackupFatherContainerPos)
+ {
+ CGroupContainerBase *gc = static_cast< CGroupContainerBase* >( getEnclosingContainer() );
+
+ if (gc && !gc->getTouchFlag(true))
+ {
+
+ if (_ViewText && _ViewText->getNumLine() <= 1)
+ {
+ if (_PrevNumLine > 1)
+ {
+ gc->restorePosition();
+ CInterfaceGroup::updateCoords();
+ }
+ }
+ else
+ {
+ if (_PrevNumLine <= 1)
+ {
+ gc->backupPosition();
+ }
+ }
+ _PrevNumLine = _ViewText->getNumLine();
+ }
+ else
+ {
+ gc->backupPosition();
+ }
+ }
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupEditBox::clearViews()
+ {
+ CInterfaceGroup::clearViews();
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupEditBox::setup()
+ {
+ // bind to the controls
+ _ViewText = dynamic_cast(CInterfaceGroup::getView("edit_text"));
+
+ if(_ViewText == NULL)
+ nlwarning("Interface: CGroupEditBox: text 'edit_text' missing or bad type");
+
+ // For MultiLine editbox, clip the end space, else weird when edit space at end of line (nothing happens)
+ if(_ViewText)
+ _ViewText->setMultiLineClipEndSpace(true);
+
+ // Bakcup the delta X of this view text
+ if(_ViewText)
+ _ViewTextDeltaX= _ViewText->getX();
+ else
+ _ViewTextDeltaX= 0;
+
+ // read options
+ CInterfaceOptions *pIO = CWidgetManager::getInstance()->getOptions("text_selection");
+ if (pIO != NULL)
+ {
+ _BackSelectColor= pIO->getValColor("back_select_color");
+ _TextSelectColor= pIO->getValColor("text_select_color");
+ }
+ }
+
+
+ // ----------------------------------------------------------------------------
+ void CGroupEditBox::setInputString(const ucstring &str)
+ {
+ _InputString = str;
+ if (_CursorPos > (sint32) str.length())
+ {
+ _CursorPos = (sint32)str.length();
+ _CursorAtPreviousLineEnd = false;
+ }
+ if (!_ViewText) return;
+ setupDisplayText();
+
+ invalidateCoords();
+ }
+
+
+ // ***************************************************************************
+ void CGroupEditBox::setDefaultInputString(const ucstring &str)
+ {
+ _DefaultInputString= true;
+ setInputString(str);
+ }
+
+
+ // ***************************************************************************
+ sint32 CGroupEditBox::getInputStringAsInt() const
+ {
+ sint32 value;
+ fromString(_InputString.toString(), value);
+ return value;
+ }
+
+ // ***************************************************************************
+ void CGroupEditBox::setInputStringAsInt(sint32 val)
+ {
+ setInputString(NLMISC::toString(val));
+ }
+
+ // ***************************************************************************
+ sint64 CGroupEditBox::getInputStringAsInt64() const
+ {
+ sint64 value;
+ fromString(_InputString.toString(), value);
+ return value;
+ }
+
+ // ***************************************************************************
+ void CGroupEditBox::setInputStringAsInt64(sint64 val)
+ {
+ setInputString(NLMISC::toString(val));
+ }
+
+ // ***************************************************************************
+ float CGroupEditBox::getInputStringAsFloat() const
+ {
+ float value;
+ fromString(_InputString.toString(), value);
+ return value;
+ }
+
+ // ***************************************************************************
+ void CGroupEditBox::setInputStringAsFloat(float val)
+ {
+ string fmt= "%." + NLMISC::toString(_MaxFloatPrec) + "f";
+ setInputString(NLMISC::toString(fmt.c_str(), val));
+ }
+
+ // ***************************************************************************
+ void CGroupEditBox::cutSelection()
+ {
+ sint32 minPos= min(_CursorPos, _SelectCursorPos);
+ sint32 maxPos= max(_CursorPos, _SelectCursorPos);
+ // cut the selection
+ if(!_InputString.empty())
+ {
+ _InputString= _InputString.substr(0, minPos) + _InputString.substr(maxPos);
+ }
+ _CurrSelection = NULL;
+ _CursorPos= minPos;
+ triggerOnChangeAH();
+ }
+
+ // ***************************************************************************
+ ucstring CGroupEditBox::getSelection()
+ {
+ sint32 minPos= min(_CursorPos, _SelectCursorPos);
+ sint32 maxPos= max(_CursorPos, _SelectCursorPos);
+ // get the selection
+ return _InputString.substr(minPos, maxPos-minPos);
+ }
+
+
+
+ // ***************************************************************************
+ void CGroupEditBox::setSelectionAll()
+ {
+ if(!_InputString.empty())
+ {
+ _CurrSelection = this;
+ _SelectCursorPos= 0;
+ _CursorPos= (sint32)_InputString.size();
+ _CursorAtPreviousLineEnd = false;
+ }
+ }
+
+ // ***************************************************************************
+ void CGroupEditBox::setActive(bool active)
+ {
+ if (!active && _ResetFocusOnHide)
+ CWidgetManager::getInstance()->resetCaptureKeyboard();
+
+ CInterfaceGroup::setActive(active);
+ }
+
+ // ***************************************************************************
+ void CGroupEditBox::setInputStringAsStdString(const std::string &str)
+ {
+ setInputString(ucstring(str));
+ }
+
+ // ***************************************************************************
+ std::string CGroupEditBox::getInputStringAsStdString() const
+ {
+ std::string result;
+ _InputString.toString(result);
+ return result;
+ }
+
+ // ***************************************************************************
+ void CGroupEditBox::setInputStringAsUtf8(const std::string &str)
+ {
+ ucstring tmp;
+ tmp.fromUtf8(str);
+ setInputString(tmp);
+ }
+
+ // ***************************************************************************
+ std::string CGroupEditBox::getInputStringAsUtf8() const
+ {
+ return _InputString.toUtf8();
+ }
+
+ // ***************************************************************************
+ void CGroupEditBox::setCommand(const ucstring &command, bool execute)
+ {
+ // do nothing if frozen
+ if(_Frozen)
+ return;
+
+ // set the string and maybe execute
+ setInputString((ucchar) '/' + command);
+ if (execute)
+ {
+ // stop selection
+ _CurrSelection = NULL;
+ _CursorAtPreviousLineEnd = false;
+ CAHManager::getInstance()->runActionHandler(_AHOnEnter, this, _AHOnEnterParams);
+ }
+ else
+ {
+ CWidgetManager::getInstance()->setCaptureKeyboard (this);
+ _CursorPos = (sint32)_InputString.length();
+ }
+ }
+
+ // ***************************************************************************
+ void CGroupEditBox::makeTopWindow()
+ {
+ CInterfaceGroup *root = getRootWindow();
+ if(root)
+ CWidgetManager::getInstance()->setTopWindow(root);
+ }
+
+ // ***************************************************************************
+ void CGroupEditBox::clearAllEditBox()
+ {
+ _InputString = "";
+ _CursorPos = 0;
+ _CursorAtPreviousLineEnd = false;
+ if (!_ViewText) return;
+ setupDisplayText();
+ invalidateCoords();
+ }
+
+ // ***************************************************************************
+ sint32 CGroupEditBox::getMaxUsedW() const
+ {
+ return _W;
+ }
+
+ // ***************************************************************************
+ sint32 CGroupEditBox::getMinUsedW() const
+ {
+ return _W;
+ }
+
+ // ***************************************************************************
+ bool CGroupEditBox::wantSerialConfig() const
+ {
+ return _Savable && !_InputString.empty();
+ }
+
+ // ***************************************************************************
+ void CGroupEditBox::serialConfig(NLMISC::IStream &f)
+ {
+ f.serialVersion(0);
+ if(_DefaultInputString) // Don't want to save the default input
+ {
+ _DefaultInputString= false;
+ _InputString.clear();
+ }
+ f.serial(_InputString);
+ f.serial(_CursorPos);
+ f.serial(_PrevNumLine);
+ if (f.isReading())
+ {
+ setInputString(_InputString);
+
+ }
+ // serial selection
+ bool isSelected = (_CurrSelection == this);
+ f.serial(isSelected);
+ if (isSelected)
+ {
+ _CurrSelection = this;
+ f.serial(_SelectCursorPos);
+ }
+ }
+
+ // ***************************************************************************
+ void CGroupEditBox::onQuit()
+ {
+ // clear the text and restore backup pos before final save
+ setInputString(ucstring(""));
+ _CurrSelection = NULL;
+ }
+
+ // ***************************************************************************
+ void CGroupEditBox::onLoadConfig()
+ {
+ // config is not saved when there's an empty string, so restore that default state.
+ setInputString(ucstring(""));
+ _CurrSelection = NULL;
+ _PrevNumLine = 1;
+ }
+
+
+ // ***************************************************************************
+ void CGroupEditBox::elementCaptured(CCtrlBase *capturedElement)
+ {
+ // If the input string is the default one, then reset it
+ if(capturedElement == this)
+ {
+ if (_DefaultInputString)
+ {
+ _DefaultInputString= false;
+ setInputString(ucstring());
+ }
+ _CanRedo = false;
+ _CanUndo = false;
+ _StartInputString = _ModifiedInputString = _InputString;
+ }
+ CInterfaceGroup::elementCaptured(capturedElement);
+ }
+
+ // ***************************************************************************
+ void CGroupEditBox::onKeyboardCaptureLost()
+ {
+ if (!_AHOnFocusLost.empty())
+ CAHManager::getInstance()->runActionHandler(_AHOnFocusLost, this, _AHOnFocusLostParams);
+
+ }
+
+ // ***************************************************************************
+ int CGroupEditBox::luaSetSelectionAll(CLuaState &ls)
+ {
+ const char *funcName = "setSelectionAll";
+ CLuaIHM::checkArgCount(ls, funcName, 0);
+ setSelectionAll();
+ return 0;
+ }
+
+ // ***************************************************************************
+ void CGroupEditBox::setFocusOnText()
+ {
+ // do nothing if frozen
+ if(_Frozen)
+ return;
+
+ // else set the focus
+ CWidgetManager::getInstance()->setCaptureKeyboard (this);
+
+ _CurrSelection = this;
+ _SelectCursorPos= (sint32)_InputString.size();
+ _CursorPos= (sint32)_InputString.size();
+ _CursorAtPreviousLineEnd = false;
+ }
+
+ // ***************************************************************************
+ int CGroupEditBox::luaSetFocusOnText(CLuaState &ls)
+ {
+ const char *funcName = "setFocusOnText";
+ CLuaIHM::checkArgCount(ls, funcName, 0);
+
+ setFocusOnText();
+
+ return 0;
+ }
+
+ // ***************************************************************************
+ int CGroupEditBox::luaCancelFocusOnText(CLuaState &ls)
+ {
+ const char *funcName = "cancelFocusOnText";
+ CLuaIHM::checkArgCount(ls, funcName, 0);
+
+ if (CWidgetManager::getInstance()->getCaptureKeyboard()==this || CWidgetManager::getInstance()->getOldCaptureKeyboard()==this)
+ CWidgetManager::getInstance()->resetCaptureKeyboard();
+
+ _CurrSelection = NULL;
+ _SelectCursorPos= 0;
+ _CursorPos= 0;
+ _CursorAtPreviousLineEnd = false;
+
+ return 0;
+ }
+
+ // ***************************************************************************
+ int CGroupEditBox::luaSetupDisplayText(CLuaState &ls)
+ {
+ const char *funcName = "setupDisplayText";
+ CLuaIHM::checkArgCount(ls, funcName, 0);
+ setupDisplayText();
+ return 0;
+ }
+
+ // ***************************************************************************
+ void CGroupEditBox::setColor(NLMISC::CRGBA col)
+ {
+ if (_ViewText)
+ _ViewText->setColor(col);
+ }
+
+ // ***************************************************************************
+ void CGroupEditBox::setFrozen (bool state)
+ {
+ _Frozen= state;
+
+ // if frozen, loose the focus
+ if(_Frozen)
+ {
+ // stop capture and selection
+ CWidgetManager::getInstance()->setCaptureKeyboard (NULL);
+ if(_CurrSelection==this) _CurrSelection = NULL;
+ // do not allow to recover focus
+ if (CWidgetManager::getInstance()->getOldCaptureKeyboard() == this)
+ {
+ CWidgetManager::getInstance()->resetCaptureKeyboard();
+ }
+ }
+ }
+}
+
diff --git a/code/ryzom/client/src/client_chat_manager.cpp b/code/ryzom/client/src/client_chat_manager.cpp
index 85038deea..bbb52e524 100644
--- a/code/ryzom/client/src/client_chat_manager.cpp
+++ b/code/ryzom/client/src/client_chat_manager.cpp
@@ -30,7 +30,7 @@
#include "entity_cl.h"
#include "nel/gui/action_handler.h"
#include "entities.h"
-#include "interface_v3/group_editbox.h"
+#include "nel/gui/group_editbox.h"
#include "permanent_ban.h"
#include "global.h"
#include "nel/gui/ctrl_text_button.h"
diff --git a/code/ryzom/client/src/commands.cpp b/code/ryzom/client/src/commands.cpp
index e3e43b55e..a5b732c60 100644
--- a/code/ryzom/client/src/commands.cpp
+++ b/code/ryzom/client/src/commands.cpp
@@ -63,7 +63,7 @@
#include "init_main_loop.h"
#include "sheet_manager.h"
#include "sound_manager.h"
-#include "interface_v3/group_editbox.h"
+#include "nel/gui/group_editbox.h"
#include "debug_client.h"
#include "user_entity.h"
#include "time_client.h"
diff --git a/code/ryzom/client/src/connection.cpp b/code/ryzom/client/src/connection.cpp
index f5e393aac..9ef633596 100644
--- a/code/ryzom/client/src/connection.cpp
+++ b/code/ryzom/client/src/connection.cpp
@@ -66,7 +66,7 @@
#include "interface_v3/character_3d.h"
#include "nel/gui/ctrl_button.h"
#include "interface_v3/input_handler_manager.h"
-#include "interface_v3/group_editbox.h"
+#include "nel/gui/group_editbox.h"
#include "nel/gui/interface_expr.h"
#include "init_main_loop.h"
#include "continent_manager.h"
diff --git a/code/ryzom/client/src/init_main_loop.cpp b/code/ryzom/client/src/init_main_loop.cpp
index a9e72c2eb..c64c0a9ea 100644
--- a/code/ryzom/client/src/init_main_loop.cpp
+++ b/code/ryzom/client/src/init_main_loop.cpp
@@ -71,7 +71,7 @@
#include "continent_manager.h"
#include "continent.h"
#include "sky_render.h"
-#include "interface_v3/group_editbox.h"
+#include "nel/gui/group_editbox.h"
#include "interface_v3/inventory_manager.h"
#include "interface_v3/bot_chat_page_all.h"
#include "main_loop.h"
diff --git a/code/ryzom/client/src/interface_v3/action_handler_base.cpp b/code/ryzom/client/src/interface_v3/action_handler_base.cpp
index cfb6c6549..e9f413322 100644
--- a/code/ryzom/client/src/interface_v3/action_handler_base.cpp
+++ b/code/ryzom/client/src/interface_v3/action_handler_base.cpp
@@ -21,7 +21,7 @@
#include "interface_manager.h"
#include "group_container.h"
-#include "group_editbox.h"
+#include "nel/gui/group_editbox.h"
#include "dbctrl_sheet.h"
#include "interface_3d_scene.h"
#include "character_3d.h"
diff --git a/code/ryzom/client/src/interface_v3/action_handler_edit.cpp b/code/ryzom/client/src/interface_v3/action_handler_edit.cpp
index 72931f511..f65784aa8 100644
--- a/code/ryzom/client/src/interface_v3/action_handler_edit.cpp
+++ b/code/ryzom/client/src/interface_v3/action_handler_edit.cpp
@@ -23,7 +23,7 @@ using namespace std;
using namespace NLMISC;
#include "nel/gui/action_handler.h"
-#include "group_editbox.h"
+#include "nel/gui/group_editbox.h"
#include "interface_manager.h"
#include "../client_chat_manager.h"
#include "people_interraction.h"
diff --git a/code/ryzom/client/src/interface_v3/action_handler_game.cpp b/code/ryzom/client/src/interface_v3/action_handler_game.cpp
index d764ea90e..a38912556 100644
--- a/code/ryzom/client/src/interface_v3/action_handler_game.cpp
+++ b/code/ryzom/client/src/interface_v3/action_handler_game.cpp
@@ -39,7 +39,7 @@
#include "nel/gui/interface_expr.h"
#include "group_menu.h"
#include "group_container.h"
-#include "group_editbox.h"
+#include "nel/gui/group_editbox.h"
#include "inventory_manager.h"
#include "guild_manager.h"
#include "../net_manager.h"
diff --git a/code/ryzom/client/src/interface_v3/action_handler_help.cpp b/code/ryzom/client/src/interface_v3/action_handler_help.cpp
index 4e12abb10..a610b26fe 100644
--- a/code/ryzom/client/src/interface_v3/action_handler_help.cpp
+++ b/code/ryzom/client/src/interface_v3/action_handler_help.cpp
@@ -27,7 +27,7 @@
#include "dbctrl_sheet.h"
#include "nel/gui/interface_expr.h"
#include "group_container.h"
-#include "group_editbox.h"
+#include "nel/gui/group_editbox.h"
#include "group_quick_help.h"
#include "nel/gui/view_text_id.h"
#include "../user_entity.h"
diff --git a/code/ryzom/client/src/interface_v3/action_handler_item.cpp b/code/ryzom/client/src/interface_v3/action_handler_item.cpp
index 57fb10631..cfe18adb4 100644
--- a/code/ryzom/client/src/interface_v3/action_handler_item.cpp
+++ b/code/ryzom/client/src/interface_v3/action_handler_item.cpp
@@ -24,7 +24,7 @@
#include "../sheet_manager.h"
#include "dbctrl_sheet.h"
#include "dbgroup_list_sheet.h"
-#include "group_editbox.h"
+#include "nel/gui/group_editbox.h"
#include "nel/gui/interface_expr.h"
#include "player_trade.h"
#include "../user_entity.h"
diff --git a/code/ryzom/client/src/interface_v3/action_handler_misc.cpp b/code/ryzom/client/src/interface_v3/action_handler_misc.cpp
index dfbbeafc3..c36bbdfa7 100644
--- a/code/ryzom/client/src/interface_v3/action_handler_misc.cpp
+++ b/code/ryzom/client/src/interface_v3/action_handler_misc.cpp
@@ -19,7 +19,7 @@
#include "interface_manager.h"
#include "nel/gui/ctrl_button.h"
#include "group_container.h"
-#include "group_editbox.h"
+#include "nel/gui/group_editbox.h"
#include "people_interraction.h"
#include "nel/misc/algo.h"
#include "nel/gui/interface_expr.h"
diff --git a/code/ryzom/client/src/interface_v3/action_handler_ui.cpp b/code/ryzom/client/src/interface_v3/action_handler_ui.cpp
index fd5d58329..b3ea4d6ff 100644
--- a/code/ryzom/client/src/interface_v3/action_handler_ui.cpp
+++ b/code/ryzom/client/src/interface_v3/action_handler_ui.cpp
@@ -27,7 +27,7 @@
#include "macrocmd_manager.h"
#include "chat_window.h"
#include "people_interraction.h"
-#include "group_editbox.h"
+#include "nel/gui/group_editbox.h"
#include "group_html.h"
#include "inventory_manager.h"
diff --git a/code/ryzom/client/src/interface_v3/action_phrase_faber.cpp b/code/ryzom/client/src/interface_v3/action_phrase_faber.cpp
index 92d4f4897..48e611348 100644
--- a/code/ryzom/client/src/interface_v3/action_phrase_faber.cpp
+++ b/code/ryzom/client/src/interface_v3/action_phrase_faber.cpp
@@ -30,7 +30,7 @@
#include "../net_manager.h"
#include "sbrick_manager.h"
#include "sphrase_manager.h"
-#include "group_editbox.h"
+#include "nel/gui/group_editbox.h"
#include "dbview_bar.h"
#include "skill_manager.h"
#include "game_share/bot_chat_types.h"
diff --git a/code/ryzom/client/src/interface_v3/bot_chat_page_create_guild.cpp b/code/ryzom/client/src/interface_v3/bot_chat_page_create_guild.cpp
index ec3ff4d64..9dc8f1a13 100644
--- a/code/ryzom/client/src/interface_v3/bot_chat_page_create_guild.cpp
+++ b/code/ryzom/client/src/interface_v3/bot_chat_page_create_guild.cpp
@@ -22,7 +22,7 @@
#include "guild_manager.h"
#include "nel/gui/interface_group.h"
#include "nel/gui/action_handler.h"
-#include "group_editbox.h"
+#include "nel/gui/group_editbox.h"
#include "dbctrl_sheet.h"
#include "bot_chat_manager.h"
#include "bot_chat_page_all.h"
diff --git a/code/ryzom/client/src/interface_v3/bot_chat_page_trade.cpp b/code/ryzom/client/src/interface_v3/bot_chat_page_trade.cpp
index aeb455224..e98019b25 100644
--- a/code/ryzom/client/src/interface_v3/bot_chat_page_trade.cpp
+++ b/code/ryzom/client/src/interface_v3/bot_chat_page_trade.cpp
@@ -34,7 +34,7 @@
#include "bot_chat_page_all.h"
#include "bot_chat_manager.h"
#include "dbctrl_sheet.h"
-#include "group_editbox.h"
+#include "nel/gui/group_editbox.h"
#include "group_tab.h"
#include "group_container.h"
#include "action_handler_help.h"
diff --git a/code/ryzom/client/src/interface_v3/chat_window.cpp b/code/ryzom/client/src/interface_v3/chat_window.cpp
index d1f376b17..9592697a3 100644
--- a/code/ryzom/client/src/interface_v3/chat_window.cpp
+++ b/code/ryzom/client/src/interface_v3/chat_window.cpp
@@ -31,7 +31,7 @@
#include "../connection.h"
//
#include "group_container.h"
-#include "group_editbox.h"
+#include "nel/gui/group_editbox.h"
#include "group_tab.h"
#include "interface_manager.h"
#include "nel/gui/action_handler.h"
diff --git a/code/ryzom/client/src/interface_v3/chat_window.h b/code/ryzom/client/src/interface_v3/chat_window.h
index da6179fd8..d63871ba2 100644
--- a/code/ryzom/client/src/interface_v3/chat_window.h
+++ b/code/ryzom/client/src/interface_v3/chat_window.h
@@ -30,11 +30,11 @@ namespace NLGUI
class CCtrlBase;
class CViewText;
class CGroupList;
+ class CGroupEditBox;
}
class CChatWindow;
class CGroupContainer;
-class CGroupEditBox;
/** Interface to react to a chat box entry
* Derivers should define the msgEntered member function to handle entry event.
@@ -122,7 +122,7 @@ public:
*/
CGroupContainer *getContainer() const { return _Chat; }
//
- CGroupEditBox *getEditBox() const;
+ NLGUI::CGroupEditBox *getEditBox() const;
/** try to rename the chat window
* \return true if success
*/
@@ -163,7 +163,7 @@ protected:
protected:
IChatWindowListener *_Listener;
NLMISC::CRefPtr _Chat;
- CGroupEditBox *_EB;
+ NLGUI::CGroupEditBox *_EB;
bool _ParentBlink;
static CChatWindow *_ChatWindowLaunchingCommand;
std::vector _Observers;
diff --git a/code/ryzom/client/src/interface_v3/dbgroup_build_phrase.cpp b/code/ryzom/client/src/interface_v3/dbgroup_build_phrase.cpp
index b885a9979..4c3c0ae9d 100644
--- a/code/ryzom/client/src/interface_v3/dbgroup_build_phrase.cpp
+++ b/code/ryzom/client/src/interface_v3/dbgroup_build_phrase.cpp
@@ -24,7 +24,7 @@
#include "dbctrl_sheet.h"
#include "nel/gui/view_bitmap.h"
#include "nel/gui/ctrl_button.h"
-#include "group_editbox.h"
+#include "nel/gui/group_editbox.h"
#include "../client_cfg.h"
#include "nel/gui/view_text.h"
#include "skill_manager.h"
diff --git a/code/ryzom/client/src/interface_v3/dbgroup_build_phrase.h b/code/ryzom/client/src/interface_v3/dbgroup_build_phrase.h
index f37ea9134..c41f0dd83 100644
--- a/code/ryzom/client/src/interface_v3/dbgroup_build_phrase.h
+++ b/code/ryzom/client/src/interface_v3/dbgroup_build_phrase.h
@@ -31,14 +31,13 @@ namespace NLGUI
class CCtrlBaseButton;
class CViewText;
class CViewBitmap;
+ class CGroupEditBox;
}
// ***************************************************************************
class CDBCtrlSheet;
class CSBrickSheet;
-class CGroupEditBox;
-
// ***************************************************************************
/**
diff --git a/code/ryzom/client/src/interface_v3/group_container.cpp b/code/ryzom/client/src/interface_v3/group_container.cpp
index 0b103d511..ecf2ba5b9 100644
--- a/code/ryzom/client/src/interface_v3/group_container.cpp
+++ b/code/ryzom/client/src/interface_v3/group_container.cpp
@@ -26,7 +26,7 @@
#include "nel/misc/xml_auto_ptr.h"
#include "nel/gui/action_handler.h"
#include "../time_client.h"
-#include "group_editbox.h"
+#include "nel/gui/group_editbox.h"
#include "nel/gui/view_text_formated.h"
#include "nel/gui/view_text_id.h"
#include "nel/gui/lua_ihm.h"
diff --git a/code/ryzom/client/src/interface_v3/group_editbox.cpp b/code/ryzom/client/src/interface_v3/group_editbox.cpp
deleted file mode 100644
index 1fd5c37cf..000000000
--- a/code/ryzom/client/src/interface_v3/group_editbox.cpp
+++ /dev/null
@@ -1,1481 +0,0 @@
-// Ryzom - MMORPG Framework
-// Copyright (C) 2010 Winch Gate Property Limited
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as
-// published by the Free Software Foundation, either version 3 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see .
-
-#include "group_editbox.h"
-#include "nel/misc/command.h"
-#include "nel/gui/view_text.h"
-#include "nel/misc/xml_auto_ptr.h"
-#include "nel/gui/interface_options.h"
-#include "nel/gui/ctrl_draggable.h"
-#include "nel/gui/group_container_base.h"
-#include "nel/gui/lua_ihm.h"
-#include "nel/gui/widget_manager.h"
-#include "nel/gui/view_renderer.h"
-#include "nel/gui/db_manager.h"
-
-using namespace std;
-using namespace NLMISC;
-using namespace NL3D;
-
-
-/////////////
-// STATICS //
-/////////////
-
-sint32 CGroupEditBox::_SelectCursorPos = 0;
-CGroupEditBox *CGroupEditBox::_MenuFather = NULL;
-CGroupEditBox::IComboKeyHandler* CGroupEditBox::comboKeyHandler = NULL;
-
-
-// ----------------------------------------------------------------------------
-NLMISC_REGISTER_OBJECT(CViewBase, CGroupEditBox, std::string, "edit_box");
-
-CGroupEditBox::CGroupEditBox(const TCtorParam ¶m) :
- CGroupEditBoxBase(param),
- _BlinkTime(0.f),
- _CursorPos(0),
- _MaxNumChar(std::numeric_limits::max()),
- _MaxNumReturn(std::numeric_limits::max()),
- _MaxFloatPrec(20),
- _MaxCharsSize(32768),
- _FirstVisibleChar(0),
- _LastVisibleChar(0),
- _SelectingText(false),
- _ViewText(NULL),
- _MaxHistoric(0),
- _CurrentHistoricIndex(-1),
- _PrevNumLine(1),
- _EntryType(Text),
- _Setupped(false),
- _BypassNextKey(false),
- _BlinkState(false),
- _CursorAtPreviousLineEnd(false),
- _LooseFocusOnEnter(true),
- _ResetFocusOnHide(false),
- _BackupFatherContainerPos(false),
- _WantReturn(false),
- _Savable(true),
- _DefaultInputString(false),
- _Frozen(false),
- _CanRedo(false),
- _CanUndo(false),
- _CursorTexID(-1),
- _CursorWidth(0),
- _IntegerMinValue(INT_MIN),
- _IntegerMaxValue(INT_MAX),
- _PositiveIntegerMinValue(0),
- _PositiveIntegerMaxValue(UINT_MAX),
- _ViewTextDeltaX(0)
-
-{
- _Prompt = ">";
- _BackSelectColor= CRGBA::White;
- _TextSelectColor= CRGBA::Black;
-}
-
-// ----------------------------------------------------------------------------
-CGroupEditBox::~CGroupEditBox()
-{
- if (this == _CurrSelection) _CurrSelection = NULL;
- if (CWidgetManager::getInstance()->getCaptureKeyboard() == this || CWidgetManager::getInstance()->getOldCaptureKeyboard() == this)
- {
- CWidgetManager::getInstance()->resetCaptureKeyboard();
- }
-}
-
-// ----------------------------------------------------------------------------
-bool CGroupEditBox::parse(xmlNodePtr cur, CInterfaceGroup * parentGroup)
-{
- if(!CInterfaceGroup::parse(cur, parentGroup))
- return false;
- CXMLAutoPtr prop;
-
- if (! CInterfaceGroup::parse(cur,parentGroup) )
- {
- string tmp = "cannot parse view:"+getId()+", parent:"+parentGroup->getId();
- nlinfo(tmp.c_str());
- return false;
- }
-
- // NB: use InterfaceGroup "OnEnter" data. Different script params for an historic reason
- CAHManager::getInstance()->parseAH(cur, "onenter", "params", _AHOnEnter, _AHOnEnterParams);
-
- prop = (char*) xmlGetProp( cur, (xmlChar*)"onchange" );
- if (prop) _AHOnChange = (const char *) prop;
- prop = (char*) xmlGetProp( cur, (xmlChar*)"onchange_params" );
- if (prop) _ParamsOnChange = (const char *) prop;
-
- prop = (char*) xmlGetProp( cur, (xmlChar*)"on_focus_lost" );
- if (prop) _AHOnFocusLost = (const char *) prop;
- prop = (char*) xmlGetProp( cur, (xmlChar*)"on_focus_lost_params" );
- if (prop) _AHOnFocusLostParams = (const char *) prop;
-
- prop = (char*) xmlGetProp( cur, (xmlChar*)"on_focus" );
- if (prop) _AHOnFocus = (const char *) prop;
- prop = (char*) xmlGetProp( cur, (xmlChar*)"on_focus_params" );
- if (prop) _AHOnFocusParams = (const char *) prop;
-
- prop = (char*) xmlGetProp( cur, (xmlChar*)"max_num_chars" );
- if (prop) fromString((const char*)prop, _MaxNumChar);
-
- prop = (char*) xmlGetProp( cur, (xmlChar*)"max_num_return" );
- if (prop) fromString((const char*)prop, _MaxNumReturn);
-
- prop = (char*) xmlGetProp( cur, (xmlChar*)"max_chars_size" );
- if (prop) fromString((const char*)prop, _MaxCharsSize);
-
- prop = (char*) xmlGetProp( cur, (xmlChar*)"enter_loose_focus" );
- if (prop) _LooseFocusOnEnter = convertBool(prop);
-
- prop = (char*) xmlGetProp( cur, (xmlChar*)"enter_recover_focus" );
- if (prop) _RecoverFocusOnEnter = convertBool(prop);
-
- prop = (char*) xmlGetProp( cur, (xmlChar*)"reset_focus_on_hide" );
- if (prop) _ResetFocusOnHide = convertBool(prop);
-
- prop = (char*) xmlGetProp( cur, (xmlChar*)"prompt" );
- if (prop) _Prompt = (const char*)prop;
-
- prop = (char*) xmlGetProp( cur, (xmlChar*)"entry_type" );
- _EntryType = Text;
- if (prop)
- {
- if (stricmp(prop, "text") == 0) _EntryType = Text;
- else if (stricmp(prop, "integer") == 0) _EntryType = Integer;
- else if (stricmp(prop, "positive_integer") == 0) _EntryType = PositiveInteger;
- else if (stricmp(prop, "float") == 0) _EntryType = Float;
- else if (stricmp(prop, "positive_float") == 0) _EntryType = PositiveFloat;
- else if (stricmp(prop, "alpha") == 0) _EntryType = Alpha;
- else if (stricmp(prop, "alpha_num") == 0) _EntryType = AlphaNum;
- else if (stricmp(prop, "alpha_num_space") == 0) _EntryType = AlphaNumSpace;
- else if (stricmp(prop, "password") == 0) _EntryType = Password;
- else if (stricmp(prop, "filename") == 0) _EntryType = Filename;
- else if (stricmp(prop, "playername") == 0) _EntryType = PlayerName;
- else nlwarning(" Unknown entry type %s", (const char *) prop);
- }
-
- prop = (char*) xmlGetProp( cur, (xmlChar*)"menu_r" );
- if (prop)
- {
- string tmp = (const char *) prop;
- _ListMenuRight = strlwr(tmp);
- }
-
- prop = (char*) xmlGetProp( cur, (xmlChar*)"max_historic" );
- if (prop) fromString((const char*)prop, _MaxHistoric);
-
- prop = (char*) xmlGetProp( cur, (xmlChar*)"backup_father_container_pos" );
- if (prop) _BackupFatherContainerPos = convertBool(prop);
-
- prop = (char*) xmlGetProp( cur, (xmlChar*)"want_return" );
- if (prop) _WantReturn = convertBool(prop);
-
- prop = (char*) xmlGetProp( cur, (xmlChar*)"savable" );
- if (prop) _Savable = convertBool(prop);
-
- // For float conversion only
- prop = (char*) xmlGetProp( cur, (xmlChar*)"max_float_prec" );
- if (prop)
- {
- fromString((const char*)prop, _MaxFloatPrec);
- _MaxFloatPrec = min((uint32)20, _MaxFloatPrec);
- }
-
- // negative characters filter
- prop = (char*) xmlGetProp( cur, (xmlChar*)"negative_filter" );
- if (prop)
- {
- uint length = (uint)strlen(prop);
- _NegativeFilter.resize(length);
- std::copy((const char *) prop, (const char *) prop + length, _NegativeFilter.begin());
- }
-
- return true;
-}
-
-// ----------------------------------------------------------------------------
-void CGroupEditBox::draw ()
-{
- //
- CViewRenderer &rVR = *CViewRenderer::getInstance();
- //
- /*CRGBA col;
- col.modulateFromColor(CRGBA(64,64,64,255), pIM->getGlobalColorForContent());
- rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal, _WReal, _HReal, 0, false, rVR.getBlankTextureId(), col );
- */
-
- // Frozen? display text in "grayed"
- CRGBA bkupTextColor;
- if(_Frozen && _ViewText)
- {
- bkupTextColor= _ViewText->getColor();
- CRGBA grayed= bkupTextColor;
- grayed.A>>=2;
- _ViewText->setColor(grayed);
- }
-
- // draw the group and thus the text
- CInterfaceGroup::draw();
-
- // restore the text color if changed
- if(_Frozen && _ViewText)
- _ViewText->setColor(bkupTextColor);
-
- // no text setuped? abort
- if (!_ViewText) return;
-
- // Display the selection if needed
- if (_CurrSelection == this && _SelectCursorPos!=_CursorPos)
- {
- sint32 blankTextId= rVR.getBlankTextureId();
- CRGBA col= _BackSelectColor;
- col.A= CWidgetManager::getInstance()->getGlobalColorForContent().A;
- sint32 minPos= min(_CursorPos, _SelectCursorPos) + (sint32)_Prompt.length();
- sint32 maxPos= max(_CursorPos, _SelectCursorPos) + (sint32)_Prompt.length();
-
- // get its position on screen
- sint cxMinPos, cyMinPos;
- sint cxMaxPos, cyMaxPos;
- sint height;
- _ViewText->getCharacterPositionFromIndex(minPos, false, cxMinPos, cyMinPos, height);
- _ViewText->getCharacterPositionFromIndex(maxPos, false, cxMaxPos, cyMaxPos, height);
-
- // Multiline selection if cy different!
- if(cyMinPos!=cyMaxPos)
- {
- nlassert(cyMaxPosgetXReal() + cxMinPos, _ViewText->getYReal() + cyMinPos, _ViewText->getW()-cxMinPos, height, 0, 0, blankTextId, col);
-
- // Draw One quad for all lines into the big selection (if any)
- sint32 cyBigQuad= cyMaxPos+height;
- if(cyBigQuadgetXReal(), _ViewText->getYReal() + cyBigQuad, _ViewText->getW(), cyMinPos-cyBigQuad, 0, 0, blankTextId, col);
- }
-
- // draw the 3rd quad from the last line from start of line to max pos
- rVR.drawRotFlipBitmap(_RenderLayer, _ViewText->getXReal(), _ViewText->getYReal() + cyMaxPos, cxMaxPos, height, 0, 0, blankTextId, col);
- }
- else
- {
- rVR.drawRotFlipBitmap(_RenderLayer, _ViewText->getXReal() + cxMinPos, _ViewText->getYReal() + cyMinPos, cxMaxPos-cxMinPos, height, 0, 0, blankTextId, col);
- }
-
- // Draw The Selection String in black
- CRGBA bkup= _ViewText->getColor();
- _ViewText->setColor(_TextSelectColor);
- _ViewText->enableStringSelection(minPos, maxPos);
- // redraw just this string,clipped by the group
- CInterfaceGroup::drawElement(_ViewText);
- // bkup
- _ViewText->setColor(bkup);
- _ViewText->disableStringSelection();
- }
-
- // Display the cursor if needed
- if (CWidgetManager::getInstance()->getCaptureKeyboard () == this)
- {
- _BlinkTime += 0.0025f;
- if (_BlinkTime > 0.25f)
- {
- _BlinkTime = fmodf(_BlinkTime, 0.25f);
- _BlinkState = !_BlinkState;
- }
- if (_BlinkState) // is the cursor shown ?
- {
- // get its position on screen
- sint cx, cy;
- sint height;
- _ViewText->getCharacterPositionFromIndex(_CursorPos + (sint)_Prompt.length(), _CursorAtPreviousLineEnd, cx, cy, height);
- // display the cursor
- // get the texture for the cursor
- if (_CursorTexID == -1)
- {
- _CursorTexID = rVR.getTextureIdFromName("text_cursor.tga");
- sint32 dummyCursorHeight;
- rVR.getTextureSizeFromId(_CursorTexID, _CursorWidth, dummyCursorHeight);
- }
- // draw in a layer after to be on TOP of the text
- sint32 cursorx = std::max((sint) 0, (sint)(cx - (_CursorWidth >> 1)));
- rVR.drawRotFlipBitmap(_RenderLayer+1, _ViewText->getXReal() + cursorx, _ViewText->getYReal() + cy, 3, height, 0, 0, _CursorTexID);
- }
- }
-}
-
-// ----------------------------------------------------------------------------
-void CGroupEditBox::copy()
-{
- if (_CurrSelection != this)
- {
- nlwarning("Selection can only be on focus");
- }
- stopParentBlink();
-
- // get the selection and copy it
- if (CViewRenderer::getInstance()->getDriver()->copyTextToClipboard(getSelection()))
- nlinfo ("Chat input was copied in the clipboard");
-}
-
-// ----------------------------------------------------------------------------
-void CGroupEditBox::paste()
-{
- if(_CurrSelection != NULL)
- {
- if (_CurrSelection != this)
- {
- nlwarning("Selection can only be on focus");
- }
- cutSelection();
- }
-
- ucstring sString;
-
- if (CViewRenderer::getInstance()->getDriver()->pasteTextFromClipboard(sString))
- {
- // append string now
- appendStringFromClipboard(sString);
- }
-}
-
-// ----------------------------------------------------------------------------
-void CGroupEditBox::appendStringFromClipboard(const ucstring &str)
-{
- stopParentBlink();
- makeTopWindow();
-
- writeString(str, true, false);
- nlinfo ("Chat input was pasted from the clipboard");
-
- triggerOnChangeAH();
-
- _CursorAtPreviousLineEnd = false;
-}
-
-// ----------------------------------------------------------------------------
-void CGroupEditBox::writeString(const ucstring &str, bool replace, bool atEnd)
-{
- sint length = (sint)str.length();
-
- ucstring toAppend;
- // filter character depending on the entry type
- switch (_EntryType)
- {
- case Text:
- case Password:
- {
- if (_NegativeFilter.empty())
- {
- toAppend = str;
- }
- else
- {
- for (sint k = 0; k < length; ++k)
- {
- if (!isFiltered(str[k]))
- {
- toAppend += str[k];
- }
- }
- }
- // remove '\r' characters
- toAppend.erase(std::remove(toAppend.begin(), toAppend.end(), (ucchar) '\r'), toAppend.end());
-
- }
- break;
- case PositiveInteger:
- case PositiveFloat:
- {
- for (sint k = 0; k < length; ++k)
- {
- if (isdigit(str[k]) || str[k]== ' ' ||
- (_EntryType==PositiveFloat && str[k]=='.') )
- {
- if (!isFiltered(str[k]))
- {
- toAppend += str[k];
- }
- }
- }
- }
- break;
- case Integer:
- case Float:
- {
- for (sint k = 0; k < length; ++k)
- {
- if (isdigit(str[k]) || str[k]== ' ' || str[k]== '-' ||
- (_EntryType==Float && str[k]=='.') )
- {
- if (!isFiltered(str[k]))
- {
- toAppend += str[k];
- }
- }
- }
- }
- break;
- case AlphaNumSpace:
- {
- for (sint k = 0; k < length; ++k)
- {
- if (isValidAlphaNumSpace(str[k]))
- {
- if (!isFiltered(str[k]))
- {
- toAppend += str[k];
- }
- }
- }
- }
- break;
- case AlphaNum:
- {
- for (sint k = 0; k < length; ++k)
- {
- if (isValidAlphaNum(str[k]))
- {
- if (!isFiltered(str[k]))
- {
- toAppend += str[k];
- }
- }
- }
- }
- break;
- case Alpha:
- {
- for (sint k = 0; k < length; ++k)
- {
- if (isValidAlpha(str[k]))
- {
- if (!isFiltered(str[k]))
- {
- toAppend += str[k];
- }
- }
- }
- }
- break;
- case Filename:
- {
- for (sint k = 0; k < length; ++k)
- {
- if (isValidFilenameChar(str[k]))
- {
- if (!isFiltered(str[k]))
- {
- toAppend += str[k];
- }
- }
- }
- }
- break;
- case PlayerName:
- {
- for (sint k = 0; k < length; ++k)
- {
- if (isValidPlayerNameChar(str[k]))
- {
- if (!isFiltered(str[k]))
- {
- toAppend += str[k];
- }
- }
- }
- }
- }
- length = (sint)toAppend.size();
- if ((uint) (_InputString.length() + length) > _MaxNumChar)
- {
- length = _MaxNumChar - (sint)_InputString.length();
- }
- ucstring toAdd = toAppend.substr(0, length);
- sint32 minPos;
- sint32 maxPos;
- if (_CurrSelection == this)
- {
- minPos = min(_CursorPos, _SelectCursorPos);
- maxPos = max(_CursorPos, _SelectCursorPos);
- }
- else
- {
- minPos = _CursorPos;
- maxPos = _CursorPos;
- }
-
- nlinfo("%d, %d", minPos, maxPos);
- if (replace)
- {
- _InputString = _InputString.substr(0, minPos) + toAdd + _InputString.substr(maxPos);
- _CursorPos = minPos+(sint32)toAdd.length();
- }
- else
- {
- if (atEnd)
- {
- _InputString = _InputString.substr(0, maxPos) + toAdd + _InputString.substr(maxPos);
- _CursorPos = maxPos;
- _SelectCursorPos = _CursorPos;
-
- }
- else
- {
- _InputString = _InputString.substr(0, minPos) + toAdd + _InputString.substr(minPos);
- _CursorPos = minPos+(sint32)toAdd.length();
- _SelectCursorPos = maxPos+(sint32)toAdd.length();
- }
- }
-}
-
-// ----------------------------------------------------------------------------
-void CGroupEditBox::handleEventChar(const NLGUI::CEventDescriptorKey &rEDK)
-{
- stopParentBlink();
- switch(rEDK.getChar())
- {
- case KeyESCAPE:
- _CurrentHistoricIndex= -1;
- CWidgetManager::getInstance()->setCaptureKeyboard(NULL);
- // stop selection
- _CurrSelection = NULL;
- _CursorAtPreviousLineEnd = false;
- break;
- case KeyTAB:
- makeTopWindow();
- break;
- // OTHER
- default:
- if ((rEDK.getChar() == KeyRETURN) && !_WantReturn)
- {
- // update historic.
- if(_MaxHistoric)
- {
- if( !_InputString.empty() )
- {
- _Historic.push_front(_InputString);
- if(_Historic.size()>_MaxHistoric)
- _Historic.pop_back();
- }
- _CurrentHistoricIndex= -1;
- }
-
- _CursorPos = 0;
- // loose the keyboard focus
- if (NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:CHAT:ENTER_DONT_QUIT_CB")->getValue32() == 0)
- {
- if(_LooseFocusOnEnter)
- CWidgetManager::getInstance()->setCaptureKeyboard(NULL);
- }
- // stop selection
- _CurrSelection = NULL;
- _CursorAtPreviousLineEnd = false;
- CAHManager::getInstance()->runActionHandler(_AHOnEnter, this, _AHOnEnterParams);
- }
- else
- {
- // If the char is not alphanumeric -> return.
- // if(!isalnum(ec.Char))
- // return
- if( (rEDK.getChar()>=32) || (rEDK.getChar() == KeyRETURN) )
- {
- if (rEDK.getChar() == KeyRETURN)
- {
- ucstring copyStr= _InputString;
- if ((uint) std::count(copyStr.begin(), copyStr.end(), '\n') >= _MaxNumReturn)
- break;
- }
-
- // if selection is activated, then cut the selection
- if(_CurrSelection != NULL)
- {
- if (_CurrSelection != this)
- {
- nlwarning("Selection can only be on focus");
- }
- cutSelection();
- }
-
- ucchar c = (rEDK.getChar() == KeyRETURN)?'\n':rEDK.getChar();
- if (isFiltered(c)) return;
- switch(_EntryType)
- {
- case Integer:
- if (c > 255 || !(c =='-' || c==' ' || isdigit((int) c)))
- return;
- break;
- case PositiveInteger:
- if (c > 255 || !(c == ' ' || isdigit((int) c)))
- return;
- break;
- case Float:
- if (c > 255 || !(c =='-' || c==' ' || c=='.' || isdigit((int) c)))
- return;
- break;
- case PositiveFloat:
- if (c > 255 || !(c == ' ' || c=='.' || isdigit((int) c)))
- return;
- break;
- case AlphaNumSpace:
- if (!isValidAlphaNumSpace(c))
- return;
- break;
- case AlphaNum:
- if (!isValidAlphaNum(c))
- return;
- break;
- case Alpha:
- if (!isValidAlpha(c))
- return;
- break;
- case Filename:
- if (!isValidFilenameChar(c))
- return;
- break;
- case PlayerName:
- if (!isValidPlayerNameChar(c))
- return;
- break;
- default:
- break;
- }
- // verify integer bounds
- if(_EntryType==Integer && (_IntegerMinValue!=INT_MIN || _IntegerMaxValue!=INT_MAX))
- {
- // estimate new string
- ucstring copyStr= _InputString;
- ucstring::iterator it = copyStr.begin() + _CursorPos;
- copyStr.insert(it, c);
- sint32 value;
- fromString(copyStr.toString(), value);
- // if out of bounds, abort char
- if(value<_IntegerMinValue || value>_IntegerMaxValue)
- return;
- }
- // verify integer bounds
- if(_EntryType==PositiveInteger && (_PositiveIntegerMinValue!=0 || _PositiveIntegerMaxValue!=UINT_MAX))
- {
- // estimate new string
- ucstring copyStr= _InputString;
- ucstring::iterator it = copyStr.begin() + _CursorPos;
- copyStr.insert(it, c);
- // \todo yoyo: this doesn't really work i think....
- uint32 value;
- fromString(copyStr.toString(), value);
- // if out of bounds, abort char
- if(value<_PositiveIntegerMinValue || value>_PositiveIntegerMaxValue)
- return;
- }
- // verify max num char
- if ((uint) _InputString.length() < _MaxNumChar)
- {
- makeTopWindow();
- ucstring::iterator it = _InputString.begin() + _CursorPos;
- _InputString.insert(it, c);
- ++ _CursorPos;
- triggerOnChangeAH();
- }
- if (rEDK.getChar() == KeyRETURN)
- {
- CAHManager::getInstance()->runActionHandler(_AHOnEnter, this, _AHOnEnterParams);
- }
- }
- _CursorAtPreviousLineEnd = false;
- }
- break;
- }
-}
-
-// ----------------------------------------------------------------------------
-void CGroupEditBox::handleEventString(const NLGUI::CEventDescriptorKey &rEDK)
-{
- appendStringFromClipboard(rEDK.getString());
-}
-
-// ----------------------------------------------------------------------------
-bool CGroupEditBox::undo()
-{
- if (CWidgetManager::getInstance()->getCaptureKeyboard() != this) return false;
- if (!_CanUndo) return false;
- _ModifiedInputString = _InputString;
- setInputString(_StartInputString);
- _CanUndo = false;
- _CanRedo = true;
- setCursorPos((sint32)_InputString.length());
- setSelectionAll();
- return true;
-}
-
-// ----------------------------------------------------------------------------
-bool CGroupEditBox::redo()
-{
- if (CWidgetManager::getInstance()->getCaptureKeyboard() != this) return false;
- if (!_CanRedo) return false;
- setInputString(_ModifiedInputString);
- _CanUndo = true;
- _CanRedo = false;
- setCursorPos((sint32)_InputString.length());
- setSelectionAll();
- return true;
-}
-
-// ----------------------------------------------------------------------------
-void CGroupEditBox::triggerOnChangeAH()
-{
- _CanUndo = true;
- _CanRedo = false;
-
- if (!_AHOnChange.empty())
- CAHManager::getInstance()->runActionHandler(_AHOnChange, this, _ParamsOnChange);
-
-}
-
-// ----------------------------------------------------------------------------
-bool CGroupEditBox::expand()
-{
- if ((_EntryType == Integer) ||
- (_EntryType == PositiveInteger) ||
- (_EntryType == Float) ||
- (_EntryType == PositiveFloat) ||
- (_EntryType == AlphaNumSpace) ||
- (_EntryType == AlphaNum) ||
- (_EntryType == Alpha) ||
- (_EntryType == Filename) ||
- (_EntryType == PlayerName)
- )
- return false;
-
- if(!_InputString.empty())
- {
- if (_InputString[0] == '/')
- {
- makeTopWindow();
- // for french, deutsch and russian, be aware of unicode
- std::string command = ucstring(_InputString.substr(1)).toUtf8();
- ICommand::expand(command);
- // then back to ucstring
- _InputString.fromUtf8(command);
- _InputString = '/' + _InputString;
- _CursorPos = (sint32)_InputString.length();
- _CursorAtPreviousLineEnd = false;
- triggerOnChangeAH();
- return true;
- }
- }
- return false;
-}
-
-// ----------------------------------------------------------------------------
-void CGroupEditBox::back()
-{
- makeTopWindow();
- // if selection is activated and not same cursors pos, then cut the selection
- if(_CurrSelection != NULL && _CursorPos != _SelectCursorPos)
- {
- if (_CurrSelection != this)
- {
- nlwarning("Selection can only be on focus");
- }
- cutSelection();
- _CursorAtPreviousLineEnd = false;
- }
- // else delete last character
- else if(_InputString.size () > 0 && _CursorPos != 0)
- {
- ucstring::iterator it = _InputString.begin() + (_CursorPos - 1);
- _InputString.erase(it);
- -- _CursorPos;
- _CursorAtPreviousLineEnd = false;
- triggerOnChangeAH();
- }
- // must stop selection in all case
- if (_CurrSelection)
- {
- if (_CurrSelection != this)
- {
- nlwarning("Selection can only be on focus");
- }
- _CurrSelection = NULL;
- }
-}
-
-// ----------------------------------------------------------------------------
-bool CGroupEditBox::handleEvent (const NLGUI::CEventDescriptor& event)
-{
- if (!_Active || !_ViewText)
- return false;
- if (event.getType() == NLGUI::CEventDescriptor::key)
- {
- if (_BypassNextKey)
- {
- _BypassNextKey = false;
- return true;
- }
- ///////////////
- // KEY EVENT //
- ///////////////
- const NLGUI::CEventDescriptorKey &rEDK = (const NLGUI::CEventDescriptorKey&)event;
- switch(rEDK.getKeyEventType())
- {
- case NLGUI::CEventDescriptorKey::keychar: handleEventChar(rEDK); break;
- case NLGUI::CEventDescriptorKey::keystring: handleEventString(rEDK); break;
- default: break;
- }
- // update the text
- setInputString(_InputString);
-
- // if event of type char or string, consider handle all of them
- if( rEDK.getKeyEventType()==NLGUI::CEventDescriptorKey::keychar || rEDK.getKeyEventType()==NLGUI::CEventDescriptorKey::keystring )
- return true;
- // Else filter the EventKeyDown AND EventKeyUp.
- else
- {
- // Look into the input handler Manager if the key combo has to be considered as handled
- if( ( CGroupEditBox::comboKeyHandler != NULL ) && comboKeyHandler->isComboKeyChat(rEDK) )
- return true;
- else
- return false;
- }
- }
- else
- if (event.getType() == NLGUI::CEventDescriptor::mouse)
- {
- /////////////////
- // MOUSE EVENT //
- /////////////////
- const NLGUI::CEventDescriptorMouse &eventDesc = (const NLGUI::CEventDescriptorMouse &)event;
-
- if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouserightup)
- {
- if (CWidgetManager::getInstance()->getCapturePointerRight() == this)
- {
- CWidgetManager::getInstance()->setCapturePointerRight(NULL);
- if (!_ListMenuRight.empty())
- {
- if (CCtrlDraggable::getDraggedSheet() == NULL)
- {
- _MenuFather = this;
- CWidgetManager::getInstance()->enableModalWindow (this, _ListMenuRight);
- stopParentBlink();
- }
- }
- return true;
- }
- else
- {
- return false;
- }
- }
-
- if (!isIn(eventDesc.getX(), eventDesc.getY()))
- return false;
-
- // if click, and not frozen, then get the focus
- if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftdown && !_Frozen)
- {
- _SelectingText = true;
- stopParentBlink();
- CWidgetManager::getInstance()->setCaptureKeyboard (this);
- // set the right cursor position
- uint newCurPos;
- bool cursorAtPreviousLineEnd;
- _ViewText->getCharacterIndexFromPosition(eventDesc.getX() - _ViewText->getXReal(), eventDesc.getY() - _ViewText->getYReal(), newCurPos, cursorAtPreviousLineEnd);
- _CursorAtPreviousLineEnd = cursorAtPreviousLineEnd;
- _CursorPos = newCurPos;
- _CursorPos -= (sint32)_Prompt.length();
- _CursorPos = std::max(_CursorPos, sint32(0));
- _SelectCursorPos = _CursorPos;
- _CurrSelection = NULL;
-
- return true;
- }
- // if click, and not frozen, then get the focus
- if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mousemove && !_Frozen && _SelectingText)
- {
- // set the right cursor position
- uint newCurPos;
- bool cursorAtPreviousLineEnd;
- _CurrSelection = this;
- _ViewText->getCharacterIndexFromPosition(eventDesc.getX() - _ViewText->getXReal(), eventDesc.getY() - _ViewText->getYReal(), newCurPos, cursorAtPreviousLineEnd);
- _SelectCursorPos = newCurPos;
- _SelectCursorPos -= (sint32)_Prompt.length();
- _SelectCursorPos = std::max(_SelectCursorPos, sint32(0));
- return true;
- }
-
- // if click, and not frozen, then get the focus
- if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftup && !_Frozen)
- {
- _SelectingText = false;
- if (_SelectCursorPos == _CursorPos)
- _CurrSelection = NULL;
-
- return true;
- }
-
- if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouserightdown)
- {
- CWidgetManager::getInstance()->setCapturePointerRight(this);
- return true;
- }
- }
- else
- {
- //////////////////
- // SYSTEM EVENT //
- //////////////////
- const NLGUI::CEventDescriptorSystem &eventDesc = (const NLGUI::CEventDescriptorSystem &)event;
- if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorSystem::activecalledonparent)
- {
- NLGUI::CEventDescriptorActiveCalledOnParent &activeEvent = (NLGUI::CEventDescriptorActiveCalledOnParent &) eventDesc;
- if (activeEvent.getActive() == false && _ResetFocusOnHide)
- {
- CWidgetManager::getInstance()->resetCaptureKeyboard();
- // If a selection was shown, reset it
- if (_CurrSelection == this) _CurrSelection = NULL;
- }
- CInterfaceGroup::handleEvent(activeEvent);
- }
-
- }
- return false;
-}
-
-// ----------------------------------------------------------------------------
-void CGroupEditBox::setupDisplayText()
-{
- if (_ViewText)
- {
- ucstring usTmp;
- if (_EntryType == Password)
- {
- usTmp = _Prompt;
- for (uint32 i = 0; i < _InputString.size(); ++i)
- usTmp += "*";
- }
- else
- {
- usTmp = _Prompt + _InputString;
- }
- _ViewText->setText (usTmp);
- }
-}
-
-// ----------------------------------------------------------------------------
-void CGroupEditBox::checkCoords()
-{
- setupDisplayText();
-
- CInterfaceGroup::checkCoords();
-}
-
-// ----------------------------------------------------------------------------
-void CGroupEditBox::updateCoords()
-{
- if (!_Setupped)
- {
- setup();
- _Setupped = true;
- }
- CInterfaceGroup::updateCoords();
-
- if (_ViewText)
- {
- bool bRecalc = false;
-
- // if the length of the view text exceed the max w we allow, cut it
- while (_ViewText->getWReal() > _MaxCharsSize)
- {
- // Suppr last char
- _InputString = _InputString.substr(0, _InputString.size()-1);
-
- setupDisplayText();
-
- _ViewText->updateCoords();
- bRecalc = true;
- }
-
- // if the length of the view text exceed our real size, ensure the Cursor position is at least visible
- sint32 viewTextNewX = _ViewText->getX();
- if (_ViewText->getWReal() > _WReal)
- {
- // Check if cursor visible
- sint xCursVT, xCurs, yTmp, hTmp;
- // Get the cursor pos from the BL of the viewtext
- _ViewText->getCharacterPositionFromIndex(_CursorPos+(sint)_Prompt.size(), false, xCursVT, yTmp, hTmp);
- // Get the cursor pos from the BL of the edit box
- xCurs = xCursVT - (_XReal - _ViewText->getXReal());
- // If the cursor is outside the edit box move the view text to show the cursor
- if (xCurs > _WReal)
- {
- viewTextNewX = _ViewTextDeltaX - (xCursVT - _WReal);
- }
- if (xCurs < 0)
- {
- if ((xCursVT + xCurs) < 0)
- viewTextNewX = _ViewTextDeltaX;
- else
- viewTextNewX = _ViewTextDeltaX - (xCursVT + xCurs);
- }
- if (_CursorPos == 0)
- {
- viewTextNewX = _ViewTextDeltaX;
- }
- }
- else
- {
- viewTextNewX = _ViewTextDeltaX;
- }
-
- // if X position changed, must recompute
- if (viewTextNewX != _ViewText->getX())
- {
- _ViewText->setX(viewTextNewX);
- bRecalc = true;
- }
-
- // recompute position
- if (bRecalc)
- CInterfaceGroup::updateCoords();
- }
-
- if (_BackupFatherContainerPos)
- {
- CGroupContainerBase *gc = static_cast< CGroupContainerBase* >( getEnclosingContainer() );
-
- if (gc && !gc->getTouchFlag(true))
- {
-
- if (_ViewText && _ViewText->getNumLine() <= 1)
- {
- if (_PrevNumLine > 1)
- {
- gc->restorePosition();
- CInterfaceGroup::updateCoords();
- }
- }
- else
- {
- if (_PrevNumLine <= 1)
- {
- gc->backupPosition();
- }
- }
- _PrevNumLine = _ViewText->getNumLine();
- }
- else
- {
- gc->backupPosition();
- }
- }
-}
-
-// ----------------------------------------------------------------------------
-void CGroupEditBox::clearViews()
-{
- CInterfaceGroup::clearViews();
-}
-
-// ----------------------------------------------------------------------------
-void CGroupEditBox::setup()
-{
- // bind to the controls
- _ViewText = dynamic_cast(CInterfaceGroup::getView("edit_text"));
-
- if(_ViewText == NULL)
- nlwarning("Interface: CGroupEditBox: text 'edit_text' missing or bad type");
-
- // For MultiLine editbox, clip the end space, else weird when edit space at end of line (nothing happens)
- if(_ViewText)
- _ViewText->setMultiLineClipEndSpace(true);
-
- // Bakcup the delta X of this view text
- if(_ViewText)
- _ViewTextDeltaX= _ViewText->getX();
- else
- _ViewTextDeltaX= 0;
-
- // read options
- CInterfaceOptions *pIO = CWidgetManager::getInstance()->getOptions("text_selection");
- if (pIO != NULL)
- {
- _BackSelectColor= pIO->getValColor("back_select_color");
- _TextSelectColor= pIO->getValColor("text_select_color");
- }
-}
-
-
-// ----------------------------------------------------------------------------
-void CGroupEditBox::setInputString(const ucstring &str)
-{
- _InputString = str;
- if (_CursorPos > (sint32) str.length())
- {
- _CursorPos = (sint32)str.length();
- _CursorAtPreviousLineEnd = false;
- }
- if (!_ViewText) return;
- setupDisplayText();
-
- invalidateCoords();
-}
-
-
-// ***************************************************************************
-void CGroupEditBox::setDefaultInputString(const ucstring &str)
-{
- _DefaultInputString= true;
- setInputString(str);
-}
-
-
-// ***************************************************************************
-sint32 CGroupEditBox::getInputStringAsInt() const
-{
- sint32 value;
- fromString(_InputString.toString(), value);
- return value;
-}
-
-// ***************************************************************************
-void CGroupEditBox::setInputStringAsInt(sint32 val)
-{
- setInputString(NLMISC::toString(val));
-}
-
-// ***************************************************************************
-sint64 CGroupEditBox::getInputStringAsInt64() const
-{
- sint64 value;
- fromString(_InputString.toString(), value);
- return value;
-}
-
-// ***************************************************************************
-void CGroupEditBox::setInputStringAsInt64(sint64 val)
-{
- setInputString(NLMISC::toString(val));
-}
-
-// ***************************************************************************
-float CGroupEditBox::getInputStringAsFloat() const
-{
- float value;
- fromString(_InputString.toString(), value);
- return value;
-}
-
-// ***************************************************************************
-void CGroupEditBox::setInputStringAsFloat(float val)
-{
- string fmt= "%." + NLMISC::toString(_MaxFloatPrec) + "f";
- setInputString(NLMISC::toString(fmt.c_str(), val));
-}
-
-// ***************************************************************************
-void CGroupEditBox::cutSelection()
-{
- sint32 minPos= min(_CursorPos, _SelectCursorPos);
- sint32 maxPos= max(_CursorPos, _SelectCursorPos);
- // cut the selection
- if(!_InputString.empty())
- {
- _InputString= _InputString.substr(0, minPos) + _InputString.substr(maxPos);
- }
- _CurrSelection = NULL;
- _CursorPos= minPos;
- triggerOnChangeAH();
-}
-
-// ***************************************************************************
-ucstring CGroupEditBox::getSelection()
-{
- sint32 minPos= min(_CursorPos, _SelectCursorPos);
- sint32 maxPos= max(_CursorPos, _SelectCursorPos);
- // get the selection
- return _InputString.substr(minPos, maxPos-minPos);
-}
-
-
-
-// ***************************************************************************
-void CGroupEditBox::setSelectionAll()
-{
- if(!_InputString.empty())
- {
- _CurrSelection = this;
- _SelectCursorPos= 0;
- _CursorPos= (sint32)_InputString.size();
- _CursorAtPreviousLineEnd = false;
- }
-}
-
-// ***************************************************************************
-void CGroupEditBox::setActive(bool active)
-{
- if (!active && _ResetFocusOnHide)
- CWidgetManager::getInstance()->resetCaptureKeyboard();
-
- CInterfaceGroup::setActive(active);
-}
-
-// ***************************************************************************
-void CGroupEditBox::setInputStringAsStdString(const std::string &str)
-{
- setInputString(ucstring(str));
-}
-
-// ***************************************************************************
-std::string CGroupEditBox::getInputStringAsStdString() const
-{
- std::string result;
- _InputString.toString(result);
- return result;
-}
-
-// ***************************************************************************
-void CGroupEditBox::setInputStringAsUtf8(const std::string &str)
-{
- ucstring tmp;
- tmp.fromUtf8(str);
- setInputString(tmp);
-}
-
-// ***************************************************************************
-std::string CGroupEditBox::getInputStringAsUtf8() const
-{
- return _InputString.toUtf8();
-}
-
-// ***************************************************************************
-void CGroupEditBox::setCommand(const ucstring &command, bool execute)
-{
- // do nothing if frozen
- if(_Frozen)
- return;
-
- // set the string and maybe execute
- setInputString((ucchar) '/' + command);
- if (execute)
- {
- // stop selection
- _CurrSelection = NULL;
- _CursorAtPreviousLineEnd = false;
- CAHManager::getInstance()->runActionHandler(_AHOnEnter, this, _AHOnEnterParams);
- }
- else
- {
- CWidgetManager::getInstance()->setCaptureKeyboard (this);
- _CursorPos = (sint32)_InputString.length();
- }
-}
-
-// ***************************************************************************
-void CGroupEditBox::makeTopWindow()
-{
- CInterfaceGroup *root = getRootWindow();
- if(root)
- CWidgetManager::getInstance()->setTopWindow(root);
-}
-
-// ***************************************************************************
-void CGroupEditBox::clearAllEditBox()
-{
- _InputString = "";
- _CursorPos = 0;
- _CursorAtPreviousLineEnd = false;
- if (!_ViewText) return;
- setupDisplayText();
- invalidateCoords();
-}
-
-// ***************************************************************************
-sint32 CGroupEditBox::getMaxUsedW() const
-{
- return _W;
-}
-
-// ***************************************************************************
-sint32 CGroupEditBox::getMinUsedW() const
-{
- return _W;
-}
-
-// ***************************************************************************
-bool CGroupEditBox::wantSerialConfig() const
-{
- return _Savable && !_InputString.empty();
-}
-
-// ***************************************************************************
-void CGroupEditBox::serialConfig(NLMISC::IStream &f)
-{
- f.serialVersion(0);
- if(_DefaultInputString) // Don't want to save the default input
- {
- _DefaultInputString= false;
- _InputString.clear();
- }
- f.serial(_InputString);
- f.serial(_CursorPos);
- f.serial(_PrevNumLine);
- if (f.isReading())
- {
- setInputString(_InputString);
-
- }
- // serial selection
- bool isSelected = (_CurrSelection == this);
- f.serial(isSelected);
- if (isSelected)
- {
- _CurrSelection = this;
- f.serial(_SelectCursorPos);
- }
-}
-
-// ***************************************************************************
-void CGroupEditBox::onQuit()
-{
- // clear the text and restore backup pos before final save
- setInputString(ucstring(""));
- _CurrSelection = NULL;
-}
-
-// ***************************************************************************
-void CGroupEditBox::onLoadConfig()
-{
- // config is not saved when there's an empty string, so restore that default state.
- setInputString(ucstring(""));
- _CurrSelection = NULL;
- _PrevNumLine = 1;
-}
-
-
-// ***************************************************************************
-void CGroupEditBox::elementCaptured(CCtrlBase *capturedElement)
-{
- // If the input string is the default one, then reset it
- if(capturedElement == this)
- {
- if (_DefaultInputString)
- {
- _DefaultInputString= false;
- setInputString(ucstring());
- }
- _CanRedo = false;
- _CanUndo = false;
- _StartInputString = _ModifiedInputString = _InputString;
- }
- CInterfaceGroup::elementCaptured(capturedElement);
-}
-
-// ***************************************************************************
-void CGroupEditBox::onKeyboardCaptureLost()
-{
- if (!_AHOnFocusLost.empty())
- CAHManager::getInstance()->runActionHandler(_AHOnFocusLost, this, _AHOnFocusLostParams);
-
-}
-
-// ***************************************************************************
-int CGroupEditBox::luaSetSelectionAll(CLuaState &ls)
-{
- const char *funcName = "setSelectionAll";
- CLuaIHM::checkArgCount(ls, funcName, 0);
- setSelectionAll();
- return 0;
-}
-
-// ***************************************************************************
-void CGroupEditBox::setFocusOnText()
-{
- // do nothing if frozen
- if(_Frozen)
- return;
-
- // else set the focus
- CWidgetManager::getInstance()->setCaptureKeyboard (this);
-
- _CurrSelection = this;
- _SelectCursorPos= (sint32)_InputString.size();
- _CursorPos= (sint32)_InputString.size();
- _CursorAtPreviousLineEnd = false;
-}
-
-// ***************************************************************************
-int CGroupEditBox::luaSetFocusOnText(CLuaState &ls)
-{
- const char *funcName = "setFocusOnText";
- CLuaIHM::checkArgCount(ls, funcName, 0);
-
- setFocusOnText();
-
- return 0;
-}
-
-// ***************************************************************************
-int CGroupEditBox::luaCancelFocusOnText(CLuaState &ls)
-{
- const char *funcName = "cancelFocusOnText";
- CLuaIHM::checkArgCount(ls, funcName, 0);
-
- if (CWidgetManager::getInstance()->getCaptureKeyboard()==this || CWidgetManager::getInstance()->getOldCaptureKeyboard()==this)
- CWidgetManager::getInstance()->resetCaptureKeyboard();
-
- _CurrSelection = NULL;
- _SelectCursorPos= 0;
- _CursorPos= 0;
- _CursorAtPreviousLineEnd = false;
-
- return 0;
-}
-
-// ***************************************************************************
-int CGroupEditBox::luaSetupDisplayText(CLuaState &ls)
-{
- const char *funcName = "setupDisplayText";
- CLuaIHM::checkArgCount(ls, funcName, 0);
- setupDisplayText();
- return 0;
-}
-
-// ***************************************************************************
-void CGroupEditBox::setColor(NLMISC::CRGBA col)
-{
- if (_ViewText)
- _ViewText->setColor(col);
-}
-
-// ***************************************************************************
-void CGroupEditBox::setFrozen (bool state)
-{
- _Frozen= state;
-
- // if frozen, loose the focus
- if(_Frozen)
- {
- // stop capture and selection
- CWidgetManager::getInstance()->setCaptureKeyboard (NULL);
- if(_CurrSelection==this) _CurrSelection = NULL;
- // do not allow to recover focus
- if (CWidgetManager::getInstance()->getOldCaptureKeyboard() == this)
- {
- CWidgetManager::getInstance()->resetCaptureKeyboard();
- }
- }
-}
-
diff --git a/code/ryzom/client/src/interface_v3/group_editbox.h b/code/ryzom/client/src/interface_v3/group_editbox.h
deleted file mode 100644
index 2df561ff8..000000000
--- a/code/ryzom/client/src/interface_v3/group_editbox.h
+++ /dev/null
@@ -1,363 +0,0 @@
-// Ryzom - MMORPG Framework
-// Copyright (C) 2010 Winch Gate Property Limited
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as
-// published by the Free Software Foundation, either version 3 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see .
-
-
-
-#ifndef RZ_CTRL_EDITBOX_H
-#define RZ_CTRL_EDITBOX_H
-
-#include "nel/gui/interface_group.h"
-#include "nel/gui/group_editbox_base.h"
-#include "nel/3d/u_texture.h"
-
-namespace NLGUI
-{
- class CEventDescriptor;
- class CViewText;
-}
-
-// ----------------------------------------------------------------------------
-class CGroupEditBox : public CGroupEditBoxBase
-{
-public:
-
- class IComboKeyHandler
- {
- public:
- virtual ~IComboKeyHandler(){}
- virtual bool isComboKeyChat( const NLGUI::CEventDescriptorKey &edk ) const = 0;
- };
-
- enum TEntryType { Text, Integer, PositiveInteger, Float, PositiveFloat, Alpha, AlphaNum, AlphaNumSpace, Password, Filename, PlayerName }; // the type of entry this edit bot can deal with
-
- DECLARE_UI_CLASS( CGroupEditBox )
- /// Constructor
- CGroupEditBox(const TCtorParam ¶m);
- /// Dtor
- ~CGroupEditBox();
-
- bool parse(xmlNodePtr cur,CInterfaceGroup * parentGroup);
- virtual uint32 getMemory() { return (uint32)(sizeof(*this)+_Id.size()); }
-
- virtual void draw();
-
- virtual bool handleEvent (const NLGUI::CEventDescriptor& eventDesc);
-
- /// Accessors
- ucstring getInputString() const { return _InputString; }
- const ucstring &getInputStringRef() const { return _InputString; }
- const ucstring &getPrompt() const { return _Prompt; }
-
- /** Set the prompt
- * NB : line returns are encoded as '\n', not '\r\n'
- */
- void setPrompt(const ucstring &s) { _Prompt = s; }
- void setInputString(const ucstring &str);
- void setInputStringRef(const ucstring &str) {_InputString = str; };
- void setInputStringAsInt(sint32 val);
- sint32 getInputStringAsInt() const;
- void setInputStringAsInt64(sint64 val);
- sint64 getInputStringAsInt64() const;
- void setInputStringAsFloat(float val);
- float getInputStringAsFloat() const;
- void setInputStringAsStdString(const std::string &str);
- std::string getInputStringAsStdString() const;
- void setInputStringAsUtf8(const std::string &str);
- std::string getInputStringAsUtf8() const;
- void setColor(NLMISC::CRGBA col);
-
-
- /// force the selection of all the text
- void setSelectionAll();
-
- virtual void checkCoords();
- virtual void updateCoords();
- virtual void clearViews ();
-
- virtual void setActive (bool state);
-
- static CGroupEditBox *getMenuFather() { return _MenuFather; }
-
- void setCommand(const ucstring &command, bool execute);
-
- // Stop parent from blinking
- void stopParentBlink() { if (_Parent) _Parent->disableBlink(); }
-
- // Get / set cursor position
- sint32 getCursorPos () const {return _CursorPos;}
- void setCursorPos (sint32 pos) {_CursorPos=pos;}
-
- // Get / set cursor at previous line end
- bool isCursorAtPreviousLineEnd () const {return _CursorAtPreviousLineEnd;}
- void setCursorAtPreviousLineEnd (bool setCursor) {_CursorAtPreviousLineEnd=setCursor;}
-
- // Get / set current selection position
- static sint32 getSelectCursorPos () {return _SelectCursorPos;}
- static void setSelectCursorPos (sint32 pos) {_SelectCursorPos=pos;}
-
- // Get the view text
- const CViewText *getViewText () const {return _ViewText;}
-
- // Get the historic information
- sint32 getMaxHistoric() const {return _MaxHistoric;}
- sint32 getCurrentHistoricIndex () const {return _CurrentHistoricIndex;}
- void setCurrentHistoricIndex (sint32 index) {_CurrentHistoricIndex=index;}
- const ucstring &getHistoric(uint32 index) const {return _Historic[index];}
- uint32 getNumHistoric() const {return (uint32)_Historic.size ();}
-
- // Get on change action handler
- const std::string &getAHOnChange() const {return _AHOnChange;}
- const std::string &getParamsOnChange() const {return _ParamsOnChange;}
-
- void cutSelection();
-
- /// From CInterfaceElement
- sint32 getMaxUsedW() const;
- sint32 getMinUsedW() const;
-
- // Copy the selection into buffer
- void copy();
- // Paste the selection into buffer
- void paste();
- // Write the string into buffer
- void writeString(const ucstring &str, bool replace = true, bool atEnd = true);
-
- // Expand the expression (true if there was a '/' at the start of the line)
- bool expand();
-
- // Back space
- void back();
-
- // ignore the next char/key event -> useful when a key set the focus on an editbox (keydown is received, the focus, then keychar is received by the editbox again, but is irrelevant)
- void bypassNextKey() { _BypassNextKey = true; }
-
- // True if the editBox loose the focus on enter
- bool getLooseFocusOnEnter() const {return _LooseFocusOnEnter;}
- //
- virtual void clearAllEditBox();
- // From CInterfaceElement
- virtual bool wantSerialConfig() const;
- // From CInterfaceElement
- virtual void serialConfig(NLMISC::IStream &f);
- // From CInterfaceElement
- virtual void onQuit();
- // From CInterfaceElement
- virtual void onLoadConfig();
-
- // from CCtrlBase
- virtual void elementCaptured(CCtrlBase *capturedElement);
-
- // from CCtrlBase
- virtual void onKeyboardCaptureLost();
-
- // set the input string as "default". will be reseted at first click (used for user information)
- void setDefaultInputString(const ucstring &str);
-
- // For Interger and PositiveInteger, can specify min and max values
- void setIntegerMinValue(sint32 minValue) {_IntegerMinValue=minValue;}
- void setIntegerMaxValue(sint32 maxValue) {_IntegerMaxValue=maxValue;}
- void setPositiveIntegerMinValue(uint32 minValue) {_PositiveIntegerMinValue=minValue;}
- void setPositiveIntegerMaxValue(uint32 maxValue) {_PositiveIntegerMaxValue=maxValue;}
-
- void setFocusOnText();
-
- int luaSetSelectionAll(CLuaState &ls);
- int luaSetupDisplayText(CLuaState &ls);
- int luaSetFocusOnText(CLuaState &ls);
- int luaCancelFocusOnText(CLuaState &ls);
- REFLECT_EXPORT_START(CGroupEditBox, CGroupEditBoxBase)
- REFLECT_LUA_METHOD("setupDisplayText", luaSetupDisplayText);
- REFLECT_LUA_METHOD("setSelectionAll", luaSetSelectionAll);
- REFLECT_LUA_METHOD("setFocusOnText", luaSetFocusOnText);
- REFLECT_LUA_METHOD("cancelFocusOnText", luaCancelFocusOnText);
- REFLECT_STRING("input_string", getInputStringAsStdString, setInputStringAsStdString);
- REFLECT_UCSTRING("uc_input_string", getInputString, setInputString);
- REFLECT_EXPORT_END
-
- /** Restore the original value of the edit box.
- * This value is captured when the edit box get focus
- * (return true if no undo was available)
- * Will always fails ifthe edito box do not have the focus
- */
- bool undo();
-
- /** Cancel last undo operation
- * Return true if redo operation is available
- */
- bool redo();
-
- /// freeze the control (loose focus, and cannot edit)
- void setFrozen (bool state);
- bool getFrozen () const { return _Frozen; }
-
-protected:
-
- // Cursor infos
- float _BlinkTime;
- sint32 _CursorPos;
- uint32 _MaxNumChar;
- uint32 _MaxNumReturn;
- uint32 _MaxFloatPrec; // used in setInputStringAsFloat() only
- sint32 _MaxCharsSize;
- sint32 _FirstVisibleChar;
- sint32 _LastVisibleChar;
-
- // Text selection
- static sint32 _SelectCursorPos;
- bool _SelectingText;
- NLMISC::CRGBA _TextSelectColor;
- NLMISC::CRGBA _BackSelectColor;
-
- // Text info
- ucstring _Prompt;
- ucstring _InputString;
- CViewText *_ViewText;
-
- // undo / redo
- ucstring _StartInputString; // value of the input string when focus was acuired first
- ucstring _ModifiedInputString;
-
-
- // Historic info
- typedef std::deque THistoric;
- THistoric _Historic;
- uint32 _MaxHistoric;
- sint32 _CurrentHistoricIndex;
- sint32 _PrevNumLine;
-
- // Action Handler
- std::string _AHOnChange;
- std::string _ParamsOnChange;
- std::string _ListMenuRight;
-
- std::string _AHOnFocusLost;
- std::string _AHOnFocusLostParams;
-
- // entry type
- TEntryType _EntryType;
-
-
- bool _Setupped : 1; // setup
- bool _BypassNextKey : 1;
- bool _BlinkState : 1;
- bool _CursorAtPreviousLineEnd : 1; // force the cursor to be displayed at the end of the previous line end (if END has beeen pressed while in a string split accross 2 lines)
- bool _LooseFocusOnEnter : 1;
- bool _ResetFocusOnHide : 1;
- bool _BackupFatherContainerPos : 1; // Backup father container position when characters are typed.
- // If the edit box is at the bottom of the screen and if it expands on y
- // because of multiline, thz parent container will be moved to top
- // The good position can be restored by a press on enter then
- bool _WantReturn : 1; // Want return char, don't call the enter action handler
- bool _Savable : 1; // should content be saved ?
- bool _DefaultInputString : 1; // Is the current input string the default one (should not be edited)
- bool _Frozen : 1; // is the control frozen? (cannot edit in it)
-
- bool _CanRedo : 1;
- bool _CanUndo : 1;
-
- std::vector _NegativeFilter;
-
- sint _CursorTexID;
- sint32 _CursorWidth;
-
- sint32 _IntegerMinValue;
- sint32 _IntegerMaxValue;
- uint32 _PositiveIntegerMinValue;
- uint32 _PositiveIntegerMaxValue;
-
- sint32 _ViewTextDeltaX;
-
-private:
- void setupDisplayText();
- void makeTopWindow();
- void handleEventChar(const NLGUI::CEventDescriptorKey &event);
- void handleEventString(const NLGUI::CEventDescriptorKey &event);
- void setup();
- void triggerOnChangeAH();
- void appendStringFromClipboard(const ucstring &str);
-
- ucstring getSelection();
-
- static CGroupEditBox *_MenuFather;
-
- static bool isValidAlphaNumSpace(ucchar c)
- {
- if (c > 255) return false;
- char ac = (char) c;
- return (ac >= '0' && ac <= '9') ||
- (ac >= 'a' && ac <= 'z') ||
- (ac >= 'A' && ac <= 'Z') ||
- ac==' ';
- }
-
- static bool isValidAlphaNum(ucchar c)
- {
- if (c > 255) return false;
- char ac = (char) c;
- return (ac >= '0' && ac <= '9') ||
- (ac >= 'a' && ac <= 'z') ||
- (ac >= 'A' && ac <= 'Z');
- }
-
- static bool isValidAlpha(ucchar c)
- {
- if (c > 255) return false;
- char ac = (char) c;
- return (ac >= 'a' && ac <= 'z') ||
- (ac >= 'A' && ac <= 'Z');
- }
-
- static bool isValidPlayerNameChar(ucchar c)
- {
- // valid player name (with possible shard prefix / suffix format
- return isValidAlpha(c) || c=='.' || c=='(' || c==')';
- }
-
- static bool isValidFilenameChar(ucchar c)
- {
- if (c == '\\' ||
- c == '/' ||
- c == ':' ||
- c == '*' ||
- c == '?' ||
- c == '\"' ||
- c == '<' ||
- c == '>' ||
- c == '|') return false;
- return true;
- }
- //
- bool isFiltered(ucchar c)
- {
- uint length = (uint)_NegativeFilter.size();
- for (uint k = 0; k < length; ++k)
- {
- if ((ucchar) _NegativeFilter[k] == c) return true;
- }
- return false;
- }
-
- static IComboKeyHandler *comboKeyHandler;
-
-public:
- static void setComboKeyHandler( IComboKeyHandler *handler ){ comboKeyHandler = handler; }
-
-};
-
-
-#endif // RZ_CTRL_EDITBOX_H
-
-/* End of ctrl_editbox.h */
diff --git a/code/ryzom/client/src/interface_v3/group_html.cpp b/code/ryzom/client/src/interface_v3/group_html.cpp
index 3f10224c5..422af5755 100644
--- a/code/ryzom/client/src/interface_v3/group_html.cpp
+++ b/code/ryzom/client/src/interface_v3/group_html.cpp
@@ -38,7 +38,7 @@ extern "C"
#include "nel/gui/ctrl_text_button.h"
#include "nel/gui/action_handler.h"
#include "group_paragraph.h"
-#include "group_editbox.h"
+#include "nel/gui/group_editbox.h"
#include "interface_manager.h"
#include "nel/gui/view_bitmap.h"
#include "../actions.h"
diff --git a/code/ryzom/client/src/interface_v3/group_map.cpp b/code/ryzom/client/src/interface_v3/group_map.cpp
index 68341375f..7593780b7 100644
--- a/code/ryzom/client/src/interface_v3/group_map.cpp
+++ b/code/ryzom/client/src/interface_v3/group_map.cpp
@@ -25,7 +25,7 @@
#include "../zone_util.h"
#include "../user_entity.h"
#include "nel/gui/ctrl_button.h"
-#include "group_editbox.h"
+#include "nel/gui/group_editbox.h"
#include "../string_manager_client.h"
#include "group_container.h"
#include "nel/gui/action_handler.h"
diff --git a/code/ryzom/client/src/interface_v3/input_handler_manager.h b/code/ryzom/client/src/interface_v3/input_handler_manager.h
index aa5903b72..8491bd53a 100644
--- a/code/ryzom/client/src/interface_v3/input_handler_manager.h
+++ b/code/ryzom/client/src/interface_v3/input_handler_manager.h
@@ -26,7 +26,7 @@
#include
#include "nel/gui/event_descriptor.h"
#include "nel/gui/input_handler.h"
-#include "group_editbox.h"
+#include "nel/gui/group_editbox.h"
/**
diff --git a/code/ryzom/client/src/interface_v3/interface_manager.cpp b/code/ryzom/client/src/interface_v3/interface_manager.cpp
index ab028fc3e..a3535a109 100644
--- a/code/ryzom/client/src/interface_v3/interface_manager.cpp
+++ b/code/ryzom/client/src/interface_v3/interface_manager.cpp
@@ -64,7 +64,7 @@
#include "group_menu.h"
#include "group_container.h"
#include "nel/gui/group_modal.h"
-#include "group_editbox.h"
+#include "nel/gui/group_editbox.h"
#include "group_in_scene_bubble.h"
#include "group_skills.h"
#include "group_compas.h"
diff --git a/code/ryzom/client/src/interface_v3/interface_parser.cpp b/code/ryzom/client/src/interface_v3/interface_parser.cpp
index 62a38eace..ec5a22938 100644
--- a/code/ryzom/client/src/interface_v3/interface_parser.cpp
+++ b/code/ryzom/client/src/interface_v3/interface_parser.cpp
@@ -70,7 +70,7 @@
#include "group_menu.h"
#include "group_container.h"
#include "group_scrolltext.h"
-#include "group_editbox.h"
+#include "nel/gui/group_editbox.h"
#include "group_skills.h"
#include "group_html_forum.h"
#include "group_html_mail.h"
diff --git a/code/ryzom/client/src/interface_v3/lua_ihm_ryzom.cpp b/code/ryzom/client/src/interface_v3/lua_ihm_ryzom.cpp
index cf1a1c2a8..54892a61a 100644
--- a/code/ryzom/client/src/interface_v3/lua_ihm_ryzom.cpp
+++ b/code/ryzom/client/src/interface_v3/lua_ihm_ryzom.cpp
@@ -76,7 +76,7 @@
#include "../motion/user_controls.h"
#include "group_html_cs.h"
#include "bonus_malus.h"
-#include "group_editbox.h"
+#include "nel/gui/group_editbox.h"
#include "../entities.h"
#include "../sheet_manager.h" // for emotes
#include "../global.h" // for emotes
diff --git a/code/ryzom/client/src/interface_v3/macrocmd_key.cpp b/code/ryzom/client/src/interface_v3/macrocmd_key.cpp
index 1bec84943..d4d2d87ad 100644
--- a/code/ryzom/client/src/interface_v3/macrocmd_key.cpp
+++ b/code/ryzom/client/src/interface_v3/macrocmd_key.cpp
@@ -25,7 +25,7 @@
#include "interface_manager.h"
#include "nel/gui/action_handler.h"
#include "nel/gui/ctrl_button.h"
-#include "group_editbox.h"
+#include "nel/gui/group_editbox.h"
#include "nel/gui/group_list.h"
#include "dbgroup_combo_box.h"
#include "group_container.h"
diff --git a/code/ryzom/client/src/interface_v3/macrocmd_manager.cpp b/code/ryzom/client/src/interface_v3/macrocmd_manager.cpp
index 96a5145d0..099b6f364 100644
--- a/code/ryzom/client/src/interface_v3/macrocmd_manager.cpp
+++ b/code/ryzom/client/src/interface_v3/macrocmd_manager.cpp
@@ -26,7 +26,7 @@
#include "nel/gui/action_handler.h"
#include "dbctrl_sheet.h"
#include "nel/gui/ctrl_button.h"
-#include "group_editbox.h"
+#include "nel/gui/group_editbox.h"
#include "nel/gui/group_list.h"
#include "dbgroup_combo_box.h"
#include "group_container.h"
diff --git a/code/ryzom/client/src/interface_v3/people_interraction.cpp b/code/ryzom/client/src/interface_v3/people_interraction.cpp
index ec9043989..1a7593031 100644
--- a/code/ryzom/client/src/interface_v3/people_interraction.cpp
+++ b/code/ryzom/client/src/interface_v3/people_interraction.cpp
@@ -26,7 +26,7 @@
#include "action_handler_misc.h"
#include "chat_window.h"
#include "../entity_animation_manager.h"
-#include "group_editbox.h"
+#include "nel/gui/group_editbox.h"
#include "group_menu.h"
#include "../client_chat_manager.h"
#include "../string_manager_client.h"
diff --git a/code/ryzom/client/src/interface_v3/people_list.cpp b/code/ryzom/client/src/interface_v3/people_list.cpp
index 1d2be1faa..3eb1c500f 100644
--- a/code/ryzom/client/src/interface_v3/people_list.cpp
+++ b/code/ryzom/client/src/interface_v3/people_list.cpp
@@ -23,7 +23,7 @@
#include "nel/gui/view_bitmap.h"
#include "interface_manager.h"
#include "nel/gui/action_handler.h"
-#include "group_editbox.h"
+#include "nel/gui/group_editbox.h"
#include "../client_chat_manager.h"
#include "chat_text_manager.h"
#include "people_interraction.h"
diff --git a/code/ryzom/client/src/interface_v3/register_interface_elements.cpp b/code/ryzom/client/src/interface_v3/register_interface_elements.cpp
index 3a2d7f7b1..2df8c0dda 100644
--- a/code/ryzom/client/src/interface_v3/register_interface_elements.cpp
+++ b/code/ryzom/client/src/interface_v3/register_interface_elements.cpp
@@ -40,7 +40,7 @@
#include "dbctrl_sheet.h"
#include "dbgroup_list_sheet.h"
#include "nel/gui/group_editbox_base.h"
-#include "group_editbox.h"
+#include "nel/gui/group_editbox.h"
#include "nel/gui/group_tree.h"
#include "nel/gui/reflect.h"
#include "dbview_bar.h"
diff --git a/code/ryzom/client/src/login.cpp b/code/ryzom/client/src/login.cpp
index eb5008ee2..5d37d7c54 100644
--- a/code/ryzom/client/src/login.cpp
+++ b/code/ryzom/client/src/login.cpp
@@ -35,7 +35,7 @@
#include "interface_v3/interface_manager.h"
#include "interface_v3/input_handler_manager.h"
-#include "interface_v3/group_editbox.h"
+#include "nel/gui/group_editbox.h"
#include "interface_v3/group_quick_help.h"
#include "nel/gui/view_text.h"
#include "nel/gui/ctrl_button.h"
diff --git a/code/ryzom/client/src/r2/editor.cpp b/code/ryzom/client/src/r2/editor.cpp
index 54b498858..f740cdf81 100644
--- a/code/ryzom/client/src/r2/editor.cpp
+++ b/code/ryzom/client/src/r2/editor.cpp
@@ -81,7 +81,7 @@ using namespace NLGUI;
#include "../interface_v3/input_handler_manager.h"
#include "../connection.h"
#include "../init_main_loop.h"
-#include "../interface_v3/group_editbox.h"
+#include "nel/gui/group_editbox.h"
#include "../landscape_poly_drawer.h"
#include "../input.h"
#include "../motion/user_controls.h"