mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-25 15:45:38 +00:00
Merge pull request #101 from zigurana/SystemCaroussel
System carousel theming
This commit is contained in:
commit
bf1c0b841b
|
@ -47,7 +47,11 @@ endif()
|
|||
find_package(Freetype REQUIRED)
|
||||
find_package(FreeImage REQUIRED)
|
||||
find_package(SDL2 REQUIRED)
|
||||
if(MSVC)
|
||||
find_package(Boost REQUIRED COMPONENTS system date_time locale)
|
||||
else()
|
||||
find_package(Boost REQUIRED COMPONENTS system filesystem date_time locale)
|
||||
endif()
|
||||
find_package(Eigen3 REQUIRED)
|
||||
find_package(CURL REQUIRED)
|
||||
find_package(VLC REQUIRED)
|
||||
|
@ -81,9 +85,14 @@ if(CMAKE_COMPILER_IS_GNUCXX)
|
|||
endif()
|
||||
|
||||
#set up compiler flags for GCC
|
||||
if (CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wno-attributes -O0") #support C++11 for std::, optimize
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -O0")
|
||||
else()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wno-attributes -O3") #support C++11 for std::, optimize
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -O3") #-s = strip binary
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(${GLSystem} MATCHES "Desktop OpenGL")
|
||||
add_definitions(-DUSE_OPENGL_DESKTOP)
|
||||
|
|
23
THEMES.md
23
THEMES.md
|
@ -400,8 +400,12 @@ Reference
|
|||
#### system
|
||||
* `helpsystem name="help"` - ALL
|
||||
- The help system style for this view.
|
||||
* `carousel name="systemcarousel"` -ALL
|
||||
- The system logo carousel
|
||||
* `image name="logo"` - PATH
|
||||
- A logo image, to be displayed in the system logo carousel.
|
||||
* `text name="systemInfo"` - ALL
|
||||
- Displays details of the system currently selected in the carousel.
|
||||
* You can use extra elements (elements with `extra="true"`) to add your own backgrounds, etc. They will be displayed behind the carousel, and scroll relative to the carousel.
|
||||
|
||||
|
||||
|
@ -471,6 +475,7 @@ Can be created as an extra.
|
|||
- `w h` - works like a "text box." If `h` is non-zero and `h` <= `fontSize` (implying it should be a single line of text), text that goes beyond `w` will be truncated with an elipses (...).
|
||||
* `text` - type: STRING.
|
||||
* `color` - type: COLOR.
|
||||
* `backgroundColor` - type: COLOR;
|
||||
* `fontPath` - type: PATH.
|
||||
- Path to a truetype font (.ttf).
|
||||
* `fontSize` - type: FLOAT.
|
||||
|
@ -544,6 +549,24 @@ EmulationStation borrows the concept of "nine patches" from Android (or "9-Slice
|
|||
* `fontPath` - type: PATH.
|
||||
* `fontSize` - type: FLOAT.
|
||||
|
||||
#### carousel
|
||||
|
||||
* `type` - type: STRING.
|
||||
* Accepted values are "HORIZONTAL" or "VERTICAL". Sets the scoll direction of the carousel.
|
||||
* Default is "HORIZONTAL".
|
||||
* `size` - type: NORMALIZED_PAIR. Default is "1 0.2325"
|
||||
* `pos` - type: NORMALIZED_PAIR. Default is "0 0.38375".
|
||||
* `color` - type: COLOR.
|
||||
* Controls the color of the carousel background.
|
||||
* Default is FFFFFFD8
|
||||
* `logoSize` - type: NORMALIZED_PAIR. Default is "0.25 0.155"
|
||||
* `logoScale` - type: FLOAT.
|
||||
* Selected logo is increased in size by this scale
|
||||
* Default is 1.5
|
||||
* `maxLogoCount` - type: FLOAT.
|
||||
* Sets the number of logos to display in the carousel.
|
||||
* Default is 3
|
||||
|
||||
The help system is a special element that displays a context-sensitive list of actions the user can take at any time. You should try and keep the position constant throughout every screen. Keep in mind the "default" settings (including position) are used whenever the user opens a menu.
|
||||
|
||||
[*Check out the "official" themes for some more examples!*](http://aloshi.com/emulationstation#themes)
|
||||
|
|
|
@ -9,22 +9,15 @@
|
|||
#include "Settings.h"
|
||||
#include "Util.h"
|
||||
|
||||
#define SELECTED_SCALE 1.5f
|
||||
#define LOGO_PADDING ((logoSize().x() * (SELECTED_SCALE - 1)/2) + (mSize.x() * 0.06f))
|
||||
#define BAND_HEIGHT (logoSize().y() * SELECTED_SCALE)
|
||||
|
||||
SystemView::SystemView(Window* window) : IList<SystemViewData, SystemData*>(window, LIST_SCROLL_STYLE_SLOW, LIST_ALWAYS_LOOP),
|
||||
mSystemInfo(window, "SYSTEM INFO", Font::get(FONT_SIZE_SMALL), 0x33333300, ALIGN_CENTER)
|
||||
mViewNeedsReload(true),
|
||||
mSystemInfo(window, "SYSTEM INFO", Font::get(FONT_SIZE_SMALL), 0x33333300, ALIGN_CENTER)
|
||||
{
|
||||
mCamOffset = 0;
|
||||
mExtrasCamOffset = 0;
|
||||
mExtrasFadeOpacity = 0.0f;
|
||||
|
||||
setSize((float)Renderer::getScreenWidth(), (float)Renderer::getScreenHeight());
|
||||
|
||||
mSystemInfo.setSize(mSize.x(), mSystemInfo.getSize().y() * 1.333f);
|
||||
mSystemInfo.setPosition(0, (mSize.y() + BAND_HEIGHT) / 2);
|
||||
|
||||
populate();
|
||||
}
|
||||
|
||||
|
@ -36,6 +29,9 @@ void SystemView::populate()
|
|||
{
|
||||
const std::shared_ptr<ThemeData>& theme = (*it)->getTheme();
|
||||
|
||||
if(mViewNeedsReload)
|
||||
getViewElements(theme);
|
||||
|
||||
Entry e;
|
||||
e.name = (*it)->getName();
|
||||
e.object = *it;
|
||||
|
@ -43,18 +39,20 @@ void SystemView::populate()
|
|||
// make logo
|
||||
if(theme->getElement("system", "logo", "image"))
|
||||
{
|
||||
ImageComponent* logo = new ImageComponent(mWindow, false, false);
|
||||
logo->setMaxSize(Eigen::Vector2f(logoSize().x(), logoSize().y()));
|
||||
ImageComponent* logo = new ImageComponent(mWindow);
|
||||
logo->setMaxSize(Eigen::Vector2f(mCarousel.logoSize.x(), mCarousel.logoSize.y()));
|
||||
logo->applyTheme((*it)->getTheme(), "system", "logo", ThemeFlags::PATH);
|
||||
logo->setPosition((logoSize().x() - logo->getSize().x()) / 2, (logoSize().y() - logo->getSize().y()) / 2); // center
|
||||
logo->setPosition((mCarousel.logoSize.x() - logo->getSize().x()) / 2,
|
||||
(mCarousel.logoSize.y() - logo->getSize().y()) / 2); // center
|
||||
e.data.logo = std::shared_ptr<GuiComponent>(logo);
|
||||
|
||||
ImageComponent* logoSelected = new ImageComponent(mWindow, false, false);
|
||||
logoSelected->setMaxSize(Eigen::Vector2f(logoSize().x() * SELECTED_SCALE, logoSize().y() * SELECTED_SCALE * 0.70f));
|
||||
logoSelected->applyTheme((*it)->getTheme(), "system", "logo", ThemeFlags::PATH);
|
||||
logoSelected->setPosition((logoSize().x() - logoSelected->getSize().x()) / 2,
|
||||
(logoSize().y() - logoSelected->getSize().y()) / 2); // center
|
||||
ImageComponent* logoSelected = new ImageComponent(mWindow);
|
||||
logoSelected->setMaxSize(Eigen::Vector2f(mCarousel.logoSize.x() * mCarousel.logoScale, mCarousel.logoSize.y() * mCarousel.logoScale));
|
||||
logoSelected->applyTheme((*it)->getTheme(), "system", "logo", ThemeFlags::PATH | ThemeFlags::COLOR);
|
||||
logoSelected->setPosition((mCarousel.logoSize.x() - logoSelected->getSize().x()) / 2,
|
||||
(mCarousel.logoSize.y() - logoSelected->getSize().y()) / 2); // center
|
||||
e.data.logoSelected = std::shared_ptr<GuiComponent>(logoSelected);
|
||||
|
||||
}else{
|
||||
// no logo in theme; use text
|
||||
TextComponent* text = new TextComponent(mWindow,
|
||||
|
@ -62,15 +60,15 @@ void SystemView::populate()
|
|||
Font::get(FONT_SIZE_LARGE),
|
||||
0x000000FF,
|
||||
ALIGN_CENTER);
|
||||
text->setSize(logoSize());
|
||||
text->setSize(mCarousel.logoSize);
|
||||
e.data.logo = std::shared_ptr<GuiComponent>(text);
|
||||
|
||||
TextComponent* textSelected = new TextComponent(mWindow,
|
||||
(*it)->getName(),
|
||||
Font::get((int)(FONT_SIZE_LARGE * SELECTED_SCALE)),
|
||||
Font::get((int)(FONT_SIZE_LARGE * 1.5)),
|
||||
0x000000FF,
|
||||
ALIGN_CENTER);
|
||||
textSelected->setSize(logoSize());
|
||||
textSelected->setSize(mCarousel.logoSize);
|
||||
e.data.logoSelected = std::shared_ptr<GuiComponent>(textSelected);
|
||||
}
|
||||
|
||||
|
@ -96,26 +94,40 @@ bool SystemView::input(InputConfig* config, Input input)
|
|||
{
|
||||
if(config->getDeviceId() == DEVICE_KEYBOARD && input.value && input.id == SDLK_r && SDL_GetModState() & KMOD_LCTRL && Settings::getInstance()->getBool("Debug"))
|
||||
{
|
||||
LOG(LogInfo) << " Reloading SystemList view";
|
||||
LOG(LogInfo) << " Reloading all";
|
||||
ViewController::get()->reloadAll();
|
||||
return true;
|
||||
}
|
||||
|
||||
// reload themes
|
||||
for(auto it = mEntries.begin(); it != mEntries.end(); it++)
|
||||
it->object->loadTheme();
|
||||
switch (mCarousel.type)
|
||||
{
|
||||
case VERTICAL:
|
||||
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;
|
||||
}
|
||||
|
||||
populate();
|
||||
updateHelpPrompts();
|
||||
return true;
|
||||
}
|
||||
if(config->isMappedTo("left", input))
|
||||
{
|
||||
listInput(-1);
|
||||
return true;
|
||||
}
|
||||
if(config->isMappedTo("right", input))
|
||||
{
|
||||
listInput(1);
|
||||
return true;
|
||||
}
|
||||
if(config->isMappedTo("a", input))
|
||||
{
|
||||
stopScrolling();
|
||||
|
@ -123,7 +135,10 @@ bool SystemView::input(InputConfig* config, Input input)
|
|||
return true;
|
||||
}
|
||||
}else{
|
||||
if(config->isMappedTo("left", input) || config->isMappedTo("right", input))
|
||||
if(config->isMappedTo("left", input) ||
|
||||
config->isMappedTo("right", input) ||
|
||||
config->isMappedTo("up", input) ||
|
||||
config->isMappedTo("down", input))
|
||||
listInput(0);
|
||||
}
|
||||
|
||||
|
@ -254,28 +269,136 @@ void SystemView::onCursorChanged(const CursorState& state)
|
|||
void SystemView::render(const Eigen::Affine3f& parentTrans)
|
||||
{
|
||||
if(size() == 0)
|
||||
return;
|
||||
|
||||
Eigen::Affine3f trans = getTransform() * parentTrans;
|
||||
return; // nothing to render
|
||||
|
||||
// draw the list elements (titles, backgrounds, logos)
|
||||
const float logoSizeX = logoSize().x() + LOGO_PADDING;
|
||||
Eigen::Affine3f trans = getTransform() * parentTrans;
|
||||
|
||||
int logoCount = (int)(mSize.x() / logoSizeX) + 2; // how many logos we need to draw
|
||||
renderExtras(trans);
|
||||
renderCarousel(trans);
|
||||
renderInfoBar(trans);
|
||||
}
|
||||
|
||||
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"));
|
||||
return prompts;
|
||||
}
|
||||
|
||||
HelpStyle SystemView::getHelpStyle()
|
||||
{
|
||||
HelpStyle style;
|
||||
style.applyTheme(mEntries.at(mCursor).object->getTheme(), "system");
|
||||
return style;
|
||||
}
|
||||
|
||||
void SystemView::onThemeChanged(const std::shared_ptr<ThemeData>& theme)
|
||||
{
|
||||
LOG(LogDebug) << "SystemView::onThemeChanged()";
|
||||
mViewNeedsReload = true;
|
||||
populate();
|
||||
}
|
||||
|
||||
// Get the ThemeElements that make up the SystemView.
|
||||
void SystemView::getViewElements(const std::shared_ptr<ThemeData>& theme)
|
||||
{
|
||||
LOG(LogDebug) << "SystemView::getViewElements()";
|
||||
|
||||
getDefaultElements();
|
||||
|
||||
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
|
||||
void SystemView::renderCarousel(const Eigen::Affine3f& trans)
|
||||
{
|
||||
Eigen::Vector2i clipPos((int)mCarousel.pos.x(), (int)mCarousel.pos.y());
|
||||
Eigen::Vector2i clipSize((int)mCarousel.size.x(), (int)mCarousel.size.y());
|
||||
|
||||
Renderer::pushClipRect(clipPos, clipSize);
|
||||
|
||||
// background box behind logos
|
||||
Renderer::setMatrix(trans);
|
||||
Renderer::drawRect(mCarousel.pos.x(), mCarousel.pos.y(), mCarousel.size.x(), mCarousel.size.y(), mCarousel.color);
|
||||
|
||||
// draw logos
|
||||
Eigen::Vector2f logoSpacing(0.0, 0.0); // NB: logoSpacing will include the size of the logo itself as well!
|
||||
float xOff = 0.0;
|
||||
float yOff = 0.0;
|
||||
|
||||
switch (mCarousel.type)
|
||||
{
|
||||
case VERTICAL:
|
||||
logoSpacing[1] = ((mCarousel.size.y() - (mCarousel.logoSize.y() * mCarousel.maxLogoCount)) / (mCarousel.maxLogoCount)) + mCarousel.logoSize.y();
|
||||
xOff = mCarousel.pos.x() + (mCarousel.size.x() / 2) - (mCarousel.logoSize.x() / 2);
|
||||
yOff = mCarousel.pos.y() + (mCarousel.size.y() - mCarousel.logoSize.y()) / 2 - (mCamOffset * logoSpacing[1]);
|
||||
break;
|
||||
case HORIZONTAL:
|
||||
default:
|
||||
logoSpacing[0] = ((mCarousel.size.x() - (mCarousel.logoSize.x() * mCarousel.maxLogoCount)) / (mCarousel.maxLogoCount)) + mCarousel.logoSize.x();
|
||||
xOff = mCarousel.pos.x() + (mCarousel.size.x() - mCarousel.logoSize.x()) / 2 - (mCamOffset * logoSpacing[0]);
|
||||
yOff = mCarousel.pos.y() + (mCarousel.size.y() / 2) - (mCarousel.logoSize.y() / 2);
|
||||
break;
|
||||
}
|
||||
|
||||
Eigen::Affine3f logoTrans = trans;
|
||||
int center = (int)(mCamOffset);
|
||||
int logoCount = std::min(mCarousel.maxLogoCount, (int)mEntries.size()) + 2;
|
||||
|
||||
if(mEntries.size() == 1)
|
||||
logoCount = 1;
|
||||
|
||||
// draw background extras
|
||||
Eigen::Affine3f extrasTrans = trans;
|
||||
int extrasCenter = (int)mExtrasCamOffset;
|
||||
for(int i = extrasCenter - 1; i < extrasCenter + 2; i++)
|
||||
for (int i = center - logoCount / 2; i < center + logoCount / 2 + 1; i++)
|
||||
{
|
||||
int index = i;
|
||||
while(index < 0)
|
||||
while (index < 0)
|
||||
index += mEntries.size();
|
||||
while(index >= (int)mEntries.size())
|
||||
while (index >= (int)mEntries.size())
|
||||
index -= mEntries.size();
|
||||
|
||||
logoTrans.translation() = trans.translation() + Eigen::Vector3f(i * logoSpacing[0] + xOff, i * logoSpacing [1] + yOff, 0);
|
||||
|
||||
if (index == mCursor) //Selected System
|
||||
{
|
||||
const std::shared_ptr<GuiComponent>& comp = mEntries.at(index).data.logoSelected;
|
||||
comp->setOpacity(0xFF);
|
||||
comp->render(logoTrans);
|
||||
}
|
||||
else { // not selected systems
|
||||
const std::shared_ptr<GuiComponent>& comp = mEntries.at(index).data.logo;
|
||||
comp->setOpacity(0x80);
|
||||
comp->render(logoTrans);
|
||||
}
|
||||
}
|
||||
Renderer::popClipRect();
|
||||
}
|
||||
|
||||
void SystemView::renderInfoBar(const Eigen::Affine3f& trans)
|
||||
{
|
||||
Renderer::setMatrix(trans);
|
||||
mSystemInfo.render(trans);
|
||||
}
|
||||
|
||||
// Draw background extras
|
||||
void SystemView::renderExtras(const Eigen::Affine3f& trans)
|
||||
{
|
||||
Eigen::Affine3f extrasTrans = trans;
|
||||
int extrasCenter = (int)mExtrasCamOffset;
|
||||
for (int i = extrasCenter - 1; i < extrasCenter + 2; i++)
|
||||
{
|
||||
int index = i;
|
||||
while (index < 0)
|
||||
index += mEntries.size();
|
||||
while (index >= (int)mEntries.size())
|
||||
index -= mEntries.size();
|
||||
|
||||
extrasTrans.translation() = trans.translation() + Eigen::Vector3f((i - mExtrasCamOffset) * mSize.x(), 0, 0);
|
||||
|
@ -287,61 +410,50 @@ void SystemView::render(const Eigen::Affine3f& parentTrans)
|
|||
}
|
||||
|
||||
// fade extras if necessary
|
||||
if(mExtrasFadeOpacity)
|
||||
if (mExtrasFadeOpacity)
|
||||
{
|
||||
Renderer::setMatrix(trans);
|
||||
Renderer::drawRect(0.0f, 0.0f, mSize.x(), mSize.y(), 0x00000000 | (unsigned char)(mExtrasFadeOpacity * 255));
|
||||
}
|
||||
|
||||
// draw logos
|
||||
float xOff = (mSize.x() - logoSize().x())/2 - (mCamOffset * logoSizeX);
|
||||
float yOff = (mSize.y() - logoSize().y())/2;
|
||||
|
||||
// background behind the logos
|
||||
Renderer::setMatrix(trans);
|
||||
Renderer::drawRect(0.f, (mSize.y() - BAND_HEIGHT) / 2, mSize.x(), BAND_HEIGHT, 0xFFFFFFD8);
|
||||
|
||||
Eigen::Affine3f logoTrans = trans;
|
||||
for(int i = center - logoCount/2; i < center + logoCount/2 + 1; i++)
|
||||
{
|
||||
int index = i;
|
||||
while(index < 0)
|
||||
index += mEntries.size();
|
||||
while(index >= (int)mEntries.size())
|
||||
index -= mEntries.size();
|
||||
|
||||
logoTrans.translation() = trans.translation() + Eigen::Vector3f(i * logoSizeX + xOff, yOff, 0);
|
||||
|
||||
if(index == mCursor) //scale our selection up
|
||||
{
|
||||
// selected
|
||||
const std::shared_ptr<GuiComponent>& comp = mEntries.at(index).data.logoSelected;
|
||||
comp->setOpacity(0xFF);
|
||||
comp->render(logoTrans);
|
||||
}else{
|
||||
// not selected
|
||||
const std::shared_ptr<GuiComponent>& comp = mEntries.at(index).data.logo;
|
||||
comp->setOpacity(0x80);
|
||||
comp->render(logoTrans);
|
||||
}
|
||||
}
|
||||
|
||||
Renderer::setMatrix(trans);
|
||||
Renderer::drawRect(mSystemInfo.getPosition().x(), mSystemInfo.getPosition().y() - 1, mSize.x(), mSystemInfo.getSize().y(), 0xDDDDDD00 | (unsigned char)(mSystemInfo.getOpacity() / 255.f * 0xD8));
|
||||
mSystemInfo.render(trans);
|
||||
}
|
||||
|
||||
std::vector<HelpPrompt> SystemView::getHelpPrompts()
|
||||
// Populate the system carousel with the legacy values
|
||||
void SystemView::getDefaultElements(void)
|
||||
{
|
||||
std::vector<HelpPrompt> prompts;
|
||||
prompts.push_back(HelpPrompt("left/right", "choose"));
|
||||
prompts.push_back(HelpPrompt("a", "select"));
|
||||
return prompts;
|
||||
// Carousel
|
||||
mCarousel.type = HORIZONTAL;
|
||||
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());
|
||||
mCarousel.color = 0xFFFFFFD8;
|
||||
mCarousel.logoScale = 1.5f;
|
||||
mCarousel.logoSize.x() = 0.25f * mSize.x();
|
||||
mCarousel.logoSize.y() = 0.155f * mSize.y();
|
||||
mCarousel.maxLogoCount = 3;
|
||||
|
||||
// System Info Bar
|
||||
mSystemInfo.setSize(mSize.x(), mSystemInfo.getFont()->getLetterHeight()*2.2f);
|
||||
mSystemInfo.setPosition(0, (mCarousel.pos.y() + mCarousel.size.y()));
|
||||
mSystemInfo.setBackgroundColor(0xDDDDDDD8);
|
||||
mSystemInfo.setFont(Font::get((int)(0.035f * mSize.y()), Font::getDefaultPath()));
|
||||
mSystemInfo.setColor(0x000000FF);
|
||||
}
|
||||
|
||||
HelpStyle SystemView::getHelpStyle()
|
||||
void SystemView::getCarouselFromTheme(const ThemeData::ThemeElement* elem)
|
||||
{
|
||||
HelpStyle style;
|
||||
style.applyTheme(mEntries.at(mCursor).object->getTheme(), "system");
|
||||
return style;
|
||||
if (elem->has("type"))
|
||||
mCarousel.type = !(elem->get<std::string>("type").compare("vertical")) ? VERTICAL : HORIZONTAL;
|
||||
if (elem->has("size"))
|
||||
mCarousel.size = elem->get<Eigen::Vector2f>("size").cwiseProduct(mSize);
|
||||
if (elem->has("pos"))
|
||||
mCarousel.pos = elem->get<Eigen::Vector2f>("pos").cwiseProduct(mSize);
|
||||
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"))
|
||||
mCarousel.logoSize = elem->get<Eigen::Vector2f>("logoSize").cwiseProduct(mSize);
|
||||
if (elem->has("maxLogoCount"))
|
||||
mCarousel.maxLogoCount = std::round(elem->get<float>("maxLogoCount"));
|
||||
}
|
||||
|
|
|
@ -10,6 +10,12 @@
|
|||
class SystemData;
|
||||
class AnimatedImageComponent;
|
||||
|
||||
enum CarouselType : unsigned int
|
||||
{
|
||||
HORIZONTAL = 0,
|
||||
VERTICAL = 1
|
||||
};
|
||||
|
||||
struct SystemViewData
|
||||
{
|
||||
std::shared_ptr<GuiComponent> logo;
|
||||
|
@ -17,6 +23,18 @@ struct SystemViewData
|
|||
std::shared_ptr<ThemeExtras> backgroundExtras;
|
||||
};
|
||||
|
||||
struct SystemViewCarousel
|
||||
{
|
||||
CarouselType type;
|
||||
Eigen::Vector2f pos;
|
||||
Eigen::Vector2f size;
|
||||
float logoScale;
|
||||
Eigen::Vector2f logoSpacing;
|
||||
unsigned int color;
|
||||
int maxLogoCount; // number of logos shown on the carousel
|
||||
Eigen::Vector2f logoSize;
|
||||
};
|
||||
|
||||
class SystemView : public IList<SystemViewData, SystemData*>
|
||||
{
|
||||
public:
|
||||
|
@ -28,6 +46,8 @@ public:
|
|||
void update(int deltaTime) override;
|
||||
void render(const Eigen::Affine3f& parentTrans) override;
|
||||
|
||||
void onThemeChanged(const std::shared_ptr<ThemeData>& theme);
|
||||
|
||||
std::vector<HelpPrompt> getHelpPrompts() override;
|
||||
virtual HelpStyle getHelpStyle() override;
|
||||
|
||||
|
@ -35,14 +55,22 @@ protected:
|
|||
void onCursorChanged(const CursorState& state) override;
|
||||
|
||||
private:
|
||||
inline Eigen::Vector2f logoSize() const { return Eigen::Vector2f(mSize.x() * 0.25f, mSize.y() * 0.155f); }
|
||||
|
||||
void populate();
|
||||
void getViewElements(const std::shared_ptr<ThemeData>& theme);
|
||||
void getDefaultElements(void);
|
||||
void getCarouselFromTheme(const ThemeData::ThemeElement* elem);
|
||||
|
||||
void renderCarousel(const Eigen::Affine3f& parentTrans);
|
||||
void renderExtras(const Eigen::Affine3f& parentTrans);
|
||||
void renderInfoBar(const Eigen::Affine3f& trans);
|
||||
|
||||
SystemViewCarousel mCarousel;
|
||||
TextComponent mSystemInfo;
|
||||
|
||||
// unit is list index
|
||||
float mCamOffset;
|
||||
float mExtrasCamOffset;
|
||||
float mExtrasFadeOpacity;
|
||||
|
||||
bool mViewNeedsReload;
|
||||
};
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include "animations/LaunchAnimation.h"
|
||||
#include "animations/MoveCameraAnimation.h"
|
||||
#include "animations/LambdaAnimation.h"
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL.h>
|
||||
|
||||
ViewController* ViewController::sInstance = NULL;
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ ElementMapType makeMap(const T& mapInit)
|
|||
}
|
||||
|
||||
std::vector<std::string> ThemeData::sSupportedViews = boost::assign::list_of("system")("basic")("detailed")("video");
|
||||
std::vector<std::string> ThemeData::sSupportedFeatures = boost::assign::list_of("video");
|
||||
std::vector<std::string> ThemeData::sSupportedFeatures = boost::assign::list_of("video")("carousel");
|
||||
|
||||
std::map< std::string, ElementMapType > ThemeData::sElementMap = boost::assign::map_list_of
|
||||
("image", makeMap(boost::assign::map_list_of
|
||||
|
@ -39,12 +39,14 @@ std::map< std::string, ElementMapType > ThemeData::sElementMap = boost::assign::
|
|||
("pos", NORMALIZED_PAIR)
|
||||
("size", NORMALIZED_PAIR)
|
||||
("text", STRING)
|
||||
("color", COLOR)
|
||||
("backgroundColor", COLOR)
|
||||
("fontPath", PATH)
|
||||
("fontSize", FLOAT)
|
||||
("color", COLOR)
|
||||
("alignment", STRING)
|
||||
("forceUppercase", BOOLEAN)
|
||||
("lineSpacing", FLOAT)))
|
||||
("lineSpacing", FLOAT)
|
||||
("value", STRING)))
|
||||
("textlist", makeMap(boost::assign::map_list_of
|
||||
("pos", NORMALIZED_PAIR)
|
||||
("size", NORMALIZED_PAIR)
|
||||
|
@ -94,12 +96,20 @@ std::map< std::string, ElementMapType > ThemeData::sElementMap = boost::assign::
|
|||
("default", PATH)
|
||||
("delay", FLOAT)
|
||||
("showSnapshotNoVideo", BOOLEAN)
|
||||
("showSnapshotDelay", BOOLEAN)));
|
||||
("showSnapshotDelay", BOOLEAN)))
|
||||
("carousel", makeMap(boost::assign::map_list_of
|
||||
("type", STRING)
|
||||
("size", NORMALIZED_PAIR)
|
||||
("pos", NORMALIZED_PAIR)
|
||||
("color", COLOR)
|
||||
("logoScale", FLOAT)
|
||||
("logoSize", NORMALIZED_PAIR)
|
||||
("maxLogoCount", FLOAT)));
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
#define MINIMUM_THEME_FORMAT_VERSION 3
|
||||
#define CURRENT_THEME_FORMAT_VERSION 3
|
||||
#define CURRENT_THEME_FORMAT_VERSION 4
|
||||
|
||||
// helper
|
||||
unsigned int getHexColor(const char* str)
|
||||
|
|
|
@ -102,8 +102,13 @@ fs::path resolvePath(const fs::path& path, const fs::path& relativeTo, bool allo
|
|||
|
||||
fs::path removeCommonPathUsingStrings(const fs::path& path, const fs::path& relativeTo, bool& contains)
|
||||
{
|
||||
#ifdef WIN32
|
||||
std::wstring pathStr = path.c_str();
|
||||
std::wstring relativeToStr = relativeTo.c_str();
|
||||
#else
|
||||
std::string pathStr = path.c_str();
|
||||
std::string relativeToStr = relativeTo.c_str();
|
||||
#endif
|
||||
if (pathStr.find_first_of(relativeToStr) == 0) {
|
||||
contains = true;
|
||||
return pathStr.substr(relativeToStr.size() + 1);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "components/TextComponent.h"
|
||||
|
||||
#include "Renderer.h"
|
||||
#include "Log.h"
|
||||
#include "Window.h"
|
||||
|
@ -7,16 +8,17 @@
|
|||
#include "Settings.h"
|
||||
|
||||
TextComponent::TextComponent(Window* window) : GuiComponent(window),
|
||||
mFont(Font::get(FONT_SIZE_MEDIUM)), mUppercase(false), mColor(0x000000FF), mAutoCalcExtent(true, true), mAlignment(ALIGN_LEFT), mLineSpacing(1.5f)
|
||||
mFont(Font::get(FONT_SIZE_MEDIUM)), mUppercase(false), mColor(0x000000FF), mAutoCalcExtent(true, true), mAlignment(ALIGN_LEFT), mLineSpacing(1.5f), mBgColor(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
TextComponent::TextComponent(Window* window, const std::string& text, const std::shared_ptr<Font>& font, unsigned int color, Alignment align,
|
||||
Eigen::Vector3f pos, Eigen::Vector2f size) : GuiComponent(window),
|
||||
mFont(NULL), mUppercase(false), mColor(0x000000FF), mAutoCalcExtent(true, true), mAlignment(align), mLineSpacing(1.5f)
|
||||
Eigen::Vector3f pos, Eigen::Vector2f size, unsigned int bgcolor) : GuiComponent(window),
|
||||
mFont(NULL), mUppercase(false), mColor(0x000000FF), mAutoCalcExtent(true, true), mAlignment(align), mLineSpacing(1.5f), mBgColor(NULL)
|
||||
{
|
||||
setFont(font);
|
||||
setColor(color);
|
||||
setBackgroundColor(bgcolor);
|
||||
setText(text);
|
||||
setPosition(pos);
|
||||
setSize(size);
|
||||
|
@ -34,19 +36,34 @@ void TextComponent::setFont(const std::shared_ptr<Font>& font)
|
|||
onTextChanged();
|
||||
}
|
||||
|
||||
// Set the color of the font/text
|
||||
void TextComponent::setColor(unsigned int color)
|
||||
{
|
||||
mColor = color;
|
||||
|
||||
unsigned char opacity = mColor & 0x000000FF;
|
||||
GuiComponent::setOpacity(opacity);
|
||||
|
||||
mColorOpacity = mColor & 0x000000FF;
|
||||
onColorChanged();
|
||||
}
|
||||
|
||||
// Set the color of the background box
|
||||
void TextComponent::setBackgroundColor(unsigned int color)
|
||||
{
|
||||
mBgColor = color;
|
||||
mBgColorOpacity = mBgColor & 0x000000FF;
|
||||
}
|
||||
|
||||
// Scale the opacity
|
||||
void TextComponent::setOpacity(unsigned char opacity)
|
||||
{
|
||||
mColor = (mColor & 0xFFFFFF00) | opacity;
|
||||
// This method is mostly called to do fading in-out of the Text component element.
|
||||
// Therefore, we assume here that opacity is a fractional value (expressed as an int 0-255),
|
||||
// of the opacity originally set with setColor() or setBackgroundColor().
|
||||
|
||||
unsigned char o = (unsigned char)((float)opacity / 255.f * (float) mColorOpacity);
|
||||
mColor = (mColor & 0xFFFFFF00) | (unsigned char) o;
|
||||
|
||||
unsigned char bgo = (unsigned char)((float)opacity / 255.f * (float)mBgColorOpacity);
|
||||
mBgColor = (mBgColor & 0xFFFFFF00) | (unsigned char)bgo;
|
||||
|
||||
onColorChanged();
|
||||
|
||||
GuiComponent::setOpacity(opacity);
|
||||
|
@ -73,11 +90,11 @@ void TextComponent::render(const Eigen::Affine3f& parentTrans)
|
|||
{
|
||||
Eigen::Affine3f trans = parentTrans * getTransform();
|
||||
|
||||
/*Eigen::Vector3f dim(mSize.x(), mSize.y(), 0);
|
||||
dim = trans * dim - trans.translation();
|
||||
Renderer::pushClipRect(Eigen::Vector2i((int)trans.translation().x(), (int)trans.translation().y()),
|
||||
Eigen::Vector2i((int)(dim.x() + 0.5f), (int)(dim.y() + 0.5f)));
|
||||
*/
|
||||
if (mBgColor)
|
||||
{
|
||||
Renderer::drawRect(getPosition().x(), getPosition().y() - 1,
|
||||
getSize().x(), getSize().y(), mBgColor);
|
||||
}
|
||||
|
||||
if(mTextCache)
|
||||
{
|
||||
|
@ -90,7 +107,7 @@ void TextComponent::render(const Eigen::Affine3f& parentTrans)
|
|||
Renderer::setMatrix(trans);
|
||||
Renderer::drawRect(0.f, 0.f, mSize.x(), mSize.y(), 0xFF000033);
|
||||
}
|
||||
|
||||
|
||||
trans.translate(off);
|
||||
trans = roundMatrix(trans);
|
||||
Renderer::setMatrix(trans);
|
||||
|
@ -111,11 +128,8 @@ void TextComponent::render(const Eigen::Affine3f& parentTrans)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mFont->renderTextCache(mTextCache.get());
|
||||
}
|
||||
|
||||
//Renderer::popClipRect();
|
||||
}
|
||||
|
||||
void TextComponent::calculateExtent()
|
||||
|
@ -216,8 +230,11 @@ void TextComponent::applyTheme(const std::shared_ptr<ThemeData>& theme, const st
|
|||
if(!elem)
|
||||
return;
|
||||
|
||||
if(properties & COLOR && elem->has("color"))
|
||||
setColor(elem->get<unsigned int>("color"));
|
||||
if (properties & COLOR && elem->has("color"))
|
||||
setColor(elem->get<unsigned int>("color"));
|
||||
|
||||
if (properties & COLOR && elem->has("backgroundColor"))
|
||||
setBackgroundColor(elem->get<unsigned int>("backgroundColor"));
|
||||
|
||||
if(properties & ALIGNMENT && elem->has("alignment"))
|
||||
{
|
||||
|
|
|
@ -16,7 +16,7 @@ class TextComponent : public GuiComponent
|
|||
public:
|
||||
TextComponent(Window* window);
|
||||
TextComponent(Window* window, const std::string& text, const std::shared_ptr<Font>& font, unsigned int color = 0x000000FF, Alignment align = ALIGN_LEFT,
|
||||
Eigen::Vector3f pos = Eigen::Vector3f::Zero(), Eigen::Vector2f size = Eigen::Vector2f::Zero());
|
||||
Eigen::Vector3f pos = Eigen::Vector3f::Zero(), Eigen::Vector2f size = Eigen::Vector2f::Zero(), unsigned int bgcolor = 0x00000000);
|
||||
|
||||
void setFont(const std::shared_ptr<Font>& font);
|
||||
void setUppercase(bool uppercase);
|
||||
|
@ -25,6 +25,7 @@ public:
|
|||
void setColor(unsigned int color);
|
||||
void setAlignment(Alignment align);
|
||||
void setLineSpacing(float spacing);
|
||||
void setBackgroundColor(unsigned int color);
|
||||
|
||||
void render(const Eigen::Affine3f& parentTrans) override;
|
||||
|
||||
|
@ -45,6 +46,10 @@ private:
|
|||
void onColorChanged();
|
||||
|
||||
unsigned int mColor;
|
||||
unsigned int mBgColor;
|
||||
unsigned char mColorOpacity;
|
||||
unsigned char mBgColorOpacity;
|
||||
|
||||
std::shared_ptr<Font> mFont;
|
||||
bool mUppercase;
|
||||
Eigen::Matrix<bool, 1, 2> mAutoCalcExtent;
|
||||
|
|
|
@ -84,7 +84,13 @@ int quitES(const std::string& filename)
|
|||
|
||||
void touch(const std::string& filename)
|
||||
{
|
||||
#ifdef WIN32
|
||||
FILE* fp = fopen(filename.c_str(), "ab+");
|
||||
if (fp != NULL)
|
||||
fclose(fp);
|
||||
#else
|
||||
int fd = open(filename.c_str(), O_CREAT|O_WRONLY, 0644);
|
||||
if (fd >= 0)
|
||||
close(fd);
|
||||
#endif
|
||||
}
|
Loading…
Reference in a new issue