1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-11-29 16:34:30 +00:00

Merge branch 'warn-baby-warn-warning-inferno' into 'master'

Warning inferno - fix warnings, then fix warnings

Closes #8674

See merge request OpenMW/openmw!4927
This commit is contained in:
Alexei Kotov 2025-11-23 15:01:53 +03:00
commit b49b048f72
361 changed files with 2203 additions and 2196 deletions

View file

@ -36,7 +36,7 @@ variables:
Ubuntu_GCC_preprocess: Ubuntu_GCC_preprocess:
extends: .Ubuntu_Image extends: .Ubuntu_Image
cache: cache:
key: Ubuntu_GCC_preprocess.ubuntu_24.04.v1 key: Ubuntu_GCC_preprocess.ubuntu_24.04.v2
paths: paths:
- apt-cache/ - apt-cache/
- .cache/pip/ - .cache/pip/
@ -105,7 +105,7 @@ Coverity:
rules: rules:
- if: $CI_PIPELINE_SOURCE == "schedule" - if: $CI_PIPELINE_SOURCE == "schedule"
cache: cache:
key: Coverity.ubuntu_24.04.v1 key: Coverity.ubuntu_24.04.v2
paths: paths:
- apt-cache/ - apt-cache/
- ccache/ - ccache/
@ -161,7 +161,7 @@ Coverity_Upload:
Ubuntu_GCC: Ubuntu_GCC:
extends: .Ubuntu extends: .Ubuntu
cache: cache:
key: Ubuntu_GCC.ubuntu_24.04.v1 key: Ubuntu_GCC.ubuntu_24.04.v2
before_script: before_script:
- CI/install_debian_deps.sh gcc openmw-deps openmw-deps-dynamic - CI/install_debian_deps.sh gcc openmw-deps openmw-deps-dynamic
variables: variables:
@ -174,7 +174,7 @@ Ubuntu_GCC:
Ubuntu_GCC_asan: Ubuntu_GCC_asan:
extends: Ubuntu_GCC extends: Ubuntu_GCC
cache: cache:
key: Ubuntu_GCC_asan.ubuntu_24.04.v1 key: Ubuntu_GCC_asan.ubuntu_24.04.v2
variables: variables:
CMAKE_BUILD_TYPE: Debug CMAKE_BUILD_TYPE: Debug
CMAKE_CXX_FLAGS_DEBUG: -g -O1 -fno-omit-frame-pointer -fsanitize=address -fsanitize=pointer-subtract -fsanitize=leak CMAKE_CXX_FLAGS_DEBUG: -g -O1 -fno-omit-frame-pointer -fsanitize=address -fsanitize=pointer-subtract -fsanitize=leak
@ -187,7 +187,7 @@ Clang_Format:
extends: .Ubuntu_Image extends: .Ubuntu_Image
stage: checks stage: checks
cache: cache:
key: Ubuntu_Clang_Format.ubuntu_24.04.v1 key: Ubuntu_Clang_Format.ubuntu_24.04.v2
paths: paths:
- apt-cache/ - apt-cache/
variables: variables:
@ -203,7 +203,7 @@ Lupdate:
extends: .Ubuntu_Image extends: .Ubuntu_Image
stage: checks stage: checks
cache: cache:
key: Ubuntu_lupdate.ubuntu_24.04.v1 key: Ubuntu_lupdate.ubuntu_24.04.v2
paths: paths:
- apt-cache/ - apt-cache/
variables: variables:
@ -229,7 +229,7 @@ Teal:
Ubuntu_GCC_Debug: Ubuntu_GCC_Debug:
extends: .Ubuntu extends: .Ubuntu
cache: cache:
key: Ubuntu_GCC_Debug.ubuntu_24.04.v2 key: Ubuntu_GCC_Debug.ubuntu_24.04.v3
before_script: before_script:
- CI/install_debian_deps.sh gcc openmw-deps openmw-deps-dynamic - CI/install_debian_deps.sh gcc openmw-deps openmw-deps-dynamic
variables: variables:
@ -245,7 +245,7 @@ Ubuntu_GCC_Debug:
Ubuntu_GCC_tests: Ubuntu_GCC_tests:
extends: Ubuntu_GCC extends: Ubuntu_GCC
cache: cache:
key: Ubuntu_GCC_tests.ubuntu_24.04.v1 key: Ubuntu_GCC_tests.ubuntu_24.04.v2
variables: variables:
CCACHE_SIZE: 1G CCACHE_SIZE: 1G
BUILD_TESTS_ONLY: 1 BUILD_TESTS_ONLY: 1
@ -259,7 +259,7 @@ Ubuntu_GCC_tests:
.Ubuntu_GCC_tests_Debug: .Ubuntu_GCC_tests_Debug:
extends: Ubuntu_GCC extends: Ubuntu_GCC
cache: cache:
key: Ubuntu_GCC_tests_Debug.ubuntu_24.04.v1 key: Ubuntu_GCC_tests_Debug.ubuntu_24.04.v2
variables: variables:
CCACHE_SIZE: 1G CCACHE_SIZE: 1G
BUILD_TESTS_ONLY: 1 BUILD_TESTS_ONLY: 1
@ -275,7 +275,7 @@ Ubuntu_GCC_tests:
Ubuntu_GCC_tests_asan: Ubuntu_GCC_tests_asan:
extends: Ubuntu_GCC extends: Ubuntu_GCC
cache: cache:
key: Ubuntu_GCC_tests_asan.ubuntu_24.04.v1 key: Ubuntu_GCC_tests_asan.ubuntu_24.04.v2
variables: variables:
CCACHE_SIZE: 1G CCACHE_SIZE: 1G
BUILD_TESTS_ONLY: 1 BUILD_TESTS_ONLY: 1
@ -298,7 +298,7 @@ Ubuntu_GCC_tests_asan:
Ubuntu_GCC_tests_ubsan: Ubuntu_GCC_tests_ubsan:
extends: Ubuntu_GCC extends: Ubuntu_GCC
cache: cache:
key: Ubuntu_GCC_tests_ubsan.ubuntu_24.04.v1 key: Ubuntu_GCC_tests_ubsan.ubuntu_24.04.v2
variables: variables:
CCACHE_SIZE: 1G CCACHE_SIZE: 1G
BUILD_TESTS_ONLY: 1 BUILD_TESTS_ONLY: 1
@ -318,7 +318,7 @@ Ubuntu_GCC_tests_ubsan:
.Ubuntu_GCC_tests_tsan: .Ubuntu_GCC_tests_tsan:
extends: Ubuntu_GCC extends: Ubuntu_GCC
cache: cache:
key: Ubuntu_GCC_tests_tsan.ubuntu_24.04.v1 key: Ubuntu_GCC_tests_tsan.ubuntu_24.04.v2
variables: variables:
CCACHE_SIZE: 1G CCACHE_SIZE: 1G
BUILD_TESTS_ONLY: 1 BUILD_TESTS_ONLY: 1
@ -336,7 +336,7 @@ Ubuntu_GCC_tests_ubsan:
Ubuntu_GCC_tests_coverage: Ubuntu_GCC_tests_coverage:
extends: .Ubuntu_GCC_tests_Debug extends: .Ubuntu_GCC_tests_Debug
cache: cache:
key: Ubuntu_GCC_tests_coverage.ubuntu_24.04.v1 key: Ubuntu_GCC_tests_coverage.ubuntu_24.04.v2
paths: paths:
- .cache/pip - .cache/pip
variables: variables:
@ -369,7 +369,7 @@ Ubuntu_GCC_tests_coverage:
- "CI/**/*" - "CI/**/*"
- ".gitlab-ci.yml" - ".gitlab-ci.yml"
cache: cache:
key: Ubuntu_Static_Deps.ubuntu_24.04.v1 key: Ubuntu_Static_Deps.ubuntu_24.04.v2
paths: paths:
- apt-cache/ - apt-cache/
- ccache/ - ccache/
@ -386,7 +386,7 @@ Ubuntu_GCC_tests_coverage:
.Ubuntu_Static_Deps_tests: .Ubuntu_Static_Deps_tests:
extends: .Ubuntu_Static_Deps extends: .Ubuntu_Static_Deps
cache: cache:
key: Ubuntu_Static_Deps_tests.ubuntu_24.04.v1 key: Ubuntu_Static_Deps_tests.ubuntu_24.04.v2
variables: variables:
CCACHE_SIZE: 1G CCACHE_SIZE: 1G
BUILD_TESTS_ONLY: 1 BUILD_TESTS_ONLY: 1
@ -405,7 +405,7 @@ Ubuntu_Clang:
before_script: before_script:
- CI/install_debian_deps.sh clang openmw-deps openmw-deps-dynamic - CI/install_debian_deps.sh clang openmw-deps openmw-deps-dynamic
cache: cache:
key: Ubuntu_Clang.ubuntu_24.04.v2 key: Ubuntu_Clang.ubuntu_24.04.v3
variables: variables:
CC: clang CC: clang
CXX: clang++ CXX: clang++
@ -418,7 +418,7 @@ Ubuntu_Clang:
before_script: before_script:
- CI/install_debian_deps.sh clang clang-tidy openmw-deps openmw-deps-dynamic - CI/install_debian_deps.sh clang clang-tidy openmw-deps openmw-deps-dynamic
cache: cache:
key: Ubuntu_Clang_Tidy.ubuntu_24.04.v1 key: Ubuntu_Clang_Tidy.ubuntu_24.04.v2
variables: variables:
CMAKE_BUILD_TYPE: Debug CMAKE_BUILD_TYPE: Debug
CMAKE_CXX_FLAGS_DEBUG: -O0 CMAKE_CXX_FLAGS_DEBUG: -O0
@ -480,7 +480,7 @@ Ubuntu_Clang_Tidy_other:
.Ubuntu_Clang_tests: .Ubuntu_Clang_tests:
extends: Ubuntu_Clang extends: Ubuntu_Clang
cache: cache:
key: Ubuntu_Clang_tests.ubuntu_24.04.v1 key: Ubuntu_Clang_tests.ubuntu_24.04.v2
variables: variables:
CCACHE_SIZE: 1G CCACHE_SIZE: 1G
BUILD_TESTS_ONLY: 1 BUILD_TESTS_ONLY: 1
@ -494,7 +494,7 @@ Ubuntu_Clang_Tidy_other:
Ubuntu_Clang_tests_Debug: Ubuntu_Clang_tests_Debug:
extends: Ubuntu_Clang extends: Ubuntu_Clang
cache: cache:
key: Ubuntu_Clang_tests_Debug.ubuntu_24.04.v1 key: Ubuntu_Clang_tests_Debug.ubuntu_24.04.v2
variables: variables:
CCACHE_SIZE: 1G CCACHE_SIZE: 1G
BUILD_TESTS_ONLY: 1 BUILD_TESTS_ONLY: 1
@ -529,7 +529,7 @@ Ubuntu_Clang_integration_tests:
needs: needs:
- Ubuntu_Clang - Ubuntu_Clang
cache: cache:
key: Ubuntu_Clang_integration_tests.ubuntu_24.04.v2 key: Ubuntu_Clang_integration_tests.ubuntu_24.04.v3
variables: variables:
OPENMW_DEPS: openmw-integration-tests OPENMW_DEPS: openmw-integration-tests
@ -538,7 +538,7 @@ Ubuntu_GCC_integration_tests_asan:
needs: needs:
- Ubuntu_GCC_asan - Ubuntu_GCC_asan
cache: cache:
key: Ubuntu_GCC_integration_tests_asan.ubuntu_24.04.v1 key: Ubuntu_GCC_integration_tests_asan.ubuntu_24.04.v2
variables: variables:
OPENMW_DEPS: openmw-integration-tests libasan OPENMW_DEPS: openmw-integration-tests libasan
ASAN_OPTIONS: halt_on_error=1:strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1:detect_leaks=0 ASAN_OPTIONS: halt_on_error=1:strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1:detect_leaks=0
@ -591,7 +591,7 @@ Ubuntu_GCC_integration_tests_asan:
macOS15_Xcode16_amd64: macOS15_Xcode16_amd64:
extends: .MacOS extends: .MacOS
cache: cache:
key: macOS15_Xcode16_amd64.v1 key: macOS15_Xcode16_amd64.v2
variables: variables:
CCACHE_SIZE: 3G CCACHE_SIZE: 3G
DMG_IDENTIFIER: amd64 DMG_IDENTIFIER: amd64
@ -603,7 +603,7 @@ macOS15_Xcode16_amd64:
macOS15_Xcode16_arm64: macOS15_Xcode16_arm64:
extends: .MacOS extends: .MacOS
cache: cache:
key: macOS15_Xcode16_arm64.v1 key: macOS15_Xcode16_arm64.v2
variables: variables:
DMG_IDENTIFIER: arm64 DMG_IDENTIFIER: arm64
CCACHE_SIZE: 3G CCACHE_SIZE: 3G

View file

@ -482,7 +482,6 @@ set(SOL_CONFIG_DIR ${OpenMW_SOURCE_DIR}/extern/sol_config)
include_directories( include_directories(
BEFORE SYSTEM BEFORE SYSTEM
"."
${MyGUI_INCLUDE_DIRS} ${MyGUI_INCLUDE_DIRS}
${OPENAL_INCLUDE_DIR} ${OPENAL_INCLUDE_DIR}
${OPENGL_INCLUDE_DIR} ${OPENGL_INCLUDE_DIR}
@ -492,6 +491,7 @@ include_directories(
${SOL_CONFIG_DIR} ${SOL_CONFIG_DIR}
${ICU_INCLUDE_DIRS} ${ICU_INCLUDE_DIRS}
) )
include_directories(".")
link_directories(${COLLADA_DOM_LIBRARY_DIRS}) link_directories(${COLLADA_DOM_LIBRARY_DIRS})

View file

@ -104,7 +104,7 @@ namespace
surface.mHeights = values.data(); surface.mHeights = values.data();
surface.mMinHeight = -greater; surface.mMinHeight = -greater;
surface.mMaxHeight = greater; surface.mMaxHeight = greater;
surface.mSize = static_cast<int>(std::sqrt(size)); surface.mSize = static_cast<std::size_t>(std::sqrt(size));
return surface; return surface;
} }
@ -331,7 +331,7 @@ namespace
TEST_F(DetourNavigatorNavigatorTest, only_one_heightfield_per_cell_is_allowed) TEST_F(DetourNavigatorNavigatorTest, only_one_heightfield_per_cell_is_allowed)
{ {
const HeightfieldSurface surface1 = makeSquareHeightfieldSurface(defaultHeightfieldData); const HeightfieldSurface surface1 = makeSquareHeightfieldSurface(defaultHeightfieldData);
const int cellSize1 = heightfieldTileSize * (surface1.mSize - 1); const int cellSize1 = heightfieldTileSize * static_cast<int>(surface1.mSize - 1);
const std::array<float, 5 * 5> heightfieldData2{ { const std::array<float, 5 * 5> heightfieldData2{ {
-25, -25, -25, -25, -25, // row 0 -25, -25, -25, -25, -25, // row 0
@ -341,7 +341,7 @@ namespace
-25, -25, -25, -25, -25, // row 4 -25, -25, -25, -25, -25, // row 4
} }; } };
const HeightfieldSurface surface2 = makeSquareHeightfieldSurface(heightfieldData2); const HeightfieldSurface surface2 = makeSquareHeightfieldSurface(heightfieldData2);
const int cellSize2 = heightfieldTileSize * (surface2.mSize - 1); const int cellSize2 = heightfieldTileSize * static_cast<int>(surface2.mSize - 1);
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds)); ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
mNavigator->addHeightfield(mCellPosition, cellSize1, surface1, nullptr); mNavigator->addHeightfield(mCellPosition, cellSize1, surface1, nullptr);
@ -639,8 +639,9 @@ namespace
for (std::size_t i = 0; i < boxes.size(); ++i) for (std::size_t i = 0; i < boxes.size(); ++i)
{ {
const btScalar diameter = static_cast<btScalar>(i) * 10;
const btTransform transform( const btTransform transform(
btMatrix3x3::getIdentity(), btVector3(shift.x() + i * 10, shift.y() + i * 10, i * 10)); btMatrix3x3::getIdentity(), btVector3(shift.x() + diameter, shift.y() + diameter, diameter));
mNavigator->addObject( mNavigator->addObject(
ObjectId(&boxes[i].shape()), ObjectShapes(boxes[i].instance(), mObjectTransform), transform, nullptr); ObjectId(&boxes[i].shape()), ObjectShapes(boxes[i].instance(), mObjectTransform), transform, nullptr);
} }
@ -649,8 +650,9 @@ namespace
for (std::size_t i = 0; i < boxes.size(); ++i) for (std::size_t i = 0; i < boxes.size(); ++i)
{ {
const btScalar diameter = static_cast<btScalar>(i) * 10 + 1;
const btTransform transform( const btTransform transform(
btMatrix3x3::getIdentity(), btVector3(shift.x() + i * 10 + 1, shift.y() + i * 10 + 1, i * 10 + 1)); btMatrix3x3::getIdentity(), btVector3(shift.x() + diameter, shift.y() + diameter, diameter));
mNavigator->updateObject( mNavigator->updateObject(
ObjectId(&boxes[i].shape()), ObjectShapes(boxes[i].instance(), mObjectTransform), transform, nullptr); ObjectId(&boxes[i].shape()), ObjectShapes(boxes[i].instance(), mObjectTransform), transform, nullptr);
} }
@ -680,7 +682,8 @@ namespace
for (std::size_t i = 0; i < shapes.size(); ++i) for (std::size_t i = 0; i < shapes.size(); ++i)
{ {
const btTransform transform(btMatrix3x3::getIdentity(), btVector3(i * 32, i * 32, i * 32)); const btScalar diameter = static_cast<btScalar>(i) * 32;
const btTransform transform(btMatrix3x3::getIdentity(), btVector3(diameter, diameter, diameter));
mNavigator->addObject( mNavigator->addObject(
ObjectId(&shapes[i].shape()), ObjectShapes(shapes[i].instance(), mObjectTransform), transform, nullptr); ObjectId(&shapes[i].shape()), ObjectShapes(shapes[i].instance(), mObjectTransform), transform, nullptr);
} }
@ -690,7 +693,8 @@ namespace
const auto start = std::chrono::steady_clock::now(); const auto start = std::chrono::steady_clock::now();
for (std::size_t i = 0; i < shapes.size(); ++i) for (std::size_t i = 0; i < shapes.size(); ++i)
{ {
const btTransform transform(btMatrix3x3::getIdentity(), btVector3(i * 32 + 1, i * 32 + 1, i * 32 + 1)); const btScalar diameter = static_cast<btScalar>(i) * 32 + 1;
const btTransform transform(btMatrix3x3::getIdentity(), btVector3(diameter, diameter, diameter));
mNavigator->updateObject( mNavigator->updateObject(
ObjectId(&shapes[i].shape()), ObjectShapes(shapes[i].instance(), mObjectTransform), transform, nullptr); ObjectId(&shapes[i].shape()), ObjectShapes(shapes[i].instance(), mObjectTransform), transform, nullptr);
} }
@ -699,7 +703,8 @@ namespace
for (std::size_t i = 0; i < shapes.size(); ++i) for (std::size_t i = 0; i < shapes.size(); ++i)
{ {
const btTransform transform(btMatrix3x3::getIdentity(), btVector3(i * 32 + 2, i * 32 + 2, i * 32 + 2)); const btScalar diameter = static_cast<btScalar>(i) * 32 + 2;
const btTransform transform(btMatrix3x3::getIdentity(), btVector3(diameter, diameter, diameter));
mNavigator->updateObject( mNavigator->updateObject(
ObjectId(&shapes[i].shape()), ObjectShapes(shapes[i].instance(), mObjectTransform), transform, nullptr); ObjectId(&shapes[i].shape()), ObjectShapes(shapes[i].instance(), mObjectTransform), transform, nullptr);
} }

View file

@ -21,7 +21,7 @@ namespace
using namespace DetourNavigator::Tests; using namespace DetourNavigator::Tests;
template <class T, class Random> template <class T, class Random>
void generateRecastArray(T*& values, int size, Random& random) void generateRecastArray(T*& values, size_t size, Random& random)
{ {
values = static_cast<T*>(permRecastAlloc(size * sizeof(T))); values = static_cast<T*>(permRecastAlloc(size * sizeof(T)));
generateRange(values, values + static_cast<std::ptrdiff_t>(size), random); generateRange(values, values + static_cast<std::ptrdiff_t>(size), random);

View file

@ -1,6 +1,7 @@
#include "../nif/node.hpp" #include "../nif/node.hpp"
#include <components/bullethelpers/processtrianglecallback.hpp> #include <components/bullethelpers/processtrianglecallback.hpp>
#include <components/misc/convert.hpp>
#include <components/nif/data.hpp> #include <components/nif/data.hpp>
#include <components/nif/extra.hpp> #include <components/nif/extra.hpp>
#include <components/nif/node.hpp> #include <components/nif/node.hpp>
@ -300,10 +301,10 @@ namespace
void copy(const btTransform& src, Nif::NiTransform& dst) void copy(const btTransform& src, Nif::NiTransform& dst)
{ {
dst.mTranslation = osg::Vec3f(src.getOrigin().x(), src.getOrigin().y(), src.getOrigin().z()); dst.mTranslation = Misc::Convert::makeOsgVec3f(src.getOrigin());
for (int row = 0; row < 3; ++row) for (int row = 0; row < 3; ++row)
for (int column = 0; column < 3; ++column) for (int column = 0; column < 3; ++column)
dst.mRotation.mValues[row][column] = src.getBasis().getRow(row)[column]; dst.mRotation.mValues[row][column] = static_cast<float>(src.getBasis().getRow(row)[column]);
} }
struct TestBulletNifLoader : Test struct TestBulletNifLoader : Test

View file

@ -482,7 +482,7 @@ namespace
int digitCount = 1; // For a nicer output int digitCount = 1; // For a nicer output
if (recordCount > 0) if (recordCount > 0)
digitCount = (int)std::log10(recordCount) + 1; digitCount = static_cast<int>(std::log10(recordCount)) + 1;
std::cout << "Loaded " << recordCount << " records:\n\n"; std::cout << "Loaded " << recordCount << " records:\n\n";
@ -507,7 +507,7 @@ namespace
esm.setEncoder(&encoder); esm.setEncoder(&encoder);
esm.setHeader(data.mHeader); esm.setHeader(data.mHeader);
esm.setVersion(ESM::VER_130); esm.setVersion(ESM::VER_130);
esm.setRecordCount(recordCount); esm.setRecordCount(static_cast<int>(recordCount));
std::fstream save(info.outname, std::fstream::out | std::fstream::binary); std::fstream save(info.outname, std::fstream::out | std::fstream::binary);
esm.save(save); esm.save(save);

View file

@ -660,7 +660,8 @@ namespace EsmTool
std::cout << " Attributes:" << std::endl; std::cout << " Attributes:" << std::endl;
for (size_t i = 0; i < mData.mData.mAttributes.size(); ++i) for (size_t i = 0; i < mData.mData.mAttributes.size(); ++i)
std::cout << " " << ESM::Attribute::indexToRefId(i) << ": " << mData.mData.mAttributes[i] << std::endl; std::cout << " " << ESM::Attribute::indexToRefId(static_cast<int>(i)) << ": "
<< mData.mData.mAttributes[i] << std::endl;
std::cout << " Health: " << mData.mData.mHealth << std::endl; std::cout << " Health: " << mData.mData.mHealth << std::endl;
std::cout << " Magicka: " << mData.mData.mMana << std::endl; std::cout << " Magicka: " << mData.mData.mMana << std::endl;
@ -1049,11 +1050,13 @@ namespace EsmTool
std::cout << " Attributes:" << std::endl; std::cout << " Attributes:" << std::endl;
for (size_t i = 0; i != mData.mNpdt.mAttributes.size(); i++) for (size_t i = 0; i != mData.mNpdt.mAttributes.size(); i++)
std::cout << " " << attributeLabel(i) << ": " << int(mData.mNpdt.mAttributes[i]) << std::endl; std::cout << " " << attributeLabel(static_cast<int>(i)) << ": " << int(mData.mNpdt.mAttributes[i])
<< std::endl;
std::cout << " Skills:" << std::endl; std::cout << " Skills:" << std::endl;
for (size_t i = 0; i != mData.mNpdt.mSkills.size(); i++) for (size_t i = 0; i != mData.mNpdt.mSkills.size(); i++)
std::cout << " " << skillLabel(i) << ": " << int(mData.mNpdt.mSkills[i]) << std::endl; std::cout << " " << skillLabel(static_cast<int>(i)) << ": " << int(mData.mNpdt.mSkills[i])
<< std::endl;
std::cout << " Health: " << mData.mNpdt.mHealth << std::endl; std::cout << " Health: " << mData.mNpdt.mHealth << std::endl;
std::cout << " Magicka: " << mData.mNpdt.mMana << std::endl; std::cout << " Magicka: " << mData.mNpdt.mMana << std::endl;

View file

@ -48,8 +48,8 @@ namespace ESSImport
for (int i = 0; i < ESM::Skill::Length; ++i) for (int i = 0; i < ESM::Skill::Length; ++i)
{ {
npcStats.mSkills[i].mMod = 0.f; npcStats.mSkills[i].mMod = 0.f;
npcStats.mSkills[i].mCurrent = actorData.mSkills[i][1]; npcStats.mSkills[i].mCurrent = static_cast<float>(actorData.mSkills[i][1]);
npcStats.mSkills[i].mBase = actorData.mSkills[i][0]; npcStats.mSkills[i].mBase = static_cast<float>(actorData.mSkills[i][0]);
} }
npcStats.mTimeToStartDrowning = actorData.mACDT.mBreathMeter; npcStats.mTimeToStartDrowning = actorData.mACDT.mBreathMeter;

View file

@ -18,7 +18,7 @@
namespace namespace
{ {
void convertImage(char* data, int size, int width, int height, GLenum pf, const std::string& out) void convertImage(char* data, size_t size, int width, int height, GLenum pf, const std::string& out)
{ {
osg::ref_ptr<osg::Image> image(new osg::Image); osg::ref_ptr<osg::Image> image(new osg::Image);
image->allocateImage(width, height, 1, pf, GL_UNSIGNED_BYTE); image->allocateImage(width, height, 1, pf, GL_UNSIGNED_BYTE);

View file

@ -145,7 +145,7 @@ namespace Launcher
int getMaxNavMeshDbFileSizeMiB() int getMaxNavMeshDbFileSizeMiB()
{ {
return Settings::navigator().mMaxNavmeshdbFileSize / (1024 * 1024); return static_cast<int>(Settings::navigator().mMaxNavmeshdbFileSize / (1024 * 1024));
} }
} }
} }

View file

@ -406,7 +406,7 @@ void CSMDoc::WriteCellCollectionStage::perform(int stage, Messages& messages)
if (references != nullptr) if (references != nullptr)
{ {
writeReferences(persistentRefs, interior); writeReferences(persistentRefs, interior);
cellRecord.saveTempMarker(writer, static_cast<int>(references->size()) - persistentRefs.size()); cellRecord.saveTempMarker(writer, static_cast<int>(references->size() - persistentRefs.size()));
writeReferences(tempRefs, interior); writeReferences(tempRefs, interior);
} }

View file

@ -462,7 +462,7 @@ void CSMTools::ReferenceableCheckStage::creatureCheck(
for (size_t i = 0; i < creature.mData.mAttributes.size(); ++i) for (size_t i = 0; i < creature.mData.mAttributes.size(); ++i)
{ {
if (creature.mData.mAttributes[i] < 0) if (creature.mData.mAttributes[i] < 0)
messages.add(id, ESM::Attribute::indexToRefId(i).toDebugString() + " is negative", {}, messages.add(id, ESM::Attribute::indexToRefId(static_cast<int>(i)).toDebugString() + " is negative", {},
CSMDoc::Message::Severity_Warning); CSMDoc::Message::Severity_Warning);
} }

View file

@ -640,7 +640,7 @@ namespace CSMWorld
reservedList.emplace_back(pr); reservedList.emplace_back(pr);
} }
int priority = parts.size(); int priority = static_cast<int>(parts.size());
addParts(clothing.mParts.mParts, priority); addParts(clothing.mParts.mParts, priority);
addParts(reservedList, priority); addParts(reservedList, priority);

View file

@ -34,7 +34,7 @@ bool CSMWorld::CellSelection::has(const CellCoordinates& coordinates) const
int CSMWorld::CellSelection::getSize() const int CSMWorld::CellSelection::getSize() const
{ {
return mCells.size(); return static_cast<int>(mCells.size());
} }
CSMWorld::CellCoordinates CSMWorld::CellSelection::getCentre() const CSMWorld::CellCoordinates CSMWorld::CellSelection::getCentre() const

View file

@ -367,7 +367,7 @@ namespace CSMWorld
template <typename ESXRecordT> template <typename ESXRecordT>
int Collection<ESXRecordT>::getSize() const int Collection<ESXRecordT>::getSize() const
{ {
return mRecords.size(); return static_cast<int>(mRecords.size());
} }
template <typename ESXRecordT> template <typename ESXRecordT>
@ -391,7 +391,7 @@ namespace CSMWorld
template <typename ESXRecordT> template <typename ESXRecordT>
int Collection<ESXRecordT>::getColumns() const int Collection<ESXRecordT>::getColumns() const
{ {
return mColumns.size(); return static_cast<int>(mColumns.size());
} }
template <typename ESXRecordT> template <typename ESXRecordT>

View file

@ -41,7 +41,7 @@ namespace CSMWorld
point.mConnectionNum = 0; point.mConnectionNum = 0;
points.insert(points.begin() + position, point); points.insert(points.begin() + position, point);
pathgrid.mData.mPoints = pathgrid.mPoints.size(); pathgrid.mData.mPoints = static_cast<uint16_t>(pathgrid.mPoints.size());
record.setModified(pathgrid); record.setModified(pathgrid);
} }
@ -58,7 +58,7 @@ namespace CSMWorld
// Do not remove dangling edges, does not work with current undo mechanism // Do not remove dangling edges, does not work with current undo mechanism
// Do not automatically adjust indices, what would be done with dangling edges? // Do not automatically adjust indices, what would be done with dangling edges?
points.erase(points.begin() + rowToRemove); points.erase(points.begin() + rowToRemove);
pathgrid.mData.mPoints = pathgrid.mPoints.size(); pathgrid.mData.mPoints = static_cast<uint16_t>(pathgrid.mPoints.size());
record.setModified(pathgrid); record.setModified(pathgrid);
} }
@ -67,7 +67,7 @@ namespace CSMWorld
{ {
Pathgrid pathgrid = record.get(); Pathgrid pathgrid = record.get();
pathgrid.mPoints = static_cast<const NestedTableWrapper<ESM::Pathgrid::PointList>&>(nestedTable).mNestedTable; pathgrid.mPoints = static_cast<const NestedTableWrapper<ESM::Pathgrid::PointList>&>(nestedTable).mNestedTable;
pathgrid.mData.mPoints = pathgrid.mPoints.size(); pathgrid.mData.mPoints = static_cast<uint16_t>(pathgrid.mPoints.size());
record.setModified(pathgrid); record.setModified(pathgrid);
} }
@ -462,7 +462,7 @@ namespace CSMWorld
soundRef.mSound = ESM::RefId::stringRefId(value.toString().toUtf8().constData()); soundRef.mSound = ESM::RefId::stringRefId(value.toString().toUtf8().constData());
break; break;
case 1: case 1:
soundRef.mChance = static_cast<unsigned char>(value.toInt()); soundRef.mChance = static_cast<uint8_t>(value.toInt());
break; break;
default: default:
throw std::runtime_error("Region sounds subcolumn index out of range"); throw std::runtime_error("Region sounds subcolumn index out of range");
@ -543,7 +543,7 @@ namespace CSMWorld
// default row // default row
ESM::DialogueCondition condStruct; ESM::DialogueCondition condStruct;
condStruct.mIndex = conditions.size(); condStruct.mIndex = static_cast<uint8_t>(conditions.size());
conditions.insert(conditions.begin() + position, condStruct); conditions.insert(conditions.begin() + position, condStruct);
@ -855,7 +855,7 @@ namespace CSMWorld
int RaceSkillsBonusAdapter::getRowsCount(const Record<ESM::Race>& record) const int RaceSkillsBonusAdapter::getRowsCount(const Record<ESM::Race>& record) const
{ {
return record.get().mData.mBonus.size(); return static_cast<int>(record.get().mData.mBonus.size());
} }
void CellListAdapter::addRow(Record<CSMWorld::Cell>& record, int position) const void CellListAdapter::addRow(Record<CSMWorld::Cell>& record, int position) const

View file

@ -7,9 +7,7 @@ namespace CSMWorld
{ {
virtual ~NestedTableWrapperBase() = default; virtual ~NestedTableWrapperBase() = default;
virtual int size() const { return -5; } virtual size_t size() const = 0;
NestedTableWrapperBase() = default;
}; };
template <typename NestedTable> template <typename NestedTable>
@ -24,7 +22,7 @@ namespace CSMWorld
~NestedTableWrapper() override = default; ~NestedTableWrapper() override = default;
int size() const override size_t size() const override
{ {
return mNestedTable.size(); // i hope that this will be enough return mNestedTable.size(); // i hope that this will be enough
} }

View file

@ -665,7 +665,7 @@ int CSMWorld::RefIdCollection::getIndex(const ESM::RefId& id) const
int CSMWorld::RefIdCollection::getColumns() const int CSMWorld::RefIdCollection::getColumns() const
{ {
return mColumns.size(); return static_cast<int>(mColumns.size());
} }
const CSMWorld::ColumnBase& CSMWorld::RefIdCollection::getColumn(int column) const const CSMWorld::ColumnBase& CSMWorld::RefIdCollection::getColumn(int column) const

View file

@ -275,7 +275,7 @@ void CSMWorld::RefIdData::erase(const LocalIndex& index, int count)
int CSMWorld::RefIdData::getSize() const int CSMWorld::RefIdData::getSize() const
{ {
return mIndex.size(); return static_cast<int>(mIndex.size());
} }
std::vector<ESM::RefId> CSMWorld::RefIdData::getIds(bool listDeleted) const std::vector<ESM::RefId> CSMWorld::RefIdData::getIds(bool listDeleted) const

View file

