<commit_before>#include <QtWidgets>
#include "codeeditor.h"

void
CodeEditor::initUI(void)
{
    QFont font("Courier New");
    font.setStyleHint(QFont::Monospace);
    setFont(font);

    const int tabStop = 2;  // 4 characters

    QFontMetrics metrics(font);
    setTabStopWidth(tabStop * metrics.width(' '));

    lineNumberArea = new LineNumberArea(this);

    connect(this, SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberAreaWidth(int)));
    connect(this, SIGNAL(updateRequest(QRect,int)), this, SLOT(updateLineNumberArea(QRect,int)));
    connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(highlightCurrentLine()));

    updateLineNumberAreaWidth(0);
    highlightCurrentLine();
    highlighter = new Highlighter(document());

    QTextCursor cursor(textCursor());
    cursor.movePosition(QTextCursor::Start);
    setTextCursor(cursor);
    ensureCursorVisible();
    setFocus();
}

CodeEditor::CodeEditor(QFile& file, QWidget *parent) :
    QPlainTextEdit(parent)
{
    initUI();
    if (file.isOpen()) {
        setPlainText(file.readAll());
        filepath = QFileInfo(file).absoluteFilePath();
        filename = QFileInfo(file).fileName();
    } else {
        filepath = "";
        filename = "Untitled";
    }
    connect(document(), SIGNAL(contentsChange(int,int,int)), this, SLOT(replaceTabs(int,int,int)));
}

void CodeEditor::replaceTabs(int pos,int,int add)
{
    if (add>0) {
        QTextCursor cursor(document());
        cursor.setPosition(pos);
        cursor.movePosition(QTextCursor::Right,QTextCursor::KeepAnchor,add);
        QString sel = cursor.selectedText();
        if (sel.indexOf('\t')!=-1) {
            sel = sel.replace('\t',"  ");
            cursor.insertText(sel);
        }
    }
}

int CodeEditor::lineNumberAreaWidth()
{
    int digits = 1;
    int max = qMax(1, blockCount());
    while (max >= 10) {
        max /= 10;
        ++digits;
    }

    int space = 3 + fontMetrics().width(QLatin1Char('9')) * digits;

    return space;
}

void CodeEditor::updateLineNumberAreaWidth(int /* newBlockCount */)
{
    setViewportMargins(lineNumberAreaWidth(), 0, 0, 0);
}

void CodeEditor::updateLineNumberArea(const QRect &rect, int dy)
{
    if (dy)
        lineNumberArea->scroll(0, dy);
    else
        lineNumberArea->update(0, rect.y(), lineNumberArea->width(), rect.height());

    if (rect.contains(viewport()->rect()))
        updateLineNumberAreaWidth(0);
}

void CodeEditor::resizeEvent(QResizeEvent *e)
{
    QPlainTextEdit::resizeEvent(e);

    QRect cr = contentsRect();
    lineNumberArea->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height()));
}

void CodeEditor::highlightCurrentLine()
{
    QList<QTextEdit::ExtraSelection> extraSelections;

    if (!isReadOnly()) {
        QTextEdit::ExtraSelection selection;

        QColor lineColor = QColor(Qt::yellow).lighter(160);

        selection.format.setBackground(lineColor);
        selection.format.setProperty(QTextFormat::FullWidthSelection, true);
        selection.cursor = textCursor();
        selection.cursor.clearSelection();
        extraSelections.append(selection);
    }

    BracketData* bd = static_cast<BracketData*>(textCursor().block().userData());

    if (bd) {
        QVector<Bracket>& brackets = bd->brackets;
        int pos = textCursor().block().position();
        for (int i=0; i<brackets.size(); i++) {
            int curPos = textCursor().position()-textCursor().block().position();
            Bracket& b = brackets[i];
            int parenPos0 = -1;
            int parenPos1 = -1;
            int errPos = -1;
            if (b.pos == curPos-1 && (b.b == '(' || b.b == '{' || b.b == '[')) {
                parenPos1 = matchLeft(textCursor().block(), b.b, i+1, 0);
                if (parenPos1 != -1) {
                    parenPos0 = pos+b.pos;
                } else {
                    errPos = pos+b.pos;
                }
            } else if (b.pos == curPos-1 && (b.b == ')' || b.b == '}' || b.b == ']')) {
                parenPos0 = matchRight(textCursor().block(), b.b, i-1, 0);
                if (parenPos0 != -1) {
                    parenPos1 = pos+b.pos;
                } else {
                    errPos = pos+b.pos;
                }
            }
            if (parenPos0 != -1 && parenPos1 != -1) {
                QTextEdit::ExtraSelection sel;
                QTextCharFormat format = sel.format;
                format.setBackground(Qt::green);
                sel.format = format;
                QTextCursor cursor = textCursor();
                cursor.setPosition(parenPos0);
                cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
                sel.cursor = cursor;
                extraSelections.append(sel);
                cursor.setPosition(parenPos1);
                cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
                sel.cursor = cursor;
                extraSelections.append(sel);
            }
            if (errPos != -1) {
                QTextEdit::ExtraSelection sel;
                QTextCharFormat format = sel.format;
                format.setBackground(Qt::red);
                sel.format = format;
                QTextCursor cursor = textCursor();
                cursor.setPosition(errPos);
                cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
                sel.cursor = cursor;
                extraSelections.append(sel);
            }
        }
    }

    setExtraSelections(extraSelections);
}

int CodeEditor::matchLeft(QTextBlock block, QChar b, int i, int nLeft)
{
    QChar match;
    switch (b.toLatin1()) {
    case '(' : match = ')'; break;
    case '{' : match = '}'; break;
    case '[' : match = ']'; break;
    default: break; // should not happen
    }

    while (block.isValid()) {
        BracketData* bd = static_cast<BracketData*>(block.userData());
        QVector<Bracket>& brackets = bd->brackets;
        int docPos = block.position();
        for (; i<brackets.size(); i++) {
            Bracket& b = brackets[i];
            if (b.b=='(' || b.b=='{' || b.b=='[') {
                nLeft++;
            } else if (b.b==match && nLeft==0) {
                return docPos+b.pos;
            } else {
                nLeft--;
            }
        }
        block = block.next();
        i = 0;
    }
    return -1;
}

int CodeEditor::matchRight(QTextBlock block, QChar b, int i, int nRight)
{
    QChar match;
    switch (b.toLatin1()) {
    case ')' : match = '('; break;
    case '}' : match = '{'; break;
    case ']' : match = '['; break;
    default: break; // should not happen
    }

    while (block.isValid()) {
        BracketData* bd = static_cast<BracketData*>(block.userData());
        QVector<Bracket>& brackets = bd->brackets;
        if (i==-1)
            i = brackets.size()-1;
        int docPos = block.position();
        for (; i>-1 && brackets.size()>0; i--) {
            Bracket& b = brackets[i];
            if (b.b==')' || b.b=='}' || b.b==']') {
                nRight++;
            } else if (b.b==match && nRight==0) {
                return docPos+b.pos;
            } else {
                nRight--;
            }
        }
        block = block.previous();
        i = -1;
    }
    return -1;
}

void CodeEditor::lineNumberAreaPaintEvent(QPaintEvent *event)
{
    QPainter painter(lineNumberArea);
    painter.fillRect(event->rect(), Qt::lightGray);

    QTextBlock block = firstVisibleBlock();
    int blockNumber = block.blockNumber();
    int top = (int) blockBoundingGeometry(block).translated(contentOffset()).top();
    int bottom = top + (int) blockBoundingRect(block).height();

    while (block.isValid() && top <= event->rect().bottom()) {
        if (block.isVisible() && bottom >= event->rect().top()) {
            QString number = QString::number(blockNumber + 1);
            painter.setPen(Qt::black);
            painter.drawText(0, top, lineNumberArea->width(), fontMetrics().height(),
                             Qt::AlignRight, number);
        }

        block = block.next();
        top = bottom;
        bottom = top + (int) blockBoundingRect(block).height();
        ++blockNumber;
    }
}
<commit_msg>Do not replace tabs for now (messes up the undo stack)<commit_after>#include <QtWidgets>
#include "codeeditor.h"

void
CodeEditor::initUI(void)
{
    QFont font("Courier New");
    font.setStyleHint(QFont::Monospace);
    setFont(font);

    const int tabStop = 2;  // 4 characters

    QFontMetrics metrics(font);
    setTabStopWidth(tabStop * metrics.width(' '));

    lineNumberArea = new LineNumberArea(this);

    connect(this, SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberAreaWidth(int)));
    connect(this, SIGNAL(updateRequest(QRect,int)), this, SLOT(updateLineNumberArea(QRect,int)));
    connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(highlightCurrentLine()));

    updateLineNumberAreaWidth(0);
    highlightCurrentLine();
    highlighter = new Highlighter(document());

    QTextCursor cursor(textCursor());
    cursor.movePosition(QTextCursor::Start);
    setTextCursor(cursor);
    ensureCursorVisible();
    setFocus();
}

CodeEditor::CodeEditor(QFile& file, QWidget *parent) :
    QPlainTextEdit(parent)
{
    initUI();
    if (file.isOpen()) {
        setPlainText(file.readAll());
        filepath = QFileInfo(file).absoluteFilePath();
        filename = QFileInfo(file).fileName();
    } else {
        filepath = "";
        filename = "Untitled";
    }
//    connect(document(), SIGNAL(contentsChange(int,int,int)), this, SLOT(replaceTabs(int,int,int)));
}

void CodeEditor::replaceTabs(int pos,int,int add)
{
    if (add>0) {
        QTextCursor cursor(document());
        cursor.setPosition(pos);
        cursor.movePosition(QTextCursor::Right,QTextCursor::KeepAnchor,add);
        QString sel = cursor.selectedText();
        if (sel.indexOf('\t')!=-1) {
            sel = sel.replace('\t',"  ");
            cursor.insertText(sel);
        }
    }
}

int CodeEditor::lineNumberAreaWidth()
{
    int digits = 1;
    int max = qMax(1, blockCount());
    while (max >= 10) {
        max /= 10;
        ++digits;
    }

    int space = 3 + fontMetrics().width(QLatin1Char('9')) * digits;

    return space;
}

void CodeEditor::updateLineNumberAreaWidth(int /* newBlockCount */)
{
    setViewportMargins(lineNumberAreaWidth(), 0, 0, 0);
}

void CodeEditor::updateLineNumberArea(const QRect &rect, int dy)
{
    if (dy)
        lineNumberArea->scroll(0, dy);
    else
        lineNumberArea->update(0, rect.y(), lineNumberArea->width(), rect.height());

    if (rect.contains(viewport()->rect()))
        updateLineNumberAreaWidth(0);
}

void CodeEditor::resizeEvent(QResizeEvent *e)
{
    QPlainTextEdit::resizeEvent(e);

    QRect cr = contentsRect();
    lineNumberArea->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height()));
}

