コード例 #1
0
ファイル: uiwidget.cpp プロジェクト: Pucker/otclient
void UIWidget::updateStyle()
{
    if(m_destroyed)
        return;

    if(m_loadingStyle && !m_updateStyleScheduled) {
        UIWidgetPtr self = static_self_cast<UIWidget>();
        g_dispatcher.addEvent([self] {
            self->m_updateStyleScheduled = false;
            self->updateStyle();
        });
        m_updateStyleScheduled = true;
        return;
    }

    if(!m_style)
        return;

    OTMLNodePtr newStateStyle = OTMLNode::create();

    // copy only the changed styles from default style
    if(m_stateStyle) {
        for(OTMLNodePtr node : m_stateStyle->children()) {
            if(OTMLNodePtr otherNode = m_style->get(node->tag()))
                newStateStyle->addChild(otherNode->clone());
        }
    }

    // checks for states combination
    for(const OTMLNodePtr& style : m_style->children()) {
        if(stdext::starts_with(style->tag(), "$")) {
            std::string statesStr = style->tag().substr(1);
            std::vector<std::string> statesSplit = stdext::split(statesStr, " ");

            bool match = true;
            for(std::string stateStr : statesSplit) {
                if(stateStr.length() == 0)
                    continue;

                bool notstate = (stateStr[0] == '!');
                if(notstate)
                    stateStr = stateStr.substr(1);

                bool stateOn = hasState(Fw::translateState(stateStr));
                if((!notstate && !stateOn) || (notstate && stateOn))
                    match = false;
            }

            // merge states styles
            if(match) {
                newStateStyle->merge(style);
            }
        }
    }

    //TODO: prevent setting already set proprieties

    applyStyle(newStateStyle);
    m_stateStyle = newStateStyle;
}
コード例 #2
0
ファイル: config.cpp プロジェクト: JoseEduardo/otclient
void Config::mergeNode(const std::string& key, const OTMLNodePtr& node)
{
    OTMLNodePtr clone = node->clone();
    node->setTag(key);
    node->setUnique(true);
    m_confsDoc->addChild(node);
}
コード例 #3
0
ファイル: uimanager.cpp プロジェクト: Xenioz/otclient
std::string UIManager::getStyleClass(const std::string& styleName)
{
    OTMLNodePtr style = getStyle(styleName);
    if(style && style->get("__class"))
        return style->valueAt("__class");
    return "";
}
コード例 #4
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;
}
コード例 #5
0
ファイル: otmlnode.cpp プロジェクト: AdamSC1-ddg/otclient
void OTMLNode::merge(const OTMLNodePtr& node)
{
    for(const OTMLNodePtr& child : node->m_children)
        addChild(child->clone());
    setTag(node->tag());
    setSource(node->source());
}
コード例 #6
0
ファイル: config.cpp プロジェクト: JoseEduardo/otclient
std::string Config::getValue(const std::string& key)
{
    OTMLNodePtr child = m_confsDoc->get(key);
    if(child)
        return child->value();
    else
        return "";
}
コード例 #7
0
void ParticleEffectType::load(const OTMLNodePtr& node)
{
    m_node = node->clone();
    for(const OTMLNodePtr& childNode : node->children()) {
        if(childNode->tag() == "name")
            m_name = childNode->value();
        else if(childNode->tag() == "description")
            m_description = childNode->value();
    }
}
コード例 #8
0
ファイル: config.cpp プロジェクト: JoseEduardo/otclient
std::vector<std::string> Config::getList(const std::string& key)
{
    std::vector<std::string> list;
    OTMLNodePtr child = m_confsDoc->get(key);
    if(child) {
        for(const OTMLNodePtr& subchild : child->children())
            list.push_back(subchild->value());
    }
    return list;
}
コード例 #9
0
ファイル: uimanager.cpp プロジェクト: Xenioz/otclient
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;
}
コード例 #10
0
ファイル: otmlnode.cpp プロジェクト: AdamSC1-ddg/otclient
void OTMLNode::copy(const OTMLNodePtr& node)
{
    setTag(node->tag());
    setValue(node->rawValue());
    setUnique(node->isUnique());
    setNull(node->isNull());
    setSource(node->source());
    clear();
    for(const OTMLNodePtr& child : node->m_children)
        addChild(child->clone());
}
コード例 #11
0
ファイル: uiwidget.cpp プロジェクト: Pucker/otclient
void UIWidget::setStyle(const std::string& styleName)
{
    OTMLNodePtr styleNode = g_ui.getStyle(styleName);
    if(!styleNode) {
        g_logger.traceError(stdext::format("unable to retrieve style '%s': not a defined style", styleName));
        return;
    }
    styleNode = styleNode->clone();
    applyStyle(styleNode);
    m_style = styleNode;
    updateStyle();
}
コード例 #12
0
ファイル: uiwidget.cpp プロジェクト: Cayan/otclient
void UIWidget::setStyle(const std::string& styleName)
{
    OTMLNodePtr styleNode = g_ui.getStyle(styleName);
    if(!styleNode) {
        logTraceError("unable to retrive style '", styleName, "': not a defined style");
        return;
    }
    styleNode = styleNode->clone();
    applyStyle(styleNode);
    m_style = styleNode;
    updateStyle();
}
コード例 #13
0
ファイル: config.cpp プロジェクト: JoseEduardo/otclient
void Config::setList(const std::string& key, const std::vector<std::string>& list)
{
    remove(key);

    if(list.size() == 0)
        return;

    OTMLNodePtr child = OTMLNode::create(key, true);
    for(const std::string& value : list)
        child->writeIn(value);
    m_confsDoc->addChild(child);
}
コード例 #14
0
ファイル: uimanager.cpp プロジェクト: Xenioz/otclient
OTMLNodePtr UIManager::getStyle(const std::string& styleName)
{
    auto it = m_styles.find(styleName);
    if(it != m_styles.end())
        return m_styles[styleName];

    // styles starting with UI are automatically defined
    if(stdext::starts_with(styleName, "UI")) {
        OTMLNodePtr node = OTMLNode::create(styleName);
        node->writeAt("__class", styleName);
        m_styles[styleName] = node;
        return node;
    }

    return nullptr;
}
コード例 #15
0
ファイル: particleaffector.cpp プロジェクト: Cayan/otclient
bool ParticleAffector::load(const OTMLNodePtr& node)
{
    float minDelay = 0, maxDelay = 0;
    float minDuration = -1, maxDuration = -1;

    for(const OTMLNodePtr& childNode : node->children()) {
        if(childNode->tag() == "delay") {
            minDelay = childNode->value<float>();
            maxDelay = childNode->value<float>();
        }
        else if(childNode->tag() == "min-delay")
            minDelay = childNode->value<float>();
        else if(childNode->tag() == "max-delay")
            maxDelay = childNode->value<float>();

        if(childNode->tag() == "duration") {
            minDuration = childNode->value<float>();
            maxDuration = childNode->value<float>();
        }
        else if(childNode->tag() == "min-duration")
            minDuration = childNode->value<float>();
        else if(childNode->tag() == "max-duration")
            maxDuration = childNode->value<float>();
    }

    m_delay = Fw::randomRange(minDelay, maxDelay);
    m_duration = Fw::randomRange(minDuration, maxDuration);

    return true;
}
コード例 #16
0
ファイル: module.cpp プロジェクト: LeandroPerrotta/otclient
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());
    }
}
コード例 #17
0
void UIProgressRect::onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode)
{
    UIWidget::onStyleApply(styleName, styleNode);

    for(const OTMLNodePtr& node : styleNode->children()) {
        if(node->tag() == "percent")
            setPercent(node->value<float>());
    }
}
コード例 #18
0
void UIHorizontalLayout::applyStyle(const OTMLNodePtr& styleNode)
{
    UIBoxLayout::applyStyle(styleNode);

    for(const OTMLNodePtr& node : styleNode->children()) {
        if(node->tag() == "align-right")
            setAlignRight(node->value<bool>());
    }
}
コード例 #19
0
ファイル: bitmapfont.cpp プロジェクト: AdamSC1-ddg/otclient
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);
    }
}
コード例 #20
0
ファイル: uimanager.cpp プロジェクト: Xenioz/otclient
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;
    }
}
コード例 #21
0
ファイル: modulemanager.cpp プロジェクト: brun123/otclient
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;
}
コード例 #22
0
ファイル: uiwidget.cpp プロジェクト: AndreFaramir/otclient
void UIWidget::onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode)
{
    // first set id
    if(const OTMLNodePtr& node = styleNode->get("id"))
        setId(node->value());

    parseBaseStyle(styleNode);
    parseImageStyle(styleNode);
    parseTextStyle(styleNode);
}
コード例 #23
0
ファイル: uiwidget.cpp プロジェクト: Pucker/otclient
void UIWidget::applyStyle(const OTMLNodePtr& styleNode)
{
    if(m_destroyed)
        return;

    if(styleNode->size() == 0)
        return;

    m_loadingStyle = true;
    try {
        // translate ! style tags
        for(const OTMLNodePtr& node : styleNode->children()) {
            if(node->tag()[0] == '!') {
                std::string tag = node->tag().substr(1);
                std::string code = stdext::format("tostring(%s)", node->value());
                std::string origin = "@" + node->source() + ": [" + node->tag() + "]";
                g_lua.evaluateExpression(code, origin);
                std::string value = g_lua.popString();

                node->setTag(tag);
                node->setValue(value);
            }
        }

        onStyleApply(styleNode->tag(), styleNode);
        callLuaField("onStyleApply", styleNode->tag(), styleNode);

        if(m_firstOnStyle) {
            UIWidgetPtr parent = getParent();
            if(isFocusable() && isExplicitlyVisible() && isExplicitlyEnabled() &&
               parent && ((!parent->getFocusedChild() && parent->getAutoFocusPolicy() == Fw::AutoFocusFirst) ||
                           parent->getAutoFocusPolicy() == Fw::AutoFocusLast)) {
                focus();
            }
        }

        m_firstOnStyle = false;
    } catch(stdext::exception& e) {
        g_logger.traceError(stdext::format("failed to apply style to widget '%s': %s", m_id, e.what()));
    }
    m_loadingStyle = false;
}
コード例 #24
0
ファイル: uiboxlayout.cpp プロジェクト: Xenioz/otclient
void UIBoxLayout::applyStyle(const OTMLNodePtr& styleNode)
{
    UILayout::applyStyle(styleNode);

    for(const OTMLNodePtr& node : styleNode->children()) {
        if(node->tag() == "spacing")
            setSpacing(node->value<int>());
        else if(node->tag() == "fit-children")
            setFitChildren(node->value<bool>());
    }
}
コード例 #25
0
ファイル: luavaluecasts.cpp プロジェクト: HeberPcL/otclient
// otml nodes
void push_otml_subnode_luavalue(const OTMLNodePtr& node)
{
    if(node->hasValue()) {
        union {
            bool b;
            double d;
            long l;
        };
        std::string value = node->rawValue();
        if(stdext::cast(value, b))
            g_lua.pushBoolean(b);
        else if(stdext::cast(value, l))
            g_lua.pushInteger(l);
        else if(stdext::cast(value, d))
            g_lua.pushNumber(d);
        else
            g_lua.pushString(value);
    } else if(node->hasChildren()) {
        g_lua.newTable();
        bool pushedChild = false;
        int currentIndex = 1;
        for(const OTMLNodePtr& cnode : node->children()) {
            push_otml_subnode_luavalue(cnode);
            if(!g_lua.isNil()) {
                if(cnode->isUnique()) {
                    g_lua.pushString(cnode->tag());
                    g_lua.insert(-2);
                    g_lua.rawSet();
                } else
                    g_lua.rawSeti(currentIndex++);
                pushedChild = true;
            } else
                g_lua.pop();
        }
        if(!pushedChild) {
            g_lua.pop();
            g_lua.pushNil();
        }
    } else
        g_lua.pushNil();
}
コード例 #26
0
ファイル: uiminimap.cpp プロジェクト: Cadyan/otclient
void UIMinimap::onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode)
{
    UIWidget::onStyleApply(styleName, styleNode);
    for(const OTMLNodePtr& node : styleNode->children()) {
        if(node->tag() == "zoom")
            setZoom(node->value<int>());
        else if(node->tag() == "max-zoom")
            setMaxZoom(node->value<int>());
        else if(node->tag() == "min-zoom")
            setMinZoom(node->value<int>());
    }
}
コード例 #27
0
ファイル: uiwidget.cpp プロジェクト: Cayan/otclient
void UIWidget::applyStyle(const OTMLNodePtr& styleNode)
{
    if(m_destroyed)
        return;

    if(styleNode->size() == 0)
        return;

    m_loadingStyle = true;
    try {
        // translate ! style tags
        for(const OTMLNodePtr& node : styleNode->children()) {
            if(node->tag()[0] == '!') {
                std::string tag = node->tag().substr(1);
                std::string code = Fw::formatString("tostring(%s)", node->value().c_str());
                std::string origin = "@" + node->source() + "[" + node->tag() + "]";
                g_lua.evaluateExpression(code, origin);
                std::string value = g_lua.popString();

                node->setTag(tag);
                node->setValue(value);
            }
        }

        onStyleApply(styleNode->tag(), styleNode);
        callLuaField("onStyleApply", styleNode->tag(), styleNode);

        if(m_firstOnStyle) {
            callLuaField("onSetup");
            // always focus new child
            if(isFocusable() && isExplicitlyVisible() && isExplicitlyEnabled())
                focus();
        }
        m_firstOnStyle = false;
    } catch(Exception& e) {
        logError("Failed to apply style to widget '", m_id, "' style: ", e.what());
    }
    m_loadingStyle = false;
}
コード例 #28
0
ファイル: uiwidget.cpp プロジェクト: AndreFaramir/otclient
void UIWidget::applyStyle(const OTMLNodePtr& styleNode)
{
    if(styleNode->size() == 0)
        return;

    m_loadingStyle = true;
    try {
        onStyleApply(styleNode->tag(), styleNode);
        callLuaField("onStyleApply", styleNode->tag(), styleNode);

        if(m_firstOnStyle) {
            callLuaField("onSetup");
            // always focus new child
            if(isFocusable() && isExplicitlyVisible() && isExplicitlyEnabled())
                focus();
        }
        m_firstOnStyle = false;

    } catch(Exception& e) {
        logError("Failed to apply style to widget '", m_id, "' style: ", e.what());
    }
    m_loadingStyle = false;
}
コード例 #29
0
ファイル: uiwidget.cpp プロジェクト: Pucker/otclient
void UIWidget::onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode)
{
    if(m_destroyed)
        return;

    // first set id
    if(const OTMLNodePtr& node = styleNode->get("id"))
        setId(node->value());

    parseBaseStyle(styleNode);
    parseImageStyle(styleNode);
    parseTextStyle(styleNode);

    g_app.repaint();
}
コード例 #30
0
ファイル: luavaluecasts.cpp プロジェクト: HeberPcL/otclient
int push_luavalue(const OTMLNodePtr& node)
{
    if(node) {
        g_lua.newTable();
        int currentIndex = 1;
        for(const OTMLNodePtr& cnode : node->children()) {
            push_otml_subnode_luavalue(cnode);
            if(cnode->isUnique() && !cnode->tag().empty()) {
                g_lua.setField(cnode->tag());
            } else
                g_lua.rawSeti(currentIndex++);
        }
    } else
        g_lua.pushNil();
    return 1;
}