Skip to content

Commit

Permalink
add UnloadAllWorlds actions, exposed in World > Unload World when two…
Browse files Browse the repository at this point in the history
… or more worlds are loaded

expose world related signals to scripting
expose loading, unloading, accessing worlds to scripting
  • Loading branch information
dogboydog committed Dec 19, 2023
1 parent 281d1e0 commit 6816b58
Show file tree
Hide file tree
Showing 11 changed files with 375 additions and 2 deletions.
96 changes: 96 additions & 0 deletions docs/scripting-doc/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1131,6 +1131,44 @@ declare class Project extends TiledObject {
readonly fileName: string;
}

/**
* For a map that is added to a {@link World},
* @since 1.10.x TODO
*/
declare class WorldMapEntry {
/**
* File name of the map.
*/
fileName : string;
/**
* A rect describing the location and dimensions of the map within the World.
*/
rect : rect;
}

/**
* A world defined in a .world file, which is a JSON file that tells
* Tiled which maps are part of the world and at what location.
* https://doc.mapeditor.org/en/stable/manual/worlds/
* @since 1.10.x TODO
*/
declare class World extends TiledObject {
/**
* Returns all maps that are added to this World.
*/
allMaps() : WorldMapEntry[];
/**
* Return any maps that intersect with the given {@link rect} .
* @param rect - the rect used to
*/
mapsInRect(rect : rect) : WorldMapEntry[];
/**
* Returns true if this World contains the map specified in fileName.
* @param fileName filename of the map
*/
containsMap(fileName : string) : boolean;
}

/**
* Defines the font used to render objects which have {@link MapObject.shape}
* set to {@link MapObject.Text}.
Expand Down Expand Up @@ -4361,6 +4399,64 @@ declare namespace tiled {
* The {@link activeAsset} has changed.
*/
export const activeAssetChanged: Signal<Asset>;

/**
* A list of all currently loaded {@link World|worlds}.
* @since 1.10.x TODO
*/
export const worlds : World[];

/**
* Load a world contained in a .world file in the path fileName.
* @since 1.10.x TODO
*/
export function loadWorld(fileName : string) : void;

/**
* Unload a world contained in a .world file in the path fileName.
* @since 1.10.x TODO
*/
export function unloadWorld(fileName : string) : void;

/**
* Unload all currently loaded worlds.
* @since 1.10.x TODO
*/
export function unloadAllWorlds() : void;

/**
* Signal emitted when any world is saved, loaded, unloaded, or reloaded.
* @since 1.10.x TODO
*/
export const worldsChanged : Signal<void>;

/**
* Signal emitted when a world is loaded.
* Provides the file name of the world that was loaded.
* @since 1.10.x TODO
*/
export const worldLoaded : Signal<string>;

/**
* Signal emitted when a world is reloaded.
* Provides the file name of the world that was reloaded.
* @since 1.10.x TODO
*/
export const worldReloaded : Signal<string>;

/**
* Signal emitted when a world is reloaded.
* Provides the file name of the world that was unloaded.
* @since 1.10.x TODO
*/
export const worldUnloaded : Signal<string>;

/**
* Signal emitted when a world is reloaded.
* Provides the file name of the world that was saved.
* @since 1.10.x TODO
*/
export const worldSaved : Signal<string>;
}

/**
Expand Down
90 changes: 90 additions & 0 deletions src/tiled/editableworld.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* editableworld.cpp
* Copyright 2023, Chris Boehm AKA dogboydog
* Copyright 2023, Thorbjørn Lindeijer <[email protected]>
*
* This file is part of Tiled.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program 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 General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "editableworld.h"
#include "worlddocument.h"
#include "worldmanager.h"

namespace Tiled {

ScriptWorld::ScriptWorld(World *world)
: Object(*this)
{
this->world = world;
}

EditableWorld::EditableWorld(WorldDocument *worldDocument, QObject *parent)
: EditableAsset(worldDocument, &mWorldObject, parent),
mWorldObject(ScriptWorld(WorldManager::instance().worlds().value(worldDocument->fileName())))
{
}


ScriptWorldMapEntry::ScriptWorldMapEntry(World::MapEntry *mapEntry)
: mMapEntry(mapEntry)
{

}

QString ScriptWorldMapEntry::fileName() const
{
return mMapEntry->fileName;
}
QRect ScriptWorldMapEntry::rect() const
{
return mMapEntry->rect;
}
QString EditableWorld::displayName() const
{
return world()->displayName();
}

bool EditableWorld::containsMap(const QString &fileName)
{
return world()->containsMap(fileName);
}

QVector<ScriptWorldMapEntry*> EditableWorld::allMaps() const
{
QVector<ScriptWorldMapEntry*> maps;
for (auto &entry : world()->allMaps())
maps.append(new ScriptWorldMapEntry(&entry));
return maps;
}
QVector<ScriptWorldMapEntry*> EditableWorld::mapsInRect(const QRect &rect) const
{
QVector<ScriptWorldMapEntry*> maps;
for (auto &entry : world()->mapsInRect(rect))
maps.append(new ScriptWorldMapEntry(&entry));
return maps;
}
bool EditableWorld::isReadOnly() const
{
return !world()->canBeModified();
}

QSharedPointer<Document> EditableWorld::createDocument()
{
// We don't currently support opening a world in its own tab, which this
// function is meant for.
return nullptr;
}
}
92 changes: 92 additions & 0 deletions src/tiled/editableworld.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
* editableworld.h
* Copyright 2023, Chris Boehm AKA dogboydog
* Copyright 2023, Thorbjørn Lindeijer <[email protected]>
*
* This file is part of Tiled.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program 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 General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once

#include "editableasset.h"
#include "worlddocument.h"
#include "worldmanager.h"
#include <QObject>

namespace Tiled {
/*
* Wrapper which allows world structs to be used with the EditableAsset
* class
*/
class ScriptWorld : public Object
{

public:
ScriptWorld(World *world);
World *world;
};

