diff --git a/Themes/Til Death/BGAnimations/ScreenSelectMusic overlay/default.lua b/Themes/Til Death/BGAnimations/ScreenSelectMusic overlay/default.lua index 060b3f9817..8d039ccd74 100644 --- a/Themes/Til Death/BGAnimations/ScreenSelectMusic overlay/default.lua +++ b/Themes/Til Death/BGAnimations/ScreenSelectMusic overlay/default.lua @@ -14,7 +14,8 @@ t[#t+1] = LoadFont("Common Large")..{ InitCommand=cmd(xy,5,32;halign,0;valign,1;zoom,0.55;diffuse,getMainColor('positive');settext,"Select Music:"); } t[#t+1] = LoadActor("../_cursor") +t[#t+1] = LoadActor("../_mousewheelscroll") t[#t+1] = LoadActor("../_halppls") t[#t+1] = LoadActor("currenttime") -return t \ No newline at end of file +return t diff --git a/Themes/Til Death/BGAnimations/_chatbox.lua b/Themes/Til Death/BGAnimations/_chatbox.lua index 10c0e0f911..9b8899be8f 100644 --- a/Themes/Til Death/BGAnimations/_chatbox.lua +++ b/Themes/Til Death/BGAnimations/_chatbox.lua @@ -1,4 +1,6 @@ -local t = Def.ActorFrame{} + +local top +local whee local border = 5 @@ -30,6 +32,58 @@ local outputHeight = THEME:GetMetric("ScreenNetSelectBase","ChatOutputLines")*9. end +local function isOverChatbox() + if INPUTFILTER:GetMouseX() > outputX-border and INPUTFILTER:GetMouseX() < outputX + outputWidth+border*2 and INPUTFILTER:GetMouseY() > outputY-border and INPUTFILTER:GetMouseY() < outputY + outputHeight+border*2 then + return true + end + return false +end + + +local function scrollInput(event) + if event.DeviceInput.button == "DeviceButton_tab" then + if event.type == "InputEventType_FirstPress" then + local pressingtab = true + elseif event.type == "InputEventType_Release" then + local pressingtab = false + end + elseif event.DeviceInput.button == "DeviceButton_mousewheel up" and event.type == "InputEventType_FirstPress" then + if isOverChatbox() then + top:ScrollChatUp() + else + moving = true + if pressingtab == true then + whee:Move(-2) + else + whee:Move(-1) + end + end + elseif event.DeviceInput.button == "DeviceButton_mousewheel down" and event.type == "InputEventType_FirstPress" then + if isOverChatbox() then + top:ScrollChatDown() + else + moving = true + if pressingtab == true then + whee:Move(2) + else + whee:Move(1) + end + end + elseif moving == true then + whee:Move(0) + moving = false + end +end + + +local t = Def.ActorFrame{ + BeginCommand=function(self) + top = SCREENMAN:GetTopScreen() + whee = top:GetMusicWheel() + top:AddInputCallback(scrollInput) + end, +} + t[#t+1] = Def.Quad{ InitCommand=cmd(xy,inputX-border,inputY-border;zoomto,outputWidth+border*2,inputHeight+border*2;halign,0;valign,0;diffuse,color("#00000099");), TabChangedMessageCommand=function(self) @@ -53,4 +107,4 @@ t[#t+1] = Def.Quad{ end, } -return t \ No newline at end of file +return t diff --git a/Themes/Til Death/BGAnimations/_mousewheelscroll.lua b/Themes/Til Death/BGAnimations/_mousewheelscroll.lua new file mode 100644 index 0000000000..a2758433c9 --- /dev/null +++ b/Themes/Til Death/BGAnimations/_mousewheelscroll.lua @@ -0,0 +1,40 @@ + +local moving = false +local whee +local pressingtab = false + +local function scrollInput(event) + if event.DeviceInput.button == "DeviceButton_tab" then + if event.type == "InputEventType_FirstPress" then + pressingtab = true + elseif event.type == "InputEventType_Release" then + pressingtab = false + end + elseif event.DeviceInput.button == "DeviceButton_mousewheel up" and event.type == "InputEventType_FirstPress" then + moving = true + if pressingtab == true then + whee:Move(-2) + else + whee:Move(-1) + end + elseif event.DeviceInput.button == "DeviceButton_mousewheel down" and event.type == "InputEventType_FirstPress" then + moving = true + if pressingtab == true then + whee:Move(2) + else + whee:Move(1) + end + elseif moving == true then + whee:Move(0) + moving = false + end +end + +local t = Def.ActorFrame{ + BeginCommand=function(self) + whee = SCREENMAN:GetTopScreen():GetMusicWheel() + SCREENMAN:GetTopScreen():AddInputCallback(scrollInput) + self:visible(false) + end, +} +return t diff --git a/Themes/Til Death/_chatbox.lua b/Themes/Til Death/_chatbox.lua new file mode 100644 index 0000000000..40e8ebbe42 --- /dev/null +++ b/Themes/Til Death/_chatbox.lua @@ -0,0 +1,112 @@ + +local top +local whee + +local border = 5 + +local inputX = THEME:GetMetric("ScreenNetSelectBase","ChatInputX") +local inputY = THEME:GetMetric("ScreenNetSelectBase","ChatInputY") +local inputWidth = THEME:GetMetric("ScreenNetSelectBase","ChatTextInputWidth")*0.4 +local inputHeight = 25 + + +local outputX = THEME:GetMetric("ScreenNetSelectBase","ChatOutputX") +local outputY = THEME:GetMetric("ScreenNetSelectBase","ChatOutputY") +local outputWidth = THEME:GetMetric("ScreenNetSelectBase","ChatTextOutputWidth")*0.3153 +local outputHeight = THEME:GetMetric("ScreenNetSelectBase","ChatOutputLines")*9.25 + +if IsUsingWideScreen() == true then + +local border = 5 + +local inputX = THEME:GetMetric("ScreenNetSelectBase","ChatInputX") +local inputY = THEME:GetMetric("ScreenNetSelectBase","ChatInputY") +local inputWidth = THEME:GetMetric("ScreenNetSelectBase","ChatTextInputWidth")*0.4 +local inputHeight = 25 + + +local outputX = THEME:GetMetric("ScreenNetSelectBase","ChatOutputX") +local outputY = THEME:GetMetric("ScreenNetSelectBase","ChatOutputY") +local outputWidth = THEME:GetMetric("ScreenNetSelectBase","ChatTextOutputWidth")*0.3153 +local outputHeight = THEME:GetMetric("ScreenNetSelectBase","ChatOutputLines")*9.25 + +end + +local function isOverChatbox() + if INPUTFILTER:GetMouseX() > outputX-border and INPUTFILTER:GetMouseX() < outputX + outputWidth+border*2 and INPUTFILTER:GetMouseY() > outputY-border and INPUTFILTER:GetMouseY() < outputY + outputHeight+border*2 then + return true + end + return false +end + + +local function scrollInput(event) + if event.DeviceInput.button == "DeviceButton_tab" then + if event.type == "InputEventType_FirstPress" then + local pressingtab = true + elseif event.type == "InputEventType_Repeat" then + pressingtab = true + elseif event.type == "InputEventType_Release" then + local pressingtab = false + end + elseif event.DeviceInput.button == "DeviceButton_mousewheel up" and event.type == "InputEventType_FirstPress" then + if isOverChatbox() then + top:ScrollChatUp() + else + moving = true + if pressingtab == true then + whee:Move(-2) + else + whee:Move(-1) + end + end + elseif event.DeviceInput.button == "DeviceButton_mousewheel down" and event.type == "InputEventType_FirstPress" then + if isOverChatbox() then + top:ScrollChatDown() + else + moving = true + if pressingtab == true then + whee:Move(2) + else + whee:Move(1) + end + end + elseif moving == true then + whee:Move(0) + moving = false + end +end + + +local t = Def.ActorFrame{ + BeginCommand=function(self) + top = SCREENMAN:GetTopScreen() + whee = top:GetMusicWheel() + top:AddInputCallback(scrollInput) + end, +} + +t[#t+1] = Def.Quad{ + InitCommand=cmd(xy,inputX-border,inputY-border;zoomto,outputWidth+border*2,inputHeight+border*2;halign,0;valign,0;diffuse,color("#00000099");), + TabChangedMessageCommand=function(self) + local top= SCREENMAN:GetTopScreen() + if getTabIndex() == 0 then + self:visible(true) + else + self:visible(false) + end + end, + } +t[#t+1] = Def.Quad{ + InitCommand=cmd(xy,outputX-border,outputY-border;zoomto,outputWidth+border*2,outputHeight+border*2;halign,0;valign,0;diffuse,color("#00000099");), + TabChangedMessageCommand=function(self) + local top= SCREENMAN:GetTopScreen() + if getTabIndex() == 0 then + self:visible(true) + else + self:visible(false) + end + end, +} + +return t \ No newline at end of file diff --git a/src/MusicWheel.cpp b/src/MusicWheel.cpp index 6c5dbec16b..b3e831c2d7 100644 --- a/src/MusicWheel.cpp +++ b/src/MusicWheel.cpp @@ -1877,6 +1877,15 @@ class LunaMusicWheel : public Luna p->ReloadSongList(true, SArg(1)); return 1; } + static int Move(T* p, lua_State *L) + { + if (lua_isnil(L, 1)) { p->Move(0); } + else + { + p->Move(IArg(1)); + } + return 1; + } LunaMusicWheel() { @@ -1886,6 +1895,7 @@ class LunaMusicWheel : public Luna ADD_METHOD( SelectSong ); ADD_METHOD( SelectCourse ); ADD_METHOD( SongSearch ); + ADD_METHOD( Move ); } }; diff --git a/src/RoomWheel.cpp b/src/RoomWheel.cpp index 01374930ad..2e348d8385 100644 --- a/src/RoomWheel.cpp +++ b/src/RoomWheel.cpp @@ -194,6 +194,33 @@ unsigned int RoomWheel::GetNumItems() const return m_CurWheelItemData.size() - m_offset; } + +// lua start +#include "LuaBinding.h" + +class LunaRoomWheel : public Luna +{ +public: + static int Move(T* p, lua_State *L) + { + if (lua_isnil(L, 1)) { p->Move(0); } + else + { + p->Move(IArg(1)); + } + return 1; + } + + LunaRoomWheel() + { + ADD_METHOD(Move); + } +}; + +LUA_REGISTER_DERIVED_CLASS(RoomWheel, WheelBase) +// lua end + + /* * (c) 2004 Josh Allen * All rights reserved. diff --git a/src/RoomWheel.h b/src/RoomWheel.h index 59010df1f6..7f21202ce8 100644 --- a/src/RoomWheel.h +++ b/src/RoomWheel.h @@ -61,6 +61,9 @@ class RoomWheel : public WheelBase int GetPerminateOffset() const { return m_offset; } void AddItem( WheelItemBaseData *itemdata ); void RemoveItem( int index ); + + // Lua + void PushSelf(lua_State *L); private: virtual WheelItemBase *MakeItem(); diff --git a/src/ScreenNetRoom.cpp b/src/ScreenNetRoom.cpp index 0a3b210b9a..c4258aa160 100644 --- a/src/ScreenNetRoom.cpp +++ b/src/ScreenNetRoom.cpp @@ -58,6 +58,11 @@ bool ScreenNetRoom::Input( const InputEventPlus &input ) return ScreenNetSelectBase::Input( input ); } +RoomWheel* ScreenNetRoom::GetRoomWheel() +{ + return &m_RoomWheel; +} + void ScreenNetRoom::HandleScreenMessage( const ScreenMessage SM ) { if( SM == SM_GoToPrevScreen ) @@ -314,6 +319,26 @@ void ScreenNetRoom::CreateNewRoom( const RString& rName, const RString& rDesc, #endif +// lua start +#include "LuaBinding.h" + +/** @brief Allow Lua to have access to the PlayerState. */ +class LunaScreenNetRoom : public Luna +{ +public: + static int GetMusicWheel(T* p, lua_State *L) { + p->GetRoomWheel()->PushSelf(L); + return 1; + } + LunaScreenNetRoom() + { + ADD_METHOD(GetMusicWheel); + } +}; + +LUA_REGISTER_DERIVED_CLASS(ScreenNetRoom, ScreenNetSelectBase) +// lua end + /* * (c) 2004 Charles Lohr, Josh Allen * (c) 2001-2004 Chris Danford diff --git a/src/ScreenNetRoom.h b/src/ScreenNetRoom.h index dde4704ad8..66c5d8ce25 100644 --- a/src/ScreenNetRoom.h +++ b/src/ScreenNetRoom.h @@ -32,6 +32,10 @@ class ScreenNetRoom : public ScreenNetSelectBase virtual void Init(); virtual bool Input( const InputEventPlus &input ); virtual void HandleScreenMessage( const ScreenMessage SM ); + RoomWheel* GetRoomWheel(); + + // Lua + void PushSelf(lua_State *L); protected: virtual bool MenuStart( const InputEventPlus &input ); diff --git a/src/ScreenNetSelectBase.cpp b/src/ScreenNetSelectBase.cpp index de382e199a..15a6f3f843 100644 --- a/src/ScreenNetSelectBase.cpp +++ b/src/ScreenNetSelectBase.cpp @@ -63,6 +63,8 @@ void ScreenNetSelectBase::Init() m_textChatOutput.SetText( NSMAN->m_sChatText ); m_textChatOutput.SetMaxLines( SHOW_CHAT_LINES, 1 ); + + scroll = 0; //Display users list UpdateUsers(); @@ -85,12 +87,37 @@ bool ScreenNetSelectBase::Input( const InputEventPlus &input ) switch( input.DeviceI.button ) { + case KEY_PGUP: + if (!bHoldingCtrl) { + ShowPreviousMsg(); + break; + } + else { + Scroll(1); + Scroll(1); + break; + } + case KEY_PGDN: + if (!bHoldingCtrl) { + ShowNextMsg(); + break; + } + else { + Scroll(-1); + Scroll(-1); + break; + } case KEY_ENTER: case KEY_KP_ENTER: if (!bHoldingCtrl) { - if ( m_sTextInput != "" ) - NSMAN->SendChat( m_sTextInput ); + if (m_sTextInput != "") { + NSMAN->SendChat(m_sTextInput); + m_sTextLastestInputs.push_back(m_sTextInput); + m_sTextLastestInputsIndex = 0; + if (m_sTextLastestInputs.size() > 10) + m_sTextLastestInputs.erase(m_sTextLastestInputs.begin()); + } m_sTextInput=""; UpdateTextInput(); return true; @@ -206,6 +233,48 @@ void ScreenNetSelectBase::UpdateUsers() MESSAGEMAN->Broadcast("UsersUpdate"); } +void ScreenNetSelectBase::Scroll(int movescroll) +{ + if (scroll+movescroll >= 0 && scroll+movescroll <= m_textChatOutput.lines - SHOW_CHAT_LINES) + scroll += movescroll; + m_textChatOutput.ResetText(); + m_textChatOutput.SetMaxLines(SHOW_CHAT_LINES, 1, scroll); + return; +} + +RString ScreenNetSelectBase::GetPreviousMsg() +{ + m_sTextLastestInputsIndex += 1; + if (m_sTextLastestInputsIndex <= m_sTextLastestInputs.size() && m_sTextLastestInputsIndex > 0) + return m_sTextLastestInputs[m_sTextLastestInputs.size() - m_sTextLastestInputsIndex]; + m_sTextLastestInputsIndex = m_sTextLastestInputs.size(); + return m_sTextLastestInputs[m_sTextLastestInputs.size() - m_sTextLastestInputsIndex]; +} + +RString ScreenNetSelectBase::GetNextMsg() +{ + m_sTextLastestInputsIndex -= 1; + if (m_sTextLastestInputsIndex < m_sTextLastestInputs.size() && m_sTextLastestInputsIndex > 0) + return m_sTextLastestInputs[m_sTextLastestInputs.size() - m_sTextLastestInputsIndex]; + m_sTextLastestInputsIndex = 0; + return ""; +} +void ScreenNetSelectBase::ShowPreviousMsg() +{ + SetInputText(GetPreviousMsg()); + return; +} +void ScreenNetSelectBase::ShowNextMsg() +{ + SetInputText(GetNextMsg()); + return; +} +void ScreenNetSelectBase::SetInputText(RString text) +{ + m_sTextInput = text; + UpdateTextInput(); + return; +} /** ColorBitmapText ***********************************************************/ void ColorBitmapText::SetText( const RString& _sText, const RString& _sAlternateText, int iWrapWidthPixels ) { @@ -331,10 +400,192 @@ void ColorBitmapText::SetText( const RString& _sText, const RString& _sAlternate if( iLineWidth > 0 ) SimpleAddLine( sCurrentLine, iLineWidth ); + lines = m_wTextLines.size(); + BuildChars(); UpdateBaseZoom(); } +void ColorBitmapText::ResetText() +{ + ASSERT(m_pFont != NULL); + + int iWrapWidthPixels = m_iWrapWidthPixels; + + // Set up the first color. + m_vColors.clear(); + ColorChange change; + change.c = RageColor(1, 1, 1, 1); + change.l = 0; + m_vColors.push_back(change); + + m_wTextLines.clear(); + + RString sCurrentLine = ""; + int iLineWidth = 0; + + RString sCurrentWord = ""; + int iWordWidth = 0; + int iGlyphsSoFar = 0; + + for (unsigned i = 0; i < m_sText.length(); i++) + { + int iCharsLeft = m_sText.length() - i - 1; + + // First: Check for the special (color) case. + + if (m_sText.length() > 8 && i < m_sText.length() - 9) + { + RString FirstThree = m_sText.substr(i, 3); + if (FirstThree.CompareNoCase("|c0") == 0 && iCharsLeft > 8) + { + ColorChange cChange; + unsigned int r, g, b; + sscanf(m_sText.substr(i, 9).c_str(), "|%*c0%2x%2x%2x", &r, &g, &b); + cChange.c = RageColor(r / 255.f, g / 255.f, b / 255.f, 1.f); + cChange.l = iGlyphsSoFar; + if (iGlyphsSoFar == 0) + m_vColors[0] = cChange; + else + m_vColors.push_back(cChange); + i += 8; + continue; + } + } + + int iCharLength = min(utf8_get_char_len(m_sText[i]), iCharsLeft + 1); + RString curCharStr = m_sText.substr(i, iCharLength); + wchar_t curChar = utf8_get_char(curCharStr); + i += iCharLength - 1; + int iCharWidth = m_pFont->GetLineWidthInSourcePixels(wstring() + curChar); + + switch (curChar) + { + case L' ': + if ( /* iLineWidth == 0 &&*/ iWordWidth == 0) + break; + sCurrentLine += sCurrentWord + " "; + iLineWidth += iWordWidth + iCharWidth; + sCurrentWord = ""; + iWordWidth = 0; + iGlyphsSoFar++; + break; + case L'\n': + if (iLineWidth + iWordWidth > iWrapWidthPixels) + { + SimpleAddLine(sCurrentLine, iLineWidth); + if (iWordWidth > 0) + iLineWidth = iWordWidth + //Add the width of a space + m_pFont->GetLineWidthInSourcePixels(L" "); + sCurrentLine = sCurrentWord + " "; + iWordWidth = 0; + sCurrentWord = ""; + iGlyphsSoFar++; + } + else + { + SimpleAddLine(sCurrentLine + sCurrentWord, iLineWidth + iWordWidth); + sCurrentLine = ""; iLineWidth = 0; + sCurrentWord = ""; iWordWidth = 0; + } + break; + default: + if (iWordWidth + iCharWidth > iWrapWidthPixels && iLineWidth == 0) + { + SimpleAddLine(sCurrentWord, iWordWidth); + sCurrentWord = curCharStr; iWordWidth = iCharWidth; + } + else if (iWordWidth + iLineWidth + iCharWidth > iWrapWidthPixels) + { + SimpleAddLine(sCurrentLine, iLineWidth); + sCurrentLine = ""; + iLineWidth = 0; + sCurrentWord += curCharStr; + iWordWidth += iCharWidth; + } + else + { + sCurrentWord += curCharStr; + iWordWidth += iCharWidth; + } + iGlyphsSoFar++; + break; + } + } + + if (iWordWidth > 0) + { + sCurrentLine += sCurrentWord; + iLineWidth += iWordWidth; + } + + if (iLineWidth > 0) + SimpleAddLine(sCurrentLine, iLineWidth); + lines = m_wTextLines.size(); + BuildChars(); + UpdateBaseZoom(); +} + +void ColorBitmapText::SetMaxLines(int iNumLines, int iDirection, unsigned int &scroll) +{ + iNumLines = max(0, iNumLines); + iNumLines = min((int)m_wTextLines.size(), iNumLines); + if (iDirection == 0) + { + // Crop all bottom lines + m_wTextLines.resize(iNumLines); + m_iLineWidths.resize(iNumLines); + } + else + { + // Because colors are relative to the beginning, we have to crop them back + unsigned shift = 0; + if (scroll > m_iLineWidths.size() - iNumLines) + scroll = m_iLineWidths.size() - iNumLines; + + for (unsigned i = 0; i < m_wTextLines.size() - iNumLines - scroll; i++) + shift += m_wTextLines[i].length(); + + // When we're cutting out text, we need to maintain the last + // color, so our text at the top doesn't become colorless. + RageColor LastColor; + + for (unsigned i = 0; i < m_vColors.size(); i++) + { + m_vColors[i].l -= shift; + if (m_vColors[i].l < 0) + { + LastColor = m_vColors[i].c; + m_vColors.erase(m_vColors.begin() + i); + i--; + } + } + + // If we already have a color set for the first char + // do not override it. + if (m_vColors.size() > 0 && m_vColors[0].l > 0) + { + ColorChange tmp; + tmp.c = LastColor; + tmp.l = 0; + m_vColors.insert(m_vColors.begin(), tmp); + } + + if (scroll == 0 || m_iLineWidths.size() <= iNumLines || scroll > m_iLineWidths.size() - iNumLines) { + m_wTextLines.erase(m_wTextLines.begin(), m_wTextLines.end() - iNumLines); + m_iLineWidths.erase(m_iLineWidths.begin(), m_iLineWidths.end() - iNumLines); + } + else { + m_wTextLines.erase(m_wTextLines.begin(), m_wTextLines.end() - iNumLines - scroll); + m_iLineWidths.erase(m_iLineWidths.begin(), m_iLineWidths.end() - iNumLines - scroll); + + m_wTextLines.erase(m_wTextLines.end() - scroll, m_wTextLines.end()); + m_iLineWidths.erase(m_iLineWidths.begin(), m_iLineWidths.end()); + } + } + BuildChars(); +} + void ColorBitmapText::SimpleAddLine( const RString &sAddition, const int iWidthPixels) { m_wTextLines.push_back( RStringToWstring( sAddition ) ); @@ -528,6 +779,26 @@ class LunaScreenNetSelectBase : public Luna lua_pushnumber(L, 0); return 1; } + static int ScrollChatUp(T* p, lua_State *L) + { + p->Scroll(1); + return 1; + } + static int ScrollChatDown(T* p, lua_State *L) + { + p->Scroll(-1); + return 1; + } + static int ShowNextMsg(T* p, lua_State *L) + { + p->ShowNextMsg(); + return 1; + } + static int ShowPreviousMsg(T* p, lua_State *L) + { + p->ShowPreviousMsg(); + return 1; + } public: LunaScreenNetSelectBase() { @@ -540,6 +811,10 @@ class LunaScreenNetSelectBase : public Luna ADD_METHOD(GetFriendQty); ADD_METHOD(GetFriendState); ADD_METHOD(GetFriendName); + ADD_METHOD(ScrollChatUp); + ADD_METHOD(ScrollChatDown); + ADD_METHOD(ShowNextMsg); + ADD_METHOD(ShowPreviousMsg); } }; diff --git a/src/ScreenNetSelectBase.h b/src/ScreenNetSelectBase.h index 5333ca0b1d..404d898a38 100644 --- a/src/ScreenNetSelectBase.h +++ b/src/ScreenNetSelectBase.h @@ -14,7 +14,10 @@ class ColorBitmapText : public BitmapText { public: void SetText( const RString &sText, const RString &sAlternateText = "", int iWrapWidthPixels = -1 ); + void ResetText(); void DrawPrimitives(); + int lines=0; + void SetMaxLines(int iNumLines, int iDirection, unsigned int &scroll); void SetMaxLines( int iLines, bool bCutBottom = true ); //if bCutBottom = false then, it will crop the top void SimpleAddLine( const RString &sAddition, int iWidthPixels ); void SetMaxLines( int iNumLines, int iDirection ); @@ -45,6 +48,12 @@ class ScreenNetSelectBase : public ScreenWithMenuElements void SetChatboxVisible(bool visibility); void SetUsersVisible(bool visibility); vector* ToUsers(); + void Scroll(int movescroll); + RString GetPreviousMsg(); + RString GetNextMsg(); + void SetInputText(RString text); + void ShowPreviousMsg(); + void ShowNextMsg(); // Lua virtual void PushSelf(lua_State *L); private: @@ -54,6 +63,9 @@ class ScreenNetSelectBase : public ScreenWithMenuElements AutoActor m_sprChatInputBox; AutoActor m_sprChatOutputBox; RString m_sTextInput; + unsigned int m_sTextLastestInputsIndex; + vector m_sTextLastestInputs; + unsigned int scroll; RString m_actualText; vector m_textUsers;