void CodeEditor::highlightCurrentLine()
{
    QList<QTextEdit::ExtraSelection> extraSelections;

    if (!isReadOnly()) {
        QTextEdit::ExtraSelection selection;

        QColor lineColor = QColor(Qt::yellow).lighter(160);

        selection.format.setBackground(lineColor);
        selection.format.setProperty(QTextFormat::FullWidthSelection, true);
        selection.cursor = textCursor();
        selection.cursor.clearSelection();
        extraSelections.append(selection);
    }

    BracketData* bd = static_cast<BracketData*>(textCursor().block().userData());

    if (bd) {
        QVector<Bracket>& brackets = bd->brackets;
        int pos = textCursor().block().position();
        for (int i=0; i<brackets.size(); i++) {
            int curPos = textCursor().position()-textCursor().block().position();
            Bracket& b = brackets[i];
            int parenPos0 = -1;
            int parenPos1 = -1;
            int errPos = -1;
            if (b.pos == curPos-1 && (b.b == '(' || b.b == '{' || b.b == '[')) {
                parenPos1 = matchLeft(textCursor().block(), b.b, i+1, 0);
                if (parenPos1 != -1) {
                    parenPos0 = pos+b.pos;
                } else {
                    errPos = pos+b.pos;
                }
            } else if (b.pos == curPos-1 && (b.b == ')' || b.b == '}' || b.b == ']')) {
                parenPos0 = matchRight(textCursor().block(), b.b, i-1, 0);
                if (parenPos0 != -1) {
                    parenPos1 = pos+b.pos;
                } else {
                    errPos = pos+b.pos;
                }
            }
            if (parenPos0 != -1 && parenPos1 != -1) {
                QTextEdit::ExtraSelection sel;
                QTextCharFormat format = sel.format;
                format.setBackground(Qt::green);
                sel.format = format;
                QTextCursor cursor = textCursor();
                cursor.setPosition(parenPos0);
                cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
                sel.cursor = cursor;
                extraSelections.append(sel);
                cursor.setPosition(parenPos1);
                cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
                sel.cursor = cursor;
                extraSelections.append(sel);
            }
            if (errPos != -1) {
                QTextEdit::ExtraSelection sel;
                QTextCharFormat format = sel.format;
                format.setBackground(Qt::red);
                sel.format = format;
                QTextCursor cursor = textCursor();
                cursor.setPosition(errPos);
                cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
                sel.cursor = cursor;
                extraSelections.append(sel);
            }
        }
    }

    setExtraSelections(extraSelections);
}

int CodeEditor::matchLeft(QTextBlock block, QChar b, int i, int nLeft)
{
    QChar match;
    switch (b.toLatin1()) {
    case '(' : match = ')'; break;
    case '{' : match = '}'; break;
    case '[' : match = ']'; break;
    default: break; // should not happen
    }

    while (block.isValid()) {
        BracketData* bd = static_cast<BracketData*>(block.userData());
        QVector<Bracket>& brackets = bd->brackets;
        int docPos = block.position();
        for (; i<brackets.size(); i++) {
            Bracket& b = brackets[i];
            if (b.b=='(' || b.b=='{' || b.b=='[') {
                nLeft++;
            } else if (b.b==match && nLeft==0) {
                return docPos+b.pos;
            } else {
                nLeft--;
            }
        }
        block = block.next();
        i = 0;
    }
    return -1;
}

int CodeEditor::matchRight(QTextBlock block, QChar b, int i, int nRight)
{
    QChar match;
    switch (b.toLatin1()) {
    case ')' : match = '('; break;
    case '}' : match = '{'; break;
    case ']' : match = '['; break;
    default: break; // should not happen
    }

    while (block.isValid()) {
        BracketData* bd = static_cast<BracketData*>(block.userData());
        QVector<Bracket>& brackets = bd->brackets;
        if (i==-1)
            i = brackets.size()-1;
        int docPos = block.position();
        for (; i>-1 && brackets.size()>0; i--) {
            Bracket& b = brackets[i];
            if (b.b==')' || b.b=='}' || b.b==']') {
                nRight++;
            } else if (b.b==match && nRight==0) {
                return docPos+b.pos;
            } else {
                nRight--;
            }
        }
        block = block.previous();
        i = -1;
    }
    return -1;
}

void CodeEditor::lineNumberAreaPaintEvent(QPaintEvent *event)
{
    QPainter painter(lineNumberArea);
    painter.fillRect(event->rect(), Qt::lightGray);

    QTextBlock block = firstVisibleBlock();
    int blockNumber = block.blockNumber();
    int top = (int) blockBoundingGeometry(block).translated(contentOffset()).top();
    int bottom = top + (int) blockBoundingRect(block).height();

    while (block.isValid() && top <= event->rect().bottom()) {
        if (block.isVisible() && bottom >= event->rect().top()) {
            QString number = QString::number(blockNumber + 1);
            painter.setPen(Qt::black);
            painter.drawText(0, top, lineNumberArea->width(), fontMetrics().height(),
                             Qt::AlignRight, number);
        }

        block = block.next();
        top = bottom;
        bottom = top + (int) blockBoundingRect(block).height();
        ++blockNumber;
    }
}
<|endoftext|>


<commit_before>/**
 *  For conditions of distribution and use, see copyright notice in license.txt
 *
 *  @file   JavascriptModule.cpp
 *  @brief  Enables Javascript execution and scripting in Naali.
 */

#include "StableHeaders.h"
#include "DebugOperatorNew.h"

#include "JavascriptModule.h"
#include "ScriptMetaTypeDefines.h"
#include "JavascriptInstance.h"

#include "AssetAPI.h"
#include "EC_Script.h"
#include "ScriptAssetFactory.h"
#include "EC_DynamicComponent.h"
#include "EventManager.h"
#include "SceneManager.h"
#include "Input.h"
#include "UiServiceInterface.h"
#include "ISoundService.h"
#include "Frame.h"
#include "Console.h"
#include "ConsoleCommandServiceInterface.h"
#include "NaaliCoreTypeDefines.h"

#include <QtScript>

Q_SCRIPT_DECLARE_QMETAOBJECT(QPushButton, QWidget*) ///@todo Remove? This is already done in ScriptMetaTypeDefines.cpp

#include "MemoryLeakCheck.h"

std::string JavascriptModule::type_name_static_ = "Javascript";
JavascriptModule *javascriptModuleInstance_ = 0;

JavascriptModule::JavascriptModule() :
    IModule(type_name_static_),
    engine(new QScriptEngine(this))
{
}

JavascriptModule::~JavascriptModule()
{
}

void JavascriptModule::Load()
{
    DECLARE_MODULE_EC(EC_Script);
    DECLARE_MODULE_EC(EC_DynamicComponent);
    framework_->Asset()->RegisterAssetTypeFactory(AssetTypeFactoryPtr(new ScriptAssetFactory));
}

void JavascriptModule::PreInitialize()
{
}

void JavascriptModule::Initialize()
{
    connect(GetFramework(), SIGNAL(SceneAdded(const QString&)), this, SLOT(SceneAdded(const QString&)));

    LogInfo("Module " + Name() + " initializing...");

    assert(!javascriptModuleInstance_);
    javascriptModuleInstance_ = this;

    // Register ourselves as javascript scripting service.
    boost::shared_ptr<JavascriptModule> jsmodule = framework_->GetModuleManager()->GetModule<JavascriptModule>().lock();
    boost::weak_ptr<ScriptServiceInterface> service = boost::dynamic_pointer_cast<ScriptServiceInterface>(jsmodule);
    framework_->GetServiceManager()->RegisterService(Service::ST_JavascriptScripting, service);

    engine->globalObject().setProperty("print", engine->newFunction(Print));

    QScriptValue objectbutton= engine->scriptValueFromQMetaObject<QPushButton>();
    engine->globalObject().setProperty("QPushButton", objectbutton);

    JavascriptModule::RunScript("jsmodules/lib/json2.js");

    RunString("print('Hello from qtscript');");

    frameworkEventCategory_ = framework_->GetEventManager()->QueryEventCategory("Framework");
}

void JavascriptModule::PostInitialize()
{
    RegisterNaaliCoreMetaTypes();

    RegisterConsoleCommand(Console::CreateCommand(
        "JsExec", "Execute given code in the embedded Javascript interpreter. Usage: JsExec(mycodestring)",
        Console::Bind(this, &JavascriptModule::ConsoleRunString)));

    RegisterConsoleCommand(Console::CreateCommand(
        "JsLoad", "Execute a javascript file. JsLoad(myjsfile.js)",
        Console::Bind(this, &JavascriptModule::ConsoleRunFile)));

    RegisterConsoleCommand(Console::CreateCommand(
        "JsReloadScripts", "Reloads and re-executes startup scripts.",
        Console::Bind(this, &JavascriptModule::ConsoleReloadScripts)));

    // Initialize startup scripts
    LoadStartupScripts();
}

void JavascriptModule::Uninitialize()
{
    UnloadStartupScripts();
}

void JavascriptModule::Update(f64 frametime)
{
    RESETPROFILER;
}

bool JavascriptModule::HandleEvent(event_category_id_t category_id, event_id_t event_id, IEventData* data)
{
    if (category_id == frameworkEventCategory_)
    {
        if (event_id == Foundation::PROGRAM_OPTIONS)
        {
            Foundation::ProgramOptionsEvent *po_event = static_cast<Foundation::ProgramOptionsEvent*>(data);
            if (po_event->options.count("run"))
            {
                commandLineStartupScript_ = po_event->options["run"].as<std::string>();
                JavascriptInstance* jsInstance = new JavascriptInstance(commandLineStartupScript_.c_str(), this);
                PrepareScriptInstance(jsInstance);
                startupScripts_.push_back(jsInstance);
                jsInstance->Run();
            }
        }
    }
    return false;
}

Console::CommandResult JavascriptModule::ConsoleRunString(const StringVector &params)
{
    if (params.size() != 1)
        return Console::ResultFailure("Usage: JsExec(print 1 + 1)");

    JavascriptModule::RunString(QString::fromStdString(params[0]));
    return Console::ResultSuccess();
}

Console::CommandResult JavascriptModule::ConsoleRunFile(const StringVector &params)
{
    if (params.size() != 1)
        return Console::ResultFailure("Usage: JsLoad(myfile.js)");

    JavascriptModule::RunScript(QString::fromStdString(params[0]));

    return Console::ResultSuccess();
}

Console::CommandResult JavascriptModule::ConsoleReloadScripts(const StringVector &params)
{
    LoadStartupScripts();

    return Console::ResultSuccess();
}

JavascriptModule *JavascriptModule::GetInstance()
{
    assert(javascriptModuleInstance_);
    return javascriptModuleInstance_;
}

void JavascriptModule::RunString(const QString &codestr, const QVariantMap &context)
{
    QMapIterator<QString, QVariant> i(context);
    while (i.hasNext())
    {
        i.next();
        engine->globalObject().setProperty(i.key(), engine->newQObject(i.value().value<QObject*>()));
    }

    engine->evaluate(codestr);
}

void JavascriptModule::RunScript(const QString &scriptFileName)
{
    QFile scriptFile(scriptFileName);
    scriptFile.open(QIODevice::ReadOnly);
    engine->evaluate(scriptFile.readAll(), scriptFileName);
    scriptFile.close();
}

void JavascriptModule::SceneAdded(const QString &name)
{
    Scene::ScenePtr scene = GetFramework()->GetScene(name);
    connect(scene.get(), SIGNAL(ComponentAdded(Scene::Entity*, IComponent*, AttributeChange::Type)),
            SLOT(ComponentAdded(Scene::Entity*, IComponent*, AttributeChange::Type)));
    connect(scene.get(), SIGNAL(ComponentRemoved(Scene::Entity*, IComponent*, AttributeChange::Type)),
            SLOT(ComponentRemoved(Scene::Entity*, IComponent*, AttributeChange::Type)));
}

