mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-23 22:37:55 +02:00
Added VideoWidget to hide implementation details
This commit is contained in:
@@ -131,6 +131,7 @@ set(client_SRCS
|
||||
widgets/CArtifactsOfHeroMarket.cpp
|
||||
widgets/CArtifactsOfHeroBackpack.cpp
|
||||
widgets/RadialMenu.cpp
|
||||
widgets/VideoWidget.cpp
|
||||
widgets/markets/CAltarArtifacts.cpp
|
||||
widgets/markets/CAltarCreatures.cpp
|
||||
widgets/markets/CArtifactsBuying.cpp
|
||||
@@ -332,6 +333,7 @@ set(client_HEADERS
|
||||
widgets/CArtifactsOfHeroMarket.h
|
||||
widgets/CArtifactsOfHeroBackpack.h
|
||||
widgets/RadialMenu.h
|
||||
widgets/VideoWidget.h
|
||||
widgets/markets/CAltarArtifacts.h
|
||||
widgets/markets/CAltarCreatures.h
|
||||
widgets/markets/CArtifactsBuying.h
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#include "../gui/MouseButton.h"
|
||||
#include "../gui/WindowHandler.h"
|
||||
#include "../media/IMusicPlayer.h"
|
||||
#include "../media/IVideoPlayer.h"
|
||||
#include "../render/Canvas.h"
|
||||
#include "../render/IImage.h"
|
||||
#include "../render/IFont.h"
|
||||
@@ -35,6 +34,7 @@
|
||||
#include "../widgets/Images.h"
|
||||
#include "../widgets/Slider.h"
|
||||
#include "../widgets/TextControls.h"
|
||||
#include "../widgets/VideoWidget.h"
|
||||
#include "../widgets/GraphicalPrimitiveCanvas.h"
|
||||
#include "../windows/CMessage.h"
|
||||
#include "../windows/CCreatureWindow.h"
|
||||
@@ -603,7 +603,7 @@ HeroInfoWindow::HeroInfoWindow(const InfoAboutHero & hero, Point * position)
|
||||
}
|
||||
|
||||
BattleResultWindow::BattleResultWindow(const BattleResult & br, CPlayerInterface & _owner, bool allowReplay)
|
||||
: owner(_owner), currentVideo(BattleResultVideo::NONE)
|
||||
: owner(_owner)
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
|
||||
|
||||
@@ -705,68 +705,98 @@ BattleResultWindow::BattleResultWindow(const BattleResult & br, CPlayerInterface
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto resources = getResources(br);
|
||||
|
||||
description = std::make_shared<CTextBox>(resources.resultText.toString(), Rect(69, 203, 330, 68), 0, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE);
|
||||
videoPlayer = std::make_shared<VideoWidget>(Point(107, 70), resources.prologueVideo, resources.loopedVideo);
|
||||
|
||||
CCS->musich->playMusic(resources.musicName, false, true);
|
||||
}
|
||||
|
||||
BattleResultResources BattleResultWindow::getResources(const BattleResult & br)
|
||||
{
|
||||
//printing result description
|
||||
bool weAreAttacker = !(owner.cb->getBattle(br.battleID)->battleGetMySide());
|
||||
if((br.winner == 0 && weAreAttacker) || (br.winner == 1 && !weAreAttacker)) //we've won
|
||||
bool weAreDefender = !weAreAttacker;
|
||||
bool weWon = (br.winner == 0 && weAreAttacker) || (br.winner == 1 && !weAreAttacker);
|
||||
bool isSiege = owner.cb->getBattle(br.battleID)->battleGetDefendedTown() != nullptr;
|
||||
|
||||
BattleResultResources resources;
|
||||
|
||||
if(weWon)
|
||||
{
|
||||
int text = 304;
|
||||
currentVideo = BattleResultVideo::WIN;
|
||||
if(isSiege && weAreDefender)
|
||||
{
|
||||
resources.musicName = AudioPath::builtin("Music/Defend Castle");
|
||||
resources.prologueVideo = VideoPath::builtin("DEFENDALL.BIK");
|
||||
resources.loopedVideo = VideoPath::builtin("defendloop.bik");
|
||||
}
|
||||
else
|
||||
{
|
||||
resources.musicName = AudioPath::builtin("Music/Win Battle");
|
||||
resources.prologueVideo = VideoPath();
|
||||
resources.loopedVideo = VideoPath::builtin("WIN3.BIK");
|
||||
}
|
||||
|
||||
switch(br.result)
|
||||
{
|
||||
case EBattleResult::NORMAL:
|
||||
if(owner.cb->getBattle(br.battleID)->battleGetDefendedTown() && !weAreAttacker)
|
||||
currentVideo = BattleResultVideo::WIN_SIEGE;
|
||||
resources.resultText.appendTextID("core.genrltxt.304");
|
||||
break;
|
||||
case EBattleResult::ESCAPE:
|
||||
text = 303;
|
||||
resources.resultText.appendTextID("core.genrltxt.303");
|
||||
break;
|
||||
case EBattleResult::SURRENDER:
|
||||
text = 302;
|
||||
resources.resultText.appendTextID("core.genrltxt.302");
|
||||
break;
|
||||
default:
|
||||
logGlobal->error("Invalid battle result code %d. Assumed normal.", static_cast<int>(br.result));
|
||||
break;
|
||||
throw std::runtime_error("Invalid battle result!");
|
||||
}
|
||||
playVideo();
|
||||
|
||||
std::string str = CGI->generaltexth->allTexts[text];
|
||||
|
||||
const CGHeroInstance * ourHero = owner.cb->getBattle(br.battleID)->battleGetMyHero();
|
||||
if (ourHero)
|
||||
{
|
||||
str += CGI->generaltexth->allTexts[305];
|
||||
boost::algorithm::replace_first(str, "%s", ourHero->getNameTranslated());
|
||||
boost::algorithm::replace_first(str, "%d", std::to_string(br.exp[weAreAttacker ? 0 : 1]));
|
||||
resources.resultText.appendTextID("core.genrltxt.305");
|
||||
resources.resultText.replaceTextID(ourHero->getNameTranslated());
|
||||
resources.resultText.replaceNumber(br.exp[weAreAttacker ? 0 : 1]);
|
||||
}
|
||||
|
||||
description = std::make_shared<CTextBox>(str, Rect(69, 203, 330, 68), 0, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE);
|
||||
}
|
||||
else // we lose
|
||||
{
|
||||
int text = 311;
|
||||
currentVideo = BattleResultVideo::DEFEAT;
|
||||
switch(br.result)
|
||||
{
|
||||
case EBattleResult::NORMAL:
|
||||
if(owner.cb->getBattle(br.battleID)->battleGetDefendedTown() && !weAreAttacker)
|
||||
currentVideo = BattleResultVideo::DEFEAT_SIEGE;
|
||||
resources.resultText.appendTextID("core.genrltxt.311");
|
||||
resources.musicName = AudioPath::builtin("Music/LoseCombat");
|
||||
resources.prologueVideo = VideoPath::builtin("LBSTART.BIK");
|
||||
resources.loopedVideo = VideoPath::builtin("LBLOOP.BIK");
|
||||
break;
|
||||
case EBattleResult::ESCAPE:
|
||||
currentVideo = BattleResultVideo::RETREAT;
|
||||
text = 310;
|
||||
resources.resultText.appendTextID("core.genrltxt.310");
|
||||
resources.musicName = AudioPath::builtin("Music/Retreat Battle");
|
||||
resources.prologueVideo = VideoPath::builtin("RTSTART.BIK");
|
||||
resources.loopedVideo = VideoPath::builtin("RTLOOP.BIK");
|
||||
break;
|
||||
case EBattleResult::SURRENDER:
|
||||
currentVideo = BattleResultVideo::SURRENDER;
|
||||
text = 309;
|
||||
resources.resultText.appendTextID("core.genrltxt.309");
|
||||
resources.musicName = AudioPath::builtin("Music/Surrender Battle");
|
||||
resources.prologueVideo = VideoPath();
|
||||
resources.loopedVideo = VideoPath::builtin("SURRENDER.BIK");
|
||||
break;
|
||||
default:
|
||||
logGlobal->error("Invalid battle result code %d. Assumed normal.", static_cast<int>(br.result));
|
||||
break;
|
||||
throw std::runtime_error("Invalid battle result!");
|
||||
}
|
||||
playVideo();
|
||||
|
||||
labels.push_back(std::make_shared<CLabel>(235, 235, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[text]));
|
||||
if(isSiege && weAreDefender)
|
||||
{
|
||||
resources.musicName = AudioPath::builtin("Music/LoseCastle");
|
||||
resources.prologueVideo = VideoPath::builtin("LOSECSTL.BIK");
|
||||
resources.loopedVideo = VideoPath::builtin("LOSECSLP.BIK");
|
||||
}
|
||||
}
|
||||
|
||||
return resources;
|
||||
}
|
||||
|
||||
void BattleResultWindow::activate()
|
||||
@@ -775,81 +805,6 @@ void BattleResultWindow::activate()
|
||||
CIntObject::activate();
|
||||
}
|
||||
|
||||
void BattleResultWindow::show(Canvas & to)
|
||||
{
|
||||
CIntObject::show(to);
|
||||
CCS->videoh->update(pos.x + 107, pos.y + 70, to.getInternalSurface(), true, false,
|
||||
[&]()
|
||||
{
|
||||
playVideo(true);
|
||||
});
|
||||
}
|
||||
|
||||
void BattleResultWindow::playVideo(bool startLoop)
|
||||
{
|
||||
AudioPath musicName = AudioPath();
|
||||
VideoPath videoName = VideoPath();
|
||||
|
||||
if(!startLoop)
|
||||
{
|
||||
switch(currentVideo)
|
||||
{
|
||||
case BattleResultVideo::WIN:
|
||||
musicName = AudioPath::builtin("Music/Win Battle");
|
||||
videoName = VideoPath::builtin("WIN3.BIK");
|
||||
break;
|
||||
case BattleResultVideo::SURRENDER:
|
||||
musicName = AudioPath::builtin("Music/Surrender Battle");
|
||||
videoName = VideoPath::builtin("SURRENDER.BIK");
|
||||
break;
|
||||
case BattleResultVideo::RETREAT:
|
||||
musicName = AudioPath::builtin("Music/Retreat Battle");
|
||||
videoName = VideoPath::builtin("RTSTART.BIK");
|
||||
break;
|
||||
case BattleResultVideo::DEFEAT:
|
||||
musicName = AudioPath::builtin("Music/LoseCombat");
|
||||
videoName = VideoPath::builtin("LBSTART.BIK");
|
||||
break;
|
||||
case BattleResultVideo::DEFEAT_SIEGE:
|
||||
musicName = AudioPath::builtin("Music/LoseCastle");
|
||||
videoName = VideoPath::builtin("LOSECSTL.BIK");
|
||||
break;
|
||||
case BattleResultVideo::WIN_SIEGE:
|
||||
musicName = AudioPath::builtin("Music/Defend Castle");
|
||||
videoName = VideoPath::builtin("DEFENDALL.BIK");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(currentVideo)
|
||||
{
|
||||
case BattleResultVideo::RETREAT:
|
||||
currentVideo = BattleResultVideo::RETREAT_LOOP;
|
||||
videoName = VideoPath::builtin("RTLOOP.BIK");
|
||||
break;
|
||||
case BattleResultVideo::DEFEAT:
|
||||
currentVideo = BattleResultVideo::DEFEAT_LOOP;
|
||||
videoName = VideoPath::builtin("LBLOOP.BIK");
|
||||
break;
|
||||
case BattleResultVideo::DEFEAT_SIEGE:
|
||||
currentVideo = BattleResultVideo::DEFEAT_SIEGE_LOOP;
|
||||
videoName = VideoPath::builtin("LOSECSLP.BIK");
|
||||
break;
|
||||
case BattleResultVideo::WIN_SIEGE:
|
||||
currentVideo = BattleResultVideo::WIN_SIEGE_LOOP;
|
||||
videoName = VideoPath::builtin("DEFENDLOOP.BIK");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(musicName != AudioPath())
|
||||
CCS->musich->playMusic(musicName, false, true);
|
||||
|
||||
if(videoName != VideoPath())
|
||||
CCS->videoh->open(videoName);
|
||||
}
|
||||
|
||||
void BattleResultWindow::buttonPressed(int button)
|
||||
{
|
||||
if (resultCallback)
|
||||
@@ -865,7 +820,6 @@ void BattleResultWindow::buttonPressed(int button)
|
||||
//Result window and battle interface are gone. We requested all dialogs to be closed before opening the battle,
|
||||
//so we can be sure that there is no dialogs left on GUI stack.
|
||||
intTmp.showingDialog->setn(false);
|
||||
CCS->videoh->close();
|
||||
}
|
||||
|
||||
void BattleResultWindow::bExitf()
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "../../lib/FunctionList.h"
|
||||
#include "../../lib/battle/BattleHex.h"
|
||||
#include "../windows/CWindowObject.h"
|
||||
#include "../../lib/MetaString.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
@@ -42,6 +43,7 @@ class CAnimImage;
|
||||
class TransparentFilledRectangle;
|
||||
class CPlayerInterface;
|
||||
class BattleRenderer;
|
||||
class VideoWidget;
|
||||
|
||||
/// Class which shows the console at the bottom of the battle screen and manages the text of the console
|
||||
class BattleConsole : public CIntObject, public IStatusBar
|
||||
@@ -185,6 +187,14 @@ public:
|
||||
HeroInfoWindow(const InfoAboutHero & hero, Point * position);
|
||||
};
|
||||
|
||||
struct BattleResultResources
|
||||
{
|
||||
VideoPath prologueVideo;
|
||||
VideoPath loopedVideo;
|
||||
AudioPath musicName;
|
||||
MetaString resultText;
|
||||
};
|
||||
|
||||
/// Class which is responsible for showing the battle result window
|
||||
class BattleResultWindow : public WindowBase
|
||||
{
|
||||
@@ -195,25 +205,10 @@ private:
|
||||
std::shared_ptr<CButton> repeat;
|
||||
std::vector<std::shared_ptr<CAnimImage>> icons;
|
||||
std::shared_ptr<CTextBox> description;
|
||||
std::shared_ptr<VideoWidget> videoPlayer;
|
||||
CPlayerInterface & owner;
|
||||
|
||||
enum BattleResultVideo
|
||||
{
|
||||
NONE,
|
||||
WIN,
|
||||
SURRENDER,
|
||||
RETREAT,
|
||||
RETREAT_LOOP,
|
||||
DEFEAT,
|
||||
DEFEAT_LOOP,
|
||||
DEFEAT_SIEGE,
|
||||
DEFEAT_SIEGE_LOOP,
|
||||
WIN_SIEGE,
|
||||
WIN_SIEGE_LOOP,
|
||||
};
|
||||
BattleResultVideo currentVideo;
|
||||
|
||||
void playVideo(bool startLoop = false);
|
||||
BattleResultResources getResources(const BattleResult & br);
|
||||
|
||||
void buttonPressed(int button); //internal function for button callbacks
|
||||
public:
|
||||
@@ -224,7 +219,6 @@ public:
|
||||
std::function<void(int result)> resultCallback; //callback receiving which button was pressed
|
||||
|
||||
void activate() override;
|
||||
void show(Canvas & to) override;
|
||||
};
|
||||
|
||||
/// Shows the stack queue
|
||||
|
||||
@@ -19,13 +19,13 @@
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/Shortcut.h"
|
||||
#include "../media/IMusicPlayer.h"
|
||||
#include "../media/IVideoPlayer.h"
|
||||
#include "../render/Canvas.h"
|
||||
#include "../widgets/CComponent.h"
|
||||
#include "../widgets/Buttons.h"
|
||||
#include "../widgets/MiscWidgets.h"
|
||||
#include "../widgets/ObjectLists.h"
|
||||
#include "../widgets/TextControls.h"
|
||||
#include "../widgets/VideoWidget.h"
|
||||
#include "../windows/GUIClasses.h"
|
||||
#include "../windows/InfoWindows.h"
|
||||
#include "../windows/CWindowObject.h"
|
||||
@@ -100,7 +100,7 @@ CCampaignScreen::CCampaignButton::CCampaignButton(const JsonNode & config, const
|
||||
pos.h = 116;
|
||||
|
||||
campFile = config["file"].String();
|
||||
video = VideoPath::fromJson(config["video"]);
|
||||
videoPath = VideoPath::fromJson(config["video"]);
|
||||
|
||||
status = CCampaignScreen::ENABLED;
|
||||
|
||||
@@ -127,7 +127,6 @@ CCampaignScreen::CCampaignButton::CCampaignButton(const JsonNode & config, const
|
||||
{
|
||||
addUsedEvents(LCLICK | HOVER);
|
||||
graphicsImage = std::make_shared<CPicture>(ImagePath::fromJson(config["image"]));
|
||||
|
||||
hoverLabel = std::make_shared<CLabel>(pos.w / 2, pos.h + 20, FONT_MEDIUM, ETextAlignment::CENTER, Colors::YELLOW, "");
|
||||
parent->addChild(hoverLabel.get());
|
||||
}
|
||||
@@ -136,30 +135,19 @@ CCampaignScreen::CCampaignButton::CCampaignButton(const JsonNode & config, const
|
||||
graphicsCompleted = std::make_shared<CPicture>(ImagePath::builtin("CAMPCHK"));
|
||||
}
|
||||
|
||||
void CCampaignScreen::CCampaignButton::show(Canvas & to)
|
||||
{
|
||||
if(status == CCampaignScreen::DISABLED)
|
||||
return;
|
||||
|
||||
CIntObject::show(to);
|
||||
|
||||
// Play the campaign button video when the mouse cursor is placed over the button
|
||||
if(isHovered())
|
||||
CCS->videoh->update(pos.x, pos.y, to.getInternalSurface(), true, false); // plays sequentially frame by frame, starts at the beginning when the video is over
|
||||
}
|
||||
|
||||
void CCampaignScreen::CCampaignButton::clickReleased(const Point & cursorPosition)
|
||||
{
|
||||
CCS->videoh->close();
|
||||
CMainMenu::openCampaignLobby(campFile, campaignSet);
|
||||
}
|
||||
|
||||
void CCampaignScreen::CCampaignButton::hover(bool on)
|
||||
{
|
||||
if (on)
|
||||
CCS->videoh->open(video);
|
||||
OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE;
|
||||
|
||||
if (on && !videoPath.empty())
|
||||
videoPlayer = std::make_shared<VideoWidget>(Point(), videoPath);
|
||||
else
|
||||
CCS->videoh->close();
|
||||
videoPlayer.reset();
|
||||
|
||||
if(hoverLabel)
|
||||
{
|
||||
|
||||
@@ -20,6 +20,7 @@ VCMI_LIB_NAMESPACE_END
|
||||
class CLabel;
|
||||
class CPicture;
|
||||
class CButton;
|
||||
class VideoWidget;
|
||||
|
||||
class CCampaignScreen : public CWindowObject
|
||||
{
|
||||
@@ -34,10 +35,11 @@ private:
|
||||
std::shared_ptr<CLabel> hoverLabel;
|
||||
std::shared_ptr<CPicture> graphicsImage;
|
||||
std::shared_ptr<CPicture> graphicsCompleted;
|
||||
std::shared_ptr<VideoWidget> videoPlayer;
|
||||
CampaignStatus status;
|
||||
VideoPath videoPath;
|
||||
|
||||
std::string campFile; // the filename/resourcename of the campaign
|
||||
VideoPath video; // the resource name of the video
|
||||
std::string hoverText;
|
||||
|
||||
std::string campaignSet;
|
||||
@@ -47,7 +49,6 @@ private:
|
||||
|
||||
public:
|
||||
CCampaignButton(const JsonNode & config, const JsonNode & parentConfig, std::string campaignSet);
|
||||
void show(Canvas & to) override;
|
||||
};
|
||||
|
||||
std::string campaignSet;
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
#include "../gui/Shortcut.h"
|
||||
#include "../media/IMusicPlayer.h"
|
||||
#include "../media/ISoundPlayer.h"
|
||||
#include "../media/IVideoPlayer.h"
|
||||
#include "../widgets/Buttons.h"
|
||||
#include "../widgets/CTextInput.h"
|
||||
#include "../widgets/Images.h"
|
||||
#include "../widgets/GraphicalPrimitiveCanvas.h"
|
||||
#include "../widgets/VideoWidget.h"
|
||||
#include "../windows/InfoWindows.h"
|
||||
#include "../widgets/TextControls.h"
|
||||
#include "../render/Canvas.h"
|
||||
@@ -217,7 +217,7 @@ void CHighScoreScreen::buttonExitClick()
|
||||
}
|
||||
|
||||
CHighScoreInputScreen::CHighScoreInputScreen(bool won, HighScoreCalculation calc)
|
||||
: CWindowObject(BORDERED), won(won), calc(calc), videoSoundHandle(-1)
|
||||
: CWindowObject(BORDERED), won(won), calc(calc)
|
||||
{
|
||||
addUsedEvents(LCLICK | KEYBOARD);
|
||||
|
||||
@@ -229,6 +229,8 @@ CHighScoreInputScreen::CHighScoreInputScreen(bool won, HighScoreCalculation calc
|
||||
|
||||
if(won)
|
||||
{
|
||||
videoPlayer = std::make_shared<VideoWidget>(Point(30, 120), VideoPath::builtin("HSANIM.SMK"), VideoPath::builtin("HSLOOP.SMK"));
|
||||
|
||||
int border = 100;
|
||||
int textareaW = ((pos.w - 2 * border) / 4);
|
||||
std::vector<std::string> t = { "438", "439", "440", "441", "676" }; // time, score, difficulty, final score, rank
|
||||
@@ -243,9 +245,10 @@ CHighScoreInputScreen::CHighScoreInputScreen(bool won, HighScoreCalculation calc
|
||||
CCS->musich->playMusic(AudioPath::builtin("music/Win Scenario"), true, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
videoPlayer = std::make_shared<VideoWidget>(Point(30, 120), VideoPath::builtin("HSANIM.SMK"), VideoPath::builtin("LOSEGAME.SMK"));
|
||||
CCS->musich->playMusic(AudioPath::builtin("music/UltimateLose"), false, true);
|
||||
|
||||
video = won ? "HSANIM.SMK" : "LOSEGAME.SMK";
|
||||
}
|
||||
}
|
||||
|
||||
int CHighScoreInputScreen::addEntry(std::string text) {
|
||||
@@ -288,47 +291,6 @@ int CHighScoreInputScreen::addEntry(std::string text) {
|
||||
return pos;
|
||||
}
|
||||
|
||||
void CHighScoreInputScreen::show(Canvas & to)
|
||||
{
|
||||
CCS->videoh->update(pos.x, pos.y, to.getInternalSurface(), true, false,
|
||||
[&]()
|
||||
{
|
||||
if(won)
|
||||
{
|
||||
CCS->videoh->close();
|
||||
video = "HSLOOP.SMK";
|
||||
auto audioData = CCS->videoh->getAudio(VideoPath::builtin(video));
|
||||
videoSoundHandle = CCS->soundh->playSound(audioData);
|
||||
CCS->videoh->open(VideoPath::builtin(video));
|
||||
}
|
||||
else
|
||||
close();
|
||||
});
|
||||
redraw();
|
||||
|
||||
CIntObject::show(to);
|
||||
}
|
||||
|
||||
void CHighScoreInputScreen::activate()
|
||||
{
|
||||
auto audioData = CCS->videoh->getAudio(VideoPath::builtin(video));
|
||||
videoSoundHandle = CCS->soundh->playSound(audioData);
|
||||
if(!CCS->videoh->open(VideoPath::builtin(video)))
|
||||
{
|
||||
if(!won)
|
||||
close();
|
||||
}
|
||||
else
|
||||
background = nullptr;
|
||||
CIntObject::activate();
|
||||
}
|
||||
|
||||
void CHighScoreInputScreen::deactivate()
|
||||
{
|
||||
CCS->videoh->close();
|
||||
CCS->soundh->stopSound(videoSoundHandle);
|
||||
}
|
||||
|
||||
void CHighScoreInputScreen::clickPressed(const Point & cursorPosition)
|
||||
{
|
||||
OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE;
|
||||
|
||||
@@ -15,6 +15,7 @@ class CLabel;
|
||||
class CMultiLineLabel;
|
||||
class CAnimImage;
|
||||
class CTextInput;
|
||||
class VideoWidget;
|
||||
|
||||
class TransparentFilledRectangle;
|
||||
|
||||
@@ -93,9 +94,8 @@ class CHighScoreInputScreen : public CWindowObject
|
||||
std::vector<std::shared_ptr<CMultiLineLabel>> texts;
|
||||
std::shared_ptr<CHighScoreInput> input;
|
||||
std::shared_ptr<TransparentFilledRectangle> background;
|
||||
std::shared_ptr<VideoWidget> videoPlayer;
|
||||
|
||||
std::string video;
|
||||
int videoSoundHandle;
|
||||
bool won;
|
||||
HighScoreCalculation calc;
|
||||
public:
|
||||
@@ -103,9 +103,6 @@ public:
|
||||
|
||||
int addEntry(std::string text);
|
||||
|
||||
void show(Canvas & to) override;
|
||||
void activate() override;
|
||||
void deactivate() override;
|
||||
void clickPressed(const Point & cursorPosition) override;
|
||||
void keyPressed(EShortcut key) override;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#include "../lobby/CSelectionBase.h"
|
||||
#include "../lobby/CLobbyScreen.h"
|
||||
#include "../media/IMusicPlayer.h"
|
||||
#include "../media/IVideoPlayer.h"
|
||||
#include "../gui/CursorHandler.h"
|
||||
#include "../windows/GUIClasses.h"
|
||||
#include "../gui/CGuiHandler.h"
|
||||
@@ -35,6 +34,7 @@
|
||||
#include "../widgets/MiscWidgets.h"
|
||||
#include "../widgets/ObjectLists.h"
|
||||
#include "../widgets/TextControls.h"
|
||||
#include "../widgets/VideoWidget.h"
|
||||
#include "../windows/InfoWindows.h"
|
||||
#include "../CServerHandler.h"
|
||||
|
||||
@@ -92,8 +92,14 @@ CMenuScreen::CMenuScreen(const JsonNode & configNode)
|
||||
menuNameToEntry.push_back("credits");
|
||||
|
||||
tabs = std::make_shared<CTabbedInt>(std::bind(&CMenuScreen::createTab, this, _1));
|
||||
if(config["video"].isNull())
|
||||
if(!config["video"].isNull())
|
||||
{
|
||||
Point videoPosition(config["video"]["x"].Integer(), config["video"]["y"].Integer());
|
||||
videoPlayer = std::make_shared<VideoWidget>(videoPosition, VideoPath::fromJson(config["video"]["name"]));
|
||||
}
|
||||
else
|
||||
tabs->setRedrawParent(true);
|
||||
|
||||
}
|
||||
|
||||
std::shared_ptr<CIntObject> CMenuScreen::createTab(size_t index)
|
||||
@@ -104,34 +110,12 @@ std::shared_ptr<CIntObject> CMenuScreen::createTab(size_t index)
|
||||
return std::make_shared<CMenuEntry>(this, config["items"].Vector()[index]);
|
||||
}
|
||||
|
||||
void CMenuScreen::show(Canvas & to)
|
||||
{
|
||||
if(!config["video"].isNull())
|
||||
{
|
||||
// redraw order: background -> video -> buttons and pictures
|
||||
background->redraw();
|
||||
CCS->videoh->update((int)config["video"]["x"].Float() + pos.x, (int)config["video"]["y"].Float() + pos.y, to.getInternalSurface(), true, false);
|
||||
tabs->redraw();
|
||||
}
|
||||
CIntObject::show(to);
|
||||
}
|
||||
|
||||
void CMenuScreen::activate()
|
||||
{
|
||||
CCS->musich->playMusic(AudioPath::builtin("Music/MainMenu"), true, true);
|
||||
if(!config["video"].isNull())
|
||||
CCS->videoh->open(VideoPath::fromJson(config["video"]["name"]));
|
||||
CIntObject::activate();
|
||||
}
|
||||
|
||||
void CMenuScreen::deactivate()
|
||||
{
|
||||
if(!config["video"].isNull())
|
||||
CCS->videoh->close();
|
||||
|
||||
CIntObject::deactivate();
|
||||
}
|
||||
|
||||
void CMenuScreen::switchToTab(size_t index)
|
||||
{
|
||||
tabs->setActive(index);
|
||||
|
||||
@@ -28,7 +28,7 @@ class CAnimation;
|
||||
class CButton;
|
||||
class CFilledTexture;
|
||||
class CLabel;
|
||||
|
||||
class VideoWidget;
|
||||
|
||||
// TODO: Find new location for these enums
|
||||
enum class ESelectionScreen : ui8 {
|
||||
@@ -48,6 +48,7 @@ class CMenuScreen : public CWindowObject
|
||||
std::shared_ptr<CTabbedInt> tabs;
|
||||
|
||||
std::shared_ptr<CPicture> background;
|
||||
std::shared_ptr<VideoWidget> videoPlayer;
|
||||
std::vector<std::shared_ptr<CPicture>> images;
|
||||
|
||||
std::shared_ptr<CIntObject> createTab(size_t index);
|
||||
@@ -57,9 +58,7 @@ public:
|
||||
|
||||
CMenuScreen(const JsonNode & configNode);
|
||||
|
||||
void show(Canvas & to) override;
|
||||
void activate() override;
|
||||
void deactivate() override;
|
||||
|
||||
void switchToTab(size_t index);
|
||||
void switchToTab(std::string name);
|
||||
|
||||
@@ -14,14 +14,13 @@
|
||||
#include "../CGameInfo.h"
|
||||
#include "../media/IMusicPlayer.h"
|
||||
#include "../media/ISoundPlayer.h"
|
||||
#include "../media/IVideoPlayer.h"
|
||||
#include "../gui/WindowHandler.h"
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/FramerateManager.h"
|
||||
#include "../widgets/TextControls.h"
|
||||
#include "../widgets/VideoWidget.h"
|
||||
#include "../render/Canvas.h"
|
||||
|
||||
|
||||
CPrologEpilogVideo::CPrologEpilogVideo(CampaignScenarioPrologEpilog _spe, std::function<void()> callback)
|
||||
: CWindowObject(BORDERED), spe(_spe), positionCounter(0), voiceSoundHandle(-1), videoSoundHandle(-1), exitCb(callback), elapsedTimeMilliseconds(0)
|
||||
{
|
||||
@@ -30,9 +29,12 @@ CPrologEpilogVideo::CPrologEpilogVideo(CampaignScenarioPrologEpilog _spe, std::f
|
||||
pos = center(Rect(0, 0, 800, 600));
|
||||
updateShadow();
|
||||
|
||||
auto audioData = CCS->videoh->getAudio(spe.prologVideo);
|
||||
videoSoundHandle = CCS->soundh->playSound(audioData, -1);
|
||||
CCS->videoh->open(spe.prologVideo);
|
||||
videoPlayer = std::make_shared<VideoWidget>(Point(30, 120), spe.prologVideo);
|
||||
|
||||
//some videos are 800x600 in size while some are 800x400
|
||||
if (videoPlayer->pos.h == 400)
|
||||
videoPlayer->moveBy(Point(0, 100));
|
||||
|
||||
CCS->musich->playMusic(spe.prologMusic, true, true);
|
||||
voiceDurationMilliseconds = CCS->soundh->getSoundDurationMilliseconds(spe.prologVoice);
|
||||
voiceSoundHandle = CCS->soundh->playSound(spe.prologVoice);
|
||||
@@ -66,9 +68,8 @@ void CPrologEpilogVideo::tick(uint32_t msPassed)
|
||||
void CPrologEpilogVideo::show(Canvas & to)
|
||||
{
|
||||
to.drawColor(pos, Colors::BLACK);
|
||||
//some videos are 800x600 in size while some are 800x400
|
||||
CCS->videoh->update(pos.x, pos.y + (CCS->videoh->size().y == 400 ? 100 : 0), to.getInternalSurface(), true, false);
|
||||
|
||||
videoPlayer->show(to);
|
||||
text->showAll(to); // blit text over video, if needed
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "../../lib/campaign/CampaignScenarioPrologEpilog.h"
|
||||
|
||||
class CMultiLineLabel;
|
||||
class VideoWidget;
|
||||
|
||||
class CPrologEpilogVideo : public CWindowObject
|
||||
{
|
||||
@@ -25,6 +26,7 @@ class CPrologEpilogVideo : public CWindowObject
|
||||
std::function<void()> exitCb;
|
||||
|
||||
std::shared_ptr<CMultiLineLabel> text;
|
||||
std::shared_ptr<VideoWidget> videoPlayer;
|
||||
|
||||
bool voiceStopped = false;
|
||||
|
||||
|
||||
@@ -15,13 +15,10 @@
|
||||
class CEmptyVideoPlayer final : public IVideoPlayer
|
||||
{
|
||||
public:
|
||||
int curFrame() const override {return -1;};
|
||||
int frameCount() const override {return -1;};
|
||||
void redraw( int x, int y, SDL_Surface *dst, bool update) override {};
|
||||
void show( int x, int y, SDL_Surface *dst, bool update) override {};
|
||||
bool nextFrame() override {return false;};
|
||||
void close() override {};
|
||||
bool wait() override {return false;};
|
||||
bool open(const VideoPath & name, bool scale) override {return false;};
|
||||
void update(int x, int y, SDL_Surface *dst, bool forceRedraw, bool update, std::function<void()> restart) override {}
|
||||
bool openAndPlayVideo(const VideoPath & name, int x, int y, EVideoType videoType) override { return false; }
|
||||
|
||||
@@ -73,11 +73,6 @@ public:
|
||||
|
||||
Point size() override;
|
||||
|
||||
//TODO:
|
||||
bool wait() override {return false;};
|
||||
int curFrame() const override {return -1;};
|
||||
int frameCount() const override {return -1;};
|
||||
|
||||
// public to allow access from ffmpeg IO functions
|
||||
std::unique_ptr<CInputStream> data;
|
||||
std::unique_ptr<CInputStream> dataAudio;
|
||||
|
||||
@@ -31,9 +31,6 @@ public:
|
||||
virtual bool nextFrame()=0;
|
||||
virtual void show(int x, int y, SDL_Surface *dst, bool update = true)=0;
|
||||
virtual void redraw(int x, int y, SDL_Surface *dst, bool update = true)=0; //reblits buffer
|
||||
virtual bool wait()=0;
|
||||
virtual int curFrame() const =0;
|
||||
virtual int frameCount() const =0;
|
||||
virtual void update(int x, int y, SDL_Surface *dst, bool forceRedraw, bool update = true, std::function<void()> restart = nullptr) = 0;
|
||||
virtual bool openAndPlayVideo(const VideoPath & name, int x, int y, EVideoType videoType) = 0;
|
||||
virtual std::pair<std::unique_ptr<ui8 []>, si64> getAudio(const VideoPath & videoToOpen) = 0;
|
||||
|
||||
68
client/widgets/VideoWidget.cpp
Normal file
68
client/widgets/VideoWidget.cpp
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* TextControls.cpp, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#include "StdInc.h"
|
||||
#include "VideoWidget.h"
|
||||
|
||||
#include "../CGameInfo.h"
|
||||
#include "../media/IVideoPlayer.h"
|
||||
#include "../media/ISoundPlayer.h"
|
||||
#include "../render/Canvas.h"
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/WindowHandler.h"
|
||||
|
||||
VideoWidget::VideoWidget(const Point & position, const VideoPath & looped)
|
||||
: VideoWidget(position, VideoPath(), looped)
|
||||
{
|
||||
}
|
||||
|
||||
VideoWidget::VideoWidget(const Point & position, const VideoPath & prologue, const VideoPath & looped)
|
||||
:current(prologue)
|
||||
,next(looped)
|
||||
,videoSoundHandle(-1)
|
||||
{
|
||||
}
|
||||
|
||||
VideoWidget::~VideoWidget() = default;
|
||||
|
||||
void VideoWidget::show(Canvas & to)
|
||||
{
|
||||
CCS->videoh->update(pos.x + 107, pos.y + 70, to.getInternalSurface(), true, false);
|
||||
}
|
||||
|
||||
void VideoWidget::activate()
|
||||
{
|
||||
CCS->videoh->open(current);
|
||||
auto audioData = CCS->videoh->getAudio(current);
|
||||
videoSoundHandle = CCS->soundh->playSound(audioData, -1);
|
||||
|
||||
if (videoSoundHandle != -1)
|
||||
{
|
||||
CCS->soundh->setCallback(videoSoundHandle, [this](){
|
||||
if (GH.windows().isTopWindow(this))
|
||||
this->videoSoundHandle = -1;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void VideoWidget::deactivate()
|
||||
{
|
||||
CCS->videoh->close();
|
||||
CCS->soundh->stopSound(videoSoundHandle);
|
||||
}
|
||||
|
||||
void VideoWidget::showAll(Canvas & to)
|
||||
{
|
||||
CCS->videoh->update(pos.x + 107, pos.y + 70, to.getInternalSurface(), true, false);
|
||||
}
|
||||
|
||||
void VideoWidget::tick(uint32_t msPassed)
|
||||
{
|
||||
|
||||
}
|
||||
32
client/widgets/VideoWidget.h
Normal file
32
client/widgets/VideoWidget.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* VideoWidget.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "../gui/CIntObject.h"
|
||||
|
||||
#include "../lib/filesystem/ResourcePath.h"
|
||||
|
||||
class VideoWidget final : public CIntObject
|
||||
{
|
||||
VideoPath current;
|
||||
VideoPath next;
|
||||
|
||||
int videoSoundHandle;
|
||||
public:
|
||||
VideoWidget(const Point & position, const VideoPath & prologue, const VideoPath & looped);
|
||||
VideoWidget(const Point & position, const VideoPath & looped);
|
||||
~VideoWidget();
|
||||
|
||||
void activate() override;
|
||||
void deactivate() override;
|
||||
void show(Canvas & to) override;
|
||||
void showAll(Canvas & to) override;
|
||||
void tick(uint32_t msPassed) override;
|
||||
};
|
||||
@@ -20,10 +20,10 @@
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/Shortcut.h"
|
||||
#include "../gui/WindowHandler.h"
|
||||
#include "../media/IVideoPlayer.h"
|
||||
#include "../widgets/Images.h"
|
||||
#include "../widgets/Buttons.h"
|
||||
#include "../widgets/TextControls.h"
|
||||
#include "../widgets/VideoWidget.h"
|
||||
#include "../render/Canvas.h"
|
||||
|
||||
CTutorialWindow::CTutorialWindow(const TutorialMode & m)
|
||||
@@ -54,7 +54,10 @@ CTutorialWindow::CTutorialWindow(const TutorialMode & m)
|
||||
|
||||
void CTutorialWindow::setContent()
|
||||
{
|
||||
video = "tutorial/" + videos[page];
|
||||
OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE;
|
||||
auto video = VideoPath::builtin("tutorial/" + videos[page]);
|
||||
|
||||
videoPlayer = std::make_shared<VideoWidget>(Point(30, 120), video);
|
||||
|
||||
buttonLeft->block(page<1);
|
||||
buttonRight->block(page>videos.size() - 2);
|
||||
@@ -98,26 +101,3 @@ void CTutorialWindow::previous()
|
||||
deactivate();
|
||||
activate();
|
||||
}
|
||||
|
||||
void CTutorialWindow::show(Canvas & to)
|
||||
{
|
||||
CCS->videoh->update(pos.x + 30, pos.y + 120, to.getInternalSurface(), true, false,
|
||||
[&]()
|
||||
{
|
||||
CCS->videoh->close();
|
||||
CCS->videoh->open(VideoPath::builtin(video));
|
||||
});
|
||||
|
||||
CIntObject::show(to);
|
||||
}
|
||||
|
||||
void CTutorialWindow::activate()
|
||||
{
|
||||
CCS->videoh->open(VideoPath::builtin(video));
|
||||
CIntObject::activate();
|
||||
}
|
||||
|
||||
void CTutorialWindow::deactivate()
|
||||
{
|
||||
CCS->videoh->close();
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ class CFilledTexture;
|
||||
class CButton;
|
||||
class CLabel;
|
||||
class CMultiLineLabel;
|
||||
class VideoWidget;
|
||||
|
||||
enum TutorialMode
|
||||
{
|
||||
@@ -33,8 +34,8 @@ class CTutorialWindow : public CWindowObject
|
||||
|
||||
std::shared_ptr<CLabel> labelTitle;
|
||||
std::shared_ptr<CMultiLineLabel> labelInformation;
|
||||
std::shared_ptr<VideoWidget> videoPlayer;
|
||||
|
||||
std::string video;
|
||||
std::vector<std::string> videos;
|
||||
|
||||
int page;
|
||||
@@ -47,8 +48,4 @@ class CTutorialWindow : public CWindowObject
|
||||
public:
|
||||
CTutorialWindow(const TutorialMode & m);
|
||||
static void openWindowFirstTime(const TutorialMode & m);
|
||||
|
||||
void show(Canvas & to) override;
|
||||
void activate() override;
|
||||
void deactivate() override;
|
||||
};
|
||||
|
||||
@@ -26,8 +26,6 @@
|
||||
#include "../gui/Shortcut.h"
|
||||
#include "../gui/WindowHandler.h"
|
||||
|
||||
#include "../media/IVideoPlayer.h"
|
||||
|
||||
#include "../widgets/CComponent.h"
|
||||
#include "../widgets/CGarrisonInt.h"
|
||||
#include "../widgets/CreatureCostBox.h"
|
||||
@@ -36,6 +34,7 @@
|
||||
#include "../widgets/Slider.h"
|
||||
#include "../widgets/TextControls.h"
|
||||
#include "../widgets/ObjectLists.h"
|
||||
#include "../widgets/VideoWidget.h"
|
||||
|
||||
#include "../render/Canvas.h"
|
||||
#include "../render/CAnimation.h"
|
||||
@@ -516,11 +515,11 @@ CTavernWindow::CTavernWindow(const CGObjectInstance * TavernObj, const std::func
|
||||
recruit->block(true);
|
||||
}
|
||||
if(LOCPLINT->castleInt)
|
||||
CCS->videoh->open(LOCPLINT->castleInt->town->town->clientInfo.tavernVideo);
|
||||
videoPlayer = std::make_shared<VideoWidget>(Point(70, 56), LOCPLINT->castleInt->town->town->clientInfo.tavernVideo);
|
||||
else if(const auto * townObj = dynamic_cast<const CGTownInstance *>(TavernObj))
|
||||
CCS->videoh->open(townObj->town->clientInfo.tavernVideo);
|
||||
videoPlayer = std::make_shared<VideoWidget>(Point(70, 56), townObj->town->clientInfo.tavernVideo);
|
||||
else
|
||||
CCS->videoh->open(VideoPath::builtin("TAVERN.BIK"));
|
||||
videoPlayer = std::make_shared<VideoWidget>(Point(70, 56), VideoPath::builtin("TAVERN.BIK"));
|
||||
|
||||
addInvite();
|
||||
}
|
||||
@@ -573,11 +572,6 @@ void CTavernWindow::close()
|
||||
CStatusbarWindow::close();
|
||||
}
|
||||
|
||||
CTavernWindow::~CTavernWindow()
|
||||
{
|
||||
CCS->videoh->close();
|
||||
}
|
||||
|
||||
void CTavernWindow::show(Canvas & to)
|
||||
{
|
||||
CWindowObject::show(to);
|
||||
@@ -601,8 +595,6 @@ void CTavernWindow::show(Canvas & to)
|
||||
|
||||
to.drawBorder(Rect::createAround(sel->pos, 2), Colors::BRIGHT_YELLOW, 2);
|
||||
}
|
||||
|
||||
CCS->videoh->update(pos.x+70, pos.y+56, to.getInternalSurface(), true, false);
|
||||
}
|
||||
|
||||
void CTavernWindow::HeroPortrait::clickPressed(const Point & cursorPosition)
|
||||
|
||||
@@ -39,6 +39,7 @@ class CHeroArea;
|
||||
class CAnimImage;
|
||||
class CFilledTexture;
|
||||
class IImage;
|
||||
class VideoWidget;
|
||||
|
||||
enum class EUserEvent;
|
||||
|
||||
@@ -261,6 +262,7 @@ public:
|
||||
std::shared_ptr<CLabel> cost;
|
||||
std::shared_ptr<CLabel> heroesForHire;
|
||||
std::shared_ptr<CTextBox> heroDescription;
|
||||
std::shared_ptr<VideoWidget> videoPlayer;
|
||||
|
||||
std::shared_ptr<CTextBox> rumor;
|
||||
|
||||
@@ -272,7 +274,6 @@ public:
|
||||
void addInvite();
|
||||
|
||||
CTavernWindow(const CGObjectInstance * TavernObj, const std::function<void()> & onWindowClosed);
|
||||
~CTavernWindow();
|
||||
|
||||
void close() override;
|
||||
void recruitb();
|
||||
|
||||
Reference in New Issue
Block a user