示例#1
0
void Module::discover(const OTMLNodePtr& moduleNode)
{
    const static std::string none = "none";
    m_description = moduleNode->valueAt("description", none);
    m_author = moduleNode->valueAt("author", none);
    m_website = moduleNode->valueAt("website", none);
    m_version = moduleNode->valueAt("version", none);
    m_autoLoad = moduleNode->valueAt<bool>("autoload", false);
    m_reloadable = moduleNode->valueAt<bool>("reloadable", true);
    m_autoLoadPriority = moduleNode->valueAt<int>("autoload-priority", 9999);

    if(OTMLNodePtr node = moduleNode->get("dependencies")) {
        for(const OTMLNodePtr& tmp : node->children())
            m_dependencies.push_back(tmp->value());
    }

    // set onLoad callback
    if(OTMLNodePtr node = moduleNode->get("@onLoad")) {
        g_lua.loadFunction(node->value(), "@" + node->source() + "[" + node->tag() + "]");
        g_lua.useValue();
        m_loadCallback = g_lua.polymorphicPop<std::function<void()>>();
    }

    // set onUnload callback
    if(OTMLNodePtr node = moduleNode->get("@onUnload")) {
        g_lua.loadFunction(node->value(), "@" + node->source() + "[" + node->tag() + "]");
        g_lua.useValue();
        m_unloadCallback = g_lua.polymorphicPop<std::function<void()>>();
    }

    if(OTMLNodePtr node = moduleNode->get("load-later")) {
        for(const OTMLNodePtr& tmp : node->children())
            m_loadLaterModules.push_back(tmp->value());
    }
}
示例#2
0
void BitmapFont::load(const OTMLNodePtr& fontNode)
{
    OTMLNodePtr textureNode = fontNode->at("texture");
    std::string textureFile = stdext::resolve_path(textureNode->value(), textureNode->source());
    Size glyphSize = fontNode->valueAt<Size>("glyph-size");
    m_glyphHeight = fontNode->valueAt<int>("height");
    m_yOffset = fontNode->valueAt("y-offset", 0);
    m_firstGlyph = fontNode->valueAt("first-glyph", 32);
    m_glyphSpacing = fontNode->valueAt("spacing", Size(0,0));
    int spaceWidth = fontNode->valueAt("space-width", glyphSize.width());

    // load font texture
    m_texture = g_textures.getTexture(textureFile);

    if(OTMLNodePtr node = fontNode->get("fixed-glyph-width")) {
        for(int glyph = m_firstGlyph; glyph < 256; ++glyph)
            m_glyphsSize[glyph] = Size(node->value<int>(), m_glyphHeight);
    } else {
        calculateGlyphsWidthsAutomatically(Image::load(textureFile), glyphSize);
    }

    // 32 and 160 are spaces (&nbsp;)
    m_glyphsSize[32].setWidth(spaceWidth);
    m_glyphsSize[160].setWidth(spaceWidth);

    // use 127 as spacer [Width: 1], Important for the current NPC highlighting system
    m_glyphsSize[127].setWidth(1);

    // new line actually has a size that will be useful in multiline algorithm
    m_glyphsSize[(uchar)'\n'] = Size(1, m_glyphHeight);

    // read custom widths
    /*
    if(OTMLNodePtr node = fontNode->get("glyph-widths")) {
        for(const OTMLNodePtr& child : node->children())
            m_glyphsSize[stdext::safe_cast<int>(child->tag())].setWidth(child->value<int>());
    }
    */


    // calculate glyphs texture coords
    int numHorizontalGlyphs = m_texture->getSize().width() / glyphSize.width();
    for(int glyph = m_firstGlyph; glyph < 256; ++glyph) {
        m_glyphsTextureCoords[glyph].setRect(((glyph - m_firstGlyph) % numHorizontalGlyphs) * glyphSize.width(),
                                                ((glyph - m_firstGlyph) / numHorizontalGlyphs) * glyphSize.height(),
                                                m_glyphsSize[glyph].width(),
                                                m_glyphHeight);
    }
}
示例#3
0
UIWidgetPtr UIManager::createWidgetFromOTML(const OTMLNodePtr& widgetNode, const UIWidgetPtr& parent)
{
    OTMLNodePtr originalStyleNode = getStyle(widgetNode->tag());
    if(!originalStyleNode)
        stdext::throw_exception(stdext::format("'%s' is not a defined style", widgetNode->tag()));

    OTMLNodePtr styleNode = originalStyleNode->clone();
    styleNode->merge(widgetNode);

    std::string widgetType = styleNode->valueAt("__class");

    // call widget creation from lua
    UIWidgetPtr widget = g_lua.callGlobalField<UIWidgetPtr>(widgetType, "create");
    if(parent)
        parent->addChild(widget);

    if(widget) {
        widget->callLuaField("onCreate");

        widget->setStyleFromNode(styleNode);

        for(const OTMLNodePtr& childNode : styleNode->children()) {
            if(!childNode->isUnique()) {
                createWidgetFromOTML(childNode, widget);
                styleNode->removeChild(childNode);
            }
        }
    } else
        stdext::throw_exception(stdext::format("unable to create widget of type '%s'", widgetType));

    widget->callLuaField("onSetup");
    return widget;
}
示例#4
0
std::string UIManager::getStyleClass(const std::string& styleName)
{
    OTMLNodePtr style = getStyle(styleName);
    if(style && style->get("__class"))
        return style->valueAt("__class");
    return "";
}
示例#5
0
ModulePtr ModuleManager::discoverModule(const std::string& moduleFile)
{
    ModulePtr module;
    try {
        OTMLDocumentPtr doc = OTMLDocument::parse(moduleFile);
        OTMLNodePtr moduleNode = doc->at("Module");

        std::string name = moduleNode->valueAt("name");

        bool push = false;
        module = getModule(name);
        if(!module) {
            module = ModulePtr(new Module(name));
            push = true;
        }
        module->discover(moduleNode);

        // not loaded modules are always in back
        if(push)
            m_modules.push_back(module);
    } catch(stdext::exception& e) {
        g_logger.error(stdext::format("Unable to discover module from file '%s': %s", moduleFile, e.what()));
    }
    return module;
}
示例#6
0
文件: font.cpp 项目: Cayan/otclient
void Font::load(const OTMLNodePtr& fontNode)
{
    OTMLNodePtr textureNode = fontNode->at("texture");
    std::string textureFile = Fw::resolvePath(textureNode->value(), textureNode->source());
    Size glyphSize = fontNode->valueAt<Size>("glyph-size");
    m_glyphHeight = fontNode->valueAt<int>("height");
    m_yOffset = fontNode->valueAt("y-offset", 0);
    m_firstGlyph = fontNode->valueAt("first-glyph", 32);
    m_glyphSpacing = fontNode->valueAt("spacing", Size(0,0));

    // load font texture
    m_texture = g_textures.getTexture(textureFile);

    if(OTMLNodePtr node = fontNode->get("fixed-glyph-width")) {
        for(int glyph = m_firstGlyph; glyph < 256; ++glyph)
            m_glyphsSize[glyph] = Size(node->value<int>(), m_glyphHeight);
    } else {
        calculateGlyphsWidthsAutomatically(Image::load(textureFile), glyphSize);
    }

    // new line actually has a size that will be useful in multiline algorithm
    m_glyphsSize[(uchar)'\n'] = Size(1, m_glyphHeight);

    // read custom widths
    if(OTMLNodePtr node = fontNode->get("glyph-widths")) {
        for(const OTMLNodePtr& child : node->children())
            m_glyphsSize[Fw::safeCast<int>(child->tag())].setWidth(child->value<int>());
    }

    // calculate glyphs texture coords
    int numHorizontalGlyphs = m_texture->getSize().width() / glyphSize.width();
    for(int glyph = m_firstGlyph; glyph < 256; ++glyph) {
        m_glyphsTextureCoords[glyph].setRect(((glyph - m_firstGlyph) % numHorizontalGlyphs) * glyphSize.width(),
                                                ((glyph - m_firstGlyph) / numHorizontalGlyphs) * glyphSize.height(),
                                                m_glyphsSize[glyph].width(),
                                                m_glyphHeight);
    }
}
示例#7
0
void UIManager::importStyleFromOTML(const OTMLNodePtr& styleNode)
{
    std::string tag = styleNode->tag();
    std::vector<std::string> split = stdext::split(tag, "<");
    if(split.size() != 2)
        throw OTMLException(styleNode, "not a valid style declaration");

    std::string name = split[0];
    std::string base = split[1];
    bool unique = false;

    stdext::trim(name);
    stdext::trim(base);

    if(name[0] == '#') {
        name = name.substr(1);
        unique = true;

        styleNode->setTag(name);
        styleNode->writeAt("__unique", true);
    }

    OTMLNodePtr oldStyle = m_styles[name];

    // Warn about redefined styles
    /*
    if(!g_app.isRunning() && (oldStyle && !oldStyle->valueAt("__unique", false))) {
        auto it = m_styles.find(name);
        if(it != m_styles.end())
            g_logger.warning(stdext::format("style '%s' is being redefined", name));
    }
    */

    if(!oldStyle || !oldStyle->valueAt("__unique", false) || unique) {
        OTMLNodePtr originalStyle = getStyle(base);
        if(!originalStyle)
            stdext::throw_exception(stdext::format("base style '%s', is not defined", base));
        OTMLNodePtr style = originalStyle->clone();
        style->merge(styleNode);
        style->setTag(name);
        m_styles[name] = style;
    }
}
示例#8
0
ModulePtr ModuleManager::discoverModule(const std::string& moduleFile)
{
    ModulePtr module;
    try {
        OTMLDocumentPtr doc = OTMLDocument::parse(moduleFile);
        OTMLNodePtr moduleNode = doc->at("Module");

        std::string name = moduleNode->valueAt("name");
        if(getModule(name))
            Fw::throwException("module '", name, "' already exists, cannot have duplicate module names");

        module = ModulePtr(new Module(name));
        module->discover(moduleNode);
        m_modules.push_back(module);
    } catch(Exception& e) {
        logError("Unable to discover module from file '", moduleFile, "': ", e.what());
    }
    return module;
}
示例#9
0
BorderImagePtr BorderImage::loadFromOTML(const OTMLNodePtr& borderImageNode)
{
    Rect leftBorder;
    Rect rightBorder;
    Rect topBorder;
    Rect bottomBorder;
    Rect topLeftCorner;
    Rect topRightCorner;
    Rect bottomLeftCorner;
    Rect bottomRightCorner;
    Rect center;
    Rect subRect;
    int top, bottom, left, right, border;
    Size size;
    Point offset;

    // load texture
    std::string source = borderImageNode->at("source")->value();
    TexturePtr texture = g_textures.getTexture(source);

    // load basic border confs
    size = texture->getSize();
    size = borderImageNode->valueAt("size", size);
    offset = borderImageNode->valueAt("offset", offset);
    border = borderImageNode->valueAt("border", 0);
    subRect = Rect(offset, size);

    // load border margins
    top = bottom = left = right = border;
    top = borderImageNode->valueAt("border.top", top);
    bottom = borderImageNode->valueAt("border.bottom", bottom);
    left = borderImageNode->valueAt("border.left", left);
    right = borderImageNode->valueAt("border.right", right);

    // calculates border coords
    leftBorder = Rect(subRect.left(), subRect.top() + top, left, subRect.height() - top - bottom);
    rightBorder = Rect(subRect.right() - right + 1, subRect.top() + top, right, subRect.height() - top - bottom);
    topBorder = Rect(subRect.left() + left, subRect.top(), subRect.width() - right - left, top);
    bottomBorder = Rect(subRect.left() + left, subRect.bottom() - bottom + 1, subRect.width() - right - left, bottom);
    topLeftCorner = Rect(subRect.left(), subRect.top(), left, top);
    topRightCorner = Rect(subRect.right() - right + 1, subRect.top(), right, top);
    bottomLeftCorner = Rect(subRect.left(), subRect.bottom() - bottom + 1, left, bottom);
    bottomRightCorner = Rect(subRect.right() - right + 1, subRect.bottom() - bottom + 1, right, bottom);
    center = Rect(subRect.left() + left, subRect.top() + top, subRect.width() - right - left, subRect.height() - top - bottom);

    // load individual border conf if supplied
    /*
    leftBorder = borderImageNode->valueAt("left border", leftBorder);
    rightBorder = borderImageNode->valueAt("right border", rightBorder);
    topBorder = borderImageNode->valueAt("top border", topBorder);
    bottomBorder = borderImageNode->valueAt("bottom border", bottomBorder);
    topLeftCorner = borderImageNode->valueAt("top left corner", topLeftCorner);
    topRightCorner = borderImageNode->valueAt("top right corner", topRightCorner);
    bottomLeftCorner = borderImageNode->valueAt("bottom left corner", bottomLeftCorner);
    bottomRightCorner = borderImageNode->valueAt("bottom right corner", bottomRightCorner);
    center = borderImageNode->valueAt("center", center);
    */

    return BorderImagePtr(new BorderImage(texture,
                            leftBorder,
                            rightBorder,
                            topBorder,
                            bottomBorder,
                            topLeftCorner,
                            topRightCorner,
                            bottomLeftCorner,
                            bottomRightCorner,
                            center));
}