1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-16 17:59:56 +00:00

Document the Lua Image widget, add UI texture resources

This commit is contained in:
uramer 2022-02-07 23:37:08 +01:00
parent 58e794414a
commit e092ee2624
10 changed files with 209 additions and 43 deletions

View file

@ -37,6 +37,8 @@ namespace MWLua
mLocalLoader = createUserdataSerializer(true, mWorldView.getObjectRegistry(), &mContentFileMapping); mLocalLoader = createUserdataSerializer(true, mWorldView.getObjectRegistry(), &mContentFileMapping);
mGlobalScripts.setSerializer(mGlobalSerializer.get()); mGlobalScripts.setSerializer(mGlobalSerializer.get());
mUiResourceManager = std::make_unique<LuaUi::ResourceManager>(vfs);
} }
void LuaManager::initConfiguration() void LuaManager::initConfiguration()

View file

@ -8,6 +8,8 @@
#include <components/lua/luastate.hpp> #include <components/lua/luastate.hpp>
#include <components/lua/storage.hpp> #include <components/lua/storage.hpp>
#include <components/lua_ui/resources.hpp>
#include "../mwbase/luamanager.hpp" #include "../mwbase/luamanager.hpp"
#include "actions.hpp" #include "actions.hpp"
@ -89,10 +91,14 @@ namespace MWLua
return [this, c](Arg arg) { this->queueCallback(c, sol::make_object(c.mFunc.lua_state(), arg)); }; return [this, c](Arg arg) { this->queueCallback(c, sol::make_object(c.mFunc.lua_state(), arg)); };
} }
LuaUi::ResourceManager* uiResourceManager() { return mUiResourceManager.get(); }
private: private:
void initConfiguration(); void initConfiguration();
LocalScripts* createLocalScripts(const MWWorld::Ptr& ptr, ESM::LuaScriptCfg::Flags); LocalScripts* createLocalScripts(const MWWorld::Ptr& ptr, ESM::LuaScriptCfg::Flags);
std::unique_ptr<LuaUi::ResourceManager> mUiResourceManager;
bool mInitialized = false; bool mInitialized = false;
bool mGlobalScriptsStarted = false; bool mGlobalScriptsStarted = false;
LuaUtil::ScriptsConfiguration mConfiguration; LuaUtil::ScriptsConfiguration mConfiguration;

View file

@ -4,6 +4,7 @@
#include <components/lua_ui/content.hpp> #include <components/lua_ui/content.hpp>
#include <components/lua_ui/registerscriptsettings.hpp> #include <components/lua_ui/registerscriptsettings.hpp>
#include <components/lua_ui/alignment.hpp> #include <components/lua_ui/alignment.hpp>
#include <components/lua_ui/resources.hpp>
#include "context.hpp" #include "context.hpp"
#include "actions.hpp" #include "actions.hpp"
@ -77,46 +78,46 @@ namespace MWLua
std::shared_ptr<LuaUi::Element> mElement; std::shared_ptr<LuaUi::Element> mElement;
}; };
class LayerAction final : public Action
{
public:
LayerAction(std::string_view name, std::string_view afterName,
LuaUi::Layers::Options options, LuaUtil::LuaState* state)
: Action(state)
, mName(name)
, mAfterName(afterName)
, mOptions(options)
{}
void apply(WorldView&) const override
{
size_t index = LuaUi::Layers::indexOf(mAfterName);
if (index == LuaUi::Layers::size())
throw std::logic_error(std::string("Layer not found"));
LuaUi::Layers::insert(index, mName, mOptions);
}
std::string toString() const override
{
std::string result("Insert UI layer \"");
result += mName;
result += "\" after \"";
result += mAfterName;
result += "\"";
return result;
}
private:
std::string mName;
std::string mAfterName;
LuaUi::Layers::Options mOptions;
};
// Lua arrays index from 1 // Lua arrays index from 1
inline size_t fromLuaIndex(size_t i) { return i - 1; } inline size_t fromLuaIndex(size_t i) { return i - 1; }
inline size_t toLuaIndex(size_t i) { return i + 1; } inline size_t toLuaIndex(size_t i) { return i + 1; }
} }
class LayerAction final : public Action
{
public:
LayerAction(std::string_view name, std::string_view afterName,
LuaUi::Layers::Options options, LuaUtil::LuaState* state)
: Action(state)
, mName(name)
, mAfterName(afterName)
, mOptions(options)
{}
void apply(WorldView&) const override
{
size_t index = LuaUi::Layers::indexOf(mAfterName);
if (index == LuaUi::Layers::size())
throw std::logic_error(std::string("Layer not found"));
LuaUi::Layers::insert(index, mName, mOptions);
}
std::string toString() const override
{
std::string result("Insert UI layer \"");
result += mName;
result += "\" after \"";
result += mAfterName;
result += "\"";
return result;
}
private:
std::string mName;
std::string mAfterName;
LuaUi::Layers::Options mOptions;
};
sol::table initUserInterfacePackage(const Context& context) sol::table initUserInterfacePackage(const Context& context)
{ {
auto uiContent = context.mLua->sol().new_usertype<LuaUi::Content>("UiContent"); auto uiContent = context.mLua->sol().new_usertype<LuaUi::Content>("UiContent");
@ -278,6 +279,23 @@ namespace MWLua
api["registerSettingsPage"] = &LuaUi::registerSettingsPage; api["registerSettingsPage"] = &LuaUi::registerSettingsPage;
api["texture"] = [luaManager=context.mLuaManager](const sol::table& options)
{
LuaUi::TextureData data;
sol::object path = LuaUtil::getFieldOrNil(options, "path");
if (path.is<std::string>() and !path.as<std::string>().empty())
data.mPath = path.as<std::string>();
else
throw sol::error("Invalid texture path");
sol::object offset = LuaUtil::getFieldOrNil(options, "offset");
if (offset.is<osg::Vec2f>())
data.mOffset = offset.as<osg::Vec2f>();
sol::object size = LuaUtil::getFieldOrNil(options, "size");
if (size.is<osg::Vec2f>())
data.mSize = size.as<osg::Vec2f>();
return luaManager->uiResourceManager()->registerTexture(data);
};
return LuaUtil::makeReadOnly(api); return LuaUtil::makeReadOnly(api);
} }
} }

