diff --git a/modules/client_entergame/characterlist.otui b/modules/client_entergame/characterlist.otui index 268d9cf8..4088c485 100644 --- a/modules/client_entergame/characterlist.otui +++ b/modules/client_entergame/characterlist.otui @@ -28,6 +28,7 @@ MainWindow anchors.top: characterList.top anchors.bottom: characterList.bottom anchors.right: characterList.right + maximum: 0 Label id: accountStatusLabel diff --git a/modules/client_options/general.otui b/modules/client_options/general.otui new file mode 100644 index 00000000..a72eb57a --- /dev/null +++ b/modules/client_options/general.otui @@ -0,0 +1,28 @@ +Panel + OptionCheckBox + id: classicControl + text: Classic control + + OptionCheckBox + id: showInfoMessagesInConsole + text: Show info messages in console + + OptionCheckBox + id: showEventMessagesInConsole + text: Show event messages in console + + OptionCheckBox + id: showStatusMessagesInConsole + text: Show status messages in console + + OptionCheckBox + id: showTimestampsInConsole + text: Show timestamps in console + + OptionCheckBox + id: showLevelsInConsole + text: Show levels in console + + OptionCheckBox + id: showPrivateMessagesInConsole + text: Show private messages in console \ No newline at end of file diff --git a/modules/client_options/graphics.otui b/modules/client_options/graphics.otui new file mode 100644 index 00000000..2ca033ec --- /dev/null +++ b/modules/client_options/graphics.otui @@ -0,0 +1,32 @@ +Panel + OptionCheckBox + id: vsync + text: Enable vertical synchronization + tooltip: Limits FPS to 60 + + OptionCheckBox + id: showfps + text: Show frame rate + + OptionCheckBox + id: fullscreen + text: Fullscreen + + Label + text: Frame rate limit + anchors.left: parent.left + anchors.right: parent.right + anchors.top: prev.bottom + margin-top: 6 + + HorizontalScrollBar + id: frameRateScrollBar + anchors.left: parent.left + anchors.right: parent.right + anchors.top: prev.bottom + margin-top: 3 + minimum: 0 + maximum: 50 + value: 0 + step: 1 + @onValueChange: g_app.setFrameSleep(self:getValue()) diff --git a/modules/client_options/options.lua b/modules/client_options/options.lua index b7d5957e..37b22b50 100644 --- a/modules/client_options/options.lua +++ b/modules/client_options/options.lua @@ -2,6 +2,7 @@ Options = {} local optionsWindow local optionsButton +local optionsTabBar local options = { vsync = true, showfps = true, fullscreen = false, @@ -22,18 +23,24 @@ function Options.init() end end + Keyboard.bindKeyDown('Ctrl+P', Options.toggle) + optionsWindow = displayUI('options.otui') optionsWindow:hide() optionsButton = TopMenu.addLeftButton('optionsButton', 'Options (Ctrl+O)', 'options.png', Options.toggle) - Keyboard.bindKeyDown('Ctrl+O', Options.toggle) + optionsTabBar = optionsWindow:getChildById('optionsTabBar') + optionsTabBar:setContentWidget(optionsWindow:getChildById('optionsTabContent')) + optionsTabBar:addTab('General', loadUI('general.otui')) + optionsTabBar:addTab('Graphics', loadUI('graphics.otui')) end function Options.terminate() - Keyboard.unbindKeyDown('Ctrl+O') + Keyboard.unbindKeyDown('Ctrl+P') optionsWindow:destroy() optionsWindow = nil optionsButton:destroy() optionsButton = nil + optionsTabBar = nil Options = nil end diff --git a/modules/client_options/options.otui b/modules/client_options/options.otui index 7353b113..6e1540ff 100644 --- a/modules/client_options/options.otui +++ b/modules/client_options/options.otui @@ -16,51 +16,24 @@ OptionCheckBox < CheckBox MainWindow id: optionsWindow text: Options - size: 286 250 + size: 286 200 @onEnter: Options.hide() @onEscape: Options.hide() - OptionCheckBox - id: vsync - text: Enable vertical synchronization - tooltip: Limits FPS to 60 - - OptionCheckBox - id: showfps - text: Show frame rate - - OptionCheckBox - id: fullscreen - text: Fullscreen - - OptionCheckBox - id: classicControl - text: Classic control - - OptionCheckBox - id: showInfoMessagesInConsole - text: Show info messages in console - - OptionCheckBox - id: showEventMessagesInConsole - text: Show event messages in console - - OptionCheckBox - id: showStatusMessagesInConsole - text: Show status messages in console - - OptionCheckBox - id: showTimestampsInConsole - text: Show timestamps in console - - OptionCheckBox - id: showLevelsInConsole - text: Show levels in console + TabBar + id: optionsTabBar + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right - OptionCheckBox - id: showPrivateMessagesInConsole - text: Show private messages in console + Panel + id: optionsTabContent + anchors.top: optionsTabBar.bottom + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + margin-top: 10 Button text: Ok diff --git a/modules/core_lib/core_lib.otmod b/modules/core_lib/core_lib.otmod index 30d773cf..9a3d8c57 100644 --- a/modules/core_lib/core_lib.otmod +++ b/modules/core_lib/core_lib.otmod @@ -41,4 +41,5 @@ Module dofile 'widgets/uimessagebox' dofile 'widgets/uisplitter' dofile 'widgets/uiscrollbar' + dofile 'widgets/uiscrollarea' diff --git a/modules/core_lib/globals.lua b/modules/core_lib/globals.lua index a1e24a5d..5f39e372 100644 --- a/modules/core_lib/globals.lua +++ b/modules/core_lib/globals.lua @@ -4,7 +4,10 @@ importStyle = g_ui.importStyle importFont = g_fonts.importFont setDefaultFont = g_fonts.setDefaultFont -loadUI = g_ui.loadUI +function loadUI(otui, parent) + local otuiFilePath = resolvepath(otui, 2) + return g_ui.loadUI(otuiFilePath, parent) +end function displayUI(otui, parent) parent = parent or rootWidget @@ -17,7 +20,6 @@ function createWidget(stylename, parent) parent = rootWidget:recursiveGetChildById(parent) end local widget = g_ui.createWidgetFromStyle(stylename, parent) - --widget:setStyle(stylename) return widget end @@ -36,6 +38,26 @@ function addEvent(callback, front) return event end + +function periodicalEvent(eventFunc, conditionFunc, delay, autoRepeatDelay) + delay = delay or 30 + autoRepeatDelay = autoRepeatDelay or delay + + local func + func = function() + if conditionFunc and not conditionFunc() then + func = nil + return + end + eventFunc() + scheduleEvent(func, delay) + end + + scheduleEvent(function() + func() + end, autoRepeatDelay) +end + function removeEvent(event) if event then event:cancel() diff --git a/modules/core_lib/mouse.lua b/modules/core_lib/mouse.lua index 7e63bf7c..0f6e8a90 100644 --- a/modules/core_lib/mouse.lua +++ b/modules/core_lib/mouse.lua @@ -15,3 +15,24 @@ end function Mouse.restoreCursor() g_window.restoreMouseCursor() end + +function Mouse.bindAutoPress(widget, callback) + connect(widget, { onMousePress = function(widget, mousePos, mouseButton) + callback() + periodicalEvent(function() + callback() + end, function() + return widget:isPressed() + end, 30, 300) + return true + end }) +end + +function Mouse.bindPressMove(widget, callback) + connect(widget, { onMouseMove = function(widget, mousePos, mouseMoved) + if widget:isPressed() then + callback(mousePos, mouseMoved) + end + return true + end }) +end diff --git a/modules/core_lib/widgets/uiscrollarea.lua b/modules/core_lib/widgets/uiscrollarea.lua new file mode 100644 index 00000000..1db2550a --- /dev/null +++ b/modules/core_lib/widgets/uiscrollarea.lua @@ -0,0 +1,15 @@ +UIScrollArea = extends(UIWidget) + +function UIScrollArea.create() + local scrollarea = UIScrollArea.internalCreate() + scrollarea:setClipping(true) + return scrollarea +end + +function UIScrollArea:onStyleApply(styleName, styleNode) + for name,value in pairs(styleNode) do + if name == 'horizontal-scrollbar' then + + end + end +end diff --git a/modules/core_lib/widgets/uiscrollbar.lua b/modules/core_lib/widgets/uiscrollbar.lua index 8448eddd..a80e03be 100644 --- a/modules/core_lib/widgets/uiscrollbar.lua +++ b/modules/core_lib/widgets/uiscrollbar.lua @@ -1,30 +1,157 @@ UIScrollBar = extends(UIWidget) +-- private functions +local function calcValues(self) + local slider = self:getChildById('sliderButton') + local decrementButton = self:getChildById('decrementButton') + local incrementButton = self:getChildById('incrementButton') + + local pxrange, center + if self.orientation == 'vertical' then + pxrange = (self:getHeight() - decrementButton:getHeight() - decrementButton:getMarginTop() - decrementButton:getMarginBottom() + - incrementButton:getHeight() - incrementButton:getMarginTop() - incrementButton:getMarginBottom()) + center = self:getY() + self:getHeight() / 2 + else -- horizontal + pxrange = (self:getWidth() - decrementButton:getWidth() - decrementButton:getMarginLeft() - decrementButton:getMarginRight() + - incrementButton:getWidth() - incrementButton:getMarginLeft() - incrementButton:getMarginRight()) + center = self:getX() + self:getWidth() / 2 + end + + local range = self.maximum - self.minimum + 1 + local proportion = math.max(range*(self.step/range), 1)/range + local px = math.max(math.floor(proportion * pxrange), 10) + local offset = ((self.value / (range - 1)) - 0.5) * (pxrange - px) + + return range, pxrange, px, offset, center +end + +local function updateSlider(self) + local slider = self:getChildById('sliderButton') + if slider == nil then return end + + local range, pxrange, px, offset, center = calcValues(self) + if self.orientation == 'vertical' then + slider:setHeight(px) + slider:setMarginTop(offset) + else -- horizontal + slider:setWidth(px) + slider:setMarginLeft(offset) + end + + if self.maximum == self.minimum then + self:disable() + else + self:enable() + end +end + +local function parseSliderPos(self, pos) + local point + if self.orientation == 'vertical' then + point = pos.y + else + point = pos.x + end + local range, pxrange, px, offset, center = calcValues(self) + offset = math.min(math.max(point - center, -pxrange/2), pxrange/2) + local newvalue = math.floor(((offset / (pxrange - px)) + 0.5) * (range - 1)) + self:setValue(newvalue) +end + + +-- public functions function UIScrollBar.create() local scrollbar = UIScrollBar.internalCreate() scrollbar:setFocusable(false) + scrollbar.value = 0 + scrollbar.minimum = 0 + scrollbar.maximum = 0 + scrollbar.step = 1 + scrollbar.orientation = 'vertical' return scrollbar end function UIScrollBar:onSetup() - --self.getChildById('upButton').onClick = function() self.navigateUp() end - --self.getChildById('upButton').onClick = function() self.navigateDown() end -end - -function UIScrollBar:attachWidget(widget) - self.attachedWidget = widget + addEvent(function() + Mouse.bindAutoPress(self:getChildById('decrementButton'), function() self:decrement() end) + Mouse.bindAutoPress(self:getChildById('incrementButton'), function() self:increment() end) + Mouse.bindPressMove(self:getChildById('sliderButton'), function(mousePos, mouseMoved) parseSliderPos(self, mousePos) end) + updateSlider(self) + end) end function UIScrollBar:onStyleApply(styleName, styleNode) - if styleNode['attached-to'] then - local id = styleNode['attached-to'] - local parent = self:getParent() - local widget - if id == 'parent' then - widget = parent - elseif parent then - widget = parent:getChildById(id) + for name,value in pairs(styleNode) do + if name == 'maximum' then + self:setMaximum(tonumber(value)) + elseif name == 'minimum' then + self:setMinimum(tonumber(value)) + elseif name == 'step' then + self:setStep(tonumber(value)) + elseif name == 'orientation' then + self:setOrientation(value) + elseif name == 'value' then + self:setValue(value) end - self:attachWidget(widget) end end + +function UIScrollBar:decrement() + self:setValue(self.value - self.step) +end + +function UIScrollBar:increment() + self:setValue(self.value + self.step) +end + +function UIScrollBar:setMaximum(maximum) + if maximum == self.maximum then return end + self.maximum = maximum + if self.value > maximum then + self:setValue(maximum) + else + updateSlider(self) + end +end + +function UIScrollBar:setMinimum(minimum) + if minimum == self.minimum then return end + self.minimum = minimum + if self.value < minimum then + self:setValue(minimum) + else + updateSlider(self) + end +end + +function UIScrollBar:setRange(minimum, maximum) + self:setMinimum(minimum) + self:setMaximum(maximum) +end + +function UIScrollBar:setValue(value) + value = math.max(math.min(value, self.maximum), self.minimum) + if self.value == value then return end + local delta = value - self.value + self.value = value + updateSlider(self) + signalcall(self.onValueChange, self, value, delta) +end + +function UIScrollBar:setStep(step) + self.step = step +end + +function UIScrollBar:setOrientation(orientation) + self.orientation = orientation +end + +function UIScrollBar:onGeometryChange() + updateSlider(self) +end + +function UIScrollBar:getMaximum() return self.maximum end +function UIScrollBar:getMinimum() return self.minimum end +function UIScrollBar:getValue() return self.value end +function UIScrollBar:getStep() return self.step end +function UIScrollBar:getOrientation() return self.orientation end diff --git a/modules/core_styles/styles/images/scrollbar.png b/modules/core_styles/styles/images/scrollbar.png new file mode 100644 index 00000000..993d8af0 Binary files /dev/null and b/modules/core_styles/styles/images/scrollbar.png differ diff --git a/modules/core_styles/styles/images/vscrollbar.png b/modules/core_styles/styles/images/vscrollbar.png deleted file mode 100644 index 41f01e19..00000000 Binary files a/modules/core_styles/styles/images/vscrollbar.png and /dev/null differ diff --git a/modules/core_styles/styles/listboxes.otui b/modules/core_styles/styles/listboxes.otui index 5038d3cd..dc6e9b15 100644 --- a/modules/core_styles/styles/listboxes.otui +++ b/modules/core_styles/styles/listboxes.otui @@ -1,4 +1,4 @@ -TextList < UIWidget +TextList < UIScrollArea layout: verticalBox border-width: 1 border-color: #1d222b diff --git a/modules/core_styles/styles/scrollbars.otui b/modules/core_styles/styles/scrollbars.otui index eabcdd83..0e824652 100644 --- a/modules/core_styles/styles/scrollbars.otui +++ b/modules/core_styles/styles/scrollbars.otui @@ -1,30 +1,94 @@ +ScrollBarSlider < UIButton + id: sliderButton + anchors.centerIn: parent + size: 13 13 + image-source: images/scrollbar.png + image-clip: 0 26 13 13 + image-border: 2 + image-color: #ffffffff + $hover: + image-clip: 13 26 13 13 + $pressed: + image-clip: 26 26 13 13 + $disabled: + image-color: #ffffff66 + VerticalScrollBar < UIScrollBar + orientation: vertical width: 13 - image-source: images/vscrollbar.png - image-clip: 0 39 13 32 + height: 39 + image-source: images/scrollbar.png + image-clip: 39 0 13 65 image-border: 1 UIButton - id: upButton + id: decrementButton anchors.top: parent.top - anchors.right: parent.right - image-source: images/vscrollbar.png + anchors.left: parent.left + image-source: images/scrollbar.png image-clip: 0 0 13 13 + image-color: #ffffffff size: 13 13 + $hover: + image-clip: 13 0 13 13 + $pressed: + image-clip: 26 0 13 13 + $disabled: + image-color: #ffffff66 UIButton - id: downButton + id: incrementButton anchors.bottom: parent.bottom anchors.right: parent.right size: 13 13 - image-source: images/vscrollbar.png + image-source: images/scrollbar.png image-clip: 0 13 13 13 + image-color: #ffffffff + $hover: + image-clip: 13 13 13 13 + $pressed: + image-clip: 26 13 13 13 + $disabled: + image-color: #ffffff66 + + ScrollBarSlider + +HorizontalScrollBar < UIScrollBar + orientation: horizontal + height: 13 + width: 39 + image-source: images/scrollbar.png + image-clip: 0 65 52 13 + image-border: 1 + + UIButton + id: decrementButton + anchors.top: parent.top + anchors.left: parent.left + image-source: images/scrollbar.png + image-clip: 0 39 13 13 + image-color: #ffffffff + size: 13 13 + $hover: + image-clip: 13 39 13 13 + $pressed: + image-clip: 26 39 13 13 + $disabled: + image-color: #ffffff66 + + UIButton + id: incrementButton + anchors.bottom: parent.bottom + anchors.right: parent.right + size: 13 13 + image-source: images/scrollbar.png + image-clip: 0 52 13 13 + image-color: #ffffffff + $hover: + image-clip: 13 52 13 13 + $pressed: + image-clip: 26 52 13 13 + $disabled: + image-color: #ffffff66 - //UIButton - //id: middleButton - //anchors.top: parent.top - //anchors.right: parent.right - //size: 13 13 - //margin-top: 30 - //image-source: images/vscrollbar.png - //image-clip: 0 26 13 13 + ScrollBarSlider diff --git a/modules/core_styles/styles/tabbars.otui b/modules/core_styles/styles/tabbars.otui index 7a09f6b3..4afee7f4 100644 --- a/modules/core_styles/styles/tabbars.otui +++ b/modules/core_styles/styles/tabbars.otui @@ -1,4 +1,5 @@ TabBar < UITabBar + size: 80 20 TabBarPanel < Panel TabBarButton < UIButton size: 20 20 @@ -9,7 +10,6 @@ TabBarButton < UIButton icon-color: white color: #aaaaaa anchors.top: parent.top - margin-left: 5 padding: 5 $first: @@ -17,6 +17,7 @@ TabBarButton < UIButton $!first: anchors.left: prev.right + margin-left: 5 $hover !checked: image-clip: 0 20 20 20 diff --git a/modules/game/widgets/uigamemap.lua b/modules/game/widgets/uigamemap.lua index a37e3ba0..9842b5eb 100644 --- a/modules/game/widgets/uigamemap.lua +++ b/modules/game/widgets/uigamemap.lua @@ -57,19 +57,23 @@ function UIGameMap:onDrop(widget, mousePos) return true end +function UIGameMap:onClick(mousePosition) + local tile = self:getTile(mousePosition) + if tile == nil then return false end + local dirs = g_map.findPath(g_game.getLocalPlayer():getPosition(), tile:getPosition(), 255) + if #dirs == 0 then + TextMessage.displayStatus('There is no way.') + return true + end + g_game.autoWalk(dirs) + return true +end + function UIGameMap:onMouseRelease(mousePosition, mouseButton) local tile = self:getTile(mousePosition) if tile == nil then return false end if GameInterface.processMouseAction(mousePosition, mouseButton, nil, tile:getTopLookThing(), tile:getTopUseThing(), tile:getTopCreature(), tile:getTopMultiUseThing()) then return true - elseif mouseButton == MouseLeftButton then - local dirs = g_map.findPath(g_game.getLocalPlayer():getPosition(), tile:getPosition(), 255) - if #dirs == 0 then - TextMessage.displayStatus('There is no way.') - return true - end - g_game.autoWalk(dirs) - return true end return false end diff --git a/src/framework/application.cpp b/src/framework/application.cpp index 2f4cbc02..ec979dab 100644 --- a/src/framework/application.cpp +++ b/src/framework/application.cpp @@ -57,6 +57,7 @@ Application::Application(const std::string& appName) g_app = this; m_appName = appName; m_pollCycleDelay = POLL_CYCLE_DELAY; + m_frameSleep = 0; } Application::~Application() @@ -200,6 +201,9 @@ void Application::run() // sleeps until next poll to avoid massive cpu usage g_clock.sleep(POLL_CYCLE_DELAY+1); } + + if(m_frameSleep > 0) + g_clock.sleep(m_frameSleep); } m_stopping = false; diff --git a/src/framework/application.h b/src/framework/application.h index a2c1448a..e3cf6524 100644 --- a/src/framework/application.h +++ b/src/framework/application.h @@ -43,10 +43,13 @@ public: virtual void poll(); virtual void close(); + void setFrameSleep(int delay) { m_frameSleep = delay; } void setPollCycleDelay(int delay) { m_pollCycleDelay = delay; } bool isRunning() { return m_running; } bool isStopping() { return m_stopping; } + int getFrameSleep() { return m_frameSleep; } + int getPollCycleDelay() { return m_pollCycleDelay; } const std::string& getName() { return m_appName; } const std::string& getVersion() { return m_appVersion; } @@ -64,6 +67,7 @@ protected: std::string m_appVersion; std::string m_appBuildDate; int m_appFlags; + int m_frameSleep; int m_pollCycleDelay; Boolean m_initialized; Boolean m_running; diff --git a/src/framework/luafunctions.cpp b/src/framework/luafunctions.cpp index 719bee65..611bf41c 100644 --- a/src/framework/luafunctions.cpp +++ b/src/framework/luafunctions.cpp @@ -104,8 +104,10 @@ void Application::registerLuaFunctions() g_lua.bindClassMemberFunction("setPhantom", &UIWidget::setPhantom); g_lua.bindClassMemberFunction("setDragable", &UIWidget::setDragable); g_lua.bindClassMemberFunction("setFixedSize", &UIWidget::setFixedSize); + g_lua.bindClassMemberFunction("setClipping", &UIWidget::setClipping); g_lua.bindClassMemberFunction("setLastFocusReason", &UIWidget::setLastFocusReason); g_lua.bindClassMemberFunction("setAutoRepeatDelay", &UIWidget::setAutoRepeatDelay); + g_lua.bindClassMemberFunction("setVirtualOffset", &UIWidget::setVirtualOffset); g_lua.bindClassMemberFunction("isVisible", &UIWidget::isVisible); g_lua.bindClassMemberFunction("isChildLocked", &UIWidget::isChildLocked); g_lua.bindClassMemberFunction("hasChild", &UIWidget::hasChild); @@ -149,6 +151,7 @@ void Application::registerLuaFunctions() g_lua.bindClassMemberFunction("isPhantom", &UIWidget::isPhantom); g_lua.bindClassMemberFunction("isDragable", &UIWidget::isDragable); g_lua.bindClassMemberFunction("isFixedSize", &UIWidget::isFixedSize); + g_lua.bindClassMemberFunction("isClipping", &UIWidget::isClipping); g_lua.bindClassMemberFunction("isDestroyed", &UIWidget::isDestroyed); g_lua.bindClassMemberFunction("hasChildren", &UIWidget::hasChildren); g_lua.bindClassMemberFunction("containsPoint", &UIWidget::containsPoint); @@ -163,6 +166,7 @@ void Application::registerLuaFunctions() g_lua.bindClassMemberFunction("getChildCount", &UIWidget::getChildCount); g_lua.bindClassMemberFunction("getLastFocusReason", &UIWidget::getLastFocusReason); g_lua.bindClassMemberFunction("getAutoRepeatDelay", &UIWidget::getAutoRepeatDelay); + g_lua.bindClassMemberFunction("getVirtualOffset", &UIWidget::getVirtualOffset); g_lua.bindClassMemberFunction("getStyleName", &UIWidget::getStyleName); g_lua.bindClassMemberFunction("setX", &UIWidget::setX); g_lua.bindClassMemberFunction("setY", &UIWidget::setY); @@ -418,8 +422,12 @@ void Application::registerLuaFunctions() // Application g_lua.registerStaticClass("g_app"); g_lua.bindClassStaticFunction("g_app", "exit", std::bind(&Application::exit, g_app)); + g_lua.bindClassStaticFunction("g_app", "setFrameSleep", std::bind(&Application::setFrameSleep, g_app, _1)); + g_lua.bindClassStaticFunction("g_app", "setPollCycleDelay", std::bind(&Application::setPollCycleDelay, g_app, _1)); g_lua.bindClassStaticFunction("g_app", "isRunning", std::bind(&Application::isRunning, g_app)); g_lua.bindClassStaticFunction("g_app", "isStopping", std::bind(&Application::isStopping, g_app)); + g_lua.bindClassStaticFunction("g_app", "getFrameSleep", std::bind(&Application::getFrameSleep, g_app)); + g_lua.bindClassStaticFunction("g_app", "getPollCycleDelay", std::bind(&Application::getPollCycleDelay, g_app)); g_lua.bindClassStaticFunction("g_app", "getName", std::bind(&Application::getName, g_app)); g_lua.bindClassStaticFunction("g_app", "getVersion", std::bind(&Application::getVersion, g_app)); g_lua.bindClassStaticFunction("g_app", "getBuildCompiler", std::bind(&Application::getBuildCompiler, g_app)); diff --git a/src/framework/luascript/luaobject.h b/src/framework/luascript/luaobject.h index 6df4a81f..d8736ee9 100644 --- a/src/framework/luascript/luaobject.h +++ b/src/framework/luascript/luaobject.h @@ -40,6 +40,7 @@ public: template R callLuaField(const std::string& field, const T&... args); + /// Returns true if the lua field exists bool hasLuaField(const std::string& field); /// Sets a field in this lua object diff --git a/src/framework/ui/uiwidget.cpp b/src/framework/ui/uiwidget.cpp index a41fd1d4..ea2cb376 100644 --- a/src/framework/ui/uiwidget.cpp +++ b/src/framework/ui/uiwidget.cpp @@ -53,20 +53,14 @@ UIWidget::~UIWidget() void UIWidget::draw(const Rect& visibleRect) { - drawSelf(); - if(m_children.size() > 0) { - bool clip = true; - if(this == g_ui.getRootWidget().get()) - clip = false; - - if(clip) - g_graphics.beginClipping(visibleRect); + if(m_clipping) + g_graphics.beginClipping(visibleRect); - drawChildren(visibleRect); + drawSelf(); + drawChildren(visibleRect); - if(clip) - g_graphics.endClipping(); - } + if(m_clipping) + g_graphics.endClipping(); } void UIWidget::drawSelf() @@ -1325,12 +1319,20 @@ bool UIWidget::onMouseWheel(const Point& mousePos, Fw::MouseWheelDirection direc bool UIWidget::onClick(const Point& mousePos) { - return callLuaField("onClick", mousePos); + if(hasLuaField("onClick")) { + callLuaField("onClick", mousePos); + return true; + } + return false; } bool UIWidget::onDoubleClick(const Point& mousePos) { - return callLuaField("onDoubleClick", mousePos); + if(hasLuaField("onDoubleClick")) { + callLuaField("onDoubleClick", mousePos); + return true; + } + return false; } bool UIWidget::propagateOnKeyText(const std::string& keyText) diff --git a/src/framework/ui/uiwidget.h b/src/framework/ui/uiwidget.h index 5fc3893c..aa2b231f 100644 --- a/src/framework/ui/uiwidget.h +++ b/src/framework/ui/uiwidget.h @@ -41,6 +41,8 @@ struct EdgeGroup { T left; }; +// generate lua bindings for this class running: +// ./tools/lua-binding-generator/generate_lua_bindings.lua src/framework/ui/uiwidget.h class UIWidget : public LuaObject { // widget core @@ -65,6 +67,7 @@ protected: Boolean m_phantom; Boolean m_dragable; Boolean m_destroyed; + Boolean m_clipping; UILayoutPtr m_layout; UIWidgetWeakPtr m_parent; UIWidgetList m_children; @@ -120,6 +123,7 @@ public: void setPhantom(bool phantom); void setDragable(bool dragable); void setFixedSize(bool fixed); + void setClipping(bool clipping) { m_clipping = clipping; } void setLastFocusReason(Fw::FocusReason reason); void setAutoRepeatDelay(int delay) { m_autoRepeatDelay = delay; } void setVirtualOffset(const Point& offset); @@ -226,6 +230,7 @@ public: bool isPhantom() { return m_phantom; } bool isDragable() { return m_dragable; } bool isFixedSize() { return m_fixedSize; } + bool isClipping() { return m_clipping; } bool isDestroyed() { return m_destroyed; } bool hasChildren() { return m_children.size() > 0; } diff --git a/src/framework/ui/uiwidgetbasestyle.cpp b/src/framework/ui/uiwidgetbasestyle.cpp index bee1d1d4..b11a0e2b 100644 --- a/src/framework/ui/uiwidgetbasestyle.cpp +++ b/src/framework/ui/uiwidgetbasestyle.cpp @@ -120,6 +120,8 @@ void UIWidget::parseBaseStyle(const OTMLNodePtr& styleNode) setSize(node->value()); else if(node->tag() == "fixed-size") setFixedSize(node->value()); + else if(node->tag() == "clipping") + setClipping(node->value()); else if(node->tag() == "border") { auto split = Fw::split(node->value(), " "); if(split.size() == 2) {