/*
* Exposes the World::MapEntry struct to scripting
*/
class ScriptWorldMapEntry : public QObject
{
Q_OBJECT
Q_PROPERTY(QString fileName READ fileName CONSTANT)
Q_PROPERTY(QRect rect READ rect CONSTANT)

public:
ScriptWorldMapEntry(World::MapEntry *mapEntry);
QString fileName() const;
QRect rect() const;

private:
World::MapEntry *mMapEntry;
};

/**
* @brief The EditableWorld class provides access to Worlds via scripting
*/
class EditableWorld final : public EditableAsset
{

Q_OBJECT
Q_PROPERTY(QString displayName READ displayName)
Q_PROPERTY(QVector<ScriptWorldMapEntry*> allMaps READ allMaps)

public:
EditableWorld(WorldDocument *worldDocument, QObject *parent = nullptr);
bool isReadOnly() const override;
World *world() const;
QString displayName() const;
Q_INVOKABLE QVector<ScriptWorldMapEntry*> allMaps() const;
Q_INVOKABLE QVector<ScriptWorldMapEntry*> mapsInRect(const QRect &rect) const;
Q_INVOKABLE bool containsMap(const QString &fileName);

QSharedPointer<Document> createDocument() override;

private:
ScriptWorld mWorldObject;
};

inline World *EditableWorld::world() const
{
return static_cast<ScriptWorld*>(object())->world;
}

}

Q_DECLARE_METATYPE(Tiled::EditableWorld*)
Q_DECLARE_METATYPE(Tiled::ScriptWorldMapEntry*)
2 changes: 2 additions & 0 deletions src/tiled/libtilededitor.qbs
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,8 @@ DynamicLibrary {
"editabletileset.h",
"editablewangset.cpp",
"editablewangset.h",
"editableworld.cpp",
"editableworld.h",
"editor.cpp",
"editor.h",
"editpolygontool.cpp",
Expand Down
5 changes: 5 additions & 0 deletions src/tiled/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ MainWindow::MainWindow(QWidget *parent, Qt::WindowFlags flags)
ActionManager::registerAction(mUi->actionLabelsForAllObjects, "LabelsForAllObjects");
ActionManager::registerAction(mUi->actionLabelsForSelectedObjects, "LabelsForSelectedObjects");
ActionManager::registerAction(mUi->actionLoadWorld, "LoadWorld");
ActionManager::registerAction(mUi->actionUnloadAllWorlds, "UnloadAllWorlds");
ActionManager::registerAction(mUi->actionMapProperties, "MapProperties");
ActionManager::registerAction(mUi->actionNewMap, "NewMap");
ActionManager::registerAction(mUi->actionNewProject, "NewProject");
Expand Down Expand Up @@ -615,6 +616,8 @@ MainWindow::MainWindow(QWidget *parent, Qt::WindowFlags flags)
mLoadedWorlds = WorldManager::instance().worlds().keys();
});
}
if (WorldManager::instance().worlds().count() >= 2)
mUi->menuUnloadWorld->addAction(mUi->actionUnloadAllWorlds);
});
connect(mUi->actionNewWorld, &QAction::triggered, this, [this] {
Session &session = Session::current();
Expand Down Expand Up @@ -656,8 +659,10 @@ MainWindow::MainWindow(QWidget *parent, Qt::WindowFlags flags)
});
}
});
connect(mUi->actionUnloadAllWorlds, &QAction::triggered, this, []{WorldManager::instance().unloadAllWorlds();});
connect(mUi->menuWorld, &QMenu::aboutToShow, this, [this] {
mUi->menuUnloadWorld->setEnabled(!WorldManager::instance().worlds().isEmpty());
mUi->actionUnloadAllWorlds->setEnabled(!WorldManager::instance().worlds().isEmpty());
mUi->menuSaveWorld->setEnabled(DocumentManager::instance()->isAnyWorldModified());
});
connect(mUi->actionResizeMap, &QAction::triggered, this, &MainWindow::resizeMap);
Expand Down
6 changes: 6 additions & 0 deletions src/tiled/mainwindow.ui
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@
<property name="title">
<string>&amp;Unload World</string>
</property>
<addaction name="actionUnloadAllWorlds"/>
</widget>
<widget class="QMenu" name="menuSaveWorld">
<property name="title">
Expand Down Expand Up @@ -804,6 +805,11 @@
<string notr="true">Ctrl+Shift+P</string>
</property>
</action>
<action name="actionUnloadAllWorlds">
<property name="text">
<string>Unload All Worlds</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources>
Expand Down
2 changes: 2 additions & 0 deletions src/tiled/scriptmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "editabletilelayer.h"
#include "editabletileset.h"
#include "editablewangset.h"
#include "editableworld.h"
#include "logginginterface.h"
#include "mapeditor.h"
#include "mapview.h"
Expand Down Expand Up @@ -115,6 +116,7 @@ ScriptManager::ScriptManager(QObject *parent)
qRegisterMetaType<EditableTileLayer*>();
qRegisterMetaType<EditableTileset*>();
qRegisterMetaType<EditableWangSet*>();
qRegisterMetaType<EditableWorld*>();
qRegisterMetaType<Font>();
qRegisterMetaType<MapEditor*>();
qRegisterMetaType<MapView*>();
Expand Down
Loading

0 comments on commit 6816b58

Please sign in to comment.