add animation buttons
This commit is contained in:
parent
112684b40a
commit
528e7ae5a6
BIN
assets.zip
BIN
assets.zip
Binary file not shown.
@ -31,9 +31,25 @@
|
|||||||
"y": 300,
|
"y": 300,
|
||||||
"width": 200,
|
"width": 200,
|
||||||
"height": 50,
|
"height": 50,
|
||||||
|
"animations": {
|
||||||
|
"buttonsExit": {
|
||||||
|
"repeat": false,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"type": "move",
|
||||||
|
"to": [
|
||||||
|
-400,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"duration": 1.0,
|
||||||
|
"easing": "easein"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
"textures": {
|
"textures": {
|
||||||
"normal": "./resources/button.png",
|
"normal": "./resources/button.png",
|
||||||
"hover": "./resources/button.png",
|
"hover": "./resources/sand.png",
|
||||||
"pressed": "./resources/button.png"
|
"pressed": "./resources/button.png"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -44,9 +60,29 @@
|
|||||||
"y": 200,
|
"y": 200,
|
||||||
"width": 200,
|
"width": 200,
|
||||||
"height": 50,
|
"height": 50,
|
||||||
|
"animations": {
|
||||||
|
"buttonsExit": {
|
||||||
|
"repeat": false,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"type": "wait",
|
||||||
|
"duration": 0.5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "move",
|
||||||
|
"to": [
|
||||||
|
-400,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"duration": 1.0,
|
||||||
|
"easing": "easein"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
"textures": {
|
"textures": {
|
||||||
"normal": "./resources/sand.png",
|
"normal": "./resources/sand.png",
|
||||||
"hover": "./resources/sand.png",
|
"hover": "./resources/button.png",
|
||||||
"pressed": "./resources/sand.png"
|
"pressed": "./resources/sand.png"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -57,9 +93,43 @@
|
|||||||
"y": 100,
|
"y": 100,
|
||||||
"width": 200,
|
"width": 200,
|
||||||
"height": 50,
|
"height": 50,
|
||||||
|
"animations": {
|
||||||
|
"buttonsExit": {
|
||||||
|
"repeat": false,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"type": "wait",
|
||||||
|
"duration": 1.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "move",
|
||||||
|
"to": [
|
||||||
|
-400,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"duration": 1.0,
|
||||||
|
"easing": "easein"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"bgScroll": {
|
||||||
|
"repeat": true,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"type": "move",
|
||||||
|
"to": [
|
||||||
|
1280,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"duration": 5.0,
|
||||||
|
"easing": "linear"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
"textures": {
|
"textures": {
|
||||||
"normal": "./resources/rock.png",
|
"normal": "./resources/rock.png",
|
||||||
"hover": "./resources/rock.png",
|
"hover": "./resources/button.png",
|
||||||
"pressed": "./resources/rock.png"
|
"pressed": "./resources/rock.png"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
105
src/Game.cpp
105
src/Game.cpp
@ -18,7 +18,8 @@ namespace ZL
|
|||||||
const char* CONST_ZIP_FILE = "../assets.zip";
|
const char* CONST_ZIP_FILE = "../assets.zip";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static bool g_exitBgAnimating = false;
|
||||||
|
|
||||||
|
|
||||||
Eigen::Quaternionf generateRandomQuaternion(std::mt19937& gen)
|
Eigen::Quaternionf generateRandomQuaternion(std::mt19937& gen)
|
||||||
{
|
{
|
||||||
@ -42,7 +43,7 @@ namespace ZL
|
|||||||
const float MIN_DISTANCE_SQUARED = MIN_DISTANCE * MIN_DISTANCE;
|
const float MIN_DISTANCE_SQUARED = MIN_DISTANCE * MIN_DISTANCE;
|
||||||
const float MIN_COORD = -100.0f;
|
const float MIN_COORD = -100.0f;
|
||||||
const float MAX_COORD = 100.0f;
|
const float MAX_COORD = 100.0f;
|
||||||
const int MAX_ATTEMPTS = 1000;
|
const int MAX_ATTEMPTS = 1000;
|
||||||
std::vector<BoxCoords> boxCoordsArr;
|
std::vector<BoxCoords> boxCoordsArr;
|
||||||
|
|
||||||
std::random_device rd;
|
std::random_device rd;
|
||||||
@ -65,7 +66,7 @@ namespace ZL
|
|||||||
(float)distrib(gen)
|
(float)distrib(gen)
|
||||||
);
|
);
|
||||||
|
|
||||||
accepted = true;
|
accepted = true;
|
||||||
for (const auto& existingBox : boxCoordsArr)
|
for (const auto& existingBox : boxCoordsArr)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -76,7 +77,7 @@ namespace ZL
|
|||||||
if (distanceSquared < MIN_DISTANCE_SQUARED)
|
if (distanceSquared < MIN_DISTANCE_SQUARED)
|
||||||
{
|
{
|
||||||
accepted = false;
|
accepted = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,7 +153,7 @@ namespace ZL
|
|||||||
renderer.shaderManager.AddShaderFromFiles("default", "./shaders/default.vertex", "./shaders/default_desktop.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("default", "./shaders/default.vertex", "./shaders/default_desktop.fragment", CONST_ZIP_FILE);
|
||||||
renderer.shaderManager.AddShaderFromFiles("env_sky", "./shaders/env_sky.vertex", "./shaders/env_sky_desktop.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("env_sky", "./shaders/env_sky.vertex", "./shaders/env_sky_desktop.fragment", CONST_ZIP_FILE);
|
||||||
renderer.shaderManager.AddShaderFromFiles("defaultAtmosphere", "./shaders/defaultAtmosphere.vertex", "./shaders/defaultAtmosphere_desktop.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("defaultAtmosphere", "./shaders/defaultAtmosphere.vertex", "./shaders/defaultAtmosphere_desktop.fragment", CONST_ZIP_FILE);
|
||||||
renderer.shaderManager.AddShaderFromFiles("planetBake", "./shaders/planet_bake.vertex", "./shaders/planet_bake_desktop.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("planetBake", "./shaders/planet_bake.vertex", "./shaders/planet_bake_desktop.fragment", CONST_ZIP_FILE);
|
||||||
renderer.shaderManager.AddShaderFromFiles("planetStone", "./shaders/planet_stone.vertex", "./shaders/planet_stone_desktop.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("planetStone", "./shaders/planet_stone.vertex", "./shaders/planet_stone_desktop.fragment", CONST_ZIP_FILE);
|
||||||
renderer.shaderManager.AddShaderFromFiles("planetLand", "./shaders/planet_land.vertex", "./shaders/planet_land_desktop.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("planetLand", "./shaders/planet_land.vertex", "./shaders/planet_land_desktop.fragment", CONST_ZIP_FILE);
|
||||||
|
|
||||||
@ -176,37 +177,73 @@ namespace ZL
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
//#ifndef SIMPLIFIED
|
//#ifndef SIMPLIFIED
|
||||||
bool cfgLoaded = sparkEmitter.loadFromJsonFile("config/spark_config.json", renderer, CONST_ZIP_FILE);
|
bool cfgLoaded = sparkEmitter.loadFromJsonFile("config/spark_config.json", renderer, CONST_ZIP_FILE);
|
||||||
bool projCfgLoaded = projectileEmitter.loadFromJsonFile("config/spark_projectile_config.json", renderer, CONST_ZIP_FILE);
|
bool projCfgLoaded = projectileEmitter.loadFromJsonFile("config/spark_projectile_config.json", renderer, CONST_ZIP_FILE);
|
||||||
projectileEmitter.setEmissionPoints(std::vector<Vector3f>());
|
projectileEmitter.setEmissionPoints(std::vector<Vector3f>());
|
||||||
uiManager.loadFromFile("config/ui.json", renderer, CONST_ZIP_FILE);
|
uiManager.loadFromFile("config/ui.json", renderer, CONST_ZIP_FILE);
|
||||||
|
|
||||||
uiManager.setButtonCallback("playButton", [this](const std::string& name) {
|
uiManager.loadFromFile("config/ui.json", renderer, CONST_ZIP_FILE);
|
||||||
std::cerr << "Play button pressed: " << name << std::endl;
|
uiManager.startAnimationOnNode("backgroundNode", "bgScroll");
|
||||||
});
|
static bool isExitButtonAnimating = false;
|
||||||
|
uiManager.setAnimationCallback("settingsButton", "buttonsExit", [this]() {
|
||||||
uiManager.setButtonCallback("exitButton", [](const std::string& name) {
|
std::cerr << "Settings button animation finished -> переход в настройки" << std::endl;
|
||||||
Environment::exitGameLoop = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
uiManager.setButtonCallback("settingsButton", [this](const std::string& name) {
|
|
||||||
if (uiManager.pushMenuFromFile("config/settings.json", this->renderer, CONST_ZIP_FILE)) {
|
if (uiManager.pushMenuFromFile("config/settings.json", this->renderer, CONST_ZIP_FILE)) {
|
||||||
|
|
||||||
uiManager.setButtonCallback("Opt1", [this](const std::string& n) {
|
uiManager.setButtonCallback("Opt1", [this](const std::string& n) {
|
||||||
std::cerr << "Opt1 pressed: " << n << std::endl;
|
std::cerr << "Opt1 pressed: " << n << std::endl;
|
||||||
});
|
});
|
||||||
|
|
||||||
uiManager.setButtonCallback("Opt2", [this](const std::string& n) {
|
uiManager.setButtonCallback("Opt2", [this](const std::string& n) {
|
||||||
std::cerr << "Opt2 pressed: " << n << std::endl;
|
std::cerr << "Opt2 pressed: " << n << std::endl;
|
||||||
});
|
});
|
||||||
|
|
||||||
uiManager.setButtonCallback("backButton", [this](const std::string& n) {
|
uiManager.setButtonCallback("backButton", [this](const std::string& n) {
|
||||||
|
uiManager.stopAllAnimations();
|
||||||
uiManager.popMenu();
|
uiManager.popMenu();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
std::cerr << "Failed to open settings menu" << std::endl;
|
std::cerr << "Failed to open settings menu after animations" << std::endl;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
uiManager.setAnimationCallback("exitButton", "bgScroll", []() {
|
||||||
|
std::cerr << "Exit button bgScroll animation finished" << std::endl;
|
||||||
|
g_exitBgAnimating = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Set UI button callbacks
|
||||||
|
uiManager.setButtonCallback("playButton", [this](const std::string& name) {
|
||||||
|
std::cerr << "Play button pressed: " << name << std::endl;
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
uiManager.setButtonCallback("settingsButton", [this](const std::string& name) {
|
||||||
|
std::cerr << "Settings button pressed: " << name << std::endl;
|
||||||
|
uiManager.startAnimationOnNode("playButton", "buttonsExit");
|
||||||
|
uiManager.startAnimationOnNode("settingsButton", "buttonsExit");
|
||||||
|
uiManager.startAnimationOnNode("exitButton", "buttonsExit");
|
||||||
|
});
|
||||||
|
|
||||||
|
uiManager.setButtonCallback("exitButton", [this](const std::string& name) {
|
||||||
|
std::cerr << "Exit button pressed: " << name << std::endl;
|
||||||
|
|
||||||
|
if (!g_exitBgAnimating) {
|
||||||
|
std::cerr << "start repeat anim bgScroll on exitButton" << std::endl;
|
||||||
|
g_exitBgAnimating = true;
|
||||||
|
uiManager.startAnimationOnNode("exitButton", "bgScroll");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::cerr << "stop repeat anim bgScroll on exitButton" << std::endl;
|
||||||
|
g_exitBgAnimating = false;
|
||||||
|
uiManager.stopAnimationOnNode("exitButton", "bgScroll");
|
||||||
|
|
||||||
|
auto exitButton = uiManager.findButton("exitButton");
|
||||||
|
if (exitButton) {
|
||||||
|
exitButton->animOffsetX = 0.0f;
|
||||||
|
exitButton->animOffsetY = 0.0f;
|
||||||
|
exitButton->animScaleX = 1.0f;
|
||||||
|
exitButton->animScaleY = 1.0f;
|
||||||
|
exitButton->buildMesh();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -215,7 +252,7 @@ namespace ZL
|
|||||||
musicVolume = value;
|
musicVolume = value;
|
||||||
Environment::shipVelocity = musicVolume * 20.0f;
|
Environment::shipVelocity = musicVolume * 20.0f;
|
||||||
});
|
});
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
cubemapTexture = std::make_shared<Texture>(
|
cubemapTexture = std::make_shared<Texture>(
|
||||||
std::array<TextureDataStruct, 6>{
|
std::array<TextureDataStruct, 6>{
|
||||||
@ -234,8 +271,8 @@ namespace ZL
|
|||||||
//Load texture
|
//Load texture
|
||||||
spaceshipTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/DefaultMaterial_BaseColor_shine.png", CONST_ZIP_FILE));
|
spaceshipTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/DefaultMaterial_BaseColor_shine.png", CONST_ZIP_FILE));
|
||||||
spaceshipBase = LoadFromTextFile02("./resources/spaceship006.txt", CONST_ZIP_FILE);
|
spaceshipBase = LoadFromTextFile02("./resources/spaceship006.txt", CONST_ZIP_FILE);
|
||||||
spaceshipBase.RotateByMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(M_PI / 2.0, Eigen::Vector3f::UnitY())).toRotationMatrix());// QuatFromRotateAroundY(M_PI / 2.0).toRotationMatrix());
|
spaceshipBase.RotateByMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(M_PI / 2.0, Eigen::Vector3f::UnitY())).toRotationMatrix());// QuatFromRotateAroundY(M_PI / 2.0).toRotationMatrix();
|
||||||
|
|
||||||
//spaceshipTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/cap_D.png", CONST_ZIP_FILE));
|
//spaceshipTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/cap_D.png", CONST_ZIP_FILE));
|
||||||
//spaceshipBase = LoadFromTextFile02("./resources/spaceship006x.txt", CONST_ZIP_FILE);
|
//spaceshipBase = LoadFromTextFile02("./resources/spaceship006x.txt", CONST_ZIP_FILE);
|
||||||
//spaceshipBase.RotateByMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(-M_PI / 2.0, Eigen::Vector3f::UnitY())).toRotationMatrix());// QuatFromRotateAroundY(M_PI / 2.0).toRotationMatrix());
|
//spaceshipBase.RotateByMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(-M_PI / 2.0, Eigen::Vector3f::UnitY())).toRotationMatrix());// QuatFromRotateAroundY(M_PI / 2.0).toRotationMatrix());
|
||||||
@ -446,11 +483,11 @@ namespace ZL
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//#ifndef SIMPLIFIED
|
//#ifndef SIMPLIFIED
|
||||||
|
|
||||||
sparkEmitter.draw(renderer, Environment::zoom, Environment::width, Environment::height);
|
sparkEmitter.draw(renderer, Environment::zoom, Environment::width, Environment::height);
|
||||||
projectileEmitter.draw(renderer, Environment::zoom, Environment::width, Environment::height);
|
projectileEmitter.draw(renderer, Environment::zoom, Environment::width, Environment::height);
|
||||||
//#endif
|
//#endif
|
||||||
renderer.PopMatrix();
|
renderer.PopMatrix();
|
||||||
renderer.PopProjectionMatrix();
|
renderer.PopProjectionMatrix();
|
||||||
renderer.DisableVertexAttribArray(vPositionName);
|
renderer.DisableVertexAttribArray(vPositionName);
|
||||||
@ -613,10 +650,10 @@ namespace ZL
|
|||||||
drawShip();
|
drawShip();
|
||||||
drawBoxes();
|
drawBoxes();
|
||||||
|
|
||||||
//#ifndef SIMPLIFIED
|
//#ifndef SIMPLIFIED
|
||||||
|
|
||||||
drawUI();
|
drawUI();
|
||||||
//#endif
|
//#endif
|
||||||
CheckGlError();
|
CheckGlError();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -632,10 +669,10 @@ namespace ZL
|
|||||||
size_t delta = (newTickCount - lastTickCount > CONST_MAX_TIME_INTERVAL) ?
|
size_t delta = (newTickCount - lastTickCount > CONST_MAX_TIME_INTERVAL) ?
|
||||||
CONST_MAX_TIME_INTERVAL : newTickCount - lastTickCount;
|
CONST_MAX_TIME_INTERVAL : newTickCount - lastTickCount;
|
||||||
|
|
||||||
//#ifndef SIMPLIFIED
|
//#ifndef SIMPLIFIED
|
||||||
//gameObjects.updateScene(delta);
|
//gameObjects.updateScene(delta);
|
||||||
sparkEmitter.update(static_cast<float>(delta));
|
sparkEmitter.update(static_cast<float>(delta));
|
||||||
//#endif
|
//#endif
|
||||||
planetObject.update(static_cast<float>(delta));
|
planetObject.update(static_cast<float>(delta));
|
||||||
if (Environment::tapDownHold) {
|
if (Environment::tapDownHold) {
|
||||||
|
|
||||||
@ -670,7 +707,7 @@ namespace ZL
|
|||||||
Environment::shipPosition = Environment::shipPosition + velocityDirectionAdjusted;
|
Environment::shipPosition = Environment::shipPosition + velocityDirectionAdjusted;
|
||||||
}
|
}
|
||||||
|
|
||||||
//#ifndef SIMPLIFIED
|
//#ifndef SIMPLIFIED
|
||||||
for (auto& p : projectiles) {
|
for (auto& p : projectiles) {
|
||||||
if (p && p->isActive()) {
|
if (p && p->isActive()) {
|
||||||
p->update(static_cast<float>(delta), renderer);
|
p->update(static_cast<float>(delta), renderer);
|
||||||
@ -705,7 +742,9 @@ namespace ZL
|
|||||||
|
|
||||||
sparkEmitter.update(static_cast<float>(delta));
|
sparkEmitter.update(static_cast<float>(delta));
|
||||||
projectileEmitter.update(static_cast<float>(delta));
|
projectileEmitter.update(static_cast<float>(delta));
|
||||||
//#endif
|
|
||||||
|
uiManager.update(static_cast<float>(delta));
|
||||||
|
//#endif
|
||||||
lastTickCount = newTickCount;
|
lastTickCount = newTickCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -763,7 +802,7 @@ namespace ZL
|
|||||||
uiManager.onMouseDown(uiX, uiY);
|
uiManager.onMouseDown(uiX, uiY);
|
||||||
|
|
||||||
bool uiHandled = false;
|
bool uiHandled = false;
|
||||||
//#ifndef SIMPLIFIED
|
//#ifndef SIMPLIFIED
|
||||||
if (event.button.button == SDL_BUTTON_LEFT && !uiManager.isUiInteraction()) {
|
if (event.button.button == SDL_BUTTON_LEFT && !uiManager.isUiInteraction()) {
|
||||||
uint64_t now = SDL_GetTicks64();
|
uint64_t now = SDL_GetTicks64();
|
||||||
if (now - lastProjectileFireTime >= static_cast<uint64_t>(projectileCooldownMs)) {
|
if (now - lastProjectileFireTime >= static_cast<uint64_t>(projectileCooldownMs)) {
|
||||||
@ -771,7 +810,7 @@ namespace ZL
|
|||||||
fireProjectiles();
|
fireProjectiles();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//#endif
|
//#endif
|
||||||
for (const auto& button : uiManager.findButton("") ? std::vector<std::shared_ptr<UiButton>>{} : std::vector<std::shared_ptr<UiButton>>{}) {
|
for (const auto& button : uiManager.findButton("") ? std::vector<std::shared_ptr<UiButton>>{} : std::vector<std::shared_ptr<UiButton>>{}) {
|
||||||
(void)button;
|
(void)button;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,6 +8,17 @@ namespace ZL {
|
|||||||
|
|
||||||
using json = nlohmann::json;
|
using json = nlohmann::json;
|
||||||
|
|
||||||
|
static float applyEasing(const std::string& easing, float t) {
|
||||||
|
if (easing == "easein") {
|
||||||
|
return t * t;
|
||||||
|
}
|
||||||
|
else if (easing == "easeout") {
|
||||||
|
float inv = 1.0f - t;
|
||||||
|
return 1.0f - inv * inv;
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
void UiButton::buildMesh() {
|
void UiButton::buildMesh() {
|
||||||
mesh.data.PositionData.clear();
|
mesh.data.PositionData.clear();
|
||||||
mesh.data.TexCoordData.clear();
|
mesh.data.TexCoordData.clear();
|
||||||
@ -52,6 +63,10 @@ namespace ZL {
|
|||||||
static const std::string vTexCoordName = "vTexCoord";
|
static const std::string vTexCoordName = "vTexCoord";
|
||||||
static const std::string textureUniformName = "Texture";
|
static const std::string textureUniformName = "Texture";
|
||||||
|
|
||||||
|
renderer.PushMatrix();
|
||||||
|
renderer.TranslateMatrix({ animOffsetX, animOffsetY, 0.0f });
|
||||||
|
renderer.ScaleMatrix({ animScaleX, animScaleY, 1.0f });
|
||||||
|
|
||||||
renderer.RenderUniform1i(textureUniformName, 0);
|
renderer.RenderUniform1i(textureUniformName, 0);
|
||||||
renderer.EnableVertexAttribArray(vPositionName);
|
renderer.EnableVertexAttribArray(vPositionName);
|
||||||
renderer.EnableVertexAttribArray(vTexCoordName);
|
renderer.EnableVertexAttribArray(vTexCoordName);
|
||||||
@ -61,6 +76,7 @@ namespace ZL {
|
|||||||
|
|
||||||
renderer.DisableVertexAttribArray(vPositionName);
|
renderer.DisableVertexAttribArray(vPositionName);
|
||||||
renderer.DisableVertexAttribArray(vTexCoordName);
|
renderer.DisableVertexAttribArray(vTexCoordName);
|
||||||
|
renderer.PopMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UiSlider::buildTrackMesh() {
|
void UiSlider::buildTrackMesh() {
|
||||||
@ -191,6 +207,8 @@ namespace ZL {
|
|||||||
sliders.clear();
|
sliders.clear();
|
||||||
collectButtonsAndSliders(root);
|
collectButtonsAndSliders(root);
|
||||||
|
|
||||||
|
nodeActiveAnims.clear();
|
||||||
|
|
||||||
for (auto& b : buttons) {
|
for (auto& b : buttons) {
|
||||||
b->buildMesh();
|
b->buildMesh();
|
||||||
}
|
}
|
||||||
@ -278,6 +296,37 @@ namespace ZL {
|
|||||||
node->slider = s;
|
node->slider = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (j.contains("animations") && j["animations"].is_object()) {
|
||||||
|
for (auto it = j["animations"].begin(); it != j["animations"].end(); ++it) {
|
||||||
|
std::string animName = it.key();
|
||||||
|
const auto& animDef = it.value();
|
||||||
|
UiNode::AnimSequence seq;
|
||||||
|
if (animDef.contains("repeat") && animDef["repeat"].is_boolean()) seq.repeat = animDef["repeat"].get<bool>();
|
||||||
|
if (animDef.contains("steps") && animDef["steps"].is_array()) {
|
||||||
|
for (const auto& step : animDef["steps"]) {
|
||||||
|
UiNode::AnimStep s;
|
||||||
|
if (step.contains("type") && step["type"].is_string()) {
|
||||||
|
s.type = step["type"].get<std::string>();
|
||||||
|
std::transform(s.type.begin(), s.type.end(), s.type.begin(), ::tolower);
|
||||||
|
}
|
||||||
|
if (step.contains("to") && step["to"].is_array() && step["to"].size() >= 2) {
|
||||||
|
s.toX = step["to"][0].get<float>();
|
||||||
|
s.toY = step["to"][1].get<float>();
|
||||||
|
}
|
||||||
|
if (step.contains("duration")) {
|
||||||
|
s.durationMs = step["duration"].get<float>() * 1000.0f;
|
||||||
|
}
|
||||||
|
if (step.contains("easing") && step["easing"].is_string()) {
|
||||||
|
s.easing = step["easing"].get<std::string>();
|
||||||
|
std::transform(s.easing.begin(), s.easing.end(), s.easing.begin(), ::tolower);
|
||||||
|
}
|
||||||
|
seq.steps.push_back(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
node->animations[animName] = std::move(seq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (j.contains("children") && j["children"].is_array()) {
|
if (j.contains("children") && j["children"].is_array()) {
|
||||||
for (const auto& ch : j["children"]) {
|
for (const auto& ch : j["children"]) {
|
||||||
node->children.push_back(parseNode(ch, renderer, zipFile));
|
node->children.push_back(parseNode(ch, renderer, zipFile));
|
||||||
@ -406,13 +455,27 @@ namespace ZL {
|
|||||||
prev.pressedSlider = pressedSlider;
|
prev.pressedSlider = pressedSlider;
|
||||||
prev.path = "";
|
prev.path = "";
|
||||||
|
|
||||||
|
prev.animCallbacks = animCallbacks;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
nodeActiveAnims.clear();
|
||||||
|
animCallbacks.clear();
|
||||||
|
for (auto& b : buttons) {
|
||||||
|
if (b) {
|
||||||
|
b->animOffsetX = 0.0f;
|
||||||
|
b->animOffsetY = 0.0f;
|
||||||
|
b->animScaleX = 1.0f;
|
||||||
|
b->animScaleY = 1.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
loadFromFile(path, renderer, zipFile);
|
loadFromFile(path, renderer, zipFile);
|
||||||
menuStack.push_back(std::move(prev));
|
menuStack.push_back(std::move(prev));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (const std::exception& e) {
|
catch (const std::exception& e) {
|
||||||
std::cerr << "UiManager: pushMenuFromFile failed to load " << path << " : " << e.what() << std::endl;
|
std::cerr << "UiManager: pushMenuFromFile failed to load " << path << " : " << e.what() << std::endl;
|
||||||
|
animCallbacks = prev.animCallbacks;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -425,19 +488,32 @@ namespace ZL {
|
|||||||
auto s = menuStack.back();
|
auto s = menuStack.back();
|
||||||
menuStack.pop_back();
|
menuStack.pop_back();
|
||||||
|
|
||||||
|
nodeActiveAnims.clear();
|
||||||
|
|
||||||
root = s.root;
|
root = s.root;
|
||||||
buttons = s.buttons;
|
buttons = s.buttons;
|
||||||
sliders = s.sliders;
|
sliders = s.sliders;
|
||||||
pressedButton = s.pressedButton;
|
pressedButton = s.pressedButton;
|
||||||
pressedSlider = s.pressedSlider;
|
pressedSlider = s.pressedSlider;
|
||||||
|
|
||||||
|
animCallbacks = s.animCallbacks;
|
||||||
|
|
||||||
for (auto& b : buttons) {
|
for (auto& b : buttons) {
|
||||||
if (b) b->buildMesh();
|
if (b) {
|
||||||
}
|
b->animOffsetX = 0.0f;
|
||||||
for (auto& sl : sliders) {
|
b->animOffsetY = 0.0f;
|
||||||
if (sl) { sl->buildTrackMesh(); sl->buildKnobMesh(); }
|
b->animScaleX = 1.0f;
|
||||||
|
b->animScaleY = 1.0f;
|
||||||
|
b->buildMesh();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto& sl : sliders) {
|
||||||
|
if (sl) {
|
||||||
|
sl->buildTrackMesh();
|
||||||
|
sl->buildKnobMesh();
|
||||||
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -461,6 +537,168 @@ namespace ZL {
|
|||||||
renderer.PopProjectionMatrix();
|
renderer.PopProjectionMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::shared_ptr<UiNode> findNodeByName(const std::shared_ptr<UiNode>& node, const std::string& name) {
|
||||||
|
if (!node) return nullptr;
|
||||||
|
if (!name.empty() && node->name == name) return node;
|
||||||
|
for (auto& c : node->children) {
|
||||||
|
auto r = findNodeByName(c, name);
|
||||||
|
if (r) return r;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UiManager::update(float deltaMs) {
|
||||||
|
if (!root) return;
|
||||||
|
|
||||||
|
std::vector<std::pair<std::shared_ptr<UiNode>, size_t>> animationsToRemove;
|
||||||
|
std::vector<std::function<void()>> pendingCallbacks;
|
||||||
|
|
||||||
|
for (auto& kv : nodeActiveAnims) {
|
||||||
|
auto node = kv.first;
|
||||||
|
auto& activeList = kv.second;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < activeList.size(); ++i) {
|
||||||
|
auto& act = activeList[i];
|
||||||
|
if (!act.seq) {
|
||||||
|
animationsToRemove.push_back({ node, i });
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& steps = act.seq->steps;
|
||||||
|
|
||||||
|
if (act.stepIndex >= steps.size()) {
|
||||||
|
if (act.repeat) {
|
||||||
|
if (node->button) {
|
||||||
|
node->button->animOffsetX = act.origOffsetX;
|
||||||
|
node->button->animOffsetY = act.origOffsetY;
|
||||||
|
node->button->animScaleX = act.origScaleX;
|
||||||
|
node->button->animScaleY = act.origScaleY;
|
||||||
|
}
|
||||||
|
act.stepIndex = 0;
|
||||||
|
act.elapsedMs = 0.0f;
|
||||||
|
act.stepStarted = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (act.onComplete) {
|
||||||
|
pendingCallbacks.push_back(act.onComplete);
|
||||||
|
}
|
||||||
|
animationsToRemove.push_back({ node, i });
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& step = steps[act.stepIndex];
|
||||||
|
|
||||||
|
if (step.durationMs <= 0.0f) {
|
||||||
|
if (step.type == "move") {
|
||||||
|
if (node->button) {
|
||||||
|
node->button->animOffsetX = step.toX;
|
||||||
|
node->button->animOffsetY = step.toY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (step.type == "scale") {
|
||||||
|
if (node->button) {
|
||||||
|
node->button->animScaleX = step.toX;
|
||||||
|
node->button->animScaleY = step.toY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
act.stepIndex++;
|
||||||
|
act.elapsedMs = 0.0f;
|
||||||
|
act.stepStarted = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!act.stepStarted && act.stepIndex == 0 && act.elapsedMs == 0.0f) {
|
||||||
|
if (node->button) {
|
||||||
|
act.origOffsetX = node->button->animOffsetX;
|
||||||
|
act.origOffsetY = node->button->animOffsetY;
|
||||||
|
act.origScaleX = node->button->animScaleX;
|
||||||
|
act.origScaleY = node->button->animScaleY;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
act.origOffsetX = act.origOffsetY = 0.0f;
|
||||||
|
act.origScaleX = act.origScaleY = 1.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float prevElapsed = act.elapsedMs;
|
||||||
|
act.elapsedMs += deltaMs;
|
||||||
|
|
||||||
|
if (!act.stepStarted && prevElapsed == 0.0f) {
|
||||||
|
if (node->button) {
|
||||||
|
act.startOffsetX = node->button->animOffsetX;
|
||||||
|
act.startOffsetY = node->button->animOffsetY;
|
||||||
|
act.startScaleX = node->button->animScaleX;
|
||||||
|
act.startScaleY = node->button->animScaleY;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
act.startOffsetX = act.startOffsetY = 0.0f;
|
||||||
|
act.startScaleX = act.startScaleY = 1.0f;
|
||||||
|
}
|
||||||
|
if (step.type == "move") {
|
||||||
|
act.endOffsetX = step.toX;
|
||||||
|
act.endOffsetY = step.toY;
|
||||||
|
}
|
||||||
|
else if (step.type == "scale") {
|
||||||
|
act.endScaleX = step.toX;
|
||||||
|
act.endScaleY = step.toY;
|
||||||
|
}
|
||||||
|
act.stepStarted = true;
|
||||||
|
}
|
||||||
|
float t = (step.durationMs > 0.0f) ? (act.elapsedMs / step.durationMs) : 1.0f;
|
||||||
|
if (t > 1.0f) t = 1.0f;
|
||||||
|
float te = applyEasing(step.easing, t);
|
||||||
|
|
||||||
|
if (step.type == "move") {
|
||||||
|
float nx = act.startOffsetX + (act.endOffsetX - act.startOffsetX) * te;
|
||||||
|
float ny = act.startOffsetY + (act.endOffsetY - act.startOffsetY) * te;
|
||||||
|
if (node->button) {
|
||||||
|
node->button->animOffsetX = nx;
|
||||||
|
node->button->animOffsetY = ny;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (step.type == "scale") {
|
||||||
|
float sx = act.startScaleX + (act.endScaleX - act.startScaleX) * te;
|
||||||
|
float sy = act.startScaleY + (act.endScaleY - act.startScaleY) * te;
|
||||||
|
if (node->button) {
|
||||||
|
node->button->animScaleX = sx;
|
||||||
|
node->button->animScaleY = sy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (step.type == "wait") {
|
||||||
|
//wait
|
||||||
|
}
|
||||||
|
if (act.elapsedMs >= step.durationMs) {
|
||||||
|
act.stepIndex++;
|
||||||
|
act.elapsedMs = 0.0f;
|
||||||
|
act.stepStarted = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto it = animationsToRemove.rbegin(); it != animationsToRemove.rend(); ++it) {
|
||||||
|
auto& [node, index] = *it;
|
||||||
|
if (nodeActiveAnims.find(node) != nodeActiveAnims.end()) {
|
||||||
|
auto& animList = nodeActiveAnims[node];
|
||||||
|
if (index < animList.size()) {
|
||||||
|
animList.erase(animList.begin() + index);
|
||||||
|
}
|
||||||
|
if (animList.empty()) {
|
||||||
|
nodeActiveAnims.erase(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& cb : pendingCallbacks) {
|
||||||
|
try {
|
||||||
|
cb();
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
std::cerr << "UiManager: animation onComplete callback threw exception" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void UiManager::onMouseMove(int x, int y) {
|
void UiManager::onMouseMove(int x, int y) {
|
||||||
for (auto& b : buttons) {
|
for (auto& b : buttons) {
|
||||||
if (b->rect.contains((float)x, (float)y)) {
|
if (b->rect.contains((float)x, (float)y)) {
|
||||||
@ -540,4 +778,88 @@ namespace ZL {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool UiManager::startAnimationOnNode(const std::string& nodeName, const std::string& animName) {
|
||||||
|
if (!root) return false;
|
||||||
|
auto node = findNodeByName(root, nodeName);
|
||||||
|
if (!node) return false;
|
||||||
|
auto it = node->animations.find(animName);
|
||||||
|
if (it == node->animations.end()) return false;
|
||||||
|
|
||||||
|
ActiveAnim aa;
|
||||||
|
aa.name = animName;
|
||||||
|
aa.seq = &it->second;
|
||||||
|
aa.stepIndex = 0;
|
||||||
|
aa.elapsedMs = 0.0f;
|
||||||
|
aa.repeat = it->second.repeat;
|
||||||
|
aa.stepStarted = false;
|
||||||
|
if (node->button) {
|
||||||
|
aa.origOffsetX = node->button->animOffsetX;
|
||||||
|
aa.origOffsetY = node->button->animOffsetY;
|
||||||
|
aa.origScaleX = node->button->animScaleX;
|
||||||
|
aa.origScaleY = node->button->animScaleY;
|
||||||
|
}
|
||||||
|
auto cbIt = animCallbacks.find({ nodeName, animName });
|
||||||
|
if (cbIt != animCallbacks.end()) aa.onComplete = cbIt->second;
|
||||||
|
nodeActiveAnims[node].push_back(std::move(aa));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UiManager::stopAnimationOnNode(const std::string& nodeName, const std::string& animName) {
|
||||||
|
if (!root) return false;
|
||||||
|
auto node = findNodeByName(root, nodeName);
|
||||||
|
if (!node) return false;
|
||||||
|
auto it = nodeActiveAnims.find(node);
|
||||||
|
if (it != nodeActiveAnims.end()) {
|
||||||
|
auto& animList = it->second;
|
||||||
|
for (auto animIt = animList.begin(); animIt != animList.end(); ) {
|
||||||
|
if (animIt->name == animName) {
|
||||||
|
animIt = animList.erase(animIt);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
++animIt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (animList.empty()) {
|
||||||
|
nodeActiveAnims.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UiManager::startAnimation(const std::string& animName) {
|
||||||
|
if (!root) return;
|
||||||
|
std::function<void(const std::shared_ptr<UiNode>&)> traverse = [&](const std::shared_ptr<UiNode>& n) {
|
||||||
|
if (!n) return;
|
||||||
|
auto it = n->animations.find(animName);
|
||||||
|
if (it != n->animations.end()) {
|
||||||
|
ActiveAnim aa;
|
||||||
|
aa.name = animName;
|
||||||
|
aa.seq = &it->second;
|
||||||
|
aa.stepIndex = 0;
|
||||||
|
aa.elapsedMs = 0.0f;
|
||||||
|
aa.repeat = it->second.repeat;
|
||||||
|
aa.stepStarted = false;
|
||||||
|
if (n->button) {
|
||||||
|
aa.origOffsetX = n->button->animOffsetX;
|
||||||
|
aa.origOffsetY = n->button->animOffsetY;
|
||||||
|
aa.origScaleX = n->button->animScaleX;
|
||||||
|
aa.origScaleY = n->button->animScaleY;
|
||||||
|
}
|
||||||
|
auto cbIt = animCallbacks.find({ n->name, animName });
|
||||||
|
if (cbIt != animCallbacks.end()) aa.onComplete = cbIt->second;
|
||||||
|
nodeActiveAnims[n].push_back(std::move(aa));
|
||||||
|
}
|
||||||
|
for (auto& c : n->children) traverse(c);
|
||||||
|
};
|
||||||
|
traverse(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UiManager::setAnimationCallback(const std::string& nodeName, const std::string& animName, std::function<void()> cb) {
|
||||||
|
animCallbacks[{nodeName, animName}] = std::move(cb);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ZL
|
} // namespace ZL
|
||||||
@ -8,6 +8,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
namespace ZL {
|
namespace ZL {
|
||||||
|
|
||||||
@ -41,6 +42,12 @@ namespace ZL {
|
|||||||
|
|
||||||
std::function<void(const std::string&)> onClick;
|
std::function<void(const std::string&)> onClick;
|
||||||
|
|
||||||
|
// animation runtime
|
||||||
|
float animOffsetX = 0.0f;
|
||||||
|
float animOffsetY = 0.0f;
|
||||||
|
float animScaleX = 1.0f;
|
||||||
|
float animScaleY = 1.0f;
|
||||||
|
|
||||||
void buildMesh();
|
void buildMesh();
|
||||||
void draw(Renderer& renderer) const;
|
void draw(Renderer& renderer) const;
|
||||||
};
|
};
|
||||||
@ -73,6 +80,19 @@ namespace ZL {
|
|||||||
std::shared_ptr<UiSlider> slider;
|
std::shared_ptr<UiSlider> slider;
|
||||||
std::string orientation = "vertical";
|
std::string orientation = "vertical";
|
||||||
float spacing = 0.0f;
|
float spacing = 0.0f;
|
||||||
|
|
||||||
|
struct AnimStep {
|
||||||
|
std::string type;
|
||||||
|
float toX = 0.0f;
|
||||||
|
float toY = 0.0f;
|
||||||
|
float durationMs = 0.0f;
|
||||||
|
std::string easing = "linear";
|
||||||
|
};
|
||||||
|
struct AnimSequence {
|
||||||
|
std::vector<AnimStep> steps;
|
||||||
|
bool repeat = false;
|
||||||
|
};
|
||||||
|
std::map<std::string, AnimSequence> animations;
|
||||||
};
|
};
|
||||||
|
|
||||||
class UiManager {
|
class UiManager {
|
||||||
@ -91,6 +111,19 @@ namespace ZL {
|
|||||||
return pressedButton != nullptr || pressedSlider != nullptr;
|
return pressedButton != nullptr || pressedSlider != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void stopAllAnimations() {
|
||||||
|
nodeActiveAnims.clear();
|
||||||
|
|
||||||
|
for (auto& b : buttons) {
|
||||||
|
if (b) {
|
||||||
|
b->animOffsetX = 0.0f;
|
||||||
|
b->animOffsetY = 0.0f;
|
||||||
|
b->animScaleX = 1.0f;
|
||||||
|
b->animScaleY = 1.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<UiButton> findButton(const std::string& name);
|
std::shared_ptr<UiButton> findButton(const std::string& name);
|
||||||
|
|
||||||
bool setButtonCallback(const std::string& name, std::function<void(const std::string&)> cb);
|
bool setButtonCallback(const std::string& name, std::function<void(const std::string&)> cb);
|
||||||
@ -106,15 +139,47 @@ namespace ZL {
|
|||||||
bool popMenu();
|
bool popMenu();
|
||||||
void clearMenuStack();
|
void clearMenuStack();
|
||||||
|
|
||||||
|
void update(float deltaMs);
|
||||||
|
void startAnimation(const std::string& animName);
|
||||||
|
bool startAnimationOnNode(const std::string& nodeName, const std::string& animName);
|
||||||
|
bool stopAnimationOnNode(const std::string& nodeName, const std::string& animName);
|
||||||
|
bool setAnimationCallback(const std::string& nodeName, const std::string& animName, std::function<void()> cb);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<UiNode> parseNode(const json& j, Renderer& renderer, const std::string& zipFile);
|
std::shared_ptr<UiNode> parseNode(const json& j, Renderer& renderer, const std::string& zipFile);
|
||||||
void layoutNode(const std::shared_ptr<UiNode>& node);
|
void layoutNode(const std::shared_ptr<UiNode>& node);
|
||||||
void collectButtonsAndSliders(const std::shared_ptr<UiNode>& node);
|
void collectButtonsAndSliders(const std::shared_ptr<UiNode>& node);
|
||||||
|
|
||||||
|
struct ActiveAnim {
|
||||||
|
std::string name;
|
||||||
|
const UiNode::AnimSequence* seq = nullptr;
|
||||||
|
size_t stepIndex = 0;
|
||||||
|
float elapsedMs = 0.0f;
|
||||||
|
bool repeat = false;
|
||||||
|
float startOffsetX = 0.0f;
|
||||||
|
float startOffsetY = 0.0f;
|
||||||
|
float endOffsetX = 0.0f;
|
||||||
|
float endOffsetY = 0.0f;
|
||||||
|
float startScaleX = 1.0f;
|
||||||
|
float startScaleY = 1.0f;
|
||||||
|
float endScaleX = 1.0f;
|
||||||
|
float endScaleY = 1.0f;
|
||||||
|
std::function<void()> onComplete;
|
||||||
|
|
||||||
|
float origOffsetX = 0.0f;
|
||||||
|
float origOffsetY = 0.0f;
|
||||||
|
float origScaleX = 1.0f;
|
||||||
|
float origScaleY = 1.0f;
|
||||||
|
bool stepStarted = false;
|
||||||
|
};
|
||||||
|
|
||||||
std::shared_ptr<UiNode> root;
|
std::shared_ptr<UiNode> root;
|
||||||
std::vector<std::shared_ptr<UiButton>> buttons;
|
std::vector<std::shared_ptr<UiButton>> buttons;
|
||||||
std::vector<std::shared_ptr<UiSlider>> sliders;
|
std::vector<std::shared_ptr<UiSlider>> sliders;
|
||||||
|
|
||||||
|
std::map<std::shared_ptr<UiNode>, std::vector<ActiveAnim>> nodeActiveAnims;
|
||||||
|
std::map<std::pair<std::string, std::string>, std::function<void()>> animCallbacks; // key: (nodeName, animName)
|
||||||
|
|
||||||
std::shared_ptr<UiButton> pressedButton;
|
std::shared_ptr<UiButton> pressedButton;
|
||||||
std::shared_ptr<UiSlider> pressedSlider;
|
std::shared_ptr<UiSlider> pressedSlider;
|
||||||
|
|
||||||
@ -125,6 +190,7 @@ namespace ZL {
|
|||||||
std::shared_ptr<UiButton> pressedButton;
|
std::shared_ptr<UiButton> pressedButton;
|
||||||
std::shared_ptr<UiSlider> pressedSlider;
|
std::shared_ptr<UiSlider> pressedSlider;
|
||||||
std::string path;
|
std::string path;
|
||||||
|
std::map<std::pair<std::string, std::string>, std::function<void()>> animCallbacks;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<MenuState> menuStack;
|
std::vector<MenuState> menuStack;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user