Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions docs/scripting-doc/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4632,6 +4632,53 @@ declare namespace Tiled {
const Zstandard: CompressionMethod;
}


/**
* Provides access to session-specific settings. The session stores
* per-project preferences like last-used tile sizes, open files, and
* file states.
*
* Values are accessed by their string key (e.g. `"map.tileWidth"`).
*
* @since 1.12
*/
interface Session {
/**
* Path to the current session file.
*/
readonly fileName: string;

/**
* Returns the session value for the given key, or `defaultValue` if
* the key is not set.
*/
get(key: string, defaultValue?: any): any;

/**
* Sets the session value for the given key.
*/
set(key: string, value: any): void;

/**
* Returns whether the given key is present in the session.
*/
isSet(key: string): boolean;

/**
* Returns the per-file state for the given file name.
*/
fileState(fileName: string): { [key: string]: any };

/**
* Sets the per-file state for the given file name.
*/
setFileState(fileName: string, fileState: { [key: string]: any }): void;

/**
* Sets a single value in the per-file state for the given file name.
*/
setFileStateValue(fileName: string, name: string, value: any): void;
}
/**
* The `tiled` module is the main entry point and provides properties,
* functions and signals which are documented below.
Expand Down Expand Up @@ -4767,6 +4814,18 @@ declare namespace tiled {
*/
export const tilesetEditor: TilesetEditor;

/**
* Provides access to the current session, allowing scripts to read and
* write session-specific settings like last-used tile size.
*
* In command-line mode (`--evaluate`), no session may be available. In
* that case, methods return safe defaults (empty strings, default
* values, etc.).
*
* @since 1.12
*/
export const session: Session;

/**
* This function can be used to trigger any registered action. This
* includes most actions you would normally trigger through the menu or
Expand Down
2 changes: 2 additions & 0 deletions src/tiled/libtilededitor.qbs
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,8 @@ DynamicLibrary {
"scriptmodule.h",
"scriptprocess.cpp",
"scriptprocess.h",
"scriptsession.cpp",
"scriptsession.h",
"scriptpropertytype.cpp",
"scriptpropertytype.h",
"selectionrectangle.cpp",
Expand Down
7 changes: 7 additions & 0 deletions src/tiled/scriptmodule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include "scriptfileformatwrappers.h"
#include "scriptimage.h"
#include "scriptmanager.h"
#include "scriptsession.h"
#include "tilesetdocument.h"
#include "tileseteditor.h"
#include "worlddocument.h"
Expand All @@ -56,6 +57,7 @@ namespace Tiled {

ScriptModule::ScriptModule(QObject *parent)
: QObject(parent)
, mSession(new ScriptSession(this))
{
// If the script module is only created for command-line use, there will
// not be a DocumentManager instance.
Expand Down Expand Up @@ -240,6 +242,11 @@ MapEditor *ScriptModule::mapEditor() const
return nullptr;
}

ScriptSession *ScriptModule::session() const
{
return mSession;
}

QColor ScriptModule::color(const QString &name) const
{
#if QT_VERSION < QT_VERSION_CHECK(6, 4, 0)
Expand Down
6 changes: 6 additions & 0 deletions src/tiled/scriptmodule.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class Document;
class EditableAsset;
class MapEditor;
class ScriptImage;
class ScriptSession;
class ScriptMapFormatWrapper;
class ScriptTilesetFormatWrapper;
class ScriptedAction;
Expand Down Expand Up @@ -75,6 +76,8 @@ class ScriptModule : public QObject
Q_PROPERTY(Tiled::TilesetEditor *tilesetEditor READ tilesetEditor)
Q_PROPERTY(QList<QObject*> worlds READ worlds)

Q_PROPERTY(Tiled::ScriptSession *session READ session)

public:
ScriptModule(QObject *parent = nullptr);
~ScriptModule() override;
Expand Down Expand Up @@ -105,6 +108,8 @@ class ScriptModule : public QObject
TilesetEditor *tilesetEditor() const;
MapEditor *mapEditor() const;

ScriptSession *session() const;

Q_INVOKABLE QColor color(const QString &name) const;
Q_INVOKABLE QColor color(float r, float g, float b, float a = 1.0f) const;
Q_INVOKABLE Tiled::FilePath filePath(const QUrl &path) const;
Expand Down Expand Up @@ -194,6 +199,7 @@ public slots:
std::map<Id, std::unique_ptr<ScriptedTool>> mRegisteredTools;

QStringList mScriptArguments;
ScriptSession *mSession = nullptr;
};

inline bool ScriptModule::versionLessThan(const QString &a)
Expand Down
73 changes: 73 additions & 0 deletions src/tiled/scriptsession.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#include "scriptsession.h"

#include "session.h"

namespace Tiled {

ScriptSession::ScriptSession(QObject *parent)
: QObject(parent)
{}

QString ScriptSession::fileName() const
{
if (!Session::hasCurrent())
return QString();
return Session::current().fileName();
}

QVariant ScriptSession::get(const QString &key,
const QVariant &defaultValue) const
{
if (!Session::hasCurrent())
return defaultValue;

const QByteArray latin1Key = key.toLatin1();
auto &session = Session::current();

if (!session.isSet(latin1Key.constData()))
return defaultValue;

return session.get<QVariant>(latin1Key.constData());
}

void ScriptSession::set(const QString &key, const QVariant &value)
{
if (!Session::hasCurrent())
return;
Session::current().set(key.toLatin1().constData(), value);
}

bool ScriptSession::isSet(const QString &key) const
{
if (!Session::hasCurrent())
return false;
return Session::current().isSet(key.toLatin1().constData());
}

QVariantMap ScriptSession::fileState(const QString &fileName) const
{
if (!Session::hasCurrent())
return {};
return Session::current().fileState(fileName);
}

void ScriptSession::setFileState(const QString &fileName,
const QVariantMap &fileState)
{
if (!Session::hasCurrent())
return;
Session::current().setFileState(fileName, fileState);
}

void ScriptSession::setFileStateValue(const QString &fileName,
const QString &name,
const QVariant &value)
{
if (!Session::hasCurrent())
return;
Session::current().setFileStateValue(fileName, name, value);
}

} // namespace Tiled

#include "moc_scriptsession.cpp"
40 changes: 40 additions & 0 deletions src/tiled/scriptsession.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@

#pragma once

#include <QObject>
#include <QVariant>
#include <QVariantMap>

namespace Tiled {

/**
* Exposes the current Session to the scripting API as tiled.session.
*
* Provides generic get/set access to session values by their string key,
* as well as access to per-file states.
*/
class ScriptSession : public QObject
{
Q_OBJECT

Q_PROPERTY(QString fileName READ fileName)

public:
explicit ScriptSession(QObject *parent = nullptr);

QString fileName() const;

Q_INVOKABLE QVariant get(const QString &key,
const QVariant &defaultValue = QVariant()) const;
Q_INVOKABLE void set(const QString &key, const QVariant &value);
Q_INVOKABLE bool isSet(const QString &key) const;

Q_INVOKABLE QVariantMap fileState(const QString &fileName) const;
Q_INVOKABLE void setFileState(const QString &fileName,
const QVariantMap &fileState);
Q_INVOKABLE void setFileStateValue(const QString &fileName,
const QString &name,
const QVariant &value);
};

}
1 change: 1 addition & 0 deletions src/tiled/session.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ class TILED_EDITOR_EXPORT Session : protected FileHelper

static Session &initialize();
static Session &current();
static bool hasCurrent() { return mCurrent != nullptr; }
static Session &switchCurrent(const QString &fileName);
static void deinitialize();

Expand Down