void JavascriptModule::ScriptAssetChanged(ScriptAssetPtr newScript)
{
    PROFILE(JSModule_ScriptAssetChanged);

    EC_Script *sender = dynamic_cast<EC_Script*>(this->sender());
    assert(sender && "JavascriptModule::ScriptAssetChanged needs to be invoked from EC_Script!");
    if (!sender)
        return;

    // First clean up any previous running script from EC_Script, if any exists.
    // (but only clean up scripts of our script type, other engines can clean up theirs)
    if (dynamic_cast<JavascriptInstance*>(sender->GetScriptInstance()))
        sender->SetScriptInstance(0);

    // EC_Script can host scripts of different types, and all script engines listen to asset changes.
    // First we'll need to validate whether the user even specified a script file that's QtScript.
    QString scriptType = sender->type.Get().trimmed().toLower();
    if (scriptType != "js" && scriptType.length() > 0)
        return; // The user enforced a foreign script type using the EC_Script type field.

    if (newScript->Name().endsWith(".js") || scriptType == "js") // We're positively using QtScript.
    {
        JavascriptInstance *jsInstance = new JavascriptInstance(newScript, this);
        jsInstance->SetOwnerComponent(sender->GetSharedPtr());
        sender->SetScriptInstance(jsInstance);

        // Register all core APIs and names to this script engine.
        PrepareScriptInstance(jsInstance, sender);

        if (sender->runOnLoad.Get())
            sender->Run();
    }
}

void JavascriptModule::ComponentAdded(Scene::Entity* entity, IComponent* comp, AttributeChange::Type change)
{
    if (comp->TypeName() == EC_Script::TypeNameStatic())
        connect(comp, SIGNAL(ScriptAssetChanged(ScriptAssetPtr)), this, SLOT(ScriptAssetChanged(ScriptAssetPtr)), Qt::UniqueConnection);
}

void JavascriptModule::ComponentRemoved(Scene::Entity* entity, IComponent* comp, AttributeChange::Type change)
{
    if (comp->TypeName() == EC_Script::TypeNameStatic())
        disconnect(comp, SIGNAL(ScriptAssetChanged(ScriptAssetPtr)), this, SLOT(ScriptAssetChanged(ScriptAssetPtr)));
}

void JavascriptModule::LoadStartupScripts()
{
    UnloadStartupScripts();

    std::string path = "./jsmodules/startup";
    std::vector<std::string> scripts;

    try
    {
        boost::filesystem::directory_iterator i(path);
        boost::filesystem::directory_iterator end_iter;
        while (i != end_iter)
        {
            if (boost::filesystem::is_regular_file(i->status()))
            {
                std::string ext = i->path().extension();
                boost::algorithm::to_lower(ext);
                if (ext == ".js")
                    scripts.push_back(i->path().string());
            }
            ++i;
        }
    }
    catch (std::exception &/*e*/)
    {
    }

    // Create a script instance for each of the files, register services for it and try to run.
    for (uint i = 0; i < scripts.size(); ++i)
    {
        JavascriptInstance* jsInstance = new JavascriptInstance(QString::fromStdString(scripts[i]), this);
        PrepareScriptInstance(jsInstance);
        startupScripts_.push_back(jsInstance);
        jsInstance->Run();
    }
}

void JavascriptModule::UnloadStartupScripts()
{
    // Stop the startup scripts, if any running
    for (uint i = 0; i < startupScripts_.size(); ++i)
        startupScripts_[i]->Unload();
    for (uint i = 0; i < startupScripts_.size(); ++i)
        delete startupScripts_[i];
    startupScripts_.clear();
}

void JavascriptModule::PrepareScriptInstance(JavascriptInstance* instance, EC_Script *comp)
{
    static std::set<QObject*> checked;

    // Register framework's dynamic properties (service objects) and the framework itself to the script engine
    QList<QByteArray> properties = framework_->dynamicPropertyNames();
    for (uint i = 0; i < properties.size(); ++i)
    {
        QString name = properties[i];
        QObject* serviceobject = framework_->property(name.toStdString().c_str()).value<QObject*>();
        instance->RegisterService(serviceobject, name);

        if (checked.find(serviceobject) == checked.end())
        {
            // Check if the service object has an OnScriptEngineCreated() slot, and give it a chance to perform further actions
            const QMetaObject* meta = serviceobject->metaObject();
            if (meta->indexOfSlot("OnScriptEngineCreated(QScriptEngine*)") != -1)
                QObject::connect(this, SIGNAL(ScriptEngineCreated(QScriptEngine*)), serviceobject, SLOT(OnScriptEngineCreated(QScriptEngine*)));

            checked.insert(serviceobject);
        }
    }

    instance->RegisterService(framework_, "framework");
    instance->RegisterService(instance, "engine");

    for(uint i = 0; i < properties.size(); ++i)
        instance->RegisterService(framework_->property(properties[i]).value<QObject*>(), properties[i]);

    if (comp)
    {
        // Set entity and scene that own the EC_Script component.
        instance->RegisterService(comp->GetParentEntity(), "me");
        instance->RegisterService(comp->GetParentEntity()->GetScene(), "scene");
    }

    emit ScriptEngineCreated(instance->GetEngine());
}

QScriptValue Print(QScriptContext *context, QScriptEngine *engine)
{
    std::cout << "{QtScript} " << context->argument(0).toString().toStdString() << "\n";
    return QScriptValue();
}

QScriptValue ScriptRunFile(QScriptContext *context, QScriptEngine *engine)
{
    JavascriptModule::GetInstance()->RunScript(context->argument(0).toString());
    return QScriptValue();
}

extern "C" void POCO_LIBRARY_API SetProfiler(Foundation::Profiler *profiler);
void SetProfiler(Foundation::Profiler *profiler)
{
    Foundation::ProfilerSection::SetProfiler(profiler);
}

POCO_BEGIN_MANIFEST(IModule)
   POCO_EXPORT_CLASS(JavascriptModule)
POCO_END_MANIFEST
<commit_msg>Cleaned up old test code from JavascriptModule.cpp<commit_after>/**
 *  For conditions of distribution and use, see copyright notice in license.txt
 *
 *  @file   JavascriptModule.cpp
 *  @brief  Enables Javascript execution and scripting in Naali.
 */

#include "StableHeaders.h"
#include "DebugOperatorNew.h"

#include "JavascriptModule.h"
#include "ScriptMetaTypeDefines.h"
#include "JavascriptInstance.h"

#include "AssetAPI.h"
#include "EC_Script.h"
#include "ScriptAssetFactory.h"
#include "EC_DynamicComponent.h"
#include "EventManager.h"
#include "SceneManager.h"
#include "Input.h"
#include "UiServiceInterface.h"
#include "ISoundService.h"
#include "Frame.h"
#include "Console.h"
#include "ConsoleCommandServiceInterface.h"
#include "NaaliCoreTypeDefines.h"

#include <QtScript>

#include "MemoryLeakCheck.h"

std::string JavascriptModule::type_name_static_ = "Javascript";
JavascriptModule *javascriptModuleInstance_ = 0;

JavascriptModule::JavascriptModule() :
    IModule(type_name_static_),
    engine(new QScriptEngine(this))
{
}

JavascriptModule::~JavascriptModule()
{
}

void JavascriptModule::Load()
{
    DECLARE_MODULE_EC(EC_Script);
    DECLARE_MODULE_EC(EC_DynamicComponent);
    framework_->Asset()->RegisterAssetTypeFactory(AssetTypeFactoryPtr(new ScriptAssetFactory));
}

void JavascriptModule::PreInitialize()
{
}

void JavascriptModule::Initialize()
{
    connect(GetFramework(), SIGNAL(SceneAdded(const QString&)), this, SLOT(SceneAdded(const QString&)));

    LogInfo("Module " + Name() + " initializing...");

    assert(!javascriptModuleInstance_);
    javascriptModuleInstance_ = this;

    // Register ourselves as javascript scripting service.
    boost::shared_ptr<JavascriptModule> jsmodule = framework_->GetModuleManager()->GetModule<JavascriptModule>().lock();
    boost::weak_ptr<ScriptServiceInterface> service = boost::dynamic_pointer_cast<ScriptServiceInterface>(jsmodule);
    framework_->GetServiceManager()->RegisterService(Service::ST_JavascriptScripting, service);

    engine->globalObject().setProperty("print", engine->newFunction(Print));

    frameworkEventCategory_ = framework_->GetEventManager()->QueryEventCategory("Framework");
}

void JavascriptModule::PostInitialize()
{
    RegisterNaaliCoreMetaTypes();

    RegisterConsoleCommand(Console::CreateCommand(
        "JsExec", "Execute given code in the embedded Javascript interpreter. Usage: JsExec(mycodestring)",
        Console::Bind(this, &JavascriptModule::ConsoleRunString)));

    RegisterConsoleCommand(Console::CreateCommand(
        "JsLoad", "Execute a javascript file. JsLoad(myjsfile.js)",
        Console::Bind(this, &JavascriptModule::ConsoleRunFile)));

    RegisterConsoleCommand(Console::CreateCommand(
        "JsReloadScripts", "Reloads and re-executes startup scripts.",
        Console::Bind(this, &JavascriptModule::ConsoleReloadScripts)));

    // Initialize startup scripts
    LoadStartupScripts();
}

void JavascriptModule::Uninitialize()
{
    UnloadStartupScripts();
}

void JavascriptModule::Update(f64 frametime)
{
    RESETPROFILER;
}

bool JavascriptModule::HandleEvent(event_category_id_t category_id, event_id_t event_id, IEventData* data)
{
    if (category_id == frameworkEventCategory_)
    {
        if (event_id == Foundation::PROGRAM_OPTIONS)
        {
            Foundation::ProgramOptionsEvent *po_event = static_cast<Foundation::ProgramOptionsEvent*>(data);
            if (po_event->options.count("run"))
            {
                commandLineStartupScript_ = po_event->options["run"].as<std::string>();
                JavascriptInstance* jsInstance = new JavascriptInstance(commandLineStartupScript_.c_str(), this);
                PrepareScriptInstance(jsInstance);
                startupScripts_.push_back(jsInstance);
                jsInstance->Run();
            }
        }
    }
    return false;
}

Console::CommandResult JavascriptModule::ConsoleRunString(const StringVector &params)
{
    if (params.size() != 1)
        return Console::ResultFailure("Usage: JsExec(print 1 + 1)");

    JavascriptModule::RunString(QString::fromStdString(params[0]));
    return Console::ResultSuccess();
}

Console::CommandResult JavascriptModule::ConsoleRunFile(const StringVector &params)
{
    if (params.size() != 1)
        return Console::ResultFailure("Usage: JsLoad(myfile.js)");

    JavascriptModule::RunScript(QString::fromStdString(params[0]));

    return Console::ResultSuccess();
}

Console::CommandResult JavascriptModule::ConsoleReloadScripts(const StringVector &params)
{
    LoadStartupScripts();

    return Console::ResultSuccess();
}