@ -115,7 +115,7 @@ void CSVFilter::EditWidget::createFilterRequest(const std::vector<FilterData>& s
newFilter.emplace_back(newFilterData); newFilter.emplace_back(newFilterData);
} }
const unsigned count = newFilter.size(); const size_t count = newFilter.size();
bool multipleElements = false; bool multipleElements = false;
switch (count) // setting multipleElements; switch (count) // setting multipleElements;
@ -181,7 +181,7 @@ void CSVFilter::EditWidget::createFilterRequest(const std::vector<FilterData>& s
ss << orAnd << oldContent.toUtf8().constData() << ','; ss << orAnd << oldContent.toUtf8().constData() << ',';
} }
for (unsigned i = 0; i < count; ++i) for (size_t i = 0; i < count; ++i)
{ {
ss << generateFilter(newFilter[i], filterType); ss << generateFilter(newFilter[i], filterType);
@ -221,13 +221,13 @@ void CSVFilter::EditWidget::createFilterRequest(const std::vector<FilterData>& s
std::string CSVFilter::EditWidget::generateFilter(const FilterData& filterData, FilterType filterType) const std::string CSVFilter::EditWidget::generateFilter(const FilterData& filterData, FilterType filterType) const
{ {
const unsigned columns = filterData.columns.size(); const size_t columns = filterData.columns.size();
bool multipleColumns = false; bool multipleColumns = false;
switch (columns) switch (columns)
{ {
case 0: // empty case 0: // empty
return ""; // no column to filter return {}; // no column to filter
case 1: // one column to look for case 1: // one column to look for
multipleColumns = false; multipleColumns = false;
@ -244,7 +244,7 @@ std::string CSVFilter::EditWidget::generateFilter(const FilterData& filterData,
else else
{ {
Log(Debug::Warning) << "Generating record filter failed."; Log(Debug::Warning) << "Generating record filter failed.";
return ""; return {};
} }
if (filterType == FilterType::String) if (filterType == FilterType::String)
quotesResolved = '"' + quotesResolved + '"'; quotesResolved = '"' + quotesResolved + '"';
@ -254,7 +254,7 @@ std::string CSVFilter::EditWidget::generateFilter(const FilterData& filterData,
if (multipleColumns) if (multipleColumns)
{ {
ss << "or("; ss << "or(";
for (unsigned i = 0; i < columns; ++i) for (size_t i = 0; i < columns; ++i)
{ {
ss << filterTypeName(filterType) << "(" << '"' << filterData.columns[i] << '"' << ',' << quotesResolved ss << filterTypeName(filterType) << "(" << '"' << filterData.columns[i] << '"' << ',' << quotesResolved
<< ')'; << ')';

View file

@ -190,7 +190,7 @@ void CSVRender::BrushDraw::buildCircleGeometry(const float& radius, const osg::V
osg::ref_ptr<osg::Vec4Array> colors(new osg::Vec4Array()); osg::ref_ptr<osg::Vec4Array> colors(new osg::Vec4Array());
const int amountOfPoints = 128; const int amountOfPoints = 128;
const float step((osg::PI * 2.0f) / static_cast<float>(amountOfPoints)); const float step((osg::PIf * 2.0f) / static_cast<float>(amountOfPoints));
const float brushOutlineHeight(1.0f); const float brushOutlineHeight(1.0f);
osg::Vec4f lineColor(1.0f, 1.0f, 1.0f, 0.6f); osg::Vec4f lineColor(1.0f, 1.0f, 1.0f, 0.6f);

View file

@ -17,13 +17,16 @@
#include "../../model/world/cellcoordinates.hpp" #include "../../model/world/cellcoordinates.hpp"
const int CSVRender::CellBorder::CellSize = ESM::Land::REAL_SIZE; namespace
{
constexpr int CellSize = ESM::Land::REAL_SIZE;
/* /*
The number of vertices per cell border is equal to the number of vertices per edge The number of vertices per cell border is equal to the number of vertices per edge
minus the duplicated corner vertices. An additional vertex to close the loop is NOT needed. minus the duplicated corner vertices. An additional vertex to close the loop is NOT needed.
*/ */
const int CSVRender::CellBorder::VertexCount = (ESM::Land::LAND_SIZE * 4) - 4; constexpr unsigned VertexCount = (ESM::Land::LAND_SIZE * 4) - 4;
}
CSVRender::CellBorder::CellBorder(osg::Group* cellNode, const CSMWorld::CellCoordinates& coords) CSVRender::CellBorder::CellBorder(osg::Group* cellNode, const CSMWorld::CellCoordinates& coords)
: mParentNode(cellNode) : mParentNode(cellNode)
@ -105,7 +108,7 @@ void CSVRender::CellBorder::buildShape(const ESM::Land& esmLand)
= new osg::DrawElementsUShort(osg::PrimitiveSet::LINE_STRIP, VertexCount + 1); = new osg::DrawElementsUShort(osg::PrimitiveSet::LINE_STRIP, VertexCount + 1);
// Assign one primitive to each vertex. // Assign one primitive to each vertex.
for (size_t i = 0; i < VertexCount; ++i) for (unsigned i = 0; i < VertexCount; ++i)
primitives->setElement(i, i); primitives->setElement(i, i);
// Assign the last primitive to the first vertex to close the loop. // Assign the last primitive to the first vertex to close the loop.

View file

@ -34,9 +34,6 @@ namespace CSVRender
void buildShape(const ESM::Land& esmLand); void buildShape(const ESM::Land& esmLand);
private: private:
static const int CellSize;
static const int VertexCount;
size_t landIndex(int x, int y); size_t landIndex(int x, int y);
float scaleToWorld(int val); float scaleToWorld(int val);

View file

@ -27,16 +27,16 @@ public:
void apply(osg::Switch& switchNode) override void apply(osg::Switch& switchNode) override
{ {
constexpr int noIndex = -1; constexpr unsigned noIndex = static_cast<unsigned>(-1);
int initialIndex = noIndex; unsigned initialIndex = noIndex;
if (!switchNode.getUserValue("initialIndex", initialIndex)) if (!switchNode.getUserValue("initialIndex", initialIndex))
{ {
for (size_t i = 0; i < switchNode.getValueList().size(); ++i) for (size_t i = 0; i < switchNode.getValueList().size(); ++i)
{ {
if (switchNode.getValueList()[i]) if (switchNode.getValueList()[i])
{ {
initialIndex = i; initialIndex = static_cast<unsigned>(i);
break; break;
} }
} }

View file

@ -203,11 +203,11 @@ namespace CSVRender
void ObjectMarker::detachMarker() void ObjectMarker::detachMarker()
{ {
for (std::size_t index = mRootNode->getNumParents(); index > 0;) for (unsigned index = mRootNode->getNumParents(); index > 0;)
mRootNode->getParent(--index)->removeChild(mRootNode); mRootNode->getParent(--index)->removeChild(mRootNode);
osg::ref_ptr<osg::Group> widgetRoot = mMarkerNodes["unitArrows"]->asGroup(); osg::ref_ptr<osg::Group> widgetRoot = mMarkerNodes["unitArrows"]->asGroup();
for (std::size_t index = widgetRoot->getNumChildren(); index > 0;) for (unsigned index = widgetRoot->getNumChildren(); index > 0;)
widgetRoot->getChild(--index)->setNodeMask(Mask_Hidden); widgetRoot->getChild(--index)->setNodeMask(Mask_Hidden);
} }

View file

@ -306,15 +306,17 @@ namespace CSVRender
commands.push(new CSMWorld::RevertCommand(*model, idString)); commands.push(new CSMWorld::RevertCommand(*model, idString));
int parentColumn = mPathgridCollection.findColumnIndex(CSMWorld::Columns::ColumnId_PathgridPoints); int parentColumn = mPathgridCollection.findColumnIndex(CSMWorld::Columns::ColumnId_PathgridPoints);
for (int row = source->mPoints.size() - 1; row >= 0; --row) for (size_t row = source->mPoints.size(); row > 0; --row)
{ {
commands.push(new CSMWorld::DeleteNestedCommand(*model, idString, row, parentColumn)); commands.push(
new CSMWorld::DeleteNestedCommand(*model, idString, static_cast<int>(row - 1), parentColumn));
} }
parentColumn = mPathgridCollection.findColumnIndex(CSMWorld::Columns::ColumnId_PathgridEdges); parentColumn = mPathgridCollection.findColumnIndex(CSMWorld::Columns::ColumnId_PathgridEdges);
for (int row = source->mEdges.size() - 1; row >= 0; --row) for (size_t row = source->mEdges.size(); row > 0; --row)
{ {
commands.push(new CSMWorld::DeleteNestedCommand(*model, idString, row, parentColumn)); commands.push(
new CSMWorld::DeleteNestedCommand(*model, idString, static_cast<int>(row - 1), parentColumn));
} }
} }
} }
@ -420,8 +422,8 @@ namespace CSVRender
for (size_t edge = 0; edge < source->mEdges.size(); ++edge) for (size_t edge = 0; edge < source->mEdges.size(); ++edge)
{ {
int adjustment0 = 0; size_t adjustment0 = 0;
int adjustment1 = 0; size_t adjustment1 = 0;
// Determine necessary adjustment // Determine necessary adjustment
for (const auto point : mSelected) for (const auto point : mSelected)
@ -436,24 +438,24 @@ namespace CSVRender
} }
if (source->mEdges[edge].mV0 > point) if (source->mEdges[edge].mV0 > point)
--adjustment0; ++adjustment0;
if (source->mEdges[edge].mV1 > point) if (source->mEdges[edge].mV1 > point)
--adjustment1; ++adjustment1;
} }
if (adjustment0 != 0) if (adjustment0 != 0)
{ {
int adjustedEdge = source->mEdges[edge].mV0 + adjustment0; int adjustedEdge = static_cast<int>(source->mEdges[edge].mV0 - adjustment0);
commands.push( commands.push(new CSMWorld::ModifyCommand(
new CSMWorld::ModifyCommand(*model, model->index(edge, edge0Column, parent), adjustedEdge)); *model, model->index(static_cast<int>(edge), edge0Column, parent), adjustedEdge));
} }
if (adjustment1 != 0) if (adjustment1 != 0)
{ {
int adjustedEdge = source->mEdges[edge].mV1 + adjustment1; int adjustedEdge = static_cast<int>(source->mEdges[edge].mV1 - adjustment1);
commands.push( commands.push(new CSMWorld::ModifyCommand(
new CSMWorld::ModifyCommand(*model, model->index(edge, edge1Column, parent), adjustedEdge)); *model, model->index(static_cast<int>(edge), edge1Column, parent), adjustedEdge));
} }
} }

View file

@ -14,8 +14,8 @@
#include <apps/opencs/view/render/lightingday.hpp> #include <apps/opencs/view/render/lightingday.hpp>
#include <apps/opencs/view/render/lightingnight.hpp> #include <apps/opencs/view/render/lightingnight.hpp>
#include <extern/osgQt/CompositeOsgRenderer.hpp> #include <osgQt/CompositeOsgRenderer.hpp>
#include <extern/osgQt/osgQOpenGLWidget.hpp> #include <osgQt/osgQOpenGLWidget.hpp>
#include <osg/Array> #include <osg/Array>
#include <osg/Camera> #include <osg/Camera>

View file

@ -112,8 +112,8 @@ void CSVRender::TerrainSelection::update()
mGeometry->setVertexArray(vertices); mGeometry->setVertexArray(vertices);
osg::ref_ptr<osg::DrawArrays> drawArrays = new osg::DrawArrays(osg::PrimitiveSet::LINES); osg::ref_ptr<osg::DrawArrays> drawArrays = new osg::DrawArrays(osg::PrimitiveSet::LINES);
drawArrays->setCount(vertices->size()); drawArrays->setCount(static_cast<GLsizei>(vertices->size()));
if (vertices->size() != 0) if (!vertices->empty())
mGeometry->addPrimitiveSet(drawArrays); mGeometry->addPrimitiveSet(drawArrays);
mSelectionNode->addChild(mGeometry); mSelectionNode->addChild(mGeometry);
} }

View file

@ -308,24 +308,27 @@ void CSVWidget::SceneToolTextureBrush::showPanel(const QPoint& position)
void CSVWidget::SceneToolTextureBrush::updatePanel() void CSVWidget::SceneToolTextureBrush::updatePanel()
{ {
mTable->setRowCount(mBrushHistory.size()); mTable->setRowCount(static_cast<int>(mBrushHistory.size()));
for (int i = mBrushHistory.size() - 1; i >= 0; --i) for (size_t i = mBrushHistory.size(); i > 0; --i)
{ {
CSMWorld::IdCollection<ESM::LandTexture>& landtexturesCollection = mDocument.getData().getLandTextures(); CSMWorld::IdCollection<ESM::LandTexture>& landtexturesCollection = mDocument.getData().getLandTextures();
int landTextureFilename = landtexturesCollection.findColumnIndex(CSMWorld::Columns::ColumnId_Texture); int landTextureFilename = landtexturesCollection.findColumnIndex(CSMWorld::Columns::ColumnId_Texture);
const int index = landtexturesCollection.searchId(mBrushHistory[i]); const int index = landtexturesCollection.searchId(mBrushHistory[i - 1]);
const int row = static_cast<int>(i - 1);
if (index != -1 && !landtexturesCollection.getRecord(index).isDeleted()) if (index != -1 && !landtexturesCollection.getRecord(index).isDeleted())
{ {
mTable->setItem(i, 1, mTable->setItem(row, 1,
new QTableWidgetItem(landtexturesCollection.getData(index, landTextureFilename).value<QString>())); new QTableWidgetItem(landtexturesCollection.getData(index, landTextureFilename).value<QString>()));
mTable->setItem(i, 0, new QTableWidgetItem(QString::fromStdString(mBrushHistory[i].getRefIdString()))); mTable->setItem(
row, 0, new QTableWidgetItem(QString::fromStdString(mBrushHistory[i - 1].getRefIdString())));
} }
else else
{ {
mTable->setItem(i, 1, new QTableWidgetItem("Invalid/deleted texture")); mTable->setItem(row, 1, new QTableWidgetItem("Invalid/deleted texture"));
mTable->setItem(i, 0, new QTableWidgetItem(QString::fromStdString(mBrushHistory[i].getRefIdString()))); mTable->setItem(
row, 0, new QTableWidgetItem(QString::fromStdString(mBrushHistory[i - 1].getRefIdString())));
} }
} }
} }

View file

@ -28,7 +28,7 @@ void CSVWorld::ScriptErrorTable::report(const std::string& message, const Compil
addMessage(stream.str(), addMessage(stream.str(),
type == Compiler::ErrorHandler::WarningMessage ? CSMDoc::Message::Severity_Warning type == Compiler::ErrorHandler::WarningMessage ? CSMDoc::Message::Severity_Warning
: CSMDoc::Message::Severity_Error, : CSMDoc::Message::Severity_Error,
loc.mLine, loc.mColumn - loc.mLiteral.length()); loc.mLine, loc.mColumn - static_cast<int>(loc.mLiteral.length()));
} }
void CSVWorld::ScriptErrorTable::report(const std::string& message, Type type) void CSVWorld::ScriptErrorTable::report(const std::string& message, Type type)

View file

@ -170,8 +170,8 @@ target_link_libraries(openmw-lib
${MyGUI_LIBRARIES} ${MyGUI_LIBRARIES}
SDL2::SDL2 SDL2::SDL2
${RecastNavigation_LIBRARIES} ${RecastNavigation_LIBRARIES}
"osg-ffmpeg-videoplayer" osg-ffmpeg-videoplayer
"oics" oics
components components
) )

View file

@ -319,7 +319,7 @@ bool OMW::Engine::frame(unsigned frameNumber, float frametime)
const bool reportResource = stats->collectStats("resource"); const bool reportResource = stats->collectStats("resource");
if (reportResource) if (reportResource)
stats->setAttribute(frameNumber, "UnrefQueue", mUnrefQueue->getSize()); stats->setAttribute(frameNumber, "UnrefQueue", static_cast<double>(mUnrefQueue->getSize()));
mUnrefQueue->flush(*mWorkQueue); mUnrefQueue->flush(*mWorkQueue);
@ -329,8 +329,8 @@ bool OMW::Engine::frame(unsigned frameNumber, float frametime)
mResourceSystem->reportStats(frameNumber, stats); mResourceSystem->reportStats(frameNumber, stats);
stats->setAttribute(frameNumber, "WorkQueue", mWorkQueue->getNumItems()); stats->setAttribute(frameNumber, "WorkQueue", static_cast<double>(mWorkQueue->getNumItems()));
stats->setAttribute(frameNumber, "WorkThread", mWorkQueue->getNumActiveThreads()); stats->setAttribute(frameNumber, "WorkThread", static_cast<double>(mWorkQueue->getNumActiveThreads()));
mMechanicsManager->reportStats(frameNumber, *stats); mMechanicsManager->reportStats(frameNumber, *stats);
mWorld->reportStats(frameNumber, *stats); mWorld->reportStats(frameNumber, *stats);
@ -740,7 +740,8 @@ void OMW::Engine::prepareEngine()
mResourceSystem->getSceneManager()->setUnRefImageDataAfterApply( mResourceSystem->getSceneManager()->setUnRefImageDataAfterApply(
false); // keep to Off for now to allow better state sharing false); // keep to Off for now to allow better state sharing
mResourceSystem->getSceneManager()->setFilterSettings(Settings::general().mTextureMagFilter, mResourceSystem->getSceneManager()->setFilterSettings(Settings::general().mTextureMagFilter,
Settings::general().mTextureMinFilter, Settings::general().mTextureMipmap, Settings::general().mAnisotropy); Settings::general().mTextureMinFilter, Settings::general().mTextureMipmap,
static_cast<float>(Settings::general().mAnisotropy));
mEnvironment.setResourceSystem(*mResourceSystem); mEnvironment.setResourceSystem(*mResourceSystem);
mWorkQueue = new SceneUtil::WorkQueue(Settings::cells().mPreloadNumThreads); mWorkQueue = new SceneUtil::WorkQueue(Settings::cells().mPreloadNumThreads);
@ -1039,7 +1040,7 @@ void OMW::Engine::go()
const unsigned frameNumber = mViewer->getFrameStamp()->getFrameNumber(); const unsigned frameNumber = mViewer->getFrameStamp()->getFrameNumber();
if (!frame(frameNumber, dt)) if (!frame(frameNumber, static_cast<float>(dt)))
{ {
std::this_thread::sleep_for(std::chrono::milliseconds(5)); std::this_thread::sleep_for(std::chrono::milliseconds(5));
continue; continue;

View file

@ -100,7 +100,7 @@ namespace MWBase
/// @note Controlled by an option, gets discarded when dialogue ends by default /// @note Controlled by an option, gets discarded when dialogue ends by default
virtual void applyBarterDispositionChange(int delta) = 0; virtual void applyBarterDispositionChange(int delta) = 0;
virtual int countSavedGameRecords() const = 0; virtual size_t countSavedGameRecords() const = 0;
virtual void write(ESM::ESMWriter& writer, Loading::Listener& progress) const = 0; virtual void write(ESM::ESMWriter& writer, Loading::Listener& progress) const = 0;

View file

@ -86,7 +86,7 @@ namespace MWBase
virtual std::string getControllerButtonIcon(int button) = 0; virtual std::string getControllerButtonIcon(int button) = 0;
virtual std::string getControllerAxisIcon(int axis) = 0; virtual std::string getControllerAxisIcon(int axis) = 0;
virtual int countSavedGameRecords() const = 0; virtual size_t countSavedGameRecords() const = 0;
virtual void write(ESM::ESMWriter& writer, Loading::Listener& progress) = 0; virtual void write(ESM::ESMWriter& writer, Loading::Listener& progress) = 0;
virtual void readRecord(ESM::ESMReader& reader, uint32_t type) = 0; virtual void readRecord(ESM::ESMReader& reader, uint32_t type) = 0;

View file

@ -74,7 +74,7 @@ namespace MWBase
virtual const TQuestContainer& getQuests() const = 0; virtual const TQuestContainer& getQuests() const = 0;
virtual int countSavedGameRecords() const = 0; virtual size_t countSavedGameRecords() const = 0;
virtual void write(ESM::ESMWriter& writer, Loading::Listener& progress) const = 0; virtual void write(ESM::ESMWriter& writer, Loading::Listener& progress) const = 0;

View file

@ -141,7 +141,7 @@ namespace MWBase
virtual void setupPlayer(const MWWorld::Ptr&) = 0; virtual void setupPlayer(const MWWorld::Ptr&) = 0;
// Saving // Saving
int countSavedGameRecords() const { return 1; } size_t countSavedGameRecords() const { return 1; }
virtual void write(ESM::ESMWriter& writer, Loading::Listener& progress) = 0; virtual void write(ESM::ESMWriter& writer, Loading::Listener& progress) = 0;
virtual void saveLocalScripts(const MWWorld::Ptr& ptr, ESM::LuaScripts& data) = 0; virtual void saveLocalScripts(const MWWorld::Ptr& ptr, ESM::LuaScripts& data) = 0;

View file

@ -245,7 +245,7 @@ namespace MWBase
virtual void playerLoaded() = 0; virtual void playerLoaded() = 0;
virtual int countSavedGameRecords() const = 0; virtual size_t countSavedGameRecords() const = 0;
virtual void write(ESM::ESMWriter& writer, Loading::Listener& listener) const = 0; virtual void write(ESM::ESMWriter& writer, Loading::Listener& listener) const = 0;

View file

@ -311,7 +311,7 @@ namespace MWBase
virtual void write(ESM::ESMWriter& writer, Loading::Listener& progress) = 0; virtual void write(ESM::ESMWriter& writer, Loading::Listener& progress) = 0;
virtual void readRecord(ESM::ESMReader& reader, uint32_t type) = 0; virtual void readRecord(ESM::ESMReader& reader, uint32_t type) = 0;
virtual int countSavedGameRecords() const = 0; virtual size_t countSavedGameRecords() const = 0;
/// Does the current stack of GUI-windows permit saving? /// Does the current stack of GUI-windows permit saving?
virtual bool isSavingAllowed() const = 0; virtual bool isSavingAllowed() const = 0;
@ -391,7 +391,7 @@ namespace MWBase
virtual int getControllerMenuHeight() = 0; virtual int getControllerMenuHeight() = 0;
/// Cycle to the next window to receive controller events /// Cycle to the next window to receive controller events
virtual void cycleActiveControllerWindow(bool next) = 0; virtual void cycleActiveControllerWindow(bool next) = 0;
virtual void setActiveControllerWindow(MWGui::GuiMode mode, int activeIndex) = 0; virtual void setActiveControllerWindow(MWGui::GuiMode mode, size_t activeIndex) = 0;
virtual bool getControllerTooltipVisible() const = 0; virtual bool getControllerTooltipVisible() const = 0;
virtual void setControllerTooltipVisible(bool visible) = 0; virtual void setControllerTooltipVisible(bool visible) = 0;
virtual bool getControllerTooltipEnabled() const = 0; virtual bool getControllerTooltipEnabled() const = 0;

View file

@ -120,7 +120,7 @@ namespace MWBase
World() {} World() {}
virtual ~World() {} virtual ~World() = default;
virtual void setRandomSeed(uint32_t seed) = 0; virtual void setRandomSeed(uint32_t seed) = 0;
///< \param seed The seed used when starting a new game. ///< \param seed The seed used when starting a new game.
@ -130,8 +130,8 @@ namespace MWBase
virtual void clear() = 0; virtual void clear() = 0;
virtual int countSavedGameRecords() const = 0; virtual size_t countSavedGameRecords() const = 0;
virtual int countSavedGameCells() const = 0; virtual size_t countSavedGameCells() const = 0;
virtual void write(ESM::ESMWriter& writer, Loading::Listener& listener) const = 0; virtual void write(ESM::ESMWriter& writer, Loading::Listener& listener) const = 0;

View file

@ -339,7 +339,7 @@ namespace MWClass
->mValue.getInteger(); ->mValue.getInteger();
if (ref->mBase->mData.mWeight == 0) if (ref->mBase->mData.mWeight == 0)
return ref->mBase->mData.mArmor; return static_cast<float>(ref->mBase->mData.mArmor);
else else
return ref->mBase->mData.mArmor * armorSkill / static_cast<float>(iBaseArmorSkill); return ref->mBase->mData.mArmor * armorSkill / static_cast<float>(iBaseArmorSkill);
} }

View file

@ -190,7 +190,7 @@ namespace MWClass
ESM::Clothing newItem = *ref->mBase; ESM::Clothing newItem = *ref->mBase;
newItem.mId = ESM::RefId(); newItem.mId = ESM::RefId();
newItem.mName = newName; newItem.mName = newName;
newItem.mData.mEnchant = enchCharge; newItem.mData.mEnchant = static_cast<uint16_t>(enchCharge);
newItem.mEnchant = enchId; newItem.mEnchant = enchId;
const ESM::Clothing* record = MWBase::Environment::get().getESMStore()->insert(newItem); const ESM::Clothing* record = MWBase::Environment::get().getESMStore()->insert(newItem);
return record->mId; return record->mId;

View file

@ -132,7 +132,8 @@ namespace MWClass
// creature stats // creature stats
for (size_t i = 0; i < ref->mBase->mData.mAttributes.size(); ++i) for (size_t i = 0; i < ref->mBase->mData.mAttributes.size(); ++i)
data->mCreatureStats.setAttribute(ESM::Attribute::indexToRefId(i), ref->mBase->mData.mAttributes[i]); data->mCreatureStats.setAttribute(ESM::Attribute::indexToRefId(static_cast<int>(i)),
static_cast<float>(ref->mBase->mData.mAttributes[i]));
data->mCreatureStats.setHealth(static_cast<float>(ref->mBase->mData.mHealth)); data->mCreatureStats.setHealth(static_cast<float>(ref->mBase->mData.mHealth));
data->mCreatureStats.setMagicka(static_cast<float>(ref->mBase->mData.mMana)); data->mCreatureStats.setMagicka(static_cast<float>(ref->mBase->mData.mMana));
data->mCreatureStats.setFatigue(static_cast<float>(ref->mBase->mData.mFatigue)); data->mCreatureStats.setFatigue(static_cast<float>(ref->mBase->mData.mFatigue));
@ -757,11 +758,11 @@ namespace MWClass
switch (skillRecord->mData.mSpecialization) switch (skillRecord->mData.mSpecialization)
{ {
case ESM::Class::Combat: case ESM::Class::Combat:
return ref->mBase->mData.mCombat; return static_cast<float>(ref->mBase->mData.mCombat);
case ESM::Class::Magic: case ESM::Class::Magic:
return ref->mBase->mData.mMagic; return static_cast<float>(ref->mBase->mData.mMagic);
case ESM::Class::Stealth: case ESM::Class::Stealth:
return ref->mBase->mData.mStealth; return static_cast<float>(ref->mBase->mData.mStealth);
default: default:
throw std::runtime_error("invalid specialisation"); throw std::runtime_error("invalid specialisation");
} }
@ -887,7 +888,7 @@ namespace MWClass
void Creature::setBaseAISetting(const ESM::RefId& id, MWMechanics::AiSetting setting, int value) const void Creature::setBaseAISetting(const ESM::RefId& id, MWMechanics::AiSetting setting, int value) const
{ {
MWMechanics::setBaseAISetting<ESM::Creature>(id, setting, value); MWMechanics::setBaseAISetting<ESM::Creature>(id, setting, static_cast<unsigned char>(value));
} }
void Creature::modifyBaseInventory(const ESM::RefId& actorId, const ESM::RefId& itemId, int amount) const void Creature::modifyBaseInventory(const ESM::RefId& actorId, const ESM::RefId& itemId, int amount) const

View file

@ -215,14 +215,14 @@ namespace MWClass
MWBase::Environment::get().getSoundManager()->fadeOutSound3D(ptr, closeSound, 0.5f); MWBase::Environment::get().getSoundManager()->fadeOutSound3D(ptr, closeSound, 0.5f);
// Doors rotate at 90 degrees per second, so start the sound at // Doors rotate at 90 degrees per second, so start the sound at
// where it would be at the current rotation. // where it would be at the current rotation.
float offset = doorRot / (osg::PI * 0.5f); float offset = doorRot / (osg::PIf * 0.5f);
action->setSoundOffset(offset); action->setSoundOffset(offset);
action->setSound(openSound); action->setSound(openSound);
} }
else else
{ {
MWBase::Environment::get().getSoundManager()->fadeOutSound3D(ptr, openSound, 0.5f); MWBase::Environment::get().getSoundManager()->fadeOutSound3D(ptr, openSound, 0.5f);
float offset = 1.0f - doorRot / (osg::PI * 0.5f); float offset = 1.0f - doorRot / (osg::PIf * 0.5f);
action->setSoundOffset(std::max(offset, 0.0f)); action->setSoundOffset(std::max(offset, 0.0f));
action->setSound(closeSound); action->setSound(closeSound);
} }

View file

@ -134,7 +134,7 @@ namespace MWClass
if (ref->mBase->mData.mEffectID[i] < 0) if (ref->mBase->mData.mEffectID[i] < 0)
continue; continue;
MWGui::Widgets::SpellEffectParams params; MWGui::Widgets::SpellEffectParams params;
params.mEffectID = ref->mBase->mData.mEffectID[i]; params.mEffectID = static_cast<short>(ref->mBase->mData.mEffectID[i]);
params.mAttribute = ESM::Attribute::indexToRefId(ref->mBase->mData.mAttributes[i]); params.mAttribute = ESM::Attribute::indexToRefId(ref->mBase->mData.mAttributes[i]);
params.mSkill = ESM::Skill::indexToRefId(ref->mBase->mData.mSkills[i]); params.mSkill = ESM::Skill::indexToRefId(ref->mBase->mData.mSkills[i]);
params.mKnown = alchemySkill >= fWortChanceValue * (i + 1); params.mKnown = alchemySkill >= fWortChanceValue * (i + 1);

View file

@ -90,13 +90,13 @@ namespace MWClass
if (Settings::game().mRebalanceSoulGemValues) if (Settings::game().mRebalanceSoulGemValues)
{ {
// use the 'soul gem value rebalance' formula from the Morrowind Code Patch // use the 'soul gem value rebalance' formula from the Morrowind Code Patch
float soulValue = 0.0001 * pow(soul, 3) + 2 * soul; double soulValue = 0.0001 * std::pow(soul, 3) + 2 * soul;
// for Azura's star add the unfilled value // for Azura's star add the unfilled value
if (ptr.getCellRef().getRefId() == "Misc_SoulGem_Azura") if (ptr.getCellRef().getRefId() == "Misc_SoulGem_Azura")
value += soulValue; value += static_cast<int>(soulValue);
else else
value = soulValue; value = static_cast<int>(soulValue);
} }
else else
value *= soul; value *= soul;

View file

@ -85,24 +85,24 @@ namespace
const NpcParts npcParts; const NpcParts npcParts;
int is_even(double d) bool isEven(double d)
{ {
double intPart; double intPart;
modf(d / 2.0, &intPart); std::modf(d / 2.0, &intPart);
return 2.0 * intPart == d; return 2.0 * intPart == d;
} }
int round_ieee_754(double d) float round_ieee_754(float f)
{ {
double i = floor(d); float i = std::floor(f);
d -= i; f -= i;
if (d < 0.5) if (f < 0.5)
return static_cast<int>(i); return i;
if (d > 0.5) if (f > 0.5)
return static_cast<int>(i) + 1; return i + 1.f;
if (is_even(i)) if (isEven(i))
return static_cast<int>(i); return i;
return static_cast<int>(i) + 1; return i + 1.f;
} }
void autoCalculateAttributes(const ESM::NPC* npc, MWMechanics::CreatureStats& creatureStats) void autoCalculateAttributes(const ESM::NPC* npc, MWMechanics::CreatureStats& creatureStats)
@ -115,7 +115,8 @@ namespace
const auto& attributes = MWBase::Environment::get().getESMStore()->get<ESM::Attribute>(); const auto& attributes = MWBase::Environment::get().getESMStore()->get<ESM::Attribute>();
int level = creatureStats.getLevel(); int level = creatureStats.getLevel();
for (const ESM::Attribute& attribute : attributes) for (const ESM::Attribute& attribute : attributes)
creatureStats.setAttribute(attribute.mId, race->mData.getAttribute(attribute.mId, male)); creatureStats.setAttribute(
attribute.mId, static_cast<float>(race->mData.getAttribute(attribute.mId, male)));
// class bonus // class bonus
const ESM::Class* npcClass = MWBase::Environment::get().getESMStore()->get<ESM::Class>().find(npc->mClass); const ESM::Class* npcClass = MWBase::Environment::get().getESMStore()->get<ESM::Class>().find(npc->mClass);
@ -155,7 +156,7 @@ namespace
creatureStats.setAttribute(attribute.mId, creatureStats.setAttribute(attribute.mId,
std::min( std::min(
round_ieee_754(creatureStats.getAttribute(attribute.mId).getBase() + (level - 1) * modifierSum), round_ieee_754(creatureStats.getAttribute(attribute.mId).getBase() + (level - 1) * modifierSum),
100)); 100.f));
} }
// initial health // initial health
@ -248,7 +249,7 @@ namespace
npcStats.getSkill(skill.mId).setBase( npcStats.getSkill(skill.mId).setBase(
std::min(round_ieee_754(npcStats.getSkill(skill.mId).getBase() + 5 + raceBonus + specBonus std::min(round_ieee_754(npcStats.getSkill(skill.mId).getBase() + 5 + raceBonus + specBonus
+ (int(level) - 1) * (majorMultiplier + specMultiplier)), + (int(level) - 1) * (majorMultiplier + specMultiplier)),
100)); // Must gracefully handle level 0 100.f)); // Must gracefully handle level 0
} }
if (!spellsInitialised) if (!spellsInitialised)
@ -334,10 +335,12 @@ namespace MWClass
gold = ref->mBase->mNpdt.mGold; gold = ref->mBase->mNpdt.mGold;
for (size_t i = 0; i < ref->mBase->mNpdt.mSkills.size(); ++i) for (size_t i = 0; i < ref->mBase->mNpdt.mSkills.size(); ++i)
data->mNpcStats.getSkill(ESM::Skill::indexToRefId(i)).setBase(ref->mBase->mNpdt.mSkills[i]); data->mNpcStats.getSkill(ESM::Skill::indexToRefId(static_cast<int>(i)))
.setBase(ref->mBase->mNpdt.mSkills[i]);
for (size_t i = 0; i < ref->mBase->mNpdt.mAttributes.size(); ++i) for (size_t i = 0; i < ref->mBase->mNpdt.mAttributes.size(); ++i)
data->mNpcStats.setAttribute(ESM::Attribute::indexToRefId(i), ref->mBase->mNpdt.mAttributes[i]); data->mNpcStats.setAttribute(
ESM::Attribute::indexToRefId(static_cast<int>(i)), ref->mBase->mNpdt.mAttributes[i]);
data->mNpcStats.setHealth(ref->mBase->mNpdt.mHealth); data->mNpcStats.setHealth(ref->mBase->mNpdt.mHealth);
data->mNpcStats.setMagicka(ref->mBase->mNpdt.mMana); data->mNpcStats.setMagicka(ref->mBase->mNpdt.mMana);
@ -589,7 +592,7 @@ namespace MWClass
if (!weapon.isEmpty()) if (!weapon.isEmpty())
weapskill = weapon.getClass().getEquipmentSkill(weapon); weapskill = weapon.getClass().getEquipmentSkill(weapon);
float hitchance = MWMechanics::getHitChance(ptr, victim, getSkill(ptr, weapskill)); float hitchance = MWMechanics::getHitChance(ptr, victim, static_cast<int>(getSkill(ptr, weapskill)));
return Misc::Rng::roll0to99(world->getPrng()) < hitchance; return Misc::Rng::roll0to99(world->getPrng()) < hitchance;
} }
@ -1405,7 +1408,7 @@ namespace MWClass
void Npc::setBaseAISetting(const ESM::RefId& id, MWMechanics::AiSetting setting, int value) const void Npc::setBaseAISetting(const ESM::RefId& id, MWMechanics::AiSetting setting, int value) const
{ {
MWMechanics::setBaseAISetting<ESM::NPC>(id, setting, value); MWMechanics::setBaseAISetting<ESM::NPC>(id, setting, static_cast<unsigned char>(value));
} }
void Npc::modifyBaseInventory(const ESM::RefId& actorId, const ESM::RefId& itemId, int amount) const void Npc::modifyBaseInventory(const ESM::RefId& actorId, const ESM::RefId& itemId, int amount) const

View file

@ -261,7 +261,7 @@ namespace MWClass
ESM::Weapon newItem = *ref->mBase; ESM::Weapon newItem = *ref->mBase;
newItem.mId = ESM::RefId(); newItem.mId = ESM::RefId();
newItem.mName = newName; newItem.mName = newName;
newItem.mData.mEnchant = enchCharge; newItem.mData.mEnchant = static_cast<uint16_t>(enchCharge);
newItem.mEnchant = enchId; newItem.mEnchant = enchId;
newItem.mData.mFlags |= ESM::Weapon::Magical; newItem.mData.mFlags |= ESM::Weapon::Magical;
const ESM::Weapon* record = MWBase::Environment::get().getESMStore()->insert(newItem); const ESM::Weapon* record = MWBase::Environment::get().getESMStore()->insert(newItem);

View file

@ -441,8 +441,9 @@ namespace MWDialogue
// Get the sum of disposition effects minus charm (shouldn't be made permanent) // Get the sum of disposition effects minus charm (shouldn't be made permanent)
npcStats.setBaseDisposition(0); npcStats.setBaseDisposition(0);
int zero = MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mActor, false) int zero = static_cast<int>(
- npcStats.getMagicEffects().getOrDefault(ESM::MagicEffect::Charm).getMagnitude(); MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mActor, false)
- npcStats.getMagicEffects().getOrDefault(ESM::MagicEffect::Charm).getMagnitude());
// Clamp new permanent disposition to avoid negative derived disposition (can be caused by intimidate) // Clamp new permanent disposition to avoid negative derived disposition (can be caused by intimidate)
int disposition = std::clamp(mOriginalDisposition + mPermanentDispositionChange, -zero, 100 - zero); int disposition = std::clamp(mOriginalDisposition + mPermanentDispositionChange, -zero, 100 - zero);
@ -652,7 +653,7 @@ namespace MWDialogue
return info != nullptr; return info != nullptr;
} }
int DialogueManager::countSavedGameRecords() const size_t DialogueManager::countSavedGameRecords() const
{ {
return 1; // known topics return 1; // known topics
} }

