tibia-client/src/framework/ui/uimanager.cpp

186 lines
5.5 KiB
C++
Raw Normal View History

2011-08-14 04:09:11 +02:00
#include "uimanager.h"
#include "ui.h"
2011-08-15 16:06:15 +02:00
#include <framework/otml/otml.h>
#include <framework/graphics/graphics.h>
2011-08-14 04:09:11 +02:00
UIManager g_ui;
void UIManager::init()
{
// creates root widget
m_rootWidget = UIWidgetPtr(new UIWidget);
m_rootWidget->setId("root");
m_rootWidget->setHovered(true);
2011-08-14 04:09:11 +02:00
m_rootWidget->resize(g_graphics.getScreenSize());
}
void UIManager::terminate()
{
// destroy root widget and its children'
m_rootWidget->destroy();
m_rootWidget.reset();
}
void UIManager::render()
{
m_rootWidget->render();
2011-08-14 04:09:11 +02:00
}
void UIManager::resize(const Size& size)
{
if(m_rootWidget)
m_rootWidget->resize(size);
}
2011-08-15 21:15:49 +02:00
void UIManager::inputEvent(const PlatformEvent& event)
2011-08-14 04:09:11 +02:00
{
// translate input event to ui events
if(m_rootWidget) {
if(event.type & EventKeyboardAction) {
2011-08-22 14:44:26 +02:00
int keyboardModifiers = UI::KeyboardNoModifier;
2011-08-14 04:09:11 +02:00
if(event.ctrl)
2011-08-22 14:44:26 +02:00
keyboardModifiers |= UI::KeyboardCtrlModifier;
2011-08-14 04:09:11 +02:00
if(event.shift)
2011-08-22 14:44:26 +02:00
keyboardModifiers |= UI::KeyboardShiftModifier;
2011-08-14 04:09:11 +02:00
if(event.alt)
2011-08-22 14:44:26 +02:00
keyboardModifiers |= UI::KeyboardAltModifier;
2011-08-14 04:09:11 +02:00
if(event.type == EventKeyDown)
2011-08-22 14:44:26 +02:00
m_rootWidget->onKeyPress(event.keycode, event.keychar, keyboardModifiers);
2011-08-14 04:09:11 +02:00
else
2011-08-22 14:44:26 +02:00
m_rootWidget->onKeyRelease(event.keycode, event.keychar, keyboardModifiers);
2011-08-14 04:09:11 +02:00
} else if(event.type & EventMouseAction) {
if(event.type == EventMouseMove) {
2011-08-22 14:44:26 +02:00
m_rootWidget->onMouseMove(event.mousePos, event.mouseMoved);
2011-08-14 04:09:11 +02:00
}
else if(event.type & EventMouseWheel) {
2011-08-22 14:44:26 +02:00
UI::MouseWheelDirection dir = UI::MouseNoWheel;
2011-08-14 04:09:11 +02:00
if(event.type & EventDown)
2011-08-22 14:44:26 +02:00
dir = UI::MouseWheelDown;
2011-08-14 04:09:11 +02:00
else if(event.type & EventUp)
2011-08-22 14:44:26 +02:00
dir = UI::MouseWheelUp;
2011-08-22 14:44:26 +02:00
m_rootWidget->onMouseWheel(event.mousePos, dir);
2011-08-14 04:09:11 +02:00
} else {
2011-08-22 14:44:26 +02:00
UI::MouseButton button = UI::MouseNoButton;
2011-08-14 04:09:11 +02:00
if(event.type & EventMouseLeftButton)
2011-08-22 14:44:26 +02:00
button = UI::MouseLeftButton;
2011-08-14 04:09:11 +02:00
else if(event.type & EventMouseMidButton)
2011-08-22 14:44:26 +02:00
button = UI::MouseMidButton;
2011-08-14 04:09:11 +02:00
else if(event.type & EventMouseRightButton)
2011-08-22 14:44:26 +02:00
button = UI::MouseRightButton;
2011-08-14 04:09:11 +02:00
if(event.type & EventDown)
2011-08-22 14:44:26 +02:00
m_rootWidget->onMousePress(event.mousePos, button);
2011-08-14 04:09:11 +02:00
else if(event.type & EventUp)
2011-08-22 14:44:26 +02:00
m_rootWidget->onMouseRelease(event.mousePos, button);
2011-08-14 04:09:11 +02:00
}
}
}
}
bool UIManager::importStyles(const std::string& file)
{
try {
OTMLDocumentPtr doc = OTMLDocument::parse(file);
for(const OTMLNodePtr& styleNode : doc->children())
2011-08-14 04:09:11 +02:00
importStyleFromOTML(styleNode);
return true;
} catch(std::exception& e) {
2011-08-20 22:30:41 +02:00
logError("failed to import ui styles from '", file, "':\n", e.what());
2011-08-14 04:09:11 +02:00
return false;
}
}
void UIManager::importStyleFromOTML(const OTMLNodePtr& styleNode)
{
std::string tag = styleNode->tag();
std::vector<std::string> split;
boost::split(split, tag, boost::is_any_of(std::string("<")));
if(split.size() != 2)
throw OTMLException(styleNode, "not a valid style declaration");
std::string name = split[0];
std::string base = split[1];
boost::trim(name);
boost::trim(base);
auto it = m_styles.find(name);
if(it != m_styles.end())
2011-08-20 22:30:41 +02:00
logWarning("style '", name, "' is being redefined");
2011-08-14 04:09:11 +02:00
OTMLNodePtr style = getStyle(base)->clone();
style->merge(styleNode);
style->setTag(name);
m_styles[name] = style;
}
OTMLNodePtr UIManager::getStyle(const std::string& styleName)
{
if(boost::starts_with(styleName, "UI")) {
OTMLNodePtr node = OTMLNode::create();
2011-08-14 04:09:11 +02:00
node->writeAt("__widgetType", styleName);
return node;
}
auto it = m_styles.find(styleName);
if(it == m_styles.end())
throw std::runtime_error(fw::mkstr("style '", styleName, "' is not a defined style"));
2011-08-14 04:09:11 +02:00
return m_styles[styleName];
}
UIWidgetPtr UIManager::loadUI(const std::string& file)
{
try {
OTMLDocumentPtr doc = OTMLDocument::parse(file);
UIWidgetPtr widget;
for(const OTMLNodePtr& node : doc->children()) {
2011-08-14 04:09:11 +02:00
std::string tag = node->tag();
// import styles in these files too
if(tag.find("<") != std::string::npos)
importStyleFromOTML(node);
else {
if(widget)
throw std::runtime_error("cannot have multiple main widgets in .otui files");
2011-08-14 04:09:11 +02:00
widget = loadWidgetFromOTML(node);
}
}
2011-08-14 04:09:11 +02:00
return widget;
} catch(std::exception& e) {
2011-08-20 22:30:41 +02:00
logError("failed to load ui from '", file, "':\n", e.what());
2011-08-14 04:09:11 +02:00
return nullptr;
}
}
UIWidgetPtr UIManager::loadWidgetFromOTML(const OTMLNodePtr& widgetNode)
{
OTMLNodePtr styleNode = getStyle(widgetNode->tag())->clone();
styleNode->merge(widgetNode);
std::string widgetType = styleNode->valueAt("__widgetType");
2011-08-14 04:09:11 +02:00
2011-08-22 21:13:52 +02:00
// call widget creation from lua
//g_lua.getGlobalField(widgetType, "create");
g_lua.getGlobal(widgetType);
g_lua.getField("create");
g_lua.remove(-2);
g_lua.protectedCall(0, 1);
UIWidgetPtr widget = g_lua.polymorphicPop<UIWidgetPtr>();
2011-08-14 04:09:11 +02:00
2011-08-22 14:44:26 +02:00
widget->onStyleApply(styleNode);
2011-08-21 21:43:05 +02:00
widget->updateLayout();
2011-08-14 04:09:11 +02:00
for(const OTMLNodePtr& childNode : widgetNode->children()) {
2011-08-14 04:09:11 +02:00
if(!childNode->isUnique())
widget->addChild(loadWidgetFromOTML(childNode));
}
return widget;
}