make menu work

This commit is contained in:
Eduardo Bart 2012-01-02 20:09:49 -02:00
parent 43c16a1643
commit 90600bbd69
10 changed files with 128 additions and 47 deletions

View File

@ -17,11 +17,11 @@ PopupMenuButton < UIButton
$disabled: $disabled:
color: #555555 color: #555555
PopupMenuFirstButton < PopupMenuButton $first:
margin-top: 3 margin-top: 3
PopupMenuLastButton < PopupMenuButton $last:
margin-bottom: 3 margin-bottom: 3
PopupMenuSeparator < UIWidget PopupMenuSeparator < UIWidget
margin-left: 2 margin-left: 2

View File

@ -7,28 +7,50 @@ function UIPopupMenu.create()
local layout = UIVerticalLayout.create(menu) local layout = UIVerticalLayout.create(menu)
layout:setFitParent(true) layout:setFitParent(true)
menu:setLayout(layout) menu:setLayout(layout)
menu:setStyle('PopupMenu')
return menu return menu
end end
function UIPopupMenu.display(otui, pos) function UIPopupMenu.display(menu, pos)
local menu = UI.display(otui, {x = pos.x, y = pos.y}) UI.display(menu, {x = pos.x, y = pos.y})
menu:bindRectToParent()
menu:grabMouse()
menu:grabKeyboard()
return menu return menu
end end
function UIPopupMenu.addOption(menu, optionName, optionCallback)
local optionWidget = UIButton.create()
local lastOptionWidget = menu:getLastChild()
optionWidget.onClick = function()
optionCallback()
menu:destroy()
end
optionWidget:setText(optionName)
optionWidget:setStyle('PopupMenuButton')
menu:addChild(optionWidget)
end
function UIPopupMenu.addSeparator(menu)
local separatorWidget = UIWidget.create()
separatorWidget:setStyle('PopupMenuSeparator')
menu:addChild(separator)
end
-- hooked events -- hooked events
local function onWidgetStyleApply(widget, style) function UIPopupMenu.onMousePress(menu, mousePos, mouseButton)
if style and style.popupmenu then -- clicks outside menu area destroys the menu
widget.popupmenu = style.popupmenu if not menu:containsPoint(mousePos) then
end menu:destroy()
end
local function onWidgetMousePress(widget, mousePos, mouseButton)
if widget.popupmenu and mouseButton == MouseRightButton then
UIPopupMenu.display(widget.popupmenu, mousePos)
return true return true
end end
return false return false
end end
connect(UIWidget, { onStyleApply = onWidgetStyleApply, function UIPopupMenu.onKeyPress(menu, keyCode, keyText, keyboardModifiers)
onMousePress = onWidgetMousePress }) if keyCode == KeyEscape then
menu:destroy()
return true
end
return false
end

View File