View file

@ -112,7 +112,7 @@ namespace MWDialogue
/// @note Controlled by an option, gets discarded when dialogue ends by default /// @note Controlled by an option, gets discarded when dialogue ends by default
void applyBarterDispositionChange(int delta) override; void applyBarterDispositionChange(int delta) override;
int countSavedGameRecords() const override; size_t countSavedGameRecords() const override;
void write(ESM::ESMWriter& writer, Loading::Listener& progress) const override; void write(ESM::ESMWriter& writer, Loading::Listener& progress) const override;

View file

@ -400,7 +400,7 @@ int MWDialogue::Filter::getSelectStructInteger(const SelectWrapper& select) cons
case ESM::DialogueCondition::Function_PcLuck: case ESM::DialogueCondition::Function_PcLuck:
{ {
ESM::RefId attribute = ESM::Attribute::indexToRefId(select.getArgument()); ESM::RefId attribute = ESM::Attribute::indexToRefId(select.getArgument());
return player.getClass().getCreatureStats(player).getAttribute(attribute).getModified(); return static_cast<int>(player.getClass().getCreatureStats(player).getAttribute(attribute).getModified());
} }
case ESM::DialogueCondition::Function_PcBlock: case ESM::DialogueCondition::Function_PcBlock:
case ESM::DialogueCondition::Function_PcArmorer: case ESM::DialogueCondition::Function_PcArmorer:

View file

@ -151,7 +151,7 @@ namespace MWDialogue
return iter->second.getIndex(); return iter->second.getIndex();
} }
int Journal::countSavedGameRecords() const size_t Journal::countSavedGameRecords() const
{ {
std::size_t count = mQuests.size(); std::size_t count = mQuests.size();
@ -163,7 +163,7 @@ namespace MWDialogue
for (const auto& [_, topic] : mTopics) for (const auto& [_, topic] : mTopics)
count += topic.size(); count += topic.size();
return static_cast<int>(count); return count;
} }
void Journal::write(ESM::ESMWriter& writer, Loading::Listener& progress) const void Journal::write(ESM::ESMWriter& writer, Loading::Listener& progress) const

View file

@ -53,7 +53,7 @@ namespace MWDialogue
const TQuestContainer& getQuests() const override { return mQuests; } const TQuestContainer& getQuests() const override { return mQuests; }
int countSavedGameRecords() const override; size_t countSavedGameRecords() const override;
void write(ESM::ESMWriter& writer, Loading::Listener& progress) const override; void write(ESM::ESMWriter& writer, Loading::Listener& progress) const override;

View file