JavascriptModule *JavascriptModule::GetInstance()
{
    assert(javascriptModuleInstance_);
    return javascriptModuleInstance_;
}

void JavascriptModule::RunString(const QString &codestr, const QVariantMap &context)
{
    QMapIterator<QString, QVariant> i(context);
    while (i.hasNext())
    {
        i.next();
        engine->globalObject().setProperty(i.key(), engine->newQObject(i.value().value<QObject*>()));
    }

    engine->evaluate(codestr);
}

void JavascriptModule::RunScript(const QString &scriptFileName)
{
    QFile scriptFile(scriptFileName);
    scriptFile.open(QIODevice::ReadOnly);
    engine->evaluate(scriptFile.readAll(), scriptFileName);
    scriptFile.close();
}

void JavascriptModule::SceneAdded(const QString &name)
{
    Scene::ScenePtr scene = GetFramework()->GetScene(name);
    connect(scene.get(), SIGNAL(ComponentAdded(Scene::Entity*, IComponent*, AttributeChange::Type)),
            SLOT(ComponentAdded(Scene::Entity*, IComponent*, AttributeChange::Type)));
    connect(scene.get(), SIGNAL(ComponentRemoved(Scene::Entity*, IComponent*, AttributeChange::Type)),
            SLOT(ComponentRemoved(Scene::Entity*, IComponent*, AttributeChange::Type)));
}

void JavascriptModule::ScriptAssetChanged(ScriptAssetPtr newScript)
{
    PROFILE(JSModule_ScriptAssetChanged);

    EC_Script *sender = dynamic_cast<EC_Script*>(this->sender());
    assert(sender && "JavascriptModule::ScriptAssetChanged needs to be invoked from EC_Script!");
    if (!sender)
        return;

    // First clean up any previous running script from EC_Script, if any exists.
    // (but only clean up scripts of our script type, other engines can clean up theirs)
    if (dynamic_cast<JavascriptInstance*>(sender->GetScriptInstance()))
        sender->SetScriptInstance(0);

    // EC_Script can host scripts of different types, and all script engines listen to asset changes.
    // First we'll need to validate whether the user even specified a script file that's QtScript.
    QString scriptType = sender->type.Get().trimmed().toLower();
    if (scriptType != "js" && scriptType.length() > 0)
        return; // The user enforced a foreign script type using the EC_Script type field.

    if (newScript->Name().endsWith(".js") || scriptType == "js") // We're positively using QtScript.
    {
        JavascriptInstance *jsInstance = new JavascriptInstance(newScript, this);
        jsInstance->SetOwnerComponent(sender->GetSharedPtr());
        sender->SetScriptInstance(jsInstance);

        // Register all core APIs and names to this script engine.
        PrepareScriptInstance(jsInstance, sender);

        if (sender->runOnLoad.Get())
            sender->Run();
    }
}

void JavascriptModule::ComponentAdded(Scene::Entity* entity, IComponent* comp, AttributeChange::Type change)
{
    if (comp->TypeName() == EC_Script::TypeNameStatic())
        connect(comp, SIGNAL(ScriptAssetChanged(ScriptAssetPtr)), this, SLOT(ScriptAssetChanged(ScriptAssetPtr)), Qt::UniqueConnection);
}

void JavascriptModule::ComponentRemoved(Scene::Entity* entity, IComponent* comp, AttributeChange::Type change)
{
    if (comp->TypeName() == EC_Script::TypeNameStatic())
        disconnect(comp, SIGNAL(ScriptAssetChanged(ScriptAssetPtr)), this, SLOT(ScriptAssetChanged(ScriptAssetPtr)));
}

void JavascriptModule::LoadStartupScripts()
{
    UnloadStartupScripts();

    std::string path = "./jsmodules/startup";
    std::vector<std::string> scripts;

    try
    {
        boost::filesystem::directory_iterator i(path);
        boost::filesystem::directory_iterator end_iter;
        while (i != end_iter)
        {
            if (boost::filesystem::is_regular_file(i->status()))
            {
                std::string ext = i->path().extension();
                boost::algorithm::to_lower(ext);
                if (ext == ".js")
                    scripts.push_back(i->path().string());
            }
            ++i;
        }
    }
    catch (std::exception &/*e*/)
    {
    }

    // Create a script instance for each of the files, register services for it and try to run.
    for (uint i = 0; i < scripts.size(); ++i)
    {
        JavascriptInstance* jsInstance = new JavascriptInstance(QString::fromStdString(scripts[i]), this);
        PrepareScriptInstance(jsInstance);
        startupScripts_.push_back(jsInstance);
        jsInstance->Run();
    }
}

void JavascriptModule::UnloadStartupScripts()
{
    // Stop the startup scripts, if any running
    for (uint i = 0; i < startupScripts_.size(); ++i)
        startupScripts_[i]->Unload();
    for (uint i = 0; i < startupScripts_.size(); ++i)
        delete startupScripts_[i];
    startupScripts_.clear();
}

void JavascriptModule::PrepareScriptInstance(JavascriptInstance* instance, EC_Script *comp)
{
    static std::set<QObject*> checked;

    // Register framework's dynamic properties (service objects) and the framework itself to the script engine
    QList<QByteArray> properties = framework_->dynamicPropertyNames();
    for (uint i = 0; i < properties.size(); ++i)
    {
        QString name = properties[i];
        QObject* serviceobject = framework_->property(name.toStdString().c_str()).value<QObject*>();
        instance->RegisterService(serviceobject, name);

        if (checked.find(serviceobject) == checked.end())
        {
            // Check if the service object has an OnScriptEngineCreated() slot, and give it a chance to perform further actions
            const QMetaObject* meta = serviceobject->metaObject();
            if (meta->indexOfSlot("OnScriptEngineCreated(QScriptEngine*)") != -1)
                QObject::connect(this, SIGNAL(ScriptEngineCreated(QScriptEngine*)), serviceobject, SLOT(OnScriptEngineCreated(QScriptEngine*)));

            checked.insert(serviceobject);
        }
    }

    instance->RegisterService(framework_, "framework");
    instance->RegisterService(instance, "engine");

    for(uint i = 0; i < properties.size(); ++i)
        instance->RegisterService(framework_->property(properties[i]).value<QObject*>(), properties[i]);

    if (comp)
    {
        // Set entity and scene that own the EC_Script component.
        instance->RegisterService(comp->GetParentEntity(), "me");
        instance->RegisterService(comp->GetParentEntity()->GetScene(), "scene");
    }

    emit ScriptEngineCreated(instance->GetEngine());
}

QScriptValue Print(QScriptContext *context, QScriptEngine *engine)
{
    std::cout << "{QtScript} " << context->argument(0).toString().toStdString() << "\n";
    return QScriptValue();
}

extern "C" void POCO_LIBRARY_API SetProfiler(Foundation::Profiler *profiler);
void SetProfiler(Foundation::Profiler *profiler)
{
    Foundation::ProfilerSection::SetProfiler(profiler);
}

POCO_BEGIN_MANIFEST(IModule)
   POCO_EXPORT_CLASS(JavascriptModule)
POCO_END_MANIFEST
<|endoftext|>


<commit_before>#define CATCH_CONFIG_MAIN

#include <stdlib.h>
#include <string.h>

#include "catch.hpp"

#include <cserial.h>

#ifdef _WIN32
#define snprintf _snprintf_s
#define sprintf sprintf_s
#define strcat strcat_s
#endif

TEST_CASE("Loopback send/receive", "[tx][rx][loopback]")
{
	struct cserial_port txPort, rxPort;
	struct cserial_port_conf conf = {
		conf.baud = 19200,
		conf.parity = PARITY_NONE,
		conf.csize = 8,
		conf.stopbits = 1,
	};
	char *txDev, *rxDev;
	char tx[32], rx[32];
	int txLen;
	int ret;

	memset(tx, 0, sizeof(tx));
	memset(rx, 0, sizeof(rx));

	snprintf(tx, sizeof(tx), "Erich");

	/* Get the device file to transmit data out. */
	txDev = getenv("CSERIAL_TX");
	INFO("transmitting using: " << txDev);
	REQUIRE(txDev != 0);

	/* Get the device file to receive data in. */
	rxDev = getenv("CSERIAL_RX");
	INFO("receiving using: " << rxDev);
	REQUIRE(rxDev != 0);

	ret = cserial_open(&txPort, &conf, txDev);
	REQUIRE(ret == 0);
	ret = cserial_open(&rxPort, &conf, rxDev);
	REQUIRE(ret == 0);

	txLen = strlen(tx);
	ret = cserial_write(&txPort, tx, txLen);
	REQUIRE(ret == txLen);

	ret = cserial_read(&rxPort, rx, sizeof(rx));
	/* We should receive everything we transmitted. */
	REQUIRE(ret == txLen);

	ret = cserial_close(&txPort);
	ret = cserial_close(&rxPort);
	REQUIRE(ret == 0);
}

<commit_msg>Fixed memory leak in unit test.<commit_after>#define CATCH_CONFIG_MAIN

#include <stdlib.h>
#include <string.h>

#include "catch.hpp"

#include <cserial.h>

#ifdef _WIN32
#define snprintf _snprintf_s
#define sprintf sprintf_s
#define strcat strcat_s
#endif

TEST_CASE("Loopback send/receive", "[tx][rx][loopback]")
{
	struct cserial_port txPort, rxPort;
	struct cserial_port_conf conf = {
		conf.baud = 19200,
		conf.parity = PARITY_NONE,
		conf.csize = 8,
		conf.stopbits = 1,
	};
	char *txDev, *rxDev;
	char tx[32], rx[32];
	int txLen;
	int ret;

	memset(tx, 0, sizeof(tx));
	memset(rx, 0, sizeof(rx));

	snprintf(tx, sizeof(tx), "Erich");

	/* Get the device file to transmit data out. */
	txDev = getenv("CSERIAL_TX");
	INFO("transmitting using: " << txDev);
	REQUIRE(txDev != 0);

	/* Get the device file to receive data in. */
	rxDev = getenv("CSERIAL_RX");
	INFO("receiving using: " << rxDev);
	REQUIRE(rxDev != 0);

	ret = cserial_open(&txPort, &conf, txDev);
	REQUIRE(ret == 0);
	ret = cserial_open(&rxPort, &conf, rxDev);
	REQUIRE(ret == 0);

	txLen = strlen(tx);
	ret = cserial_write(&txPort, tx, txLen);
	REQUIRE(ret == txLen);

	ret = cserial_read(&rxPort, rx, sizeof(rx));
	/* We should receive everything we transmitted. */
	REQUIRE(ret == txLen);

	ret = cserial_close(&txPort);
	ret = cserial_close(&rxPort);
	REQUIRE(ret == 0);

	free(txPort.device);
	free(rxPort.device);
}

<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
// Name:      managedframe.cpp
// Purpose:   Implementation of wxExManagedFrame class.
// Author:    Anton van Wezenbeek
// Created:   2010-04-11
// Copyright: (c) 2010 Anton van Wezenbeek
////////////////////////////////////////////////////////////////////////////////

#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
#include <wx/wxcrt.h>
#include <wx/extension/managedframe.h>
#include <wx/extension/defs.h>
#include <wx/extension/frd.h>
#include <wx/extension/stc.h>
#include <wx/extension/toolbar.h>
#include <wx/extension/util.h>
#include <wx/extension/vi.h>