@ -17,9 +17,6 @@ local InventorySlotAmmo = 10
-- public functions -- public functions
function Inventory.create() function Inventory.create()
window = UI.display('inventory.otui', { parent = Game.gameRightPanel }) window = UI.display('inventory.otui', { parent = Game.gameRightPanel })
local itemWidget = window:getChildById('feet')
window:setHeight(itemWidget:getPosition().y + itemWidget:getHeight() - window:getPosition().y)
end end
function Inventory.destroy() function Inventory.destroy()
@ -66,6 +63,13 @@ function Inventory.onSoulChange(soul)
widget:setText("Soul:\n" .. soul) widget:setText("Soul:\n" .. soul)
end end
function Inventory.onInventoryItemMousePress(itemWidget, mousePos, mouseButton)
local menu = UIPopupMenu.create()
menu:addOption('Look', function() print('look') end)
menu:addOption('Use', function() print('use') end)
menu:display(mousePos)
end
connect(Game, { onLogin = Inventory.create, connect(Game, { onLogin = Inventory.create,
onLogout = Inventory.destroy, onLogout = Inventory.destroy,
onInventoryChange = Inventory.onInventoryChange, onInventoryChange = Inventory.onInventoryChange,

View File

@ -1,8 +1,9 @@
InvetoryItem < Item InvetoryItem < Item
popupmenu: /game_inventory/itempopupmenu.otui &onMousePress: Inventory.onInventoryItemMousePress
UIWindow UIWindow
width: 192 width: 192
height: 148
margin-top: 10 margin-top: 10
margin-left: 6 margin-left: 6
margin-right: 6 margin-right: 6

View File

@ -63,6 +63,7 @@ void Application::registerLuaFunctions()
g_lua.bindClassMemberFunction<UIWidget>("setMarginLeft", &UIWidget::setMarginLeft); g_lua.bindClassMemberFunction<UIWidget>("setMarginLeft", &UIWidget::setMarginLeft);
g_lua.bindClassMemberFunction<UIWidget>("setSizeFixed", &UIWidget::setSizeFixed); g_lua.bindClassMemberFunction<UIWidget>("setSizeFixed", &UIWidget::setSizeFixed);
g_lua.bindClassMemberFunction<UIWidget>("setLastFocusReason", &UIWidget::setLastFocusReason); g_lua.bindClassMemberFunction<UIWidget>("setLastFocusReason", &UIWidget::setLastFocusReason);
g_lua.bindClassMemberFunction<UIWidget>("bindRectToParent", &UIWidget::bindRectToParent);
g_lua.bindClassMemberFunction<UIWidget>("resize", &UIWidget::resize); g_lua.bindClassMemberFunction<UIWidget>("resize", &UIWidget::resize);
g_lua.bindClassMemberFunction<UIWidget>("moveTo", &UIWidget::moveTo); g_lua.bindClassMemberFunction<UIWidget>("moveTo", &UIWidget::moveTo);
g_lua.bindClassMemberFunction<UIWidget>("hide", &UIWidget::hide); g_lua.bindClassMemberFunction<UIWidget>("hide", &UIWidget::hide);
@ -72,6 +73,10 @@ void Application::registerLuaFunctions()
g_lua.bindClassMemberFunction<UIWidget>("lock", &UIWidget::lock); g_lua.bindClassMemberFunction<UIWidget>("lock", &UIWidget::lock);
g_lua.bindClassMemberFunction<UIWidget>("unlock", &UIWidget::unlock); g_lua.bindClassMemberFunction<UIWidget>("unlock", &UIWidget::unlock);
g_lua.bindClassMemberFunction<UIWidget>("focus", &UIWidget::focus); g_lua.bindClassMemberFunction<UIWidget>("focus", &UIWidget::focus);
g_lua.bindClassMemberFunction<UIWidget>("grabMouse", &UIWidget::grabMouse);
g_lua.bindClassMemberFunction<UIWidget>("ungrabMouse", &UIWidget::ungrabMouse);
g_lua.bindClassMemberFunction<UIWidget>("grabKeyboard", &UIWidget::grabKeyboard);
g_lua.bindClassMemberFunction<UIWidget>("ungrabKeyboard", &UIWidget::ungrabKeyboard);
g_lua.bindClassMemberFunction<UIWidget>("isActive", &UIWidget::isActive); g_lua.bindClassMemberFunction<UIWidget>("isActive", &UIWidget::isActive);
g_lua.bindClassMemberFunction<UIWidget>("isEnabled", &UIWidget::isEnabled); g_lua.bindClassMemberFunction<UIWidget>("isEnabled", &UIWidget::isEnabled);
g_lua.bindClassMemberFunction<UIWidget>("isDisabled", &UIWidget::isDisabled); g_lua.bindClassMemberFunction<UIWidget>("isDisabled", &UIWidget::isDisabled);
@ -85,6 +90,7 @@ void Application::registerLuaFunctions()
g_lua.bindClassMemberFunction<UIWidget>("isFocusable", &UIWidget::isFocusable); g_lua.bindClassMemberFunction<UIWidget>("isFocusable", &UIWidget::isFocusable);
g_lua.bindClassMemberFunction<UIWidget>("isPhantom", &UIWidget::isPhantom); g_lua.bindClassMemberFunction<UIWidget>("isPhantom", &UIWidget::isPhantom);
g_lua.bindClassMemberFunction<UIWidget>("isSizeFixed", &UIWidget::isSizeFixed); g_lua.bindClassMemberFunction<UIWidget>("isSizeFixed", &UIWidget::isSizeFixed);
g_lua.bindClassMemberFunction<UIWidget>("containsPoint", &UIWidget::containsPoint);
g_lua.bindClassMemberFunction<UIWidget>("hasChildren", &UIWidget::hasChildren); g_lua.bindClassMemberFunction<UIWidget>("hasChildren", &UIWidget::hasChildren);
g_lua.bindClassMemberFunction<UIWidget>("hasChild", &UIWidget::hasChild); g_lua.bindClassMemberFunction<UIWidget>("hasChild", &UIWidget::hasChild);
g_lua.bindClassMemberFunction<UIWidget>("getId", &UIWidget::getId); g_lua.bindClassMemberFunction<UIWidget>("getId", &UIWidget::getId);
@ -117,6 +123,8 @@ void Application::registerLuaFunctions()
g_lua.bindClassMemberFunction<UIWidget>("getChildById", &UIWidget::getChildById); g_lua.bindClassMemberFunction<UIWidget>("getChildById", &UIWidget::getChildById);
g_lua.bindClassMemberFunction<UIWidget>("getChildByPos", &UIWidget::getChildByPos); g_lua.bindClassMemberFunction<UIWidget>("getChildByPos", &UIWidget::getChildByPos);
g_lua.bindClassMemberFunction<UIWidget>("getChildByIndex", &UIWidget::getChildByIndex); g_lua.bindClassMemberFunction<UIWidget>("getChildByIndex", &UIWidget::getChildByIndex);
g_lua.bindClassMemberFunction<UIWidget>("getFirstChild", &UIWidget::getFirstChild);
g_lua.bindClassMemberFunction<UIWidget>("getLastChild", &UIWidget::getLastChild);
g_lua.bindClassMemberFunction<UIWidget>("recursiveGetChildById", &UIWidget::recursiveGetChildById); g_lua.bindClassMemberFunction<UIWidget>("recursiveGetChildById", &UIWidget::recursiveGetChildById);
g_lua.bindClassMemberFunction<UIWidget>("recursiveGetChildByPos", &UIWidget::recursiveGetChildByPos); g_lua.bindClassMemberFunction<UIWidget>("recursiveGetChildByPos", &UIWidget::recursiveGetChildByPos);
g_lua.bindClassMemberFunction<UIWidget>("backwardsGetWidgetById", &UIWidget::backwardsGetWidgetById); g_lua.bindClassMemberFunction<UIWidget>("backwardsGetWidgetById", &UIWidget::backwardsGetWidgetById);

View File

@ -35,6 +35,8 @@ void UIManager::init()
m_rootWidget = UIWidget::create<UIWidget>(); m_rootWidget = UIWidget::create<UIWidget>();
m_rootWidget->setId("root"); m_rootWidget->setId("root");
m_rootWidget->resize(g_window.getSize()); m_rootWidget->resize(g_window.getSize());
m_mouseReceiver = m_rootWidget;
m_keyboardReceiver = m_rootWidget;
} }
void UIManager::terminate() void UIManager::terminate()
@ -58,23 +60,23 @@ void UIManager::inputEvent(const InputEvent& event)
{ {
switch(event.type) { switch(event.type) {
case Fw::KeyPressInputEvent: case Fw::KeyPressInputEvent:
m_rootWidget->onKeyPress(event.keyCode, event.keyText, event.keyboardModifiers); m_keyboardReceiver->onKeyPress(event.keyCode, event.keyText, event.keyboardModifiers);
break; break;
case Fw::KeyReleaseInputEvent: case Fw::KeyReleaseInputEvent:
m_rootWidget->onKeyRelease(event.keyCode, event.keyText, event.keyboardModifiers); m_keyboardReceiver->onKeyRelease(event.keyCode, event.keyText, event.keyboardModifiers);
break; break;
case Fw::MousePressInputEvent: case Fw::MousePressInputEvent:
m_rootWidget->onMousePress(event.mousePos, event.mouseButton); m_keyboardReceiver->onMousePress(event.mousePos, event.mouseButton);
break; break;
case Fw::MouseReleaseInputEvent: case Fw::MouseReleaseInputEvent:
m_rootWidget->onMouseRelease(event.mousePos, event.mouseButton); m_mouseReceiver->onMouseRelease(event.mousePos, event.mouseButton);
break; break;
case Fw::MouseMoveInputEvent: case Fw::MouseMoveInputEvent:
m_rootWidget->updateState(Fw::HoverState); m_mouseReceiver->updateState(Fw::HoverState);
m_rootWidget->onMouseMove(event.mousePos, event.mouseMoved); m_mouseReceiver->onMouseMove(event.mousePos, event.mouseMoved);
break; break;
case Fw::MouseWheelInputEvent: case Fw::MouseWheelInputEvent:
m_rootWidget->onMouseWheel(event.mousePos, event.wheelDirection); m_mouseReceiver->onMouseWheel(event.mousePos, event.wheelDirection);
break; break;
}; };
} }

View File

@ -44,15 +44,19 @@ public:
UIWidgetPtr loadUI(const std::string& file, const UIWidgetPtr& parent = nullptr); UIWidgetPtr loadUI(const std::string& file, const UIWidgetPtr& parent = nullptr);
UIWidgetPtr loadWidgetFromOTML(const OTMLNodePtr& widgetNode, const UIWidgetPtr& parent); UIWidgetPtr loadWidgetFromOTML(const OTMLNodePtr& widgetNode, const UIWidgetPtr& parent);
//void setMouseGrabWidget(); void setMouseReceiver(const UIWidgetPtr& widget) { m_mouseReceiver = widget; }
//void setKeyboardGrabWidget(); void setKeyboardReceiver(const UIWidgetPtr& widget) { m_keyboardReceiver = widget; }
void resetMouseReceiver() { m_mouseReceiver = m_rootWidget; }
void resetKeyboardReceiver() { m_keyboardReceiver = m_rootWidget; }
UIWidgetPtr getMouseReceiver() { return m_mouseReceiver; }
UIWidgetPtr getKeyboardReceiver() { return m_keyboardReceiver; }
UIWidgetPtr getRootWidget() { return m_rootWidget; } UIWidgetPtr getRootWidget() { return m_rootWidget; }
private: private:
UIWidgetPtr m_rootWidget; UIWidgetPtr m_rootWidget;
//UIWidgetPtr m_mouseGrabWidget; UIWidgetPtr m_mouseReceiver;
//UIWidgetPtr m_keyboardGrabWidget; UIWidgetPtr m_keyboardReceiver;
std::map<std::string, OTMLNodePtr> m_styles; std::map<std::string, OTMLNodePtr> m_styles;
}; };