@ -216,7 +216,7 @@ namespace MWGui
std::set<std::string> itemNames, itemEffects; std::set<std::string> itemNames, itemEffects;
for (size_t i = 0; i < mModel->getItemCount(); ++i) for (size_t i = 0; i < mModel->getItemCount(); ++i)
{ {
MWWorld::Ptr item = mModel->getItem(i).mBase; MWWorld::Ptr item = mModel->getItem(static_cast<ItemModel::ModelIndex>(i)).mBase;
if (item.getType() != ESM::Ingredient::sRecordId) if (item.getType() != ESM::Ingredient::sRecordId)
continue; continue;
@ -376,7 +376,7 @@ namespace MWGui
mItemSelectionDialog->eventDialogCanceled += MyGUI::newDelegate(this, &AlchemyWindow::onItemCancel); mItemSelectionDialog->eventDialogCanceled += MyGUI::newDelegate(this, &AlchemyWindow::onItemCancel);
mItemSelectionDialog->setVisible(true); mItemSelectionDialog->setVisible(true);
mItemSelectionDialog->openContainer(MWMechanics::getPlayer()); mItemSelectionDialog->openContainer(MWMechanics::getPlayer());
mItemSelectionDialog->getSortModel()->setApparatusTypeFilter(i); mItemSelectionDialog->getSortModel()->setApparatusTypeFilter(static_cast<int32_t>(i));
mItemSelectionDialog->setFilter(SortFilterItemModel::Filter_OnlyAlchemyTools); mItemSelectionDialog->setFilter(SortFilterItemModel::Filter_OnlyAlchemyTools);
} }
else else
@ -459,7 +459,7 @@ namespace MWGui
for (const MWMechanics::EffectKey& effectKey : effectIds) for (const MWMechanics::EffectKey& effectKey : effectIds)
{ {
Widgets::SpellEffectParams params; Widgets::SpellEffectParams params;
params.mEffectID = effectKey.mId; params.mEffectID = static_cast<short>(effectKey.mId);
const ESM::MagicEffect* magicEffect const ESM::MagicEffect* magicEffect
= MWBase::Environment::get().getESMStore()->get<ESM::MagicEffect>().find(effectKey.mId); = MWBase::Environment::get().getESMStore()->get<ESM::MagicEffect>().find(effectKey.mId);
if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetSkill) if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetSkill)
@ -589,11 +589,11 @@ namespace MWGui
if (arg.button == SDL_CONTROLLER_BUTTON_B) if (arg.button == SDL_CONTROLLER_BUTTON_B)
{ {
// Remove active ingredients or close the window, starting with right-most slot. // Remove active ingredients or close the window, starting with right-most slot.
for (int i = mIngredients.size() - 1; i >= 0; --i) for (size_t i = mIngredients.size(); i > 0; --i)
{ {
if (mIngredients[i]->isUserString("ToolTipType")) if (mIngredients[i - 1]->isUserString("ToolTipType"))
{ {
onIngredientSelected(mIngredients[i]); onIngredientSelected(mIngredients[i - 1]);
return true; return true;
} }
} }

View file

@ -12,28 +12,108 @@
#include <components/sceneutil/depth.hpp> #include <components/sceneutil/depth.hpp>
#include <components/settings/values.hpp> #include <components/settings/values.hpp>
namespace
{
std::optional<MyGUI::GlyphInfo> getGlyphInfo(MyGUI::IFont* font, MyGUI::Char ch)
{
const MyGUI::GlyphInfo* gi = font->getGlyphInfo(ch);
if (!gi)
return {};
const float scale = font->getDefaultHeight() / static_cast<float>(Settings::gui().mFontSize);
MyGUI::GlyphInfo info = *gi;
info.bearingX /= scale;
info.bearingY /= scale;
info.width /= scale;
info.height /= scale;
info.advance /= scale;
return info;
}
bool ucsLineBreak(Utf8Stream::UnicodeChar codePoint)
{
return codePoint == '\n';
}
bool ucsCarriageReturn(Utf8Stream::UnicodeChar codePoint)
{
return codePoint == '\r';
}
// Normal no-break space (0x00A0) is ignored here
// because Morrowind compatibility requires us to render its glyph
bool ucsSpace(Utf8Stream::UnicodeChar codePoint)
{
switch (codePoint)
{
case 0x0020: // SPACE
case 0x1680: // OGHAM SPACE MARK
case 0x180E: // MONGOLIAN VOWEL SEPARATOR
case 0x2000: // EN QUAD
case 0x2001: // EM QUAD
case 0x2002: // EN SPACE
case 0x2003: // EM SPACE
case 0x2004: // THREE-PER-EM SPACE
case 0x2005: // FOUR-PER-EM SPACE
case 0x2006: // SIX-PER-EM SPACE
case 0x2007: // FIGURE SPACE
case 0x2008: // PUNCTUATION SPACE
case 0x2009: // THIN SPACE
case 0x200A: // HAIR SPACE
case 0x200B: // ZERO WIDTH SPACE
case 0x202F: // NARROW NO-BREAK SPACE
case 0x205F: // MEDIUM MATHEMATICAL SPACE
case 0x3000: // IDEOGRAPHIC SPACE
case 0xFEFF: // ZERO WIDTH NO-BREAK SPACE
return true;
default:
return false;
}
}
// No-break spaces (0x00A0, 0x202F, 0xFEFF - normal, narrow, zero width)
// are ignored here for obvious reasons
// Figure space (0x2007) is not a breaking space either
bool ucsBreakingSpace(int codePoint)
{
switch (codePoint)
{
case 0x0020: // SPACE
case 0x1680: // OGHAM SPACE MARK
case 0x180E: // MONGOLIAN VOWEL SEPARATOR
case 0x2000: // EN QUAD
case 0x2001: // EM QUAD
case 0x2002: // EN SPACE
case 0x2003: // EM SPACE
case 0x2004: // THREE-PER-EM SPACE
case 0x2005: // FOUR-PER-EM SPACE
case 0x2006: // SIX-PER-EM SPACE
case 0x2008: // PUNCTUATION SPACE
case 0x2009: // THIN SPACE
case 0x200A: // HAIR SPACE
case 0x200B: // ZERO WIDTH SPACE
case 0x205F: // MEDIUM MATHEMATICAL SPACE
case 0x3000: // IDEOGRAPHIC SPACE
return true;
default:
return false;
}
}
}
namespace MWGui namespace MWGui
{ {
struct TypesetBookImpl; struct TypesetBookImpl;
class PageDisplay; class PageDisplay;
class BookPageImpl; class BookPageImpl;
static bool ucsSpace(int codePoint);
static bool ucsLineBreak(int codePoint);
static bool ucsCarriageReturn(int codePoint);
static bool ucsBreakingSpace(int codePoint);
struct BookTypesetter::Style struct BookTypesetter::Style
{ {
virtual ~Style() {} virtual ~Style() = default;
}; };
struct TypesetBookImpl : TypesetBook struct TypesetBookImpl : TypesetBook
{ {
typedef std::vector<uint8_t> Content; typedef std::pair<Utf8Stream::Point, Utf8Stream::Point> Range;
typedef std::list<Content> Contents;
typedef Utf8Stream::Point Utf8Point;
typedef std::pair<Utf8Point, Utf8Point> Range;
struct StyleImpl : BookTypesetter::Style struct StyleImpl : BookTypesetter::Style
{ {
@ -44,29 +124,28 @@ namespace MWGui
InteractiveId mInteractiveId; InteractiveId mInteractiveId;
bool match(MyGUI::IFont* tstFont, const MyGUI::Colour& tstHotColour, const MyGUI::Colour& tstActiveColour, bool match(MyGUI::IFont* tstFont, const MyGUI::Colour& tstHotColour, const MyGUI::Colour& tstActiveColour,
const MyGUI::Colour& tstNormalColour, intptr_t tstInteractiveId) const MyGUI::Colour& tstNormalColour, InteractiveId tstInteractiveId) const
{ {
return (mFont == tstFont) return (mFont == tstFont)
&& partal_match(tstHotColour, tstActiveColour, tstNormalColour, tstInteractiveId); && partialMatch(tstHotColour, tstActiveColour, tstNormalColour, tstInteractiveId);
} }
bool match(std::string_view tstFont, const MyGUI::Colour& tstHotColour, bool match(std::string_view tstFont, const MyGUI::Colour& tstHotColour,
const MyGUI::Colour& tstActiveColour, const MyGUI::Colour& tstNormalColour, intptr_t tstInteractiveId) const MyGUI::Colour& tstActiveColour, const MyGUI::Colour& tstNormalColour,
InteractiveId tstInteractiveId) const
{ {
return (mFont->getResourceName() == tstFont) return (mFont->getResourceName() == tstFont)
&& partal_match(tstHotColour, tstActiveColour, tstNormalColour, tstInteractiveId); && partialMatch(tstHotColour, tstActiveColour, tstNormalColour, tstInteractiveId);
} }
bool partal_match(const MyGUI::Colour& tstHotColour, const MyGUI::Colour& tstActiveColour, bool partialMatch(const MyGUI::Colour& tstHotColour, const MyGUI::Colour& tstActiveColour,
const MyGUI::Colour& tstNormalColour, intptr_t tstInteractiveId) const MyGUI::Colour& tstNormalColour, InteractiveId tstInteractiveId) const
{ {
return (mHotColour == tstHotColour) && (mActiveColour == tstActiveColour) return (mHotColour == tstHotColour) && (mActiveColour == tstActiveColour)
&& (mNormalColour == tstNormalColour) && (mInteractiveId == tstInteractiveId); && (mNormalColour == tstNormalColour) && (mInteractiveId == tstInteractiveId);
} }
}; };
typedef std::list<StyleImpl> Styles;
struct Run struct Run
{ {
StyleImpl* mStyle; StyleImpl* mStyle;
@ -75,19 +154,15 @@ namespace MWGui
int mPrintableChars; int mPrintableChars;
}; };
typedef std::vector<Run> Runs;
struct Line struct Line
{ {
Runs mRuns; std::vector<Run> mRuns;
MyGUI::IntRect mRect; MyGUI::IntRect mRect;
}; };
typedef std::vector<Line> Lines;
struct Section struct Section
{ {
Lines mLines; std::vector<Line> mLines;
MyGUI::IntRect mRect; MyGUI::IntRect mRect;
}; };
@ -97,12 +172,10 @@ namespace MWGui
// A page is basically a "window" into a portion of the source text, similar to a ScrollView. // A page is basically a "window" into a portion of the source text, similar to a ScrollView.
typedef std::pair<int, int> Page; typedef std::pair<int, int> Page;
typedef std::vector<Page> Pages; std::vector<Page> mPages;
Pages mPages;
Sections mSections; Sections mSections;
Contents mContents; std::list<Content> mContents;
Styles mStyles; std::list<StyleImpl> mStyles;
MyGUI::IntRect mRect; MyGUI::IntRect mRect;
void setColour(size_t section, size_t line, size_t run, const MyGUI::Colour& colour) const override void setColour(size_t section, size_t line, size_t run, const MyGUI::Colour& colour) const override
@ -117,16 +190,16 @@ namespace MWGui
mSections[section].mLines[line].mRuns[run].mStyle->mNormalColour = colour; mSections[section].mLines[line].mRuns[run].mStyle->mNormalColour = colour;
} }
virtual ~TypesetBookImpl() {} virtual ~TypesetBookImpl() = default;
Range addContent(const BookTypesetter::Utf8Span& text) Range addContent(std::string_view text)
{ {
Contents::iterator i = mContents.insert(mContents.end(), Content(text.first, text.second)); Content& content = mContents.emplace_back(text.begin(), text.end());
if (i->empty()) if (content.empty())
return Range(Utf8Point(nullptr), Utf8Point(nullptr)); return Range(nullptr, nullptr);
return Range(i->data(), i->data() + i->size()); return Range(content.data(), content.data() + content.size());
} }
size_t pageCount() const override { return mPages.size(); } size_t pageCount() const override { return mPages.size(); }
@ -139,19 +212,19 @@ namespace MWGui
template <typename Visitor> template <typename Visitor>
void visitRuns(int top, int bottom, MyGUI::IFont* font, Visitor const& visitor) const void visitRuns(int top, int bottom, MyGUI::IFont* font, Visitor const& visitor) const
{ {
for (Sections::const_iterator i = mSections.begin(); i != mSections.end(); ++i) for (const Section& section : mSections)
{ {
if (top >= mRect.bottom || bottom <= i->mRect.top) if (top >= mRect.bottom || bottom <= section.mRect.top)
continue; continue;
for (const Line& line : section.mLines)
for (Lines::const_iterator j = i->mLines.begin(); j != i->mLines.end(); ++j)
{ {
if (top >= j->mRect.bottom || bottom <= j->mRect.top) if (top >= line.mRect.bottom || bottom <= line.mRect.top)
continue; continue;
for (const Run& run : line.mRuns)
for (Runs::const_iterator k = j->mRuns.begin(); k != j->mRuns.end(); ++k) {
if (!font || k->mStyle->mFont == font) if (!font || run.mStyle->mFont == font)
visitor(*i, *j, *k); visitor(section, line, run);
}
} }
} }
} }
@ -192,26 +265,26 @@ namespace MWGui
StyleImpl* hitTest(int left, int top) const StyleImpl* hitTest(int left, int top) const
{ {
for (Sections::const_iterator i = mSections.begin(); i != mSections.end(); ++i) for (const Section& section : mSections)
{ {
if (top < i->mRect.top || top >= i->mRect.bottom) if (top < section.mRect.top || top >= section.mRect.bottom)
continue; continue;
int left1 = left - i->mRect.left; int left1 = left - section.mRect.left;
for (Lines::const_iterator j = i->mLines.begin(); j != i->mLines.end(); ++j) for (const Line& line : section.mLines)
{ {
if (top < j->mRect.top || top >= j->mRect.bottom) if (top < line.mRect.top || top >= line.mRect.bottom)
continue; continue;
int left2 = left1 - j->mRect.left; int left2 = left1 - line.mRect.left;
for (Runs::const_iterator k = j->mRuns.begin(); k != j->mRuns.end(); ++k) for (const Run& run : line.mRuns)
{ {
if (left2 < k->mLeft || left2 >= k->mRight) if (left2 < run.mLeft || left2 >= run.mRight)
continue; continue;
return k->mStyle; return run.mStyle;
} }
} }
} }
@ -221,9 +294,9 @@ namespace MWGui
MyGUI::IFont* affectedFont(StyleImpl* style) MyGUI::IFont* affectedFont(StyleImpl* style)
{ {
for (Styles::iterator i = mStyles.begin(); i != mStyles.end(); ++i) for (const StyleImpl& s : mStyles)
if (&*i == style) if (&s == style)
return i->mFont; return s.mFont;
return nullptr; return nullptr;
} }
@ -248,14 +321,10 @@ namespace MWGui
} }
}; };
typedef TypesetBookImpl Book;
typedef std::shared_ptr<Book> BookPtr;
typedef std::vector<PartialText>::const_iterator PartialTextConstIterator;
int mPageWidth; int mPageWidth;
int mPageHeight; int mPageHeight;
BookPtr mBook; std::shared_ptr<TypesetBookImpl> mBook;
Section* mSection; Section* mSection;
Line* mLine; Line* mLine;
Run* mRun; Run* mRun;
@ -264,10 +333,10 @@ namespace MWGui
std::vector<PartialText> mPartialWhitespace; std::vector<PartialText> mPartialWhitespace;
std::vector<PartialText> mPartialWord; std::vector<PartialText> mPartialWord;
Book::Content const* mCurrentContent; TypesetBookImpl::Content const* mCurrentContent;
Alignment mCurrentAlignment; Alignment mCurrentAlignment;
Typesetter(size_t width, size_t height) Typesetter(int width, int height)
: mPageWidth(width) : mPageWidth(width)
, mPageHeight(height) , mPageHeight(height)
, mSection(nullptr) , mSection(nullptr)
@ -276,12 +345,12 @@ namespace MWGui
, mCurrentContent(nullptr) , mCurrentContent(nullptr)
, mCurrentAlignment(AlignLeft) , mCurrentAlignment(AlignLeft)
{ {
mBook = std::make_shared<Book>(); mBook = std::make_shared<TypesetBookImpl>();
} }
virtual ~Typesetter() {} virtual ~Typesetter() = default;
Style* createStyle(const std::string& fontName, const Colour& fontColour, bool useBookFont) override Style* createStyle(const std::string& fontName, const MyGUI::Colour& fontColour, bool useBookFont) override
{ {
std::string fullFontName; std::string fullFontName;
if (fontName.empty()) if (fontName.empty())
@ -292,9 +361,9 @@ namespace MWGui
if (useBookFont) if (useBookFont)
fullFontName = "Journalbook " + fullFontName; fullFontName = "Journalbook " + fullFontName;
for (Styles::iterator i = mBook->mStyles.begin(); i != mBook->mStyles.end(); ++i) for (StyleImpl& style : mBook->mStyles)
if (i->match(fullFontName, fontColour, fontColour, fontColour, 0)) if (style.match(fullFontName, fontColour, fontColour, fontColour, 0))
return &*i; return &style;
MyGUI::IFont* font = MyGUI::FontManager::getInstance().getByName(fullFontName); MyGUI::IFont* font = MyGUI::FontManager::getInstance().getByName(fullFontName);
if (!font) if (!font)
@ -310,15 +379,15 @@ namespace MWGui
return &style; return &style;
} }
Style* createHotStyle(Style* baseStyle, const Colour& normalColour, const Colour& hoverColour, Style* createHotStyle(Style* baseStyle, const MyGUI::Colour& normalColour, const MyGUI::Colour& hoverColour,
const Colour& activeColour, InteractiveId id, bool unique) override const MyGUI::Colour& activeColour, InteractiveId id, bool unique) override
{ {
StyleImpl* const baseStyleImpl = static_cast<StyleImpl*>(baseStyle); StyleImpl* const baseStyleImpl = static_cast<StyleImpl*>(baseStyle);
if (!unique) if (!unique)
for (Styles::iterator i = mBook->mStyles.begin(); i != mBook->mStyles.end(); ++i) for (StyleImpl& style : mBook->mStyles)
if (i->match(baseStyleImpl->mFont, hoverColour, activeColour, normalColour, id)) if (style.match(baseStyleImpl->mFont, hoverColour, activeColour, normalColour, id))
return &*i; return &style;
StyleImpl& style = *mBook->mStyles.insert(mBook->mStyles.end(), StyleImpl()); StyleImpl& style = *mBook->mStyles.insert(mBook->mStyles.end(), StyleImpl());
@ -331,30 +400,30 @@ namespace MWGui
return &style; return &style;
} }
void write(Style* style, Utf8Span text) override void write(Style* style, std::string_view text) override
{ {
Range range = mBook->addContent(text); Range range = mBook->addContent(text);
writeImpl(static_cast<StyleImpl*>(style), range.first, range.second); writeImpl(static_cast<StyleImpl*>(style), Utf8Stream(range.first, range.second));
} }
intptr_t addContent(Utf8Span text, bool select) override const Content* addContent(std::string_view text, bool select) override
{ {
add_partial_text(); add_partial_text();
Contents::iterator i = mBook->mContents.insert(mBook->mContents.end(), Content(text.first, text.second)); Content& content = mBook->mContents.emplace_back(text.begin(), text.end());
if (select) if (select)
mCurrentContent = &(*i); mCurrentContent = &content;
return reinterpret_cast<intptr_t>(&(*i)); return &content;
} }
void selectContent(intptr_t contentHandle) override void selectContent(const Content* contentHandle) override
{ {
add_partial_text(); add_partial_text();
mCurrentContent = reinterpret_cast<Content const*>(contentHandle); mCurrentContent = contentHandle;
} }
void write(Style* style, size_t begin, size_t end) override void write(Style* style, size_t begin, size_t end) override
@ -363,10 +432,10 @@ namespace MWGui
assert(end <= mCurrentContent->size()); assert(end <= mCurrentContent->size());
assert(begin <= mCurrentContent->size()); assert(begin <= mCurrentContent->size());
const Utf8Point contentBegin = mCurrentContent->data() + begin; const Utf8Stream::Point contentBegin = mCurrentContent->data() + begin;
const Utf8Point contentEnd = mCurrentContent->data() + end; const Utf8Stream::Point contentEnd = mCurrentContent->data() + end;
writeImpl(static_cast<StyleImpl*>(style), contentBegin, contentEnd); writeImpl(static_cast<StyleImpl*>(style), Utf8Stream(contentBegin, contentEnd));
} }
void lineBreak(float margin) override void lineBreak(float margin) override
@ -403,7 +472,7 @@ namespace MWGui
mCurrentAlignment = sectionAlignment; mCurrentAlignment = sectionAlignment;
} }
TypesetBook::Ptr complete() override std::shared_ptr<TypesetBook> complete() override
{ {
int curPageStart = 0; int curPageStart = 0;
int curPageStop = 0; int curPageStop = 0;
@ -414,26 +483,26 @@ namespace MWGui
for (Sections::iterator i = mBook->mSections.begin(); i != mBook->mSections.end(); ++i, ++sa) for (Sections::iterator i = mBook->mSections.begin(); i != mBook->mSections.end(); ++i, ++sa)
{ {
// apply alignment to individual lines... // apply alignment to individual lines...
for (Lines::iterator j = i->mLines.begin(); j != i->mLines.end(); ++j) for (Line& line : i->mLines)
{ {
int width = j->mRect.width(); int width = line.mRect.width();
int excess = mPageWidth - width; int excess = mPageWidth - width;
switch (*sa) switch (*sa)
{ {
default: default:
case AlignLeft: case AlignLeft:
j->mRect.left = 0; line.mRect.left = 0;
break; break;
case AlignCenter: case AlignCenter:
j->mRect.left = excess / 2; line.mRect.left = excess / 2;
break; break;
case AlignRight: case AlignRight:
j->mRect.left = excess; line.mRect.left = excess;
break; break;
} }
j->mRect.right = j->mRect.left + width; line.mRect.right = line.mRect.left + width;
} }
if (curPageStop == curPageStart) if (curPageStop == curPageStart)
@ -458,7 +527,7 @@ namespace MWGui
// one. // one.
assert(curPageStart != curPageStop); assert(curPageStart != curPageStop);
mBook->mPages.push_back(Page(curPageStart, curPageStop)); mBook->mPages.emplace_back(curPageStart, curPageStop);
curPageStart = i->mRect.top; curPageStart = i->mRect.top;
curPageStop = i->mRect.bottom; curPageStop = i->mRect.bottom;
@ -470,7 +539,7 @@ namespace MWGui
{ {
// The section won't completely fit on the current page. Finish the current page and start a new // The section won't completely fit on the current page. Finish the current page and start a new
// one. // one.
mBook->mPages.push_back(Page(curPageStart, curPageStop)); mBook->mPages.emplace_back(curPageStart, curPageStop);
curPageStart = i->mRect.top; curPageStart = i->mRect.top;
curPageStop = i->mRect.bottom; curPageStop = i->mRect.bottom;
@ -481,16 +550,16 @@ namespace MWGui
{ {
// Adjust to the top of the first line that does not fit on the current page anymore // Adjust to the top of the first line that does not fit on the current page anymore
int splitPos = curPageStop; int splitPos = curPageStop;
for (Lines::iterator j = i->mLines.begin(); j != i->mLines.end(); ++j) for (const Line& line : i->mLines)
{ {
if (j->mRect.bottom > curPageStart + mPageHeight) if (line.mRect.bottom > curPageStart + mPageHeight)
{ {
splitPos = j->mRect.top; splitPos = line.mRect.top;
break; break;
} }
} }
mBook->mPages.push_back(Page(curPageStart, splitPos)); mBook->mPages.emplace_back(curPageStart, splitPos);
curPageStart = splitPos; curPageStart = splitPos;
curPageStop = splitPos; curPageStop = splitPos;
@ -501,15 +570,13 @@ namespace MWGui
} }
if (curPageStart != curPageStop) if (curPageStart != curPageStop)
mBook->mPages.push_back(Page(curPageStart, curPageStop)); mBook->mPages.emplace_back(curPageStart, curPageStop);
return mBook; return mBook;
} }
void writeImpl(StyleImpl* style, Utf8Stream::Point begin, Utf8Stream::Point end) void writeImpl(StyleImpl* style, Utf8Stream&& stream)
{ {
Utf8Stream stream(begin, end);
while (!stream.eof()) while (!stream.eof())
{ {
if (ucsLineBreak(stream.peek())) if (ucsLineBreak(stream.peek()))
@ -531,9 +598,9 @@ namespace MWGui
while (!stream.eof() && !ucsLineBreak(stream.peek()) && ucsBreakingSpace(stream.peek())) while (!stream.eof() && !ucsLineBreak(stream.peek()) && ucsBreakingSpace(stream.peek()))
{ {
MWGui::GlyphInfo info = GlyphInfo(style->mFont, stream.peek()); std::optional<MyGUI::GlyphInfo> info = getGlyphInfo(style->mFont, stream.peek());
if (info.charFound) if (info)
spaceWidth += static_cast<int>(info.advance + info.bearingX); spaceWidth += static_cast<int>(info->advance + info->bearingX);
stream.consume(); stream.consume();
} }
@ -541,9 +608,9 @@ namespace MWGui
while (!stream.eof() && !ucsLineBreak(stream.peek()) && !ucsBreakingSpace(stream.peek())) while (!stream.eof() && !ucsLineBreak(stream.peek()) && !ucsBreakingSpace(stream.peek()))
{ {
MWGui::GlyphInfo info = GlyphInfo(style->mFont, stream.peek()); std::optional<MyGUI::GlyphInfo> info = getGlyphInfo(style->mFont, stream.peek());
if (info.charFound) if (info)
wordWidth += static_cast<int>(info.advance + info.bearingX); wordWidth += static_cast<int>(info->advance + info->bearingX);
stream.consume(); stream.consume();
} }
@ -568,10 +635,10 @@ namespace MWGui
int spaceWidth = 0; int spaceWidth = 0;
int wordWidth = 0; int wordWidth = 0;
for (PartialTextConstIterator i = mPartialWhitespace.begin(); i != mPartialWhitespace.end(); ++i) for (const PartialText& partialText : mPartialWhitespace)
spaceWidth += i->mWidth; spaceWidth += partialText.mWidth;
for (PartialTextConstIterator i = mPartialWord.begin(); i != mPartialWord.end(); ++i) for (const PartialText& partialText : mPartialWord)
wordWidth += i->mWidth; wordWidth += partialText.mWidth;
int left = mLine ? mLine->mRect.right : 0; int left = mLine ? mLine->mRect.right : 0;
@ -583,21 +650,23 @@ namespace MWGui
} }
else else
{ {
for (PartialTextConstIterator i = mPartialWhitespace.begin(); i != mPartialWhitespace.end(); ++i) for (const PartialText& partialText : mPartialWhitespace)
{ {
int top = mLine ? mLine->mRect.top : mBook->mRect.bottom; int top = mLine ? mLine->mRect.top : mBook->mRect.bottom;
append_run(i->mStyle, i->mBegin, i->mEnd, 0, left + i->mWidth, top + fontHeight); appendRun(partialText.mStyle, partialText.mBegin, partialText.mEnd, 0, left + partialText.mWidth,
top + fontHeight);
left = mLine->mRect.right; left = mLine->mRect.right;
} }
} }
for (PartialTextConstIterator i = mPartialWord.begin(); i != mPartialWord.end(); ++i) for (const PartialText& partialText : mPartialWord)
{ {
int top = mLine ? mLine->mRect.top : mBook->mRect.bottom; int top = mLine ? mLine->mRect.top : mBook->mRect.bottom;
const int numChars = static_cast<int>(partialText.mEnd - partialText.mBegin);
append_run(i->mStyle, i->mBegin, i->mEnd, i->mEnd - i->mBegin, left + i->mWidth, top + fontHeight); appendRun(partialText.mStyle, partialText.mBegin, partialText.mEnd, numChars, left + partialText.mWidth,
top + fontHeight);
left = mLine->mRect.right; left = mLine->mRect.right;
} }
@ -606,7 +675,7 @@ namespace MWGui
mPartialWord.clear(); mPartialWord.clear();
} }
void append_run(StyleImpl* style, Utf8Stream::Point begin, Utf8Stream::Point end, int pc, int right, int bottom) void appendRun(StyleImpl* style, Utf8Stream::Point begin, Utf8Stream::Point end, int pc, int right, int bottom)
{ {
if (mSection == nullptr) if (mSection == nullptr)
{ {
@ -664,7 +733,7 @@ namespace MWGui
} }
}; };
BookTypesetter::Ptr BookTypesetter::create(int pageWidth, int pageHeight) std::shared_ptr<BookTypesetter> BookTypesetter::create(int pageWidth, int pageHeight)
{ {
return std::make_shared<TypesetBookImpl::Typesetter>(pageWidth, pageHeight); return std::make_shared<TypesetBookImpl::Typesetter>(pageWidth, pageHeight);
} }
@ -788,34 +857,34 @@ namespace MWGui
mCursor.top = mOrigin.top + top; mCursor.top = mOrigin.top + top;
} }
void emitGlyph(wchar_t ch) void emitGlyph(MyGUI::Char ch)
{ {
MWGui::GlyphInfo info = GlyphInfo(mFont, ch); std::optional<MyGUI::GlyphInfo> info = getGlyphInfo(mFont, ch);
if (!info.charFound) if (!info)
return; return;
MyGUI::FloatRect vr; MyGUI::FloatRect vr;
vr.left = mCursor.left + info.bearingX; vr.left = mCursor.left + info->bearingX;
vr.top = mCursor.top + info.bearingY; vr.top = mCursor.top + info->bearingY;
vr.right = vr.left + info.width; vr.right = vr.left + info->width;
vr.bottom = vr.top + info.height; vr.bottom = vr.top + info->height;
MyGUI::FloatRect tr = info.uvRect; MyGUI::FloatRect tr = info->uvRect;
if (mRenderXform.clip(vr, tr)) if (mRenderXform.clip(vr, tr))
quad(vr, tr); quad(vr, tr);
mCursor.left += static_cast<int>(info.bearingX + info.advance); mCursor.left += static_cast<int>(info->bearingX + info->advance);
} }
void emitSpace(wchar_t ch) void emitSpace(MyGUI::Char ch)
{ {
MWGui::GlyphInfo info = GlyphInfo(mFont, ch); std::optional<MyGUI::GlyphInfo> info = getGlyphInfo(mFont, ch);
if (info.charFound) if (info)
mCursor.left += static_cast<int>(info.bearingX + info.advance); mCursor.left += static_cast<int>(info->bearingX + info->advance);
} }
private: private:
@ -849,17 +918,12 @@ namespace MWGui
{ {
MYGUI_RTTI_DERIVED(PageDisplay) MYGUI_RTTI_DERIVED(PageDisplay)
protected: protected:
typedef TypesetBookImpl::Section Section;
typedef TypesetBookImpl::Line Line;
typedef TypesetBookImpl::Run Run;
bool mIsPageReset; bool mIsPageReset;
size_t mPage; size_t mPage;
struct TextFormat : ISubWidget struct TextFormat : ISubWidget
{ {
typedef MyGUI::IFont* Id; MyGUI::IFont* mFont;
Id mFont;
int mCountVertex; int mCountVertex;
MyGUI::ITexture* mTexture; MyGUI::ITexture* mTexture;
MyGUI::RenderItem* mRenderItem; MyGUI::RenderItem* mRenderItem;
@ -934,16 +998,15 @@ namespace MWGui
} }
public: public:
typedef TypesetBookImpl::StyleImpl Style; typedef std::map<MyGUI::IFont*, std::unique_ptr<TextFormat>> ActiveTextFormats;
typedef std::map<TextFormat::Id, std::unique_ptr<TextFormat>> ActiveTextFormats;
int mViewTop; int mViewTop;
int mViewBottom; int mViewBottom;
Style* mFocusItem; TypesetBookImpl::StyleImpl* mFocusItem;
bool mItemActive; bool mItemActive;
MyGUI::MouseButton mLastDown; MyGUI::MouseButton mLastDown;
std::function<void(intptr_t)> mLinkClicked; std::function<void(TypesetBook::InteractiveId)> mLinkClicked;
std::shared_ptr<TypesetBookImpl> mBook; std::shared_ptr<TypesetBookImpl> mBook;
@ -989,7 +1052,7 @@ namespace MWGui
void onMouseMove(int left, int top) void onMouseMove(int left, int top)
{ {
Style* hit = nullptr; TypesetBookImpl::StyleImpl* hit = nullptr;
if (auto pos = getAdjustedPos(left, top, true)) if (auto pos = getAdjustedPos(left, top, true))
if (pos->top <= mViewBottom) if (pos->top <= mViewBottom)
hit = mBook->hitTestWithMargin(pos->left, pos->top); hit = mBook->hitTestWithMargin(pos->left, pos->top);
@ -1040,7 +1103,8 @@ namespace MWGui
if (pos && mLastDown == id) if (pos && mLastDown == id)
{ {
Style* item = pos->top <= mViewBottom ? mBook->hitTestWithMargin(pos->left, pos->top) : nullptr; TypesetBookImpl::StyleImpl* item
= pos->top <= mViewBottom ? mBook->hitTestWithMargin(pos->left, pos->top) : nullptr;
bool clicked = mFocusItem == item; bool clicked = mFocusItem == item;
@ -1055,7 +1119,7 @@ namespace MWGui
} }
} }
void showPage(TypesetBook::Ptr book, size_t newPage) void showPage(std::shared_ptr<TypesetBook> book, size_t newPage)
{ {
std::shared_ptr<TypesetBookImpl> newBook = std::dynamic_pointer_cast<TypesetBookImpl>(book); std::shared_ptr<TypesetBookImpl> newBook = std::dynamic_pointer_cast<TypesetBookImpl>(book);
@ -1129,7 +1193,8 @@ namespace MWGui
{ {
} }
void operator()(Section const& section, Line const& line, Run const& run) const void operator()(const TypesetBookImpl::Section& section, const TypesetBookImpl::Line& line,
const TypesetBookImpl::Run& run) const
{ {
MyGUI::IFont* const font = run.mStyle->mFont; MyGUI::IFont* const font = run.mStyle->mFont;
@ -1198,7 +1263,8 @@ namespace MWGui
{ {
} }
void operator()(Section const& section, Line const& line, Run const& run) const void operator()(const TypesetBookImpl::Section& section, const TypesetBookImpl::Line& line,
const TypesetBookImpl::Run& run) const
{ {
bool isActive = run.mStyle->mInteractiveId && (run.mStyle == mPageDisplay->mFocusItem); bool isActive = run.mStyle->mInteractiveId && (run.mStyle == mPageDisplay->mFocusItem);
@ -1291,14 +1357,20 @@ namespace MWGui
{ {
} }
void showPage(TypesetBook::Ptr book, size_t page) override { mPageDisplay->showPage(std::move(book), page); } void showPage(std::shared_ptr<TypesetBook> book, size_t page) override
{
mPageDisplay->showPage(std::move(book), page);
}
void adviseLinkClicked(std::function<void(InteractiveId)> linkClicked) override void adviseLinkClicked(std::function<void(TypesetBook::InteractiveId)> linkClicked) override
{ {
mPageDisplay->mLinkClicked = std::move(linkClicked); mPageDisplay->mLinkClicked = std::move(linkClicked);
} }
void unadviseLinkClicked() override { mPageDisplay->mLinkClicked = std::function<void(InteractiveId)>(); } void unadviseLinkClicked() override
{
mPageDisplay->mLinkClicked = std::function<void(TypesetBook::InteractiveId)>();
}
void setFocusItem(BookTypesetter::Style* itemStyle) override void setFocusItem(BookTypesetter::Style* itemStyle) override
{ {
@ -1350,75 +1422,4 @@ namespace MWGui
factory.registerFactory<BookPageImpl>("Widget"); factory.registerFactory<BookPageImpl>("Widget");
factory.registerFactory<PageDisplay>("BasisSkin"); factory.registerFactory<PageDisplay>("BasisSkin");
} }
static bool ucsLineBreak(int codePoint)
{
return codePoint == '\n';
}
static bool ucsCarriageReturn(int codePoint)
{
return codePoint == '\r';
}
// Normal no-break space (0x00A0) is ignored here
// because Morrowind compatibility requires us to render its glyph
static bool ucsSpace(int codePoint)
{
switch (codePoint)
{
case 0x0020: // SPACE
case 0x1680: // OGHAM SPACE MARK
case 0x180E: // MONGOLIAN VOWEL SEPARATOR
case 0x2000: // EN QUAD
case 0x2001: // EM QUAD
case 0x2002: // EN SPACE
case 0x2003: // EM SPACE
case 0x2004: // THREE-PER-EM SPACE
case 0x2005: // FOUR-PER-EM SPACE
case 0x2006: // SIX-PER-EM SPACE
case 0x2007: // FIGURE SPACE
case 0x2008: // PUNCTUATION SPACE
case 0x2009: // THIN SPACE
case 0x200A: // HAIR SPACE
case 0x200B: // ZERO WIDTH SPACE
case 0x202F: // NARROW NO-BREAK SPACE
case 0x205F: // MEDIUM MATHEMATICAL SPACE
case 0x3000: // IDEOGRAPHIC SPACE
case 0xFEFF: // ZERO WIDTH NO-BREAK SPACE
return true;
default:
return false;
}
}
// No-break spaces (0x00A0, 0x202F, 0xFEFF - normal, narrow, zero width)
// are ignored here for obvious reasons
// Figure space (0x2007) is not a breaking space either
static bool ucsBreakingSpace(int codePoint)
{
switch (codePoint)
{
case 0x0020: // SPACE
case 0x1680: // OGHAM SPACE MARK
case 0x180E: // MONGOLIAN VOWEL SEPARATOR
case 0x2000: // EN QUAD
case 0x2001: // EM QUAD
case 0x2002: // EN SPACE
case 0x2003: // EM SPACE
case 0x2004: // THREE-PER-EM SPACE
case 0x2005: // FOUR-PER-EM SPACE
case 0x2006: // SIX-PER-EM SPACE
case 0x2008: // PUNCTUATION SPACE
case 0x2009: // THIN SPACE
case 0x200A: // HAIR SPACE
case 0x200B: // ZERO WIDTH SPACE
case 0x205F: // MEDIUM MATHEMATICAL SPACE
case 0x3000: // IDEOGRAPHIC SPACE
return true;
default:
return false;
}
}
} }

View file

@ -8,6 +8,7 @@
#include <cstdint> #include <cstdint>
#include <functional> #include <functional>
#include <memory> #include <memory>
#include <vector>
#include <components/settings/values.hpp> #include <components/settings/values.hpp>
@ -17,7 +18,7 @@ namespace MWGui
/// the book page widget. /// the book page widget.
struct TypesetBook struct TypesetBook
{ {
typedef std::shared_ptr<TypesetBook> Ptr; using Content = std::vector<uint8_t>;
typedef intptr_t InteractiveId; typedef intptr_t InteractiveId;
/// Returns the number of pages in the document. /// Returns the number of pages in the document.
@ -37,55 +38,9 @@ namespace MWGui
virtual ~TypesetBook() = default; virtual ~TypesetBook() = default;
}; };
struct GlyphInfo
{
char codePoint;
float width;
float height;
float advance;
float bearingX;
float bearingY;
bool charFound;
MyGUI::FloatRect uvRect;
GlyphInfo(MyGUI::IFont* font, MyGUI::Char ch)
{
const MyGUI::GlyphInfo* gi = font->getGlyphInfo(ch);
if (gi)
{
const float scale = font->getDefaultHeight() / static_cast<float>(Settings::gui().mFontSize);
codePoint = gi->codePoint;
bearingX = (int)gi->bearingX / scale;
bearingY = (int)gi->bearingY / scale;
width = (int)gi->width / scale;
height = (int)gi->height / scale;
advance = (int)gi->advance / scale;
uvRect = gi->uvRect;
charFound = true;
}
else
{
codePoint = 0;
bearingX = 0;
bearingY = 0;
width = 0;
height = 0;
advance = 0;
charFound = false;
}
}
};
/// A factory class for creating a typeset book instance. /// A factory class for creating a typeset book instance.
struct BookTypesetter struct BookTypesetter
{ {
typedef std::shared_ptr<BookTypesetter> Ptr;
typedef TypesetBook::InteractiveId InteractiveId;
typedef MyGUI::Colour Colour;
typedef uint8_t const* Utf8Point;
typedef std::pair<Utf8Point, Utf8Point> Utf8Span;
virtual ~BookTypesetter() = default; virtual ~BookTypesetter() = default;
enum Alignment enum Alignment
@ -102,16 +57,18 @@ namespace MWGui
struct Style; struct Style;
/// A factory function for creating the default implementation of a book typesetter /// A factory function for creating the default implementation of a book typesetter
static Ptr create(int pageWidth, int pageHeight); static std::shared_ptr<BookTypesetter> create(int pageWidth, int pageHeight);
/// Create a simple text style consisting of a font and a text color. /// Create a simple text style consisting of a font and a text color.
virtual Style* createStyle(const std::string& fontName, const Colour& colour, bool useBookFont = true) = 0; virtual Style* createStyle(const std::string& fontName, const MyGUI::Colour& colour, bool useBookFont = true)
= 0;
/// Create a hyper-link style with a user-defined identifier based on an /// Create a hyper-link style with a user-defined identifier based on an
/// existing style. The unique flag forces a new instance of this style /// existing style. The unique flag forces a new instance of this style
/// to be created even if an existing instance is present. /// to be created even if an existing instance is present.
virtual Style* createHotStyle(Style* baseStyle, const Colour& normalColour, const Colour& hoverColour, virtual Style* createHotStyle(Style* baseStyle, const MyGUI::Colour& normalColour,
const Colour& activeColour, InteractiveId id, bool unique = true) const MyGUI::Colour& hoverColour, const MyGUI::Colour& activeColour, TypesetBook::InteractiveId id,
bool unique = true)
= 0; = 0;
/// Insert a line break into the document. Newline characters in the input /// Insert a line break into the document. Newline characters in the input
@ -129,22 +86,22 @@ namespace MWGui
virtual void setSectionAlignment(Alignment sectionAlignment) = 0; virtual void setSectionAlignment(Alignment sectionAlignment) = 0;
// Layout a block of text with the specified style into the document. // Layout a block of text with the specified style into the document.
virtual void write(Style* style, Utf8Span text) = 0; virtual void write(Style* style, std::string_view text) = 0;
/// Adds a content block to the document without laying it out. An /// Adds a content block to the document without laying it out. An
/// identifier is returned that can be used to refer to it. If select /// identifier is returned that can be used to refer to it. If select
/// is true, the block is activated to be references by future writes. /// is true, the block is activated to be references by future writes.
virtual intptr_t addContent(Utf8Span text, bool select = true) = 0; virtual const TypesetBook::Content* addContent(std::string_view text, bool select = true) = 0;
/// Select a previously created content block for future writes. /// Select a previously created content block for future writes.
virtual void selectContent(intptr_t contentHandle) = 0; virtual void selectContent(const TypesetBook::Content* contentHandle) = 0;
/// Layout a span of the selected content block into the document /// Layout a span of the selected content block into the document
/// using the specified style. /// using the specified style.
virtual void write(Style* style, size_t begin, size_t end) = 0; virtual void write(Style* style, size_t begin, size_t end) = 0;
/// Finalize the document layout, and return a pointer to it. /// Finalize the document layout, and return a pointer to it.
virtual TypesetBook::Ptr complete() = 0; virtual std::shared_ptr<TypesetBook> complete() = 0;
}; };
/// An interface to the BookPage widget. /// An interface to the BookPage widget.
@ -152,11 +109,10 @@ namespace MWGui
{ {
MYGUI_RTTI_DERIVED(BookPage) MYGUI_RTTI_DERIVED(BookPage)
public: public:
typedef TypesetBook::InteractiveId InteractiveId; using ClickCallback = std::function<void(TypesetBook::InteractiveId)>;
typedef std::function<void(InteractiveId)> ClickCallback;
/// Make the widget display the specified page from the specified book. /// Make the widget display the specified page from the specified book.
virtual void showPage(TypesetBook::Ptr book, size_t page) = 0; virtual void showPage(std::shared_ptr<TypesetBook> book, size_t page) = 0;
/// Set the callback for a clicking a hyper-link in the document. /// Set the callback for a clicking a hyper-link in the document.
virtual void adviseLinkClicked(ClickCallback callback) = 0; virtual void adviseLinkClicked(ClickCallback callback) = 0;

View file

@ -62,8 +62,8 @@ namespace MWGui
{ {
// english button has a 7 pixel wide strip of garbage on its right edge // english button has a 7 pixel wide strip of garbage on its right edge
mNextPageButton->setSize(64 - 7, mNextPageButton->getSize().height); mNextPageButton->setSize(64 - 7, mNextPageButton->getSize().height);
mNextPageButton->setImageCoord( mNextPageButton->setImageCoord(MyGUI::IntCoord(
MyGUI::IntCoord(0, 0, (64 - 7) * scale, mNextPageButton->getSize().height * scale)); 0, 0, static_cast<int>((64 - 7) * scale), static_cast<int>(mNextPageButton->getSize().height * scale)));
} }
mControllerButtons.mL1 = "#{Interface:Prev}"; mControllerButtons.mL1 = "#{Interface:Prev}";

View file

@ -151,13 +151,14 @@ namespace MWGui
mReviewDialog->onFrame(duration); mReviewDialog->onFrame(duration);
} }
void CharacterCreation::spawnDialog(const char id) void CharacterCreation::spawnDialog(const GuiMode id)
{ {
try try
{ {
switch (id) switch (id)
{ {
case GM_Name: case GM_Name:
{
MWBase::Environment::get().getWindowManager()->removeDialog(std::move(mNameDialog)); MWBase::Environment::get().getWindowManager()->removeDialog(std::move(mNameDialog));
mNameDialog = std::make_unique<TextInputDialog>(); mNameDialog = std::make_unique<TextInputDialog>();
mNameDialog->setTextLabel( mNameDialog->setTextLabel(
@ -167,8 +168,9 @@ namespace MWGui
mNameDialog->eventDone += MyGUI::newDelegate(this, &CharacterCreation::onNameDialogDone); mNameDialog->eventDone += MyGUI::newDelegate(this, &CharacterCreation::onNameDialogDone);
mNameDialog->setVisible(true); mNameDialog->setVisible(true);
break; break;
}
case GM_Race: case GM_Race:
{
MWBase::Environment::get().getWindowManager()->removeDialog(std::move(mRaceDialog)); MWBase::Environment::get().getWindowManager()->removeDialog(std::move(mRaceDialog));
mRaceDialog = std::make_unique<RaceDialog>(mParent, mResourceSystem); mRaceDialog = std::make_unique<RaceDialog>(mParent, mResourceSystem);
mRaceDialog->setNextButtonShow(mCreationStage >= CSE_RaceChosen); mRaceDialog->setNextButtonShow(mCreationStage >= CSE_RaceChosen);
@ -179,8 +181,9 @@ namespace MWGui
if (mCreationStage < CSE_NameChosen) if (mCreationStage < CSE_NameChosen)
mCreationStage = CSE_NameChosen; mCreationStage = CSE_NameChosen;
break; break;
}
case GM_Class: case GM_Class:
{
MWBase::Environment::get().getWindowManager()->removeDialog(std::move(mClassChoiceDialog)); MWBase::Environment::get().getWindowManager()->removeDialog(std::move(mClassChoiceDialog));
mClassChoiceDialog = std::make_unique<ClassChoiceDialog>(); mClassChoiceDialog = std::make_unique<ClassChoiceDialog>();
mClassChoiceDialog->eventButtonSelected mClassChoiceDialog->eventButtonSelected
@ -189,8 +192,9 @@ namespace MWGui
if (mCreationStage < CSE_RaceChosen) if (mCreationStage < CSE_RaceChosen)
mCreationStage = CSE_RaceChosen; mCreationStage = CSE_RaceChosen;
break; break;
}
case GM_ClassPick: case GM_ClassPick:
{
MWBase::Environment::get().getWindowManager()->removeDialog(std::move(mPickClassDialog)); MWBase::Environment::get().getWindowManager()->removeDialog(std::move(mPickClassDialog));
mPickClassDialog = std::make_unique<PickClassDialog>(); mPickClassDialog = std::make_unique<PickClassDialog>();
mPickClassDialog->setNextButtonShow(mCreationStage >= CSE_ClassChosen); mPickClassDialog->setNextButtonShow(mCreationStage >= CSE_ClassChosen);
@ -201,8 +205,9 @@ namespace MWGui
if (mCreationStage < CSE_RaceChosen) if (mCreationStage < CSE_RaceChosen)
mCreationStage = CSE_RaceChosen; mCreationStage = CSE_RaceChosen;
break; break;
}
case GM_Birth: case GM_Birth:
{
MWBase::Environment::get().getWindowManager()->removeDialog(std::move(mBirthSignDialog)); MWBase::Environment::get().getWindowManager()->removeDialog(std::move(mBirthSignDialog));
mBirthSignDialog = std::make_unique<BirthDialog>(); mBirthSignDialog = std::make_unique<BirthDialog>();
mBirthSignDialog->setNextButtonShow(mCreationStage >= CSE_BirthSignChosen); mBirthSignDialog->setNextButtonShow(mCreationStage >= CSE_BirthSignChosen);
@ -213,8 +218,9 @@ namespace MWGui
if (mCreationStage < CSE_ClassChosen) if (mCreationStage < CSE_ClassChosen)
mCreationStage = CSE_ClassChosen; mCreationStage = CSE_ClassChosen;
break; break;
}
case GM_ClassCreate: case GM_ClassCreate:
{
if (mCreateClassDialog == nullptr) if (mCreateClassDialog == nullptr)
{ {
mCreateClassDialog = std::make_unique<CreateClassDialog>(); mCreateClassDialog = std::make_unique<CreateClassDialog>();
@ -228,7 +234,9 @@ namespace MWGui
if (mCreationStage < CSE_RaceChosen) if (mCreationStage < CSE_RaceChosen)
mCreationStage = CSE_RaceChosen; mCreationStage = CSE_RaceChosen;
break; break;
}
case GM_ClassGenerate: case GM_ClassGenerate:
{
mGenerateClassStep = 0; mGenerateClassStep = 0;
mGenerateClass = ESM::RefId(); mGenerateClass = ESM::RefId();
mGenerateClassSpecializations[0] = 0; mGenerateClassSpecializations[0] = 0;
@ -238,7 +246,9 @@ namespace MWGui
if (mCreationStage < CSE_RaceChosen) if (mCreationStage < CSE_RaceChosen)
mCreationStage = CSE_RaceChosen; mCreationStage = CSE_RaceChosen;
break; break;
}
case GM_Review: case GM_Review:
{
MWBase::Environment::get().getWindowManager()->removeDialog(std::move(mReviewDialog)); MWBase::Environment::get().getWindowManager()->removeDialog(std::move(mReviewDialog));
mReviewDialog = std::make_unique<ReviewDialog>(); mReviewDialog = std::make_unique<ReviewDialog>();
@ -279,6 +289,11 @@ namespace MWGui
if (mCreationStage < CSE_BirthSignChosen) if (mCreationStage < CSE_BirthSignChosen)
mCreationStage = CSE_BirthSignChosen; mCreationStage = CSE_BirthSignChosen;
break; break;
}
default:
{
Log(Debug::Error) << "Unexpected GuiMode in CharacterCreation::spawnDialog: " << id;
}
} }
} }
catch (std::exception& e) catch (std::exception& e)

View file

@ -7,6 +7,7 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
#include "mode.hpp"
#include "statswatcher.hpp" #include "statswatcher.hpp"
namespace osg namespace osg
@ -42,7 +43,7 @@ namespace MWGui
virtual ~CharacterCreation(); virtual ~CharacterCreation();
// Show a dialog // Show a dialog
void spawnDialog(const char id); void spawnDialog(const GuiMode id);
void setAttribute(ESM::RefId id, const MWMechanics::AttributeValue& value) override; void setAttribute(ESM::RefId id, const MWMechanics::AttributeValue& value) override;
void setValue(std::string_view id, const MWMechanics::DynamicStat<float>& value) override; void setValue(std::string_view id, const MWMechanics::DynamicStat<float>& value) override;

View file

@ -129,7 +129,7 @@ namespace MWGui
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++)
{ {
char theIndex = '0' + i; char theIndex = '0' + static_cast<char>(i);
getWidget(mMajorSkill[i], std::string("MajorSkill").append(1, theIndex)); getWidget(mMajorSkill[i], std::string("MajorSkill").append(1, theIndex));
getWidget(mMinorSkill[i], std::string("MinorSkill").append(1, theIndex)); getWidget(mMinorSkill[i], std::string("MinorSkill").append(1, theIndex));
} }
@ -483,7 +483,7 @@ namespace MWGui
return true; return true;
setControllerFocus(mButtons, mControllerFocus, false); setControllerFocus(mButtons, mControllerFocus, false);
mControllerFocus = wrap(mControllerFocus - 1, mButtons.size()); mControllerFocus = wrap(mControllerFocus, mButtons.size(), -1);
setControllerFocus(mButtons, mControllerFocus, true); setControllerFocus(mButtons, mControllerFocus, true);
} }
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_DOWN) else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_DOWN)
@ -494,7 +494,7 @@ namespace MWGui
return true; return true;
setControllerFocus(mButtons, mControllerFocus, false); setControllerFocus(mButtons, mControllerFocus, false);
mControllerFocus = wrap(mControllerFocus + 1, mButtons.size()); mControllerFocus = wrap(mControllerFocus, mButtons.size(), 1);
setControllerFocus(mButtons, mControllerFocus, true); setControllerFocus(mButtons, mControllerFocus, true);
} }
@ -546,7 +546,7 @@ namespace MWGui
"MajorSkillT", MWBase::Environment::get().getWindowManager()->getGameSettingString("sSkillClassMajor", {})); "MajorSkillT", MWBase::Environment::get().getWindowManager()->getGameSettingString("sSkillClassMajor", {}));
setText( setText(
"MinorSkillT", MWBase::Environment::get().getWindowManager()->getGameSettingString("sSkillClassMinor", {})); "MinorSkillT", MWBase::Environment::get().getWindowManager()->getGameSettingString("sSkillClassMinor", {}));
for (int i = 0; i < 5; i++) for (char i = 0; i < 5; i++)
{ {
char theIndex = '0' + i; char theIndex = '0' + i;
getWidget(mMajorSkill[i], std::string("MajorSkill").append(1, theIndex)); getWidget(mMajorSkill[i], std::string("MajorSkill").append(1, theIndex));
@ -713,13 +713,13 @@ namespace MWGui
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_LEFT) else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_LEFT)
{ {
setControllerFocus(mButtons, mControllerFocus, false); setControllerFocus(mButtons, mControllerFocus, false);
mControllerFocus = wrap(mControllerFocus - 1, mButtons.size()); mControllerFocus = wrap(mControllerFocus, mButtons.size(), -1);
setControllerFocus(mButtons, mControllerFocus, true); setControllerFocus(mButtons, mControllerFocus, true);
} }
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_RIGHT) else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_RIGHT)
{ {
setControllerFocus(mButtons, mControllerFocus, false); setControllerFocus(mButtons, mControllerFocus, false);
mControllerFocus = wrap(mControllerFocus + 1, mButtons.size()); mControllerFocus = wrap(mControllerFocus, mButtons.size(), 1);
setControllerFocus(mButtons, mControllerFocus, true); setControllerFocus(mButtons, mControllerFocus, true);
} }
return true; return true;
@ -1001,13 +1001,13 @@ namespace MWGui
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_UP) else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_UP)
{ {
mAttributeButtons[mControllerFocus]->setStateSelected(false); mAttributeButtons[mControllerFocus]->setStateSelected(false);
mControllerFocus = wrap(mControllerFocus - 1, mAttributeButtons.size()); mControllerFocus = wrap(mControllerFocus, mAttributeButtons.size(), -1);
mAttributeButtons[mControllerFocus]->setStateSelected(true); mAttributeButtons[mControllerFocus]->setStateSelected(true);
} }
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_DOWN) else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_DOWN)
{ {
mAttributeButtons[mControllerFocus]->setStateSelected(false); mAttributeButtons[mControllerFocus]->setStateSelected(false);
mControllerFocus = wrap(mControllerFocus + 1, mAttributeButtons.size()); mControllerFocus = wrap(mControllerFocus, mAttributeButtons.size(), 1);
mAttributeButtons[mControllerFocus]->setStateSelected(true); mAttributeButtons[mControllerFocus]->setStateSelected(true);
} }
@ -1103,13 +1103,13 @@ namespace MWGui
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_UP) else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_UP)
{ {
mSkillButtons[mControllerFocus]->setStateSelected(false); mSkillButtons[mControllerFocus]->setStateSelected(false);
mControllerFocus = wrap(mControllerFocus - 1, mSkillButtons.size()); mControllerFocus = wrap(mControllerFocus, mSkillButtons.size(), -1);
mSkillButtons[mControllerFocus]->setStateSelected(true); mSkillButtons[mControllerFocus]->setStateSelected(true);
} }
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_DOWN) else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_DOWN)
{ {
mSkillButtons[mControllerFocus]->setStateSelected(false); mSkillButtons[mControllerFocus]->setStateSelected(false);
mControllerFocus = wrap(mControllerFocus + 1, mSkillButtons.size()); mControllerFocus = wrap(mControllerFocus, mSkillButtons.size(), 1);
mSkillButtons[mControllerFocus]->setStateSelected(true); mSkillButtons[mControllerFocus]->setStateSelected(true);
} }
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_LEFT || arg.button == SDL_CONTROLLER_BUTTON_DPAD_RIGHT) else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_LEFT || arg.button == SDL_CONTROLLER_BUTTON_DPAD_RIGHT)

View file

@ -28,7 +28,7 @@ namespace MWGui
MWWorld::Ptr CompanionItemModel::addItem(const ItemStack& item, size_t count, bool allowAutoEquip) MWWorld::Ptr CompanionItemModel::addItem(const ItemStack& item, size_t count, bool allowAutoEquip)
{ {
if (hasProfit(mActor)) if (hasProfit(mActor))
modifyProfit(mActor, item.mBase.getClass().getValue(item.mBase) * count); modifyProfit(mActor, static_cast<int>(item.mBase.getClass().getValue(item.mBase) * count));
return InventoryItemModel::addItem(item, count, allowAutoEquip); return InventoryItemModel::addItem(item, count, allowAutoEquip);
} }
@ -36,7 +36,7 @@ namespace MWGui
MWWorld::Ptr CompanionItemModel::copyItem(const ItemStack& item, size_t count, bool allowAutoEquip) MWWorld::Ptr CompanionItemModel::copyItem(const ItemStack& item, size_t count, bool allowAutoEquip)
{ {
if (hasProfit(mActor)) if (hasProfit(mActor))
modifyProfit(mActor, item.mBase.getClass().getValue(item.mBase) * count); modifyProfit(mActor, static_cast<int>(item.mBase.getClass().getValue(item.mBase) * count));
return InventoryItemModel::copyItem(item, count, allowAutoEquip); return InventoryItemModel::copyItem(item, count, allowAutoEquip);
} }
@ -44,7 +44,7 @@ namespace MWGui
void CompanionItemModel::removeItem(const ItemStack& item, size_t count) void CompanionItemModel::removeItem(const ItemStack& item, size_t count)
{ {
if (hasProfit(mActor)) if (hasProfit(mActor))
modifyProfit(mActor, -item.mBase.getClass().getValue(item.mBase) * count); modifyProfit(mActor, -static_cast<int>(item.mBase.getClass().getValue(item.mBase) * count));
InventoryItemModel::removeItem(item, count); InventoryItemModel::removeItem(item, count);
} }

View file