#if wxUSE_GUI

// Support class.
// Offers a text ctrl related to a vi object.
class wxExViTextCtrl: public wxTextCtrl
{
public:
  /// Constructor. Creates empty control.
  wxExViTextCtrl(
    wxWindow* parent,
    wxExManagedFrame* frame,
    wxWindowID id = wxID_ANY,
    const wxPoint& pos = wxDefaultPosition,
    const wxSize& size = wxDefaultSize);

  /// Returns vi component.
  wxExVi* GetVi() {return m_vi;};

  /// Sets vi component.
  void SetVi(wxExVi* vi);
protected:
  void OnCommand(wxCommandEvent& event);
  void OnEnter(wxCommandEvent& event);
  void OnFocus(wxFocusEvent& event);
  void OnKey(wxKeyEvent& event);
private:
  wxExManagedFrame* m_Frame;
  wxExVi* m_vi;
  bool m_UserInput;

  DECLARE_EVENT_TABLE()
};

BEGIN_EVENT_TABLE(wxExManagedFrame, wxExFrame)
  EVT_MENU(wxID_PREFERENCES, wxExManagedFrame::OnCommand)
  EVT_MENU_RANGE(ID_VIEW_LOWEST, ID_VIEW_HIGHEST, wxExManagedFrame::OnCommand)
  EVT_UPDATE_UI_RANGE(
    ID_VIEW_LOWEST, ID_VIEW_HIGHEST, wxExManagedFrame::OnUpdateUI)
END_EVENT_TABLE()

wxExManagedFrame::wxExManagedFrame(wxWindow* parent,
  wxWindowID id,
  const wxString& title,
  long style)
  : wxExFrame(parent, id, title, style)

{
  m_Manager.SetManagedWindow(this);

  wxExToolBar* toolBar = new wxExToolBar(this);
  toolBar->AddControls();
  DoAddControl(toolBar);

  AddToolBarPane(toolBar, "TOOLBAR", _("Toolbar"));
  AddToolBarPane(new wxExFindToolBar(this), "FINDBAR", _("Findbar"));

  // A vi panel starts with small static text for : or /, then
  // comes the vi ctrl for getting user input.
  wxPanel* panel = new wxPanel(this);
  m_viTextPrefix = new wxStaticText(panel, wxID_ANY, wxEmptyString);
  m_viTextCtrl = new wxExViTextCtrl(panel, this, wxID_ANY);

  wxFlexGridSizer* sizer = new wxFlexGridSizer(2);
  sizer->AddGrowableCol(1);
  sizer->Add(m_viTextPrefix, wxSizerFlags().Expand());
  sizer->Add(m_viTextCtrl, wxSizerFlags().Expand());

  panel->SetSizerAndFit(sizer);

  AddToolBarPane(panel, "VIBAR");

  m_Manager.Update();
}

wxExManagedFrame::~wxExManagedFrame()
{
  m_Manager.UnInit();
}

bool wxExManagedFrame::AddToolBarPane(
  wxWindow* window,
  const wxString& name,
  const wxString& caption)
{
  wxAuiPaneInfo pane;

  pane
    .LeftDockable(false)
    .RightDockable(false)
    .Name(name);

  // If the toolbar has a caption, it is at the top,
  // otherwise fixed at the bottom and initially hidden.
  if (!caption.empty())
  {
    pane
      .Top()
      .ToolbarPane()
      .Caption(caption);
  }
  else
  {
    pane
      .Bottom()
      .CloseButton(false)
      .Hide()
      .DockFixed(true)
      .Movable(false)
      .CaptionVisible(false);
  }

  return m_Manager.AddPane(window, pane);
}

void wxExManagedFrame::GetViCommand(wxExVi* vi, const wxString& command)
{
  m_viTextPrefix->SetLabel(command);
  m_viTextCtrl->SetVi(vi);

  m_Manager.GetPane("VIBAR").Show();
  m_Manager.Update();
}

bool wxExManagedFrame::GetViCommandIsFind() const
{
  return m_viTextPrefix->GetLabel() == "/" || m_viTextPrefix->GetLabel() == "?";
}

bool wxExManagedFrame::GetViCommandIsFindNext() const
{
  return GetViCommandIsFind() && m_viTextPrefix->GetLabel() == "/";
}

void wxExManagedFrame::HideViBar()
{
  if (m_Manager.GetPane("VIBAR").IsShown())
  {
    m_Manager.GetPane("VIBAR").Hide();
    m_Manager.Update();

    m_viTextCtrl->GetVi()->GetSTC()->SetFocus();
  }
}

void wxExManagedFrame::OnCommand(wxCommandEvent& event)
{
  switch (event.GetId())
  {
    case wxID_PREFERENCES:
      wxExSTC::ConfigDialog(this,
        _("Editor Options"),
        wxExSTC::STC_CONFIG_MODELESS |
        wxExSTC::STC_CONFIG_SIMPLE |
        wxExSTC::STC_CONFIG_WITH_APPLY,
        event.GetId());
    break;

    case ID_VIEW_FINDBAR: TogglePane("FINDBAR"); break;
    case ID_VIEW_TOOLBAR: TogglePane("TOOLBAR"); break;

    default:
      wxFAIL;
  }
}

void wxExManagedFrame::OnUpdateUI(wxUpdateUIEvent& event)
{
  switch (event.GetId())
  {
    case ID_VIEW_FINDBAR:
      event.Check(m_Manager.GetPane("FINDBAR").IsShown());
    break;

    case ID_VIEW_TOOLBAR:
      event.Check(m_Manager.GetPane("TOOLBAR").IsShown());
    break;

    default:
      wxFAIL;
  }
}

void wxExManagedFrame::ShowViMessage(const wxString& text)
{
  if (GetStatusBar()->IsShown())
  {
    GetStatusBar()->SetStatusText(text);

    m_Manager.GetPane("VIBAR").Hide();
  }
  else
  {
    m_viTextPrefix->SetLabel(text);
    m_viTextCtrl->Hide();

    m_Manager.GetPane("VIBAR").Show();
  }

  m_Manager.Update();
}

void wxExManagedFrame::TogglePane(const wxString& pane)
{
  wxAuiPaneInfo& info = m_Manager.GetPane(pane);

  wxASSERT(info.IsOk());

  info.IsShown() ? info.Hide(): info.Show();

  m_Manager.Update();
}

// Implementation of support class.

BEGIN_EVENT_TABLE(wxExViTextCtrl, wxTextCtrl)
  EVT_CHAR(wxExViTextCtrl::OnKey)
  EVT_SET_FOCUS(wxExViTextCtrl::OnFocus)
  EVT_TEXT(wxID_ANY, wxExViTextCtrl::OnCommand)
  EVT_TEXT_ENTER(wxID_ANY, wxExViTextCtrl::OnEnter)
END_EVENT_TABLE()

wxExViTextCtrl::wxExViTextCtrl(
  wxWindow* parent,
  wxExManagedFrame* frame,
  wxWindowID id,
  const wxPoint& pos,
  const wxSize& size)
  : wxTextCtrl(parent, id, wxEmptyString, pos, size, wxTE_PROCESS_ENTER)
  , m_Frame(frame)
  , m_vi(NULL)
  , m_UserInput(false)
{
}

void wxExViTextCtrl::OnCommand(wxCommandEvent& event)
{
  event.Skip();

  if (m_UserInput && m_vi != NULL && m_Frame->GetViCommandIsFind())
  {
    m_vi->GetSTC()->PositionRestore();
    m_vi->GetSTC()->FindNext(
      GetValue(),
      m_vi->GetSearchFlags(),
      m_Frame->GetViCommandIsFindNext());
  }
}

void wxExViTextCtrl::OnEnter(wxCommandEvent& event)
{
  event.Skip();

  if (!m_Frame->GetViCommandIsFind())
  {
    if (m_vi != NULL)
    {
      if (m_vi->ExecCommand(GetValue()))
      {
        m_Frame->HideViBar();
      }
    }
  }
  else
  {
    if (m_UserInput)
    {
      if (!GetValue().empty())
      {
        wxExFindReplaceData::Get()->SetFindString(GetValue());
      }
    }
    else if (m_vi != NULL)
    {
      m_vi->GetSTC()->FindNext(
        GetValue(),
        m_vi->GetSearchFlags(),
        m_Frame->GetViCommandIsFindNext());
    }

    m_Frame->HideViBar();
  }
}

void wxExViTextCtrl::OnFocus(wxFocusEvent& event)
{
  event.Skip();

  if (m_vi != NULL)
  {
    m_vi->GetSTC()->PositionSave();
  }
}

void wxExViTextCtrl::OnKey(wxKeyEvent& event)
{
  const auto key = event.GetKeyCode();

  if (key == WXK_ESCAPE)
  {
    if (m_vi != NULL)
    {
      m_vi->GetSTC()->PositionRestore();
    }

    m_Frame->HideViBar();

    m_UserInput = false;
  }
  else
  {
    m_UserInput = true;

    event.Skip();
  }
}

void wxExViTextCtrl::SetVi(wxExVi* vi)
{
  if (vi->GetSTC()->IsBeingDeleted())
  {
    wxLogStatus("invalid vi");
    m_vi = NULL;
  }
  else
  {
    m_vi = vi;
    m_UserInput = false;

    Show();

    if (m_Frame->GetViCommandIsFind())
    {
      // sync with frd data.
      SetValue(wxExFindReplaceData::Get()->GetFindString());
      SelectAll();
    }
    else
    {
      Clear();
    }

    SetFocus();
  }
}

#endif // wxUSE_GUI
<commit_msg>Edited extension/src/managedframe.cpp via GitHub<commit_after>////////////////////////////////////////////////////////////////////////////////
// Name:      managedframe.cpp
// Purpose:   Implementation of wxExManagedFrame class.
// Author:    Anton van Wezenbeek
// Created:   2010-04-11
// Copyright: (c) 2010 Anton van Wezenbeek
////////////////////////////////////////////////////////////////////////////////

#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
#include <wx/config.h>
#include <wx/wxcrt.h>
#include <wx/extension/managedframe.h>
#include <wx/extension/defs.h>
#include <wx/extension/frd.h>
#include <wx/extension/stc.h>
#include <wx/extension/toolbar.h>
#include <wx/extension/util.h>
#include <wx/extension/vi.h>

#if wxUSE_GUI

// Support class.
// Offers a text ctrl related to a vi object.
class wxExViTextCtrl: public wxTextCtrl
{
public:
  /// Constructor. Creates empty control.
  wxExViTextCtrl(
    wxWindow* parent,
    wxExManagedFrame* frame,
    wxWindowID id = wxID_ANY,
    const wxPoint& pos = wxDefaultPosition,
    const wxSize& size = wxDefaultSize);

  /// Returns vi component.
  wxExVi* GetVi() {return m_vi;};

  /// Sets vi component.
  void SetVi(wxExVi* vi);
protected:
  void OnCommand(wxCommandEvent& event);
  void OnEnter(wxCommandEvent& event);
  void OnFocus(wxFocusEvent& event);
  void OnKey(wxKeyEvent& event);
private:
  wxExManagedFrame* m_Frame;
  wxExVi* m_vi;
  bool m_UserInput;

