diff --git a/modules/client_entergame/characterlist.lua b/modules/client_entergame/characterlist.lua index a48a0e75..edc533aa 100644 --- a/modules/client_entergame/characterlist.lua +++ b/modules/client_entergame/characterlist.lua @@ -78,7 +78,7 @@ local function resendWait() end if charactersWindow then - local selected = charactersWindow:getChildById('characterList'):getFocusedChild() + local selected = characterList:getFocusedChild() if selected then local charInfo = { worldHost = selected.worldHost, worldPort = selected.worldPort, @@ -101,19 +101,6 @@ local function onLoginWait(message, time) resendWaitEvent = scheduleEvent(resendWait, time * 1000) end -local function onCharactersWindowKeyPress(self, keyCode, keyboardModifiers) - if keyboardModifiers == KeyboardNoModifier then - if keyCode == KeyUp then - characterList:focusPreviousChild(KeyboardFocusReason) - return true - elseif keyCode == KeyDown or keyCode == KeyTab then - characterList:focusNextChild(KeyboardFocusReason) - return true - end - end - return false -end - function onGameLoginError(message) CharacterList.destroyLoadBox() errorBox = displayErrorBox(tr("Login Error"), message) @@ -134,10 +121,6 @@ end -- public functions function CharacterList.init() - charactersWindow = g_ui.displayUI('characterlist.otui') - charactersWindow:hide() - characterList = charactersWindow:getChildById('characterList') - charactersWindow.onKeyPress = onCharactersWindowKeyPress connect(g_game, { onLoginError = onGameLoginError }) connect(g_game, { onConnectionError = onGameConnectionError }) connect(g_game, { onGameStart = CharacterList.destroyLoadBox }) @@ -145,7 +128,7 @@ function CharacterList.init() connect(g_game, { onGameEnd = CharacterList.showAgain }) if G.characters then - CharacterList.create(G.characters, G.premDays) + CharacterList.create(G.characters, G.characterAccount) end end @@ -155,9 +138,8 @@ function CharacterList.terminate() disconnect(g_game, { onGameStart = CharacterList.destroyLoadBox }) disconnect(g_game, { onLoginWait = onLoginWait }) disconnect(g_game, { onGameEnd = CharacterList.showAgain }) - characterList = nil - charactersWindow:destroy() - charactersWindow = nil + CharacterList.destroy() + if loadBox then g_game.cancelLogin() loadBox:destroy() @@ -182,36 +164,54 @@ function CharacterList.terminate() CharacterList = nil end -function CharacterList.create(characters, account) +function CharacterList.create(characters, account, otui) + if not otui then otui = 'characterlist.otui' end + + charactersWindow = g_ui.displayUI(otui) + characterList = charactersWindow:getChildById('characters') + + -- characters G.characters = characters - G.premDays = account.premDays + G.characterAccount = account characterList:destroyChildren() local accountStatusLabel = charactersWindow:getChildById('accountStatusLabel') local focusLabel for i,characterInfo in ipairs(characters) do - local characterName = characterInfo.name - local worldName = characterInfo.worldName - local worldHost = characterInfo.worldIp - local worldPort = characterInfo.worldPort + local widget = g_ui.createWidget('CharacterWidget', characterList) + for key,value in pairs(characterInfo) do + local subWidget = widget:getChildById(key) + if subWidget then + if key == 'outfit' then -- it's an exception + subWidget:setOutfit(value) + else + local text = value + if subWidget.baseText and subWidget.baseTranslate then + text = tr(subWidget.baseText, text) + elseif subWidget.baseText then + text = string.format(subWidget.baseText, text) + end + subWidget:setText(text) + end + end + end - local label = g_ui.createWidget('CharacterListLabel', characterList) - label:setText(characterName .. ' (' .. worldName .. ')') - label:setPhantom(false) - label.characterName = characterName - label.worldHost = worldHost - label.worldPort = worldPort + -- these are used by login + widget.characterName = characterInfo.name + widget.worldHost = characterInfo.worldIp + widget.worldPort = characterInfo.worldPort - connect(label, { onDoubleClick = function () CharacterList.doLogin() return true end } ) + connect(widget, { onDoubleClick = function () CharacterList.doLogin() return true end } ) if i == 1 or g_settings.get('lastUsedCharacter') == characterName then - focusLabel = label + focusLabel = widget end end characterList:focusChild(focusLabel, ActiveFocusReason) + -- account if account.premDays > 0 then accountStatusLabel:setText(tr("Account Status:\nPremium Account (%s) days left", account.premDays)) else @@ -219,13 +219,14 @@ function CharacterList.create(characters, account) end end -function CharacterList.hide() - charactersWindow:hide() -end - function CharacterList.destroy() - CharacterList.hide() - if not g_game.isOnline() then + if charactersWindow then + characterList = nil + charactersWindow:destroy() + charactersWindow = nil + end + + if EnterGame and not g_game.isOnline() then EnterGame.show() end end @@ -238,6 +239,10 @@ function CharacterList.show() end end +function CharacterList.hide() + charactersWindow:hide() +end + function CharacterList.showAgain() if characterList:hasChildren() then CharacterList.show() @@ -252,7 +257,7 @@ function CharacterList.isVisible() end function CharacterList.doLogin() - local selected = charactersWindow:getChildById('characterList'):getFocusedChild() + local selected = characterList:getFocusedChild() if selected then local charInfo = { worldHost = selected.worldHost, worldPort = selected.worldPort, diff --git a/modules/client_entergame/characterlist.otui b/modules/client_entergame/characterlist.otui index 707d6df1..4f3a4d35 100644 --- a/modules/client_entergame/characterlist.otui +++ b/modules/client_entergame/characterlist.otui @@ -1,22 +1,45 @@ -CharacterListLabel < Label - font: verdana-11px-monochrome - background-color: alpha - text-offset: 2 0 +CharacterWidget < UIWidget + height: 14 focusable: true + background-color: alpha $focus: background-color: #ffffff22 + + Label + id: name color: #ffffff + anchors.top: parent.top + anchors.left: parent.left + font: verdana-11px-monochrome + text-auto-resize: true + background-color: alpha + text-offset: 2 0 + + Label + id: worldName + color: #ffffff + anchors.top: parent.top + anchors.right: parent.right + margin-right: 5 + font: verdana-11px-monochrome + text-auto-resize: true + background-color: alpha + &baseText: '(%s)' MainWindow id: charactersWindow !text: tr('Character List') size: 250 248 + visible: false @onEnter: CharacterList.doLogin() @onEscape: CharacterList.destroy() + @onSetup: | + g_keyboard.bindKeyPress('Up', function() self:getChildById('characters'):focusPreviousChild(KeyboardFocusReason) end, self) + g_keyboard.bindKeyPress('Down', function() self:getChildById('characters'):focusNextChild(KeyboardFocusReason) end, self) TextList - id: characterList + id: characters anchors.top: parent.top anchors.left: parent.left anchors.right: characterListScrollBar.left diff --git a/modules/client_entergame/entergame.lua b/modules/client_entergame/entergame.lua index 605c9118..65d25b93 100644 --- a/modules/client_entergame/entergame.lua +++ b/modules/client_entergame/entergame.lua @@ -28,7 +28,7 @@ local function onMotd(protocol, motd) motdButton:show() end -local function onCharacterList(protocol, characters, account) +local function onCharacterList(protocol, characters, account, otui) if enterGame:getChildById('rememberPasswordBox'):isChecked() then g_settings.set('account', g_crypt.encrypt(G.account)) g_settings.set('password', g_crypt.encrypt(G.password)) @@ -40,7 +40,7 @@ local function onCharacterList(protocol, characters, account) loadBox:destroy() loadBox = nil - CharacterList.create(characters, account) + CharacterList.create(characters, account, otui) CharacterList.show() local lastMotdNumber = g_settings.getNumber("motd") diff --git a/modules/client_locales/locales/pt.lua b/modules/client_locales/locales/pt.lua index 1979c6ce..d5b09df3 100644 --- a/modules/client_locales/locales/pt.lua +++ b/modules/client_locales/locales/pt.lua @@ -86,6 +86,7 @@ locale = { ["Copy message"] = "Copiar mensagem", ["Copy name"] = "Copiar nome", ["Copy Name"] = "Copiar Nome", + ["Create"] = "Criar", ["Create New Offer"] = "Criar nova oferta", ["Create Offer"] = "Criar oferta", ["Current hotkeys:"] = "Atalhos atuais", @@ -310,6 +311,7 @@ locale = { ["Weight:"] = "Peso", ["Will detect when to use diagonal step based on the\nkeys you are pressing"] = "Detectar quando usar o passo diagonal\nbaseado nas teclas pressionadas", ["With crosshair"] = "Com mira", + ["World"] = "Mundo", ["Yes"] = "Sim", ["You are bleeding"] = "Você está sangrando", ["You are burning"] = "Você está queimando", diff --git a/modules/client_skins/skins/default/styles/listboxes.otui b/modules/client_skins/skins/default/styles/listboxes.otui index dc6e9b15..702a84a6 100644 --- a/modules/client_skins/skins/default/styles/listboxes.otui +++ b/modules/client_skins/skins/default/styles/listboxes.otui @@ -3,3 +3,9 @@ TextList < UIScrollArea border-width: 1 border-color: #1d222b background-color: #222833 + +HorizontalList < UIScrollArea + layout: horizontalBox + border-width: 1 + border-color: #1d222b + background-color: #222833 diff --git a/modules/corelib/ui/uiscrollarea.lua b/modules/corelib/ui/uiscrollarea.lua index baa7ca06..782e438d 100644 --- a/modules/corelib/ui/uiscrollarea.lua +++ b/modules/corelib/ui/uiscrollarea.lua @@ -47,7 +47,9 @@ function UIScrollArea:updateScrollBars() if scrollbar then if self.inverted then scrollbar:setMinimum(-scrollWidth) + scrollbar:setMaximum(0) else + scrollbar:setMinimum(0) scrollbar:setMaximum(scrollWidth) end end @@ -75,6 +77,11 @@ end function UIScrollArea:setHorizontalScrollBar(scrollbar) self.horizontalScrollBar = scrollbar + self.horizontalScrollBar.onValueChange = function(scrollbar, value) + local virtualOffset = self:getVirtualOffset() + virtualOffset.x = value + self:setVirtualOffset(virtualOffset) + end self:updateScrollBars() end @@ -97,6 +104,12 @@ function UIScrollArea:onMouseWheel(mousePos, mouseWheel) else self.verticalScrollBar:increment() end + elseif self.horizontalScrollBar then + if mouseWheel == MouseWheelUp then + self.horizontalScrollBar:increment() + else + self.horizontalScrollBar:decrement() + end end return true end @@ -104,14 +117,26 @@ end function UIScrollArea:onChildFocusChange(focusedChild, oldFocused, reason) if focusedChild and (reason == MouseFocusReason or reason == KeyboardFocusReason) then local paddingRect = self:getPaddingRect() - local delta = paddingRect.y - focusedChild:getY() - if delta > 0 then - self.verticalScrollBar:decrement(delta) - end + if self.verticalScrollBar then + local deltaY = paddingRect.y - focusedChild:getY() + if deltaY > 0 then + self.verticalScrollBar:decrement(deltaY) + end - delta = (focusedChild:getY() + focusedChild:getHeight()) - (paddingRect.y + paddingRect.height) - if delta > 0 then - self.verticalScrollBar:increment(delta) + deltaY = (focusedChild:getY() + focusedChild:getHeight()) - (paddingRect.y + paddingRect.height) + if deltaY > 0 then + self.verticalScrollBar:increment(deltaY) + end + else + local deltaX = paddingRect.x - focusedChild:getX() + if deltaX > 0 then + self.horizontalScrollBar:decrement(deltaX) + end + + deltaX = (focusedChild:getX() + focusedChild:getWidth()) - (paddingRect.x + paddingRect.width) + if deltaX > 0 then + self.horizontalScrollBar:increment(deltaX) + end end end end diff --git a/modules/corelib/ui/uiscrollbar.lua b/modules/corelib/ui/uiscrollbar.lua index ca9f8d87..8f732593 100644 --- a/modules/corelib/ui/uiscrollbar.lua +++ b/modules/corelib/ui/uiscrollbar.lua @@ -15,7 +15,7 @@ local function calcValues(self) else -- horizontal pxrange = (self:getWidth() - decrementButton:getWidth() - decrementButton:getMarginLeft() - decrementButton:getMarginRight() - incrementButton:getWidth() - incrementButton:getMarginLeft() - incrementButton:getMarginRight()) - center = self:getX() + self:getWidth() / 2 + center = self:getX() + math.floor(self:getWidth() / 2) end local range = self.maximum - self.minimum + 1 @@ -83,6 +83,7 @@ local function parseSliderPos(self, pos) offset = math.min(math.max(point - center, -pxrange/2), pxrange/2) local newvalue = math.floor(((offset / (pxrange - px)) + 0.5) * (range - 1)) + self.minimum self:setValue(newvalue) + -- this function must be reworked, scroll is not that good based on center end diff --git a/modules/gamelib/protocollogin.lua b/modules/gamelib/protocollogin.lua index 916d661d..6d67498e 100644 --- a/modules/gamelib/protocollogin.lua +++ b/modules/gamelib/protocollogin.lua @@ -123,7 +123,8 @@ end function ProtocolLogin:parseExtendedCharacterList(msg) local characters = msg:getTable() local account = msg:getTable() - signalcall(self.onCharacterList, self, characters, account) + local otui = msg:getString() + signalcall(self.onCharacterList, self, characters, account, otui) end function ProtocolLogin:parseOpcode(opcode, msg) diff --git a/src/framework/ui/uiwidgetbasestyle.cpp b/src/framework/ui/uiwidgetbasestyle.cpp index f7af9982..6a7af66a 100644 --- a/src/framework/ui/uiwidgetbasestyle.cpp +++ b/src/framework/ui/uiwidgetbasestyle.cpp @@ -130,7 +130,7 @@ void UIWidget::parseBaseStyle(const OTMLNodePtr& styleNode) setBorderWidth(stdext::safe_cast(split[0])); setBorderColor(stdext::safe_cast(split[1])); } else - throw OTMLException(node, "border param must have its width followed by its color"); + throw OTMLException(node, "border param must have its width followed by its color"); } else if(node->tag() == "border-width") setBorderWidth(node->value()); diff --git a/src/otclient/luafunctions.cpp b/src/otclient/luafunctions.cpp index 626f14e9..23a319a2 100644 --- a/src/otclient/luafunctions.cpp +++ b/src/otclient/luafunctions.cpp @@ -462,6 +462,7 @@ void OTClient::registerLuaFunctions() g_lua.registerClass(); g_lua.bindClassStaticFunction("create", []{ return UICreaturePtr(new UICreature); } ); g_lua.bindClassMemberFunction("setCreature", &UICreature::setCreature); + g_lua.bindClassMemberFunction("setOutfit", &UICreature::setOutfit); g_lua.bindClassMemberFunction("setFixedCreatureSize", &UICreature::setFixedCreatureSize); g_lua.bindClassMemberFunction("getCreature", &UICreature::getCreature); g_lua.bindClassMemberFunction("isFixedCreatureSize", &UICreature::isFixedCreatureSize); diff --git a/src/otclient/uicreature.cpp b/src/otclient/uicreature.cpp index 405c054b..26c2a2eb 100644 --- a/src/otclient/uicreature.cpp +++ b/src/otclient/uicreature.cpp @@ -38,6 +38,14 @@ void UICreature::drawSelf(Fw::DrawPane drawPane) } } +void UICreature::setOutfit(const Outfit& outfit) +{ + if(!m_creature) + m_creature = CreaturePtr(new Creature); + m_creature->setDirection(Otc::South); + m_creature->setOutfit(outfit); +} + void UICreature::onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode) { UIWidget::onStyleApply(styleName, styleNode); diff --git a/src/otclient/uicreature.h b/src/otclient/uicreature.h index 98813b01..b8fe04a3 100644 --- a/src/otclient/uicreature.h +++ b/src/otclient/uicreature.h @@ -34,6 +34,7 @@ public: void setCreature(const CreaturePtr& creature) { m_creature = creature; } void setFixedCreatureSize(bool fixed) { m_fixedCreatureSize = fixed; } + void setOutfit(const Outfit& outfit); CreaturePtr getCreature() { return m_creature; } bool isFixedCreatureSize() { return m_fixedCreatureSize; }