@ -89,7 +89,7 @@ namespace MWGui
} }
MWWorld::Ptr object = item.mBase; MWWorld::Ptr object = item.mBase;
int count = item.mCount; size_t count = item.mCount;
bool shift = MyGUI::InputManager::getInstance().isShiftPressed(); bool shift = MyGUI::InputManager::getInstance().isShiftPressed();
if (MyGUI::InputManager::getInstance().isControlPressed()) if (MyGUI::InputManager::getInstance().isControlPressed())
count = 1; count = 1;
@ -101,7 +101,7 @@ namespace MWGui
CountDialog* dialog = MWBase::Environment::get().getWindowManager()->getCountDialog(); CountDialog* dialog = MWBase::Environment::get().getWindowManager()->getCountDialog();
std::string name{ object.getClass().getName(object) }; std::string name{ object.getClass().getName(object) };
name += MWGui::ToolTips::getSoulString(object.getCellRef()); name += MWGui::ToolTips::getSoulString(object.getCellRef());
dialog->openCountDialog(name, "#{sTake}", count); dialog->openCountDialog(name, "#{sTake}", static_cast<int>(count));
dialog->eventOkClicked.clear(); dialog->eventOkClicked.clear();
if (Settings::gui().mControllerMenus || MyGUI::InputManager::getInstance().isAltPressed()) if (Settings::gui().mControllerMenus || MyGUI::InputManager::getInstance().isAltPressed())
dialog->eventOkClicked += MyGUI::newDelegate(this, &CompanionWindow::transferItem); dialog->eventOkClicked += MyGUI::newDelegate(this, &CompanionWindow::transferItem);
@ -174,9 +174,9 @@ namespace MWGui
{ {
if (mPtr.isEmpty()) if (mPtr.isEmpty())
return; return;
float capacity = mPtr.getClass().getCapacity(mPtr); int capacity = static_cast<int>(mPtr.getClass().getCapacity(mPtr));
float encumbrance = mPtr.getClass().getEncumbrance(mPtr); float encumbrance = std::ceil(mPtr.getClass().getEncumbrance(mPtr));
mEncumbranceBar->setValue(std::ceil(encumbrance), static_cast<int>(capacity)); mEncumbranceBar->setValue(static_cast<int>(encumbrance), capacity);
if (mModel && mModel->hasProfit(mPtr)) if (mModel && mModel->hasProfit(mPtr))
{ {

View file

@ -32,6 +32,14 @@
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "../mwworld/esmstore.hpp" #include "../mwworld/esmstore.hpp"
namespace
{
bool isWhitespace(MyGUI::UString::code_point c)
{
return c == ' ' || c == '\t';
}
}
namespace MWGui namespace MWGui
{ {
class ConsoleInterpreterContext : public MWScript::InterpreterContext class ConsoleInterpreterContext : public MWScript::InterpreterContext
@ -275,11 +283,6 @@ namespace MWGui
resetReference(); resetReference();
} }
bool isWhitespace(char c)
{
return c == ' ' || c == '\t';
}
void Console::commandBoxKeyPress(MyGUI::Widget* /*sender*/, MyGUI::KeyCode key, MyGUI::Char /*value*/) void Console::commandBoxKeyPress(MyGUI::Widget* /*sender*/, MyGUI::KeyCode key, MyGUI::Char /*value*/)
{ {
if (MyGUI::InputManager::getInstance().isControlPressed()) if (MyGUI::InputManager::getInstance().isControlPressed())
@ -697,7 +700,7 @@ namespace MWGui
/* Is there still something in the input string? If not just display all commands and return the unchanged /* Is there still something in the input string? If not just display all commands and return the unchanged
* input. */ * input. */
if (tmp.length() == 0) if (tmp.empty())
{ {
matches = mNames; matches = mNames;
return input; return input;
@ -756,10 +759,9 @@ namespace MWGui
} }
/* Check if all matching strings match further than input. If yes complete to this match. */ /* Check if all matching strings match further than input. If yes complete to this match. */
int i = tmp.length(); size_t i = tmp.length();
for (std::string::iterator iter = matches.front().begin() + tmp.length(); iter < matches.front().end(); for (auto iter = matches.front().begin() + tmp.length(); iter < matches.front().end(); ++iter, ++i)
++iter, ++i)
{ {
for (std::string& match : matches) for (std::string& match : matches)
{ {

View file

@ -84,7 +84,7 @@ namespace MWGui
} }
MWWorld::Ptr object = item.mBase; MWWorld::Ptr object = item.mBase;
int count = item.mCount; size_t count = item.mCount;
bool shift = MyGUI::InputManager::getInstance().isShiftPressed(); bool shift = MyGUI::InputManager::getInstance().isShiftPressed();
if (MyGUI::InputManager::getInstance().isControlPressed()) if (MyGUI::InputManager::getInstance().isControlPressed())
count = 1; count = 1;
@ -96,7 +96,7 @@ namespace MWGui
CountDialog* dialog = MWBase::Environment::get().getWindowManager()->getCountDialog(); CountDialog* dialog = MWBase::Environment::get().getWindowManager()->getCountDialog();
std::string name{ object.getClass().getName(object) }; std::string name{ object.getClass().getName(object) };
name += MWGui::ToolTips::getSoulString(object.getCellRef()); name += MWGui::ToolTips::getSoulString(object.getCellRef());
dialog->openCountDialog(name, "#{sTake}", count); dialog->openCountDialog(name, "#{sTake}", static_cast<int>(count));
dialog->eventOkClicked.clear(); dialog->eventOkClicked.clear();
if (Settings::gui().mControllerMenus || MyGUI::InputManager::getInstance().isAltPressed()) if (Settings::gui().mControllerMenus || MyGUI::InputManager::getInstance().isAltPressed())
dialog->eventOkClicked += MyGUI::newDelegate(this, &ContainerWindow::transferItem); dialog->eventOkClicked += MyGUI::newDelegate(this, &ContainerWindow::transferItem);
@ -116,7 +116,7 @@ namespace MWGui
const ItemStack item = mModel->getItem(mSelectedItem); const ItemStack item = mModel->getItem(mSelectedItem);
if (!mModel->onTakeItem(item.mBase, count)) if (!mModel->onTakeItem(item.mBase, static_cast<int>(count)))
return; return;
mDragAndDrop->startDrag(mSelectedItem, mSortModel, mModel, mItemView, count); mDragAndDrop->startDrag(mSelectedItem, mSortModel, mModel, mItemView, count);
@ -129,7 +129,7 @@ namespace MWGui
const ItemStack item = mModel->getItem(mSelectedItem); const ItemStack item = mModel->getItem(mSelectedItem);
if (!mModel->onTakeItem(item.mBase, count)) if (!mModel->onTakeItem(item.mBase, static_cast<int>(count)))
return; return;
mItemTransfer->apply(item, count, *mItemView); mItemTransfer->apply(item, count, *mItemView);
@ -140,7 +140,7 @@ namespace MWGui
if (mModel == nullptr) if (mModel == nullptr)
return; return;
bool success = mModel->onDropItem(mDragAndDrop->mItem.mBase, mDragAndDrop->mDraggedCount); bool success = mModel->onDropItem(mDragAndDrop->mItem.mBase, static_cast<int>(mDragAndDrop->mDraggedCount));
if (success) if (success)
mDragAndDrop->drop(mModel, mItemView); mDragAndDrop->drop(mModel, mItemView);
@ -248,7 +248,7 @@ namespace MWGui
MWWorld::InventoryStore& invStore = mPtr.getClass().getInventoryStore(mPtr); MWWorld::InventoryStore& invStore = mPtr.getClass().getInventoryStore(mPtr);
for (size_t i = 0; i < mModel->getItemCount(); ++i) for (size_t i = 0; i < mModel->getItemCount(); ++i)
{ {
const ItemStack& item = mModel->getItem(i); const ItemStack& item = mModel->getItem(static_cast<ItemModel::ModelIndex>(i));
if (invStore.isEquipped(item.mBase) == false) if (invStore.isEquipped(item.mBase) == false)
continue; continue;
@ -263,14 +263,14 @@ namespace MWGui
if (i == 0) if (i == 0)
{ {
// play the sound of the first object // play the sound of the first object
MWWorld::Ptr item = mModel->getItem(i).mBase; MWWorld::Ptr item = mModel->getItem(static_cast<ItemModel::ModelIndex>(i)).mBase;
const ESM::RefId& sound = item.getClass().getUpSoundId(item); const ESM::RefId& sound = item.getClass().getUpSoundId(item);
MWBase::Environment::get().getWindowManager()->playSound(sound); MWBase::Environment::get().getWindowManager()->playSound(sound);
} }
const ItemStack item = mModel->getItem(i); const ItemStack item = mModel->getItem(static_cast<ItemModel::ModelIndex>(i));
if (!mModel->onTakeItem(item.mBase, item.mCount)) if (!mModel->onTakeItem(item.mBase, static_cast<int>(item.mCount)))
break; break;
mModel->moveItem(item, item.mCount, playerModel); mModel->moveItem(item, item.mCount, playerModel);

View file

@ -90,7 +90,7 @@ namespace MWGui
ItemModel::ModelIndex ContainerItemModel::getIndex(const ItemStack& item) ItemModel::ModelIndex ContainerItemModel::getIndex(const ItemStack& item)
{ {
size_t i = 0; ModelIndex i = 0;
for (ItemStack& itemStack : mItems) for (ItemStack& itemStack : mItems)
{ {
if (itemStack == item) if (itemStack == item)
@ -106,7 +106,7 @@ namespace MWGui
MWWorld::ContainerStore& store = source.first.getClass().getContainerStore(source.first); MWWorld::ContainerStore& store = source.first.getClass().getContainerStore(source.first);
if (item.mBase.getContainerStore() == &store) if (item.mBase.getContainerStore() == &store)
throw std::runtime_error("Item to add needs to be from a different container!"); throw std::runtime_error("Item to add needs to be from a different container!");
return *store.add(item.mBase, count, allowAutoEquip); return *store.add(item.mBase, static_cast<int>(count), allowAutoEquip);
} }
MWWorld::Ptr ContainerItemModel::copyItem(const ItemStack& item, size_t count, bool allowAutoEquip) MWWorld::Ptr ContainerItemModel::copyItem(const ItemStack& item, size_t count, bool allowAutoEquip)
@ -115,13 +115,13 @@ namespace MWGui
MWWorld::ContainerStore& store = source.first.getClass().getContainerStore(source.first); MWWorld::ContainerStore& store = source.first.getClass().getContainerStore(source.first);
if (item.mBase.getContainerStore() == &store) if (item.mBase.getContainerStore() == &store)
throw std::runtime_error("Item to copy needs to be from a different container!"); throw std::runtime_error("Item to copy needs to be from a different container!");
MWWorld::ManualRef newRef(*MWBase::Environment::get().getESMStore(), item.mBase, count); MWWorld::ManualRef newRef(*MWBase::Environment::get().getESMStore(), item.mBase, static_cast<int>(count));
return *store.add(newRef.getPtr(), count, allowAutoEquip); return *store.add(newRef.getPtr(), static_cast<int>(count), allowAutoEquip);
} }
void ContainerItemModel::removeItem(const ItemStack& item, size_t count) void ContainerItemModel::removeItem(const ItemStack& item, size_t count)
{ {
int toRemove = count; int toRemove = static_cast<int>(count);
for (auto& source : mItemSources) for (auto& source : mItemSources)
{ {

View file

@ -93,7 +93,7 @@ namespace MWGui
void CountDialog::onSliderMoved(MyGUI::ScrollBar* sender, size_t position) void CountDialog::onSliderMoved(MyGUI::ScrollBar* sender, size_t position)
{ {
mItemEdit->setValue(position + 1); mItemEdit->setValue(static_cast<int>(position + 1));
} }
bool CountDialog::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) bool CountDialog::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg)

View file

@ -32,8 +32,6 @@
#include "bookpage.hpp" #include "bookpage.hpp"
#include "textcolours.hpp" #include "textcolours.hpp"
#include "journalbooks.hpp" // to_utf8_span
namespace MWGui namespace MWGui
{ {
void ResponseCallback::addResponse(std::string_view title, std::string_view text) void ResponseCallback::addResponse(std::string_view title, std::string_view text)
@ -186,13 +184,13 @@ namespace MWGui
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_UP) else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_UP)
{ {
setControllerFocus(mButtons, mControllerFocus, false); setControllerFocus(mButtons, mControllerFocus, false);
mControllerFocus = wrap(mControllerFocus - 1, mButtons.size()); mControllerFocus = wrap(mControllerFocus, mButtons.size(), -1);
setControllerFocus(mButtons, mControllerFocus, true); setControllerFocus(mButtons, mControllerFocus, true);
} }
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_DOWN) else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_DOWN)
{ {
setControllerFocus(mButtons, mControllerFocus, false); setControllerFocus(mButtons, mControllerFocus, false);
mControllerFocus = wrap(mControllerFocus + 1, mButtons.size()); mControllerFocus = wrap(mControllerFocus, mButtons.size(), 1);
setControllerFocus(mButtons, mControllerFocus, true); setControllerFocus(mButtons, mControllerFocus, true);
} }
@ -208,7 +206,7 @@ namespace MWGui
mText = text; mText = text;
} }
void Response::write(BookTypesetter::Ptr typesetter, KeywordSearchT* keywordSearch, void Response::write(std::shared_ptr<BookTypesetter> typesetter, const TopicSearch& keywordSearch,
std::map<std::string, std::unique_ptr<Link>>& topicLinks) const std::map<std::string, std::unique_ptr<Link>>& topicLinks) const
{ {
typesetter->sectionBreak(mNeedMargin ? 9 : 0); typesetter->sectionBreak(mNeedMargin ? 9 : 0);
@ -218,12 +216,11 @@ namespace MWGui
{ {
const MyGUI::Colour& headerColour = windowManager->getTextColours().header; const MyGUI::Colour& headerColour = windowManager->getTextColours().header;
BookTypesetter::Style* title = typesetter->createStyle({}, headerColour, false); BookTypesetter::Style* title = typesetter->createStyle({}, headerColour, false);
typesetter->write(title, to_utf8_span(mTitle)); typesetter->write(title, mTitle);
typesetter->sectionBreak(); typesetter->sectionBreak();
} }
typedef std::pair<size_t, size_t> Range; std::map<std::pair<size_t, size_t>, const Link*> hyperLinks;
std::map<Range, intptr_t> hyperLinks;
// We need this copy for when @# hyperlinks are replaced // We need this copy for when @# hyperlinks are replaced
std::string text = mText; std::string text = mText;
@ -250,14 +247,13 @@ namespace MWGui
text.replace(posBegin, posEnd + 1 - posBegin, displayName); text.replace(posBegin, posEnd + 1 - posBegin, displayName);
if (topicLinks.find(topicName) != topicLinks.end()) if (topicLinks.find(topicName) != topicLinks.end())
hyperLinks[std::make_pair(posBegin, posBegin + displayName.size())] hyperLinks[std::make_pair(posBegin, posBegin + displayName.size())] = topicLinks[topicName].get();
= intptr_t(topicLinks[topicName].get());
} }
else else
break; break;
} }
typesetter->addContent(to_utf8_span(text)); typesetter->addContent(text);
if (hyperLinks.size() if (hyperLinks.size()
&& MWBase::Environment::get().getWindowManager()->getTranslationDataStorage().hasTranslation()) && MWBase::Environment::get().getWindowManager()->getTranslationDataStorage().hasTranslation())
@ -266,48 +262,48 @@ namespace MWGui
BookTypesetter::Style* style = typesetter->createStyle({}, textColours.normal, false); BookTypesetter::Style* style = typesetter->createStyle({}, textColours.normal, false);
size_t formatted = 0; // points to the first character that is not laid out yet size_t formatted = 0; // points to the first character that is not laid out yet
for (auto& hyperLink : hyperLinks) for (const auto& [range, link] : hyperLinks)
{ {
intptr_t topicId = hyperLink.second; BookTypesetter::Style* hotStyle = typesetter->createHotStyle(style, textColours.link,
BookTypesetter::Style* hotStyle = typesetter->createHotStyle( textColours.linkOver, textColours.linkPressed, TypesetBook::InteractiveId(link));
style, textColours.link, textColours.linkOver, textColours.linkPressed, topicId); if (formatted < range.first)
if (formatted < hyperLink.first.first) typesetter->write(style, formatted, range.first);
typesetter->write(style, formatted, hyperLink.first.first); typesetter->write(hotStyle, range.first, range.second);
typesetter->write(hotStyle, hyperLink.first.first, hyperLink.first.second); formatted = range.second;
formatted = hyperLink.first.second;
} }
if (formatted < text.size()) if (formatted < text.size())
typesetter->write(style, formatted, text.size()); typesetter->write(style, formatted, text.size());
} }
else else
{ {
std::vector<KeywordSearchT::Match> matches; std::vector<TopicSearch::Match> matches;
keywordSearch->highlightKeywords(text.begin(), text.end(), matches); keywordSearch.highlightKeywords(text.begin(), text.end(), matches);
std::string::const_iterator i = text.begin(); std::string::const_iterator i = text.begin();
for (KeywordSearchT::Match& match : matches) for (TopicSearch::Match& match : matches)
{ {
if (i != match.mBeg) if (i != match.mBeg)
addTopicLink(typesetter, 0, i - text.begin(), match.mBeg - text.begin()); addTopicLink(typesetter, nullptr, i - text.begin(), match.mBeg - text.begin());
addTopicLink(typesetter, match.mValue, match.mBeg - text.begin(), match.mEnd - text.begin()); addTopicLink(typesetter, match.mValue, match.mBeg - text.begin(), match.mEnd - text.begin());
i = match.mEnd; i = match.mEnd;
} }
if (i != text.end()) if (i != text.end())
addTopicLink(std::move(typesetter), 0, i - text.begin(), text.size()); addTopicLink(std::move(typesetter), nullptr, i - text.begin(), text.size());
} }
} }
void Response::addTopicLink(BookTypesetter::Ptr typesetter, intptr_t topicId, size_t begin, size_t end) const void Response::addTopicLink(
std::shared_ptr<BookTypesetter> typesetter, const MWGui::Topic* topic, size_t begin, size_t end) const
{ {
const TextColours& textColours = MWBase::Environment::get().getWindowManager()->getTextColours(); const TextColours& textColours = MWBase::Environment::get().getWindowManager()->getTextColours();
BookTypesetter::Style* style = typesetter->createStyle({}, textColours.normal, false); BookTypesetter::Style* style = typesetter->createStyle({}, textColours.normal, false);
if (topicId) if (topic)
style = typesetter->createHotStyle( style = typesetter->createHotStyle(style, textColours.link, textColours.linkOver, textColours.linkPressed,
style, textColours.link, textColours.linkOver, textColours.linkPressed, topicId); TypesetBook::InteractiveId(topic));
typesetter->write(style, begin, end); typesetter->write(style, begin, end);
} }
@ -316,13 +312,13 @@ namespace MWGui
mText = text; mText = text;
} }
void Message::write(BookTypesetter::Ptr typesetter, KeywordSearchT* keywordSearch, void Message::write(std::shared_ptr<BookTypesetter> typesetter, const TopicSearch&,
std::map<std::string, std::unique_ptr<Link>>& topicLinks) const std::map<std::string, std::unique_ptr<Link>>&) const
{ {
const MyGUI::Colour& textColour = MWBase::Environment::get().getWindowManager()->getTextColours().notify; const MyGUI::Colour& textColour = MWBase::Environment::get().getWindowManager()->getTextColours().notify;
BookTypesetter::Style* title = typesetter->createStyle({}, textColour, false); BookTypesetter::Style* title = typesetter->createStyle({}, textColour, false);
typesetter->sectionBreak(9); typesetter->sectionBreak(9);
typesetter->write(title, to_utf8_span(mText)); typesetter->write(title, mText);
} }
// -------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------
@ -428,8 +424,8 @@ namespace MWGui
{ {
if (!mScrollBar->getVisible()) if (!mScrollBar->getVisible())
return; return;
mScrollBar->setScrollPosition( mScrollBar->setScrollPosition(std::clamp<size_t>(
std::clamp<int>(mScrollBar->getScrollPosition() - rel * 0.3, 0, mScrollBar->getScrollRange() - 1)); static_cast<size_t>(mScrollBar->getScrollPosition() - rel * 0.3), 0, mScrollBar->getScrollRange() - 1));
onScrollbarMoved(mScrollBar, mScrollBar->getScrollPosition()); onScrollbarMoved(mScrollBar, mScrollBar->getScrollPosition());
} }
@ -441,7 +437,7 @@ namespace MWGui
} }
} }
void DialogueWindow::onSelectListItem(const std::string& topic, int id) void DialogueWindow::onSelectListItem(const std::string& topic, int /*id*/)
{ {
MWBase::DialogueManager* dialogueManager = MWBase::Environment::get().getDialogueManager(); MWBase::DialogueManager* dialogueManager = MWBase::Environment::get().getDialogueManager();
@ -607,7 +603,7 @@ namespace MWGui
void DialogueWindow::updateTopicsPane() void DialogueWindow::updateTopicsPane()
{ {
std::string focusedTopic; std::string focusedTopic;
if (Settings::gui().mControllerMenus && mControllerFocus < static_cast<int>(mTopicsList->getItemCount())) if (Settings::gui().mControllerMenus && mControllerFocus < mTopicsList->getItemCount())
focusedTopic = mTopicsList->getItemNameAt(mControllerFocus); focusedTopic = mTopicsList->getItemNameAt(mControllerFocus);
mTopicsList->clear(); mTopicsList->clear();
@ -661,7 +657,7 @@ namespace MWGui
mTopicsList->addItem(keyword, sVerticalPadding); mTopicsList->addItem(keyword, sVerticalPadding);
auto t = std::make_unique<Topic>(keyword); auto t = std::make_unique<Topic>(keyword);
mKeywordSearch.seed(topicId, intptr_t(t.get())); mKeywordSearch.seed(topicId, t.get());
t->eventTopicActivated += MyGUI::newDelegate(this, &DialogueWindow::onTopicActivated); t->eventTopicActivated += MyGUI::newDelegate(this, &DialogueWindow::onTopicActivated);
mTopicLinks[topicId] = std::move(t); mTopicLinks[topicId] = std::move(t);
@ -689,10 +685,11 @@ namespace MWGui
mScrollBar->setVisible(true); mScrollBar->setVisible(true);
} }
BookTypesetter::Ptr typesetter = BookTypesetter::create(mHistory->getWidth(), std::numeric_limits<int>::max()); std::shared_ptr<BookTypesetter> typesetter
= BookTypesetter::create(mHistory->getWidth(), std::numeric_limits<int>::max());
for (const auto& text : mHistoryContents) for (const auto& text : mHistoryContents)
text->write(typesetter, &mKeywordSearch, mTopicLinks); text->write(typesetter, mKeywordSearch, mTopicLinks);
BookTypesetter::Style* body = typesetter->createStyle({}, MyGUI::Colour::White, false); BookTypesetter::Style* body = typesetter->createStyle({}, MyGUI::Colour::White, false);
@ -712,7 +709,7 @@ namespace MWGui
typesetter->lineBreak(); typesetter->lineBreak();
BookTypesetter::Style* questionStyle = typesetter->createHotStyle( BookTypesetter::Style* questionStyle = typesetter->createHotStyle(
body, textColours.answer, textColours.answerOver, textColours.answerPressed, interactiveId); body, textColours.answer, textColours.answerOver, textColours.answerPressed, interactiveId);
typesetter->write(questionStyle, to_utf8_span(choice.first)); typesetter->write(questionStyle, choice.first);
mChoiceStyles.push_back(questionStyle); mChoiceStyles.push_back(questionStyle);
} }
@ -731,10 +728,10 @@ namespace MWGui
BookTypesetter::Style* questionStyle = typesetter->createHotStyle( BookTypesetter::Style* questionStyle = typesetter->createHotStyle(
body, textColours.answer, textColours.answerOver, textColours.answerPressed, interactiveId); body, textColours.answer, textColours.answerOver, textColours.answerPressed, interactiveId);
typesetter->lineBreak(); typesetter->lineBreak();
typesetter->write(questionStyle, to_utf8_span(goodbye)); typesetter->write(questionStyle, goodbye);
} }
TypesetBook::Ptr book = typesetter->complete(); std::shared_ptr<TypesetBook> book = typesetter->complete();
mHistory->showPage(book, 0); mHistory->showPage(book, 0);
size_t viewHeight = mHistory->getParent()->getHeight(); size_t viewHeight = mHistory->getParent()->getHeight();
if (!scrollbar && book->getSize().second > viewHeight) if (!scrollbar && book->getSize().second > viewHeight)
@ -970,10 +967,10 @@ namespace MWGui
else if (mControllerChoice >= 0 && mControllerChoice < static_cast<int>(mChoices.size())) else if (mControllerChoice >= 0 && mControllerChoice < static_cast<int>(mChoices.size()))
onChoiceActivated(mChoices[mControllerChoice].second); onChoiceActivated(mChoices[mControllerChoice].second);
} }
else if (mControllerFocus == static_cast<int>(mTopicsList->getItemCount())) else if (mControllerFocus == mTopicsList->getItemCount())
onGoodbyeActivated(); onGoodbyeActivated();
else else
onSelectListItem(mTopicsList->getItemNameAt(mControllerFocus), mControllerFocus); onSelectListItem(mTopicsList->getItemNameAt(mControllerFocus), static_cast<int>(mControllerFocus));
MWBase::Environment::get().getWindowManager()->playSound(ESM::RefId::stringRefId("Menu Click")); MWBase::Environment::get().getWindowManager()->playSound(ESM::RefId::stringRefId("Menu Click"));
} }
else if (arg.button == SDL_CONTROLLER_BUTTON_B && mChoices.empty()) else if (arg.button == SDL_CONTROLLER_BUTTON_B && mChoices.empty())
@ -1013,9 +1010,9 @@ namespace MWGui
{ {
// Number of items is mTopicsList.length+1 because of "Goodbye" button. // Number of items is mTopicsList.length+1 because of "Goodbye" button.
setControllerFocus(mControllerFocus, false); setControllerFocus(mControllerFocus, false);
if (mControllerFocus >= static_cast<int>(mTopicsList->getItemCount())) if (mControllerFocus >= mTopicsList->getItemCount())
mControllerFocus = 0; mControllerFocus = 0;
else if (mControllerFocus == static_cast<int>(mTopicsList->getItemCount()) - 1) else if (mControllerFocus == mTopicsList->getItemCount() - 1)
mControllerFocus = mTopicsList->getItemCount(); // "Goodbye" button mControllerFocus = mTopicsList->getItemCount(); // "Goodbye" button
else if (mTopicsList->getItemNameAt(mControllerFocus + 1).empty()) else if (mTopicsList->getItemNameAt(mControllerFocus + 1).empty())
mControllerFocus += 2; // Skip separator mControllerFocus += 2; // Skip separator
@ -1027,13 +1024,13 @@ namespace MWGui
else if (arg.button == SDL_CONTROLLER_BUTTON_LEFTSHOULDER && mChoices.size() == 0) else if (arg.button == SDL_CONTROLLER_BUTTON_LEFTSHOULDER && mChoices.size() == 0)
{ {
setControllerFocus(mControllerFocus, false); setControllerFocus(mControllerFocus, false);
mControllerFocus = std::max(mControllerFocus - 5, 0); mControllerFocus = mControllerFocus > 5 ? mControllerFocus - 5 : 0;
setControllerFocus(mControllerFocus, true); setControllerFocus(mControllerFocus, true);
} }
else if (arg.button == SDL_CONTROLLER_BUTTON_RIGHTSHOULDER && mChoices.size() == 0) else if (arg.button == SDL_CONTROLLER_BUTTON_RIGHTSHOULDER && mChoices.size() == 0)
{ {
setControllerFocus(mControllerFocus, false); setControllerFocus(mControllerFocus, false);
mControllerFocus = std::min(mControllerFocus + 5, static_cast<int>(mTopicsList->getItemCount())); mControllerFocus = std::min(mControllerFocus + 5, mTopicsList->getItemCount());
setControllerFocus(mControllerFocus, true); setControllerFocus(mControllerFocus, true);
} }

View file

@ -69,7 +69,7 @@ namespace MWGui
Gui::AutoSizedTextBox* mGoldLabel; Gui::AutoSizedTextBox* mGoldLabel;
std::vector<MyGUI::Button*> mButtons; std::vector<MyGUI::Button*> mButtons;
int mControllerFocus = 0; size_t mControllerFocus = 0;
void adjustAction(MyGUI::Widget* action, int& totalHeight); void adjustAction(MyGUI::Widget* action, int& totalHeight);
@ -79,14 +79,13 @@ namespace MWGui
struct Link struct Link
{ {
virtual ~Link() {} virtual ~Link() = default;
virtual void activated() = 0; virtual void activated() = 0;
}; };
struct Topic : Link struct Topic : Link
{ {
typedef MyGUI::delegates::MultiDelegate<const std::string&> EventHandle_TopicId; MyGUI::delegates::MultiDelegate<const std::string&> eventTopicActivated;
EventHandle_TopicId eventTopicActivated;
Topic(const std::string& id) Topic(const std::string& id)
: mTopicId(id) : mTopicId(id)
{ {
@ -97,8 +96,7 @@ namespace MWGui
struct Choice : Link struct Choice : Link
{ {
typedef MyGUI::delegates::MultiDelegate<int> EventHandle_ChoiceId; MyGUI::delegates::MultiDelegate<int> eventChoiceActivated;
EventHandle_ChoiceId eventChoiceActivated;
Choice(int id) Choice(int id)
: mChoiceId(id) : mChoiceId(id)
{ {
@ -109,17 +107,16 @@ namespace MWGui
struct Goodbye : Link struct Goodbye : Link
{ {
typedef MyGUI::delegates::MultiDelegate<> Event_Activated; MyGUI::delegates::MultiDelegate<> eventActivated;
Event_Activated eventActivated;
void activated() override; void activated() override;
}; };
typedef MWDialogue::KeywordSearch<intptr_t> KeywordSearchT; using TopicSearch = MWDialogue::KeywordSearch<const Topic*>;
struct DialogueText struct DialogueText
{ {
virtual ~DialogueText() = default; virtual ~DialogueText() = default;
virtual void write(BookTypesetter::Ptr typesetter, KeywordSearchT* keywordSearch, virtual void write(std::shared_ptr<BookTypesetter> typesetter, const TopicSearch& keywordSearch,
std::map<std::string, std::unique_ptr<Link>>& topicLinks) const = 0; std::map<std::string, std::unique_ptr<Link>>& topicLinks) const = 0;
std::string mText; std::string mText;
}; };
@ -127,9 +124,10 @@ namespace MWGui
struct Response : DialogueText struct Response : DialogueText
{ {
Response(std::string_view text, std::string_view title = {}, bool needMargin = true); Response(std::string_view text, std::string_view title = {}, bool needMargin = true);
void write(BookTypesetter::Ptr typesetter, KeywordSearchT* keywordSearch, void write(std::shared_ptr<BookTypesetter> typesetter, const TopicSearch& keywordSearch,
std::map<std::string, std::unique_ptr<Link>>& topicLinks) const override; std::map<std::string, std::unique_ptr<Link>>& topicLinks) const override;
void addTopicLink(BookTypesetter::Ptr typesetter, intptr_t topicId, size_t begin, size_t end) const; void addTopicLink(
std::shared_ptr<BookTypesetter> typesetter, const Topic* topic, size_t begin, size_t end) const;
std::string mTitle; std::string mTitle;
bool mNeedMargin; bool mNeedMargin;
}; };
@ -137,7 +135,7 @@ namespace MWGui
struct Message : DialogueText struct Message : DialogueText
{ {
Message(std::string_view text); Message(std::string_view text);
void write(BookTypesetter::Ptr typesetter, KeywordSearchT* keywordSearch, void write(std::shared_ptr<BookTypesetter> typesetter, const TopicSearch& keywordSearch,
std::map<std::string, std::unique_ptr<Link>>& topicLinks) const override; std::map<std::string, std::unique_ptr<Link>>& topicLinks) const override;
}; };
@ -150,9 +148,6 @@ namespace MWGui
bool exit() override; bool exit() override;
// Events
typedef MyGUI::delegates::MultiDelegate<> EventHandle_Void;
void notifyLinkClicked(TypesetBook::InteractiveId link); void notifyLinkClicked(TypesetBook::InteractiveId link);
void setPtr(const MWWorld::Ptr& actor) override; void setPtr(const MWWorld::Ptr& actor) override;
@ -213,7 +208,7 @@ namespace MWGui
std::vector<std::unique_ptr<Link>> mDeleteLater; std::vector<std::unique_ptr<Link>> mDeleteLater;
KeywordSearchT mKeywordSearch; TopicSearch mKeywordSearch;
BookPage* mHistory; BookPage* mHistory;
Gui::MWList* mTopicsList; Gui::MWList* mTopicsList;
@ -230,7 +225,7 @@ namespace MWGui
std::unique_ptr<ResponseCallback> mGreetingCallback; std::unique_ptr<ResponseCallback> mGreetingCallback;
void setControllerFocus(size_t index, bool focused); void setControllerFocus(size_t index, bool focused);
int mControllerFocus = 0; size_t mControllerFocus = 0;
int mControllerChoice = -1; int mControllerChoice = -1;
void updateTopicFormat(); void updateTopicFormat();

View file

@ -48,9 +48,9 @@ namespace MWGui
ItemModel::ModelIndex newIndex = -1; ItemModel::ModelIndex newIndex = -1;
for (size_t i = 0; i < playerModel->getItemCount(); ++i) for (size_t i = 0; i < playerModel->getItemCount(); ++i)
{ {
if (playerModel->getItem(i).mBase == item) if (playerModel->getItem(static_cast<ItemModel::ModelIndex>(i)).mBase == item)
{ {
newIndex = i; newIndex = static_cast<ItemModel::ModelIndex>(i);
break; break;
} }
} }
@ -82,7 +82,7 @@ namespace MWGui
mDraggedWidget->setItem(mItem.mBase); mDraggedWidget->setItem(mItem.mBase);
mDraggedWidget->setNeedMouseFocus(false); mDraggedWidget->setNeedMouseFocus(false);
mDraggedWidget->setCount(count); mDraggedWidget->setCount(static_cast<int>(count));
MWBase::Environment::get().getWindowManager()->setDragDrop(true); MWBase::Environment::get().getWindowManager()->setDragDrop(true);
@ -134,7 +134,7 @@ namespace MWGui
mItem.mCount = count; mItem.mCount = count;
mDraggedCount = count; mDraggedCount = count;
mDraggedWidget->setCount(mDraggedCount); mDraggedWidget->setCount(static_cast<int>(mDraggedCount));
mSourceSortModel->clearDragItems(); mSourceSortModel->clearDragItems();
mSourceSortModel->addDragItem(mItem.mBase, mDraggedCount); mSourceSortModel->addDragItem(mItem.mBase, mDraggedCount);
} }

View file

@ -349,7 +349,7 @@ namespace MWGui
if (mIsDrowning) if (mIsDrowning)
{ {
mDrowningFlashTheta += dt * osg::PI * 2; mDrowningFlashTheta += dt * osg::PIf * 2;
float intensity = (cos(mDrowningFlashTheta) + 2.0f) / 3.0f; float intensity = (cos(mDrowningFlashTheta) + 2.0f) / 3.0f;

View file

@ -37,7 +37,7 @@ namespace MWGui
ItemModel::ModelIndex InventoryItemModel::getIndex(const ItemStack& item) ItemModel::ModelIndex InventoryItemModel::getIndex(const ItemStack& item)
{ {
size_t i = 0; ModelIndex i = 0;
for (ItemStack& itemStack : mItems) for (ItemStack& itemStack : mItems)
{ {
if (itemStack == item) if (itemStack == item)
@ -51,7 +51,7 @@ namespace MWGui
{ {
if (item.mBase.getContainerStore() == &mActor.getClass().getContainerStore(mActor)) if (item.mBase.getContainerStore() == &mActor.getClass().getContainerStore(mActor))
throw std::runtime_error("Item to add needs to be from a different container!"); throw std::runtime_error("Item to add needs to be from a different container!");
return *mActor.getClass().getContainerStore(mActor).add(item.mBase, count, allowAutoEquip); return *mActor.getClass().getContainerStore(mActor).add(item.mBase, static_cast<int>(count), allowAutoEquip);
} }
MWWorld::Ptr InventoryItemModel::copyItem(const ItemStack& item, size_t count, bool allowAutoEquip) MWWorld::Ptr InventoryItemModel::copyItem(const ItemStack& item, size_t count, bool allowAutoEquip)
@ -59,8 +59,9 @@ namespace MWGui
if (item.mBase.getContainerStore() == &mActor.getClass().getContainerStore(mActor)) if (item.mBase.getContainerStore() == &mActor.getClass().getContainerStore(mActor))
throw std::runtime_error("Item to copy needs to be from a different container!"); throw std::runtime_error("Item to copy needs to be from a different container!");
MWWorld::ManualRef newRef(*MWBase::Environment::get().getESMStore(), item.mBase, count); MWWorld::ManualRef newRef(*MWBase::Environment::get().getESMStore(), item.mBase, static_cast<int>(count));
return *mActor.getClass().getContainerStore(mActor).add(newRef.getPtr(), count, allowAutoEquip); return *mActor.getClass().getContainerStore(mActor).add(
newRef.getPtr(), static_cast<int>(count), allowAutoEquip);
} }
void InventoryItemModel::removeItem(const ItemStack& item, size_t count) void InventoryItemModel::removeItem(const ItemStack& item, size_t count)
@ -70,12 +71,12 @@ namespace MWGui
if (mActor.getClass().hasInventoryStore(mActor)) if (mActor.getClass().hasInventoryStore(mActor))
{ {
MWWorld::InventoryStore& store = mActor.getClass().getInventoryStore(mActor); MWWorld::InventoryStore& store = mActor.getClass().getInventoryStore(mActor);
removed = store.remove(item.mBase, count, true); removed = store.remove(item.mBase, static_cast<int>(count), true);
} }
else else
{ {
MWWorld::ContainerStore& store = mActor.getClass().getContainerStore(mActor); MWWorld::ContainerStore& store = mActor.getClass().getContainerStore(mActor);
removed = store.remove(item.mBase, count); removed = store.remove(item.mBase, static_cast<int>(count));
} }
std::stringstream error; std::stringstream error;

View file

@ -14,9 +14,9 @@ namespace MWGui
: WindowBase("openmw_inventory_tabs.layout") : WindowBase("openmw_inventory_tabs.layout")
{ {
MyGUI::Button* tab; MyGUI::Button* tab;
static const char* kTabIds[] = { "TabMap", "TabInventory", "TabSpells", "TabStats" }; constexpr std::string_view kTabIds[] = { "TabMap", "TabInventory", "TabSpells", "TabStats" };
for (const char* id : kTabIds) for (const std::string_view id : kTabIds)
{ {
getWidget(tab, id); getWidget(tab, id);
tab->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryTabsOverlay::onTabClicked); tab->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryTabsOverlay::onTabClicked);
@ -44,7 +44,7 @@ namespace MWGui
if (!MWBase::Environment::get().getWindowManager()->getJournalAllowed()) if (!MWBase::Environment::get().getWindowManager()->getJournalAllowed())
return; return;
for (int i = 0; i < static_cast<int>(mTabs.size()); i++) for (size_t i = 0; i < mTabs.size(); ++i)
{ {
if (mTabs[i] == sender) if (mTabs[i] == sender)
{ {
@ -55,9 +55,9 @@ namespace MWGui
} }
} }
void InventoryTabsOverlay::setTab(int index) void InventoryTabsOverlay::setTab(size_t index)
{ {
for (int i = 0; i < static_cast<int>(mTabs.size()); i++) for (size_t i = 0; i < mTabs.size(); ++i)
mTabs[i]->setStateSelected(i == index); mTabs[i]->setStateSelected(i == index);
} }
} }

View file

@ -16,7 +16,7 @@ namespace MWGui
InventoryTabsOverlay(); InventoryTabsOverlay();
int getHeight(); int getHeight();
void setTab(int index); void setTab(size_t index);
private: private:
std::vector<MyGUI::Button*> mTabs; std::vector<MyGUI::Button*> mTabs;

View file

@ -218,10 +218,10 @@ namespace MWGui
const WindowRectSettingValues& rect = settings.mIsMaximized ? settings.mRegular : settings.mMaximized; const WindowRectSettingValues& rect = settings.mIsMaximized ? settings.mRegular : settings.mMaximized;
MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize(); MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize();
const float x = rect.mX * viewSize.width; const int x = static_cast<int>(rect.mX * viewSize.width);
const float y = rect.mY * viewSize.height; const int y = static_cast<int>(rect.mY * viewSize.height);
const float w = rect.mW * viewSize.width; const int w = static_cast<int>(rect.mW * viewSize.width);
const float h = rect.mH * viewSize.height; const int h = static_cast<int>(rect.mH * viewSize.height);
MyGUI::Window* window = mMainWidget->castType<MyGUI::Window>(); MyGUI::Window* window = mMainWidget->castType<MyGUI::Window>();
window->setCoord(x, y, w, h); window->setCoord(x, y, w, h);
@ -296,7 +296,7 @@ namespace MWGui
const ESM::RefId& sound = item.mBase.getClass().getDownSoundId(item.mBase); const ESM::RefId& sound = item.mBase.getClass().getDownSoundId(item.mBase);
MWWorld::Ptr object = item.mBase; MWWorld::Ptr object = item.mBase;
int count = item.mCount; size_t count = item.mCount;
bool shift = MyGUI::InputManager::getInstance().isShiftPressed(); bool shift = MyGUI::InputManager::getInstance().isShiftPressed();
if (MyGUI::InputManager::getInstance().isControlPressed()) if (MyGUI::InputManager::getInstance().isControlPressed())
@ -347,7 +347,7 @@ namespace MWGui
message = "#{sDrop}"; message = "#{sDrop}";
std::string name{ object.getClass().getName(object) }; std::string name{ object.getClass().getName(object) };
name += MWGui::ToolTips::getSoulString(object.getCellRef()); name += MWGui::ToolTips::getSoulString(object.getCellRef());
dialog->openCountDialog(name, message, count); dialog->openCountDialog(name, message, static_cast<int>(count));
dialog->eventOkClicked.clear(); dialog->eventOkClicked.clear();
if (mTrading || mPendingControllerAction == ControllerAction::Sell) if (mTrading || mPendingControllerAction == ControllerAction::Sell)
dialog->eventOkClicked += MyGUI::newDelegate(this, &InventoryWindow::sellItem); dialog->eventOkClicked += MyGUI::newDelegate(this, &InventoryWindow::sellItem);
@ -414,9 +414,9 @@ namespace MWGui
int newIndex = -1; int newIndex = -1;
for (size_t i = 0; i < mTradeModel->getItemCount(); ++i) for (size_t i = 0; i < mTradeModel->getItemCount(); ++i)
{ {
if (mTradeModel->getItem(i).mBase == newStack) if (mTradeModel->getItem(static_cast<ItemModel::ModelIndex>(i)).mBase == newStack)
{ {
newIndex = i; newIndex = static_cast<int>(i);
break; break;
} }
} }
@ -431,21 +431,21 @@ namespace MWGui
void InventoryWindow::dragItem(MyGUI::Widget* /*sender*/, std::size_t count) void InventoryWindow::dragItem(MyGUI::Widget* /*sender*/, std::size_t count)
{ {
ensureSelectedItemUnequipped(count); ensureSelectedItemUnequipped(static_cast<int>(count));
mDragAndDrop->startDrag(mSelectedItem, mSortModel, mTradeModel, mItemView, count); mDragAndDrop->startDrag(mSelectedItem, mSortModel, mTradeModel, mItemView, count);
notifyContentChanged(); notifyContentChanged();
} }
void InventoryWindow::transferItem(MyGUI::Widget* /*sender*/, std::size_t count) void InventoryWindow::transferItem(MyGUI::Widget* /*sender*/, std::size_t count)
{ {
ensureSelectedItemUnequipped(count); ensureSelectedItemUnequipped(static_cast<int>(count));
mItemTransfer->apply(mTradeModel->getItem(mSelectedItem), count, *mItemView); mItemTransfer->apply(mTradeModel->getItem(mSelectedItem), count, *mItemView);
notifyContentChanged(); notifyContentChanged();
} }
void InventoryWindow::sellItem(MyGUI::Widget* /*sender*/, std::size_t count) void InventoryWindow::sellItem(MyGUI::Widget* /*sender*/, std::size_t count)
{ {
ensureSelectedItemUnequipped(count); ensureSelectedItemUnequipped(static_cast<int>(count));
const ItemStack& item = mTradeModel->getItem(mSelectedItem); const ItemStack& item = mTradeModel->getItem(mSelectedItem);
const ESM::RefId& sound = item.mBase.getClass().getUpSoundId(item.mBase); const ESM::RefId& sound = item.mBase.getClass().getUpSoundId(item.mBase);
MWBase::Environment::get().getWindowManager()->playSound(sound); MWBase::Environment::get().getWindowManager()->playSound(sound);
@ -652,7 +652,7 @@ namespace MWGui
MWWorld::InventoryStore& invStore = mPtr.getClass().getInventoryStore(mPtr); MWWorld::InventoryStore& invStore = mPtr.getClass().getInventoryStore(mPtr);
auto [eqSlots, canStack] = ptr.getClass().getEquipmentSlots(ptr); auto [eqSlots, canStack] = ptr.getClass().getEquipmentSlots(ptr);
int useCount = isFromDragAndDrop ? mDragAndDrop->mDraggedCount : ptr.getCellRef().getCount(); int useCount = isFromDragAndDrop ? static_cast<int>(mDragAndDrop->mDraggedCount) : ptr.getCellRef().getCount();
if (!eqSlots.empty()) if (!eqSlots.empty())
{ {
@ -714,9 +714,9 @@ namespace MWGui
for (size_t i = 0; i < mTradeModel->getItemCount(); ++i) for (size_t i = 0; i < mTradeModel->getItemCount(); ++i)
{ {
if (mTradeModel->getItem(i).mBase == itemSelected) if (mTradeModel->getItem(static_cast<ItemModel::ModelIndex>(i)).mBase == itemSelected)
{ {
onItemSelectedFromSourceModel(i); onItemSelectedFromSourceModel(static_cast<int>(i));
return; return;
} }
} }
@ -726,7 +726,7 @@ namespace MWGui
MWWorld::Ptr InventoryWindow::getAvatarSelectedItem(int x, int y) MWWorld::Ptr InventoryWindow::getAvatarSelectedItem(int x, int y)
{ {
const osg::Vec2f viewportCoords = mapPreviewWindowToViewport(x, y); const osg::Vec2i viewportCoords = mapPreviewWindowToViewport(x, y);
int slot = mPreview->getSlotSelected(viewportCoords.x(), viewportCoords.y()); int slot = mPreview->getSlotSelected(viewportCoords.x(), viewportCoords.y());
if (slot == -1) if (slot == -1)
@ -748,10 +748,10 @@ namespace MWGui
{ {
MWWorld::Ptr player = MWMechanics::getPlayer(); MWWorld::Ptr player = MWMechanics::getPlayer();
float capacity = player.getClass().getCapacity(player); int capacity = static_cast<int>(player.getClass().getCapacity(player));
float encumbrance = player.getClass().getEncumbrance(player); float encumbrance = player.getClass().getEncumbrance(player);
mTradeModel->adjustEncumbrance(encumbrance); mTradeModel->adjustEncumbrance(encumbrance);
mEncumbranceBar->setValue(std::ceil(encumbrance), static_cast<int>(capacity)); mEncumbranceBar->setValue(static_cast<int>(std::ceil(encumbrance)), capacity);
} }
void InventoryWindow::onFrame(float dt) void InventoryWindow::onFrame(float dt)
@ -844,7 +844,7 @@ namespace MWGui
size_t i = 0; size_t i = 0;
for (; i < mTradeModel->getItemCount(); ++i) for (; i < mTradeModel->getItemCount(); ++i)
{ {
if (mTradeModel->getItem(i).mBase == newObject) if (mTradeModel->getItem(static_cast<ItemModel::ModelIndex>(i)).mBase == newObject)
break; break;
} }
if (i == mTradeModel->getItemCount()) if (i == mTradeModel->getItemCount())
@ -855,13 +855,13 @@ namespace MWGui
if (MyGUI::InputManager::getInstance().isAltPressed()) if (MyGUI::InputManager::getInstance().isAltPressed())
{ {
const MWWorld::Ptr item = mTradeModel->getItem(i).mBase; const MWWorld::Ptr item = mTradeModel->getItem(static_cast<ItemModel::ModelIndex>(i)).mBase;
MWBase::Environment::get().getWindowManager()->playSound(item.getClass().getDownSoundId(item)); MWBase::Environment::get().getWindowManager()->playSound(item.getClass().getDownSoundId(item));
mItemView->update(); mItemView->update();
} }
else else
{ {
mDragAndDrop->startDrag(i, mSortModel, mTradeModel, mItemView, count); mDragAndDrop->startDrag(static_cast<int>(i), mSortModel, mTradeModel, mItemView, count);
} }
MWBase::Environment::get().getWindowManager()->updateSpellWindow(); MWBase::Environment::get().getWindowManager()->updateSpellWindow();
@ -902,7 +902,7 @@ namespace MWGui
for (size_t i = 0; i < model.getItemCount(); ++i) for (size_t i = 0; i < model.getItemCount(); ++i)
{ {
cycled += incr; cycled += incr;
cycled = (cycled + model.getItemCount()) % model.getItemCount(); cycled = static_cast<ItemModel::ModelIndex>((cycled + model.getItemCount()) % model.getItemCount());
MWWorld::Ptr item = model.getItem(cycled).mBase; MWWorld::Ptr item = model.getItem(cycled).mBase;
@ -947,18 +947,19 @@ namespace MWGui
const MyGUI::IntSize previewWindowSize = mAvatarImage->getSize(); const MyGUI::IntSize previewWindowSize = mAvatarImage->getSize();
const float scale = MWBase::Environment::get().getWindowManager()->getScalingFactor(); const float scale = MWBase::Environment::get().getWindowManager()->getScalingFactor();
return MyGUI::IntSize(std::min<int>(mPreview->getTextureWidth(), previewWindowSize.width * scale), return MyGUI::IntSize(std::min(mPreview->getTextureWidth(), static_cast<int>(previewWindowSize.width * scale)),
std::min<int>(mPreview->getTextureHeight(), previewWindowSize.height * scale)); std::min(mPreview->getTextureHeight(), static_cast<int>(previewWindowSize.height * scale)));
} }
osg::Vec2f InventoryWindow::mapPreviewWindowToViewport(int x, int y) const osg::Vec2i InventoryWindow::mapPreviewWindowToViewport(int x, int y) const
{ {
const MyGUI::IntSize previewWindowSize = mAvatarImage->getSize(); const MyGUI::IntSize previewWindowSize = mAvatarImage->getSize();
const float normalisedX = x / std::max<float>(1.0f, previewWindowSize.width); const float normalisedX = x / std::max(1.f, static_cast<float>(previewWindowSize.width));
const float normalisedY = y / std::max<float>(1.0f, previewWindowSize.height); const float normalisedY = y / std::max(1.f, static_cast<float>(previewWindowSize.height));
const MyGUI::IntSize viewport = getPreviewViewportSize(); const MyGUI::IntSize viewport = getPreviewViewportSize();
return osg::Vec2f(normalisedX * float(viewport.width - 1), (1.0 - normalisedY) * float(viewport.height - 1)); return osg::Vec2i(static_cast<int>(normalisedX * (viewport.width - 1)),
static_cast<int>((1 - normalisedY) * (viewport.height - 1)));
} }
ControllerButtons* InventoryWindow::getControllerButtons() ControllerButtons* InventoryWindow::getControllerButtons()

View file

@ -158,7 +158,7 @@ namespace MWGui
void updateArmorRating(); void updateArmorRating();
MyGUI::IntSize getPreviewViewportSize() const; MyGUI::IntSize getPreviewViewportSize() const;
osg::Vec2f mapPreviewWindowToViewport(int x, int y) const; osg::Vec2i mapPreviewWindowToViewport(int x, int y) const;
void adjustPanes(); void adjustPanes();

View file

@ -161,7 +161,7 @@ namespace MWGui
mScrollView->setVisibleVScroll(true); mScrollView->setVisibleVScroll(true);
if (Settings::gui().mControllerMenus) if (Settings::gui().mControllerMenus)
updateControllerFocus(-1, mControllerFocus); updateControllerFocus(mLines.size(), mControllerFocus);
} }
void ItemChargeView::resetScrollbars() void ItemChargeView::resetScrollbars()
@ -242,37 +242,37 @@ namespace MWGui
if (mLines.empty()) if (mLines.empty())
return; return;
int prevFocus = mControllerFocus; size_t prevFocus = mControllerFocus;
if (button == SDL_CONTROLLER_BUTTON_A) if (button == SDL_CONTROLLER_BUTTON_A)
{ {
// Select the focused item, if any. // Select the focused item, if any.
if (mControllerFocus >= 0 && mControllerFocus < static_cast<int>(mLines.size())) if (mControllerFocus < mLines.size())
onIconClicked(mLines[mControllerFocus].mIcon); onIconClicked(mLines[mControllerFocus].mIcon);
} }
else if (button == SDL_CONTROLLER_BUTTON_DPAD_UP) else if (button == SDL_CONTROLLER_BUTTON_DPAD_UP)
mControllerFocus = wrap(mControllerFocus - 1, mLines.size()); mControllerFocus = wrap(mControllerFocus, mLines.size(), -1);
else if (button == SDL_CONTROLLER_BUTTON_DPAD_DOWN) else if (button == SDL_CONTROLLER_BUTTON_DPAD_DOWN)
mControllerFocus = wrap(mControllerFocus + 1, mLines.size()); mControllerFocus = wrap(mControllerFocus, mLines.size(), 1);
if (prevFocus != mControllerFocus) if (prevFocus != mControllerFocus)
updateControllerFocus(prevFocus, mControllerFocus); updateControllerFocus(prevFocus, mControllerFocus);
} }
void ItemChargeView::updateControllerFocus(int prevFocus, int newFocus) void ItemChargeView::updateControllerFocus(size_t prevFocus, size_t newFocus)
{ {
if (mLines.empty()) if (mLines.empty())
return; return;
const TextColours& textColours{ MWBase::Environment::get().getWindowManager()->getTextColours() }; const TextColours& textColours{ MWBase::Environment::get().getWindowManager()->getTextColours() };
if (prevFocus >= 0 && prevFocus < static_cast<int>(mLines.size())) if (prevFocus < mLines.size())
{ {
mLines[prevFocus].mText->setTextColour(textColours.normal); mLines[prevFocus].mText->setTextColour(textColours.normal);
mLines[prevFocus].mIcon->setControllerFocus(false); mLines[prevFocus].mIcon->setControllerFocus(false);
} }
if (newFocus >= 0 && newFocus < static_cast<int>(mLines.size())) if (newFocus < mLines.size())
{ {
mLines[newFocus].mText->setTextColour(textColours.link); mLines[newFocus].mText->setTextColour(textColours.link);
mLines[newFocus].mIcon->setControllerFocus(true); mLines[newFocus].mIcon->setControllerFocus(true);
@ -281,7 +281,7 @@ namespace MWGui
if (newFocus <= 3) if (newFocus <= 3)
mScrollView->setViewOffset(MyGUI::IntPoint(0, 0)); mScrollView->setViewOffset(MyGUI::IntPoint(0, 0));
else else
mScrollView->setViewOffset(MyGUI::IntPoint(0, -55 * (newFocus - 3))); mScrollView->setViewOffset(MyGUI::IntPoint(0, -55 * static_cast<int>(newFocus - 3)));
} }
} }
} }

View file

@ -75,8 +75,8 @@ namespace MWGui
MyGUI::ScrollView* mScrollView; MyGUI::ScrollView* mScrollView;
DisplayMode mDisplayMode; DisplayMode mDisplayMode;
int mControllerFocus = 0; size_t mControllerFocus = 0;
void updateControllerFocus(int prevFocus, int newFocus); void updateControllerFocus(size_t prevFocus, size_t newFocus);
}; };
} }

View file

@ -109,9 +109,9 @@ namespace MWGui
const ItemStack& itemToSearch = getItem(index); const ItemStack& itemToSearch = getItem(index);
for (size_t i = 0; i < mSourceModel->getItemCount(); ++i) for (size_t i = 0; i < mSourceModel->getItemCount(); ++i)
{ {
const ItemStack& item = mSourceModel->getItem(i); const ItemStack& item = mSourceModel->getItem(static_cast<ModelIndex>(i));
if (item.mBase == itemToSearch.mBase) if (item.mBase == itemToSearch.mBase)
return i; return static_cast<ModelIndex>(i);
} }
return -1; return -1;
} }
@ -121,9 +121,9 @@ namespace MWGui
const ItemStack& itemToSearch = mSourceModel->getItem(index); const ItemStack& itemToSearch = mSourceModel->getItem(index);
for (size_t i = 0; i < getItemCount(); ++i) for (size_t i = 0; i < getItemCount(); ++i)
{ {
const ItemStack& item = getItem(i); const ItemStack& item = getItem(static_cast<ModelIndex>(i));
if (item.mBase == itemToSearch.mBase) if (item.mBase == itemToSearch.mBase)
return i; return static_cast<ModelIndex>(i);
} }
return -1; return -1;
} }

View file

@ -55,7 +55,7 @@ namespace MWGui
WorldItemModel worldItemModel(0.5f, 0.5f); WorldItemModel worldItemModel(0.5f, 0.5f);
ItemModel* const targetModel = targetView == nullptr ? &worldItemModel : targetView->getModel(); ItemModel* const targetModel = targetView == nullptr ? &worldItemModel : targetView->getModel();
if (!targetModel->onDropItem(item.mBase, count)) if (!targetModel->onDropItem(item.mBase, static_cast<int>(count)))
return; return;
sourceView.getModel()->moveItem(item, count, targetModel); sourceView.getModel()->moveItem(item, count, targetModel);

View file

@ -54,7 +54,7 @@ namespace MWGui
int maxHeight = mScrollView->getHeight(); int maxHeight = mScrollView->getHeight();
mRows = std::max(maxHeight / 42, 1); mRows = std::max(maxHeight / 42, 1);
mItemCount = dragArea->getChildCount(); mItemCount = static_cast<int>(dragArea->getChildCount());
bool showScrollbar = static_cast<int>(std::ceil(mItemCount / float(mRows))) > mScrollView->getWidth() / 42; bool showScrollbar = static_cast<int>(std::ceil(mItemCount / float(mRows))) > mScrollView->getWidth() / 42;
if (showScrollbar) if (showScrollbar)
{ {
@ -129,7 +129,7 @@ namespace MWGui
if (item.mType == ItemStack::Type_Equipped) if (item.mType == ItemStack::Type_Equipped)
state = ItemWidget::Equip; state = ItemWidget::Equip;
itemWidget->setItem(item.mBase, state); itemWidget->setItem(item.mBase, state);
itemWidget->setCount(item.mCount); itemWidget->setCount(static_cast<int>(item.mCount));
itemWidget->eventMouseButtonClick += MyGUI::newDelegate(this, &ItemView::onSelectedItem); itemWidget->eventMouseButtonClick += MyGUI::newDelegate(this, &ItemView::onSelectedItem);
itemWidget->eventMouseWheel += MyGUI::newDelegate(this, &ItemView::onMouseWheelMoved); itemWidget->eventMouseWheel += MyGUI::newDelegate(this, &ItemView::onMouseWheelMoved);

View file

@ -207,10 +207,12 @@ namespace MWGui
scale = found->second; scale = found->second;
} }
const int diameter = static_cast<int>(44 * scale);
if (state == Barter && !isMagic) if (state == Barter && !isMagic)
setFrame(backgroundTex, MyGUI::IntCoord(2 * scale, 2 * scale, 44 * scale, 44 * scale)); setFrame(backgroundTex,
MyGUI::IntCoord(static_cast<int>(2 * scale), static_cast<int>(2 * scale), diameter, diameter));
else else
setFrame(backgroundTex, MyGUI::IntCoord(0, 0, 44 * scale, 44 * scale)); setFrame(backgroundTex, MyGUI::IntCoord(0, 0, diameter, diameter));
setIcon(ptr); setIcon(ptr);
} }

View file

@ -12,10 +12,10 @@ namespace
{ {
struct AddContent struct AddContent
{ {
MWGui::BookTypesetter::Ptr mTypesetter; std::shared_ptr<MWGui::BookTypesetter> mTypesetter;
MWGui::BookTypesetter::Style* mBodyStyle; MWGui::BookTypesetter::Style* mBodyStyle;
explicit AddContent(MWGui::BookTypesetter::Ptr typesetter, MWGui::BookTypesetter::Style* bodyStyle) explicit AddContent(std::shared_ptr<MWGui::BookTypesetter> typesetter, MWGui::BookTypesetter::Style* bodyStyle)
: mTypesetter(std::move(typesetter)) : mTypesetter(std::move(typesetter))
, mBodyStyle(bodyStyle) , mBodyStyle(bodyStyle)
{ {
@ -24,19 +24,19 @@ namespace
struct AddSpan : AddContent struct AddSpan : AddContent
{ {
explicit AddSpan(MWGui::BookTypesetter::Ptr typesetter, MWGui::BookTypesetter::Style* bodyStyle) explicit AddSpan(std::shared_ptr<MWGui::BookTypesetter> typesetter, MWGui::BookTypesetter::Style* bodyStyle)
: AddContent(std::move(typesetter), bodyStyle) : AddContent(std::move(typesetter), bodyStyle)
{ {
} }
void operator()(intptr_t topicId, size_t begin, size_t end) void operator()(const MWDialogue::Topic* topic, size_t begin, size_t end)
{ {
MWGui::BookTypesetter::Style* style = mBodyStyle; MWGui::BookTypesetter::Style* style = mBodyStyle;
const MWGui::TextColours& textColours = MWBase::Environment::get().getWindowManager()->getTextColours(); const MWGui::TextColours& textColours = MWBase::Environment::get().getWindowManager()->getTextColours();
if (topicId) if (topic)
style = mTypesetter->createHotStyle(mBodyStyle, textColours.journalLink, textColours.journalLinkOver, style = mTypesetter->createHotStyle(mBodyStyle, textColours.journalLink, textColours.journalLinkOver,
textColours.journalLinkPressed, topicId); textColours.journalLinkPressed, MWGui::TypesetBook::InteractiveId(topic));
mTypesetter->write(style, begin, end); mTypesetter->write(style, begin, end);
} }
@ -44,10 +44,10 @@ namespace
struct AddEntry struct AddEntry
{ {
MWGui::BookTypesetter::Ptr mTypesetter; std::shared_ptr<MWGui::BookTypesetter> mTypesetter;
MWGui::BookTypesetter::Style* mBodyStyle; MWGui::BookTypesetter::Style* mBodyStyle;
AddEntry(MWGui::BookTypesetter::Ptr typesetter, MWGui::BookTypesetter::Style* bodyStyle) AddEntry(std::shared_ptr<MWGui::BookTypesetter> typesetter, MWGui::BookTypesetter::Style* bodyStyle)
: mTypesetter(std::move(typesetter)) : mTypesetter(std::move(typesetter))
, mBodyStyle(bodyStyle) , mBodyStyle(bodyStyle)
{ {
@ -66,8 +66,8 @@ namespace
bool mAddHeader; bool mAddHeader;
MWGui::BookTypesetter::Style* mHeaderStyle; MWGui::BookTypesetter::Style* mHeaderStyle;
explicit AddJournalEntry(MWGui::BookTypesetter::Ptr typesetter, MWGui::BookTypesetter::Style* bodyStyle, explicit AddJournalEntry(std::shared_ptr<MWGui::BookTypesetter> typesetter,
MWGui::BookTypesetter::Style* headerStyle, bool addHeader) MWGui::BookTypesetter::Style* bodyStyle, MWGui::BookTypesetter::Style* headerStyle, bool addHeader)
: AddEntry(std::move(typesetter), bodyStyle) : AddEntry(std::move(typesetter), bodyStyle)
, mAddHeader(addHeader) , mAddHeader(addHeader)
, mHeaderStyle(headerStyle) , mHeaderStyle(headerStyle)
@ -90,11 +90,12 @@ namespace
struct AddTopicEntry : AddEntry struct AddTopicEntry : AddEntry
{ {
intptr_t mContentId; const MWGui::TypesetBook::Content* mContentId;
MWGui::BookTypesetter::Style* mHeaderStyle; MWGui::BookTypesetter::Style* mHeaderStyle;
explicit AddTopicEntry(MWGui::BookTypesetter::Ptr typesetter, MWGui::BookTypesetter::Style* bodyStyle, explicit AddTopicEntry(std::shared_ptr<MWGui::BookTypesetter> typesetter,
MWGui::BookTypesetter::Style* headerStyle, intptr_t contentId) MWGui::BookTypesetter::Style* bodyStyle, MWGui::BookTypesetter::Style* headerStyle,
const MWGui::TypesetBook::Content* contentId)
: AddEntry(std::move(typesetter), bodyStyle) : AddEntry(std::move(typesetter), bodyStyle)
, mContentId(contentId) , mContentId(contentId)
, mHeaderStyle(headerStyle) , mHeaderStyle(headerStyle)
@ -117,12 +118,12 @@ namespace
struct AddTopicName : AddContent struct AddTopicName : AddContent
{ {
AddTopicName(MWGui::BookTypesetter::Ptr typesetter, MWGui::BookTypesetter::Style* style) AddTopicName(std::shared_ptr<MWGui::BookTypesetter> typesetter, MWGui::BookTypesetter::Style* style)
: AddContent(std::move(typesetter), style) : AddContent(std::move(typesetter), style)
{ {
} }
void operator()(MWGui::JournalViewModel::Utf8Span topicName) void operator()(std::string_view topicName)
{ {
mTypesetter->write(mBodyStyle, topicName); mTypesetter->write(mBodyStyle, topicName);
mTypesetter->sectionBreak(); mTypesetter->sectionBreak();
@ -131,12 +132,12 @@ namespace
struct AddQuestName : AddContent struct AddQuestName : AddContent
{ {
AddQuestName(MWGui::BookTypesetter::Ptr typesetter, MWGui::BookTypesetter::Style* style) AddQuestName(std::shared_ptr<MWGui::BookTypesetter> typesetter, MWGui::BookTypesetter::Style* style)
: AddContent(std::move(typesetter), style) : AddContent(std::move(typesetter), style)
{ {
} }
void operator()(MWGui::JournalViewModel::Utf8Span topicName) void operator()(std::string_view topicName)
{ {
mTypesetter->write(mBodyStyle, topicName); mTypesetter->write(mBodyStyle, topicName);
mTypesetter->sectionBreak(); mTypesetter->sectionBreak();
@ -147,15 +148,6 @@ namespace
namespace MWGui namespace MWGui
{ {
MWGui::BookTypesetter::Utf8Span to_utf8_span(std::string_view text)
{
typedef MWGui::BookTypesetter::Utf8Point point;
point begin = reinterpret_cast<point>(text.data());
return MWGui::BookTypesetter::Utf8Span(begin, begin + text.length());
}
int getCyrillicIndexPageCount() int getCyrillicIndexPageCount()
{ {
// For small font size split alphabet to two columns (2x15 characers), for big font size split it to three // For small font size split alphabet to two columns (2x15 characers), for big font size split it to three
@ -163,33 +155,30 @@ namespace MWGui
return Settings::gui().mFontSize < 18 ? 2 : 3; return Settings::gui().mFontSize < 18 ? 2 : 3;
} }
typedef TypesetBook::Ptr book; JournalBooks::JournalBooks(std::shared_ptr<JournalViewModel> model, ToUTF8::FromType encoding)
JournalBooks::JournalBooks(JournalViewModel::Ptr model, ToUTF8::FromType encoding)
: mModel(std::move(model)) : mModel(std::move(model))
, mEncoding(encoding) , mEncoding(encoding)
, mIndexPagesCount(0) , mIndexPagesCount(0)
{ {
} }
book JournalBooks::createEmptyJournalBook() std::shared_ptr<TypesetBook> JournalBooks::createEmptyJournalBook()
{ {
BookTypesetter::Ptr typesetter = createTypesetter(); std::shared_ptr<BookTypesetter> typesetter = createTypesetter();
BookTypesetter::Style* header = typesetter->createStyle({}, journalHeaderColour); BookTypesetter::Style* header = typesetter->createStyle({}, journalHeaderColour);
BookTypesetter::Style* body = typesetter->createStyle({}, MyGUI::Colour::Black); BookTypesetter::Style* body = typesetter->createStyle({}, MyGUI::Colour::Black);
typesetter->write(header, to_utf8_span("You have no journal entries!")); typesetter->write(header, "You have no journal entries!");
typesetter->lineBreak(); typesetter->lineBreak();
typesetter->write( typesetter->write(body, "You should have gone though the starting quest and got an initial quest.");
body, to_utf8_span("You should have gone though the starting quest and got an initial quest."));
return typesetter->complete(); return typesetter->complete();
} }
book JournalBooks::createJournalBook() std::shared_ptr<TypesetBook> JournalBooks::createJournalBook()
{ {
BookTypesetter::Ptr typesetter = createTypesetter(); std::shared_ptr<BookTypesetter> typesetter = createTypesetter();
BookTypesetter::Style* header = typesetter->createStyle({}, journalHeaderColour); BookTypesetter::Style* header = typesetter->createStyle({}, journalHeaderColour);
BookTypesetter::Style* body = typesetter->createStyle({}, MyGUI::Colour::Black); BookTypesetter::Style* body = typesetter->createStyle({}, MyGUI::Colour::Black);
@ -199,49 +188,50 @@ namespace MWGui
return typesetter->complete(); return typesetter->complete();
} }
book JournalBooks::createTopicBook(uintptr_t topicId) std::shared_ptr<TypesetBook> JournalBooks::createTopicBook(const MWDialogue::Topic& topic)
{ {
BookTypesetter::Ptr typesetter = createTypesetter(); std::shared_ptr<BookTypesetter> typesetter = createTypesetter();
BookTypesetter::Style* header = typesetter->createStyle({}, journalHeaderColour); BookTypesetter::Style* header = typesetter->createStyle({}, journalHeaderColour);
BookTypesetter::Style* body = typesetter->createStyle({}, MyGUI::Colour::Black); BookTypesetter::Style* body = typesetter->createStyle({}, MyGUI::Colour::Black);
mModel->visitTopicName(topicId, AddTopicName(typesetter, header)); mModel->visitTopicName(topic, AddTopicName(typesetter, header));
intptr_t contentId = typesetter->addContent(to_utf8_span(", \"")); const TypesetBook::Content* contentId = typesetter->addContent(", \"");
mModel->visitTopicEntries(topicId, AddTopicEntry(typesetter, body, header, contentId)); mModel->visitTopicEntries(topic, AddTopicEntry(typesetter, body, header, contentId));
return typesetter->complete(); return typesetter->complete();
} }
book JournalBooks::createQuestBook(std::string_view questName) std::shared_ptr<TypesetBook> JournalBooks::createQuestBook(std::string_view questName)
{ {
BookTypesetter::Ptr typesetter = createTypesetter(); std::shared_ptr<BookTypesetter> typesetter = createTypesetter();
BookTypesetter::Style* header = typesetter->createStyle({}, journalHeaderColour); BookTypesetter::Style* header = typesetter->createStyle({}, journalHeaderColour);
BookTypesetter::Style* body = typesetter->createStyle({}, MyGUI::Colour::Black); BookTypesetter::Style* body = typesetter->createStyle({}, MyGUI::Colour::Black);
AddQuestName addName(typesetter, header); AddQuestName addName(typesetter, header);
addName(to_utf8_span(questName)); addName(questName);
mModel->visitJournalEntries(questName, AddJournalEntry(typesetter, body, header, false)); mModel->visitJournalEntries(questName, AddJournalEntry(typesetter, body, header, false));
return typesetter->complete(); return typesetter->complete();
} }
book JournalBooks::createTopicIndexBook() std::shared_ptr<TypesetBook> JournalBooks::createTopicIndexBook()
{ {
bool isRussian = (mEncoding == ToUTF8::WINDOWS_1251); bool isRussian = (mEncoding == ToUTF8::WINDOWS_1251);
BookTypesetter::Ptr typesetter = isRussian ? createCyrillicJournalIndex() : createLatinJournalIndex(); std::shared_ptr<BookTypesetter> typesetter
= isRussian ? createCyrillicJournalIndex() : createLatinJournalIndex();
return typesetter->complete(); return typesetter->complete();
} }
BookTypesetter::Ptr JournalBooks::createLatinJournalIndex() std::shared_ptr<BookTypesetter> JournalBooks::createLatinJournalIndex()
{ {
BookTypesetter::Ptr typesetter = BookTypesetter::create(92, 260); std::shared_ptr<BookTypesetter> typesetter = BookTypesetter::create(92, 260);
typesetter->setSectionAlignment(BookTypesetter::AlignCenter); typesetter->setSectionAlignment(BookTypesetter::AlignCenter);
@ -260,12 +250,12 @@ namespace MWGui
const MWGui::TextColours& textColours = MWBase::Environment::get().getWindowManager()->getTextColours(); const MWGui::TextColours& textColours = MWBase::Environment::get().getWindowManager()->getTextColours();
BookTypesetter::Style* style = typesetter->createHotStyle(body, textColours.journalTopic, BookTypesetter::Style* style = typesetter->createHotStyle(body, textColours.journalTopic,
textColours.journalTopicOver, textColours.journalTopicPressed, (Utf8Stream::UnicodeChar)ch); textColours.journalTopicOver, textColours.journalTopicPressed, Utf8Stream::UnicodeChar(ch));
if (i == 13) if (i == 13)
typesetter->sectionBreak(); typesetter->sectionBreak();
typesetter->write(style, to_utf8_span(buffer)); typesetter->write(style, buffer);
typesetter->lineBreak(); typesetter->lineBreak();
ch++; ch++;
@ -274,9 +264,9 @@ namespace MWGui
return typesetter; return typesetter;
} }
BookTypesetter::Ptr JournalBooks::createCyrillicJournalIndex() std::shared_ptr<BookTypesetter> JournalBooks::createCyrillicJournalIndex()
{ {
BookTypesetter::Ptr typesetter = BookTypesetter::create(92, 260); std::shared_ptr<BookTypesetter> typesetter = BookTypesetter::create(92, 260);
typesetter->setSectionAlignment(BookTypesetter::AlignCenter); typesetter->setSectionAlignment(BookTypesetter::AlignCenter);
@ -314,14 +304,14 @@ namespace MWGui
if (i % sectionBreak == 0) if (i % sectionBreak == 0)
typesetter->sectionBreak(); typesetter->sectionBreak();
typesetter->write(style, to_utf8_span(buffer)); typesetter->write(style, buffer);
typesetter->lineBreak(); typesetter->lineBreak();
} }
return typesetter; return typesetter;
} }
BookTypesetter::Ptr JournalBooks::createTypesetter() std::shared_ptr<BookTypesetter> JournalBooks::createTypesetter()
{ {
// TODO: determine page size from layout... // TODO: determine page size from layout...
return BookTypesetter::create(240, 320); return BookTypesetter::create(240, 320);

View file

@ -8,31 +8,29 @@
namespace MWGui namespace MWGui
{ {
MWGui::BookTypesetter::Utf8Span to_utf8_span(std::string_view text);
int getCyrillicIndexPageCount(); int getCyrillicIndexPageCount();
const MyGUI::Colour journalHeaderColour = MyGUI::Colour(0.60f, 0.00f, 0.00f); const MyGUI::Colour journalHeaderColour = MyGUI::Colour(0.60f, 0.00f, 0.00f);
struct JournalBooks struct JournalBooks
{ {
typedef TypesetBook::Ptr Book; std::shared_ptr<JournalViewModel> mModel;
JournalViewModel::Ptr mModel;
JournalBooks(JournalViewModel::Ptr model, ToUTF8::FromType encoding); JournalBooks(std::shared_ptr<JournalViewModel> model, ToUTF8::FromType encoding);
Book createEmptyJournalBook(); std::shared_ptr<TypesetBook> createEmptyJournalBook();
Book createJournalBook(); std::shared_ptr<TypesetBook> createJournalBook();
Book createTopicBook(uintptr_t topicId); std::shared_ptr<TypesetBook> createTopicBook(const MWDialogue::Topic& topic);
Book createQuestBook(std::string_view questName); std::shared_ptr<TypesetBook> createQuestBook(std::string_view questName);
Book createTopicIndexBook(); std::shared_ptr<TypesetBook> createTopicIndexBook();
ToUTF8::FromType mEncoding; ToUTF8::FromType mEncoding;
int mIndexPagesCount; int mIndexPagesCount;
private: private:
BookTypesetter::Ptr createTypesetter(); std::shared_ptr<BookTypesetter> createTypesetter();
BookTypesetter::Ptr createLatinJournalIndex(); std::shared_ptr<BookTypesetter> createLatinJournalIndex();
BookTypesetter::Ptr createCyrillicJournalIndex(); std::shared_ptr<BookTypesetter> createCyrillicJournalIndex();
}; };
} }

View file

@ -22,26 +22,15 @@ namespace MWGui
struct JournalViewModelImpl : JournalViewModel struct JournalViewModelImpl : JournalViewModel
{ {
typedef MWDialogue::KeywordSearch<intptr_t> KeywordSearchT; using TopicSearch = MWDialogue::KeywordSearch<const MWDialogue::Topic*>;
mutable bool mKeywordSearchLoaded; mutable bool mKeywordSearchLoaded;
mutable KeywordSearchT mKeywordSearch; mutable TopicSearch mKeywordSearch;
JournalViewModelImpl() { mKeywordSearchLoaded = false; } JournalViewModelImpl() { mKeywordSearchLoaded = false; }
virtual ~JournalViewModelImpl() = default; virtual ~JournalViewModelImpl() = default;
/// \todo replace this nasty BS
static Utf8Span toUtf8Span(std::string_view str)
{
if (str.empty())
return Utf8Span(Utf8Point(nullptr), Utf8Point(nullptr));
Utf8Point point = reinterpret_cast<Utf8Point>(str.data());
return Utf8Span(point, point + str.size());
}
void load() override {} void load() override {}
void unload() override void unload() override
@ -57,7 +46,7 @@ namespace MWGui
MWBase::Journal* journal = MWBase::Environment::get().getJournal(); MWBase::Journal* journal = MWBase::Environment::get().getJournal();
for (const auto& [_, topic] : journal->getTopics()) for (const auto& [_, topic] : journal->getTopics())
mKeywordSearch.seed(topic.getName(), intptr_t(&topic)); mKeywordSearch.seed(topic.getName(), &topic);
mKeywordSearchLoaded = true; mKeywordSearchLoaded = true;
} }
@ -88,10 +77,8 @@ namespace MWGui
mutable bool loaded; mutable bool loaded;
mutable std::string utf8text; mutable std::string utf8text;
typedef std::pair<size_t, size_t> Range;
// hyperlinks in @link# notation // hyperlinks in @link# notation
mutable std::map<Range, intptr_t> mHyperLinks; mutable std::map<std::pair<size_t, size_t>, const MWDialogue::Topic*> mHyperLinks;
virtual std::string getText() const = 0; virtual std::string getText() const = 0;
@ -126,7 +113,7 @@ namespace MWGui
utf8text.replace(posBegin, posEnd + 1 - posBegin, displayName); utf8text.replace(posBegin, posEnd + 1 - posBegin, displayName);
intptr_t value = 0; const MWDialogue::Topic* value = nullptr;
if (mModel->mKeywordSearch.containsKeyword(topicName, value)) if (mModel->mKeywordSearch.containsKeyword(topicName, value))
mHyperLinks[std::make_pair(posBegin, posBegin + displayName.size())] = value; mHyperLinks[std::make_pair(posBegin, posBegin + displayName.size())] = value;
} }
@ -138,14 +125,14 @@ namespace MWGui
} }
} }
Utf8Span body() const override std::string_view body() const override
{ {
ensureLoaded(); ensureLoaded();
return toUtf8Span(utf8text); return utf8text;
} }
void visitSpans(std::function<void(TopicId, size_t, size_t)> visitor) const override void visitSpans(std::function<void(const MWDialogue::Topic*, size_t, size_t)> visitor) const override
{ {
ensureLoaded(); ensureLoaded();
mModel->ensureKeyWordSearchLoaded(); mModel->ensureKeyWordSearchLoaded();
@ -154,29 +141,24 @@ namespace MWGui
&& MWBase::Environment::get().getWindowManager()->getTranslationDataStorage().hasTranslation()) && MWBase::Environment::get().getWindowManager()->getTranslationDataStorage().hasTranslation())
{ {
size_t formatted = 0; // points to the first character that is not laid out yet size_t formatted = 0; // points to the first character that is not laid out yet
for (std::map<Range, intptr_t>::const_iterator it = mHyperLinks.begin(); it != mHyperLinks.end(); for (const auto& [range, topicId] : mHyperLinks)
++it)
{ {
intptr_t topicId = it->second; if (formatted < range.first)
if (formatted < it->first.first) visitor(0, formatted, range.first);
visitor(0, formatted, it->first.first); visitor(topicId, range.first, range.second);
visitor(topicId, it->first.first, it->first.second); formatted = range.second;
formatted = it->first.second;
} }
if (formatted < utf8text.size()) if (formatted < utf8text.size())
visitor(0, formatted, utf8text.size()); visitor(0, formatted, utf8text.size());
} }
else else
{ {
std::vector<KeywordSearchT::Match> matches; std::vector<TopicSearch::Match> matches;
mModel->mKeywordSearch.highlightKeywords(utf8text.begin(), utf8text.end(), matches); mModel->mKeywordSearch.highlightKeywords(utf8text.begin(), utf8text.end(), matches);
std::string::const_iterator i = utf8text.begin(); std::string::const_iterator i = utf8text.begin();
for (std::vector<KeywordSearchT::Match>::const_iterator it = matches.begin(); it != matches.end(); for (const TopicSearch::Match& match : matches)
++it)
{ {
const KeywordSearchT::Match& match = *it;
if (i != match.mBeg) if (i != match.mBeg)
visitor(0, i - utf8text.begin(), match.mBeg - utf8text.begin()); visitor(0, i - utf8text.begin(), match.mBeg - utf8text.begin());
@ -234,7 +216,7 @@ namespace MWGui
std::string getText() const override { return mEntry->getText(); } std::string getText() const override { return mEntry->getText(); }
Utf8Span timestamp() const override std::string_view timestamp() const override
{ {
if (timestamp_buffer.empty()) if (timestamp_buffer.empty())
{ {
@ -249,7 +231,7 @@ namespace MWGui
timestamp_buffer = os.str(); timestamp_buffer = os.str();
} }
return toUtf8Span(timestamp_buffer); return timestamp_buffer;
} }
}; };
@ -291,10 +273,10 @@ namespace MWGui
} }
} }
void visitTopicName(TopicId topicId, std::function<void(Utf8Span)> visitor) const override void visitTopicName(
const MWDialogue::Topic& topic, std::function<void(std::string_view)> visitor) const override
{ {
MWDialogue::Topic const& topic = *reinterpret_cast<MWDialogue::Topic const*>(topicId); visitor(topic.getName());
visitor(toUtf8Span(topic.getName()));
} }
void visitTopicNamesStartingWith( void visitTopicNamesStartingWith(
@ -327,19 +309,18 @@ namespace MWGui
std::string getText() const override { return mEntry->getText(); } std::string getText() const override { return mEntry->getText(); }
Utf8Span source() const override { return toUtf8Span(mEntry->mActorName); } std::string_view source() const override { return mEntry->mActorName; }
}; };
void visitTopicEntries(TopicId topicId, std::function<void(TopicEntry const&)> visitor) const override void visitTopicEntries(
const MWDialogue::Topic& topic, std::function<void(TopicEntry const&)> visitor) const override
{ {
MWDialogue::Topic const& topic = *reinterpret_cast<MWDialogue::Topic const*>(topicId);
for (const MWDialogue::Entry& entry : topic) for (const MWDialogue::Entry& entry : topic)
visitor(TopicEntryImpl(this, topic, entry)); visitor(TopicEntryImpl(this, topic, entry));
} }
}; };
JournalViewModel::Ptr JournalViewModel::create() std::shared_ptr<JournalViewModel> JournalViewModel::create()
{ {
return std::make_shared<JournalViewModelImpl>(); return std::make_shared<JournalViewModelImpl>();
} }

View file

@ -8,6 +8,11 @@
#include <components/misc/utf8stream.hpp> #include <components/misc/utf8stream.hpp>
namespace MWDialogue
{
class Topic;
}
namespace MWGui namespace MWGui
{ {
/// View-Model for the journal GUI /// View-Model for the journal GUI
@ -18,13 +23,6 @@ namespace MWGui
/// game data store. /// game data store.
struct JournalViewModel struct JournalViewModel
{ {
typedef std::shared_ptr<JournalViewModel> Ptr;
typedef intptr_t QuestId;
typedef intptr_t TopicId;
typedef uint8_t const* Utf8Point;
typedef std::pair<Utf8Point, Utf8Point> Utf8Span;
/// The base interface for both journal entries and topics. /// The base interface for both journal entries and topics.
struct Entry struct Entry
{ {
@ -33,12 +31,12 @@ namespace MWGui
/// This function returns a borrowed reference to the body of the /// This function returns a borrowed reference to the body of the
/// journal entry. The returned reference becomes invalid when the /// journal entry. The returned reference becomes invalid when the
/// entry is destroyed. /// entry is destroyed.
virtual Utf8Span body() const = 0; virtual std::string_view body() const = 0;
/// Visits each subset of text in the body, delivering the beginning /// Visits each subset of text in the body, delivering the beginning
/// and end of the span relative to the body, and a valid topic ID if /// and end of the span relative to the body, and a valid topic ID if
/// the span represents a keyword, or zero if not. /// the span represents a keyword, or zero if not.
virtual void visitSpans(std::function<void(TopicId, size_t, size_t)> visitor) const = 0; virtual void visitSpans(std::function<void(const MWDialogue::Topic*, size_t, size_t)> visitor) const = 0;
virtual ~Entry() = default; virtual ~Entry() = default;
}; };
@ -48,7 +46,7 @@ namespace MWGui
{ {
/// Returns a pre-formatted span of UTF8 encoded text representing /// Returns a pre-formatted span of UTF8 encoded text representing
/// the name of the NPC this portion of dialog was heard from. /// the name of the NPC this portion of dialog was heard from.
virtual Utf8Span source() const = 0; virtual std::string_view source() const = 0;
virtual ~TopicEntry() = default; virtual ~TopicEntry() = default;
}; };
@ -58,7 +56,7 @@ namespace MWGui
{ {
/// Returns a pre-formatted span of UTF8 encoded text representing /// Returns a pre-formatted span of UTF8 encoded text representing
/// the in-game date this entry was added to the journal. /// the in-game date this entry was added to the journal.
virtual Utf8Span timestamp() const = 0; virtual std::string_view timestamp() const = 0;
virtual ~JournalEntry() = default; virtual ~JournalEntry() = default;
}; };
@ -81,17 +79,19 @@ namespace MWGui
std::string_view questName, std::function<void(JournalEntry const&)> visitor) const = 0; std::string_view questName, std::function<void(JournalEntry const&)> visitor) const = 0;
/// provides the name of the topic specified by its id /// provides the name of the topic specified by its id
virtual void visitTopicName(TopicId topicId, std::function<void(Utf8Span)> visitor) const = 0; virtual void visitTopicName(
const MWDialogue::Topic& topic, std::function<void(std::string_view)> visitor) const = 0;
/// walks over the topics whose names start with the character /// walks over the topics whose names start with the character
virtual void visitTopicNamesStartingWith( virtual void visitTopicNamesStartingWith(
Utf8Stream::UnicodeChar character, std::function<void(std::string_view)> visitor) const = 0; Utf8Stream::UnicodeChar character, std::function<void(std::string_view)> visitor) const = 0;
/// walks over the topic entries for the topic specified by its identifier /// walks over the topic entries for the topic specified by its identifier
virtual void visitTopicEntries(TopicId topicId, std::function<void(TopicEntry const&)> visitor) const = 0; virtual void visitTopicEntries(
const MWDialogue::Topic& topic, std::function<void(TopicEntry const&)> visitor) const = 0;
// create an instance of the default journal view model implementation // create an instance of the default journal view model implementation
static Ptr create(); static std::shared_ptr<JournalViewModel> create();
virtual ~JournalViewModel() = default; virtual ~JournalViewModel() = default;
}; };

View file

@ -49,14 +49,12 @@ namespace
{ {
struct DisplayState struct DisplayState
{ {
unsigned int mPage; size_t mPage;
Book mBook; std::shared_ptr<MWGui::TypesetBook> mBook;
}; };
typedef std::stack<DisplayState> DisplayStateStack; std::stack<DisplayState> mStates;
std::shared_ptr<MWGui::TypesetBook> mTopicIndexBook;
DisplayStateStack mStates;
Book mTopicIndexBook;
bool mQuestMode; bool mQuestMode;
bool mOptionsMode; bool mOptionsMode;
bool mTopicsMode; bool mTopicsMode;
@ -91,7 +89,7 @@ namespace
MWGui::BookPage* getPage(std::string_view name) { return getWidget<MWGui::BookPage>(name); } MWGui::BookPage* getPage(std::string_view name) { return getWidget<MWGui::BookPage>(name); }
JournalWindowImpl(MWGui::JournalViewModel::Ptr model, bool questList, ToUTF8::FromType encoding) JournalWindowImpl(std::shared_ptr<MWGui::JournalViewModel> model, bool questList, ToUTF8::FromType encoding)
: JournalBooks(std::move(model), encoding) : JournalBooks(std::move(model), encoding)
, JournalWindow() , JournalWindow()
{ {
@ -123,7 +121,10 @@ namespace
topicsList->eventItemSelected += MyGUI::newDelegate(this, &JournalWindowImpl::notifyTopicSelected); topicsList->eventItemSelected += MyGUI::newDelegate(this, &JournalWindowImpl::notifyTopicSelected);
{ {
MWGui::BookPage::ClickCallback callback = [this](intptr_t linkId) { notifyTopicClicked(linkId); }; MWGui::BookPage::ClickCallback callback = [this](MWGui::TypesetBook::InteractiveId linkId) {
const MWDialogue::Topic& topic = *reinterpret_cast<const MWDialogue::Topic*>(linkId);
notifyTopicClicked(topic);
};
getPage(LeftBookPage)->adviseLinkClicked(callback); getPage(LeftBookPage)->adviseLinkClicked(callback);
getPage(RightBookPage)->adviseLinkClicked(std::move(callback)); getPage(RightBookPage)->adviseLinkClicked(std::move(callback));
@ -135,8 +136,9 @@ namespace
} }
{ {
MWGui::BookPage::ClickCallback callback MWGui::BookPage::ClickCallback callback = [this](MWGui::TypesetBook::InteractiveId index) {
= [this](MWGui::TypesetBook::InteractiveId index) { notifyIndexLinkClicked(index); }; notifyIndexLinkClicked(static_cast<Utf8Stream::UnicodeChar>(index));
};
getPage(LeftTopicIndex)->adviseLinkClicked(callback); getPage(LeftTopicIndex)->adviseLinkClicked(callback);
getPage(CenterTopicIndex)->adviseLinkClicked(callback); getPage(CenterTopicIndex)->adviseLinkClicked(callback);
@ -159,8 +161,8 @@ namespace
{ {
// english button has a 7 pixel wide strip of garbage on its right edge // english button has a 7 pixel wide strip of garbage on its right edge
nextButton->setSize(64 - 7, nextButton->getSize().height); nextButton->setSize(64 - 7, nextButton->getSize().height);
nextButton->setImageCoord( nextButton->setImageCoord(MyGUI::IntCoord(0, 0, static_cast<int>((64 - 7) * nextButtonScale),
MyGUI::IntCoord(0, 0, (64 - 7) * nextButtonScale, nextButton->getSize().height * nextButtonScale)); static_cast<int>(nextButton->getSize().height * nextButtonScale)));
} }
if (!questList) if (!questList)
@ -240,18 +242,18 @@ namespace
setBookMode(); setBookMode();
Book journalBook; std::shared_ptr<MWGui::TypesetBook> journalBook;
if (mModel->isEmpty()) if (mModel->isEmpty())
journalBook = createEmptyJournalBook(); journalBook = createEmptyJournalBook();
else else
journalBook = createJournalBook(); journalBook = createJournalBook();
pushBook(journalBook, 0); pushBook(journalBook);
// fast forward to the last page // fast forward to the last page
if (!mStates.empty()) if (!mStates.empty())
{ {
unsigned int& page = mStates.top().mPage; size_t& page = mStates.top().mPage;
page = mStates.top().mBook->pageCount() - 1; page = mStates.top().mBook->pageCount() - 1;
if (page % 2) if (page % 2)
--page; --page;
@ -268,8 +270,8 @@ namespace
{ {
mModel->unload(); mModel->unload();
getPage(LeftBookPage)->showPage(Book(), 0); getPage(LeftBookPage)->showPage({}, 0);
getPage(RightBookPage)->showPage(Book(), 0); getPage(RightBookPage)->showPage({}, 0);
while (!mStates.empty()) while (!mStates.empty())
mStates.pop(); mStates.pop();
@ -315,7 +317,7 @@ namespace
// TODO: figure out how to make "options" page overlay book page // TODO: figure out how to make "options" page overlay book page
// correctly, so that text may show underneath // correctly, so that text may show underneath
getPage(RightBookPage)->showPage(Book(), 0); getPage(RightBookPage)->showPage({}, 0);
// If in quest mode, ensure the quest list is updated // If in quest mode, ensure the quest list is updated
if (mQuestMode) if (mQuestMode)
@ -326,21 +328,21 @@ namespace
MWBase::Environment::get().getWindowManager()->updateControllerButtonsOverlay(); MWBase::Environment::get().getWindowManager()->updateControllerButtonsOverlay();
} }
void pushBook(Book& book, unsigned int page) void pushBook(std::shared_ptr<MWGui::TypesetBook>& book)
{ {
DisplayState bs; DisplayState bs;
bs.mPage = page; bs.mPage = 0;
bs.mBook = book; bs.mBook = book;
mStates.push(bs); mStates.push(bs);
updateShowingPages(); updateShowingPages();
updateCloseJournalButton(); updateCloseJournalButton();
} }
void replaceBook(Book& book, unsigned int page) void replaceBook(std::shared_ptr<MWGui::TypesetBook>& book)
{ {
assert(!mStates.empty()); assert(!mStates.empty());
mStates.top().mBook = book; mStates.top().mBook = book;
mStates.top().mPage = page; mStates.top().mPage = 0;
updateShowingPages(); updateShowingPages();
} }
@ -360,9 +362,9 @@ namespace
void updateShowingPages() void updateShowingPages()
{ {
Book book; std::shared_ptr<MWGui::TypesetBook> book;
unsigned int page; size_t page;
unsigned int relPages; size_t relPages;
if (!mStates.empty()) if (!mStates.empty())
{ {
@ -393,8 +395,16 @@ namespace
setVisible(PageOneNum, relPages > 0); setVisible(PageOneNum, relPages > 0);
setVisible(PageTwoNum, relPages > 1); setVisible(PageTwoNum, relPages > 1);
getPage(LeftBookPage)->showPage((relPages > 0) ? book : Book(), page + 0); if (relPages > 0)
getPage(RightBookPage)->showPage((relPages > 0) ? std::move(book) : Book(), page + 1); {
getPage(LeftBookPage)->showPage(book, page + 0);
getPage(RightBookPage)->showPage(std::move(book), page + 1);
}
else
{
getPage(LeftBookPage)->showPage({}, page + 0);
getPage(RightBookPage)->showPage({}, page + 1);
}
setText(PageOneNum, page + 1); setText(PageOneNum, page + 1);
setText(PageTwoNum, page + 2); setText(PageTwoNum, page + 2);
@ -410,14 +420,14 @@ namespace
notifyNextPage(sender); notifyNextPage(sender);
} }
void notifyTopicClicked(intptr_t linkId) void notifyTopicClicked(const MWDialogue::Topic& topic)
{ {
Book topicBook = createTopicBook(linkId); std::shared_ptr<MWGui::TypesetBook> topicBook = createTopicBook(topic);
if (mStates.size() > 1) if (mStates.size() > 1)
replaceBook(topicBook, 0); replaceBook(topicBook);
else else
pushBook(topicBook, 0); pushBook(topicBook);
setVisible(OptionsOverlay, false); setVisible(OptionsOverlay, false);
setVisible(OptionsBTN, true); setVisible(OptionsBTN, true);
@ -434,22 +444,19 @@ namespace
{ {
ESM::RefId topic = ESM::RefId::stringRefId(topicIdString); ESM::RefId topic = ESM::RefId::stringRefId(topicIdString);
const MWBase::Journal* journal = MWBase::Environment::get().getJournal(); const MWBase::Journal* journal = MWBase::Environment::get().getJournal();
intptr_t topicId = 0; /// \todo get rid of intptr ids
const auto it = journal->getTopics().find(topic); const auto it = journal->getTopics().find(topic);
if (it != journal->getTopics().end()) if (it != journal->getTopics().end())
topicId = intptr_t(&it->second); notifyTopicClicked(it->second);
notifyTopicClicked(topicId);
} }
void notifyQuestClicked(const std::string& name, int id) void notifyQuestClicked(const std::string& name, int id)
{ {
Book book = createQuestBook(name); std::shared_ptr<MWGui::TypesetBook> book = createQuestBook(name);
if (mStates.size() > 1) if (mStates.size() > 1)
replaceBook(book, 0); replaceBook(book);
else else
pushBook(book, 0); pushBook(book);
setVisible(OptionsOverlay, false); setVisible(OptionsOverlay, false);
setVisible(OptionsBTN, true); setVisible(OptionsBTN, true);
@ -508,7 +515,7 @@ namespace
} }
} }
void notifyIndexLinkClicked(MWGui::TypesetBook::InteractiveId index) void notifyIndexLinkClicked(Utf8Stream::UnicodeChar index)
{ {
setVisible(LeftTopicIndex, false); setVisible(LeftTopicIndex, false);
setVisible(CenterTopicIndex, false); setVisible(CenterTopicIndex, false);
@ -604,7 +611,7 @@ namespace
if (Settings::gui().mControllerMenus) if (Settings::gui().mControllerMenus)
{ {
addControllerButtons(list, mSelectedQuest); addControllerButtons(list, mSelectedQuest);
setControllerFocusedQuest(MWGui::wrap(mSelectedQuest, mButtons.size())); setControllerFocusedQuest(std::min(mSelectedQuest, mButtons.size()));
} }
if (mAllQuests) if (mAllQuests)
@ -663,8 +670,8 @@ namespace
return; return;
if (!mStates.empty()) if (!mStates.empty())
{ {
unsigned int& page = mStates.top().mPage; size_t& page = mStates.top().mPage;
Book book = mStates.top().mBook; std::shared_ptr<MWGui::TypesetBook> book = mStates.top().mBook;
if (page + 2 < book->pageCount()) if (page + 2 < book->pageCount())
{ {
@ -682,7 +689,7 @@ namespace
return; return;
if (!mStates.empty()) if (!mStates.empty())
{ {
unsigned int& page = mStates.top().mPage; size_t& page = mStates.top().mPage;
if (page >= 2) if (page >= 2)
{ {
@ -718,8 +725,8 @@ namespace
void setIndexControllerFocus(bool focused) void setIndexControllerFocus(bool focused)
{ {
int col = mSelectedIndex / mIndexRowCount; size_t col = mSelectedIndex / mIndexRowCount;
int row = mSelectedIndex % mIndexRowCount; size_t row = mSelectedIndex % mIndexRowCount;
mTopicIndexBook->setColour(col, row, 0, focused ? MWGui::journalHeaderColour : MyGUI::Colour::Black); mTopicIndexBook->setColour(col, row, 0, focused ? MWGui::journalHeaderColour : MyGUI::Colour::Black);
} }
@ -728,7 +735,7 @@ namespace
setIndexControllerFocus(false); setIndexControllerFocus(false);
int numChars = mEncoding == ToUTF8::WINDOWS_1251 ? 30 : 26; int numChars = mEncoding == ToUTF8::WINDOWS_1251 ? 30 : 26;
int col = mSelectedIndex / mIndexRowCount; size_t col = mSelectedIndex / mIndexRowCount;
if (offset == -1) // Up if (offset == -1) // Up
{ {
@ -785,7 +792,8 @@ namespace
if (mSelectedIndex >= 27) if (mSelectedIndex >= 27)
russianOffset++; // 27, not 28, because of skipping char 26 russianOffset++; // 27, not 28, because of skipping char 26
bool isRussian = (mEncoding == ToUTF8::WINDOWS_1251); bool isRussian = (mEncoding == ToUTF8::WINDOWS_1251);
notifyIndexLinkClicked(isRussian ? mSelectedIndex + russianOffset : mSelectedIndex + 'A'); size_t ch = isRussian ? mSelectedIndex + russianOffset : mSelectedIndex + 'A';
notifyIndexLinkClicked(static_cast<Utf8Stream::UnicodeChar>(ch));
} }
} }
else if (arg.button == SDL_CONTROLLER_BUTTON_B) // B: Back else if (arg.button == SDL_CONTROLLER_BUTTON_B) // B: Back
@ -836,7 +844,7 @@ namespace
return true; return true;
// Scroll through the list of quests or topics // Scroll through the list of quests or topics
setControllerFocusedQuest(MWGui::wrap(mSelectedQuest - 1, mButtons.size())); setControllerFocusedQuest(MWGui::wrap(mSelectedQuest, mButtons.size(), -1));
} }
else else
moveSelectedIndex(-1); moveSelectedIndex(-1);
@ -849,19 +857,19 @@ namespace
return true; return true;
// Scroll through the list of quests or topics // Scroll through the list of quests or topics
setControllerFocusedQuest(MWGui::wrap(mSelectedQuest + 1, mButtons.size())); setControllerFocusedQuest(MWGui::wrap(mSelectedQuest, mButtons.size(), 1));
} }
else else
moveSelectedIndex(1); moveSelectedIndex(1);
} }
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_LEFT && !mQuestMode && !mTopicsMode) else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_LEFT && !mQuestMode && !mTopicsMode)
moveSelectedIndex(-mIndexRowCount); moveSelectedIndex(-static_cast<int>(mIndexRowCount));
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_RIGHT && !mQuestMode && !mTopicsMode) else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_RIGHT && !mQuestMode && !mTopicsMode)
moveSelectedIndex(mIndexRowCount); moveSelectedIndex(static_cast<int>(mIndexRowCount));
else if (arg.button == SDL_CONTROLLER_BUTTON_LEFTSHOULDER && (mQuestMode || mTopicsMode)) else if (arg.button == SDL_CONTROLLER_BUTTON_LEFTSHOULDER && (mQuestMode || mTopicsMode))
{ {
// Scroll up 5 items in the list of quests or topics // Scroll up 5 items in the list of quests or topics
setControllerFocusedQuest(std::max(static_cast<int>(mSelectedQuest) - 5, 0)); setControllerFocusedQuest(mSelectedQuest >= 5 ? mSelectedQuest - 5 : 0);
} }
else if (arg.button == SDL_CONTROLLER_BUTTON_RIGHTSHOULDER && (mQuestMode || mTopicsMode)) else if (arg.button == SDL_CONTROLLER_BUTTON_RIGHTSHOULDER && (mQuestMode || mTopicsMode))
{ {
@ -945,7 +953,7 @@ namespace
// glue the implementation to the interface // glue the implementation to the interface
std::unique_ptr<MWGui::JournalWindow> MWGui::JournalWindow::create( std::unique_ptr<MWGui::JournalWindow> MWGui::JournalWindow::create(
JournalViewModel::Ptr model, bool questList, ToUTF8::FromType encoding) std::shared_ptr<JournalViewModel> model, bool questList, ToUTF8::FromType encoding)
{ {
return std::make_unique<JournalWindowImpl>(model, questList, encoding); return std::make_unique<JournalWindowImpl>(model, questList, encoding);
} }

View file

@ -36,10 +36,6 @@ namespace MWGui
size_t mIndexRowCount = 1; size_t mIndexRowCount = 1;
size_t mSelectedQuest = 0; size_t mSelectedQuest = 0;
size_t mSelectedIndex = 0; size_t mSelectedIndex = 0;
void moveSelectedIndex(int offset);
void setIndexControllerFocus(bool focused);
void setControllerFocusedQuest(size_t index);
bool optionsModeButtonHandler(const SDL_ControllerButtonEvent& arg);
}; };
} }

View file

@ -111,7 +111,7 @@ namespace MWGui
for (const ESM::Attribute& attribute : MWBase::Environment::get().getESMStore()->get<ESM::Attribute>()) for (const ESM::Attribute& attribute : MWBase::Environment::get().getESMStore()->get<ESM::Attribute>())
{ {
int val = creatureStats.getAttribute(attribute.mId).getBase(); int val = static_cast<int>(creatureStats.getAttribute(attribute.mId).getBase());
if (std::find(mSpentAttributes.begin(), mSpentAttributes.end(), attribute.mId) != mSpentAttributes.end()) if (std::find(mSpentAttributes.begin(), mSpentAttributes.end(), attribute.mId) != mSpentAttributes.end())
{ {
val += pcStats.getLevelupAttributeMultiplier(attribute.mId); val += pcStats.getLevelupAttributeMultiplier(attribute.mId);
@ -202,8 +202,8 @@ namespace MWGui
widgets.mValue->setEnabled(true); widgets.mValue->setEnabled(true);
availableAttributes++; availableAttributes++;
float mult = pcStats.getLevelupAttributeMultiplier(attribute.mId); int mult = pcStats.getLevelupAttributeMultiplier(attribute.mId);
mult = std::min(mult, 100 - pcStats.getAttribute(attribute.mId).getBase()); mult = std::min(mult, static_cast<int>(100 - pcStats.getAttribute(attribute.mId).getBase()));
if (mult <= 1) if (mult <= 1)
widgets.mMultiplier->setCaption({}); widgets.mMultiplier->setCaption({});
else else
@ -231,7 +231,7 @@ namespace MWGui
{ {
mControllerFocus = 0; mControllerFocus = 0;
for (size_t i = 0; i < mAttributeButtons.size(); i++) for (size_t i = 0; i < mAttributeButtons.size(); i++)
setControllerFocus(mAttributeButtons, i, i == 0); mAttributeButtons[i]->setStateSelected(i == 0);
} }
// Play LevelUp Music // Play LevelUp Music

View file

@ -120,8 +120,9 @@ namespace MWGui
void operator()(osg::RenderInfo& renderInfo) const override void operator()(osg::RenderInfo& renderInfo) const override
{ {
int w = renderInfo.getCurrentCamera()->getViewport()->width(); const osg::Viewport* viewPort = renderInfo.getCurrentCamera()->getViewport();
int h = renderInfo.getCurrentCamera()->getViewport()->height(); int w = static_cast<int>(viewPort->width());
int h = static_cast<int>(viewPort->height());
mTexture->copyTexImage2D(*renderInfo.getState(), 0, 0, w, h); mTexture->copyTexImage2D(*renderInfo.getState(), 0, 0, w, h);
mOneshot = false; mOneshot = false;
@ -259,10 +260,10 @@ namespace MWGui
return false; return false;
// the minimal delay before a loading screen shows // the minimal delay before a loading screen shows
const float initialDelay = 0.05; constexpr float initialDelay = 0.05f;
bool alreadyShown = (mLastRenderTime > mLoadingOnTime); bool alreadyShown = (mLastRenderTime > mLoadingOnTime);
float diff = (mTimer.time_m() - mLoadingOnTime); double diff = (mTimer.time_m() - mLoadingOnTime);
if (!alreadyShown) if (!alreadyShown)
{ {

View file

@ -71,7 +71,7 @@ namespace MWGui
size_t mProgress; size_t mProgress;
bool mShowWallpaper; bool mShowWallpaper;
float mOldIcoMin = 0.f; double mOldIcoMin = 0.0;
unsigned int mOldIcoMax = 0; unsigned int mOldIcoMax = 0;
MyGUI::Widget* mLoadingBox; MyGUI::Widget* mLoadingBox;

View file

@ -364,10 +364,10 @@ namespace MWGui
// Trim off some of the excessive padding // Trim off some of the excessive padding
// TODO: perhaps do this within ImageButton? // TODO: perhaps do this within ImageButton?
int height = requested.height; int height = requested.height;
button->setImageTile(MyGUI::IntSize(requested.width, requested.height - 16 * scale)); button->setImageTile(MyGUI::IntSize(requested.width, static_cast<int>(requested.height - 16 * scale)));
button->setCoord( button->setCoord(static_cast<int>((maxwidth - requested.width / scale) / 2), curH,
(maxwidth - requested.width / scale) / 2, curH, requested.width / scale, height / scale - 16); static_cast<int>(requested.width / scale), static_cast<int>(height / scale - 16));
curH += height / scale - 16; curH += static_cast<int>(height / scale - 16);
} }
if (state == MWBase::StateManager::State_NoGame) if (state == MWBase::StateManager::State_NoGame)

View file

@ -92,7 +92,8 @@ namespace
return Constants::CellGridRadius; return Constants::CellGridRadius;
if (!Settings::terrain().mDistantTerrain) if (!Settings::terrain().mDistantTerrain)
return Constants::CellGridRadius; return Constants::CellGridRadius;
const int viewingDistanceInCells = Settings::camera().mViewingDistance / Constants::CellSizeInUnits; const int viewingDistanceInCells
= static_cast<int>(Settings::camera().mViewingDistance / Constants::CellSizeInUnits);
return std::clamp( return std::clamp(
viewingDistanceInCells, Constants::CellGridRadius, Settings::map().mMaxLocalViewingDistance.get()); viewingDistanceInCells, Constants::CellGridRadius, Settings::map().mMaxLocalViewingDistance.get());
} }
@ -255,8 +256,8 @@ namespace MWGui
{ {
// normalized cell coordinates // normalized cell coordinates
auto mapWidgetSize = getWidgetSize(); auto mapWidgetSize = getWidgetSize();
return MyGUI::IntPoint(std::round((nX + cellX - mGrid.left) * mapWidgetSize), return MyGUI::IntPoint(static_cast<int>(std::round((nX + cellX - mGrid.left) * mapWidgetSize)),
std::round((nY - cellY + mGrid.bottom) * mapWidgetSize)); static_cast<int>(std::round((nY - cellY + mGrid.bottom) * mapWidgetSize)));
} }
MyGUI::IntPoint LocalMapBase::getMarkerPosition(float worldX, float worldY, MarkerUserData& markerPos) const MyGUI::IntPoint LocalMapBase::getMarkerPosition(float worldX, float worldY, MarkerUserData& markerPos) const
@ -286,7 +287,7 @@ namespace MWGui
} }
MyGUI::IntCoord LocalMapBase::getMarkerCoordinates( MyGUI::IntCoord LocalMapBase::getMarkerCoordinates(
float worldX, float worldY, MarkerUserData& markerPos, size_t markerSize) const float worldX, float worldY, MarkerUserData& markerPos, unsigned short markerSize) const
{ {
int halfMarkerSize = markerSize / 2; int halfMarkerSize = markerSize / 2;
auto position = getMarkerPosition(worldX, worldY, markerPos); auto position = getMarkerPosition(worldX, worldY, markerPos);
@ -320,7 +321,7 @@ namespace MWGui
mLocalMap->setViewOffset(viewOffset); mLocalMap->setViewOffset(viewOffset);
} }
MyGUI::IntCoord LocalMapBase::getMarkerCoordinates(MyGUI::Widget* widget, size_t markerSize) const MyGUI::IntCoord LocalMapBase::getMarkerCoordinates(MyGUI::Widget* widget, unsigned short markerSize) const
{ {
MarkerUserData& markerPos(*widget->getUserData<MarkerUserData>()); MarkerUserData& markerPos(*widget->getUserData<MarkerUserData>());
auto position = getPosition(markerPos.cellX, markerPos.cellY, markerPos.nX, markerPos.nY); auto position = getPosition(markerPos.cellX, markerPos.cellY, markerPos.nX, markerPos.nY);
@ -453,7 +454,7 @@ namespace MWGui
} }
if (oldSize != MyGUI::IntSize{ mGrid.width(), mGrid.height() }) if (oldSize != MyGUI::IntSize{ mGrid.width(), mGrid.height() })
setCanvasSize(mLocalMap, mGrid, getWidgetSize()); setCanvasSize(mLocalMap, mGrid, static_cast<int>(getWidgetSize()));
// Delay the door markers update until scripts have been given a chance to run. // Delay the door markers update until scripts have been given a chance to run.
// If we don't do this, door markers that should be disabled will still appear on the map. // If we don't do this, door markers that should be disabled will still appear on the map.
@ -665,8 +666,7 @@ namespace MWGui
{ {
std::vector<std::string> destNotes; std::vector<std::string> destNotes;
CustomMarkerCollection::RangeType markers = mCustomMarkers.getMarkers(marker.dest); CustomMarkerCollection::RangeType markers = mCustomMarkers.getMarkers(marker.dest);
for (CustomMarkerCollection::ContainerType::const_iterator iter = markers.first; iter != markers.second; for (auto iter = markers.first; iter != markers.second; ++iter)
++iter)
destNotes.push_back(iter->second.mNote); destNotes.push_back(iter->second.mNote);
MyGUI::Widget* markerWidget = nullptr; MyGUI::Widget* markerWidget = nullptr;
@ -733,9 +733,10 @@ namespace MWGui
void LocalMapBase::updateLocalMap() void LocalMapBase::updateLocalMap()
{ {
auto mapWidgetSize = getWidgetSize(); auto mapWidgetSize = getWidgetSize();
setCanvasSize(mLocalMap, mGrid, getWidgetSize()); setCanvasSize(mLocalMap, mGrid, static_cast<int>(getWidgetSize()));
const auto size = MyGUI::IntSize(std::ceil(mapWidgetSize), std::ceil(mapWidgetSize)); const auto size
= MyGUI::IntSize(static_cast<int>(std::ceil(mapWidgetSize)), static_cast<int>(std::ceil(mapWidgetSize)));
for (auto& entry : mMaps) for (auto& entry : mMaps)
{ {
const auto position = getPosition(entry.mCellX, entry.mCellY, 0, 0); const auto position = getPosition(entry.mCellX, entry.mCellY, 0, 0);
@ -917,7 +918,7 @@ namespace MWGui
const int localWidgetSize = Settings::map().mLocalMapWidgetSize; const int localWidgetSize = Settings::map().mLocalMapWidgetSize;
const bool zoomOut = rel < 0; const bool zoomOut = rel < 0;
const bool zoomIn = !zoomOut; const bool zoomIn = !zoomOut;
const double speedDiff = zoomOut ? 1.0 / speed : speed; const float speedDiff = zoomOut ? 1.f / speed : speed;
const float currentMinLocalMapZoom const float currentMinLocalMapZoom
= std::max({ (float(Settings::map().mGlobalMapCellSize) * 4.f) / float(localWidgetSize), = std::max({ (float(Settings::map().mGlobalMapCellSize) * 4.f) / float(localWidgetSize),
@ -985,8 +986,8 @@ namespace MWGui
Settings::map().mGlobal ? updateGlobalMap() : updateLocalMap(); Settings::map().mGlobal ? updateGlobalMap() : updateLocalMap();
map->setViewOffset(MyGUI::IntPoint(std::round(centerView.left * speedDiff) + cursor.left, map->setViewOffset(MyGUI::IntPoint(static_cast<int>(std::round(centerView.left * speedDiff) + cursor.left),
std::round(centerView.top * speedDiff) + cursor.top)); static_cast<int>(std::round(centerView.top * speedDiff) + cursor.top)));
} }
void MapWindow::updateGlobalMap() void MapWindow::updateGlobalMap()
@ -1004,7 +1005,8 @@ namespace MWGui
for (auto& [marker, col] : mGlobalMapMarkers) for (auto& [marker, col] : mGlobalMapMarkers)
{ {
marker.widget->setCoord(createMarkerCoords(marker.position.x(), marker.position.y(), col.size())); marker.widget->setCoord(
createMarkerCoords(marker.position.x(), marker.position.y(), static_cast<float>(col.size())));
marker.widget->setVisible(marker.widget->getHeight() >= 6); marker.widget->setVisible(marker.widget->getHeight() >= 6);
} }
} }
@ -1036,10 +1038,10 @@ namespace MWGui
// Restore the window to pinned size. // Restore the window to pinned size.
MyGUI::Window* window = mMainWidget->castType<MyGUI::Window>(); MyGUI::Window* window = mMainWidget->castType<MyGUI::Window>();
MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize(); MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize();
const float x = Settings::windows().mMapX * viewSize.width; const int x = static_cast<int>(Settings::windows().mMapX * viewSize.width);
const float y = Settings::windows().mMapY * viewSize.height; const int y = static_cast<int>(Settings::windows().mMapY * viewSize.height);
const float w = Settings::windows().mMapW * viewSize.width; const int w = static_cast<int>(Settings::windows().mMapW * viewSize.width);
const float h = Settings::windows().mMapH * viewSize.height; const int h = static_cast<int>(Settings::windows().mMapH * viewSize.height);
window->setCoord(x, y, w, h); window->setCoord(x, y, w, h);
} }
} }
@ -1063,10 +1065,10 @@ namespace MWGui
worldPosToGlobalMapImageSpace( worldPosToGlobalMapImageSpace(
(x + 0.5f) * Constants::CellSizeInUnits, (y + 0.5f) * Constants::CellSizeInUnits, worldX, worldY); (x + 0.5f) * Constants::CellSizeInUnits, (y + 0.5f) * Constants::CellSizeInUnits, worldX, worldY);
const float markerSize = getMarkerSize(agregatedWeight); const float markerSize = getMarkerSize(static_cast<size_t>(agregatedWeight));
const float halfMarkerSize = markerSize / 2.0f; const float halfMarkerSize = markerSize / 2.0f;
return MyGUI::IntCoord(static_cast<int>(worldX - halfMarkerSize), static_cast<int>(worldY - halfMarkerSize), return MyGUI::IntCoord(static_cast<int>(worldX - halfMarkerSize), static_cast<int>(worldY - halfMarkerSize),
markerSize, markerSize); static_cast<int>(markerSize), static_cast<int>(markerSize));
} }
MyGUI::Widget* MapWindow::createMarker(const std::string& name, float x, float y, float agregatedWeight) MyGUI::Widget* MapWindow::createMarker(const std::string& name, float x, float y, float agregatedWeight)
@ -1075,7 +1077,7 @@ namespace MWGui
"MarkerButton", createMarkerCoords(x, y, agregatedWeight), MyGUI::Align::Default); "MarkerButton", createMarkerCoords(x, y, agregatedWeight), MyGUI::Align::Default);
markerWidget->setVisible(markerWidget->getHeight() >= 6.0); markerWidget->setVisible(markerWidget->getHeight() >= 6.0);
markerWidget->setUserString("Caption_TextOneLine", "#{sCell=" + name + "}"); markerWidget->setUserString("Caption_TextOneLine", "#{sCell=" + name + "}");
setGlobalMapMarkerTooltip(markerWidget, x, y); setGlobalMapMarkerTooltip(markerWidget, static_cast<int>(x), static_cast<int>(y));
markerWidget->setUserString("ToolTipLayout", "TextToolTipOneLine"); markerWidget->setUserString("ToolTipLayout", "TextToolTipOneLine");
@ -1098,14 +1100,15 @@ namespace MWGui
cell.second = y; cell.second = y;
if (mMarkers.insert(cell).second) if (mMarkers.insert(cell).second)
{ {
MapMarkerType mapMarkerWidget = { osg::Vec2f(x, y), createMarker(name, x, y, 0) }; const osg::Vec2f pos(static_cast<float>(x), static_cast<float>(y));
MapMarkerType mapMarkerWidget = { pos, createMarker(name, pos.x(), pos.y(), 0) };
mGlobalMapMarkers.emplace(mapMarkerWidget, std::vector<MapMarkerType>()); mGlobalMapMarkers.emplace(mapMarkerWidget, std::vector<MapMarkerType>());
const std::string markerName = name.substr(0, name.find(',')); const std::string markerName = name.substr(0, name.find(','));
auto& entry = mGlobalMapMarkersByName[markerName]; auto& entry = mGlobalMapMarkersByName[markerName];
if (!entry.widget) if (!entry.widget)
{ {
entry = { osg::Vec2f(x, y), entry.widget }; // update the coords entry = { pos, entry.widget }; // update the coords
entry.widget = createMarker(markerName, entry.position.x(), entry.position.y(), 1); entry.widget = createMarker(markerName, entry.position.x(), entry.position.y(), 1);
mGlobalMapMarkers.emplace(entry, std::vector<MapMarkerType>{ entry }); mGlobalMapMarkers.emplace(entry, std::vector<MapMarkerType>{ entry });
@ -1123,7 +1126,8 @@ namespace MWGui
[](const auto& left, const auto& right) { return left + right.position; }) [](const auto& left, const auto& right) { return left + right.position; })
/ float(elements.size()); / float(elements.size());
marker.widget->setCoord(createMarkerCoords(marker.position.x(), marker.position.y(), elements.size())); marker.widget->setCoord(
createMarkerCoords(marker.position.x(), marker.position.y(), static_cast<float>(elements.size())));
marker.widget->setVisible(marker.widget->getHeight() >= 6); marker.widget->setVisible(marker.widget->getHeight() >= 6);
} }
} }
@ -1167,16 +1171,16 @@ namespace MWGui
{ {
float markerSize = 12.f * mGlobalMapZoom; float markerSize = 12.f * mGlobalMapZoom;
if (mGlobalMapZoom < 1) if (mGlobalMapZoom < 1)
return markerSize * std::sqrt(agregatedWeight); // we want to see agregated object return static_cast<float>(markerSize * std::sqrt(agregatedWeight)); // we want to see agregated object
return agregatedWeight ? 0 : markerSize; // we want to see only original markers (i.e. non agregated) return agregatedWeight ? 0 : markerSize; // we want to see only original markers (i.e. non agregated)
} }
void MapWindow::resizeGlobalMap() void MapWindow::resizeGlobalMap()
{ {
mGlobalMap->setCanvasSize( int width = static_cast<int>(mGlobalMapRender->getWidth() * mGlobalMapZoom);
mGlobalMapRender->getWidth() * mGlobalMapZoom, mGlobalMapRender->getHeight() * mGlobalMapZoom); int height = static_cast<int>(mGlobalMapRender->getHeight() * mGlobalMapZoom);
mGlobalMapImage->setSize( mGlobalMap->setCanvasSize(width, height);
mGlobalMapRender->getWidth() * mGlobalMapZoom, mGlobalMapRender->getHeight() * mGlobalMapZoom); mGlobalMapImage->setSize(width, height);
} }
void MapWindow::worldPosToGlobalMapImageSpace(float x, float y, float& imageX, float& imageY) const void MapWindow::worldPosToGlobalMapImageSpace(float x, float y, float& imageX, float& imageY) const
@ -1191,7 +1195,8 @@ namespace MWGui
LocalMapBase::updateCustomMarkers(); LocalMapBase::updateCustomMarkers();
for (auto& [widgetPair, ignore] : mGlobalMapMarkers) for (auto& [widgetPair, ignore] : mGlobalMapMarkers)
setGlobalMapMarkerTooltip(widgetPair.widget, widgetPair.position.x(), widgetPair.position.y()); setGlobalMapMarkerTooltip(widgetPair.widget, static_cast<int>(widgetPair.position.x()),
static_cast<int>(widgetPair.position.y()));
} }
void MapWindow::onDragStart(MyGUI::Widget* /*sender*/, int left, int top, MyGUI::MouseButton id) void MapWindow::onDragStart(MyGUI::Widget* /*sender*/, int left, int top, MyGUI::MouseButton id)
@ -1574,7 +1579,7 @@ namespace MWGui
{ {
if (getDeleteButtonShown()) if (getDeleteButtonShown())
{ {
mControllerFocus = wrap(mControllerFocus - 1, 3); mControllerFocus = wrap(mControllerFocus, 3, -1);
mDeleteButton->setStateSelected(mControllerFocus == 0); mDeleteButton->setStateSelected(mControllerFocus == 0);
mOkButton->setStateSelected(mControllerFocus == 1); mOkButton->setStateSelected(mControllerFocus == 1);
mCancelButton->setStateSelected(mControllerFocus == 2); mCancelButton->setStateSelected(mControllerFocus == 2);
@ -1590,7 +1595,7 @@ namespace MWGui
{ {
if (getDeleteButtonShown()) if (getDeleteButtonShown())
{ {
mControllerFocus = wrap(mControllerFocus + 1, 3); mControllerFocus = wrap(mControllerFocus, 3, 1);
mDeleteButton->setStateSelected(mControllerFocus == 0); mDeleteButton->setStateSelected(mControllerFocus == 0);
mOkButton->setStateSelected(mControllerFocus == 1); mOkButton->setStateSelected(mControllerFocus == 1);
mCancelButton->setStateSelected(mControllerFocus == 2); mCancelButton->setStateSelected(mControllerFocus == 2);

View file

@ -163,9 +163,9 @@ namespace MWGui
MyGUI::IntPoint getPosition(int cellX, int cellY, float nx, float ny) const; MyGUI::IntPoint getPosition(int cellX, int cellY, float nx, float ny) const;
MyGUI::IntPoint getMarkerPosition(float worldX, float worldY, MarkerUserData& markerPos) const; MyGUI::IntPoint getMarkerPosition(float worldX, float worldY, MarkerUserData& markerPos) const;
MyGUI::IntCoord getMarkerCoordinates( MyGUI::IntCoord getMarkerCoordinates(
float worldX, float worldY, MarkerUserData& markerPos, size_t markerSize) const; float worldX, float worldY, MarkerUserData& markerPos, unsigned short markerSize) const;
MyGUI::Widget* createDoorMarker(const std::string& name, float x, float y) const; MyGUI::Widget* createDoorMarker(const std::string& name, float x, float y) const;
MyGUI::IntCoord getMarkerCoordinates(MyGUI::Widget* widget, size_t markerSize) const; MyGUI::IntCoord getMarkerCoordinates(MyGUI::Widget* widget, unsigned short markerSize) const;
virtual void notifyPlayerUpdate() {} virtual void notifyPlayerUpdate() {}
virtual void centerView(); virtual void centerView();
@ -225,7 +225,7 @@ namespace MWGui
MyGUI::Button* mDeleteButton; MyGUI::Button* mDeleteButton;
bool onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) override; bool onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) override;
int mControllerFocus = 0; size_t mControllerFocus = 0;
}; };
class MapWindow : public MWGui::WindowPinnableBase, public LocalMapBase, public NoDrop class MapWindow : public MWGui::WindowPinnableBase, public LocalMapBase, public NoDrop

View file

@ -191,7 +191,7 @@ namespace MWGui
return true; return true;
mButtons[mControllerFocus].first->setStateSelected(false); mButtons[mControllerFocus].first->setStateSelected(false);
mControllerFocus = wrap(mControllerFocus - 1, mButtons.size()); mControllerFocus = wrap(mControllerFocus, mButtons.size(), -1);
mButtons[mControllerFocus].first->setStateSelected(true); mButtons[mControllerFocus].first->setStateSelected(true);
} }
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_DOWN) else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_DOWN)
@ -200,7 +200,7 @@ namespace MWGui
return true; return true;
mButtons[mControllerFocus].first->setStateSelected(false); mButtons[mControllerFocus].first->setStateSelected(false);
mControllerFocus = wrap(mControllerFocus + 1, mButtons.size()); mControllerFocus = wrap(mControllerFocus, mButtons.size(), 1);
mButtons[mControllerFocus].first->setStateSelected(true); mButtons[mControllerFocus].first->setStateSelected(true);
} }
@ -213,7 +213,7 @@ namespace MWGui
else else
{ {
const int lineHeight = Settings::gui().mFontSize + 2; const int lineHeight = Settings::gui().mFontSize + 2;
mList->setViewOffset(MyGUI::IntPoint(0, -lineHeight * (line - 5))); mList->setViewOffset(MyGUI::IntPoint(0, -lineHeight * static_cast<int>(line - 5)));
} }
} }

View file

@ -473,7 +473,7 @@ namespace MWGui
return true; return true;
setControllerFocus(mButtons, mControllerFocus, false); setControllerFocus(mButtons, mControllerFocus, false);
mControllerFocus = wrap(mControllerFocus - 1, mButtons.size()); mControllerFocus = wrap(mControllerFocus, mButtons.size(), -1);
setControllerFocus(mButtons, mControllerFocus, true); setControllerFocus(mButtons, mControllerFocus, true);
} }
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_DOWN || arg.button == SDL_CONTROLLER_BUTTON_DPAD_RIGHT) else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_DOWN || arg.button == SDL_CONTROLLER_BUTTON_DPAD_RIGHT)
@ -484,7 +484,7 @@ namespace MWGui
return true; return true;
setControllerFocus(mButtons, mControllerFocus, false); setControllerFocus(mButtons, mControllerFocus, false);
mControllerFocus = wrap(mControllerFocus + 1, mButtons.size()); mControllerFocus = wrap(mControllerFocus, mButtons.size(), 1);
setControllerFocus(mButtons, mControllerFocus, true); setControllerFocus(mButtons, mControllerFocus, true);
} }

View file

@ -34,7 +34,7 @@ namespace MWGui
for (size_t i = 0; i < mSourceModel->getItemCount(); ++i) for (size_t i = 0; i < mSourceModel->getItemCount(); ++i)
{ {
if (Misc::Rng::roll0to99(prng) > chance) if (Misc::Rng::roll0to99(prng) > chance)
mHiddenItems.push_back(mSourceModel->getItem(i)); mHiddenItems.push_back(mSourceModel->getItem(static_cast<ModelIndex>(i)));
} }
} }
} }
@ -64,7 +64,7 @@ namespace MWGui
mItems.clear(); mItems.clear();
for (size_t i = 0; i < mSourceModel->getItemCount(); ++i) for (size_t i = 0; i < mSourceModel->getItemCount(); ++i)
{ {
const ItemStack& item = mSourceModel->getItem(i); const ItemStack& item = mSourceModel->getItem(static_cast<ModelIndex>(i));
// Bound items may not be stolen // Bound items may not be stolen
if (item.mFlags & ItemStack::Flag_Bound) if (item.mFlags & ItemStack::Flag_Bound)

View file

@ -172,16 +172,16 @@ namespace MWGui
if (selected == MyGUI::ITEM_NONE) if (selected == MyGUI::ITEM_NONE)
return; return;
int index = direction == Direction::Up ? static_cast<int>(selected) - 1 : selected + 1; size_t index = direction == Direction::Up ? selected - 1 : selected + 1;
index = std::clamp<int>(index, 0, mActiveList->getItemCount() - 1); index = std::clamp<size_t>(index, 0, mActiveList->getItemCount() - 1);
if (static_cast<size_t>(index) != selected) if (index != selected)
{ {
auto technique = getTechnique(*mActiveList, selected); auto technique = getTechnique(*mActiveList, selected);
if (technique->getDynamic() || technique->getInternal()) if (technique->getDynamic() || technique->getInternal())
return; return;
if (processor->enableTechnique(std::move(technique), index - mOffset) if (processor->enableTechnique(std::move(technique), static_cast<int>(index) - mOffset)
!= MWRender::PostProcessor::Status_Error) != MWRender::PostProcessor::Status_Error)
processor->saveChain(); processor->saveChain();
} }
@ -279,7 +279,7 @@ namespace MWGui
void PostProcessorHud::notifyMouseWheel(MyGUI::Widget* /*sender*/, int rel) void PostProcessorHud::notifyMouseWheel(MyGUI::Widget* /*sender*/, int rel)
{ {
int offset = mConfigLayout->getViewOffset().top + rel * 0.3; double offset = mConfigLayout->getViewOffset().top + rel * 0.3;
if (offset > 0) if (offset > 0)
mConfigLayout->setViewOffset(MyGUI::IntPoint(0, 0)); mConfigLayout->setViewOffset(MyGUI::IntPoint(0, 0));
else else

View file

@ -290,8 +290,8 @@ namespace MWGui
if (texture) if (texture)
scale = texture->getHeight() / 64.f; scale = texture->getHeight() / 64.f;
mSelected->button->setFrame( mSelected->button->setFrame("textures\\menu_icon_select_magic_magic.dds",
"textures\\menu_icon_select_magic_magic.dds", MyGUI::IntCoord(0, 0, 44 * scale, 44 * scale)); MyGUI::IntCoord(0, 0, static_cast<int>(44 * scale), static_cast<int>(44 * scale)));
mSelected->button->setIcon(item); mSelected->button->setIcon(item);
mSelected->button->setUserString("ToolTipType", "ItemPtr"); mSelected->button->setUserString("ToolTipType", "ItemPtr");
@ -324,8 +324,7 @@ namespace MWGui
std::string path = effect->mIcon; std::string path = effect->mIcon;
std::replace(path.begin(), path.end(), '/', '\\'); std::replace(path.begin(), path.end(), '/', '\\');
int slashPos = path.rfind('\\'); path.insert(path.rfind('\\') + 1, "b_");
path.insert(slashPos + 1, "b_");
path = Misc::ResourceHelpers::correctIconPath(path, MWBase::Environment::get().getResourceSystem()->getVFS()); path = Misc::ResourceHelpers::correctIconPath(path, MWBase::Environment::get().getResourceSystem()->getVFS());
float scale = 1.f; float scale = 1.f;
@ -334,8 +333,8 @@ namespace MWGui
if (texture) if (texture)
scale = texture->getHeight() / 64.f; scale = texture->getHeight() / 64.f;
mSelected->button->setFrame( const int diameter = static_cast<int>(44 * scale);
"textures\\menu_icon_select_magic.dds", MyGUI::IntCoord(0, 0, 44 * scale, 44 * scale)); mSelected->button->setFrame("textures\\menu_icon_select_magic.dds", MyGUI::IntCoord(0, 0, diameter, diameter));
mSelected->button->setIcon(path); mSelected->button->setIcon(path);
if (mMagicSelectionDialog) if (mMagicSelectionDialog)
@ -562,9 +561,9 @@ namespace MWGui
else if (arg.button == SDL_CONTROLLER_BUTTON_B) else if (arg.button == SDL_CONTROLLER_BUTTON_B)
mParent->onCancelButtonClicked(mCancelButton); mParent->onCancelButtonClicked(mCancelButton);
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_UP) else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_UP)
mControllerFocus = wrap(mControllerFocus - 1, 4); mControllerFocus = wrap(mControllerFocus, 4, -1);
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_DOWN) else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_DOWN)
mControllerFocus = wrap(mControllerFocus + 1, 4); mControllerFocus = wrap(mControllerFocus, 4, 1);
mItemButton->setStateSelected(mControllerFocus == 0); mItemButton->setStateSelected(mControllerFocus == 0);
mMagicButton->setStateSelected(mControllerFocus == 1); mMagicButton->setStateSelected(mControllerFocus == 1);

View file

@ -96,7 +96,7 @@ namespace MWGui
QuickKeysMenu* mParent; QuickKeysMenu* mParent;
bool onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) override; bool onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) override;
int mControllerFocus = 0; size_t mControllerFocus = 0;
}; };
class MagicSelectionDialog : public WindowModal class MagicSelectionDialog : public WindowModal
@ -117,7 +117,7 @@ namespace MWGui
void onModelIndexSelected(SpellModel::ModelIndex index); void onModelIndexSelected(SpellModel::ModelIndex index);
bool onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) override; bool onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) override;
int mControllerFocus = 0; size_t mControllerFocus = 0;
}; };
} }