  DECLARE_EVENT_TABLE()
};

BEGIN_EVENT_TABLE(wxExManagedFrame, wxExFrame)
  EVT_MENU(wxID_PREFERENCES, wxExManagedFrame::OnCommand)
  EVT_MENU_RANGE(ID_VIEW_LOWEST, ID_VIEW_HIGHEST, wxExManagedFrame::OnCommand)
  EVT_UPDATE_UI_RANGE(
    ID_VIEW_LOWEST, ID_VIEW_HIGHEST, wxExManagedFrame::OnUpdateUI)
END_EVENT_TABLE()

wxExManagedFrame::wxExManagedFrame(wxWindow* parent,
  wxWindowID id,
  const wxString& title,
  long style)
  : wxExFrame(parent, id, title, style)

{
  m_Manager.SetManagedWindow(this);

  wxExToolBar* toolBar = new wxExToolBar(this);
  toolBar->AddControls();
  DoAddControl(toolBar);

  AddToolBarPane(toolBar, "TOOLBAR", _("Toolbar"));
  AddToolBarPane(new wxExFindToolBar(this), "FINDBAR", _("Findbar"));

  // A vi panel starts with small static text for : or /, then
  // comes the vi ctrl for getting user input.
  wxPanel* panel = new wxPanel(this);
  m_viTextPrefix = new wxStaticText(panel, wxID_ANY, wxEmptyString);
  m_viTextCtrl = new wxExViTextCtrl(panel, this, wxID_ANY);

  wxFlexGridSizer* sizer = new wxFlexGridSizer(2);
  sizer->AddGrowableCol(1);
  sizer->Add(m_viTextPrefix, wxSizerFlags().Expand());
  sizer->Add(m_viTextCtrl, wxSizerFlags().Expand());

  panel->SetSizerAndFit(sizer);

  AddToolBarPane(panel, "VIBAR");

  m_Manager.Update();
}

wxExManagedFrame::~wxExManagedFrame()
{
  m_Manager.UnInit();
}

bool wxExManagedFrame::AddToolBarPane(
  wxWindow* window,
  const wxString& name,
  const wxString& caption)
{
  wxAuiPaneInfo pane;

  pane
    .LeftDockable(false)
    .RightDockable(false)
    .Name(name);

  // If the toolbar has a caption, it is at the top,
  // otherwise fixed at the bottom and initially hidden.
  if (!caption.empty())
  {
    pane
      .Top()
      .ToolbarPane()
      .Caption(caption);
  }
  else
  {
    pane
      .Bottom()
      .CloseButton(false)
      .Hide()
      .DockFixed(true)
      .Movable(false)
      .CaptionVisible(false);
  }

  return m_Manager.AddPane(window, pane);
}

void wxExManagedFrame::GetViCommand(wxExVi* vi, const wxString& command)
{
  m_viTextPrefix->SetLabel(command);
  m_viTextCtrl->SetVi(vi);

  m_Manager.GetPane("VIBAR").Show();
  m_Manager.Update();
}

bool wxExManagedFrame::GetViCommandIsFind() const
{
  return m_viTextPrefix->GetLabel() == "/" || m_viTextPrefix->GetLabel() == "?";
}

bool wxExManagedFrame::GetViCommandIsFindNext() const
{
  return GetViCommandIsFind() && m_viTextPrefix->GetLabel() == "/";
}

void wxExManagedFrame::HideViBar()
{
  if (m_Manager.GetPane("VIBAR").IsShown())
  {
    m_Manager.GetPane("VIBAR").Hide();
    m_Manager.Update();

    m_viTextCtrl->GetVi()->GetSTC()->SetFocus();
  }
}

void wxExManagedFrame::OnCommand(wxCommandEvent& event)
{
  switch (event.GetId())
  {
    case wxID_PREFERENCES:
      wxExSTC::ConfigDialog(this,
        _("Editor Options"),
        wxExSTC::STC_CONFIG_MODELESS |
        wxExSTC::STC_CONFIG_SIMPLE |
        wxExSTC::STC_CONFIG_WITH_APPLY,
        event.GetId());
    break;

    case ID_VIEW_FINDBAR: TogglePane("FINDBAR"); break;
    case ID_VIEW_TOOLBAR: TogglePane("TOOLBAR"); break;

    default:
      wxFAIL;
  }
}

void wxExManagedFrame::OnUpdateUI(wxUpdateUIEvent& event)
{
  switch (event.GetId())
  {
    case ID_VIEW_FINDBAR:
      event.Check(m_Manager.GetPane("FINDBAR").IsShown());
    break;

    case ID_VIEW_TOOLBAR:
      event.Check(m_Manager.GetPane("TOOLBAR").IsShown());
    break;

    default:
      wxFAIL;
  }
}

void wxExManagedFrame::ShowViMessage(const wxString& text)
{
  if (GetStatusBar()->IsShown())
  {
    GetStatusBar()->SetStatusText(text);

    m_Manager.GetPane("VIBAR").Hide();
  }
  else
  {
    m_viTextPrefix->SetLabel(text);
    m_viTextCtrl->Hide();

    m_Manager.GetPane("VIBAR").Show();
  }

  m_Manager.Update();
}

void wxExManagedFrame::TogglePane(const wxString& pane)
{
  wxAuiPaneInfo& info = m_Manager.GetPane(pane);

  wxASSERT(info.IsOk());

  info.IsShown() ? info.Hide(): info.Show();

  m_Manager.Update();
}

// Implementation of support class.

BEGIN_EVENT_TABLE(wxExViTextCtrl, wxTextCtrl)
  EVT_CHAR(wxExViTextCtrl::OnKey)
  EVT_SET_FOCUS(wxExViTextCtrl::OnFocus)
  EVT_TEXT(wxID_ANY, wxExViTextCtrl::OnCommand)
  EVT_TEXT_ENTER(wxID_ANY, wxExViTextCtrl::OnEnter)
END_EVENT_TABLE()

wxExViTextCtrl::wxExViTextCtrl(
  wxWindow* parent,
  wxExManagedFrame* frame,
  wxWindowID id,
  const wxPoint& pos,
  const wxSize& size)
  : wxTextCtrl(parent, id, wxEmptyString, pos, size, wxTE_PROCESS_ENTER)
  , m_Frame(frame)
  , m_vi(NULL)
  , m_UserInput(false)
{
}

void wxExViTextCtrl::OnCommand(wxCommandEvent& event)
{
  event.Skip();

  if (m_UserInput && m_vi != NULL && m_Frame->GetViCommandIsFind())
  {
    m_vi->GetSTC()->PositionRestore();
    m_vi->GetSTC()->FindNext(
      GetValue(),
      m_vi->GetSearchFlags(),
      m_Frame->GetViCommandIsFindNext());
  }
}

void wxExViTextCtrl::OnEnter(wxCommandEvent& event)
{
  event.Skip();

  if (!m_Frame->GetViCommandIsFind())
  {
    if (m_vi != NULL)
    {
      if (m_vi->ExecCommand(GetValue()))
      {
        wxConfigBase::Get()->Write("vicommand", GetValue()));
        m_Frame->HideViBar();
      }
    }
  }
  else
  {
    if (m_UserInput)
    {
      if (!GetValue().empty())
      {
        wxExFindReplaceData::Get()->SetFindString(GetValue());
      }
    }
    else if (m_vi != NULL)
    {
      m_vi->GetSTC()->FindNext(
        GetValue(),
        m_vi->GetSearchFlags(),
        m_Frame->GetViCommandIsFindNext());
    }

    m_Frame->HideViBar();
  }
}

void wxExViTextCtrl::OnFocus(wxFocusEvent& event)
{
  event.Skip();

  if (m_vi != NULL)
  {
    m_vi->GetSTC()->PositionSave();
  }
}

void wxExViTextCtrl::OnKey(wxKeyEvent& event)
{
  const auto key = event.GetKeyCode();

  if (key == WXK_ESCAPE)
  {
    if (m_vi != NULL)
    {
      m_vi->GetSTC()->PositionRestore();
    }

    m_Frame->HideViBar();

    m_UserInput = false;
  }
  else
  {
    m_UserInput = true;

    event.Skip();
  }
}

void wxExViTextCtrl::SetVi(wxExVi* vi)
{
  m_UserInput = false;

  if (vi->GetSTC()->IsBeingDeleted())
  {
    wxLogStatus("invalid vi");
    m_vi = NULL;
  }
  else
  {
    m_vi = vi;

    Show();

    if (m_Frame->GetViCommandIsFind())
    {
      SetValue(wxExFindReplaceData::Get()->GetFindString());
    }
    else
    {
      SetValue(wxConfigBase::Get()->Read("vicommand", wxEmptyString));
    }

    SelectAll();
    SetFocus();
  }
}

#endif // wxUSE_GUI
<|endoftext|>


<commit_before>#include <gl/glew.h>

#include "StageCanvas.h"
#include "Exception.h"
#include "ExceptionDlg.h"
#include "EditPanelImpl.h"
#include "KeysState.h"
#include "subject_id.h"
#include "panel_msg.h"
#include "EE_DTex.h"
#include "EE_GTxt.h"

#include <unirender/UR_RenderContext.h>
#include <shaderlab/ShaderMgr.h>
#include <sprite2/RenderCtxStack.h>
#include <sprite2/SprTimer.h>
#include <gum/GUM_ShaderLab.h>
#include <gum/GUM_DTex.h>
#include <gum/RenderContext.h>
#include <gum/GUM_AsyncTask.h>
#include <gum/AudioContext.h>

