diff --git a/TODO b/TODO index 1555507c..d893ffbe 100644 --- a/TODO +++ b/TODO @@ -25,7 +25,7 @@ setOnClose review and reenable some warnings make lua/c++ logger more friendly bind every global lua function in a static class -use metatable for Point,Rect,Color,Size lua classes +use metatable for lua classes set special types for g_configs like lists/point/size create a class for reading binary files handle corrupt errors in dat/spr @@ -38,7 +38,10 @@ use indices in CoordsBuffer move UICheckBox to lua move UIWindow to lua +create UIMessageBox, UIToolTip and UIInputBox rework UI image style class UIImage and UIText add UI border -fix style inheretance using a style translator \ No newline at end of file +fix style inheretance using a style translator + +make possible to bind non LuaObject derived classes on lua engine (for usage with Point,Rect,Color,Size) \ No newline at end of file diff --git a/modules/addon_mapeffects/mapeffects.lua b/modules/addon_mapeffects/mapeffects.lua new file mode 100644 index 00000000..e6c9fced --- /dev/null +++ b/modules/addon_mapeffects/mapeffects.lua @@ -0,0 +1,14 @@ +MapEffects = {} + +function MapEffects.init() + local box = createWidget('ComboBox') + box:moveTo({x=100, y=8}) + box:addOption('Normal') + box:addOption('Bloom') + box:addOption('TV') + --displayUI(box) +end + +function MapEffects.terminate() + +end diff --git a/modules/addon_mapeffects/mapeffects.otmod b/modules/addon_mapeffects/mapeffects.otmod new file mode 100644 index 00000000..90172be6 --- /dev/null +++ b/modules/addon_mapeffects/mapeffects.otmod @@ -0,0 +1,16 @@ +Module + name: mapeffects + description: Contains experimental shader effects for map + author: OTClient team + website: https://github.com/edubart/otclient + + // console can be loaded after core + autoLoad: true + autoLoadPriority: 1000 + + onLoad: | + require 'mapeffects' + MapEffects.init() + + onUnload: | + MapEffects.terminate() diff --git a/modules/client/client.lua b/modules/client/client.lua index c6577c83..816b61c1 100644 --- a/modules/client/client.lua +++ b/modules/client/client.lua @@ -2,6 +2,7 @@ Client = {} -- TODO: load and save configurations function Client.init() + -- set default settings g_window.show() g_window.setMinimumSize({ width = 550, height = 450 }) @@ -9,14 +10,21 @@ function Client.init() if g_window.getPlatformType() == "X11-EGL" then g_window.setFullscreen(true) else - local size = { width = 1024, - height = 768 } + -- window size + local size = { width = 800, height = 600 } + size = Settings.getSize('window-size', size) g_window.resize(size) + -- window position, default is the screen center local displaySize = g_window.getDisplaySize() local pos = { x = (displaySize.width - size.width)/2, y = (displaySize.height - size.height)/2 } + pos = Settings.getPoint('window-pos', size) g_window.move(pos) + + -- window maximized? + local maximized = Settings.getBoolean('window-maximized', false) + if maximized then g_window.maximize() end end g_window.setTitle('OTClient') @@ -28,4 +36,7 @@ function Client.init() end function Client.terminate() + Settings.set('window-size', g_window.getUnmaximizedSize()) + Settings.set('window-pos', g_window.getUnmaximizedPos()) + Settings.set('window-maximized', g_window.isMaximized()) end diff --git a/modules/client_entergame/entergame.otui b/modules/client_entergame/entergame.otui index f07f2525..a811fad1 100644 --- a/modules/client_entergame/entergame.otui +++ b/modules/client_entergame/entergame.otui @@ -78,10 +78,7 @@ MainWindow margin-top: 10 margin-left: 18 margin-right: 18 - @onCheckChange: | - function(self, checked) - self:getParent():getChildById('autoLoginBox'):setEnabled(checked) - end + @onCheckChange: self:getParent():getChildById('autoLoginBox'):setEnabled(self:isChecked()) CheckBox id: autoLoginBox diff --git a/modules/client_options/options.lua b/modules/client_options/options.lua index 42f11087..14b164d9 100644 --- a/modules/client_options/options.lua +++ b/modules/client_options/options.lua @@ -1,72 +1,34 @@ Options = {} --- private variables -local options -local fpsEnabled = false -local vsyncEnabled = false +-- public functions +function Options.load() + -- set default settings + Settings.setDefault('vsync', true) + Settings.setDefault('showfps', true) + + -- load the options + Options.enableVsync(Settings.getBoolean('vsync')) + Options.enableFps(Settings.getBoolean('showfps')) +end -function getConfig(name, default) - if g_configs.exists(name) then - local val = g_configs.get(name):trim() - if val == 'true' or val == 'false' then - return toboolean(val) - else - return val - end - else - if default ~= nil then - g_configs.set(name, default) - return default - else - return nil - end - end +function Options.show() + displayUI('options.otui', { locked = true }) end -function setConfig(name, value) - g_configs.set(name, tostring(value)) +function Options.openWebpage() + displayErrorBox("Error", "Not implemented yet") end -- private functions function Options.enableVsync(on) - vsyncEnabled = on g_window.setVerticalSync(on) - setConfig('vsync', on) + Settings.set('vsync', on) + Options.vsync = on end function Options.enableFps(on) - fpsEnabled = on local frameCounter = rootWidget:recursiveGetChildById('frameCounter') frameCounter:setVisible(on) - setConfig('showfps', on) -end - --- public functions -function Options.create() - options = displayUI('options.otui', { locked = true }) - - local fpsBox = options:getChildById('fpsCheckBox') - local vsyncBox = options:getChildById('vsyncCheckBox') - - fpsBox:setChecked(fpsEnabled) - vsyncBox:setChecked(vsyncEnabled) - - fpsBox.onCheckChange = function(self, checked) Options.enableFps(checked) end - vsyncBox.onCheckChange = function(self, checked) Options.enableVsync(checked) end -end - -function Options.load() - Options.enableVsync(getConfig('vsync', true)) - Options.enableFps(getConfig('showfps', true)) -end - -function Options.destroy() - options:destroy() - options = nil + Settings.set('showfps', on) + Options.fps = on end - -function Options.openWebpage() - displayErrorBox("Error", "Not implemented yet") -end - -addEvent(Options.load) \ No newline at end of file diff --git a/modules/client_options/options.otmod b/modules/client_options/options.otmod index 7e434931..542df62d 100644 --- a/modules/client_options/options.otmod +++ b/modules/client_options/options.otmod @@ -6,3 +6,5 @@ Module onLoad: | require 'options' + Options.load() + diff --git a/modules/client_options/options.otui b/modules/client_options/options.otui index abd2697d..8e57ad36 100644 --- a/modules/client_options/options.otui +++ b/modules/client_options/options.otui @@ -13,6 +13,8 @@ MainWindow margin-top: 28 margin-left: 18 margin-right: 18 + @onCheckChange: Options.enableVsync(self:isChecked()) + @onSetup: self:setChecked(Options.vsync) CheckBox id: fpsCheckBox @@ -23,6 +25,8 @@ MainWindow margin-top: 10 margin-left: 18 margin-right: 18 + @onCheckChange: Options.enableFps(self:isChecked()) + @onSetup: self:setChecked(Options.fps) Button text: Ok @@ -31,4 +35,4 @@ MainWindow anchors.bottom: parent.bottom margin-right: 10 margin-bottom: 10 - @onClick: Options.destroy() \ No newline at end of file + @onClick: self:getParent():destroy() \ No newline at end of file diff --git a/modules/client_topmenu/topmenu.otui b/modules/client_topmenu/topmenu.otui index 729ed44a..2ae1c173 100644 --- a/modules/client_topmenu/topmenu.otui +++ b/modules/client_topmenu/topmenu.otui @@ -13,7 +13,7 @@ TopPanel margin-left: 6 tooltip: Options icon: /core_styles/icons/settings.png - @onClick: Options.create() + @onClick: Options.show() TopButton diff --git a/modules/core_lib/core_lib.otmod b/modules/core_lib/core_lib.otmod index 9eea1d17..5bd5cd40 100644 --- a/modules/core_lib/core_lib.otmod +++ b/modules/core_lib/core_lib.otmod @@ -15,6 +15,5 @@ Module require 'util' require 'globals' require 'dispatcher' - require 'widget' require 'effects' require 'settings' diff --git a/modules/core_lib/dispatcher.lua b/modules/core_lib/dispatcher.lua index ee13f5a0..0f323c74 100644 --- a/modules/core_lib/dispatcher.lua +++ b/modules/core_lib/dispatcher.lua @@ -2,6 +2,7 @@ local eventId = 0 local eventList = {} function scheduleEvent(func, delay) + if not func then return end eventId = eventId + 1 local id = eventId local function proxyFunc() diff --git a/modules/core_lib/settings.lua b/modules/core_lib/settings.lua new file mode 100644 index 00000000..d34e07d1 --- /dev/null +++ b/modules/core_lib/settings.lua @@ -0,0 +1,79 @@ +Settings = {} + +local function convertSettingValue(value) + if type(value) == 'table' then + if value.x and value.width then + return recttostring(value) + elseif value.x then + return pointtostring(value) + elseif value.width then + return sizetostring(value) + elseif value.r then + return colortostring(value) + end + else + return tostring(value) + end +end + +function Settings.exists(key) + return g_configs.exists(key) +end + +function Settings.remove(key) + g_configs.remove(key) +end + +function Settings.set(key, value) + g_configs.set(key, convertSettingValue(value)) +end + +function Settings.setDefault(key, value) + if Settings.exists(key) then return false end + Settings.set(key, value) + return true +end + +function Settings.get(key, default) + if Settings.exists(key) then + elseif default ~= nil then + Settings.set(key, default) + end + return g_configs.get(key) +end + +function Settings.getString(key, default) + return Settings.get(key, default) +end + +function Settings.getInteger(key, default) + return tonumber(Settings.get(key, default)) +end + +function Settings.getNumber(key, default) + return tonumber(Settings.get(key, default)) +end + +function Settings.getBoolean(key, default) + return toboolean(Settings.get(key, default)) +end + +function Settings.getPoint(key, default) + return topoint(Settings.get(key, default)) +end + +function Settings.getRect(key, default) + return torect(Settings.get(key, default)) +end + +function Settings.getSize(key, default) + return tosize(Settings.get(key, default)) +end + +function Settings.getColor(key, default) + return tocolor(Settings.get(key, default)) +end + +function Settings.getColor(key, default) + return tocolor(Settings.get(key, default)) +end diff --git a/modules/core_widgets/core_widgets.otmod b/modules/core_widgets/core_widgets.otmod index 6f1dc31d..7a6b2250 100644 --- a/modules/core_widgets/core_widgets.otmod +++ b/modules/core_widgets/core_widgets.otmod @@ -7,6 +7,7 @@ Module onLoad: | require 'tooltip/tooltip' require 'messagebox/messagebox' + require 'uiwidget' require 'uibutton' require 'uilabel' require 'uicombobox' diff --git a/modules/core_widgets/uipopupmenu.lua b/modules/core_widgets/uipopupmenu.lua index 8b51053d..1a676ac9 100644 --- a/modules/core_widgets/uipopupmenu.lua +++ b/modules/core_widgets/uipopupmenu.lua @@ -45,7 +45,7 @@ function UIPopupMenu:onDestroy() end function UIPopupMenu:onMousePress(mousePos, mouseButton) - -- clicks outside self area destroys the self + -- clicks outside menu area destroys the menu if not self:containsPoint(mousePos) then self:destroy() return true @@ -61,11 +61,10 @@ function UIPopupMenu:onKeyPress(keyCode, keyText, keyboardModifiers) return false end -local function onRootGeometryUpdate() -- close all menus when the window is resized +local function onRootGeometryUpdate() for i,menu in ipairs(displayedMenuList) do menu:destroy() end end - connect(rootWidget, { onGeometryChange = onRootGeometryUpdate} ) diff --git a/modules/core_lib/widget.lua b/modules/core_widgets/uiwidget.lua similarity index 100% rename from modules/core_lib/widget.lua rename to modules/core_widgets/uiwidget.lua diff --git a/modules/game_skills/skills.lua b/modules/game_skills/skills.lua index b2db37b1..153a1a6b 100644 --- a/modules/game_skills/skills.lua +++ b/modules/game_skills/skills.lua @@ -19,7 +19,7 @@ end local function setSkillValue(id, value) local skill = skillWindow:recursiveGetChildById(id) - + if skill then local widget = skill:getChildById('value') widget:setText(value) @@ -28,11 +28,11 @@ end local function setSkillPercent(id, percent, tooltip) local skill = skillWindow:recursiveGetChildById(id) - + if skill then local widget = skill:getChildById('percent') widget:setPercent(percent) - + if tooltip then widget:setTooltip(tooltip) end @@ -49,6 +49,19 @@ function Skills.destroy() skillWindow = nil end +function Skills.onSkillButtonClick(button) + local percentBar = button:getChildById('percent') + if percentBar then + percentBar:setVisible(not percentBar:isVisible()) + if percentBar:isVisible() then + button:setHeight(21) + else + button:setHeight(21 - 6) + end + button:updateParentLayout() + end +end + -- hooked events function Skills.onExperienceChange(value) setSkillValue('experience', getNumberString(value)) @@ -82,7 +95,7 @@ function Skills.onStaminaChange(stamina) minutes = '0' .. minutes end local percent = 100 * stamina / (42 * 60) -- max is 42 hours - + setSkillValue('stamina', hours .. ":" .. minutes) setSkillPercent('stamina', percent, 'You have ' .. percent .. ' percent') end diff --git a/modules/game_skills/skills.otui b/modules/game_skills/skills.otui index 4d0dadc4..39793cfd 100644 --- a/modules/game_skills/skills.otui +++ b/modules/game_skills/skills.otui @@ -5,20 +5,7 @@ SkillButton < UIButton margin-top: 3 margin-left: 10 margin-right: 10 - - @onClick: | - function(self) - local percentBar = self:getChildById('percent') - if percentBar then - percentBar:setVisible(not percentBar:isVisible()) - if percentBar:isVisible() then - self:setHeight(21) - else - self:setHeight(21 - 6) - end - self:updateParentLayout() - end - end + &onClick: Skills.onSkillButtonClick SkillNameLabel < GameLabel font: verdana-11px-monochrome diff --git a/src/framework/luafunctions.cpp b/src/framework/luafunctions.cpp index ca878208..dc4f6937 100644 --- a/src/framework/luafunctions.cpp +++ b/src/framework/luafunctions.cpp @@ -31,25 +31,17 @@ #include #include -class LuaRect : public LuaObject, public Rect { -public: - LuaRect() : TRect() { } -}; - void Application::registerLuaFunctions() { - // globals - g_lua.registerStaticClass("Rect"); - g_lua.bindClassStaticFunction("Rect", "create", []{ return std::shared_ptr(new LuaRect); }); - g_lua.bindClassMemberFunction("Rect", "resize", (void (Rect::*)(int,int)) &Rect::resize); - - /* - g_lua.bindGlobalFunction("torect", [](const std::string& str) { return Fw::unsafeCast(str); }); - g_lua.bindGlobalFunction("topoint", [](const std::string& str) { return Fw::unsafeCast(str); }); - g_lua.bindGlobalFunction("tocolor", [](const std::string& str) { return Fw::unsafeCast(str); }); - g_lua.bindGlobalFunction("tosize", [](const std::string& str) { return Fw::unsafeCast(str); }); - g_lua.bindGlobalFunction("toboolean", [](const std::string& str) { return Fw::unsafeCast(str); }); - */ + // conversion globals + g_lua.bindGlobalFunction("torect", [](const std::string& v) { return Fw::fromstring(v); }); + g_lua.bindGlobalFunction("topoint", [](const std::string& v) { return Fw::fromstring(v); }); + g_lua.bindGlobalFunction("tocolor", [](const std::string& v) { return Fw::fromstring(v); }); + g_lua.bindGlobalFunction("tosize", [](const std::string& v) { return Fw::fromstring(v); }); + g_lua.bindGlobalFunction("recttostring", [](const Rect& v) { return Fw::tostring(v); }); + g_lua.bindGlobalFunction("pointtostring", [](const Point& v) { return Fw::tostring(v); }); + g_lua.bindGlobalFunction("colortostring", [](const Color& v) { return Fw::tostring(v); }); + g_lua.bindGlobalFunction("sizetostring", [](const Size& v) { return Fw::tostring(v); }); // UIWidget g_lua.registerClass(); @@ -189,25 +181,25 @@ void Application::registerLuaFunctions() // UIVerticalLayout g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", &UIVerticalLayout::create); + g_lua.bindClassStaticFunction("create", [](UIWidgetPtr parent){ return UIVerticalLayoutPtr(new UIVerticalLayout(parent)); } ); g_lua.bindClassMemberFunction("setFitParent", &UIVerticalLayout::setFitParent); // UIAnchorLayout g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", &UIAnchorLayout::create); + g_lua.bindClassStaticFunction("create", [](UIWidgetPtr parent){ return UIAnchorLayoutPtr(new UIAnchorLayout(parent)); } ); g_lua.bindClassMemberFunction("removeAnchors", &UIAnchorLayout::removeAnchors); g_lua.bindClassMemberFunction("centerIn", &UIAnchorLayout::centerIn); g_lua.bindClassMemberFunction("fill", &UIAnchorLayout::fill); // UIProgressBar g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", &UIWidget::create); + g_lua.bindClassStaticFunction("create", []{ return UIProgressBarPtr(new UIProgressBar); } ); g_lua.bindClassMemberFunction("getPercent", &UIProgressBar::getPercent); g_lua.bindClassMemberFunction("setPercent", &UIProgressBar::setPercent); // UILineEdit g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", &UIWidget::create); + g_lua.bindClassStaticFunction("create", []{ return UILineEditPtr(new UILineEdit); } ); g_lua.bindClassMemberFunction("setTextHorizontalMargin", &UILineEdit::setTextHorizontalMargin); g_lua.bindClassMemberFunction("setCursorPos", &UILineEdit::setCursorPos); g_lua.bindClassMemberFunction("setCursorEnabled", &UILineEdit::setCursorEnabled); @@ -226,17 +218,17 @@ void Application::registerLuaFunctions() // UICheckBox g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", &UIWidget::create); + g_lua.bindClassStaticFunction("create", []{ return UICheckBoxPtr(new UICheckBox); } ); // UIWindow g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", &UIWidget::create); + g_lua.bindClassStaticFunction("create", []{ return UIWindowPtr(new UIWindow); } ); g_lua.bindClassMemberFunction("getTitle", &UIWindow::getTitle); g_lua.bindClassMemberFunction("setTitle", &UIWindow::setTitle); // UIFrameCounter g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", &UIWidget::create); + g_lua.bindClassStaticFunction("create", []{ return UIFrameCounterPtr(new UIFrameCounter); } ); g_lua.bindClassMemberFunction("getFrameCount", &UIFrameCounter::getFrameCount); // Protocol @@ -250,21 +242,38 @@ void Application::registerLuaFunctions() g_lua.registerStaticClass("g_window"); - g_lua.bindClassStaticFunction("g_window", "show", std::bind(&PlatformWindow::show, &g_window)); - g_lua.bindClassStaticFunction("g_window", "hide", std::bind(&PlatformWindow::hide, &g_window)); g_lua.bindClassStaticFunction("g_window", "move", std::bind(&PlatformWindow::move, &g_window, _1)); g_lua.bindClassStaticFunction("g_window", "resize", std::bind(&PlatformWindow::resize, &g_window, _1)); + g_lua.bindClassStaticFunction("g_window", "show", std::bind(&PlatformWindow::show, &g_window)); + g_lua.bindClassStaticFunction("g_window", "hide", std::bind(&PlatformWindow::hide, &g_window)); + g_lua.bindClassStaticFunction("g_window", "maximize", std::bind(&PlatformWindow::maximize, &g_window)); + g_lua.bindClassStaticFunction("g_window", "showMouse", std::bind(&PlatformWindow::showMouse, &g_window)); + g_lua.bindClassStaticFunction("g_window", "hideMouse", std::bind(&PlatformWindow::hideMouse, &g_window)); + g_lua.bindClassStaticFunction("g_window", "setTitle", std::bind(&PlatformWindow::setTitle, &g_window, _1)); g_lua.bindClassStaticFunction("g_window", "setMinimumSize", std::bind(&PlatformWindow::setMinimumSize, &g_window, _1)); - g_lua.bindClassStaticFunction("g_window", "setVerticalSync", std::bind(&PlatformWindow::setVerticalSync, &g_window, _1)); g_lua.bindClassStaticFunction("g_window", "setFullscreen", std::bind(&PlatformWindow::setFullscreen, &g_window, _1)); - g_lua.bindClassStaticFunction("g_window", "setTitle", std::bind(&PlatformWindow::setTitle, &g_window, _1)); + g_lua.bindClassStaticFunction("g_window", "setVerticalSync", std::bind(&PlatformWindow::setVerticalSync, &g_window, _1)); g_lua.bindClassStaticFunction("g_window", "setIcon", std::bind(&PlatformWindow::setIcon, &g_window, _1)); g_lua.bindClassStaticFunction("g_window", "setClipboardText", std::bind(&PlatformWindow::setClipboardText, &g_window, _1)); - g_lua.bindClassStaticFunction("g_window", "getMousePos", std::bind(&PlatformWindow::getMousePos, &g_window)); - g_lua.bindClassStaticFunction("g_window", "getSize", std::bind(&PlatformWindow::getSize, &g_window)); g_lua.bindClassStaticFunction("g_window", "getDisplaySize", std::bind(&PlatformWindow::getDisplaySize, &g_window)); - g_lua.bindClassStaticFunction("g_window", "getPlatformType", std::bind(&PlatformWindow::getPlatformType, &g_window)); g_lua.bindClassStaticFunction("g_window", "getClipboardText", std::bind(&PlatformWindow::getClipboardText, &g_window)); + g_lua.bindClassStaticFunction("g_window", "getPlatformType", std::bind(&PlatformWindow::getPlatformType, &g_window)); + g_lua.bindClassStaticFunction("g_window", "getDisplayWidth", std::bind(&PlatformWindow::getDisplayWidth, &g_window)); + g_lua.bindClassStaticFunction("g_window", "getDisplayHeight", std::bind(&PlatformWindow::getDisplayHeight, &g_window)); + g_lua.bindClassStaticFunction("g_window", "getUnmaximizedSize", std::bind(&PlatformWindow::getUnmaximizedSize, &g_window)); + g_lua.bindClassStaticFunction("g_window", "getSize", std::bind(&PlatformWindow::getSize, &g_window)); + g_lua.bindClassStaticFunction("g_window", "getWidth", std::bind(&PlatformWindow::getWidth, &g_window)); + g_lua.bindClassStaticFunction("g_window", "getHeight", std::bind(&PlatformWindow::getHeight, &g_window)); + g_lua.bindClassStaticFunction("g_window", "getUnmaximizedPos", std::bind(&PlatformWindow::getUnmaximizedPos, &g_window)); + g_lua.bindClassStaticFunction("g_window", "getPos", std::bind(&PlatformWindow::getPos, &g_window)); + g_lua.bindClassStaticFunction("g_window", "getX", std::bind(&PlatformWindow::getX, &g_window)); + g_lua.bindClassStaticFunction("g_window", "getY", std::bind(&PlatformWindow::getY, &g_window)); + g_lua.bindClassStaticFunction("g_window", "getMousePos", std::bind(&PlatformWindow::getMousePos, &g_window)); + g_lua.bindClassStaticFunction("g_window", "getKeyboardModifiers", std::bind(&PlatformWindow::getKeyboardModifiers, &g_window)); + g_lua.bindClassStaticFunction("g_window", "isVisible", std::bind(&PlatformWindow::isVisible, &g_window)); + g_lua.bindClassStaticFunction("g_window", "isFullscreen", std::bind(&PlatformWindow::isFullscreen, &g_window)); + g_lua.bindClassStaticFunction("g_window", "isMaximized", std::bind(&PlatformWindow::isMaximized, &g_window)); + g_lua.bindClassStaticFunction("g_window", "hasFocus", std::bind(&PlatformWindow::hasFocus, &g_window)); // Logger g_lua.registerClass(); diff --git a/src/framework/luascript/luainterface.cpp b/src/framework/luascript/luainterface.cpp index c4e62c95..57ae62cc 100644 --- a/src/framework/luascript/luainterface.cpp +++ b/src/framework/luascript/luainterface.cpp @@ -302,25 +302,26 @@ void LuaInterface::loadScript(const std::string& fileName) void LuaInterface::loadFunction(const std::string& buffer, const std::string& source) { - // gets the function contained in that buffer - if(boost::starts_with(buffer, "function")) { - // evaluate the function - std::string buf = Fw::mkstr("__func = ", buffer); - loadBuffer(buf, source); - safeCall(); - - // get the function - getGlobal("__func"); - - // reset the global __func + if(buffer.empty()) { pushNil(); - setGlobal("__func"); + return; } - // gets the buffer as a function - else if(!buffer.empty()) - loadBuffer(buffer, source); + + std::string buf; + if(boost::starts_with(buffer, "function")) + buf = Fw::mkstr("__func = ", buffer); else - pushNil(); + buf = Fw::mkstr("__func = function(self)\n", buffer,"\nend"); + + loadBuffer(buf, source); + safeCall(); + + // get the function + getGlobal("__func"); + + // reset the global __func + pushNil(); + setGlobal("__func"); } void LuaInterface::evaluateExpression(const std::string& expression, const std::string& source) diff --git a/src/framework/platform/platformwindow.cpp b/src/framework/platform/platformwindow.cpp index ebbc5a21..87a24356 100644 --- a/src/framework/platform/platformwindow.cpp +++ b/src/framework/platform/platformwindow.cpp @@ -31,3 +31,11 @@ X11Window window; #endif PlatformWindow& g_window = window; + +void PlatformWindow::updateUnmaximizedCoords() +{ + if(!isMaximized()) { + m_unmaximizedPos = m_pos; + m_unmaximizedSize = m_size; + } +} diff --git a/src/framework/platform/platformwindow.h b/src/framework/platform/platformwindow.h index 87152731..133ffe4c 100644 --- a/src/framework/platform/platformwindow.h +++ b/src/framework/platform/platformwindow.h @@ -59,9 +59,11 @@ public: int getDisplayWidth() { return getDisplaySize().width(); } int getDisplayHeight() { return getDisplaySize().width(); } + Size getUnmaximizedSize() { return m_unmaximizedSize; } Size getSize() { return m_size; } int getWidth() { return m_size.width(); } int getHeight() { return m_size.height(); } + Point getUnmaximizedPos() { return m_unmaximizedPos; } Point getPos() { return m_pos; } int getX() { return m_pos.x; } int getY() { return m_pos.y; } @@ -70,6 +72,7 @@ public: bool isVisible() { return m_visible; } bool isFullscreen() { return m_fullscreen; } + virtual bool isMaximized() = 0; bool hasFocus() { return m_focused; } void setOnClose(const SimpleCallback& onClose) { m_onClose = onClose; } @@ -77,8 +80,12 @@ public: void setOnInputEvent(const OnInputEventCallback& onInputEvent) { m_onInputEvent = onInputEvent; } protected: + void updateUnmaximizedCoords(); + Size m_size; Point m_pos; + Size m_unmaximizedSize; + Point m_unmaximizedPos; InputEvent m_inputEvent; Boolean m_created; diff --git a/src/framework/platform/win32window.cpp b/src/framework/platform/win32window.cpp index dda64c2d..0201a2d2 100644 --- a/src/framework/platform/win32window.cpp +++ b/src/framework/platform/win32window.cpp @@ -354,6 +354,7 @@ void WIN32Window::resize(const Size& size) void WIN32Window::show() { + updateUnmaximizedCoords(); if(m_maximized) ShowWindow(m_window, SW_MAXIMIZE); else @@ -472,6 +473,7 @@ LRESULT WIN32Window::windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar case WM_MOVE: { m_pos.x = LOWORD(lParam); m_pos.y = HIWORD(lParam); + updateUnmaximizedCoords(); break; } case WM_SIZE: { @@ -487,6 +489,7 @@ LRESULT WIN32Window::windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar m_visible = !(wParam == SIZE_MINIMIZED); m_size.setWidth(LOWORD(lParam)); m_size.setHeight(HIWORD(lParam)); + updateUnmaximizedCoords(); m_onResize(m_size); break; } diff --git a/src/framework/platform/x11window.cpp b/src/framework/platform/x11window.cpp index 2400babe..eaf66e5e 100644 --- a/src/framework/platform/x11window.cpp +++ b/src/framework/platform/x11window.cpp @@ -278,6 +278,7 @@ void X11Window::internalCreateWindow() vis = CopyFromParent; } + updateUnmaximizedCoords(); m_window = XCreateWindow(m_display, m_rootWindow, m_pos.x, m_pos.y, m_size.width(), m_size.height(), 0, @@ -494,6 +495,8 @@ void X11Window::hide() void X11Window::maximize() { + updateUnmaximizedCoords(); + Atom wmState = XInternAtom(m_display, "_NET_WM_STATE", False); Atom wmStateMaximizedVert = XInternAtom(m_display, "_NET_WM_STATE_MAXIMIZED_VERT", False); Atom wmStateMaximizedHorz = XInternAtom(m_display, "_NET_WM_STATE_MAXIMIZED_HORZ", False); @@ -561,6 +564,7 @@ void X11Window::poll() // updates window pos m_pos = newPos; + updateUnmaximizedCoords(); break; } case SelectionRequest: { @@ -916,6 +920,9 @@ std::string X11Window::getPlatformType() bool X11Window::isMaximized() { + if(!m_display || !m_window) + return false; + Atom wmState = XInternAtom(m_display, "_NET_WM_STATE", False); Atom wmStateMaximizedVert = XInternAtom(m_display, "_NET_WM_STATE_MAXIMIZED_VERT", False); Atom wmStateMaximizedHorz = XInternAtom(m_display, "_NET_WM_STATE_MAXIMIZED_HORZ", False); @@ -940,7 +947,7 @@ bool X11Window::isMaximized() } if(maximizedMask == 3) - maximizedMask = true; + maximized = true; XFree(propertyValue); } diff --git a/src/framework/ui/uianchorlayout.h b/src/framework/ui/uianchorlayout.h index 16b05e33..c45adbb4 100644 --- a/src/framework/ui/uianchorlayout.h +++ b/src/framework/ui/uianchorlayout.h @@ -62,7 +62,6 @@ class UIAnchorLayout : public UILayout { public: UIAnchorLayout(UIWidgetPtr parentWidget) : UILayout(parentWidget) { } - static UIAnchorLayoutPtr create(UIWidgetPtr parentWidget) { return UIAnchorLayoutPtr(new UIAnchorLayout(parentWidget)); } void addAnchor(const UIWidgetPtr& anchoredWidget, Fw::AnchorEdge anchoredEdge, const std::string& hookedWidgetId, Fw::AnchorEdge hookedEdge); diff --git a/src/framework/ui/uimanager.cpp b/src/framework/ui/uimanager.cpp index d92484ba..ec79d0f7 100644 --- a/src/framework/ui/uimanager.cpp +++ b/src/framework/ui/uimanager.cpp @@ -32,7 +32,7 @@ UIManager g_ui; void UIManager::init() { // creates root widget - m_rootWidget = UIWidget::create(); + m_rootWidget = UIWidgetPtr(new UIWidget); m_rootWidget->setId("root"); m_mouseReceiver = m_rootWidget; m_keyboardReceiver = m_rootWidget; diff --git a/src/framework/ui/uiverticallayout.cpp b/src/framework/ui/uiverticallayout.cpp index 084e9752..3c9ee70f 100644 --- a/src/framework/ui/uiverticallayout.cpp +++ b/src/framework/ui/uiverticallayout.cpp @@ -119,4 +119,3 @@ void UIVerticalLayout::setFitParent(bool fitParent) m_fitParent = fitParent; update(); } - diff --git a/src/framework/ui/uiverticallayout.h b/src/framework/ui/uiverticallayout.h index a58020dd..028239e2 100644 --- a/src/framework/ui/uiverticallayout.h +++ b/src/framework/ui/uiverticallayout.h @@ -29,7 +29,6 @@ class UIVerticalLayout : public UILayout { public: UIVerticalLayout(UIWidgetPtr parentWidget); - static UIVerticalLayoutPtr create(UIWidgetPtr parentWidget) { return UIVerticalLayoutPtr(new UIVerticalLayout(parentWidget)); } virtual void applyStyle(const OTMLNodePtr& styleNode); virtual void update(); diff --git a/src/framework/ui/uiwidget.cpp b/src/framework/ui/uiwidget.cpp index 7d784ed0..18473c8f 100644 --- a/src/framework/ui/uiwidget.cpp +++ b/src/framework/ui/uiwidget.cpp @@ -526,7 +526,7 @@ void UIWidget::addChild(const UIWidgetPtr& child) // create default layout if(!m_layout) - m_layout = UIAnchorLayout::create(asUIWidget()); + m_layout = UIAnchorLayoutPtr(new UIAnchorLayout(asUIWidget())); // add to layout and updates it m_layout->addWidget(child); @@ -559,7 +559,7 @@ void UIWidget::insertChild(int index, const UIWidgetPtr& child) // create default layout if needed if(!m_layout) - m_layout = UIAnchorLayout::create(asUIWidget()); + m_layout = UIAnchorLayoutPtr(new UIAnchorLayout(asUIWidget())); // add to layout and updates it m_layout->addWidget(child); @@ -829,7 +829,7 @@ void UIWidget::updateState(Fw::WidgetState state) do { parent = widget->getParent(); if(!widget->isExplicitlyEnabled() || - ((parent && parent->getFocusedChild() != widget))) { + ((parent && parent->getFocusedChild() != widget))) { newStatus = false; break; } @@ -850,7 +850,7 @@ void UIWidget::updateState(Fw::WidgetState state) do { parent = widget->getParent(); if(!widget->isExplicitlyEnabled() || !widget->isExplicitlyVisible() || !widget->containsPoint(mousePos) || - (parent && widget != parent->getChildByPos(mousePos))) { + (parent && widget != parent->getChildByPos(mousePos))) { newStatus = false; break; } @@ -1093,9 +1093,9 @@ void UIWidget::onStyleApply(const std::string& styleName, const OTMLNodePtr& sty if(!layoutType.empty()) { UILayoutPtr layout; if(layoutType == "verticalBox") - layout = UIVerticalLayout::create(asUIWidget()); + layout = UIVerticalLayoutPtr(new UIVerticalLayout(asUIWidget())); else if(layoutType == "anchor") - layout = UIAnchorLayout::create(asUIWidget()); + layout = UIAnchorLayoutPtr(new UIAnchorLayout(asUIWidget())); else throw OTMLException(node, "cannot determine layout type"); setLayout(layout); @@ -1158,6 +1158,7 @@ void UIWidget::onStyleApply(const std::string& styleName, const OTMLNodePtr& sty } if(m_firstOnStyle) { + callLuaField("onSetup"); // always focus new child if(isFocusable() && isExplicitlyVisible() && isExplicitlyEnabled()) focus(); diff --git a/src/framework/ui/uiwidget.h b/src/framework/ui/uiwidget.h index 77c136a9..4178034a 100644 --- a/src/framework/ui/uiwidget.h +++ b/src/framework/ui/uiwidget.h @@ -35,9 +35,6 @@ public: UIWidget(); virtual ~UIWidget() { } - template - static std::shared_ptr create() { auto t = std::shared_ptr(new T); return t; } - void destroy(); protected: diff --git a/src/otclient/luafunctions.cpp b/src/otclient/luafunctions.cpp index 460b71d9..fae18c97 100644 --- a/src/otclient/luafunctions.cpp +++ b/src/otclient/luafunctions.cpp @@ -1,3 +1,25 @@ +/* + * Copyright (c) 2010-2012 OTClient + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include "otclient.h" #include #include @@ -84,20 +106,20 @@ void OTClient::registerLuaFunctions() g_lua.bindClassStaticFunction("getFollowingCreature", std::bind(&Game::getFollowingCreature, &g_game)); g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", &UIItem::create); + g_lua.bindClassStaticFunction("create", []{ return UIItemPtr(new UIItem); } ); g_lua.bindClassMemberFunction("getItem", &UIItem::getItem); g_lua.bindClassMemberFunction("setItem", &UIItem::setItem); g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", &UICreature::create); + g_lua.bindClassStaticFunction("create", []{ return UICreaturePtr(new UICreature); } ); g_lua.bindClassMemberFunction("getCreature", &UICreature::getCreature); g_lua.bindClassMemberFunction("setCreature", &UICreature::setCreature); g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", &UIWidget::create); + g_lua.bindClassStaticFunction("create", []{ return UIMapPtr(new UIMap); } ); g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", &UIWidget::create); + g_lua.bindClassStaticFunction("create", []{ return UIGamePtr(new UIGame); } ); #ifdef FORBIDDEN_FUNCTIONS g_lua.bindClassStaticFunction("talkChannel", std::bind(&Game::talkChannel, &g_game, _1, _2, _3)); diff --git a/src/otclient/ui/declarations.h b/src/otclient/ui/declarations.h index d9dbba9c..9c2a3cd4 100644 --- a/src/otclient/ui/declarations.h +++ b/src/otclient/ui/declarations.h @@ -20,3 +20,20 @@ * THE SOFTWARE. */ +#ifndef OTCLIENT_UI_DECLARATIONS_H +#define OTCLIENT_UI_DECLARATIONS_H + +#include +#include + +class UIItem; +class UICreature; +class UIMap; +class UIGame; + +typedef std::shared_ptr UIItemPtr; +typedef std::shared_ptr UICreaturePtr; +typedef std::shared_ptr UIMapPtr; +typedef std::shared_ptr UIGamePtr; + +#endif