View file

@ -248,7 +248,7 @@ namespace MWGui
void RaceDialog::onHeadRotate(MyGUI::ScrollBar* scroll, size_t position) void RaceDialog::onHeadRotate(MyGUI::ScrollBar* scroll, size_t position)
{ {
float angle = (float(position) / (scroll->getScrollRange() - 1) - 0.5f) * osg::PI * 2; float angle = (float(position) / (scroll->getScrollRange() - 1) - 0.5f) * osg::PIf * 2;
mPreview->setAngle(angle); mPreview->setAngle(angle);
mCurrentAngle = angle; mCurrentAngle = angle;
@ -256,7 +256,7 @@ namespace MWGui
void RaceDialog::onSelectPreviousGender(MyGUI::Widget*) void RaceDialog::onSelectPreviousGender(MyGUI::Widget*)
{ {
mGenderIndex = wrap(mGenderIndex - 1, 2); mGenderIndex = wrap(mGenderIndex, 2, -1);
recountParts(); recountParts();
updatePreview(); updatePreview();
@ -264,7 +264,7 @@ namespace MWGui
void RaceDialog::onSelectNextGender(MyGUI::Widget*) void RaceDialog::onSelectNextGender(MyGUI::Widget*)
{ {
mGenderIndex = wrap(mGenderIndex + 1, 2); mGenderIndex = wrap(mGenderIndex, 2, 1);
recountParts(); recountParts();
updatePreview(); updatePreview();
@ -272,25 +272,25 @@ namespace MWGui
void RaceDialog::onSelectPreviousFace(MyGUI::Widget*) void RaceDialog::onSelectPreviousFace(MyGUI::Widget*)
{ {
mFaceIndex = wrap(mFaceIndex - 1, mAvailableHeads.size()); mFaceIndex = wrap(mFaceIndex, mAvailableHeads.size(), -1);
updatePreview(); updatePreview();
} }
void RaceDialog::onSelectNextFace(MyGUI::Widget*) void RaceDialog::onSelectNextFace(MyGUI::Widget*)
{ {
mFaceIndex = wrap(mFaceIndex + 1, mAvailableHeads.size()); mFaceIndex = wrap(mFaceIndex, mAvailableHeads.size(), 1);
updatePreview(); updatePreview();
} }
void RaceDialog::onSelectPreviousHair(MyGUI::Widget*) void RaceDialog::onSelectPreviousHair(MyGUI::Widget*)
{ {
mHairIndex = wrap(mHairIndex - 1, mAvailableHairs.size()); mHairIndex = wrap(mHairIndex, mAvailableHairs.size(), -1);
updatePreview(); updatePreview();
} }
void RaceDialog::onSelectNextHair(MyGUI::Widget*) void RaceDialog::onSelectNextHair(MyGUI::Widget*)
{ {
mHairIndex = wrap(mHairIndex + 1, mAvailableHairs.size()); mHairIndex = wrap(mHairIndex, mAvailableHairs.size(), 1);
updatePreview(); updatePreview();
} }
@ -359,10 +359,10 @@ namespace MWGui
record.mRace = mCurrentRaceId; record.mRace = mCurrentRaceId;
record.setIsMale(mGenderIndex == 0); record.setIsMale(mGenderIndex == 0);
if (mFaceIndex >= 0 && mFaceIndex < int(mAvailableHeads.size())) if (mFaceIndex < mAvailableHeads.size())
record.mHead = mAvailableHeads[mFaceIndex]; record.mHead = mAvailableHeads[mFaceIndex];
if (mHairIndex >= 0 && mHairIndex < int(mAvailableHairs.size())) if (mHairIndex < mAvailableHairs.size())
record.mHair = mAvailableHairs[mHairIndex]; record.mHair = mAvailableHairs[mHairIndex];
try try

View file

@ -110,7 +110,7 @@ namespace MWGui
MyGUI::Widget* mSpellPowerList; MyGUI::Widget* mSpellPowerList;
std::vector<MyGUI::Widget*> mSpellPowerItems; std::vector<MyGUI::Widget*> mSpellPowerItems;
int mGenderIndex, mFaceIndex, mHairIndex; size_t mGenderIndex, mFaceIndex, mHairIndex;
ESM::RefId mCurrentRaceId; ESM::RefId mCurrentRaceId;

Some files were not shown because too many files have changed in this diff Show more