namespace ee
{

BEGIN_EVENT_TABLE(StageCanvas, wxGLCanvas)
	EVT_SIZE(StageCanvas::OnSize)
	EVT_PAINT(StageCanvas::OnPaint)
//	EVT_ERASE_BACKGROUND(StageCanvas::OnEraseBackground)
 	EVT_MOUSE_EVENTS(StageCanvas::OnMouse)
 	EVT_KEY_DOWN(StageCanvas::OnKeyDown)
	EVT_KEY_UP(StageCanvas::OnKeyUp)
	EVT_CHAR(StageCanvas::OnChar)
	EVT_TIMER(TIMER_ID, StageCanvas::OnTimer)
	EVT_KILL_FOCUS(StageCanvas::OnKillFocus)
END_EVENT_TABLE()

static const int GL_ATTRIB[20] = {WX_GL_RGBA, WX_GL_MIN_RED, 1, WX_GL_MIN_GREEN, 1,
								  WX_GL_MIN_BLUE, 1, WX_GL_DEPTH_SIZE, 1,
								  WX_GL_DOUBLEBUFFER,WX_GL_STENCIL_SIZE, 8, 0};

static const float FPS = 30;

StageCanvas::StageCanvas(wxWindow* stage_wnd, EditPanelImpl* stage,
						   wxGLContext* glctx, bool use_context_stack)
	: wxGLCanvas(stage_wnd, wxID_ANY, GL_ATTRIB)
	, m_share_context(false)
	, m_use_context_stack(use_context_stack)
	, m_stage(stage)
 	, m_width(0), m_height(0)
	, m_dirty(false)
	, m_cam_dirty(false)
	, m_render_ctx_idx(-1)
	, m_timer(this, TIMER_ID)
	, m_draw(true)
{
	if (glctx) {
		m_share_context = true;
		m_gl_ctx = glctx;
	} else {
		m_share_context = false;
		m_gl_ctx = new wxGLContext(this);
		Init();
	}

	m_bg_color.FromFloat(0.5f, 0.5f, 0.5f);
	m_timer.Start(1000 / FPS);

	RegistSubject(SetCanvasDirtySJ::Instance());

	if (m_use_context_stack) {
		m_render_ctx_idx = s2::RenderCtxStack::Instance()->Push(s2::RenderContext());
	}
}

StageCanvas::~StageCanvas()
{
	m_timer.Stop();

	if (!m_share_context) {
		delete m_gl_ctx;
	}

	if (m_use_context_stack)
	{
		s2::RenderCtxStack::Instance()->Pop();

		const s2::RenderContext* ctx = s2::RenderCtxStack::Instance()->Top();
		if (ctx) {
			gum::RenderContext::Instance()->OnSize(ctx->GetScreenWidth(), ctx->GetScreenHeight());
		}
	}
}

void StageCanvas::SetCurrentCanvas()
{
	SetCurrent(*m_gl_ctx);
	s2::RenderCtxStack::Instance()->Bind(m_render_ctx_idx);
}

void StageCanvas::SetBgColor(const s2::Color& color)
{
	m_bg_color = color;
}

void StageCanvas::OnNotify(int sj_id, void* ud)
{
	switch (sj_id)
	{
	case MSG_SET_CANVAS_DIRTY:
		m_dirty = true;
		break;
	}
}

void StageCanvas::Init()
{
	SetCurrentCanvas();

	if (glewInit() != GLEW_OK) {
		exit(1);
	}

	s2::SprTimer::Instance()->Init();
	// prepare 2d
	// todo: move to child, for defferent init (such as 3d ?)
	gum::ShaderLab::Instance()->Init();
	gum::AudioContext::Instance()->Init();
	DTex::Init();
	GTxt::Init();

	try {
// 		ShaderContext::Reload();
// 		ShaderContext::Reset();

		glEnable(GL_TEXTURE_2D);
	} catch (Exception& e) {
		ExceptionDlg dlg(m_parent, e);
		dlg.ShowModal();
	}
}

void StageCanvas::OnSize(wxSizeEvent& event)
{
	SetCurrentCanvas();

	wxSize size = event.GetSize();
 	m_width = size.GetWidth();
 	m_height = size.GetHeight();
	OnSize(m_width, m_height);

	sl::ShaderMgr::Instance()->GetContext()->ClearTextureCache();
}

void StageCanvas::OnPaint(wxPaintEvent& event)
{
	if (!m_draw) {
		return;
	}

	// Makes the OpenGL state that is represented by the OpenGL rendering
	// context context current
	SetCurrentCanvas();

	OnDrawWhole();
	m_dirty = false;
	m_cam_dirty = false;

	sl::ShaderMgr::Instance()->FlushShader();

	glFlush();
	SwapBuffers();

	gum::ShaderLab::Instance()->Update(1 / 30.0f);

//	wxPaintDC dc(this);
//	OnDrawDC();
}

// void StageCanvas::OnEraseBackground(wxEraseEvent& event)
// {
// }

void StageCanvas::OnMouse(wxMouseEvent& event)
{
	m_stage->OnMouse(event);

	// The handler of this event should normally call event.Skip() to allow the default processing
	// to take place as otherwise the window under mouse wouldn't get the focus.
	if (event.LeftDown()) {
		event.Skip();
	}
}

void StageCanvas::OnKeyDown(wxKeyEvent& event)
{
	m_stage->OnKeyDown(event);
}

void StageCanvas::OnKeyUp(wxKeyEvent& event)
{
	m_stage->OnKeyUp(event);
}

void StageCanvas::OnChar(wxKeyEvent& event)
{
	m_stage->OnChar(event);
}

void StageCanvas::OnTimer(wxTimerEvent& event)
{
	OnTimer();

	float dt = 0.166f;
	clock_t curr_time = clock();
	static clock_t last_time = 0;
	if (last_time != 0) {
		dt = (float)(curr_time - last_time) / CLOCKS_PER_SEC;
	}
	last_time = curr_time;

	if (s2::SprTimer::Instance()->Update(dt)) {
		m_dirty = true;
	}

	gum::DTex::Instance()->Flush();
	gum::AsyncTask::Instance()->Update();

	bool dirty = m_stage->Update();
	if (dirty) {
		m_dirty = dirty;
	}

	if (m_dirty || m_cam_dirty) {
		Refresh();
	}
}

void StageCanvas::OnKillFocus(wxFocusEvent& event)
{
	m_stage->GetKeyState().Reset();
}

}<commit_msg>add s2 init<commit_after>#include <gl/glew.h>

#include "StageCanvas.h"
#include "Exception.h"
#include "ExceptionDlg.h"
#include "EditPanelImpl.h"
#include "KeysState.h"
#include "subject_id.h"
#include "panel_msg.h"
#include "EE_DTex.h"
#include "EE_GTxt.h"

#include <unirender/UR_RenderContext.h>
#include <shaderlab/ShaderMgr.h>
#include <sprite2/RenderCtxStack.h>
#include <sprite2/SprTimer.h>
#include <gum/GUM_ShaderLab.h>
#include <gum/GUM_DTex.h>
#include <gum/RenderContext.h>
#include <gum/GUM_AsyncTask.h>
#include <gum/AudioContext.h>
#include <gum/GUM_Sprite2.h>

namespace ee
{

BEGIN_EVENT_TABLE(StageCanvas, wxGLCanvas)
	EVT_SIZE(StageCanvas::OnSize)
	EVT_PAINT(StageCanvas::OnPaint)
//	EVT_ERASE_BACKGROUND(StageCanvas::OnEraseBackground)
 	EVT_MOUSE_EVENTS(StageCanvas::OnMouse)
 	EVT_KEY_DOWN(StageCanvas::OnKeyDown)
	EVT_KEY_UP(StageCanvas::OnKeyUp)
	EVT_CHAR(StageCanvas::OnChar)
	EVT_TIMER(TIMER_ID, StageCanvas::OnTimer)
	EVT_KILL_FOCUS(StageCanvas::OnKillFocus)
END_EVENT_TABLE()

static const int GL_ATTRIB[20] = {WX_GL_RGBA, WX_GL_MIN_RED, 1, WX_GL_MIN_GREEN, 1,
								  WX_GL_MIN_BLUE, 1, WX_GL_DEPTH_SIZE, 1,
								  WX_GL_DOUBLEBUFFER,WX_GL_STENCIL_SIZE, 8, 0};

static const float FPS = 30;

StageCanvas::StageCanvas(wxWindow* stage_wnd, EditPanelImpl* stage,
						   wxGLContext* glctx, bool use_context_stack)
	: wxGLCanvas(stage_wnd, wxID_ANY, GL_ATTRIB)
	, m_share_context(false)
	, m_use_context_stack(use_context_stack)
	, m_stage(stage)
 	, m_width(0), m_height(0)
	, m_dirty(false)
	, m_cam_dirty(false)
	, m_render_ctx_idx(-1)
	, m_timer(this, TIMER_ID)
	, m_draw(true)
{
	if (glctx) {
		m_share_context = true;
		m_gl_ctx = glctx;
	} else {
		m_share_context = false;
		m_gl_ctx = new wxGLContext(this);
		Init();
	}

	m_bg_color.FromFloat(0.5f, 0.5f, 0.5f);
	m_timer.Start(1000 / FPS);

	RegistSubject(SetCanvasDirtySJ::Instance());

	if (m_use_context_stack) {
		m_render_ctx_idx = s2::RenderCtxStack::Instance()->Push(s2::RenderContext());
	}
}

StageCanvas::~StageCanvas()
{
	m_timer.Stop();

	if (!m_share_context) {
		delete m_gl_ctx;
	}

	if (m_use_context_stack)
	{
		s2::RenderCtxStack::Instance()->Pop();

		const s2::RenderContext* ctx = s2::RenderCtxStack::Instance()->Top();
		if (ctx) {
			gum::RenderContext::Instance()->OnSize(ctx->GetScreenWidth(), ctx->GetScreenHeight());
		}
	}
}

void StageCanvas::SetCurrentCanvas()
{
	SetCurrent(*m_gl_ctx);
	s2::RenderCtxStack::Instance()->Bind(m_render_ctx_idx);
}

void StageCanvas::SetBgColor(const s2::Color& color)
{
	m_bg_color = color;
}

void StageCanvas::OnNotify(int sj_id, void* ud)
{
	switch (sj_id)
	{
	case MSG_SET_CANVAS_DIRTY:
		m_dirty = true;
		break;
	}
}

void StageCanvas::Init()
{
	SetCurrentCanvas();

	if (glewInit() != GLEW_OK) {
		exit(1);
	}

	s2::SprTimer::Instance()->Init();
	// prepare 2d
	// todo: move to child, for defferent init (such as 3d ?)
	gum::ShaderLab::Instance()->Init();
	gum::AudioContext::Instance()->Init();
	gum::Sprite2::Init();
	DTex::Init();
	GTxt::Init();

	try {
// 		ShaderContext::Reload();
// 		ShaderContext::Reset();

		glEnable(GL_TEXTURE_2D);
	} catch (Exception& e) {
		ExceptionDlg dlg(m_parent, e);
		dlg.ShowModal();
	}
}

void StageCanvas::OnSize(wxSizeEvent& event)
{
	SetCurrentCanvas();

	wxSize size = event.GetSize();
 	m_width = size.GetWidth();
 	m_height = size.GetHeight();
	OnSize(m_width, m_height);

	sl::ShaderMgr::Instance()->GetContext()->ClearTextureCache();
}

void StageCanvas::OnPaint(wxPaintEvent& event)
{
	if (!m_draw) {
		return;
	}

	// Makes the OpenGL state that is represented by the OpenGL rendering
	// context context current
	SetCurrentCanvas();

	OnDrawWhole();
	m_dirty = false;
	m_cam_dirty = false;

	sl::ShaderMgr::Instance()->FlushShader();

	glFlush();
	SwapBuffers();

	gum::ShaderLab::Instance()->Update(1 / 30.0f);

//	wxPaintDC dc(this);
//	OnDrawDC();
}

// void StageCanvas::OnEraseBackground(wxEraseEvent& event)
// {
// }

void StageCanvas::OnMouse(wxMouseEvent& event)
{
	m_stage->OnMouse(event);

	// The handler of this event should normally call event.Skip() to allow the default processing
	// to take place as otherwise the window under mouse wouldn't get the focus.
	if (event.LeftDown()) {
		event.Skip();
	}
}

void StageCanvas::OnKeyDown(wxKeyEvent& event)
{
	m_stage->OnKeyDown(event);
}

void StageCanvas::OnKeyUp(wxKeyEvent& event)
{
	m_stage->OnKeyUp(event);
}

void StageCanvas::OnChar(wxKeyEvent& event)
{
	m_stage->OnChar(event);
}

void StageCanvas::OnTimer(wxTimerEvent& event)
{
	OnTimer();

	float dt = 0.166f;
	clock_t curr_time = clock();
	static clock_t last_time = 0;
	if (last_time != 0) {
		dt = (float)(curr_time - last_time) / CLOCKS_PER_SEC;
	}
	last_time = curr_time;

	if (s2::SprTimer::Instance()->Update(dt)) {
		m_dirty = true;
	}

	gum::DTex::Instance()->Flush();
	gum::AsyncTask::Instance()->Update();

	bool dirty = m_stage->Update();
	if (dirty) {
		m_dirty = dirty;
	}

	if (m_dirty || m_cam_dirty) {
		Refresh();
	}
}

void StageCanvas::OnKillFocus(wxFocusEvent& event)
{
	m_stage->GetKeyState().Reset();
}

}<|endoftext|>


