diff --git a/modules/client_terminal/terminal.lua b/modules/client_terminal/terminal.lua index d41d1e56..d423fb79 100644 --- a/modules/client_terminal/terminal.lua +++ b/modules/client_terminal/terminal.lua @@ -9,7 +9,7 @@ local LabelHeight = 16 local MaxHistory = 1000 -- private variables -local terminalWidget +local terminalWindow local terminalButton local logLocked = false local commandEnv = newenv() @@ -107,22 +107,36 @@ end -- public functions function Terminal.init() - terminalWidget = displayUI('terminal.otui') - terminalWidget:setVisible(false) + terminalWindow = displayUI('terminal.otui') + terminalWindow:setVisible(false) + + local poped = false + terminalWindow.onDoubleClick = function(self) + if poped then + self:fill('parent') + poped = false + else + self:breakAnchors() + self:resize(g_window.getWidth()/2, g_window.getHeight()/2) + self:move(g_window.getWidth()/2, g_window.getHeight()/2) + poped = true + end + end + terminalButton = TopMenu.addLeftButton('terminalButton', 'Terminal (Ctrl + T)', 'terminal.png', Terminal.toggle) Keyboard.bindKeyDown('Ctrl+T', Terminal.toggle) commandHistory = Settings.getList('terminal-history') - commandLineEdit = terminalWidget:getChildById('commandLineEdit') + commandLineEdit = terminalWindow:getChildById('commandLineEdit') Keyboard.bindKeyPress('Up', function() navigateCommand(1) end, commandLineEdit) Keyboard.bindKeyPress('Down', function() navigateCommand(-1) end, commandLineEdit) Keyboard.bindKeyDown('Tab', completeCommand, commandLineEdit) Keyboard.bindKeyDown('Enter', doCommand, commandLineEdit) - Keyboard.bindKeyDown('Escape', Terminal.hide, terminalWidget) + Keyboard.bindKeyDown('Escape', Terminal.hide, terminalWindow) - terminalBuffer = terminalWidget:getChildById('terminalBuffer') + terminalBuffer = terminalWindow:getChildById('terminalBuffer') g_logger.setOnLog(onLog) g_logger.fireOldMessages() end @@ -135,14 +149,14 @@ function Terminal.terminate() terminalButton = nil commandLineEdit = nil terminalBuffer = nil - terminalWidget:destroy() - terminalWidget = nil + terminalWindow:destroy() + terminalWindow = nil commandEnv = nil Terminal = nil end function Terminal.toggle() - if terminalWidget:isVisible() then + if terminalWindow:isVisible() then Terminal.hide() else Terminal.show() @@ -150,13 +164,13 @@ function Terminal.toggle() end function Terminal.show() - terminalWidget:show() - terminalWidget:raise() - terminalWidget:focus() + terminalWindow:show() + terminalWindow:raise() + terminalWindow:focus() end function Terminal.hide() - terminalWidget:hide() + terminalWindow:hide() end function Terminal.addLine(text, color) diff --git a/modules/client_terminal/terminal.otui b/modules/client_terminal/terminal.otui index 42fd41fe..62c71d07 100644 --- a/modules/client_terminal/terminal.otui +++ b/modules/client_terminal/terminal.otui @@ -1,16 +1,21 @@ TerminalLabel < UILabel font: terminus-14px-bold height: 16 + text-wrap: true + text-auto-resize: true -UIWidget - id: terminalWidget +UIWindow + id: terminalWindow background-color: #000000 opacity: 0.85 + clipping: true anchors.fill: parent Panel id: terminalBuffer - layout: verticalBox + layout: + type: verticalBox + align-bottom: true focusable: false anchors.left: parent.left anchors.right: parent.right @@ -35,3 +40,5 @@ UIWidget anchors.right: parent.right margin-left: 5 font: terminus-14px-bold + + diff --git a/modules/core_lib/ui/effects.lua b/modules/core_lib/ui/effects.lua index f2399da7..fb40079c 100644 --- a/modules/core_lib/ui/effects.lua +++ b/modules/core_lib/ui/effects.lua @@ -2,8 +2,9 @@ Effects = {} function Effects.fadeIn(widget, time, elapsed) if not elapsed then elapsed = 0 end - if not time then time = 250 end + if not time then time = 300 end widget:setOpacity(math.min(elapsed/time, 1)) + removeEvent(widget.fadeEvent) if elapsed < time then removeEvent(widget.fadeEvent) widget.fadeEvent = scheduleEvent(function() @@ -16,19 +17,20 @@ end function Effects.fadeOut(widget, time, elapsed) if not elapsed then elapsed = 0 end - if not time then time = 250 end + if not time then time = 300 end + elapsed = math.max((1 - widget:getOpacity()) * time, elapsed) + removeEvent(widget.fadeEvent) widget:setOpacity(math.max((time - elapsed)/time, 0)) if elapsed < time then - removeEvent(widget.fadeEvent) widget.fadeEvent = scheduleEvent(function() Effects.fadeOut(widget, time, elapsed + 30) end, 30) else widget.fadeEvent = nil - widget:destroy() end end function Effects.cancelFade(widget) removeEvent(widget.fadeEvent) + widget.fadeEvent = nil end diff --git a/modules/core_lib/ui/tooltip.lua b/modules/core_lib/ui/tooltip.lua index a8fdd19c..2e717e8e 100644 --- a/modules/core_lib/ui/tooltip.lua +++ b/modules/core_lib/ui/tooltip.lua @@ -74,12 +74,12 @@ function ToolTip.display(text) toolTipLabel:show() toolTipLabel:raise() toolTipLabel:enable() + Effects.fadeIn(toolTipLabel, 100) moveToolTip(toolTipLabel) end function ToolTip.hide() - - toolTipLabel:hide() + Effects.fadeOut(toolTipLabel, 100) end -- UIWidget extensions diff --git a/modules/core_lib/widgets/uisplitter.lua b/modules/core_lib/widgets/uisplitter.lua index 96b3136e..26ab2f2d 100644 --- a/modules/core_lib/widgets/uisplitter.lua +++ b/modules/core_lib/widgets/uisplitter.lua @@ -3,6 +3,7 @@ UISplitter = extends(UIWidget) function UISplitter.create() local splitter = UISplitter.internalCreate() splitter:setFocusable(false) + splitter.relativeMargin = 'bottom' return splitter end @@ -15,17 +16,22 @@ function UISplitter:onHoverChange(hovered) Mouse.setHorizontalCursor() self.vertical = false end - elseif not self:isPressed() then - Mouse.restoreCursor() + if not self:isPressed() then + Effects.fadeIn(self) + end + else + if not self:isPressed() then + Mouse.restoreCursor() + Effects.fadeOut(self) + end end end - function UISplitter:onMouseMove(mousePos, mouseMoved) if self:isPressed() then + --local currentmargin, newmargin, delta if self.vertical then - local delta = mousePos.y - self:getY() - local currentMargin = self:getMarginBottom() + local delta = mousePos.y - self:getY() - self:getHeight()/2 local newMargin = self:canUpdateMargin(self:getMarginBottom() - delta) if newMargin ~= currentMargin then self.newMargin = newMargin @@ -36,7 +42,16 @@ function UISplitter:onMouseMove(mousePos, mouseMoved) end end else - --TODO + local delta = mousePos.x - self:getX() - self:getWidth()/2 + local newMargin = self:canUpdateMargin(self:getMarginRight() - delta) + if newMargin ~= currentMargin then + self.newMargin = newMargin + if not self.event or self.event:isExecuted() then + self.event = addEvent(function() + self:setMarginRight(self.newMargin) + end) + end + end end return true end @@ -45,14 +60,14 @@ end function UISplitter:onMouseRelease(mousePos, mouseButton) if not self:isHovered() then Mouse.restoreCursor() + Effects.fadeOut(self) end end function UISplitter:onStyleApply(styleName, styleNode) - --TODO: relative margins - --if styleNode['relative-margin'] then - --- self.relativeMargin = styleNode['relative-margin'] - --end + if styleNode['relative-margin'] then + self.relativeMargin = styleNode['relative-margin'] + end end function UISplitter:canUpdateMargin(newMargin) diff --git a/modules/core_styles/core_styles.otmod b/modules/core_styles/core_styles.otmod index 42f70d46..bc2ed829 100644 --- a/modules/core_styles/core_styles.otmod +++ b/modules/core_styles/core_styles.otmod @@ -29,3 +29,4 @@ Module importStyle 'styles/spinboxes.otui' importStyle 'styles/messageboxes.otui' importStyle 'styles/scrollbars.otui' + importStyle 'styles/splitters.otui' diff --git a/modules/core_styles/styles/windows.otui b/modules/core_styles/styles/windows.otui index aadd2990..ec41553a 100644 --- a/modules/core_styles/styles/windows.otui +++ b/modules/core_styles/styles/windows.otui @@ -17,7 +17,7 @@ Window < UIWindow $disabled: color: #aaaaaa88 - $pressed: + $dragging: opacity: 0.8 MainWindow < Window diff --git a/modules/game/gameinterface.otui b/modules/game/gameinterface.otui index 3181e65a..29e34bba 100644 --- a/modules/game/gameinterface.otui +++ b/modules/game/gameinterface.otui @@ -24,43 +24,51 @@ UIWidget anchors.bottom: gameBottomPanel.top focusable: false - UISplitter - id: mapSplitter - anchors.left: gameLeftPanel.right - anchors.right: gameRightPanel.left - anchors.bottom: parent.bottom - relative-margin: bottom - margin-bottom: 172 - height: 4 - margin-top: -2 - @canUpdateMargin: function(self, newMargin) return math.min(math.max(newMargin, 100), self:getParent():getHeight() - 300) end - @onGeometryChange: function(self) self:setMarginBottom(math.min(self:getParent():getHeight() - 300, self:getMarginBottom())) end - GameBottomPanel id: gameBottomPanel anchors.left: gameLeftPanel.right anchors.right: gameRightPanel.left - anchors.top: mapSplitter.top + anchors.top: bottomSplitter.top anchors.bottom: parent.bottom GameSidePanel - id: gameRightPanel - width: 190 + id: gameLeftPanel + width: 0 layout: verticalBox - anchors.right: parent.right + anchors.left: parent.left anchors.top: parent.top anchors.bottom: parent.bottom focusable: false GameSidePanel - id: gameLeftPanel - width: 0 + id: gameRightPanel layout: verticalBox - anchors.left: parent.left + anchors.left: rightSplitter.left + anchors.right: parent.right anchors.top: parent.top anchors.bottom: parent.bottom focusable: false + Splitter + id: bottomSplitter + anchors.left: gameLeftPanel.right + anchors.right: gameRightPanel.left + anchors.bottom: parent.bottom + relative-margin: bottom + margin-bottom: 172 + @canUpdateMargin: function(self, newMargin) return math.min(math.max(newMargin, 100), self:getParent():getHeight() - 300) end + @onGeometryChange: function(self) self:setMarginBottom(math.min(self:getParent():getHeight() - 300, self:getMarginBottom())) end + + Splitter + id: rightSplitter + anchors.right: parent.right + anchors.top: parent.top + anchors.bottom: parent.bottom + relative-margin: right + margin-right: 190 + @canUpdateMargin: function(self, newMargin) return math.min(math.max(newMargin, 150), self:getParent():getWidth() - 300) end + @onGeometryChange: function(self) self:setMarginRight(math.min(self:getParent():getWidth() - 300, self:getMarginRight())) end + UIWidget id: mouseGrabber focusable: false diff --git a/modules/game_textmessage/textmessage.lua b/modules/game_textmessage/textmessage.lua index aca30df8..8bf99c1c 100644 --- a/modules/game_textmessage/textmessage.lua +++ b/modules/game_textmessage/textmessage.lua @@ -59,6 +59,8 @@ local function createTextMessageLabel(id, parent) label:setTextAlign(AlignCenter) label:setId(id) label:setMarginBottom(2) + label:setTextWrap(true) + label:setTextAutoResize(true) label:setVisible(false) return label end diff --git a/modules/game_textmessage/textmessage.otui b/modules/game_textmessage/textmessage.otui index 9a8ef01f..78015ae4 100644 --- a/modules/game_textmessage/textmessage.otui +++ b/modules/game_textmessage/textmessage.otui @@ -2,6 +2,7 @@ CenterLabel < GameLabel font: verdana-11px-rounded height: 64 text-align: center + text-wrap: true anchors.centerIn: parent size: 360 264 @@ -11,5 +12,4 @@ BottomLabel < GameLabel text-align: center margin-bottom: 2 anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.right: parent.right + anchors.horizontalCenter: parent.horizontalCenter diff --git a/src/framework/luafunctions.cpp b/src/framework/luafunctions.cpp index 92a976f4..89294bdd 100644 --- a/src/framework/luafunctions.cpp +++ b/src/framework/luafunctions.cpp @@ -58,8 +58,8 @@ void Application::registerLuaFunctions() g_lua.bindClassMemberFunction("ticks", &ScheduledEvent::ticks); // UIWidget - g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", []{ return UIWidgetPtr(new UIWidget); }); + + g_lua.registerClass(); g_lua.bindClassStaticFunction("create", []{ return UIWidgetPtr(new UIWidget); }); g_lua.bindClassMemberFunction("addChild", &UIWidget::addChild); g_lua.bindClassMemberFunction("insertChild", &UIWidget::insertChild); g_lua.bindClassMemberFunction("removeChild", &UIWidget::removeChild); @@ -169,6 +169,7 @@ void Application::registerLuaFunctions() g_lua.bindClassMemberFunction("getAutoRepeatDelay", &UIWidget::getAutoRepeatDelay); g_lua.bindClassMemberFunction("getVirtualOffset", &UIWidget::getVirtualOffset); g_lua.bindClassMemberFunction("getStyleName", &UIWidget::getStyleName); + g_lua.bindClassMemberFunction("getLastClickPosition", &UIWidget::getLastClickPosition); g_lua.bindClassMemberFunction("setX", &UIWidget::setX); g_lua.bindClassMemberFunction("setY", &UIWidget::setY); g_lua.bindClassMemberFunction("setWidth", &UIWidget::setWidth); @@ -298,8 +299,10 @@ void Application::registerLuaFunctions() g_lua.bindClassMemberFunction("setTextAlign", &UIWidget::setTextAlign); g_lua.bindClassMemberFunction("setTextOffset", &UIWidget::setTextOffset); g_lua.bindClassMemberFunction("setTextWrap", &UIWidget::setTextWrap); + g_lua.bindClassMemberFunction("setTextAutoResize", &UIWidget::setTextAutoResize); g_lua.bindClassMemberFunction("setFont", &UIWidget::setFont); g_lua.bindClassMemberFunction("getText", &UIWidget::getText); + g_lua.bindClassMemberFunction("getDrawText", &UIWidget::getDrawText); g_lua.bindClassMemberFunction("getTextAlign", &UIWidget::getTextAlign); g_lua.bindClassMemberFunction("getTextOffset", &UIWidget::getTextOffset); g_lua.bindClassMemberFunction("getTextWrap", &UIWidget::getTextWrap); diff --git a/src/framework/ui/uimanager.cpp b/src/framework/ui/uimanager.cpp index ea667c64..c9e22871 100644 --- a/src/framework/ui/uimanager.cpp +++ b/src/framework/ui/uimanager.cpp @@ -116,8 +116,11 @@ void UIManager::inputEvent(const InputEvent& event) } case Fw::MouseMoveInputEvent: { // start dragging when moving a pressed widget - if(m_pressedWidget && m_pressedWidget->isDragable() && m_draggingWidget != m_pressedWidget) - updateDraggingWidget(m_pressedWidget, event.mousePos - event.mouseMoved); + if(m_pressedWidget && m_pressedWidget->isDragable() && m_draggingWidget != m_pressedWidget) { + // only drags when moving more than 4 pixels + if((event.mousePos - m_pressedWidget->getLastClickPosition()).length() >= 4) + updateDraggingWidget(m_pressedWidget, event.mousePos - event.mouseMoved); + } // mouse move can change hovered widgets updateHoveredWidget(); diff --git a/src/framework/ui/uiwidget.cpp b/src/framework/ui/uiwidget.cpp index 9f2c2cc7..02ca1c85 100644 --- a/src/framework/ui/uiwidget.cpp +++ b/src/framework/ui/uiwidget.cpp @@ -1323,6 +1323,7 @@ bool UIWidget::onMousePress(const Point& mousePos, Fw::MouseButton button) m_clickTimer.stop(); } else m_clickTimer.restart(); + m_lastClickPosition = mousePos; } if(hasLuaField("onMousePress")) diff --git a/src/framework/ui/uiwidget.h b/src/framework/ui/uiwidget.h index 33ceec2f..289f4bfb 100644 --- a/src/framework/ui/uiwidget.h +++ b/src/framework/ui/uiwidget.h @@ -43,6 +43,7 @@ struct EdgeGroup { // 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 @@ -253,6 +254,7 @@ public: int getAutoRepeatDelay() { return m_autoRepeatDelay; } Point getVirtualOffset() { return m_virtualOffset; } std::string getStyleName() { return m_style->tag(); } + Point getLastClickPosition() { return m_lastClickPosition; } // base style @@ -277,6 +279,7 @@ protected: EdgeGroup m_padding; float m_opacity; int m_autoRepeatDelay; + Point m_lastClickPosition; public: void setX(int x) { move(x, getY()); } diff --git a/src/framework/ui/uiwidgettext.cpp b/src/framework/ui/uiwidgettext.cpp index 45d61c68..db6ddc63 100644 --- a/src/framework/ui/uiwidgettext.cpp +++ b/src/framework/ui/uiwidgettext.cpp @@ -50,7 +50,12 @@ void UIWidget::updateText() newSize.setHeight(textSize.height()); setSize(newSize); } else if(m_textAutoResize) { - setSize(getTextSize()); + Size textSize = getTextSize(); + Size size = getSize(); + if(textSize.width() > size.width()) + size.setWidth(textSize.width()); + size.setHeight(textSize.height()); + setSize(size); } m_textMustRecache = true;