View file

@ -259,7 +259,7 @@ add_component_dir (queries
add_component_dir (lua_ui add_component_dir (lua_ui
registerscriptsettings scriptsettings registerscriptsettings scriptsettings
properties widget element util layers content alignment properties widget element util layers content alignment resources
adapter text textedit window image container adapter text textedit window image container
) )

View file

@ -2,6 +2,8 @@
#include <MyGUI_RenderManager.h> #include <MyGUI_RenderManager.h>
#include "resources.hpp"
namespace LuaUi namespace LuaUi
{ {
void LuaTileRect::_setAlign(const MyGUI::IntSize& _oldsize) void LuaTileRect::_setAlign(const MyGUI::IntSize& _oldsize)
@ -33,19 +35,38 @@ namespace LuaUi
void LuaImage::updateProperties() void LuaImage::updateProperties()
{ {
setImageTexture(propertyValue("path", std::string())); TextureResource* resource = propertyValue<TextureResource*>("resource", nullptr);
MyGUI::IntCoord atlasCoord;
if (resource)
{
auto& data = resource->data();
atlasCoord = MyGUI::IntCoord(
static_cast<int>(data.mOffset.x()),
static_cast<int>(data.mOffset.y()),
static_cast<int>(data.mSize.x()),
static_cast<int>(data.mSize.y()));
setImageTexture(data.mPath);
}
bool tileH = propertyValue("tileH", false); bool tileH = propertyValue("tileH", false);
bool tileV = propertyValue("tileV", false); bool tileV = propertyValue("tileV", false);
MyGUI::ITexture* texture = MyGUI::RenderManager::getInstance().getTexture(_getTextureName()); MyGUI::ITexture* texture = MyGUI::RenderManager::getInstance().getTexture(_getTextureName());
MyGUI::IntSize textureSize; MyGUI::IntSize textureSize;
if (texture != nullptr) if (texture != nullptr)
textureSize = MyGUI::IntSize(texture->getWidth(), texture->getHeight()); textureSize = MyGUI::IntSize(texture->getWidth(), texture->getHeight());
mTileRect->updateSize(MyGUI::IntSize( mTileRect->updateSize(MyGUI::IntSize(
tileH ? textureSize.width : 0, tileH ? textureSize.width : 0,
tileV ? textureSize.height : 0 tileV ? textureSize.height : 0
)); ));
if (atlasCoord.width == 0)
atlasCoord.width = textureSize.width;
if (atlasCoord.height == 0)
atlasCoord.height = textureSize.height;
setImageCoord(atlasCoord);
WidgetExtension::updateProperties(); WidgetExtension::updateProperties();
} }
} }

View file

@ -0,0 +1,23 @@
#include "resources.hpp"
#include <components/vfs/manager.hpp>
namespace LuaUi
{
std::shared_ptr<TextureResource> ResourceManager::registerTexture(TextureData data)
{
std::string normalizedPath = vfs()->normalizeFilename(data.mPath);
if (!vfs()->exists(normalizedPath))
{
std::string error("Texture with path \"");
error += data.mPath;
error += "\" doesn't exist";
throw std::logic_error(error);
}
data.mPath = normalizedPath;
TextureResources& list = mTextures[normalizedPath];
list.push_back(std::make_shared<TextureResource>(data));
return list.back();
}
}

View file

@ -0,0 +1,55 @@
#ifndef OPENMW_LUAUI_RESOURCES
#define OPENMW_LUAUI_RESOURCES
#include <string>
#include <unordered_map>
#include <vector>
#include <memory>
#include <osg/Vec2f>
namespace VFS
{
class Manager;
}
namespace LuaUi
{
struct TextureData
{
std::string mPath;
osg::Vec2f mOffset;
osg::Vec2f mSize;
};
class TextureResource
{
public:
TextureResource(TextureData data)
: mData(data)
{}
const TextureData& data() { return mData; }
private:
TextureData mData;
};
class ResourceManager {
public:
ResourceManager(const VFS::Manager* vfs)
: mVfs(vfs)
{}
std::shared_ptr<TextureResource> registerTexture(TextureData data);
protected:
const VFS::Manager* vfs() const { return mVfs; }
private:
const VFS::Manager* mVfs;
using TextureResources = std::vector<std::shared_ptr<TextureResource>>;
std::unordered_map<std::string, TextureResources> mTextures;
};
}
#endif // OPENMW_LUAUI_LAYERS

View file

@ -80,6 +80,7 @@ Widget types
Widget: Base widget type, all the other widgets inherit its properties and events. <widgets/widget> Widget: Base widget type, all the other widgets inherit its properties and events. <widgets/widget>
Text: Displays text. <widgets/text> Text: Displays text. <widgets/text>
TextEdit: Accepts text input from the user. <widgets/textedit> TextEdit: Accepts text input from the user. <widgets/textedit>
Image: Renders a texture. <widgets/image>
Example Example
------- -------

View file

@ -0,0 +1,22 @@
Image Widget
============
Properties
----------
.. list-table::
:header-rows: 1
:widths: 20 20 60
* - name
- type (default value)
- description
* - resource
- ui.texture
- The texture resource to display
* - tileH
- boolean (false)
- Whether to tile the texture horizontally
* - tileV
- boolean (false)
- Whether to tile the texture vertically

View file

@ -53,7 +53,15 @@
--- ---
-- Adds a settings page to main menu setting's Scripts tab. -- Adds a settings page to main menu setting's Scripts tab.
-- @function [parent=#ui] registerSettingsPage -- @function [parent=#ui] registerSettingsPage
-- @param #SettingsPage page -- @param #SettingsPageOptions page
---
-- Table with settings page options, passed as an argument to ui.registerSettingsPage
-- @type SettingsPageOptions
-- @field #string name Name of the page, displayed in the list, used for search
-- @field #string searchHints Additional keywords used in search, not displayed anywhere
-- @field #Element element The page's UI, which will be attached to the settings tab. The root widget has to have a fixed size (set `size` field in `props`, see Widget documentation, `relativeSize` is ignored)
--- ---
-- Layout -- Layout
@ -162,10 +170,20 @@
-- @field #number button Mouse button which triggered the event (could be nil) -- @field #number button Mouse button which triggered the event (could be nil)
--- ---
-- Settings page parameters, passed as an argument to ui.registerSettingsPage -- Register a new texture resource
-- @type SettingsPage -- @function [parent=#ui] texture #TextureResource
-- @field #string name Name of the page, displayed in the list, used for search -- @param #TextureResourceOptions options
-- @field #string searchHints Additional keywords used in search, not displayed anywhere
-- @field #Element element The page's UI, which will be attached to the settings tab. The root widget has to have a fixed size (set `size` field in `props`, see Widget documentation, `relativeSize` is ignored) ---
-- A texture ready to be used by UI widgets
-- @type TextureResource
---
-- Table with argument passed to ui.texture
-- @type TextureResourceOptions
-- @field #string path Path to the texture file. Required
-- @field openmw.util#Vector2 offset Offset of this resource in the texture. (0, 0) by default
-- @field openmw.util#Vector2 size Size of the resource in the texture. (0, 0) by default.
-- 0 means the whole texture size is used.
return nil return nil