<commit_before>/*!
 * This file is part of CameraPlus.
 *
 * Copyright (C) 2012-2014 Mohammed Sameer <msameer@foolab.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "batteryinfo.h"
#include <QBatteryInfo>
#if defined(QT4)
#include <QDeclarativeInfo>
#elif defined(QT5)
#include <QQmlInfo>
#endif

BatteryInfo::BatteryInfo(QObject *parent) :
  QObject(parent),
  m_battery(0),
  m_isGood(true) {

}

BatteryInfo::~BatteryInfo() {
  setActive(false);
}

bool BatteryInfo::isGood() const {
  return m_isGood;
}

bool BatteryInfo::isActive() const {
  return m_battery != 0;
}

void BatteryInfo::setActive(bool active) {
  if (isActive() == active) {
    return;
  }

  if (!active) {
    m_battery->deleteLater();
    m_battery = 0;
  }
  else {
    m_battery = new QBatteryInfo(this);

    QObject::connect(m_battery, SIGNAL(batteryStatusChanged(int, QBatteryInfo::BatteryStatus)),
		     this, SLOT(check()));
    QObject::connect(m_battery, SIGNAL(chargingStateChanged(int, QBatteryInfo::ChargingState)),
		     this, SLOT(check()));
  }

  emit activeChanged();

  if (m_battery) {
    check();
  }
}

void BatteryInfo::check() {
  bool isGood = false;

  if (!m_battery) {
    qmlInfo(this) << "BatteryInfo has to be activated first";
    isGood = true;
  } else if (m_battery->chargingState(0) == QBatteryInfo::Charging) {
    isGood = true;
  } else {
    QBatteryInfo::BatteryStatus state = m_battery->batteryStatus(0);
    if (state == QBatteryInfo::BatteryOk || state == QBatteryInfo::BatteryFull) {
      isGood = true;
    } else {
      isGood = false;
    }
  }

  if (isGood != m_isGood) {
    m_isGood = isGood;
    emit isGoodChanged();
  }
}
<commit_msg>sailfish: initial Qt 5.2 port<commit_after>/*!
 * This file is part of CameraPlus.
 *
 * Copyright (C) 2012-2014 Mohammed Sameer <msameer@foolab.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "batteryinfo.h"
#include <QBatteryInfo>
#if defined(QT4)
#include <QDeclarativeInfo>
#elif defined(QT5)
#include <QQmlInfo>
#endif

BatteryInfo::BatteryInfo(QObject *parent) :
  QObject(parent),
  m_battery(0),
  m_isGood(true) {

}

BatteryInfo::~BatteryInfo() {
  setActive(false);
}

bool BatteryInfo::isGood() const {
  return m_isGood;
}

bool BatteryInfo::isActive() const {
  return m_battery != 0;
}

void BatteryInfo::setActive(bool active) {
  if (isActive() == active) {
    return;
  }

  if (!active) {
    m_battery->deleteLater();
    m_battery = 0;
  }
  else {
    m_battery = new QBatteryInfo(this);

    QObject::connect(m_battery, SIGNAL(levelStatusChanged(QBatteryInfo::LevelStatus)),
		     this, SLOT(check()));
    QObject::connect(m_battery, SIGNAL(chargingStateChanged(QBatteryInfo::ChargingState)),
		     this, SLOT(check()));
  }

  emit activeChanged();

  if (m_battery) {
    check();
  }
}

void BatteryInfo::check() {
  bool isGood = false;

  if (!m_battery) {
    qmlInfo(this) << "BatteryInfo has to be activated first";
    isGood = true;
  } else if (m_battery->chargingState() == QBatteryInfo::Charging) {
    isGood = true;
  } else {
    QBatteryInfo::LevelStatus state = m_battery->levelStatus();
    if (state == QBatteryInfo::LevelOk || state == QBatteryInfo::LevelFull) {
      isGood = true;
    } else {
      isGood = false;
    }
  }

  if (isGood != m_isGood) {
    m_isGood = isGood;
    emit isGoodChanged();
  }
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: xmlfiltercommon.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2004-08-20 08:30:42 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the License); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an AS IS basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _XMLFILTERCOMMON_HXX_
#define _XMLFILTERCOMMON_HXX_

#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_
#include <com/sun/star/lang/XComponent.hpp>
#endif

#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif

#ifndef _COM_SUN_STAR_CONTAINER_XHIERARCHICALNAME_HPP_
#include <com/sun/star/container/XHierarchicalName.hpp>
#endif

#ifndef _COM_SUN_STAR_CONTAINER_XNAMECONTAINER_HPP_
#include <com/sun/star/container/XNameContainer.hpp>
#endif

#ifndef _COM_SUN_STAR_IO_XINPUTSTREAM_HPP_
#include <com/sun/star/io/XInputStream.hpp>
#endif

#ifndef _COM_SUN_STAR_IO_XOUTPUTSTREAM_HPP_
#include <com/sun/star/io/XOutputStream.hpp>
#endif

#include <vector>

// --------------------------------------------------------------------

extern ::rtl::OUString string_encode( const ::rtl::OUString & rText );
extern ::rtl::OUString xmlname_encode( const ::rtl::OUString & rText );
extern ::rtl::OUString string_decode( const ::rtl::OUString & rText );

// --------------------------------------------------------------------

extern bool isFileURL( const ::rtl::OUString & rURL );

// --------------------------------------------------------------------

bool copyStreams( ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > xIS, ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > xOS );
bool createDirectory( ::rtl::OUString& rURL );

// --------------------------------------------------------------------

class filter_info_impl
{
public:
    rtl::OUString   maFilterName;
    rtl::OUString   maType;
    rtl::OUString   maDocumentService;
    rtl::OUString   maFilterService;
    rtl::OUString   maInterfaceName;
    rtl::OUString   maComment;
    rtl::OUString   maExtension;
    rtl::OUString   maDTD;
    rtl::OUString   maExportXSLT;
    rtl::OUString   maImportXSLT;
    rtl::OUString   maImportTemplate;
    rtl::OUString   maDocType;
    rtl::OUString   maImportService;
    rtl::OUString   maExportService;

    sal_Int32       maFlags;
    sal_Int32       maFileFormatVersion;
    sal_Int32       mnDocumentIconID;

    sal_Bool        mbReadonly;
    filter_info_impl();
    filter_info_impl( const filter_info_impl& rInfo );
    int operator==( const filter_info_impl& ) const;

    com::sun::star::uno::Sequence< rtl::OUString > getFilterUserData() const;
};

// --------------------------------------------------------------------

struct application_info_impl
{
    rtl::OUString   maDocumentService;
    rtl::OUString   maDocumentUIName;
    rtl::OUString   maXMLImporter;
    rtl::OUString   maXMLExporter;

    application_info_impl( const sal_Char * pDocumentService, ResId& rUINameRes, const sal_Char * mpXMLImporter, const sal_Char * mpXMLExporter );
};

// --------------------------------------------------------------------

extern std::vector< application_info_impl* >& getApplicationInfos();
extern rtl::OUString getApplicationUIName( const rtl::OUString& rServiceName );
extern const application_info_impl* getApplicationInfo( const rtl::OUString& rServiceName );

extern ResMgr* getXSLTDialogResMgr();

#define RESID(x) ResId(x, getXSLTDialogResMgr() )

#endif
<commit_msg>INTEGRATION: CWS ooo19126 (1.5.242); FILE MERGED 2005/09/05 14:31:53 rt 1.5.242.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: xmlfiltercommon.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 22:17:23 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _XMLFILTERCOMMON_HXX_
#define _XMLFILTERCOMMON_HXX_

#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_
#include <com/sun/star/lang/XComponent.hpp>
#endif

#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif

#ifndef _COM_SUN_STAR_CONTAINER_XHIERARCHICALNAME_HPP_
#include <com/sun/star/container/XHierarchicalName.hpp>
#endif

#ifndef _COM_SUN_STAR_CONTAINER_XNAMECONTAINER_HPP_
#include <com/sun/star/container/XNameContainer.hpp>
#endif

#ifndef _COM_SUN_STAR_IO_XINPUTSTREAM_HPP_
#include <com/sun/star/io/XInputStream.hpp>
#endif

#ifndef _COM_SUN_STAR_IO_XOUTPUTSTREAM_HPP_
#include <com/sun/star/io/XOutputStream.hpp>
#endif

#include <vector>

// --------------------------------------------------------------------

extern ::rtl::OUString string_encode( const ::rtl::OUString & rText );
extern ::rtl::OUString xmlname_encode( const ::rtl::OUString & rText );
extern ::rtl::OUString string_decode( const ::rtl::OUString & rText );

// --------------------------------------------------------------------

extern bool isFileURL( const ::rtl::OUString & rURL );

// --------------------------------------------------------------------

bool copyStreams( ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > xIS, ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > xOS );
bool createDirectory( ::rtl::OUString& rURL );

// --------------------------------------------------------------------

class filter_info_impl
{
public:
    rtl::OUString   maFilterName;
    rtl::OUString   maType;
    rtl::OUString   maDocumentService;
    rtl::OUString   maFilterService;
    rtl::OUString   maInterfaceName;
    rtl::OUString   maComment;
    rtl::OUString   maExtension;
    rtl::OUString   maDTD;
    rtl::OUString   maExportXSLT;
    rtl::OUString   maImportXSLT;
    rtl::OUString   maImportTemplate;
    rtl::OUString   maDocType;
    rtl::OUString   maImportService;
    rtl::OUString   maExportService;

    sal_Int32       maFlags;
    sal_Int32       maFileFormatVersion;
    sal_Int32       mnDocumentIconID;

    sal_Bool        mbReadonly;
    filter_info_impl();
    filter_info_impl( const filter_info_impl& rInfo );
    int operator==( const filter_info_impl& ) const;

    com::sun::star::uno::Sequence< rtl::OUString > getFilterUserData() const;
};

// --------------------------------------------------------------------

struct application_info_impl
{
    rtl::OUString   maDocumentService;
    rtl::OUString   maDocumentUIName;
    rtl::OUString   maXMLImporter;
    rtl::OUString   maXMLExporter;

    application_info_impl( const sal_Char * pDocumentService, ResId& rUINameRes, const sal_Char * mpXMLImporter, const sal_Char * mpXMLExporter );
};

// --------------------------------------------------------------------

extern std::vector< application_info_impl* >& getApplicationInfos();
extern rtl::OUString getApplicationUIName( const rtl::OUString& rServiceName );
extern const application_info_impl* getApplicationInfo( const rtl::OUString& rServiceName );

extern ResMgr* getXSLTDialogResMgr();

#define RESID(x) ResId(x, getXSLTDialogResMgr() )

#endif
<|endoftext|>