2014-06-25 16:29:58 +00:00
|
|
|
#include "views/SystemView.h"
|
2017-11-01 22:21:10 +00:00
|
|
|
|
2014-06-25 16:29:58 +00:00
|
|
|
#include "animations/LambdaAnimation.h"
|
2017-09-08 13:20:07 +00:00
|
|
|
#include "guis/GuiMsgBox.h"
|
2017-11-18 22:23:56 +00:00
|
|
|
#include "views/UIModeController.h"
|
2017-11-01 22:21:10 +00:00
|
|
|
#include "views/ViewController.h"
|
|
|
|
#include "Log.h"
|
|
|
|
#include "Renderer.h"
|
2014-06-25 16:29:58 +00:00
|
|
|
#include "Settings.h"
|
2017-11-01 22:21:10 +00:00
|
|
|
#include "SystemData.h"
|
|
|
|
#include "Window.h"
|
2014-06-25 16:29:58 +00:00
|
|
|
|
2017-05-17 12:01:15 +00:00
|
|
|
// buffer values for scrolling velocity (left, stopped, right)
|
|
|
|
const int logoBuffersLeft[] = { -5, -2, -1 };
|
|
|
|
const int logoBuffersRight[] = { 1, 2, 5 };
|
|
|
|
|
2014-06-25 16:29:58 +00:00
|
|
|
SystemView::SystemView(Window* window) : IList<SystemViewData, SystemData*>(window, LIST_SCROLL_STYLE_SLOW, LIST_ALWAYS_LOOP),
|
2017-03-13 21:11:07 +00:00
|
|
|
mViewNeedsReload(true),
|
|
|
|
mSystemInfo(window, "SYSTEM INFO", Font::get(FONT_SIZE_SMALL), 0x33333300, ALIGN_CENTER)
|
2014-06-25 16:29:58 +00:00
|
|
|
{
|
|
|
|
mCamOffset = 0;
|
|
|
|
mExtrasCamOffset = 0;
|
|
|
|
mExtrasFadeOpacity = 0.0f;
|
|
|
|
|
|
|
|
setSize((float)Renderer::getScreenWidth(), (float)Renderer::getScreenHeight());
|
|
|
|
populate();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SystemView::populate()
|
|
|
|
{
|
|
|
|
mEntries.clear();
|
|
|
|
|
2017-11-11 14:56:22 +00:00
|
|
|
for(auto it = SystemData::sSystemVector.cbegin(); it != SystemData::sSystemVector.cend(); it++)
|
2014-06-25 16:29:58 +00:00
|
|
|
{
|
|
|
|
const std::shared_ptr<ThemeData>& theme = (*it)->getTheme();
|
|
|
|
|
2017-03-13 21:11:07 +00:00
|
|
|
if(mViewNeedsReload)
|
|
|
|
getViewElements(theme);
|
|
|
|
|
2017-09-08 13:20:07 +00:00
|
|
|
if((*it)->getDisplayedGameCount() > 0)
|
2014-06-25 16:29:58 +00:00
|
|
|
{
|
2017-09-08 13:20:07 +00:00
|
|
|
Entry e;
|
|
|
|
e.name = (*it)->getName();
|
|
|
|
e.object = *it;
|
2017-05-14 04:07:28 +00:00
|
|
|
|
2017-09-08 13:20:07 +00:00
|
|
|
// make logo
|
|
|
|
const ThemeData::ThemeElement* logoElem = theme->getElement("system", "logo", "image");
|
|
|
|
if(logoElem)
|
|
|
|
{
|
|
|
|
std::string path = logoElem->get<std::string>("path");
|
|
|
|
std::string defaultPath = logoElem->has("default") ? logoElem->get<std::string>("default") : "";
|
|
|
|
if((!path.empty() && ResourceManager::getInstance()->fileExists(path))
|
|
|
|
|| (!defaultPath.empty() && ResourceManager::getInstance()->fileExists(defaultPath)))
|
|
|
|
{
|
|
|
|
ImageComponent* logo = new ImageComponent(mWindow, false, false);
|
|
|
|
logo->setMaxSize(mCarousel.logoSize * mCarousel.logoScale);
|
|
|
|
logo->applyTheme(theme, "system", "logo", ThemeFlags::PATH | ThemeFlags::COLOR);
|
|
|
|
e.data.logo = std::shared_ptr<GuiComponent>(logo);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!e.data.logo)
|
|
|
|
{
|
|
|
|
// no logo in theme; use text
|
|
|
|
TextComponent* text = new TextComponent(mWindow,
|
|
|
|
(*it)->getName(),
|
|
|
|
Font::get(FONT_SIZE_LARGE),
|
|
|
|
0x000000FF,
|
|
|
|
ALIGN_CENTER);
|
|
|
|
text->setSize(mCarousel.logoSize * mCarousel.logoScale);
|
|
|
|
text->applyTheme((*it)->getTheme(), "system", "logoText", ThemeFlags::FONT_PATH | ThemeFlags::FONT_SIZE | ThemeFlags::COLOR | ThemeFlags::FORCE_UPPERCASE);
|
|
|
|
e.data.logo = std::shared_ptr<GuiComponent>(text);
|
|
|
|
|
|
|
|
if (mCarousel.type == VERTICAL || mCarousel.type == VERTICAL_WHEEL)
|
|
|
|
text->setHorizontalAlignment(mCarousel.logoAlignment);
|
|
|
|
else
|
|
|
|
text->setVerticalAlignment(mCarousel.logoAlignment);
|
2017-05-14 04:07:28 +00:00
|
|
|
}
|
2014-06-25 16:29:58 +00:00
|
|
|
|
2017-08-15 02:34:34 +00:00
|
|
|
if (mCarousel.type == VERTICAL || mCarousel.type == VERTICAL_WHEEL)
|
2017-09-08 13:20:07 +00:00
|
|
|
{
|
|
|
|
if (mCarousel.logoAlignment == ALIGN_LEFT)
|
|
|
|
e.data.logo->setOrigin(0, 0.5);
|
|
|
|
else if (mCarousel.logoAlignment == ALIGN_RIGHT)
|
|
|
|
e.data.logo->setOrigin(1.0, 0.5);
|
|
|
|
else
|
|
|
|
e.data.logo->setOrigin(0.5, 0.5);
|
|
|
|
} else {
|
|
|
|
if (mCarousel.logoAlignment == ALIGN_TOP)
|
|
|
|
e.data.logo->setOrigin(0.5, 0);
|
|
|
|
else if (mCarousel.logoAlignment == ALIGN_BOTTOM)
|
|
|
|
e.data.logo->setOrigin(0.5, 1);
|
|
|
|
else
|
|
|
|
e.data.logo->setOrigin(0.5, 0.5);
|
|
|
|
}
|
2017-08-15 02:34:34 +00:00
|
|
|
|
2017-09-08 13:20:07 +00:00
|
|
|
Vector2f denormalized = mCarousel.logoSize * e.data.logo->getOrigin();
|
|
|
|
e.data.logo->setPosition(denormalized.x(), denormalized.y(), 0.0);
|
|
|
|
// delete any existing extras
|
|
|
|
for (auto extra : e.data.backgroundExtras)
|
|
|
|
delete extra;
|
|
|
|
e.data.backgroundExtras.clear();
|
2017-04-22 14:15:16 +00:00
|
|
|
|
2017-09-08 13:20:07 +00:00
|
|
|
// make background extras
|
|
|
|
e.data.backgroundExtras = ThemeData::makeExtras((*it)->getTheme(), "system", mWindow);
|
2017-04-22 14:15:16 +00:00
|
|
|
|
2017-09-08 13:20:07 +00:00
|
|
|
// sort the extras by z-index
|
|
|
|
std::stable_sort(e.data.backgroundExtras.begin(), e.data.backgroundExtras.end(), [](GuiComponent* a, GuiComponent* b) {
|
|
|
|
return b->getZIndex() > a->getZIndex();
|
|
|
|
});
|
2014-06-25 16:29:58 +00:00
|
|
|
|
2017-09-08 13:20:07 +00:00
|
|
|
this->add(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (mEntries.size() == 0)
|
|
|
|
{
|
|
|
|
// Something is wrong, there is not a single system to show, check if UI mode is not full
|
2017-11-18 22:23:56 +00:00
|
|
|
if (!UIModeController::getInstance()->isUIModeFull())
|
2017-09-08 13:20:07 +00:00
|
|
|
{
|
|
|
|
Settings::getInstance()->setString("UIMode", "Full");
|
|
|
|
mWindow->pushGui(new GuiMsgBox(mWindow, "The selected UI mode has nothing to show,\n returning to UI mode: FULL", "OK", nullptr));
|
|
|
|
}
|
2014-06-25 16:29:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SystemView::goToSystem(SystemData* system, bool animate)
|
|
|
|
{
|
|
|
|
setCursor(system);
|
|
|
|
|
|
|
|
if(!animate)
|
|
|
|
finishAnimation(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SystemView::input(InputConfig* config, Input input)
|
|
|
|
{
|
|
|
|
if(input.value != 0)
|
|
|
|
{
|
|
|
|
if(config->getDeviceId() == DEVICE_KEYBOARD && input.value && input.id == SDLK_r && SDL_GetModState() & KMOD_LCTRL && Settings::getInstance()->getBool("Debug"))
|
|
|
|
{
|
2017-03-13 21:11:07 +00:00
|
|
|
LOG(LogInfo) << " Reloading all";
|
|
|
|
ViewController::get()->reloadAll();
|
2014-06-25 16:29:58 +00:00
|
|
|
return true;
|
|
|
|
}
|
2017-03-13 21:11:07 +00:00
|
|
|
|
|
|
|
switch (mCarousel.type)
|
2014-06-25 16:29:58 +00:00
|
|
|
{
|
2017-03-13 21:11:07 +00:00
|
|
|
case VERTICAL:
|
2017-08-15 02:34:34 +00:00
|
|
|
case VERTICAL_WHEEL:
|
2017-03-13 21:11:07 +00:00
|
|
|
if (config->isMappedTo("up", input))
|
|
|
|
{
|
|
|
|
listInput(-1);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (config->isMappedTo("down", input))
|
|
|
|
{
|
|
|
|
listInput(1);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case HORIZONTAL:
|
|
|
|
default:
|
|
|
|
if (config->isMappedTo("left", input))
|
|
|
|
{
|
|
|
|
listInput(-1);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (config->isMappedTo("right", input))
|
|
|
|
{
|
|
|
|
listInput(1);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
break;
|
2014-06-25 16:29:58 +00:00
|
|
|
}
|
2017-03-13 21:11:07 +00:00
|
|
|
|
2014-06-25 16:29:58 +00:00
|
|
|
if(config->isMappedTo("a", input))
|
|
|
|
{
|
|
|
|
stopScrolling();
|
2016-03-29 04:03:39 +00:00
|
|
|
ViewController::get()->goToGameList(getSelected());
|
2014-06-25 16:29:58 +00:00
|
|
|
return true;
|
|
|
|
}
|
2016-12-20 20:25:35 +00:00
|
|
|
if (config->isMappedTo("x", input))
|
|
|
|
{
|
2017-06-12 16:38:59 +00:00
|
|
|
// get random system
|
|
|
|
// go to system
|
|
|
|
setCursor(SystemData::getRandomSystem());
|
2016-12-20 20:25:35 +00:00
|
|
|
return true;
|
|
|
|
}
|
2014-06-25 16:29:58 +00:00
|
|
|
}else{
|
2017-05-27 07:40:18 +00:00
|
|
|
if(config->isMappedTo("left", input) ||
|
2017-03-13 21:11:07 +00:00
|
|
|
config->isMappedTo("right", input) ||
|
2017-05-27 07:40:18 +00:00
|
|
|
config->isMappedTo("up", input) ||
|
2017-03-13 21:11:07 +00:00
|
|
|
config->isMappedTo("down", input))
|
2014-06-25 16:29:58 +00:00
|
|
|
listInput(0);
|
2017-06-01 20:08:44 +00:00
|
|
|
if(config->isMappedTo("select", input) && Settings::getInstance()->getBool("ScreenSaverControls"))
|
|
|
|
{
|
|
|
|
mWindow->startScreenSaver();
|
|
|
|
mWindow->renderScreenSaver();
|
|
|
|
return true;
|
|
|
|
}
|
2014-06-25 16:29:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return GuiComponent::input(config, input);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SystemView::update(int deltaTime)
|
|
|
|
{
|
|
|
|
listUpdate(deltaTime);
|
|
|
|
GuiComponent::update(deltaTime);
|
|
|
|
}
|
|
|
|
|
2017-11-17 14:58:52 +00:00
|
|
|
void SystemView::onCursorChanged(const CursorState& /*state*/)
|
2014-06-25 16:29:58 +00:00
|
|
|
{
|
|
|
|
// update help style
|
|
|
|
updateHelpPrompts();
|
|
|
|
|
|
|
|
float startPos = mCamOffset;
|
|
|
|
|
|
|
|
float posMax = (float)mEntries.size();
|
|
|
|
float target = (float)mCursor;
|
|
|
|
|
|
|
|
// what's the shortest way to get to our target?
|
|
|
|
// it's one of these...
|
|
|
|
|
|
|
|
float endPos = target; // directly
|
|
|
|
float dist = abs(endPos - startPos);
|
2017-05-27 07:40:18 +00:00
|
|
|
|
2014-06-25 16:29:58 +00:00
|
|
|
if(abs(target + posMax - startPos) < dist)
|
|
|
|
endPos = target + posMax; // loop around the end (0 -> max)
|
|
|
|
if(abs(target - posMax - startPos) < dist)
|
|
|
|
endPos = target - posMax; // loop around the start (max - 1 -> -1)
|
|
|
|
|
2017-05-27 07:40:18 +00:00
|
|
|
|
2014-06-25 16:29:58 +00:00
|
|
|
// animate mSystemInfo's opacity (fade out, wait, fade back in)
|
|
|
|
|
|
|
|
cancelAnimation(1);
|
|
|
|
cancelAnimation(2);
|
|
|
|
|
2017-07-20 07:07:02 +00:00
|
|
|
std::string transition_style = Settings::getInstance()->getString("TransitionStyle");
|
|
|
|
bool goFast = transition_style == "instant";
|
2014-06-25 16:29:58 +00:00
|
|
|
const float infoStartOpacity = mSystemInfo.getOpacity() / 255.f;
|
|
|
|
|
|
|
|
Animation* infoFadeOut = new LambdaAnimation(
|
|
|
|
[infoStartOpacity, this] (float t)
|
|
|
|
{
|
2017-11-13 22:16:38 +00:00
|
|
|
mSystemInfo.setOpacity((unsigned char)(Math::lerp(infoStartOpacity, 0.f, t) * 255));
|
2017-07-20 07:07:02 +00:00
|
|
|
}, (int)(infoStartOpacity * (goFast ? 10 : 150)));
|
2014-06-25 16:29:58 +00:00
|
|
|
|
2017-05-27 07:40:18 +00:00
|
|
|
unsigned int gameCount = getSelected()->getDisplayedGameCount();
|
2014-06-25 16:29:58 +00:00
|
|
|
|
|
|
|
// also change the text after we've fully faded out
|
|
|
|
setAnimation(infoFadeOut, 0, [this, gameCount] {
|
|
|
|
std::stringstream ss;
|
2017-05-27 07:40:18 +00:00
|
|
|
|
2017-06-12 16:38:59 +00:00
|
|
|
if (!getSelected()->isGameSystem())
|
2016-11-08 19:38:10 +00:00
|
|
|
ss << "CONFIGURATION";
|
2017-07-20 07:07:02 +00:00
|
|
|
else
|
2014-06-25 16:29:58 +00:00
|
|
|
ss << gameCount << " GAMES AVAILABLE";
|
|
|
|
|
2017-05-27 07:40:18 +00:00
|
|
|
mSystemInfo.setText(ss.str());
|
2014-06-25 16:29:58 +00:00
|
|
|
}, false, 1);
|
|
|
|
|
2017-07-20 07:07:02 +00:00
|
|
|
Animation* infoFadeIn = new LambdaAnimation(
|
|
|
|
[this](float t)
|
2014-06-25 16:29:58 +00:00
|
|
|
{
|
2017-11-13 22:16:38 +00:00
|
|
|
mSystemInfo.setOpacity((unsigned char)(Math::lerp(0.f, 1.f, t) * 255));
|
2017-07-20 07:07:02 +00:00
|
|
|
}, goFast ? 10 : 300);
|
2014-06-25 16:29:58 +00:00
|
|
|
|
2017-07-20 07:07:02 +00:00
|
|
|
// wait 600ms to fade in
|
|
|
|
setAnimation(infoFadeIn, goFast ? 0 : 2000, nullptr, false, 2);
|
2014-06-25 16:29:58 +00:00
|
|
|
|
|
|
|
// no need to animate transition, we're not going anywhere (probably mEntries.size() == 1)
|
|
|
|
if(endPos == mCamOffset && endPos == mExtrasCamOffset)
|
|
|
|
return;
|
|
|
|
|
|
|
|
Animation* anim;
|
2017-06-28 16:50:37 +00:00
|
|
|
bool move_carousel = Settings::getInstance()->getBool("MoveCarousel");
|
2017-05-26 00:52:49 +00:00
|
|
|
if(transition_style == "fade")
|
2014-06-25 16:29:58 +00:00
|
|
|
{
|
|
|
|
float startExtrasFade = mExtrasFadeOpacity;
|
|
|
|
anim = new LambdaAnimation(
|
2017-06-28 16:50:37 +00:00
|
|
|
[this, startExtrasFade, startPos, endPos, posMax, move_carousel](float t)
|
2014-06-25 16:29:58 +00:00
|
|
|
{
|
|
|
|
t -= 1;
|
2017-11-13 22:16:38 +00:00
|
|
|
float f = Math::lerp(startPos, endPos, t*t*t + 1);
|
2014-06-25 16:29:58 +00:00
|
|
|
if(f < 0)
|
|
|
|
f += posMax;
|
|
|
|
if(f >= posMax)
|
|
|
|
f -= posMax;
|
|
|
|
|
2017-06-28 16:50:37 +00:00
|
|
|
this->mCamOffset = move_carousel ? f : endPos;
|
2014-06-25 16:29:58 +00:00
|
|
|
|
|
|
|
t += 1;
|
|
|
|
if(t < 0.3f)
|
2017-11-13 22:16:38 +00:00
|
|
|
this->mExtrasFadeOpacity = Math::lerp(0.0f, 1.0f, t / 0.3f + startExtrasFade);
|
2014-06-25 16:29:58 +00:00
|
|
|
else if(t < 0.7f)
|
|
|
|
this->mExtrasFadeOpacity = 1.0f;
|
|
|
|
else
|
2017-11-13 22:16:38 +00:00
|
|
|
this->mExtrasFadeOpacity = Math::lerp(1.0f, 0.0f, (t - 0.7f) / 0.3f);
|
2014-06-25 16:29:58 +00:00
|
|
|
|
|
|
|
if(t > 0.5f)
|
|
|
|
this->mExtrasCamOffset = endPos;
|
|
|
|
|
|
|
|
}, 500);
|
2017-05-26 00:52:49 +00:00
|
|
|
} else if (transition_style == "slide") {
|
2017-05-24 00:41:14 +00:00
|
|
|
// slide
|
2014-06-25 16:29:58 +00:00
|
|
|
anim = new LambdaAnimation(
|
2017-06-28 16:50:37 +00:00
|
|
|
[this, startPos, endPos, posMax, move_carousel](float t)
|
2014-06-25 16:29:58 +00:00
|
|
|
{
|
|
|
|
t -= 1;
|
2017-11-13 22:16:38 +00:00
|
|
|
float f = Math::lerp(startPos, endPos, t*t*t + 1);
|
2014-06-25 16:29:58 +00:00
|
|
|
if(f < 0)
|
|
|
|
f += posMax;
|
|
|
|
if(f >= posMax)
|
|
|
|
f -= posMax;
|
|
|
|
|
2017-06-28 16:50:37 +00:00
|
|
|
this->mCamOffset = move_carousel ? f : endPos;
|
2014-06-25 16:29:58 +00:00
|
|
|
this->mExtrasCamOffset = f;
|
|
|
|
}, 500);
|
2017-06-28 16:50:37 +00:00
|
|
|
} else {
|
|
|
|
// instant
|
2017-05-26 00:52:49 +00:00
|
|
|
anim = new LambdaAnimation(
|
2017-06-28 16:50:37 +00:00
|
|
|
[this, startPos, endPos, posMax, move_carousel ](float t)
|
2017-05-26 00:52:49 +00:00
|
|
|
{
|
|
|
|
t -= 1;
|
2017-11-13 22:16:38 +00:00
|
|
|
float f = Math::lerp(startPos, endPos, t*t*t + 1);
|
2017-05-26 00:52:49 +00:00
|
|
|
if(f < 0)
|
|
|
|
f += posMax;
|
|
|
|
if(f >= posMax)
|
|
|
|
f -= posMax;
|
|
|
|
|
2017-06-28 16:50:37 +00:00
|
|
|
this->mCamOffset = move_carousel ? f : endPos;
|
2017-05-24 00:41:14 +00:00
|
|
|
this->mExtrasCamOffset = endPos;
|
2017-06-28 16:50:37 +00:00
|
|
|
}, move_carousel ? 500 : 1);
|
2014-06-25 16:29:58 +00:00
|
|
|
}
|
|
|
|
|
2017-05-24 00:41:14 +00:00
|
|
|
|
2014-06-25 16:29:58 +00:00
|
|
|
setAnimation(anim, 0, nullptr, false, 0);
|
|
|
|
}
|
|
|
|
|
2017-10-28 20:24:35 +00:00
|
|
|
void SystemView::render(const Transform4x4f& parentTrans)
|
2014-06-25 16:29:58 +00:00
|
|
|
{
|
|
|
|
if(size() == 0)
|
2017-03-13 21:11:07 +00:00
|
|
|
return; // nothing to render
|
2017-05-27 07:40:18 +00:00
|
|
|
|
2017-10-28 20:24:35 +00:00
|
|
|
Transform4x4f trans = getTransform() * parentTrans;
|
2014-06-25 16:29:58 +00:00
|
|
|
|
2017-04-22 14:15:16 +00:00
|
|
|
auto systemInfoZIndex = mSystemInfo.getZIndex();
|
|
|
|
auto minMax = std::minmax(mCarousel.zIndex, systemInfoZIndex);
|
|
|
|
|
|
|
|
renderExtras(trans, INT16_MIN, minMax.first);
|
|
|
|
renderFade(trans);
|
|
|
|
|
|
|
|
if (mCarousel.zIndex > mSystemInfo.getZIndex()) {
|
|
|
|
renderInfoBar(trans);
|
|
|
|
} else {
|
|
|
|
renderCarousel(trans);
|
|
|
|
}
|
|
|
|
|
|
|
|
renderExtras(trans, minMax.first, minMax.second);
|
|
|
|
|
|
|
|
if (mCarousel.zIndex > mSystemInfo.getZIndex()) {
|
|
|
|
renderCarousel(trans);
|
|
|
|
} else {
|
|
|
|
renderInfoBar(trans);
|
|
|
|
}
|
|
|
|
|
|
|
|
renderExtras(trans, minMax.second, INT16_MAX);
|
2017-03-13 21:11:07 +00:00
|
|
|
}
|
2014-06-25 16:29:58 +00:00
|
|
|
|
2017-03-13 21:11:07 +00:00
|
|
|
std::vector<HelpPrompt> SystemView::getHelpPrompts()
|
|
|
|
{
|
|
|
|
std::vector<HelpPrompt> prompts;
|
|
|
|
if (mCarousel.type == VERTICAL)
|
|
|
|
prompts.push_back(HelpPrompt("up/down", "choose"));
|
|
|
|
else
|
|
|
|
prompts.push_back(HelpPrompt("left/right", "choose"));
|
|
|
|
prompts.push_back(HelpPrompt("a", "select"));
|
2016-12-20 20:25:35 +00:00
|
|
|
prompts.push_back(HelpPrompt("x", "random"));
|
2017-06-01 20:08:44 +00:00
|
|
|
|
|
|
|
if (Settings::getInstance()->getBool("ScreenSaverControls"))
|
|
|
|
prompts.push_back(HelpPrompt("select", "launch screensaver"));
|
|
|
|
|
2017-03-13 21:11:07 +00:00
|
|
|
return prompts;
|
|
|
|
}
|
2014-06-25 16:29:58 +00:00
|
|
|
|
2017-03-13 21:11:07 +00:00
|
|
|
HelpStyle SystemView::getHelpStyle()
|
|
|
|
{
|
|
|
|
HelpStyle style;
|
|
|
|
style.applyTheme(mEntries.at(mCursor).object->getTheme(), "system");
|
|
|
|
return style;
|
|
|
|
}
|
2014-06-25 16:29:58 +00:00
|
|
|
|
2017-11-17 14:58:52 +00:00
|
|
|
void SystemView::onThemeChanged(const std::shared_ptr<ThemeData>& /*theme*/)
|
2017-03-13 21:11:07 +00:00
|
|
|
{
|
|
|
|
LOG(LogDebug) << "SystemView::onThemeChanged()";
|
|
|
|
mViewNeedsReload = true;
|
|
|
|
populate();
|
|
|
|
}
|
2014-06-25 16:29:58 +00:00
|
|
|
|
2017-03-13 21:11:07 +00:00
|
|
|
// Get the ThemeElements that make up the SystemView.
|
|
|
|
void SystemView::getViewElements(const std::shared_ptr<ThemeData>& theme)
|
|
|
|
{
|
|
|
|
LOG(LogDebug) << "SystemView::getViewElements()";
|
2014-06-25 16:29:58 +00:00
|
|
|
|
2017-03-13 21:11:07 +00:00
|
|
|
getDefaultElements();
|
2014-06-25 16:29:58 +00:00
|
|
|
|
2017-04-06 21:24:32 +00:00
|
|
|
if (!theme->hasView("system"))
|
|
|
|
return;
|
|
|
|
|
2017-03-13 21:11:07 +00:00
|
|
|
const ThemeData::ThemeElement* carouselElem = theme->getElement("system", "systemcarousel", "carousel");
|
|
|
|
if (carouselElem)
|
|
|
|
getCarouselFromTheme(carouselElem);
|
|
|
|
|
|
|
|
const ThemeData::ThemeElement* sysInfoElem = theme->getElement("system", "systemInfo", "text");
|
|
|
|
if (sysInfoElem)
|
|
|
|
mSystemInfo.applyTheme(theme, "system", "systemInfo", ThemeFlags::ALL);
|
|
|
|
|
|
|
|
mViewNeedsReload = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Render system carousel
|
2017-10-28 20:24:35 +00:00
|
|
|
void SystemView::renderCarousel(const Transform4x4f& trans)
|
2017-03-13 21:11:07 +00:00
|
|
|
{
|
2017-08-15 02:34:34 +00:00
|
|
|
// background box behind logos
|
2017-10-28 20:24:35 +00:00
|
|
|
Transform4x4f carouselTrans = trans;
|
|
|
|
carouselTrans.translate(Vector3f(mCarousel.pos.x(), mCarousel.pos.y(), 0.0));
|
|
|
|
carouselTrans.translate(Vector3f(mCarousel.origin.x() * mCarousel.size.x() * -1, mCarousel.origin.y() * mCarousel.size.y() * -1, 0.0f));
|
2014-06-25 16:29:58 +00:00
|
|
|
|
2017-10-28 20:24:35 +00:00
|
|
|
Vector2f clipPos(carouselTrans.translation().x(), carouselTrans.translation().y());
|
|
|
|
Renderer::pushClipRect(Vector2i((int)clipPos.x(), (int)clipPos.y()), Vector2i((int)mCarousel.size.x(), (int)mCarousel.size.y()));
|
2017-03-13 21:11:07 +00:00
|
|
|
|
2017-08-15 02:34:34 +00:00
|
|
|
Renderer::setMatrix(carouselTrans);
|
|
|
|
Renderer::drawRect(0.0, 0.0, mCarousel.size.x(), mCarousel.size.y(), mCarousel.color);
|
2017-03-13 21:11:07 +00:00
|
|
|
|
|
|
|
// draw logos
|
2017-10-28 20:24:35 +00:00
|
|
|
Vector2f logoSpacing(0.0, 0.0); // NB: logoSpacing will include the size of the logo itself as well!
|
2017-03-13 21:11:07 +00:00
|
|
|
float xOff = 0.0;
|
|
|
|
float yOff = 0.0;
|
|
|
|
|
|
|
|
switch (mCarousel.type)
|
|
|
|
{
|
2017-08-15 02:34:34 +00:00
|
|
|
case VERTICAL_WHEEL:
|
2017-10-18 14:19:32 +00:00
|
|
|
yOff = (mCarousel.size.y() - mCarousel.logoSize.y()) / 2.f - (mCamOffset * logoSpacing[1]);
|
2017-08-15 02:34:34 +00:00
|
|
|
if (mCarousel.logoAlignment == ALIGN_LEFT)
|
2017-10-18 14:19:32 +00:00
|
|
|
xOff = mCarousel.logoSize.x() / 10.f;
|
2017-08-15 02:34:34 +00:00
|
|
|
else if (mCarousel.logoAlignment == ALIGN_RIGHT)
|
2017-10-18 14:19:32 +00:00
|
|
|
xOff = mCarousel.size.x() - (mCarousel.logoSize.x() * 1.1f);
|
2017-08-15 02:34:34 +00:00
|
|
|
else
|
2017-10-18 14:19:32 +00:00
|
|
|
xOff = (mCarousel.size.x() - mCarousel.logoSize.x()) / 2.f;
|
2017-08-15 02:34:34 +00:00
|
|
|
break;
|
2017-03-13 21:11:07 +00:00
|
|
|
case VERTICAL:
|
|
|
|
logoSpacing[1] = ((mCarousel.size.y() - (mCarousel.logoSize.y() * mCarousel.maxLogoCount)) / (mCarousel.maxLogoCount)) + mCarousel.logoSize.y();
|
2017-10-18 14:19:32 +00:00
|
|
|
yOff = (mCarousel.size.y() - mCarousel.logoSize.y()) / 2.f - (mCamOffset * logoSpacing[1]);
|
2017-08-15 02:34:34 +00:00
|
|
|
|
|
|
|
if (mCarousel.logoAlignment == ALIGN_LEFT)
|
2017-10-18 14:19:32 +00:00
|
|
|
xOff = mCarousel.logoSize.x() / 10.f;
|
2017-08-15 02:34:34 +00:00
|
|
|
else if (mCarousel.logoAlignment == ALIGN_RIGHT)
|
2017-10-18 14:19:32 +00:00
|
|
|
xOff = mCarousel.size.x() - (mCarousel.logoSize.x() * 1.1f);
|
2017-08-15 02:34:34 +00:00
|
|
|
else
|
|
|
|
xOff = (mCarousel.size.x() - mCarousel.logoSize.x()) / 2;
|
2017-03-13 21:11:07 +00:00
|
|
|
break;
|
|
|
|
case HORIZONTAL:
|
|
|
|
default:
|
|
|
|
logoSpacing[0] = ((mCarousel.size.x() - (mCarousel.logoSize.x() * mCarousel.maxLogoCount)) / (mCarousel.maxLogoCount)) + mCarousel.logoSize.x();
|
2017-10-18 14:19:32 +00:00
|
|
|
xOff = (mCarousel.size.x() - mCarousel.logoSize.x()) / 2.f - (mCamOffset * logoSpacing[0]);
|
2017-08-15 02:34:34 +00:00
|
|
|
|
|
|
|
if (mCarousel.logoAlignment == ALIGN_TOP)
|
2017-10-18 14:19:32 +00:00
|
|
|
yOff = mCarousel.logoSize.y() / 10.f;
|
2017-08-15 02:34:34 +00:00
|
|
|
else if (mCarousel.logoAlignment == ALIGN_BOTTOM)
|
2017-10-18 14:19:32 +00:00
|
|
|
yOff = mCarousel.size.y() - (mCarousel.logoSize.y() * 1.1f);
|
2017-08-15 02:34:34 +00:00
|
|
|
else
|
2017-10-18 14:19:32 +00:00
|
|
|
yOff = (mCarousel.size.y() - mCarousel.logoSize.y()) / 2.f;
|
2017-03-13 21:11:07 +00:00
|
|
|
break;
|
|
|
|
}
|
2014-06-25 16:29:58 +00:00
|
|
|
|
2017-03-13 21:11:07 +00:00
|
|
|
int center = (int)(mCamOffset);
|
2017-11-13 22:16:38 +00:00
|
|
|
int logoCount = Math::min(mCarousel.maxLogoCount, (int)mEntries.size());
|
2017-03-13 21:11:07 +00:00
|
|
|
|
2017-05-27 07:40:18 +00:00
|
|
|
// Adding texture loading buffers depending on scrolling speed and status
|
|
|
|
int bufferIndex = getScrollingVelocity() + 1;
|
2017-08-24 01:49:47 +00:00
|
|
|
int bufferLeft = logoBuffersLeft[bufferIndex];
|
|
|
|
int bufferRight = logoBuffersRight[bufferIndex];
|
|
|
|
if (logoCount == 1)
|
|
|
|
{
|
|
|
|
bufferLeft = 0;
|
|
|
|
bufferRight = 0;
|
|
|
|
}
|
2017-05-27 07:40:18 +00:00
|
|
|
|
2017-08-24 01:49:47 +00:00
|
|
|
for (int i = center - logoCount / 2 + bufferLeft; i <= center + logoCount / 2 + bufferRight; i++)
|
2014-06-25 16:29:58 +00:00
|
|
|
{
|
|
|
|
int index = i;
|
2017-03-13 21:11:07 +00:00
|
|
|
while (index < 0)
|
2017-11-17 14:58:52 +00:00
|
|
|
index += (int)mEntries.size();
|
2017-03-13 21:11:07 +00:00
|
|
|
while (index >= (int)mEntries.size())
|
2017-11-17 14:58:52 +00:00
|
|
|
index -= (int)mEntries.size();
|
2014-06-25 16:29:58 +00:00
|
|
|
|
2017-10-28 20:24:35 +00:00
|
|
|
Transform4x4f logoTrans = carouselTrans;
|
|
|
|
logoTrans.translate(Vector3f(i * logoSpacing[0] + xOff, i * logoSpacing[1] + yOff, 0));
|
2014-06-25 16:29:58 +00:00
|
|
|
|
2017-08-15 02:34:34 +00:00
|
|
|
float distance = i - mCamOffset;
|
|
|
|
|
2017-10-18 14:19:32 +00:00
|
|
|
float scale = 1.0f + ((mCarousel.logoScale - 1.0f) * (1.0f - fabs(distance)));
|
2017-11-13 22:16:38 +00:00
|
|
|
scale = Math::min(mCarousel.logoScale, Math::max(1.0f, scale));
|
2017-08-15 02:34:34 +00:00
|
|
|
scale /= mCarousel.logoScale;
|
|
|
|
|
2017-11-17 14:58:52 +00:00
|
|
|
int opacity = (int)Math::round(0x80 + ((0xFF - 0x80) * (1.0f - fabs(distance))));
|
2017-11-13 22:16:38 +00:00
|
|
|
opacity = Math::max((int) 0x80, opacity);
|
2017-08-15 02:34:34 +00:00
|
|
|
|
|
|
|
const std::shared_ptr<GuiComponent> &comp = mEntries.at(index).data.logo;
|
|
|
|
if (mCarousel.type == VERTICAL_WHEEL) {
|
|
|
|
comp->setRotationDegrees(mCarousel.logoRotation * distance);
|
|
|
|
comp->setRotationOrigin(mCarousel.logoRotationOrigin);
|
2014-06-25 16:29:58 +00:00
|
|
|
}
|
2017-08-15 02:34:34 +00:00
|
|
|
comp->setScale(scale);
|
2017-11-17 14:58:52 +00:00
|
|
|
comp->setOpacity((unsigned char)opacity);
|
2017-08-15 02:34:34 +00:00
|
|
|
comp->render(logoTrans);
|
2014-06-25 16:29:58 +00:00
|
|
|
}
|
2017-03-13 21:11:07 +00:00
|
|
|
Renderer::popClipRect();
|
|
|
|
}
|
2014-06-25 16:29:58 +00:00
|
|
|
|
2017-10-28 20:24:35 +00:00
|
|
|
void SystemView::renderInfoBar(const Transform4x4f& trans)
|
2017-03-13 21:11:07 +00:00
|
|
|
{
|
2014-06-25 16:29:58 +00:00
|
|
|
Renderer::setMatrix(trans);
|
|
|
|
mSystemInfo.render(trans);
|
|
|
|
}
|
|
|
|
|
2017-03-13 21:11:07 +00:00
|
|
|
// Draw background extras
|
2017-10-28 20:24:35 +00:00
|
|
|
void SystemView::renderExtras(const Transform4x4f& trans, float lower, float upper)
|
2014-06-25 16:29:58 +00:00
|
|
|
{
|
2017-03-13 21:11:07 +00:00
|
|
|
int extrasCenter = (int)mExtrasCamOffset;
|
2017-05-27 07:40:18 +00:00
|
|
|
|
2017-05-17 12:01:15 +00:00
|
|
|
// Adding texture loading buffers depending on scrolling speed and status
|
|
|
|
int bufferIndex = getScrollingVelocity() + 1;
|
2017-05-19 03:04:41 +00:00
|
|
|
|
2017-10-28 20:24:35 +00:00
|
|
|
Renderer::pushClipRect(Vector2i::Zero(), Vector2i((int)mSize.x(), (int)mSize.y()));
|
2017-05-19 03:04:41 +00:00
|
|
|
|
2017-05-17 12:01:15 +00:00
|
|
|
for (int i = extrasCenter + logoBuffersLeft[bufferIndex]; i <= extrasCenter + logoBuffersRight[bufferIndex]; i++)
|
2017-03-13 21:11:07 +00:00
|
|
|
{
|
|
|
|
int index = i;
|
|
|
|
while (index < 0)
|
2017-11-17 14:58:52 +00:00
|
|
|
index += (int)mEntries.size();
|
2017-03-13 21:11:07 +00:00
|
|
|
while (index >= (int)mEntries.size())
|
2017-11-17 14:58:52 +00:00
|
|
|
index -= (int)mEntries.size();
|
2017-03-13 21:11:07 +00:00
|
|
|
|
2017-08-15 02:34:34 +00:00
|
|
|
//Only render selected system when not showing
|
|
|
|
if (mShowing || index == mCursor)
|
2017-04-22 14:15:16 +00:00
|
|
|
{
|
2017-10-28 20:24:35 +00:00
|
|
|
Transform4x4f extrasTrans = trans;
|
2017-08-15 02:34:34 +00:00
|
|
|
if (mCarousel.type == HORIZONTAL)
|
2017-10-28 20:24:35 +00:00
|
|
|
extrasTrans.translate(Vector3f((i - mExtrasCamOffset) * mSize.x(), 0, 0));
|
2017-08-15 02:34:34 +00:00
|
|
|
else
|
2017-10-28 20:24:35 +00:00
|
|
|
extrasTrans.translate(Vector3f(0, (i - mExtrasCamOffset) * mSize.y(), 0));
|
2017-08-15 02:34:34 +00:00
|
|
|
|
2017-10-28 20:24:35 +00:00
|
|
|
Renderer::pushClipRect(Vector2i((int)extrasTrans.translation()[0], (int)extrasTrans.translation()[1]),
|
|
|
|
Vector2i((int)mSize.x(), (int)mSize.y()));
|
2017-08-15 02:34:34 +00:00
|
|
|
SystemViewData data = mEntries.at(index).data;
|
|
|
|
for (unsigned int j = 0; j < data.backgroundExtras.size(); j++) {
|
|
|
|
GuiComponent *extra = data.backgroundExtras[j];
|
|
|
|
if (extra->getZIndex() >= lower && extra->getZIndex() < upper) {
|
|
|
|
extra->render(extrasTrans);
|
|
|
|
}
|
2017-04-22 14:15:16 +00:00
|
|
|
}
|
2017-08-15 02:34:34 +00:00
|
|
|
Renderer::popClipRect();
|
2017-04-22 14:15:16 +00:00
|
|
|
}
|
2017-03-13 21:11:07 +00:00
|
|
|
}
|
2017-05-19 03:04:41 +00:00
|
|
|
Renderer::popClipRect();
|
2017-04-22 14:15:16 +00:00
|
|
|
}
|
2017-03-13 21:11:07 +00:00
|
|
|
|
2017-10-28 20:24:35 +00:00
|
|
|
void SystemView::renderFade(const Transform4x4f& trans)
|
2017-04-22 14:15:16 +00:00
|
|
|
{
|
2017-03-13 21:11:07 +00:00
|
|
|
// fade extras if necessary
|
|
|
|
if (mExtrasFadeOpacity)
|
|
|
|
{
|
|
|
|
Renderer::setMatrix(trans);
|
|
|
|
Renderer::drawRect(0.0f, 0.0f, mSize.x(), mSize.y(), 0x00000000 | (unsigned char)(mExtrasFadeOpacity * 255));
|
|
|
|
}
|
2014-06-25 16:29:58 +00:00
|
|
|
}
|
|
|
|
|
2017-03-13 21:11:07 +00:00
|
|
|
// Populate the system carousel with the legacy values
|
|
|
|
void SystemView::getDefaultElements(void)
|
2014-06-25 16:29:58 +00:00
|
|
|
{
|
2017-03-13 21:11:07 +00:00
|
|
|
// Carousel
|
|
|
|
mCarousel.type = HORIZONTAL;
|
2017-08-15 02:34:34 +00:00
|
|
|
mCarousel.logoAlignment = ALIGN_CENTER;
|
2017-03-13 21:11:07 +00:00
|
|
|
mCarousel.size.x() = mSize.x();
|
|
|
|
mCarousel.size.y() = 0.2325f * mSize.y();
|
|
|
|
mCarousel.pos.x() = 0.0f;
|
|
|
|
mCarousel.pos.y() = 0.5f * (mSize.y() - mCarousel.size.y());
|
2017-08-15 02:34:34 +00:00
|
|
|
mCarousel.origin.x() = 0.0f;
|
|
|
|
mCarousel.origin.y() = 0.0f;
|
2017-03-13 21:11:07 +00:00
|
|
|
mCarousel.color = 0xFFFFFFD8;
|
2017-05-04 17:49:35 +00:00
|
|
|
mCarousel.logoScale = 1.2f;
|
2017-08-15 02:34:34 +00:00
|
|
|
mCarousel.logoRotation = 7.5;
|
|
|
|
mCarousel.logoRotationOrigin.x() = -5;
|
|
|
|
mCarousel.logoRotationOrigin.y() = 0.5;
|
2017-03-13 21:11:07 +00:00
|
|
|
mCarousel.logoSize.x() = 0.25f * mSize.x();
|
|
|
|
mCarousel.logoSize.y() = 0.155f * mSize.y();
|
|
|
|
mCarousel.maxLogoCount = 3;
|
2017-04-22 14:15:16 +00:00
|
|
|
mCarousel.zIndex = 40;
|
2017-03-13 21:11:07 +00:00
|
|
|
|
|
|
|
// System Info Bar
|
|
|
|
mSystemInfo.setSize(mSize.x(), mSystemInfo.getFont()->getLetterHeight()*2.2f);
|
2017-05-01 02:54:27 +00:00
|
|
|
mSystemInfo.setPosition(0, (mCarousel.pos.y() + mCarousel.size.y() - 0.2f));
|
2017-03-13 21:11:07 +00:00
|
|
|
mSystemInfo.setBackgroundColor(0xDDDDDDD8);
|
2017-05-01 02:54:27 +00:00
|
|
|
mSystemInfo.setRenderBackground(true);
|
2017-03-13 21:11:07 +00:00
|
|
|
mSystemInfo.setFont(Font::get((int)(0.035f * mSize.y()), Font::getDefaultPath()));
|
|
|
|
mSystemInfo.setColor(0x000000FF);
|
2017-04-22 14:15:16 +00:00
|
|
|
mSystemInfo.setZIndex(50);
|
|
|
|
mSystemInfo.setDefaultZIndex(50);
|
2017-03-13 21:11:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SystemView::getCarouselFromTheme(const ThemeData::ThemeElement* elem)
|
|
|
|
{
|
|
|
|
if (elem->has("type"))
|
2017-08-15 02:34:34 +00:00
|
|
|
{
|
|
|
|
if (!(elem->get<std::string>("type").compare("vertical")))
|
|
|
|
mCarousel.type = VERTICAL;
|
|
|
|
else if (!(elem->get<std::string>("type").compare("vertical_wheel")))
|
|
|
|
mCarousel.type = VERTICAL_WHEEL;
|
|
|
|
else
|
|
|
|
mCarousel.type = HORIZONTAL;
|
|
|
|
}
|
2017-03-13 21:11:07 +00:00
|
|
|
if (elem->has("size"))
|
2017-10-28 20:24:35 +00:00
|
|
|
mCarousel.size = elem->get<Vector2f>("size") * mSize;
|
2017-03-13 21:11:07 +00:00
|
|
|
if (elem->has("pos"))
|
2017-10-28 20:24:35 +00:00
|
|
|
mCarousel.pos = elem->get<Vector2f>("pos") * mSize;
|
2017-08-15 02:34:34 +00:00
|
|
|
if (elem->has("origin"))
|
2017-10-28 20:24:35 +00:00
|
|
|
mCarousel.origin = elem->get<Vector2f>("origin");
|
2017-03-13 21:11:07 +00:00
|
|
|
if (elem->has("color"))
|
|
|
|
mCarousel.color = elem->get<unsigned int>("color");
|
|
|
|
if (elem->has("logoScale"))
|
|
|
|
mCarousel.logoScale = elem->get<float>("logoScale");
|
|
|
|
if (elem->has("logoSize"))
|
2017-10-28 20:24:35 +00:00
|
|
|
mCarousel.logoSize = elem->get<Vector2f>("logoSize") * mSize;
|
2017-03-13 21:11:07 +00:00
|
|
|
if (elem->has("maxLogoCount"))
|
2017-11-17 14:58:52 +00:00
|
|
|
mCarousel.maxLogoCount = (int)Math::round(elem->get<float>("maxLogoCount"));
|
2017-04-22 14:15:16 +00:00
|
|
|
if (elem->has("zIndex"))
|
|
|
|
mCarousel.zIndex = elem->get<float>("zIndex");
|
2017-08-15 02:34:34 +00:00
|
|
|
if (elem->has("logoRotation"))
|
|
|
|
mCarousel.logoRotation = elem->get<float>("logoRotation");
|
|
|
|
if (elem->has("logoRotationOrigin"))
|
2017-10-28 20:24:35 +00:00
|
|
|
mCarousel.logoRotationOrigin = elem->get<Vector2f>("logoRotationOrigin");
|
2017-08-15 02:34:34 +00:00
|
|
|
if (elem->has("logoAlignment"))
|
|
|
|
{
|
|
|
|
if (!(elem->get<std::string>("logoAlignment").compare("left")))
|
|
|
|
mCarousel.logoAlignment = ALIGN_LEFT;
|
|
|
|
else if (!(elem->get<std::string>("logoAlignment").compare("right")))
|
|
|
|
mCarousel.logoAlignment = ALIGN_RIGHT;
|
|
|
|
else if (!(elem->get<std::string>("logoAlignment").compare("top")))
|
|
|
|
mCarousel.logoAlignment = ALIGN_TOP;
|
|
|
|
else if (!(elem->get<std::string>("logoAlignment").compare("bottom")))
|
|
|
|
mCarousel.logoAlignment = ALIGN_BOTTOM;
|
|
|
|
else
|
|
|
|
mCarousel.logoAlignment = ALIGN_CENTER;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SystemView::onShow()
|
|
|
|
{
|
|
|
|
mShowing = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SystemView::onHide()
|
|
|
|
{
|
|
|
|
mShowing = false;
|
2014-06-25 16:29:58 +00:00
|
|
|
}
|