View File

@ -52,6 +52,13 @@ void UIWidget::destroy()
setVisible(false); setVisible(false);
setEnabled(false); setEnabled(false);
// release input grabs
if(g_ui.getKeyboardReceiver() == asUIWidget())
g_ui.resetKeyboardReceiver();
if(g_ui.getMouseReceiver() == asUIWidget())
g_ui.resetMouseReceiver();
// remove itself from parent // remove itself from parent
if(UIWidgetPtr parent = getParent()) { if(UIWidgetPtr parent = getParent()) {
if(parent->hasChild(asUIWidget())) if(parent->hasChild(asUIWidget()))
@ -207,6 +214,18 @@ void UIWidget::setRect(const Rect& rect)
m_updateEventScheduled = true; m_updateEventScheduled = true;
} }
void UIWidget::bindRectToParent()
{
Rect boundRect = m_rect;
UIWidgetPtr parent = getParent();
if(parent) {
Rect parentRect = parent->getRect();
boundRect.bound(parentRect);
}
setRect(boundRect);
}
void UIWidget::lock() void UIWidget::lock()
{ {
if(UIWidgetPtr parent = getParent()) if(UIWidgetPtr parent = getParent())
@ -227,6 +246,28 @@ void UIWidget::focus()
parent->focusChild(asUIWidget(), Fw::ActiveFocusReason); parent->focusChild(asUIWidget(), Fw::ActiveFocusReason);
} }
void UIWidget::grabMouse()
{
g_ui.setMouseReceiver(asUIWidget());
}
void UIWidget::ungrabMouse()
{
if(g_ui.getMouseReceiver() == asUIWidget())
g_ui.resetMouseReceiver();
}
void UIWidget::grabKeyboard()
{
g_ui.setKeyboardReceiver(asUIWidget());
}
void UIWidget::ungrabKeyboard()
{
if(g_ui.getKeyboardReceiver() == asUIWidget())
g_ui.resetKeyboardReceiver();
}
bool UIWidget::isVisible() bool UIWidget::isVisible()
{ {
if(!m_visible) if(!m_visible)
@ -282,7 +323,7 @@ UIWidgetPtr UIWidget::getChildByPos(const Point& childPos)
{ {
for(auto it = m_children.rbegin(); it != m_children.rend(); ++it) { for(auto it = m_children.rbegin(); it != m_children.rend(); ++it) {
const UIWidgetPtr& widget = (*it); const UIWidgetPtr& widget = (*it);
if(widget->isExplicitlyVisible() && widget->getRect().contains(childPos)) if(widget->isExplicitlyVisible() && widget->containsPoint(childPos))
return widget; return widget;
} }
@ -313,7 +354,7 @@ UIWidgetPtr UIWidget::recursiveGetChildById(const std::string& id)
UIWidgetPtr UIWidget::recursiveGetChildByPos(const Point& childPos) UIWidgetPtr UIWidget::recursiveGetChildByPos(const Point& childPos)
{ {
for(const UIWidgetPtr& child : m_children) { for(const UIWidgetPtr& child : m_children) {
if(child->getRect().contains(childPos)) { if(child->containsPoint(childPos)) {
if(UIWidgetPtr subChild = child->recursiveGetChildByPos(childPos)) if(UIWidgetPtr subChild = child->recursiveGetChildByPos(childPos))
return subChild; return subChild;
return child; return child;
@ -677,7 +718,7 @@ void UIWidget::updateState(Fw::WidgetState state)
UIWidgetPtr parent; UIWidgetPtr parent;
do { do {
parent = widget->getParent(); parent = widget->getParent();
if(!widget->isExplicitlyEnabled() || !widget->isExplicitlyVisible() || !widget->getRect().contains(mousePos) || if(!widget->isExplicitlyEnabled() || !widget->isExplicitlyVisible() || !widget->containsPoint(mousePos) ||
(parent && widget != parent->getChildByPos(mousePos))) { (parent && widget != parent->getChildByPos(mousePos))) {
newStatus = false; newStatus = false;
break; break;
@ -1035,7 +1076,7 @@ bool UIWidget::onMousePress(const Point& mousePos, Fw::MouseButton button)
continue; continue;
// mouse press events only go to children that contains the mouse position // mouse press events only go to children that contains the mouse position
if(child->getRect().contains(mousePos) && child == getChildByPos(mousePos)) if(child->containsPoint(mousePos) && child == getChildByPos(mousePos))
children.push_back(child); children.push_back(child);
} }
@ -1119,7 +1160,7 @@ bool UIWidget::onMouseWheel(const Point& mousePos, Fw::MouseWheelDirection direc
continue; continue;
// mouse wheel events only go to children that contains the mouse position // mouse wheel events only go to children that contains the mouse position
if(child->getRect().contains(mousePos) && child == getChildByPos(mousePos)) if(child->containsPoint(mousePos) && child == getChildByPos(mousePos))
children.push_back(child); children.push_back(child);
} }

View File

@ -69,6 +69,7 @@ public:
void setSizeFixed(bool fixed) { m_fixedSize = fixed; updateParentLayout(); } void setSizeFixed(bool fixed) { m_fixedSize = fixed; updateParentLayout(); }
void setLastFocusReason(Fw::FocusReason reason) { m_lastFocusReason = reason; } void setLastFocusReason(Fw::FocusReason reason) { m_lastFocusReason = reason; }
void bindRectToParent();
void resize(const Size& size) { setRect(Rect(getPosition(), size)); } void resize(const Size& size) { setRect(Rect(getPosition(), size)); }
void moveTo(const Point& pos) { setRect(Rect(pos, getSize())); } void moveTo(const Point& pos) { setRect(Rect(pos, getSize())); }
void hide() { setVisible(false); } void hide() { setVisible(false); }
@ -78,6 +79,10 @@ public:
void lock(); void lock();
void unlock(); void unlock();
void focus(); void focus();
void grabMouse();
void ungrabMouse();
void grabKeyboard();
void ungrabKeyboard();
bool isActive() { return hasState(Fw::ActiveState); } bool isActive() { return hasState(Fw::ActiveState); }
bool isEnabled() { return !hasState(Fw::DisabledState); } bool isEnabled() { return !hasState(Fw::DisabledState); }
@ -92,6 +97,7 @@ public:
bool isFocusable() { return m_focusable; } bool isFocusable() { return m_focusable; }
bool isPhantom() { return m_phantom; } bool isPhantom() { return m_phantom; }
bool isSizeFixed() { return m_fixedSize; } bool isSizeFixed() { return m_fixedSize; }
bool containsPoint(const Point& point) { return m_rect.contains(point); }
bool hasChildren() { return m_children.size() > 0; } bool hasChildren() { return m_children.size() > 0; }
bool hasChild(const UIWidgetPtr& child); bool hasChild(const UIWidgetPtr& child);
@ -126,6 +132,8 @@ public:
UIWidgetPtr getChildById(const std::string& childId); UIWidgetPtr getChildById(const std::string& childId);
UIWidgetPtr getChildByPos(const Point& childPos); UIWidgetPtr getChildByPos(const Point& childPos);
UIWidgetPtr getChildByIndex(int index); UIWidgetPtr getChildByIndex(int index);
UIWidgetPtr getFirstChild() { return getChildByIndex(1); }
UIWidgetPtr getLastChild() { return getChildByIndex(-1); }
UIWidgetPtr recursiveGetChildById(const std::string& id); UIWidgetPtr recursiveGetChildById(const std::string& id);
UIWidgetPtr recursiveGetChildByPos(const Point& childPos); UIWidgetPtr recursiveGetChildByPos(const Point& childPos);
UIWidgetPtr backwardsGetWidgetById(const std::string& id); UIWidgetPtr backwardsGetWidgetById(const std::string& id);

View File

@ -82,16 +82,7 @@ void UIWindow::onStyleApply(const OTMLNodePtr& styleNode)
void UIWindow::onGeometryUpdate(const Rect& oldRect, const Rect& newRect) void UIWindow::onGeometryUpdate(const Rect& oldRect, const Rect& newRect)
{ {
// bind window rect to parent rect bindRectToParent();
Rect boundRect = newRect;
UIWidgetPtr parent = getParent();
if(parent) {
Rect parentRect = parent->getRect();
boundRect.bound(parentRect);
}
if(boundRect != newRect)
setRect(boundRect);
} }
bool UIWindow::onMousePress(const Point& mousePos, Fw::MouseButton button) bool UIWindow::onMousePress(const Point& mousePos, Fw::MouseButton button)