From 709e6b996e7bf49d3e205b4bb956005a07f49029 Mon Sep 17 00:00:00 2001 From: Leon Styhre Date: Sat, 6 Jun 2020 16:48:05 +0200 Subject: [PATCH] Code cleanup and code documentation. Only cosmetic changes in this commit. --- es-app/src/main.cpp | 2 +- es-app/src/views/SystemView.cpp | 304 +++++++++--------- es-app/src/views/SystemView.h | 19 +- es-app/src/views/UIModeController.cpp | 77 ++--- es-app/src/views/UIModeController.h | 21 +- es-core/src/components/ComponentGrid.cpp | 249 +++++++------- es-core/src/components/ComponentGrid.h | 37 ++- es-core/src/components/ComponentList.cpp | 210 ++++++------ es-core/src/components/ComponentList.h | 39 ++- es-core/src/components/DateTimeComponent.cpp | 31 +- es-core/src/components/DateTimeComponent.h | 20 +- .../src/components/DateTimeEditComponent.cpp | 192 +++++------ .../src/components/DateTimeEditComponent.h | 26 +- es-core/src/components/MenuComponent.cpp | 75 +++-- es-core/src/components/MenuComponent.h | 24 +- es-core/src/components/SwitchComponent.cpp | 23 +- es-core/src/components/SwitchComponent.h | 9 +- es-core/src/components/TextEditComponent.cpp | 199 ++++++------ es-core/src/components/TextEditComponent.h | 8 +- es-core/src/components/TextListComponent.h | 220 ++++++------- 20 files changed, 944 insertions(+), 841 deletions(-) diff --git a/es-app/src/main.cpp b/es-app/src/main.cpp index 43096ff7d..3b459d997 100644 --- a/es-app/src/main.cpp +++ b/es-app/src/main.cpp @@ -7,7 +7,7 @@ // Improved and extended by the RetroPie community. // Desktop Edition fork by Leon Styhre. // -// The line length limit is 100 characters. +// The line length limit is 100 characters and the tab width is 4 spaces. // // main.cpp // diff --git a/es-app/src/views/SystemView.cpp b/es-app/src/views/SystemView.cpp index afd07954e..b65d576ae 100644 --- a/es-app/src/views/SystemView.cpp +++ b/es-app/src/views/SystemView.cpp @@ -1,3 +1,9 @@ +// +// SystemView.cpp +// +// Main system view. +// + #include "views/SystemView.h" #include "animations/LambdaAnimation.h" @@ -10,13 +16,16 @@ #include "Window.h" #include "Sound.h" -// buffer values for scrolling velocity (left, stopped, right) +// Buffer values for scrolling velocity (left, stopped, right). const int logoBuffersLeft[] = { -5, -2, -1 }; const int logoBuffersRight[] = { 1, 2, 5 }; -SystemView::SystemView(Window* window) : IList(window, LIST_SCROLL_STYLE_SLOW, LIST_ALWAYS_LOOP), - mViewNeedsReload(true), - mSystemInfo(window, "SYSTEM INFO", Font::get(FONT_SIZE_SMALL), 0x33333300, ALIGN_CENTER) +SystemView::SystemView( + Window* window) + : IList + (window, LIST_SCROLL_STYLE_SLOW, LIST_ALWAYS_LOOP), + mViewNeedsReload(true), + mSystemInfo(window, "SYSTEM INFO", Font::get(FONT_SIZE_SMALL), 0x33333300, ALIGN_CENTER) { mCamOffset = 0; mExtrasCamOffset = 0; @@ -30,28 +39,27 @@ void SystemView::populate() { mEntries.clear(); - for(auto it = SystemData::sSystemVector.cbegin(); it != SystemData::sSystemVector.cend(); it++) - { + for (auto it = SystemData::sSystemVector.cbegin(); + it != SystemData::sSystemVector.cend(); it++) { const std::shared_ptr& theme = (*it)->getTheme(); - if(mViewNeedsReload) + if (mViewNeedsReload) getViewElements(theme); - if((*it)->isVisible()) - { + if ((*it)->isVisible()) { Entry e; e.name = (*it)->getName(); e.object = *it; - // make logo + // Make logo. const ThemeData::ThemeElement* logoElem = theme->getElement("system", "logo", "image"); - if(logoElem) - { + if (logoElem) { std::string path = logoElem->get("path"); - std::string defaultPath = logoElem->has("default") ? logoElem->get("default") : ""; - if((!path.empty() && ResourceManager::getInstance()->fileExists(path)) - || (!defaultPath.empty() && ResourceManager::getInstance()->fileExists(defaultPath))) - { + std::string defaultPath = logoElem->has("default") ? + logoElem->get("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); @@ -59,37 +67,39 @@ void SystemView::populate() e.data.logo = std::shared_ptr(logo); } } - if (!e.data.logo) - { - // no logo in theme; use text - TextComponent* text = new TextComponent(mWindow, + 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 | ThemeFlags::LINE_SPACING | ThemeFlags::TEXT); + text->applyTheme((*it)->getTheme(), "system", "logoText", + ThemeFlags::FONT_PATH | ThemeFlags::FONT_SIZE | ThemeFlags::COLOR | + ThemeFlags::FORCE_UPPERCASE | ThemeFlags::LINE_SPACING | ThemeFlags::TEXT); e.data.logo = std::shared_ptr(text); - if (mCarousel.type == VERTICAL || mCarousel.type == VERTICAL_WHEEL) - { + if (mCarousel.type == VERTICAL || mCarousel.type == VERTICAL_WHEEL) { text->setHorizontalAlignment(mCarousel.logoAlignment); text->setVerticalAlignment(ALIGN_CENTER); - } else { + } + else { text->setHorizontalAlignment(ALIGN_CENTER); text->setVerticalAlignment(mCarousel.logoAlignment); } } - if (mCarousel.type == VERTICAL || mCarousel.type == VERTICAL_WHEEL) - { + if (mCarousel.type == VERTICAL || mCarousel.type == VERTICAL_WHEEL) { 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 { + } + else { if (mCarousel.logoAlignment == ALIGN_TOP) e.data.logo->setOrigin(0.5, 0); else if (mCarousel.logoAlignment == ALIGN_BOTTOM) @@ -100,29 +110,30 @@ void SystemView::populate() Vector2f denormalized = mCarousel.logoSize * e.data.logo->getOrigin(); e.data.logo->setPosition(denormalized.x(), denormalized.y(), 0.0); - // delete any existing extras + // Delete any existing extras. for (auto extra : e.data.backgroundExtras) delete extra; e.data.backgroundExtras.clear(); - // make background extras + // Make background extras. e.data.backgroundExtras = ThemeData::makeExtras((*it)->getTheme(), "system", mWindow); - // sort the extras by z-index - std::stable_sort(e.data.backgroundExtras.begin(), e.data.backgroundExtras.end(), [](GuiComponent* a, GuiComponent* b) { + // 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(); }); 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 - if (!UIModeController::getInstance()->isUIModeFull()) - { + if (mEntries.size() == 0) { + // Something is wrong, there is not a single system to show, check if UI mode is not full. + if (!UIModeController::getInstance()->isUIModeFull()) { 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)); + mWindow->pushGui(new GuiMsgBox(mWindow, + "The selected UI mode has nothing to show,\n returning to UI mode: FULL", "OK", + nullptr)); } } } @@ -131,7 +142,7 @@ void SystemView::goToSystem(SystemData* system, bool animate) { setCursor(system); - if(!animate) + if (!animate) finishAnimation(0); } @@ -140,27 +151,23 @@ bool SystemView::input(InputConfig* config, Input input) auto it = SystemData::sSystemVector.cbegin(); const std::shared_ptr& theme = (*it)->getTheme(); - if(input.value != 0) - { - if(config->getDeviceId() == DEVICE_KEYBOARD && input.value && input.id == SDLK_r && SDL_GetModState() & KMOD_LCTRL && Settings::getInstance()->getBool("Debug")) - { + if (input.value != 0) { + if (config->getDeviceId() == DEVICE_KEYBOARD && input.value && input.id == SDLK_r && + SDL_GetModState() & KMOD_LCTRL && Settings::getInstance()->getBool("Debug")) { LOG(LogInfo) << " Reloading all"; ViewController::get()->reloadAll(); return true; } - switch (mCarousel.type) - { + switch (mCarousel.type) { case VERTICAL: case VERTICAL_WHEEL: - if (config->isMappedLike("up", input)) - { + if (config->isMappedLike("up", input)) { NavigationSounds::getInstance()->playThemeNavigationSound(SYSTEMBROWSESOUND); listInput(-1); return true; } - if (config->isMappedLike("down", input)) - { + if (config->isMappedLike("down", input)) { NavigationSounds::getInstance()->playThemeNavigationSound(SYSTEMBROWSESOUND); listInput(1); return true; @@ -169,14 +176,12 @@ bool SystemView::input(InputConfig* config, Input input) case HORIZONTAL: case HORIZONTAL_WHEEL: default: - if (config->isMappedLike("left", input)) - { + if (config->isMappedLike("left", input)) { NavigationSounds::getInstance()->playThemeNavigationSound(SYSTEMBROWSESOUND); listInput(-1); return true; } - if (config->isMappedLike("right", input)) - { + if (config->isMappedLike("right", input)) { NavigationSounds::getInstance()->playThemeNavigationSound(SYSTEMBROWSESOUND); listInput(1); return true; @@ -184,29 +189,29 @@ bool SystemView::input(InputConfig* config, Input input) break; } - if(config->isMappedTo("a", input)) - { + if (config->isMappedTo("a", input)) { stopScrolling(); ViewController::get()->goToGameList(getSelected()); NavigationSounds::getInstance()->playThemeNavigationSound(SELECTSOUND); return true; } - if (config->isMappedTo("x", input)) - { - // get random system - // go to system + if (config->isMappedTo("x", input)) { + // Get random system. + // Go to system. NavigationSounds::getInstance()->playThemeNavigationSound(SYSTEMBROWSESOUND); setCursor(SystemData::getRandomSystem()); return true; } - }else{ - if(config->isMappedLike("left", input) || + } + else { + if (config->isMappedLike("left", input) || config->isMappedLike("right", input) || config->isMappedLike("up", input) || config->isMappedLike("down", input)) listInput(0); - if(!UIModeController::getInstance()->isUIModeKid() && config->isMappedTo("select", input) && Settings::getInstance()->getBool("ScreenSaverControls")) - { + if (!UIModeController::getInstance()->isUIModeKid() && + config->isMappedTo("select", input) && + Settings::getInstance()->getBool("ScreenSaverControls")) { mWindow->startScreenSaver(); mWindow->renderScreenSaver(); return true; @@ -224,7 +229,7 @@ void SystemView::update(int deltaTime) void SystemView::onCursorChanged(const CursorState& /*state*/) { - // update help style + // Update help style. updateHelpPrompts(); float startPos = mCamOffset; @@ -232,18 +237,18 @@ void SystemView::onCursorChanged(const CursorState& /*state*/) float posMax = (float)mEntries.size(); float target = (float)mCursor; - // what's the shortest way to get to our target? - // it's one of these... + // What's the shortest way to get to our target? + // It's one of these... - float endPos = target; // directly + float endPos = target; // Directly. float dist = abs(endPos - startPos); - 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) + 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). - // animate mSystemInfo's opacity (fade out, wait, fade back in) + // Animate mSystemInfo's opacity (fade out, wait, fade back in). cancelAnimation(1); cancelAnimation(2); @@ -253,14 +258,13 @@ void SystemView::onCursorChanged(const CursorState& /*state*/) const float infoStartOpacity = mSystemInfo.getOpacity() / 255.f; Animation* infoFadeOut = new LambdaAnimation( - [infoStartOpacity, this] (float t) - { + [infoStartOpacity, this] (float t) { mSystemInfo.setOpacity((unsigned char)(Math::lerp(infoStartOpacity, 0.f, t) * 255)); }, (int)(infoStartOpacity * (goFast ? 10 : 150))); unsigned int gameCount = getSelected()->getDisplayedGameCount(); - // also change the text after we've fully faded out + // Also change the text after we've fully faded out. setAnimation(infoFadeOut, 0, [this, gameCount] { std::stringstream ss; @@ -273,72 +277,69 @@ void SystemView::onCursorChanged(const CursorState& /*state*/) }, false, 1); Animation* infoFadeIn = new LambdaAnimation( - [this](float t) - { + [this](float t) { mSystemInfo.setOpacity((unsigned char)(Math::lerp(0.f, 1.f, t) * 255)); }, goFast ? 10 : 300); - // wait 600ms to fade in + // Wait 600ms to fade in. setAnimation(infoFadeIn, goFast ? 0 : 2000, nullptr, false, 2); - // no need to animate transition, we're not going anywhere (probably mEntries.size() == 1) - if(endPos == mCamOffset && endPos == mExtrasCamOffset) + // No need to animate transition, we're not going anywhere (probably mEntries.size() == 1). + if (endPos == mCamOffset && endPos == mExtrasCamOffset) return; Animation* anim; bool move_carousel = Settings::getInstance()->getBool("MoveCarousel"); - if(transition_style == "fade") - { + if (transition_style == "fade") { float startExtrasFade = mExtrasFadeOpacity; anim = new LambdaAnimation( - [this, startExtrasFade, startPos, endPos, posMax, move_carousel](float t) - { + [this, startExtrasFade, startPos, endPos, posMax, move_carousel](float t) { t -= 1; float f = Math::lerp(startPos, endPos, t*t*t + 1); - if(f < 0) + if (f < 0) f += posMax; - if(f >= posMax) + if (f >= posMax) f -= posMax; this->mCamOffset = move_carousel ? f : endPos; t += 1; - if(t < 0.3f) + if (t < 0.3f) this->mExtrasFadeOpacity = Math::lerp(0.0f, 1.0f, t / 0.3f + startExtrasFade); - else if(t < 0.7f) + else if (t < 0.7f) this->mExtrasFadeOpacity = 1.0f; else this->mExtrasFadeOpacity = Math::lerp(1.0f, 0.0f, (t - 0.7f) / 0.3f); - if(t > 0.5f) + if (t > 0.5f) this->mExtrasCamOffset = endPos; }, 500); - } else if (transition_style == "slide") { - // slide + } + else if (transition_style == "slide") { + // Slide. anim = new LambdaAnimation( - [this, startPos, endPos, posMax, move_carousel](float t) - { + [this, startPos, endPos, posMax, move_carousel](float t) { t -= 1; float f = Math::lerp(startPos, endPos, t*t*t + 1); - if(f < 0) + if (f < 0) f += posMax; - if(f >= posMax) + if (f >= posMax) f -= posMax; this->mCamOffset = move_carousel ? f : endPos; this->mExtrasCamOffset = f; }, 500); - } else { - // instant + } + else { + // Instant. anim = new LambdaAnimation( - [this, startPos, endPos, posMax, move_carousel ](float t) - { + [this, startPos, endPos, posMax, move_carousel ](float t) { t -= 1; float f = Math::lerp(startPos, endPos, t*t*t + 1); - if(f < 0) + if (f < 0) f += posMax; - if(f >= posMax) + if (f >= posMax) f -= posMax; this->mCamOffset = move_carousel ? f : endPos; @@ -346,14 +347,13 @@ void SystemView::onCursorChanged(const CursorState& /*state*/) }, move_carousel ? 500 : 1); } - setAnimation(anim, 0, nullptr, false, 0); } void SystemView::render(const Transform4x4f& parentTrans) { - if(size() == 0) - return; // nothing to render + if (size() == 0) + return; // Nothing to render. Transform4x4f trans = getTransform() * parentTrans; @@ -365,7 +365,8 @@ void SystemView::render(const Transform4x4f& parentTrans) if (mCarousel.zIndex > mSystemInfo.getZIndex()) { renderInfoBar(trans); - } else { + } + else { renderCarousel(trans); } @@ -373,7 +374,8 @@ void SystemView::render(const Transform4x4f& parentTrans) if (mCarousel.zIndex > mSystemInfo.getZIndex()) { renderCarousel(trans); - } else { + } + else { renderInfoBar(trans); } @@ -390,7 +392,8 @@ std::vector SystemView::getHelpPrompts() prompts.push_back(HelpPrompt("a", "select")); prompts.push_back(HelpPrompt("x", "random")); - if (!UIModeController::getInstance()->isUIModeKid() && Settings::getInstance()->getBool("ScreenSaverControls")) + if (!UIModeController::getInstance()->isUIModeKid() && + Settings::getInstance()->getBool("ScreenSaverControls")) prompts.push_back(HelpPrompt("select", "launch screensaver")); return prompts; @@ -420,40 +423,46 @@ void SystemView::getViewElements(const std::shared_ptr& theme) if (!theme->hasView("system")) return; - const ThemeData::ThemeElement* carouselElem = theme->getElement("system", "systemcarousel", "carousel"); + const ThemeData::ThemeElement* carouselElem = theme-> + getElement("system", "systemcarousel", "carousel"); if (carouselElem) getCarouselFromTheme(carouselElem); - const ThemeData::ThemeElement* sysInfoElem = theme->getElement("system", "systemInfo", "text"); + const ThemeData::ThemeElement* sysInfoElem = theme-> + getElement("system", "systemInfo", "text"); if (sysInfoElem) mSystemInfo.applyTheme(theme, "system", "systemInfo", ThemeFlags::ALL); mViewNeedsReload = false; } -// Render system carousel +// Render system carousel. void SystemView::renderCarousel(const Transform4x4f& trans) { - // background box behind logos + // Background box behind logos. 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)); + carouselTrans.translate(Vector3f(mCarousel.origin.x() * mCarousel.size.x() * -1, + mCarousel.origin.y() * mCarousel.size.y() * -1, 0.0f)); 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())); + Renderer::pushClipRect(Vector2i((int)clipPos.x(), (int)clipPos.y()), + Vector2i((int)mCarousel.size.x(), (int)mCarousel.size.y())); Renderer::setMatrix(carouselTrans); - Renderer::drawRect(0.0f, 0.0f, mCarousel.size.x(), mCarousel.size.y(), mCarousel.color, mCarousel.colorEnd, mCarousel.colorGradientHorizontal); + Renderer::drawRect(0.0f, 0.0f, mCarousel.size.x(), mCarousel.size.y(), + mCarousel.color, mCarousel.colorEnd, mCarousel.colorGradientHorizontal); - // draw logos - Vector2f logoSpacing(0.0, 0.0); // NB: logoSpacing will include the size of the logo itself as well! + // Draw logos. + // NB: logoSpacing will also include the size of the logo itself! + Vector2f logoSpacing(0.0, 0.0); float xOff = 0.0; float yOff = 0.0; - switch (mCarousel.type) - { + switch (mCarousel.type) { case VERTICAL_WHEEL: - yOff = (mCarousel.size.y() - mCarousel.logoSize.y()) / 2.f - (mCamOffset * logoSpacing[1]); + yOff = (mCarousel.size.y() - mCarousel.logoSize.y()) / 2.f - + (mCamOffset * logoSpacing[1]); if (mCarousel.logoAlignment == ALIGN_LEFT) xOff = mCarousel.logoSize.x() / 10.f; else if (mCarousel.logoAlignment == ALIGN_RIGHT) @@ -462,8 +471,10 @@ void SystemView::renderCarousel(const Transform4x4f& trans) xOff = (mCarousel.size.x() - mCarousel.logoSize.x()) / 2.f; break; case VERTICAL: - logoSpacing[1] = ((mCarousel.size.y() - (mCarousel.logoSize.y() * mCarousel.maxLogoCount)) / (mCarousel.maxLogoCount)) + mCarousel.logoSize.y(); - yOff = (mCarousel.size.y() - mCarousel.logoSize.y()) / 2.f - (mCamOffset * logoSpacing[1]); + logoSpacing[1] = ((mCarousel.size.y() - (mCarousel.logoSize.y() * + mCarousel.maxLogoCount)) / (mCarousel.maxLogoCount)) + mCarousel.logoSize.y(); + yOff = (mCarousel.size.y() - mCarousel.logoSize.y()) / 2.f - + (mCamOffset * logoSpacing[1]); if (mCarousel.logoAlignment == ALIGN_LEFT) xOff = mCarousel.logoSize.x() / 10.f; @@ -473,7 +484,8 @@ void SystemView::renderCarousel(const Transform4x4f& trans) xOff = (mCarousel.size.x() - mCarousel.logoSize.x()) / 2; break; case HORIZONTAL_WHEEL: - xOff = (mCarousel.size.x() - mCarousel.logoSize.x()) / 2 - (mCamOffset * logoSpacing[1]); + xOff = (mCarousel.size.x() - mCarousel.logoSize.x()) / 2 - + (mCamOffset * logoSpacing[1]); if (mCarousel.logoAlignment == ALIGN_TOP) yOff = mCarousel.logoSize.y() / 10; else if (mCarousel.logoAlignment == ALIGN_BOTTOM) @@ -483,8 +495,10 @@ void SystemView::renderCarousel(const Transform4x4f& trans) break; case HORIZONTAL: default: - logoSpacing[0] = ((mCarousel.size.x() - (mCarousel.logoSize.x() * mCarousel.maxLogoCount)) / (mCarousel.maxLogoCount)) + mCarousel.logoSize.x(); - xOff = (mCarousel.size.x() - mCarousel.logoSize.x()) / 2.f - (mCamOffset * logoSpacing[0]); + logoSpacing[0] = ((mCarousel.size.x() - (mCarousel.logoSize.x() * + mCarousel.maxLogoCount)) / (mCarousel.maxLogoCount)) + mCarousel.logoSize.x(); + xOff = (mCarousel.size.x() - mCarousel.logoSize.x()) / 2.f - + (mCamOffset * logoSpacing[0]); if (mCarousel.logoAlignment == ALIGN_TOP) yOff = mCarousel.logoSize.y() / 10.f; @@ -498,18 +512,17 @@ void SystemView::renderCarousel(const Transform4x4f& trans) int center = (int)(mCamOffset); int logoCount = Math::min(mCarousel.maxLogoCount, (int)mEntries.size()); - // Adding texture loading buffers depending on scrolling speed and status + // Adding texture loading buffers depending on scrolling speed and status. int bufferIndex = getScrollingVelocity() + 1; int bufferLeft = logoBuffersLeft[bufferIndex]; int bufferRight = logoBuffersRight[bufferIndex]; - if (logoCount == 1) - { + if (logoCount == 1) { bufferLeft = 0; bufferRight = 0; } - for (int i = center - logoCount / 2 + bufferLeft; i <= center + logoCount / 2 + bufferRight; i++) - { + for (int i = center - logoCount / 2 + bufferLeft; + i <= center + logoCount / 2 + bufferRight; i++) { int index = i; while (index < 0) index += (int)mEntries.size(); @@ -546,25 +559,25 @@ void SystemView::renderInfoBar(const Transform4x4f& trans) mSystemInfo.render(trans); } -// Draw background extras +// Draw background extras. void SystemView::renderExtras(const Transform4x4f& trans, float lower, float upper) { int extrasCenter = (int)mExtrasCamOffset; - // Adding texture loading buffers depending on scrolling speed and status + // Adding texture loading buffers depending on scrolling speed and status. int bufferIndex = getScrollingVelocity() + 1; Renderer::pushClipRect(Vector2i::Zero(), Vector2i((int)mSize.x(), (int)mSize.y())); - for (int i = extrasCenter + logoBuffersLeft[bufferIndex]; i <= extrasCenter + logoBuffersRight[bufferIndex]; i++) - { + for (int i = extrasCenter + logoBuffersLeft[bufferIndex]; i <= extrasCenter + + logoBuffersRight[bufferIndex]; i++) { int index = i; while (index < 0) index += (int)mEntries.size(); while (index >= (int)mEntries.size()) index -= (int)mEntries.size(); - //Only render selected system when not showing + // Only render selected system when not showing. if (mShowing || index == mCursor) { Transform4x4f extrasTrans = trans; @@ -573,8 +586,9 @@ void SystemView::renderExtras(const Transform4x4f& trans, float lower, float upp else extrasTrans.translate(Vector3f(0, (i - mExtrasCamOffset) * mSize.y(), 0)); - Renderer::pushClipRect(Vector2i((int)extrasTrans.translation()[0], (int)extrasTrans.translation()[1]), - Vector2i((int)mSize.x(), (int)mSize.y())); + Renderer::pushClipRect(Vector2i((int)extrasTrans.translation()[0], + (int)extrasTrans.translation()[1]), + Vector2i((int)mSize.x(), (int)mSize.y())); SystemViewData data = mEntries.at(index).data; for (unsigned int j = 0; j < data.backgroundExtras.size(); j++) { GuiComponent *extra = data.backgroundExtras[j]; @@ -590,19 +604,18 @@ void SystemView::renderExtras(const Transform4x4f& trans, float lower, float upp void SystemView::renderFade(const Transform4x4f& trans) { - // fade extras if necessary - if (mExtrasFadeOpacity) - { + // Fade extras if necessary. + if (mExtrasFadeOpacity) { unsigned int fadeColor = 0x00000000 | (unsigned char)(mExtrasFadeOpacity * 255); Renderer::setMatrix(trans); Renderer::drawRect(0.0f, 0.0f, mSize.x(), mSize.y(), fadeColor, fadeColor); } } -// Populate the system carousel with the legacy values +// Populate the system carousel with the legacy values. void SystemView::getDefaultElements(void) { - // Carousel + // Carousel. mCarousel.type = HORIZONTAL; mCarousel.logoAlignment = ALIGN_CENTER; mCarousel.size.x() = mSize.x(); @@ -623,7 +636,7 @@ void SystemView::getDefaultElements(void) mCarousel.maxLogoCount = 3; mCarousel.zIndex = 40; - // System Info Bar + // System Info Bar. mSystemInfo.setSize(mSize.x(), mSystemInfo.getFont()->getLetterHeight()*2.2f); mSystemInfo.setPosition(0, (mCarousel.pos.y() + mCarousel.size.y() - 0.2f)); mSystemInfo.setBackgroundColor(0xDDDDDDD8); @@ -636,8 +649,7 @@ void SystemView::getDefaultElements(void) void SystemView::getCarouselFromTheme(const ThemeData::ThemeElement* elem) { - if (elem->has("type")) - { + if (elem->has("type")) { if (!(elem->get("type").compare("vertical"))) mCarousel.type = VERTICAL; else if (!(elem->get("type").compare("vertical_wheel"))) @@ -653,8 +665,7 @@ void SystemView::getCarouselFromTheme(const ThemeData::ThemeElement* elem) mCarousel.pos = elem->get("pos") * mSize; if (elem->has("origin")) mCarousel.origin = elem->get("origin"); - if (elem->has("color")) - { + if (elem->has("color")) { mCarousel.color = elem->get("color"); mCarousel.colorEnd = mCarousel.color; } @@ -674,8 +685,7 @@ void SystemView::getCarouselFromTheme(const ThemeData::ThemeElement* elem) mCarousel.logoRotation = elem->get("logoRotation"); if (elem->has("logoRotationOrigin")) mCarousel.logoRotationOrigin = elem->get("logoRotationOrigin"); - if (elem->has("logoAlignment")) - { + if (elem->has("logoAlignment")) { if (!(elem->get("logoAlignment").compare("left"))) mCarousel.logoAlignment = ALIGN_LEFT; else if (!(elem->get("logoAlignment").compare("right"))) diff --git a/es-app/src/views/SystemView.h b/es-app/src/views/SystemView.h index 2d4c90033..491a352bd 100644 --- a/es-app/src/views/SystemView.h +++ b/es-app/src/views/SystemView.h @@ -1,3 +1,9 @@ +// +// SystemView.h +// +// Main system view. +// + #pragma once #ifndef ES_APP_VIEWS_SYSTEM_VIEW_H #define ES_APP_VIEWS_SYSTEM_VIEW_H @@ -11,22 +17,19 @@ class AnimatedImageComponent; class SystemData; -enum CarouselType : unsigned int -{ +enum CarouselType : unsigned int { HORIZONTAL = 0, VERTICAL = 1, VERTICAL_WHEEL = 2, HORIZONTAL_WHEEL = 3 }; -struct SystemViewData -{ +struct SystemViewData { std::shared_ptr logo; std::vector backgroundExtras; }; -struct SystemViewCarousel -{ +struct SystemViewCarousel { CarouselType type; Vector2f pos; Vector2f size; @@ -38,7 +41,7 @@ struct SystemViewCarousel unsigned int color; unsigned int colorEnd; bool colorGradientHorizontal; - int maxLogoCount; // number of logos shown on the carousel + int maxLogoCount; // Number of logos shown on the carousel. Vector2f logoSize; float zIndex; }; @@ -79,7 +82,7 @@ private: SystemViewCarousel mCarousel; TextComponent mSystemInfo; - // unit is list index + // Unit is list index. float mCamOffset; float mExtrasCamOffset; float mExtrasFadeOpacity; diff --git a/es-app/src/views/UIModeController.cpp b/es-app/src/views/UIModeController.cpp index 2efa944c9..44c6e4361 100644 --- a/es-app/src/views/UIModeController.cpp +++ b/es-app/src/views/UIModeController.cpp @@ -1,3 +1,10 @@ +// +// UIModeController.cpp +// +// Handling of application user interface modes (full, kiosk and kid). +// This includes switching the mode when the UI mode passkey was used. +// + #include "UIModeController.h" #include "utils/StringUtil.h" @@ -25,8 +32,8 @@ UIModeController::UIModeController() void UIModeController::monitorUIMode() { std::string uimode = Settings::getInstance()->getString("UIMode"); - if (uimode != mCurrentUIMode) // UIMODE HAS CHANGED - { + // UI mode was changed. + if (uimode != mCurrentUIMode) { mCurrentUIMode = uimode; ViewController::get()->ReloadAndGoToStart(); } @@ -34,26 +41,18 @@ void UIModeController::monitorUIMode() bool UIModeController::listen(InputConfig * config, Input input) { - // Reads the current input to listen for the passkey - // sequence to unlock the UI mode. The progress is saved in mPassKeyCounter + // Reads the current input to listen for the passkey sequence to unlock + // the UI mode. The progress is saved in mPassKeyCounter. if (Settings::getInstance()->getBool("Debug")) - { logInput(config, input); - } if ((Settings::getInstance()->getString("UIMode") == "Full") || !isValidInput(config, input)) - { return false; // Already unlocked, or invalid input, nothing to do here. - } - if (!inputIsMatch(config, input)) - { - mPassKeyCounter = 0; // current input is incorrect, reset counter - } + mPassKeyCounter = 0; // Current input is incorrect, reset counter. - if (mPassKeyCounter == (int)mPassKeySequence.length()) - { + if (mPassKeyCounter == (int)mPassKeySequence.length()) { unlockUIMode(); return true; } @@ -62,11 +61,9 @@ bool UIModeController::listen(InputConfig * config, Input input) bool UIModeController::inputIsMatch(InputConfig * config, Input input) { - for (auto valstring : mInputVals) - { + for (auto valstring : mInputVals) { if (config->isMappedLike(valstring, input) && - (mPassKeySequence[mPassKeyCounter] == valstring[0])) - { + (mPassKeySequence[mPassKeyCounter] == valstring[0])) { mPassKeyCounter++; return true; } @@ -74,10 +71,11 @@ bool UIModeController::inputIsMatch(InputConfig * config, Input input) return false; } -// When we have reached the end of the list, trigger UI_mode unlock +// When we have reached the end of the list, trigger UI_mode unlock. void UIModeController::unlockUIMode() { - LOG(LogDebug) << " UIModeController::listen(): Passkey sequence completed, switching UIMode to full"; + LOG(LogDebug) << + " UIModeController::listen(): Passkey sequence completed, switching UIMode to full"; Settings::getInstance()->setString("UIMode", "Full"); Settings::getInstance()->saveFile(); mPassKeyCounter = 0; @@ -102,26 +100,24 @@ bool UIModeController::isUIModeKiosk() std::string UIModeController::getFormattedPassKeyStr() { - // supported sequence-inputs: u (up), d (down), l (left), r (right), a, b, x, y + // Supported sequence-inputs: u (up), d (down), l (left), r (right), a, b, x, y. std::string out = ""; - for (auto c : mPassKeySequence) - { - out += (out == "") ? "" : ", "; // add a comma after the first entry + for (auto c : mPassKeySequence) { + out += (out == "") ? "" : ", "; // Add a comma after the first entry. - switch (c) - { + switch (c) { case 'u': - out += Utils::String::unicode2Chars(0x2191); // arrow pointing up + out += Utils::String::unicode2Chars(0x2191); // Arrow pointing up. break; case 'd': - out += Utils::String::unicode2Chars(0x2193); // arrow pointing down + out += Utils::String::unicode2Chars(0x2193); // Arrow pointing down. break; case 'l': - out += Utils::String::unicode2Chars(0x2190); // arrow pointing left + out += Utils::String::unicode2Chars(0x2190); // Arrow pointing left. break; case 'r': - out += Utils::String::unicode2Chars(0x2192); // arrow pointing right + out += Utils::String::unicode2Chars(0x2192); // Arrow pointing right. break; case 'a': out += "A"; @@ -140,29 +136,26 @@ std::string UIModeController::getFormattedPassKeyStr() return out; } - void UIModeController::logInput(InputConfig * config, Input input) { std::string mapname = ""; std::vector maps = config->getMappedTo(input); - for( auto mn : maps) - { + + for (auto mn : maps) { mapname += mn; mapname += ", "; } - LOG(LogDebug) << "UIModeController::logInput( " << config->getDeviceName() <<" ):" << input.string() << ", isMappedTo= " << mapname << ", value=" << input.value; + + LOG(LogDebug) << "UIModeController::logInput( " << config->getDeviceName() << + " ):" << input.string() << ", isMappedTo= " << mapname << ", value=" << input.value; } bool UIModeController::isValidInput(InputConfig * config, Input input) { - if((config->getMappedTo(input).size() == 0) || // not a mapped input, so ignore. - (input.type == TYPE_HAT) || // ignore all HAT inputs - (!input.value)) // not a key-down event - { + if ((config->getMappedTo(input).size() == 0) || // Not a mapped input, so ignore.. + (input.type == TYPE_HAT) || // Ignore all hat inputs. + (!input.value)) // Not a key-down event. return false; - } else - { return true; - } -} \ No newline at end of file +} diff --git a/es-app/src/views/UIModeController.h b/es-app/src/views/UIModeController.h index 04913a190..19ec08ed3 100644 --- a/es-app/src/views/UIModeController.h +++ b/es-app/src/views/UIModeController.h @@ -1,3 +1,10 @@ +// +// UIModeController.h +// +// Handling of application user interface modes (full, kiosk and kid). +// This includes switching the mode when the UI mode passkey was used. +// + #pragma once #ifndef ES_APP_VIEWS_UI_MODE_CONTROLLER_H #define ES_APP_VIEWS_UI_MODE_CONTROLLER_H @@ -11,11 +18,13 @@ class ViewController; struct Input; -class UIModeController { +class UIModeController +{ public: static UIModeController* getInstance(); - // Monitor input for UI mode change, returns true (consumes input) when UI mode change is triggered. + // Monitor input for UI mode change, returns true (consumes input) when a UI mode + // change is triggered. bool listen(InputConfig* config, Input input); // Get the current Passphrase as a (unicode) formatted, comma-separated, string. @@ -28,22 +37,24 @@ public: bool isUIModeKid(); bool isUIModeKiosk(); inline std::vector getUIModes() { return mUIModes; }; + private: UIModeController(); bool inputIsMatch(InputConfig * config, Input input); bool isValidInput(InputConfig * config, Input input); void logInput(InputConfig * config, Input input); - // Return UI mode to 'FULL' + // Return UI mode to 'full'. void unlockUIMode(); static UIModeController * sInstance; const std::vector mUIModes = { "Full", "Kiosk", "Kid" }; - // default passkeyseq = "uuddlrlrba", as defined in the setting 'UIMode_passkey'. + // Default passkeyseq = "uuddlrlrba", as defined in the setting 'UIMode_passkey'. std::string mPassKeySequence; int mPassKeyCounter; - const std::vector mInputVals = { "up", "down", "left", "right", "a", "b", "x", "y" }; + const std::vector mInputVals = + { "up", "down", "left", "right", "a", "b", "x", "y" }; std::string mCurrentUIMode; }; diff --git a/es-core/src/components/ComponentGrid.cpp b/es-core/src/components/ComponentGrid.cpp index 90b6162d9..1ad0fb44c 100644 --- a/es-core/src/components/ComponentGrid.cpp +++ b/es-core/src/components/ComponentGrid.cpp @@ -1,11 +1,21 @@ +// +// ComponentGrid.cpp +// +// Providing basic layout of other components in an X*Y grid. +// + #include "components/ComponentGrid.h" #include "Settings.h" using namespace GridFlags; -ComponentGrid::ComponentGrid(Window* window, const Vector2i& gridDimensions) : GuiComponent(window), - mGridSize(gridDimensions), mCursor(0, 0) +ComponentGrid::ComponentGrid( + Window* window, + const Vector2i& gridDimensions) + : GuiComponent(window), + mGridSize(gridDimensions), + mCursor(0, 0) { assert(gridDimensions.x() > 0 && gridDimensions.y() > 0); @@ -13,9 +23,9 @@ ComponentGrid::ComponentGrid(Window* window, const Vector2i& gridDimensions) : G mColWidths = new float[gridDimensions.x()]; mRowHeights = new float[gridDimensions.y()]; - for(int x = 0; x < gridDimensions.x(); x++) + for (int x = 0; x < gridDimensions.x(); x++) mColWidths[x] = 0; - for(int y = 0; y < gridDimensions.y(); y++) + for (int y = 0; y < gridDimensions.y(); y++) mRowHeights[y] = 0; } @@ -27,16 +37,15 @@ ComponentGrid::~ComponentGrid() float ComponentGrid::getColWidth(int col) { - if(mColWidths[col] != 0) + if (mColWidths[col] != 0) return mColWidths[col] * mSize.x(); - // calculate automatic width + // Calculate automatic width. float freeWidthPerc = 1; int between = 0; - for(int x = 0; x < mGridSize.x(); x++) - { - freeWidthPerc -= mColWidths[x]; // if it's 0 it won't do anything - if(mColWidths[x] == 0) + for (int x = 0; x < mGridSize.x(); x++) { + freeWidthPerc -= mColWidths[x]; // If it's 0 it won't do anything. + if (mColWidths[x] == 0) between++; } @@ -45,16 +54,15 @@ float ComponentGrid::getColWidth(int col) float ComponentGrid::getRowHeight(int row) { - if(mRowHeights[row] != 0) + if (mRowHeights[row] != 0) return mRowHeights[row] * mSize.y(); - // calculate automatic height + // Calculate automatic height. float freeHeightPerc = 1; int between = 0; - for(int y = 0; y < mGridSize.y(); y++) - { - freeHeightPerc -= mRowHeights[y]; // if it's 0 it won't do anything - if(mRowHeights[y] == 0) + for (int y = 0; y < mGridSize.y(); y++) { + freeHeightPerc -= mRowHeights[y]; // If it's 0 it won't do anything. + if (mRowHeights[y] == 0) between++; } @@ -67,7 +75,7 @@ void ComponentGrid::setColWidthPerc(int col, float width, bool update) assert(col >= 0 && col < mGridSize.x()); mColWidths[col] = width; - if(update) + if (update) onSizeChanged(); } @@ -77,12 +85,18 @@ void ComponentGrid::setRowHeightPerc(int row, float height, bool update) assert(row >= 0 && row < mGridSize.y()); mRowHeights[row] = height; - if(update) + if (update) onSizeChanged(); } -void ComponentGrid::setEntry(const std::shared_ptr& comp, const Vector2i& pos, bool canFocus, bool resize, const Vector2i& size, - unsigned int border, GridFlags::UpdateType updateType) +void ComponentGrid::setEntry( + const std::shared_ptr& comp, + const Vector2i& pos, + bool canFocus, + bool resize, + const Vector2i& size, + unsigned int border, + GridFlags::UpdateType updateType) { assert(pos.x() >= 0 && pos.x() < mGridSize.x() && pos.y() >= 0 && pos.y() < mGridSize.y()); assert(comp != nullptr); @@ -93,8 +107,7 @@ void ComponentGrid::setEntry(const std::shared_ptr& comp, const Ve addChild(comp.get()); - if(!cursorValid() && canFocus) - { + if (!cursorValid() && canFocus) { auto origCursor = mCursor; mCursor = pos; onCursorMoved(origCursor, mCursor); @@ -106,10 +119,8 @@ void ComponentGrid::setEntry(const std::shared_ptr& comp, const Ve bool ComponentGrid::removeEntry(const std::shared_ptr& comp) { - for(auto it = mCells.cbegin(); it != mCells.cend(); it++) - { - if(it->component == comp) - { + for (auto it = mCells.cbegin(); it != mCells.cend(); it++) { + if (it->component == comp) { removeChild(comp.get()); mCells.erase(it); return true; @@ -121,25 +132,25 @@ bool ComponentGrid::removeEntry(const std::shared_ptr& comp) void ComponentGrid::updateCellComponent(const GridEntry& cell) { - // size + // Size. Vector2f size(0, 0); - for(int x = cell.pos.x(); x < cell.pos.x() + cell.dim.x(); x++) + for (int x = cell.pos.x(); x < cell.pos.x() + cell.dim.x(); x++) size[0] += getColWidth(x); - for(int y = cell.pos.y(); y < cell.pos.y() + cell.dim.y(); y++) + for (int y = cell.pos.y(); y < cell.pos.y() + cell.dim.y(); y++) size[1] += getRowHeight(y); - if(cell.resize) + if (cell.resize) cell.component->setSize(size); - // position - // find top left corner + // Position. + // Find top left corner. Vector3f pos(0, 0, 0); - for(int x = 0; x < cell.pos.x(); x++) + for (int x = 0; x < cell.pos.x(); x++) pos[0] += getColWidth(x); - for(int y = 0; y < cell.pos.y(); y++) + for (int y = 0; y < cell.pos.y(); y++) pos[1] += getRowHeight(y); - // center component + // Center component. pos[0] = pos.x() + (size.x() - cell.component->getSize().x()) / 2; pos[1] = pos.y() + (size.y() - cell.component->getSize().y()) / 2; @@ -155,49 +166,44 @@ void ComponentGrid::updateSeparators() Vector2f pos; Vector2f size; - for(auto it = mCells.cbegin(); it != mCells.cend(); it++) - { - if(!it->border && !drawAll) + for (auto it = mCells.cbegin(); it != mCells.cend(); it++) { + if (!it->border && !drawAll) continue; - // find component position + size + // Find component position + size. pos = Vector2f(0, 0); size = Vector2f(0, 0); - for(int x = 0; x < it->pos.x(); x++) + for (int x = 0; x < it->pos.x(); x++) pos[0] += getColWidth(x); - for(int y = 0; y < it->pos.y(); y++) + for (int y = 0; y < it->pos.y(); y++) pos[1] += getRowHeight(y); - for(int x = it->pos.x(); x < it->pos.x() + it->dim.x(); x++) + for (int x = it->pos.x(); x < it->pos.x() + it->dim.x(); x++) size[0] += getColWidth(x); - for(int y = it->pos.y(); y < it->pos.y() + it->dim.y(); y++) + for (int y = it->pos.y(); y < it->pos.y() + it->dim.y(); y++) size[1] += getRowHeight(y); - if(it->border & BORDER_TOP || drawAll) - { - mLines.push_back( { { pos.x(), pos.y() }, { 0.0f, 0.0f }, color } ); - mLines.push_back( { { pos.x() + size.x(), pos.y() }, { 0.0f, 0.0f }, color } ); + if (it->border & BORDER_TOP || drawAll) { + mLines.push_back( { { pos.x(), pos.y() }, { 0.0f, 0.0f }, color } ); + mLines.push_back( { { pos.x() + size.x(), pos.y() }, { 0.0f, 0.0f }, color } ); } - if(it->border & BORDER_BOTTOM || drawAll) - { - mLines.push_back( { { pos.x(), pos.y() + size.y() }, { 0.0f, 0.0f }, color } ); - mLines.push_back( { { pos.x() + size.x(), mLines.back().pos.y() }, { 0.0f, 0.0f }, color } ); + if (it->border & BORDER_BOTTOM || drawAll) { + mLines.push_back( { { pos.x(), pos.y() + size.y() }, { 0.0f, 0.0f }, color } ); + mLines.push_back( { { pos.x() + size.x(), mLines.back().pos.y() }, { 0.0f, 0.0f }, color } ); } - if(it->border & BORDER_LEFT || drawAll) - { - mLines.push_back( { { pos.x(), pos.y() }, { 0.0f, 0.0f }, color } ); - mLines.push_back( { { pos.x(), pos.y() + size.y() }, { 0.0f, 0.0f }, color } ); + if (it->border & BORDER_LEFT || drawAll) { + mLines.push_back( { { pos.x(), pos.y() }, { 0.0f, 0.0f }, color } ); + mLines.push_back( { { pos.x(), pos.y() + size.y() }, { 0.0f, 0.0f }, color } ); } - if(it->border & BORDER_RIGHT || drawAll) - { - mLines.push_back( { { pos.x() + size.x(), pos.y() }, { 0.0f, 0.0f }, color } ); - mLines.push_back( { { mLines.back().pos.x(), pos.y() + size.y() }, { 0.0f, 0.0f }, color } ); + if (it->border & BORDER_RIGHT || drawAll) { + mLines.push_back( { { pos.x() + size.x(), pos.y() }, { 0.0f, 0.0f }, color } ); + mLines.push_back( { { mLines.back().pos.x(), pos.y() + size.y() }, { 0.0f, 0.0f }, color } ); } } } void ComponentGrid::onSizeChanged() { - for(auto it = mCells.cbegin(); it != mCells.cend(); it++) + for (auto it = mCells.cbegin(); it != mCells.cend(); it++) updateCellComponent(*it); updateSeparators(); @@ -207,14 +213,13 @@ const ComponentGrid::GridEntry* ComponentGrid::getCellAt(int x, int y) const { assert(x >= 0 && x < mGridSize.x() && y >= 0 && y < mGridSize.y()); - for(auto it = mCells.cbegin(); it != mCells.cend(); it++) - { + for (auto it = mCells.cbegin(); it != mCells.cend(); it++) { int xmin = it->pos.x(); int xmax = xmin + it->dim.x(); int ymin = it->pos.y(); int ymax = ymin + it->dim.y(); - if(x >= xmin && y >= ymin && x < xmax && y < ymax) + if (x >= xmin && y >= ymin && x < xmax && y < ymax) return &(*it); } @@ -224,41 +229,34 @@ const ComponentGrid::GridEntry* ComponentGrid::getCellAt(int x, int y) const bool ComponentGrid::input(InputConfig* config, Input input) { const GridEntry* cursorEntry = getCellAt(mCursor); - if(cursorEntry && cursorEntry->component->input(config, input)) + if (cursorEntry && cursorEntry->component->input(config, input)) return true; - if(!input.value) + if (!input.value) return false; - if(config->isMappedLike("down", input)) - { + if (config->isMappedLike("down", input)) return moveCursor(Vector2i(0, 1)); - } - if(config->isMappedLike("up", input)) - { + + if (config->isMappedLike("up", input)) return moveCursor(Vector2i(0, -1)); - } - if(config->isMappedLike("left", input)) - { + + if (config->isMappedLike("left", input)) return moveCursor(Vector2i(-1, 0)); - } - if(config->isMappedLike("right", input)) - { + + if (config->isMappedLike("right", input)) return moveCursor(Vector2i(1, 0)); - } return false; } void ComponentGrid::resetCursor() { - if(!mCells.size()) + if (!mCells.size()) return; - for(auto it = mCells.cbegin(); it != mCells.cend(); it++) - { - if(it->canFocus) - { + for (auto it = mCells.cbegin(); it != mCells.cend(); it++) { + if (it->canFocus) { Vector2i origCursor = mCursor; mCursor = it->pos; onCursorMoved(origCursor, mCursor); @@ -272,51 +270,42 @@ bool ComponentGrid::moveCursor(Vector2i dir) assert(dir.x() || dir.y()); const Vector2i origCursor = mCursor; - const GridEntry* currentCursorEntry = getCellAt(mCursor); - Vector2i searchAxis(dir.x() == 0, dir.y() == 0); - while(mCursor.x() >= 0 && mCursor.y() >= 0 && mCursor.x() < mGridSize.x() && mCursor.y() < mGridSize.y()) - { + while (mCursor.x() >= 0 && mCursor.y() >= 0 && mCursor.x() < mGridSize.x() && + mCursor.y() < mGridSize.y()) { mCursor = mCursor + dir; - Vector2i curDirPos = mCursor; - const GridEntry* cursorEntry; - //spread out on search axis+ - while(mCursor.x() < mGridSize.x() && mCursor.y() < mGridSize.y() - && mCursor.x() >= 0 && mCursor.y() >= 0) - { + + // Spread out on search axis+ + while (mCursor.x() < mGridSize.x() && mCursor.y() < mGridSize.y() + && mCursor.x() >= 0 && mCursor.y() >= 0) { cursorEntry = getCellAt(mCursor); - if(cursorEntry && cursorEntry->canFocus && cursorEntry != currentCursorEntry) - { + if (cursorEntry && cursorEntry->canFocus && cursorEntry != currentCursorEntry) { onCursorMoved(origCursor, mCursor); return true; } - mCursor += searchAxis; } - //now again on search axis- + // Now again on search axis- mCursor = curDirPos; - while(mCursor.x() >= 0 && mCursor.y() >= 0 - && mCursor.x() < mGridSize.x() && mCursor.y() < mGridSize.y()) - { + while (mCursor.x() >= 0 && mCursor.y() >= 0 + && mCursor.x() < mGridSize.x() && mCursor.y() < mGridSize.y()) { cursorEntry = getCellAt(mCursor); - if(cursorEntry && cursorEntry->canFocus && cursorEntry != currentCursorEntry) - { + + if (cursorEntry && cursorEntry->canFocus && cursorEntry != currentCursorEntry) { onCursorMoved(origCursor, mCursor); return true; } - mCursor -= searchAxis; } - mCursor = curDirPos; } - //failed to find another focusable element in this direction + // Failed to find another focusable element in this direction. mCursor = origCursor; return false; } @@ -324,14 +313,14 @@ bool ComponentGrid::moveCursor(Vector2i dir) void ComponentGrid::onFocusLost() { const GridEntry* cursorEntry = getCellAt(mCursor); - if(cursorEntry) + if (cursorEntry) cursorEntry->component->onFocusLost(); } void ComponentGrid::onFocusGained() { const GridEntry* cursorEntry = getCellAt(mCursor); - if(cursorEntry) + if (cursorEntry) cursorEntry->component->onFocusGained(); } @@ -343,11 +332,12 @@ bool ComponentGrid::cursorValid() void ComponentGrid::update(int deltaTime) { - // update ALL THE THINGS + // Update ALL THE THINGS. const GridEntry* cursorEntry = getCellAt(mCursor); - for(auto it = mCells.cbegin(); it != mCells.cend(); it++) + for (auto it = mCells.cbegin(); it != mCells.cend(); it++) { - if(it->updateType == UPDATE_ALWAYS || (it->updateType == UPDATE_WHEN_SELECTED && cursorEntry == &(*it))) + if (it->updateType == UPDATE_ALWAYS || + (it->updateType == UPDATE_WHEN_SELECTED && cursorEntry == &(*it))) it->component->update(deltaTime); } } @@ -358,9 +348,8 @@ void ComponentGrid::render(const Transform4x4f& parentTrans) renderChildren(trans); - // draw cell separators - if(mLines.size()) - { + // Draw cell separators. + if (mLines.size()) { Renderer::setMatrix(trans); Renderer::bindTexture(0); Renderer::drawLines(&mLines[0], mLines.size()); @@ -370,18 +359,18 @@ void ComponentGrid::render(const Transform4x4f& parentTrans) void ComponentGrid::textInput(const char* text) { const GridEntry* selectedEntry = getCellAt(mCursor); - if(selectedEntry != NULL && selectedEntry->canFocus) + if (selectedEntry != NULL && selectedEntry->canFocus) selectedEntry->component->textInput(text); } void ComponentGrid::onCursorMoved(Vector2i from, Vector2i to) { const GridEntry* cell = getCellAt(from); - if(cell) + if (cell) cell->component->onFocusLost(); cell = getCellAt(to); - if(cell) + if (cell) cell->component->onFocusGained(); updateHelpPrompts(); @@ -389,10 +378,8 @@ void ComponentGrid::onCursorMoved(Vector2i from, Vector2i to) void ComponentGrid::setCursorTo(const std::shared_ptr& comp) { - for(auto it = mCells.cbegin(); it != mCells.cend(); it++) - { - if(it->component == comp) - { + for (auto it = mCells.cbegin(); it != mCells.cend(); it++) { + if (it->component == comp) { Vector2i oldCursor = mCursor; mCursor = it->pos; onCursorMoved(oldCursor, mCursor); @@ -400,7 +387,7 @@ void ComponentGrid::setCursorTo(const std::shared_ptr& comp) } } - // component not found!! + // Component not found!! assert(false); } @@ -408,32 +395,30 @@ std::vector ComponentGrid::getHelpPrompts() { std::vector prompts; const GridEntry* e = getCellAt(mCursor); - if(e) + if (e) prompts = e->component->getHelpPrompts(); bool canScrollVert = mGridSize.y() > 1; bool canScrollHoriz = mGridSize.x() > 1; - for(auto it = prompts.cbegin(); it != prompts.cend(); it++) - { - if(it->first == "up/down/left/right") - { + for (auto it = prompts.cbegin(); it != prompts.cend(); it++) { + if (it->first == "up/down/left/right") { canScrollHoriz = false; canScrollVert = false; break; - }else if(it->first == "up/down") - { + } + else if (it->first == "up/down") { canScrollVert = false; - }else if(it->first == "left/right") - { + } + else if (it->first == "left/right") { canScrollHoriz = false; } } - if(canScrollHoriz && canScrollVert) + if (canScrollHoriz && canScrollVert) prompts.push_back(HelpPrompt("up/down/left/right", "choose")); - else if(canScrollHoriz) + else if (canScrollHoriz) prompts.push_back(HelpPrompt("left/right", "choose")); - else if(canScrollVert) + else if (canScrollVert) prompts.push_back(HelpPrompt("up/down", "choose")); return prompts; diff --git a/es-core/src/components/ComponentGrid.h b/es-core/src/components/ComponentGrid.h index 5fad30e0e..f6eaf39ea 100644 --- a/es-core/src/components/ComponentGrid.h +++ b/es-core/src/components/ComponentGrid.h @@ -1,3 +1,9 @@ +// +// ComponentGrid.h +// +// Providing basic layout of other components in an X*Y grid. +// + #pragma once #ifndef ES_CORE_COMPONENTS_COMPONENT_GRID_H #define ES_CORE_COMPONENTS_COMPONENT_GRID_H @@ -8,15 +14,13 @@ namespace GridFlags { - enum UpdateType - { + enum UpdateType { UPDATE_ALWAYS, UPDATE_WHEN_SELECTED, UPDATE_NEVER }; - enum Border : unsigned int - { + enum Border : unsigned int { BORDER_NONE = 0, BORDER_TOP = 1, @@ -35,8 +39,14 @@ public: bool removeEntry(const std::shared_ptr& comp); - void setEntry(const std::shared_ptr& comp, const Vector2i& pos, bool canFocus, bool resize = true, - const Vector2i& size = Vector2i(1, 1), unsigned int border = GridFlags::BORDER_NONE, GridFlags::UpdateType updateType = GridFlags::UPDATE_ALWAYS); + void setEntry( + const std::shared_ptr& comp, + const Vector2i& pos, + bool canFocus, + bool resize = true, + const Vector2i& size = Vector2i(1, 1), + unsigned int border = GridFlags::BORDER_NONE, + GridFlags::UpdateType updateType = GridFlags::UPDATE_ALWAYS); void textInput(const char* text) override; bool input(InputConfig* config, Input input) override; @@ -50,8 +60,11 @@ public: float getColWidth(int col); float getRowHeight(int row); - void setColWidthPerc(int col, float width, bool update = true); // if update is false, will not call an onSizeChanged() which triggers a (potentially costly) repositioning + resizing of every element - void setRowHeightPerc(int row, float height, bool update = true); // if update is false, will not call an onSizeChanged() which triggers a (potentially costly) repositioning + resizing of every element + // If update is false, will not call an onSizeChanged() which triggers + // a (potentially costly) repositioning + resizing of every element. + void setColWidthPerc(int col, float width, bool update = true); + // Dito. + void setRowHeightPerc(int row, float height, bool update = true); bool moveCursor(Vector2i dir); void setCursorTo(const std::shared_ptr& comp); @@ -84,7 +97,8 @@ private: GridEntry(const Vector2i& p = Vector2i::Zero(), const Vector2i& d = Vector2i::Zero(), const std::shared_ptr& cmp = nullptr, bool f = false, bool r = true, - GridFlags::UpdateType u = GridFlags::UPDATE_ALWAYS, unsigned int b = GridFlags::BORDER_NONE) : + GridFlags::UpdateType u = GridFlags::UPDATE_ALWAYS, unsigned int b = + GridFlags::BORDER_NONE) : pos(p), dim(d), component(cmp), canFocus(f), resize(r), updateType(u), border(b) {}; @@ -99,12 +113,13 @@ private: std::vector mLines; - // Update position & size + // Update position & size. void updateCellComponent(const GridEntry& cell); void updateSeparators(); const GridEntry* getCellAt(int x, int y) const; - inline const GridEntry* getCellAt(const Vector2i& pos) const { return getCellAt(pos.x(), pos.y()); } + inline const GridEntry* getCellAt(const Vector2i& pos) const + { return getCellAt(pos.x(), pos.y()); } Vector2i mGridSize; diff --git a/es-core/src/components/ComponentList.cpp b/es-core/src/components/ComponentList.cpp index 1ae1c6756..386e8440c 100644 --- a/es-core/src/components/ComponentList.cpp +++ b/es-core/src/components/ComponentList.cpp @@ -1,8 +1,15 @@ +// +// ComponentList.cpp +// +// Used to lay out and navigate lists in GUI menus. +// + #include "components/ComponentList.h" #define TOTAL_HORIZONTAL_PADDING_PX 20 -ComponentList::ComponentList(Window* window) : IList(window, LIST_SCROLL_STYLE_SLOW, LIST_NEVER_LOOP) +ComponentList::ComponentList(Window* window) : IList(window, LIST_SCROLL_STYLE_SLOW, LIST_NEVER_LOOP) { mSelectorBarOffset = 0; mCameraOffset = 0; @@ -18,14 +25,14 @@ void ComponentList::addRow(const ComponentListRow& row, bool setCursorHere) this->add(e); - for(auto it = mEntries.back().data.elements.cbegin(); it != mEntries.back().data.elements.cend(); it++) + for (auto it = mEntries.back().data.elements.cbegin(); + it != mEntries.back().data.elements.cend(); it++) addChild(it->component.get()); updateElementSize(mEntries.back().data); updateElementPosition(mEntries.back().data); - if(setCursorHere) - { + if (setCursorHere) { mCursor = (int)mEntries.size() - 1; onCursorChanged(CURSOR_STOPPED); } @@ -33,8 +40,7 @@ void ComponentList::addRow(const ComponentListRow& row, bool setCursorHere) void ComponentList::onSizeChanged() { - for(auto it = mEntries.cbegin(); it != mEntries.cend(); it++) - { + for (auto it = mEntries.cbegin(); it != mEntries.cend(); it++) { updateElementSize(it->data); updateElementPosition(it->data); } @@ -54,38 +60,33 @@ void ComponentList::onFocusGained() bool ComponentList::input(InputConfig* config, Input input) { - if(size() == 0) + if (size() == 0) return false; - // give it to the current row's input handler - if(mEntries.at(mCursor).data.input_handler) - { - if(mEntries.at(mCursor).data.input_handler(config, input)) + // Give it to the current row's input handler. + if (mEntries.at(mCursor).data.input_handler) { + if (mEntries.at(mCursor).data.input_handler(config, input)) return true; - }else{ - // no input handler assigned, do the default, which is to give it to the rightmost element in the row + } + else { + // No input handler assigned, do the default, which is to give it + // to the rightmost element in the row. auto& row = mEntries.at(mCursor).data; - if(row.elements.size()) - { - if(row.elements.back().component->input(config, input)) + if (row.elements.size()) { + if (row.elements.back().component->input(config, input)) return true; } } - // input handler didn't consume the input - try to scroll - if(config->isMappedLike("up", input)) - { + // Input handler didn't consume the input - try to scroll. + if (config->isMappedLike("up", input)) return listInput(input.value != 0 ? -1 : 0); - }else if(config->isMappedLike("down", input)) - { + else if (config->isMappedLike("down", input)) return listInput(input.value != 0 ? 1 : 0); - - }else if(config->isMappedLike("leftshoulder", input)) - { + else if (config->isMappedLike("leftshoulder", input)) return listInput(input.value != 0 ? -6 : 0); - }else if(config->isMappedLike("rightshoulder", input)){ + else if (config->isMappedLike("rightshoulder", input)) return listInput(input.value != 0 ? 6 : 0); - } return false; } @@ -94,36 +95,33 @@ void ComponentList::update(int deltaTime) { listUpdate(deltaTime); - if(size()) - { - // update our currently selected row - for(auto it = mEntries.at(mCursor).data.elements.cbegin(); it != mEntries.at(mCursor).data.elements.cend(); it++) + if (size()) { + // Update our currently selected row. + for (auto it = mEntries.at(mCursor).data.elements.cbegin(); + it != mEntries.at(mCursor).data.elements.cend(); it++) it->component->update(deltaTime); } } void ComponentList::onCursorChanged(const CursorState& state) { - // update the selector bar position - // in the future this might be animated + // Update the selector bar position. + // In the future this might be animated. mSelectorBarOffset = 0; - for(int i = 0; i < mCursor; i++) - { + for (int i = 0; i < mCursor; i++) mSelectorBarOffset += getRowHeight(mEntries.at(i).data); - } updateCameraOffset(); - // this is terribly inefficient but we don't know what we came from so... - if(size()) - { - for(auto it = mEntries.cbegin(); it != mEntries.cend(); it++) + // This is terribly inefficient but we don't know what we came from so... + if (size()) { + for (auto it = mEntries.cbegin(); it != mEntries.cend(); it++) it->data.elements.back().component->onFocusLost(); mEntries.at(mCursor).data.elements.back().component->onFocusGained(); } - if(mCursorChangedCallback) + if (mCursorChangedCallback) mCursorChangedCallback(state); updateHelpPrompts(); @@ -131,110 +129,109 @@ void ComponentList::onCursorChanged(const CursorState& state) void ComponentList::updateCameraOffset() { - // move the camera to scroll + // Move the camera to scroll. const float totalHeight = getTotalRowHeight(); - if(totalHeight > mSize.y()) - { - float target = mSelectorBarOffset + getRowHeight(mEntries.at(mCursor).data)/2 - (mSize.y() / 2); + if (totalHeight > mSize.y()) { + float target = mSelectorBarOffset + getRowHeight(mEntries.at(mCursor).data)/2 - + (mSize.y() / 2); - // clamp it + // Clamp it. mCameraOffset = 0; unsigned int i = 0; - while(mCameraOffset < target && i < mEntries.size()) - { + while (mCameraOffset < target && i < mEntries.size()) { mCameraOffset += getRowHeight(mEntries.at(i).data); i++; } - if(mCameraOffset < 0) + if (mCameraOffset < 0) mCameraOffset = 0; - else if(mCameraOffset + mSize.y() > totalHeight) + else if (mCameraOffset + mSize.y() > totalHeight) mCameraOffset = totalHeight - mSize.y(); - }else{ + } + else { mCameraOffset = 0; } } void ComponentList::render(const Transform4x4f& parentTrans) { - if(!size()) + if (!size()) return; Transform4x4f trans = parentTrans * getTransform(); - // clip everything to be inside our bounds + // Clip everything to be inside our bounds. Vector3f dim(mSize.x(), mSize.y(), 0); dim = trans * dim - trans.translation(); Renderer::pushClipRect(Vector2i((int)trans.translation().x(), (int)trans.translation().y()), Vector2i((int)Math::round(dim.x()), (int)Math::round(dim.y() + 1))); - // scroll the camera + // Scroll the camera. trans.translate(Vector3f(0, -Math::round(mCameraOffset), 0)); - // draw our entries + // Draw our entries. std::vector drawAfterCursor; bool drawAll; - for(unsigned int i = 0; i < mEntries.size(); i++) - { + for (unsigned int i = 0; i < mEntries.size(); i++) { auto& entry = mEntries.at(i); drawAll = !mFocused || i != (unsigned int)mCursor; - for(auto it = entry.data.elements.cbegin(); it != entry.data.elements.cend(); it++) - { - if(drawAll || it->invert_when_selected) - { + for (auto it = entry.data.elements.cbegin(); it != entry.data.elements.cend(); it++) { + if (drawAll || it->invert_when_selected) it->component->render(trans); - }else{ + else drawAfterCursor.push_back(it->component.get()); - } } } - // custom rendering + // Custom rendering. Renderer::setMatrix(trans); - // draw selector bar - if(mFocused) - { - // inversion: src * (1 - dst) + dst * 0 = where src = 1 - // need a function that goes roughly 0x777777 -> 0xFFFFFF + // Draw selector bar. + if (mFocused) { + // Inversion: src * (1 - dst) + dst * 0 = where src = 1 + // Need a function that goes roughly 0x777777 -> 0xFFFFFF // and 0xFFFFFF -> 0x777777 // (1 - dst) + 0x77 const float selectedRowHeight = getRowHeight(mEntries.at(mCursor).data); - Renderer::drawRect(0.0f, mSelectorBarOffset, mSize.x(), selectedRowHeight, 0xFFFFFFFF, 0xFFFFFFFF, false, Renderer::Blend::ONE_MINUS_DST_COLOR, Renderer::Blend::ZERO); - Renderer::drawRect(0.0f, mSelectorBarOffset, mSize.x(), selectedRowHeight, 0x777777FF, 0x777777FF, false, Renderer::Blend::ONE, Renderer::Blend::ONE); + Renderer::drawRect(0.0f, mSelectorBarOffset, mSize.x(), selectedRowHeight, + 0xFFFFFFFF, 0xFFFFFFFF, false, Renderer::Blend::ONE_MINUS_DST_COLOR, + Renderer::Blend::ZERO); + Renderer::drawRect(0.0f, mSelectorBarOffset, mSize.x(), selectedRowHeight, + 0x777777FF, 0x777777FF, false, Renderer::Blend::ONE, + Renderer::Blend::ONE); - // hack to draw 2px dark on left/right of the bar - Renderer::drawRect(0.0f, mSelectorBarOffset, 2.0f, selectedRowHeight, 0x878787FF, 0x878787FF); - Renderer::drawRect(mSize.x() - 2.0f, mSelectorBarOffset, 2.0f, selectedRowHeight, 0x878787FF, 0x878787FF); + // Hack to draw 2px dark on left/right of the bar. + Renderer::drawRect(0.0f, mSelectorBarOffset, 2.0f, selectedRowHeight, + 0x878787FF, 0x878787FF); + Renderer::drawRect(mSize.x() - 2.0f, mSelectorBarOffset, 2.0f, selectedRowHeight, + 0x878787FF, 0x878787FF); - for(auto it = drawAfterCursor.cbegin(); it != drawAfterCursor.cend(); it++) + for (auto it = drawAfterCursor.cbegin(); it != drawAfterCursor.cend(); it++) (*it)->render(trans); - // reset matrix if one of these components changed it - if(drawAfterCursor.size()) + // Reset matrix if one of these components changed it. + if (drawAfterCursor.size()) Renderer::setMatrix(trans); } - // draw separators + // Draw separators. float y = 0; - for(unsigned int i = 0; i < mEntries.size(); i++) - { + for (unsigned int i = 0; i < mEntries.size(); i++) { Renderer::drawRect(0.0f, y, mSize.x(), 1.0f, 0xC6C7C6FF, 0xC6C7C6FF); y += getRowHeight(mEntries.at(i).data); } - Renderer::drawRect(0.0f, y, mSize.x(), 1.0f, 0xC6C7C6FF, 0xC6C7C6FF); + Renderer::drawRect(0.0f, y, mSize.x(), 1.0f, 0xC6C7C6FF, 0xC6C7C6FF); Renderer::popClipRect(); } float ComponentList::getRowHeight(const ComponentListRow& row) const { - // returns the highest component height found in the row + // Returns the highest component height found in the row. float height = 0; - for(unsigned int i = 0; i < row.elements.size(); i++) - { - if(row.elements.at(i).component->getSize().y() > height) + for (unsigned int i = 0; i < row.elements.size(); i++) { + if (row.elements.at(i).component->getSize().y() > height) height = row.elements.at(i).component->getSize().y(); } @@ -244,10 +241,8 @@ float ComponentList::getRowHeight(const ComponentListRow& row) const float ComponentList::getTotalRowHeight() const { float height = 0; - for(auto it = mEntries.cbegin(); it != mEntries.cend(); it++) - { + for (auto it = mEntries.cbegin(); it != mEntries.cend(); it++) height += getRowHeight(it->data); - } return height; } @@ -255,20 +250,17 @@ float ComponentList::getTotalRowHeight() const void ComponentList::updateElementPosition(const ComponentListRow& row) { float yOffset = 0; - for(auto it = mEntries.cbegin(); it != mEntries.cend() && &it->data != &row; it++) - { + for (auto it = mEntries.cbegin(); it != mEntries.cend() && &it->data != &row; it++) yOffset += getRowHeight(it->data); - } - // assumes updateElementSize has already been called + // Assumes updateElementSize has already been called. float rowHeight = getRowHeight(row); float x = TOTAL_HORIZONTAL_PADDING_PX / 2; - for(unsigned int i = 0; i < row.elements.size(); i++) - { + for (unsigned int i = 0; i < row.elements.size(); i++) { const auto comp = row.elements.at(i).component; - // center vertically + // Center vertically. comp->setPosition(x, (rowHeight - comp->getSize().y()) / 2 + yOffset); x += comp->getSize().x(); } @@ -279,25 +271,22 @@ void ComponentList::updateElementSize(const ComponentListRow& row) float width = mSize.x() - TOTAL_HORIZONTAL_PADDING_PX; std::vector< std::shared_ptr > resizeVec; - for(auto it = row.elements.cbegin(); it != row.elements.cend(); it++) - { - if(it->resize_width) + for (auto it = row.elements.cbegin(); it != row.elements.cend(); it++) { + if (it->resize_width) resizeVec.push_back(it->component); else width -= it->component->getSize().x(); } - // redistribute the "unused" width equally among the components with resize_width set to true + // Redistribute the "unused" width equally among the components with resize_width set to true. width = width / resizeVec.size(); - for(auto it = resizeVec.cbegin(); it != resizeVec.cend(); it++) - { + for (auto it = resizeVec.cbegin(); it != resizeVec.cend(); it++) (*it)->setSize(width, (*it)->getSize().y()); - } } void ComponentList::textInput(const char* text) { - if(!size()) + if (!size()) return; mEntries.at(mCursor).data.elements.back().component->textInput(text); @@ -305,24 +294,21 @@ void ComponentList::textInput(const char* text) std::vector ComponentList::getHelpPrompts() { - if(!size()) + if (!size()) return std::vector(); - std::vector prompts = mEntries.at(mCursor).data.elements.back().component->getHelpPrompts(); + std::vector prompts = + mEntries.at(mCursor).data.elements.back().component->getHelpPrompts(); - if(size() > 1) - { + if (size() > 1) { bool addMovePrompt = true; - for(auto it = prompts.cbegin(); it != prompts.cend(); it++) - { - if(it->first == "up/down" || it->first == "up/down/left/right") - { + for (auto it = prompts.cbegin(); it != prompts.cend(); it++) { + if (it->first == "up/down" || it->first == "up/down/left/right") { addMovePrompt = false; break; } } - - if(addMovePrompt) + if (addMovePrompt) prompts.push_back(HelpPrompt("up/down", "choose")); } diff --git a/es-core/src/components/ComponentList.h b/es-core/src/components/ComponentList.h index c5c0f9c2e..27dd56f75 100644 --- a/es-core/src/components/ComponentList.h +++ b/es-core/src/components/ComponentList.h @@ -1,13 +1,23 @@ +// +// ComponentList.h +// +// Used to lay out and navigate lists in GUI menus. +// + #pragma once #ifndef ES_CORE_COMPONENTS_COMPONENT_LIST_H #define ES_CORE_COMPONENTS_COMPONENT_LIST_H #include "IList.h" -struct ComponentListElement -{ - ComponentListElement(const std::shared_ptr& cmp = nullptr, bool resize_w = true, bool inv = true) - : component(cmp), resize_width(resize_w), invert_when_selected(inv) { }; +struct ComponentListElement { + ComponentListElement( + const std::shared_ptr& cmp = nullptr, + bool resize_w = true, + bool inv = true) + : component(cmp), + resize_width(resize_w), + invert_when_selected(inv) {}; std::shared_ptr component; bool resize_width; @@ -18,23 +28,24 @@ struct ComponentListRow { std::vector elements; - // The input handler is called when the user enters any input while this row is highlighted (including up/down). + // The input handler is called when the user enters any input while this row is + // highlighted (including up/down). // Return false to let the list try to use it or true if the input has been consumed. - // If no input handler is supplied (input_handler == nullptr), the default behavior is to forward the input to - // the rightmost element in the currently selected row. + // If no input handler is supplied (input_handler == nullptr), the default behavior is + // to forward the input to the rightmost element in the currently selected row. std::function input_handler; - inline void addElement(const std::shared_ptr& component, bool resize_width, bool invert_when_selected = true) + inline void addElement(const std::shared_ptr& component, + bool resize_width, bool invert_when_selected = true) { elements.push_back(ComponentListElement(component, resize_width, invert_when_selected)); } - // Utility method for making an input handler for "when the users presses A on this, do func." + // Utility method for making an input handler for "when the users presses A on this, do func". inline void makeAcceptInputHandler(const std::function& func) { input_handler = [func](InputConfig* config, Input input) -> bool { - if(config->isMappedTo("a", input) && input.value != 0) - { + if(config->isMappedTo("a", input) && input.value != 0) { func(); return true; } @@ -66,8 +77,10 @@ public: float getTotalRowHeight() const; inline float getRowHeight(int row) const { return getRowHeight(mEntries.at(row).data); } - inline void setCursorChangedCallback(const std::function& callback) { mCursorChangedCallback = callback; }; - inline const std::function& getCursorChangedCallback() const { return mCursorChangedCallback; }; + inline void setCursorChangedCallback(const std::function& callback) + { mCursorChangedCallback = callback; }; + inline const std::function& getCursorChangedCallback() const + { return mCursorChangedCallback; }; protected: void onCursorChanged(const CursorState& state) override; diff --git a/es-core/src/components/DateTimeComponent.cpp b/es-core/src/components/DateTimeComponent.cpp index 2883b9056..ee4ac7428 100644 --- a/es-core/src/components/DateTimeComponent.cpp +++ b/es-core/src/components/DateTimeComponent.cpp @@ -1,16 +1,32 @@ +// +// DateTimeComponent.cpp +// +// Date and time component. +// + #include "components/DateTimeComponent.h" #include "utils/StringUtil.h" #include "Log.h" #include "Settings.h" -DateTimeComponent::DateTimeComponent(Window* window) : TextComponent(window), mDisplayRelative(false) +DateTimeComponent::DateTimeComponent(Window* window) + : TextComponent(window), mDisplayRelative(false) { setFormat("%m/%d/%Y"); } -DateTimeComponent::DateTimeComponent(Window* window, const std::string& text, const std::shared_ptr& font, unsigned int color, Alignment align, - Vector3f pos, Vector2f size, unsigned int bgcolor) : TextComponent(window, text, font, color, align, pos, size, bgcolor), mDisplayRelative(false) +DateTimeComponent::DateTimeComponent( + Window* window, + const std::string& text, + const std::shared_ptr& font, + unsigned int color, + Alignment align, + Vector3f pos, + Vector2f size, + unsigned int bgcolor) + : TextComponent(window, text, font, color, align, pos, size, bgcolor), + mDisplayRelative(false) { setFormat("%m/%d/%Y"); } @@ -41,14 +57,13 @@ void DateTimeComponent::setDisplayRelative(bool displayRelative) void DateTimeComponent::onTextChanged() { mText = getDisplayString(); - TextComponent::onTextChanged(); } std::string DateTimeComponent::getDisplayString() const { if (mDisplayRelative) { - //relative time + // Relative time. if(mTime.getTime() == 0) return "never"; @@ -81,7 +96,8 @@ void DateTimeComponent::render(const Transform4x4f& parentTrans) } -void DateTimeComponent::applyTheme(const std::shared_ptr& theme, const std::string& view, const std::string& element, unsigned int properties) +void DateTimeComponent::applyTheme(const std::shared_ptr& theme, + const std::string& view, const std::string& element, unsigned int properties) { GuiComponent::applyTheme(theme, view, element, properties); @@ -106,8 +122,7 @@ void DateTimeComponent::applyTheme(const std::shared_ptr& theme, cons setRenderBackground(true); } - if(properties & ALIGNMENT && elem->has("alignment")) - { + if(properties & ALIGNMENT && elem->has("alignment")) { std::string str = elem->get("alignment"); if(str == "left") setHorizontalAlignment(ALIGN_LEFT); diff --git a/es-core/src/components/DateTimeComponent.h b/es-core/src/components/DateTimeComponent.h index 55d70ca5f..69ac36e7d 100644 --- a/es-core/src/components/DateTimeComponent.h +++ b/es-core/src/components/DateTimeComponent.h @@ -1,3 +1,9 @@ +// +// DateTimeComponent.h +// +// Date and time component. +// + #pragma once #ifndef ES_CORE_COMPONENTS_DATE_TIME_COMPONENT_H #define ES_CORE_COMPONENTS_DATE_TIME_COMPONENT_H @@ -12,8 +18,15 @@ class DateTimeComponent : public TextComponent { public: DateTimeComponent(Window* window); - DateTimeComponent(Window* window, const std::string& text, const std::shared_ptr& font, unsigned int color = 0x000000FF, Alignment align = ALIGN_LEFT, - Vector3f pos = Vector3f::Zero(), Vector2f size = Vector2f::Zero(), unsigned int bgcolor = 0x00000000); + DateTimeComponent( + Window* window, + const std::string& text, + const std::shared_ptr& font, + unsigned int color = 0x000000FF, + Alignment align = ALIGN_LEFT, + Vector3f pos = Vector3f::Zero(), + Vector2f size = Vector2f::Zero(), + unsigned int bgcolor = 0x00000000); void render(const Transform4x4f& parentTrans) override; @@ -23,7 +36,8 @@ public: void setFormat(const std::string& format); void setDisplayRelative(bool displayRelative); - virtual void applyTheme(const std::shared_ptr& theme, const std::string& view, const std::string& element, unsigned int properties) override; + virtual void applyTheme(const std::shared_ptr& theme, const std::string& view, + const std::string& element, unsigned int properties) override; protected: void onTextChanged() override; diff --git a/es-core/src/components/DateTimeEditComponent.cpp b/es-core/src/components/DateTimeEditComponent.cpp index 91787c18d..655a0082d 100644 --- a/es-core/src/components/DateTimeEditComponent.cpp +++ b/es-core/src/components/DateTimeEditComponent.cpp @@ -1,11 +1,26 @@ +// +// DateTimeEditComponent.cpp +// +// Date and time edit component. +// + #include "components/DateTimeEditComponent.h" #include "resources/Font.h" #include "utils/StringUtil.h" -DateTimeEditComponent::DateTimeEditComponent(Window* window, DisplayMode dispMode) : GuiComponent(window), - mEditing(false), mEditIndex(0), mDisplayMode(dispMode), mRelativeUpdateAccumulator(0), - mColor(0x777777FF), mFont(Font::get(FONT_SIZE_SMALL, FONT_PATH_LIGHT)), mUppercase(false), mAutoSize(true) +DateTimeEditComponent::DateTimeEditComponent( + Window* window, + DisplayMode dispMode) + : GuiComponent(window), + mEditing(false), + mEditIndex(0), + mDisplayMode(dispMode), + mRelativeUpdateAccumulator(0), + mColor(0x777777FF), + mFont(Font::get(FONT_SIZE_SMALL, FONT_PATH_LIGHT)), + mUppercase(false), + mAutoSize(true) { updateTextCache(); } @@ -18,22 +33,19 @@ void DateTimeEditComponent::setDisplayMode(DisplayMode mode) bool DateTimeEditComponent::input(InputConfig* config, Input input) { - if(input.value == 0) + if (input.value == 0) return false; - if(config->isMappedTo("a", input)) - { - if(mDisplayMode != DISP_RELATIVE_TO_NOW) //don't allow editing for relative times + if (config->isMappedTo("a", input)) { + if (mDisplayMode != DISP_RELATIVE_TO_NOW) // Don't allow editing for relative times. mEditing = !mEditing; - if(mEditing) - { - //started editing + if (mEditing) { + // Started editing. mTimeBeforeEdit = mTime; - //initialize to now if unset - if(mTime.getTime() == Utils::Time::NOT_A_DATE_TIME) - { + // Initialize to now if unset. + if (mTime.getTime() == Utils::Time::NOT_A_DATE_TIME) { mTime = Utils::Time::now(); updateTextCache(); } @@ -42,10 +54,8 @@ bool DateTimeEditComponent::input(InputConfig* config, Input input) return true; } - if(mEditing) - { - if(config->isMappedTo("b", input)) - { + if (mEditing) { + if (config->isMappedTo("b", input)) { mEditing = false; mTime = mTimeBeforeEdit; updateTextCache(); @@ -53,47 +63,45 @@ bool DateTimeEditComponent::input(InputConfig* config, Input input) } int incDir = 0; - if(config->isMappedLike("up", input) || config->isMappedLike("leftshoulder", input)) + if (config->isMappedLike("up", input) || config->isMappedLike("leftshoulder", input)) incDir = 1; - else if(config->isMappedLike("down", input) || config->isMappedLike("rightshoulder", input)) + else if (config->isMappedLike("down", input) || config->isMappedLike("rightshoulder", input)) incDir = -1; - if(incDir != 0) - { + if (incDir != 0) { tm new_tm = mTime; - if(mEditIndex == 0) - { + if (mEditIndex == 0) { new_tm.tm_mon += incDir; - if(new_tm.tm_mon > 11) + if (new_tm.tm_mon > 11) new_tm.tm_mon = 0; - else if(new_tm.tm_mon < 0) + else if (new_tm.tm_mon < 0) new_tm.tm_mon = 11; } - else if(mEditIndex == 1) - { - const int days_in_month = Utils::Time::daysInMonth(new_tm.tm_year + 1900, new_tm.tm_mon + 1); + else if (mEditIndex == 1) { + const int days_in_month = + Utils::Time::daysInMonth(new_tm.tm_year + 1900, new_tm.tm_mon + 1); new_tm.tm_mday += incDir; - if(new_tm.tm_mday > days_in_month) + if (new_tm.tm_mday > days_in_month) new_tm.tm_mday = 1; - else if(new_tm.tm_mday < 1) + else if (new_tm.tm_mday < 1) new_tm.tm_mday = days_in_month; } - else if(mEditIndex == 2) - { + else if (mEditIndex == 2) { new_tm.tm_year += incDir; - if(new_tm.tm_year < 0) + if (new_tm.tm_year < 0) new_tm.tm_year = 0; } - //validate day - const int days_in_month = Utils::Time::daysInMonth(new_tm.tm_year + 1900, new_tm.tm_mon + 1); - if(new_tm.tm_mday > days_in_month) + // Validate day. + const int days_in_month = + Utils::Time::daysInMonth(new_tm.tm_year + 1900, new_tm.tm_mon + 1); + if (new_tm.tm_mday > days_in_month) new_tm.tm_mday = days_in_month; mTime = new_tm; @@ -102,18 +110,16 @@ bool DateTimeEditComponent::input(InputConfig* config, Input input) return true; } - if(config->isMappedLike("right", input)) - { + if (config->isMappedLike("right", input)) { mEditIndex++; - if(mEditIndex >= (int)mCursorBoxes.size()) + if (mEditIndex >= (int)mCursorBoxes.size()) mEditIndex--; return true; } - if(config->isMappedLike("left", input)) - { + if (config->isMappedLike("left", input)) { mEditIndex--; - if(mEditIndex < 0) + if (mEditIndex < 0) mEditIndex++; return true; } @@ -124,11 +130,9 @@ bool DateTimeEditComponent::input(InputConfig* config, Input input) void DateTimeEditComponent::update(int deltaTime) { - if(mDisplayMode == DISP_RELATIVE_TO_NOW) - { + if (mDisplayMode == DISP_RELATIVE_TO_NOW) { mRelativeUpdateAccumulator += deltaTime; - if(mRelativeUpdateAccumulator > 1000) - { + if (mRelativeUpdateAccumulator > 1000) { mRelativeUpdateAccumulator = 0; updateTextCache(); } @@ -141,9 +145,8 @@ void DateTimeEditComponent::render(const Transform4x4f& parentTrans) { Transform4x4f trans = parentTrans * getTransform(); - if(mTextCache) - { - // vertically center + if (mTextCache) { + // Vertically center. Vector3f off(0, (mSize.y() - mTextCache->metrics.size.y()) / 2, 0); trans.translate(off); @@ -154,13 +157,11 @@ void DateTimeEditComponent::render(const Transform4x4f& parentTrans) mTextCache->setColor((mColor & 0xFFFFFF00) | getOpacity()); font->renderTextCache(mTextCache.get()); - if(mEditing) - { - if(mEditIndex >= 0 && (unsigned int)mEditIndex < mCursorBoxes.size()) - { + if (mEditing) { + if (mEditIndex >= 0 && (unsigned int)mEditIndex < mCursorBoxes.size()) Renderer::drawRect(mCursorBoxes[mEditIndex][0], mCursorBoxes[mEditIndex][1], - mCursorBoxes[mEditIndex][2], mCursorBoxes[mEditIndex][3], 0x00000022, 0x00000022); - } + mCursorBoxes[mEditIndex][2], mCursorBoxes[mEditIndex][3], + 0x00000022, 0x00000022); } } } @@ -178,14 +179,12 @@ std::string DateTimeEditComponent::getValue() const DateTimeEditComponent::DisplayMode DateTimeEditComponent::getCurrentDisplayMode() const { - /*if(mEditing) - { - if(mDisplayMode == DISP_RELATIVE_TO_NOW) - { - //TODO: if time component == 00:00:00, return DISP_DATE, else return DISP_DATE_TIME - return DISP_DATE; - } - }*/ +// if (mEditing) { +// if (mDisplayMode == DISP_RELATIVE_TO_NOW) { +// // TODO: if time component == 00:00:00, return DISP_DATE, else return DISP_DATE_TIME. +// return DISP_DATE; +// } +// } return mDisplayMode; } @@ -193,20 +192,20 @@ DateTimeEditComponent::DisplayMode DateTimeEditComponent::getCurrentDisplayMode( std::string DateTimeEditComponent::getDisplayString(DisplayMode mode) const { std::string fmt; - switch(mode) - { - case DISP_DATE: + switch (mode) { + case DISP_DATE: { fmt = "%m/%d/%Y"; break; - case DISP_DATE_TIME: - if(mTime.getTime() == 0) + } + case DISP_DATE_TIME: { + if (mTime.getTime() == 0) return "unknown"; fmt = "%m/%d/%Y %H:%M:%S"; break; - case DISP_RELATIVE_TO_NOW: - { - //relative time - if(mTime.getTime() == 0) + } + case DISP_RELATIVE_TO_NOW: { + // Relative time. + if (mTime.getTime() == 0) return "never"; Utils::Time::DateTime now(Utils::Time::now()); @@ -214,14 +213,16 @@ std::string DateTimeEditComponent::getDisplayString(DisplayMode mode) const char buf[64]; - if(dur.getDays() > 0) + if (dur.getDays() > 0) sprintf(buf, "%d day%s ago", dur.getDays(), (dur.getDays() > 1) ? "s" : ""); - else if(dur.getHours() > 0) + else if (dur.getHours() > 0) sprintf(buf, "%d hour%s ago", dur.getHours(), (dur.getHours() > 1) ? "s" : ""); - else if(dur.getMinutes() > 0) - sprintf(buf, "%d minute%s ago", dur.getMinutes(), (dur.getMinutes() > 1) ? "s" : ""); + else if (dur.getMinutes() > 0) + sprintf(buf, "%d minute%s ago", dur.getMinutes(), + (dur.getMinutes() > 1) ? "s" : ""); else - sprintf(buf, "%d second%s ago", dur.getSeconds(), (dur.getSeconds() > 1) ? "s" : ""); + sprintf(buf, "%d second%s ago", dur.getSeconds(), + (dur.getSeconds() > 1) ? "s" : ""); return std::string(buf); } @@ -233,7 +234,7 @@ std::string DateTimeEditComponent::getDisplayString(DisplayMode mode) const std::shared_ptr DateTimeEditComponent::getFont() const { - if(mFont) + if (mFont) return mFont; return Font::get(FONT_SIZE_MEDIUM); @@ -242,50 +243,51 @@ std::shared_ptr DateTimeEditComponent::getFont() const void DateTimeEditComponent::updateTextCache() { DisplayMode mode = getCurrentDisplayMode(); - const std::string dispString = mUppercase ? Utils::String::toUpper(getDisplayString(mode)) : getDisplayString(mode); + const std::string dispString = mUppercase ? + Utils::String::toUpper(getDisplayString(mode)) : getDisplayString(mode); std::shared_ptr font = getFont(); mTextCache = std::unique_ptr(font->buildTextCache(dispString, 0, 0, mColor)); - if(mAutoSize) - { + if (mAutoSize) { mSize = mTextCache->metrics.size; mAutoSize = false; - if(getParent()) + if (getParent()) getParent()->onSizeChanged(); } - //set up cursor positions + // Set up cursor positions. mCursorBoxes.clear(); - if(dispString.empty() || mode == DISP_RELATIVE_TO_NOW) + if (dispString.empty() || mode == DISP_RELATIVE_TO_NOW) return; - //month + // Month. Vector2f start(0, 0); Vector2f end = font->sizeText(dispString.substr(0, 2)); Vector2f diff = end - start; mCursorBoxes.push_back(Vector4f(start[0], start[1], diff[0], diff[1])); - //day + // Day. start[0] = font->sizeText(dispString.substr(0, 3)).x(); end = font->sizeText(dispString.substr(0, 5)); diff = end - start; mCursorBoxes.push_back(Vector4f(start[0], start[1], diff[0], diff[1])); - //year + // Year. start[0] = font->sizeText(dispString.substr(0, 6)).x(); end = font->sizeText(dispString.substr(0, 10)); diff = end - start; mCursorBoxes.push_back(Vector4f(start[0], start[1], diff[0], diff[1])); - //if mode == DISP_DATE_TIME do times too but I don't wanna do the logic for editing times because no one will ever use it so screw it + // The logic for handling time for 'mode = DISP_DATE_TIME' is missing, but + // nobody will use it anyway so it's not implemented. } void DateTimeEditComponent::setColor(unsigned int color) { mColor = color; - if(mTextCache) + if (mTextCache) mTextCache->setColor(color); } @@ -307,26 +309,28 @@ void DateTimeEditComponent::setUppercase(bool uppercase) updateTextCache(); } -void DateTimeEditComponent::applyTheme(const std::shared_ptr& theme, const std::string& view, const std::string& element, unsigned int properties) +void DateTimeEditComponent::applyTheme(const std::shared_ptr& theme, + const std::string& view, const std::string& element, unsigned int properties) { const ThemeData::ThemeElement* elem = theme->getElement(view, element, "datetime"); - if(!elem) + + if (!elem) return; // We set mAutoSize BEFORE calling GuiComponent::applyTheme because it calls // setSize(), which will call updateTextCache(), which will reset mSize if // mAutoSize == true, ignoring the theme's value. - if(properties & ThemeFlags::SIZE) + if (properties & ThemeFlags::SIZE) mAutoSize = !elem->has("size"); GuiComponent::applyTheme(theme, view, element, properties); using namespace ThemeFlags; - if(properties & COLOR && elem->has("color")) + if (properties & COLOR && elem->has("color")) setColor(elem->get("color")); - if(properties & FORCE_UPPERCASE && elem->has("forceUppercase")) + if (properties & FORCE_UPPERCASE && elem->has("forceUppercase")) setUppercase(elem->get("forceUppercase")); setFont(Font::getFromTheme(elem, properties, mFont)); diff --git a/es-core/src/components/DateTimeEditComponent.h b/es-core/src/components/DateTimeEditComponent.h index 55a010a1b..3e90fa268 100644 --- a/es-core/src/components/DateTimeEditComponent.h +++ b/es-core/src/components/DateTimeEditComponent.h @@ -1,3 +1,9 @@ +// +// DateTimeEditComponent.h +// +// Date and time edit component. +// + #pragma once #ifndef ES_CORE_COMPONENTS_DATE_TIME_EDIT_COMPONENT_H #define ES_CORE_COMPONENTS_DATE_TIME_EDIT_COMPONENT_H @@ -11,8 +17,7 @@ class TextCache; class DateTimeEditComponent : public GuiComponent { public: - enum DisplayMode - { + enum DisplayMode{ DISP_DATE, DISP_DATE_TIME, DISP_RELATIVE_TO_NOW @@ -31,15 +36,21 @@ public: // Set how the point in time will be displayed: // * DISP_DATE - only display the date. // * DISP_DATE_TIME - display both the date and the time on that date. - // * DISP_RELATIVE_TO_NOW - intelligently display the point in time relative to right now (e.g. "5 secs ago", "3 minutes ago", "1 day ago". Automatically updates as time marches on. + // * DISP_RELATIVE_TO_NOW - intelligently display the point in time relative to + // right now (e.g. "5 secs ago", "3 minutes ago", "1 day ago". + // Automatically updates as time marches on. // The initial value is DISP_DATE. void setDisplayMode(DisplayMode mode); - void setColor(unsigned int color); // Text color. - void setFont(std::shared_ptr font); // Font to display with. Default is Font::get(FONT_SIZE_MEDIUM). - void setUppercase(bool uppercase); // Force text to be uppercase when in DISP_RELATIVE_TO_NOW mode. + // Text color. + void setColor(unsigned int color); + // Font to use. Default is Font::get(FONT_SIZE_MEDIUM). + void setFont(std::shared_ptr font); + // Force text to be uppercase when in DISP_RELATIVE_TO_NOW mode. + void setUppercase(bool uppercase); - virtual void applyTheme(const std::shared_ptr& theme, const std::string& view, const std::string& element, unsigned int properties) override; + virtual void applyTheme(const std::shared_ptr& theme, const std::string& view, + const std::string& element, unsigned int properties) override; private: std::shared_ptr getFont() const; @@ -64,7 +75,6 @@ private: unsigned int mColor; std::shared_ptr mFont; bool mUppercase; - bool mAutoSize; }; diff --git a/es-core/src/components/MenuComponent.cpp b/es-core/src/components/MenuComponent.cpp index 319c6cb27..3a0496dac 100644 --- a/es-core/src/components/MenuComponent.cpp +++ b/es-core/src/components/MenuComponent.cpp @@ -1,3 +1,9 @@ +// +// MenuComponent.cpp +// +// Basic component for building a menu. +// + #include "components/MenuComponent.h" #include "components/ButtonComponent.h" @@ -8,22 +14,27 @@ #define TITLE_HEIGHT (mTitle->getFont()->getLetterHeight() + TITLE_VERT_PADDING) -MenuComponent::MenuComponent(Window* window, const char* title, const std::shared_ptr& titleFont) : GuiComponent(window), - mBackground(window), mGrid(window, Vector2i(1, 3)) +MenuComponent::MenuComponent( + Window* window, + const char* title, + const std::shared_ptr& titleFont) + : GuiComponent(window), + mBackground(window), + mGrid(window, Vector2i(1, 3)) { addChild(&mBackground); addChild(&mGrid); mBackground.setImagePath(":/frame.png"); - // set up title + // Set up title. mTitle = std::make_shared(mWindow); mTitle->setHorizontalAlignment(ALIGN_CENTER); mTitle->setColor(0x555555FF); setTitle(title, titleFont); mGrid.setEntry(mTitle, Vector2i(0, 0), false); - // set up list which will never change (externally, anyway) + // Set up list which will never change (externally, anyway). mList = std::make_shared(mWindow); mGrid.setEntry(mList, Vector2i(0, 1), true); @@ -40,10 +51,10 @@ MenuComponent::~MenuComponent() void MenuComponent::save() { - if(!mSaveFuncs.size()) + if (!mSaveFuncs.size()) return; - for(auto it = mSaveFuncs.cbegin(); it != mSaveFuncs.cend(); it++) + for (auto it = mSaveFuncs.cbegin(); it != mSaveFuncs.cend(); it++) (*it)(); Settings::getInstance()->saveFile(); @@ -57,21 +68,20 @@ void MenuComponent::setTitle(const char* title, const std::shared_ptr& fon float MenuComponent::getButtonGridHeight() const { - return (mButtonGrid ? mButtonGrid->getSize().y() : Font::get(FONT_SIZE_MEDIUM)->getHeight() + BUTTON_GRID_VERT_PADDING); + return (mButtonGrid ? mButtonGrid->getSize().y() + : Font::get(FONT_SIZE_MEDIUM)->getHeight() + BUTTON_GRID_VERT_PADDING); } void MenuComponent::updateSize() { const float maxHeight = Renderer::getScreenHeight() * 0.75f; float height = TITLE_HEIGHT + mList->getTotalRowHeight() + getButtonGridHeight() + 2; - if(height > maxHeight) - { + if (height > maxHeight) { height = TITLE_HEIGHT + getButtonGridHeight(); int i = 0; - while(i < mList->size()) - { + while (i < mList->size()) { float rowHeight = mList->getRowHeight(i); - if(height + rowHeight < maxHeight) + if (height + rowHeight < maxHeight) height += rowHeight; else break; @@ -79,7 +89,8 @@ void MenuComponent::updateSize() } } - float width = (float)Math::min((int)Renderer::getScreenHeight(), (int)(Renderer::getScreenWidth() * 0.90f)); + float width = (float)Math::min((int)Renderer::getScreenHeight(), + (int)(Renderer::getScreenWidth() * 0.90f)); setSize(width, height); } @@ -87,29 +98,30 @@ void MenuComponent::onSizeChanged() { mBackground.fitTo(mSize, Vector3f::Zero(), Vector2f(-32, -32)); - // update grid row/col sizes + // Update grid row/col sizes. mGrid.setRowHeightPerc(0, TITLE_HEIGHT / mSize.y()); mGrid.setRowHeightPerc(2, getButtonGridHeight() / mSize.y()); mGrid.setSize(mSize); } -void MenuComponent::addButton(const std::string& name, const std::string& helpText, const std::function& callback) +void MenuComponent::addButton(const std::string& name, + const std::string& helpText, const std::function& callback) { - mButtons.push_back(std::make_shared(mWindow, Utils::String::toUpper(name), helpText, callback)); + mButtons.push_back(std::make_shared + (mWindow,Utils::String::toUpper(name), helpText, callback)); updateGrid(); updateSize(); } void MenuComponent::updateGrid() { - if(mButtonGrid) + if (mButtonGrid) mGrid.removeEntry(mButtonGrid); mButtonGrid.reset(); - if(mButtons.size()) - { + if (mButtons.size()) { mButtonGrid = makeButtonGrid(mWindow, mButtons); mGrid.setEntry(mButtonGrid, Vector2i(0, 2), true, false); } @@ -120,23 +132,26 @@ std::vector MenuComponent::getHelpPrompts() return mGrid.getHelpPrompts(); } -std::shared_ptr makeButtonGrid(Window* window, const std::vector< std::shared_ptr >& buttons) +std::shared_ptr makeButtonGrid(Window* window, + const std::vector< std::shared_ptr >& buttons) { - std::shared_ptr buttonGrid = std::make_shared(window, Vector2i((int)buttons.size(), 2)); + std::shared_ptr buttonGrid = std::make_shared + (window, Vector2i((int)buttons.size(), 2)); - float buttonGridWidth = (float)BUTTON_GRID_HORIZ_PADDING * buttons.size(); // initialize to padding - for(int i = 0; i < (int)buttons.size(); i++) - { + // Initialize to padding. + float buttonGridWidth = (float)BUTTON_GRID_HORIZ_PADDING * buttons.size(); + for (int i = 0; i < (int)buttons.size(); i++) { buttonGrid->setEntry(buttons.at(i), Vector2i(i, 0), true, false); buttonGridWidth += buttons.at(i)->getSize().x(); } - for(unsigned int i = 0; i < buttons.size(); i++) - { - buttonGrid->setColWidthPerc(i, (buttons.at(i)->getSize().x() + BUTTON_GRID_HORIZ_PADDING) / buttonGridWidth); - } + for (unsigned int i = 0; i < buttons.size(); i++) + buttonGrid->setColWidthPerc(i, (buttons.at(i)->getSize().x() + + BUTTON_GRID_HORIZ_PADDING) / buttonGridWidth); - buttonGrid->setSize(buttonGridWidth, buttons.at(0)->getSize().y() + BUTTON_GRID_VERT_PADDING + 2); - buttonGrid->setRowHeightPerc(1, 2 / buttonGrid->getSize().y()); // spacer row to deal with dropshadow to make buttons look centered + buttonGrid->setSize(buttonGridWidth, buttons.at(0)->getSize().y() + + BUTTON_GRID_VERT_PADDING + 2); + // Spacer row to deal with dropshadow to make buttons look centered. + buttonGrid->setRowHeightPerc(1, 2 / buttonGrid->getSize().y()); return buttonGrid; } diff --git a/es-core/src/components/MenuComponent.h b/es-core/src/components/MenuComponent.h index 1ec0359db..393aff365 100644 --- a/es-core/src/components/MenuComponent.h +++ b/es-core/src/components/MenuComponent.h @@ -1,3 +1,9 @@ +// +// MenuComponent.h +// +// Basic component for building a menu. +// + #pragma once #ifndef ES_CORE_COMPONENTS_MENU_COMPONENT_H #define ES_CORE_COMPONENTS_MENU_COMPONENT_H @@ -11,7 +17,8 @@ class ButtonComponent; class ImageComponent; -std::shared_ptr makeButtonGrid(Window* window, const std::vector< std::shared_ptr >& buttons); +std::shared_ptr makeButtonGrid(Window* window, + const std::vector< std::shared_ptr >& buttons); std::shared_ptr makeArrow(Window* window); #define TITLE_VERT_PADDING (Renderer::getScreenHeight()*0.0637f) @@ -19,25 +26,30 @@ std::shared_ptr makeArrow(Window* window); class MenuComponent : public GuiComponent { public: - MenuComponent(Window* window, const char* title, const std::shared_ptr& titleFont = Font::get(FONT_SIZE_LARGE)); + MenuComponent(Window* window, const char* title, + const std::shared_ptr& titleFont = Font::get(FONT_SIZE_LARGE)); virtual ~MenuComponent(); // just calls save(); void save(); void onSizeChanged() override; - inline void addRow(const ComponentListRow& row, bool setCursorHere = false) { mList->addRow(row, setCursorHere); updateSize(); } + inline void addRow(const ComponentListRow& row, bool setCursorHere = false) + { mList->addRow(row, setCursorHere); updateSize(); } - inline void addWithLabel(const std::string& label, const std::shared_ptr& comp, bool setCursorHere = false, bool invert_when_selected = true) + inline void addWithLabel(const std::string& label, const std::shared_ptr& comp, + bool setCursorHere = false, bool invert_when_selected = true) { ComponentListRow row; - row.addElement(std::make_shared(mWindow, Utils::String::toUpper(label), Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true); + row.addElement(std::make_shared(mWindow, + Utils::String::toUpper(label), Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true); row.addElement(comp, false, invert_when_selected); addRow(row, setCursorHere); } inline void addSaveFunc(const std::function& func) { mSaveFuncs.push_back(func); }; - void addButton(const std::string& label, const std::string& helpText, const std::function& callback); + void addButton(const std::string& label, const std::string& helpText, + const std::function& callback); void setTitle(const char* title, const std::shared_ptr& font); diff --git a/es-core/src/components/SwitchComponent.cpp b/es-core/src/components/SwitchComponent.cpp index ac413c2fc..61c090ee9 100644 --- a/es-core/src/components/SwitchComponent.cpp +++ b/es-core/src/components/SwitchComponent.cpp @@ -1,8 +1,19 @@ +// +// SwitchComponent.cpp +// +// Basic switch used in the menus. +// + #include "SwitchComponent.h" #include "resources/Font.h" -SwitchComponent::SwitchComponent(Window* window, bool state) : GuiComponent(window), mImage(window), mState(state) +SwitchComponent::SwitchComponent( + Window* window, + bool state) + : GuiComponent(window), + mImage(window), + mState(state) { mImage.setImage(":/off.svg"); mImage.setResize(0, Font::get(FONT_SIZE_MEDIUM)->getLetterHeight()); @@ -16,8 +27,7 @@ void SwitchComponent::onSizeChanged() bool SwitchComponent::input(InputConfig* config, Input input) { - if(config->isMappedTo("a", input) && input.value) - { + if(config->isMappedTo("a", input) && input.value) { mState = !mState; onStateChanged(); return true; @@ -29,9 +39,7 @@ bool SwitchComponent::input(InputConfig* config, Input input) void SwitchComponent::render(const Transform4x4f& parentTrans) { Transform4x4f trans = parentTrans * getTransform(); - mImage.render(trans); - renderChildren(trans); } @@ -54,12 +62,9 @@ std::string SwitchComponent::getValue() const void SwitchComponent::setValue(const std::string& statestring) { if (statestring == "true") - { mState = true; - }else - { + else mState = false; - } onStateChanged(); } diff --git a/es-core/src/components/SwitchComponent.h b/es-core/src/components/SwitchComponent.h index 2e2d83f6b..ecd946842 100644 --- a/es-core/src/components/SwitchComponent.h +++ b/es-core/src/components/SwitchComponent.h @@ -1,3 +1,9 @@ +// +// SwitchComponent.h +// +// Basic switch used in the menus. +// + #pragma once #ifndef ES_CORE_COMPONENTS_SWITCH_COMPONENT_H #define ES_CORE_COMPONENTS_SWITCH_COMPONENT_H @@ -5,8 +11,7 @@ #include "components/ImageComponent.h" #include "GuiComponent.h" -// A very simple "on/off" switch. -// Should hopefully be switched to use images instead of text in the future. +// A simple "on/off" switch. class SwitchComponent : public GuiComponent { public: diff --git a/es-core/src/components/TextEditComponent.cpp b/es-core/src/components/TextEditComponent.cpp index 6d98139bb..95ec45473 100644 --- a/es-core/src/components/TextEditComponent.cpp +++ b/es-core/src/components/TextEditComponent.cpp @@ -1,3 +1,9 @@ +// +// TextEditComponent.cpp +// +// Component for editing text fields in menus. +// + #include "components/TextEditComponent.h" #include "resources/Font.h" @@ -7,17 +13,20 @@ #define TEXT_PADDING_VERT 2 #define CURSOR_REPEAT_START_DELAY 500 -#define CURSOR_REPEAT_SPEED 28 // lower is faster +#define CURSOR_REPEAT_SPEED 28 // Lower is faster. -TextEditComponent::TextEditComponent(Window* window) : GuiComponent(window), - mBox(window, ":/textinput_ninepatch.png"), mFocused(false), - mScrollOffset(0.0f, 0.0f), mCursor(0), mEditing(false), mFont(Font::get(FONT_SIZE_MEDIUM, FONT_PATH_LIGHT)), - mCursorRepeatDir(0) +TextEditComponent::TextEditComponent( + Window* window) + : GuiComponent(window), + mBox(window, ":/textinput_ninepatch.png"), + mFocused(false), + mScrollOffset(0.0f, 0.0f), + mCursor(0), mEditing(false), + mFont(Font::get(FONT_SIZE_MEDIUM, FONT_PATH_LIGHT)), + mCursorRepeatDir(0) { addChild(&mBox); - onFocusLost(); - setSize(4096, mFont->getHeight() + TEXT_PADDING_VERT); } @@ -36,7 +45,7 @@ void TextEditComponent::onFocusLost() void TextEditComponent::onSizeChanged() { mBox.fitTo(mSize, Vector3f::Zero(), Vector2f(-34, -32 - TEXT_PADDING_VERT)); - onTextChanged(); // wrap point probably changed + onTextChanged(); // Wrap point probably changed. } void TextEditComponent::setValue(const std::string& val) @@ -52,18 +61,16 @@ std::string TextEditComponent::getValue() const void TextEditComponent::textInput(const char* text) { - if(mEditing) - { + if (mEditing) { mCursorRepeatDir = 0; - if(text[0] == '\b') - { - if(mCursor > 0) - { + if (text[0] == '\b') { + if (mCursor > 0) { size_t newCursor = Utils::String::prevCursor(mText, mCursor); mText.erase(mText.begin() + newCursor, mText.begin() + mCursor); mCursor = (unsigned int)newCursor; } - }else{ + } + else { mText.insert(mCursor, text); mCursor += (unsigned int)strlen(text); } @@ -89,80 +96,73 @@ void TextEditComponent::stopEditing() bool TextEditComponent::input(InputConfig* config, Input input) { - bool const cursor_left = (config->getDeviceId() != DEVICE_KEYBOARD && config->isMappedLike("left", input)) || - (config->getDeviceId() == DEVICE_KEYBOARD && input.id == SDLK_LEFT); - bool const cursor_right = (config->getDeviceId() != DEVICE_KEYBOARD && config->isMappedLike("right", input)) || - (config->getDeviceId() == DEVICE_KEYBOARD && input.id == SDLK_RIGHT); + bool const cursor_left = (config->getDeviceId() != DEVICE_KEYBOARD && + config->isMappedLike("left", input)) || (config->getDeviceId() == DEVICE_KEYBOARD && + input.id == SDLK_LEFT); + bool const cursor_right = (config->getDeviceId() != DEVICE_KEYBOARD && + config->isMappedLike("right", input)) || (config->getDeviceId() == DEVICE_KEYBOARD && + input.id == SDLK_RIGHT); - if(input.value == 0) - { - if(cursor_left || cursor_right) + if (input.value == 0) { + if (cursor_left || cursor_right) mCursorRepeatDir = 0; return false; } - if((config->isMappedTo("a", input) || (config->getDeviceId() == DEVICE_KEYBOARD && input.id == SDLK_RETURN)) && mFocused && !mEditing) - { + if ((config->isMappedTo("a", input) || (config->getDeviceId() == DEVICE_KEYBOARD && + input.id == SDLK_RETURN)) && mFocused && !mEditing) { startEditing(); return true; } - if(mEditing) - { - if(config->getDeviceId() == DEVICE_KEYBOARD && input.id == SDLK_RETURN) - { - if(isMultiline()) - { + if (mEditing) { + if (config->getDeviceId() == DEVICE_KEYBOARD && input.id == SDLK_RETURN) { + if (isMultiline()) textInput("\n"); - }else{ + else stopEditing(); - } return true; } - if((config->getDeviceId() == DEVICE_KEYBOARD && input.id == SDLK_ESCAPE) || (config->getDeviceId() != DEVICE_KEYBOARD && config->isMappedTo("b", input))) - { + if ((config->getDeviceId() == DEVICE_KEYBOARD && input.id == SDLK_ESCAPE) || + (config->getDeviceId() != DEVICE_KEYBOARD && config->isMappedTo("b", input))) { stopEditing(); return true; } - if(config->getDeviceId() != DEVICE_KEYBOARD && config->isMappedLike("up", input)) - { - // TODO - }else if(config->getDeviceId() != DEVICE_KEYBOARD && config->isMappedLike("down", input)) - { - // TODO - }else if(cursor_left || cursor_right) - { + if (config->getDeviceId() != DEVICE_KEYBOARD && config->isMappedLike("up", input)) { + // TODO. + } + else if (config->getDeviceId() != DEVICE_KEYBOARD && config->isMappedLike("down", input)) { + // TODO. + } + else if (cursor_left || cursor_right) { mCursorRepeatDir = cursor_left ? -1 : 1; mCursorRepeatTimer = -(CURSOR_REPEAT_START_DELAY - CURSOR_REPEAT_SPEED); moveCursor(mCursorRepeatDir); - } else if(config->getDeviceId() == DEVICE_KEYBOARD) - { - switch(input.id) - { - case SDLK_HOME: - setCursor(0); - break; + } + else if (config->getDeviceId() == DEVICE_KEYBOARD) { + switch (input.id) { + case SDLK_HOME: + setCursor(0); + break; - case SDLK_END: - setCursor(std::string::npos); - break; + case SDLK_END: + setCursor(std::string::npos); + break; - case SDLK_DELETE: - if(mCursor < mText.length()) - { - // Fake as Backspace one char to the right - moveCursor(1); - textInput("\b"); - } - break; + case SDLK_DELETE: + if (mCursor < mText.length()) { + // Fake as Backspace one char to the right. + moveCursor(1); + textInput("\b"); + } + break; } } - - //consume all input when editing text + // Consume all input when editing text. return true; } @@ -177,12 +177,11 @@ void TextEditComponent::update(int deltaTime) void TextEditComponent::updateCursorRepeat(int deltaTime) { - if(mCursorRepeatDir == 0) + if (mCursorRepeatDir == 0) return; mCursorRepeatTimer += deltaTime; - while(mCursorRepeatTimer >= CURSOR_REPEAT_SPEED) - { + while (mCursorRepeatTimer >= CURSOR_REPEAT_SPEED) { moveCursor(mCursorRepeatDir); mCursorRepeatTimer -= CURSOR_REPEAT_SPEED; } @@ -196,7 +195,7 @@ void TextEditComponent::moveCursor(int amt) void TextEditComponent::setCursor(size_t pos) { - if(pos == std::string::npos) + if (pos == std::string::npos) mCursor = (unsigned int)mText.length(); else mCursor = (int)pos; @@ -206,36 +205,34 @@ void TextEditComponent::setCursor(size_t pos) void TextEditComponent::onTextChanged() { - std::string wrappedText = (isMultiline() ? mFont->wrapText(mText, getTextAreaSize().x()) : mText); - mTextCache = std::unique_ptr(mFont->buildTextCache(wrappedText, 0, 0, 0x77777700 | getOpacity())); + std::string wrappedText = (isMultiline() ? + mFont->wrapText(mText, getTextAreaSize().x()) : mText); + mTextCache = std::unique_ptr + (mFont->buildTextCache(wrappedText, 0, 0, 0x77777700 | getOpacity())); - if(mCursor > (int)mText.length()) + if (mCursor > (int)mText.length()) mCursor = (unsigned int)mText.length(); } void TextEditComponent::onCursorChanged() { - if(isMultiline()) - { - Vector2f textSize = mFont->getWrappedTextCursorOffset(mText, getTextAreaSize().x(), mCursor); + if (isMultiline()) { + Vector2f textSize = mFont-> + getWrappedTextCursorOffset(mText, getTextAreaSize().x(), mCursor); - if(mScrollOffset.y() + getTextAreaSize().y() < textSize.y() + mFont->getHeight()) //need to scroll down? - { + if (mScrollOffset.y() + getTextAreaSize().y() < textSize.y() + + mFont->getHeight()) // Need to scroll down? mScrollOffset[1] = textSize.y() - getTextAreaSize().y() + mFont->getHeight(); - }else if(mScrollOffset.y() > textSize.y()) //need to scroll up? - { + else if (mScrollOffset.y() > textSize.y()) // Need to scroll up? mScrollOffset[1] = textSize.y(); - } - }else{ + } + else { Vector2f cursorPos = mFont->sizeText(mText.substr(0, mCursor)); - if(mScrollOffset.x() + getTextAreaSize().x() < cursorPos.x()) - { + if (mScrollOffset.x() + getTextAreaSize().x() < cursorPos.x()) mScrollOffset[0] = cursorPos.x() - getTextAreaSize().x(); - }else if(mScrollOffset.x() > cursorPos.x()) - { + else if (mScrollOffset.x() > cursorPos.x()) mScrollOffset[0] = cursorPos.x(); - } } } @@ -244,40 +241,40 @@ void TextEditComponent::render(const Transform4x4f& parentTrans) Transform4x4f trans = getTransform() * parentTrans; renderChildren(trans); - // text + cursor rendering - // offset into our "text area" (padding) + // Text + cursor rendering. + // Offset into our "text area" (padding). trans.translation() += Vector3f(getTextAreaPos().x(), getTextAreaPos().y(), 0); Vector2i clipPos((int)trans.translation().x(), (int)trans.translation().y()); - Vector3f dimScaled = trans * Vector3f(getTextAreaSize().x(), getTextAreaSize().y(), 0); // use "text area" size for clipping - Vector2i clipDim((int)(dimScaled.x() - trans.translation().x()), (int)(dimScaled.y() - trans.translation().y())); + // Use "text area" size for clipping. + Vector3f dimScaled = trans * Vector3f(getTextAreaSize().x(), getTextAreaSize().y(), 0); + Vector2i clipDim((int)(dimScaled.x() - trans.translation().x()), (int)(dimScaled.y() - + trans.translation().y())); Renderer::pushClipRect(clipPos, clipDim); trans.translate(Vector3f(-mScrollOffset.x(), -mScrollOffset.y(), 0)); Renderer::setMatrix(trans); - if(mTextCache) - { + if (mTextCache) mFont->renderTextCache(mTextCache.get()); - } - // pop the clip early to allow the cursor to be drawn outside of the "text area" + // Pop the clip early to allow the cursor to be drawn outside of the "text area". Renderer::popClipRect(); - // draw cursor - if(mEditing) - { + // Draw cursor. + if (mEditing) { Vector2f cursorPos; - if(isMultiline()) - { + if (isMultiline()) { cursorPos = mFont->getWrappedTextCursorOffset(mText, getTextAreaSize().x(), mCursor); - }else{ + } + else { cursorPos = mFont->sizeText(mText.substr(0, mCursor)); cursorPos[1] = 0; } float cursorHeight = mFont->getHeight() * 0.8f; - Renderer::drawRect(cursorPos.x(), cursorPos.y() + (mFont->getHeight() - cursorHeight) / 2, 2.0f, cursorHeight, 0x000000FF, 0x000000FF); + Renderer::drawRect(cursorPos.x(), cursorPos.y() + (mFont->getHeight() - + cursorHeight) / 2, 2.0f, cursorHeight, 0x000000FF, 0x000000FF); } } @@ -299,11 +296,11 @@ Vector2f TextEditComponent::getTextAreaSize() const std::vector TextEditComponent::getHelpPrompts() { std::vector prompts; - if(mEditing) - { + if (mEditing) { prompts.push_back(HelpPrompt("up/down/left/right", "move cursor")); prompts.push_back(HelpPrompt("b", "stop editing")); - }else{ + } + else { prompts.push_back(HelpPrompt("a", "edit")); } return prompts; diff --git a/es-core/src/components/TextEditComponent.h b/es-core/src/components/TextEditComponent.h index c388b30aa..ffe02bd69 100644 --- a/es-core/src/components/TextEditComponent.h +++ b/es-core/src/components/TextEditComponent.h @@ -1,3 +1,9 @@ +// +// TextEditComponent.h +// +// Component for editing text fields in menus. +// + #pragma once #ifndef ES_CORE_COMPONENTS_TEXT_EDIT_COMPONENT_H #define ES_CORE_COMPONENTS_TEXT_EDIT_COMPONENT_H @@ -51,7 +57,7 @@ private: std::string mText; bool mFocused; bool mEditing; - unsigned int mCursor; // cursor position in characters + unsigned int mCursor; // Cursor position in characters. int mCursorRepeatTimer; int mCursorRepeatDir; diff --git a/es-core/src/components/TextListComponent.h b/es-core/src/components/TextListComponent.h index 558f3548f..6ce797824 100644 --- a/es-core/src/components/TextListComponent.h +++ b/es-core/src/components/TextListComponent.h @@ -1,3 +1,9 @@ +// +// TextListComponent.h +// +// Used for displaying and navigating the gamelists. +// + #pragma once #ifndef ES_APP_COMPONENTS_TEXT_LIST_COMPONENT_H #define ES_APP_COMPONENTS_TEXT_LIST_COMPONENT_H @@ -11,13 +17,12 @@ class TextCache; -struct TextListData -{ +struct TextListData { unsigned int colorId; std::shared_ptr textCache; }; -//A graphical list. Supports multiple colors for rows and scrolling. +// A graphical list. Supports multiple colors for rows and scrolling. template class TextListComponent : public IList { @@ -41,12 +46,12 @@ public: bool input(InputConfig* config, Input input) override; void update(int deltaTime) override; void render(const Transform4x4f& parentTrans) override; - void applyTheme(const std::shared_ptr& theme, const std::string& view, const std::string& element, unsigned int properties) override; + void applyTheme(const std::shared_ptr& theme, const std::string& view, + const std::string& element, unsigned int properties) override; void add(const std::string& name, const T& obj, unsigned int colorId); - enum Alignment - { + enum Alignment { ALIGN_LEFT, ALIGN_CENTER, ALIGN_RIGHT @@ -54,19 +59,20 @@ public: inline void setAlignment(Alignment align) { mAlignment = align; } - inline void setCursorChangedCallback(const std::function& func) { mCursorChangedCallback = func; } + inline void setCursorChangedCallback(const std::function& func) + { mCursorChangedCallback = func; } inline void setFont(const std::shared_ptr& font) { mFont = font; - for(auto it = mEntries.begin(); it != mEntries.end(); it++) + for (auto it = mEntries.begin(); it != mEntries.end(); it++) it->data.textCache.reset(); } inline void setUppercase(bool /*uppercase*/) { mUppercase = true; - for(auto it = mEntries.begin(); it != mEntries.end(); it++) + for (auto it = mEntries.begin(); it != mEntries.end(); it++) it->data.textCache.reset(); } @@ -74,7 +80,8 @@ public: inline void setSelectorOffsetY(float selectorOffsetY) { mSelectorOffsetY = selectorOffsetY; } inline void setSelectorColor(unsigned int color) { mSelectorColor = color; } inline void setSelectorColorEnd(unsigned int color) { mSelectorColorEnd = color; } - inline void setSelectorColorGradientHorizontal(bool horizontal) { mSelectorColorGradientHorizontal = horizontal; } + inline void setSelectorColorGradientHorizontal(bool horizontal) + { mSelectorColorGradientHorizontal = horizontal; } inline void setSelectedColor(unsigned int color) { mSelectedColor = color; } inline void setColor(unsigned int id, unsigned int color) { mColors[id] = color; } inline void setLineSpacing(float lineSpacing) { mLineSpacing = lineSpacing; } @@ -141,90 +148,99 @@ void TextListComponent::render(const Transform4x4f& parentTrans) std::shared_ptr& font = mFont; - if(size() == 0) + if (size() == 0) return; const float entrySize = Math::max(font->getHeight(1.0), (float)font->getSize()) * mLineSpacing; int startEntry = 0; - //number of entries that can fit on the screen simultaniously + // Number of entries that can fit on the screen simultaniously. int screenCount = (int)(mSize.y() / entrySize + 0.5f); - if(size() >= screenCount) + if (size() >= screenCount) { startEntry = mCursor - screenCount/2; - if(startEntry < 0) + if (startEntry < 0) startEntry = 0; - if(startEntry >= size() - screenCount) + if (startEntry >= size() - screenCount) startEntry = size() - screenCount; } float y = 0; int listCutoff = startEntry + screenCount; - if(listCutoff > size()) + if (listCutoff > size()) listCutoff = size(); - // draw selector bar - if(startEntry < listCutoff) - { + // Draw selector bar. + if (startEntry < listCutoff) { if (mSelectorImage.hasImage()) { - mSelectorImage.setPosition(0.f, (mCursor - startEntry)*entrySize + mSelectorOffsetY, 0.f); + mSelectorImage.setPosition(0.f, + (mCursor - startEntry)*entrySize + mSelectorOffsetY, 0.f); mSelectorImage.render(trans); - } else { + } + else { Renderer::setMatrix(trans); - Renderer::drawRect(0.0f, (mCursor - startEntry)*entrySize + mSelectorOffsetY, mSize.x(), - mSelectorHeight, mSelectorColor, mSelectorColorEnd, mSelectorColorGradientHorizontal); + Renderer::drawRect( + 0.0f, + (mCursor - startEntry)*entrySize + + mSelectorOffsetY, + mSize.x(), + mSelectorHeight, + mSelectorColor, + mSelectorColorEnd, + mSelectorColorGradientHorizontal); } } - // clip to inside margins + // Clip to inside margins. Vector3f dim(mSize.x(), mSize.y(), 0); dim = trans * dim - trans.translation(); - Renderer::pushClipRect(Vector2i((int)(trans.translation().x() + mHorizontalMargin), (int)trans.translation().y()), - Vector2i((int)(dim.x() - mHorizontalMargin*2), (int)dim.y())); + Renderer::pushClipRect(Vector2i((int)(trans.translation().x() + mHorizontalMargin), + (int)trans.translation().y()), Vector2i((int)(dim.x() - mHorizontalMargin*2), + (int)dim.y())); - for(int i = startEntry; i < listCutoff; i++) - { + for (int i = startEntry; i < listCutoff; i++) { typename IList::Entry& entry = mEntries.at((unsigned int)i); unsigned int color; - if(mCursor == i && mSelectedColor) + if (mCursor == i && mSelectedColor) color = mSelectedColor; else color = mColors[entry.data.colorId]; - if(!entry.data.textCache) - entry.data.textCache = std::unique_ptr(font->buildTextCache(mUppercase ? Utils::String::toUpper(entry.name) : entry.name, 0, 0, 0x000000FF)); + if (!entry.data.textCache) + entry.data.textCache = std::unique_ptr + (font->buildTextCache(mUppercase ? + Utils::String::toUpper(entry.name) : entry.name, 0, 0, 0x000000FF)); entry.data.textCache->setColor(color); Vector3f offset(0, y, 0); - switch(mAlignment) - { + switch (mAlignment) { case ALIGN_LEFT: offset[0] = mHorizontalMargin; break; case ALIGN_CENTER: offset[0] = (int)((mSize.x() - entry.data.textCache->metrics.size.x()) / 2); - if(offset[0] < mHorizontalMargin) + if (offset[0] < mHorizontalMargin) offset[0] = mHorizontalMargin; break; case ALIGN_RIGHT: offset[0] = (mSize.x() - entry.data.textCache->metrics.size.x()); offset[0] -= mHorizontalMargin; - if(offset[0] < mHorizontalMargin) + if (offset[0] < mHorizontalMargin) offset[0] = mHorizontalMargin; break; } - // render text + // Render text. Transform4x4f drawTrans = trans; - // currently selected item text might be scrolling - if((mCursor == i) && (mMarqueeOffset > 0)) + // Currently selected item text might be scrolling. + if ((mCursor == i) && (mMarqueeOffset > 0)) drawTrans.translate(offset - Vector3f((float)mMarqueeOffset, 0, 0)); else drawTrans.translate(offset); @@ -232,10 +248,9 @@ void TextListComponent::render(const Transform4x4f& parentTrans) Renderer::setMatrix(drawTrans); font->renderTextCache(entry.data.textCache.get()); - // render currently selected item text again if - // marquee is scrolled far enough for it to repeat - if((mCursor == i) && (mMarqueeOffset2 < 0)) - { + // Render currently selected item text again if marquee is + // scrolled far enough for it to repeat. + if ((mCursor == i) && (mMarqueeOffset2 < 0)) { drawTrans = trans; drawTrans.translate(offset - Vector3f((float)mMarqueeOffset2, 0, 0)); Renderer::setMatrix(drawTrans); @@ -246,47 +261,40 @@ void TextListComponent::render(const Transform4x4f& parentTrans) } Renderer::popClipRect(); - listRenderTitleOverlay(trans); - GuiComponent::renderChildren(trans); } template bool TextListComponent::input(InputConfig* config, Input input) { - if(size() > 0) - { - if(input.value != 0) - { - if(config->isMappedLike("down", input)) - { + if (size() > 0) { + if (input.value != 0) { + if (config->isMappedLike("down", input)) { listInput(1); return true; } - if(config->isMappedLike("up", input)) - { + if (config->isMappedLike("up", input)) { listInput(-1); return true; } - if(config->isMappedLike("rightshoulder", input)) - { + if (config->isMappedLike("rightshoulder", input)) { listInput(10); return true; } - if(config->isMappedLike("leftshoulder", input)) - { + if (config->isMappedLike("leftshoulder", input)) { listInput(-10); return true; } - }else{ - if(config->isMappedLike("down", input) || config->isMappedLike("up", input) || - config->isMappedLike("rightshoulder", input) || config->isMappedLike("leftshoulder", input)) - { + } + else { + if (config->isMappedLike("down", input) || + config->isMappedLike("up", input) || + config->isMappedLike("rightshoulder", input) || + config->isMappedLike("leftshoulder", input)) stopScrolling(); - } } } @@ -298,20 +306,18 @@ void TextListComponent::update(int deltaTime) { listUpdate(deltaTime); - if(!isScrolling() && size() > 0) - { - // always reset the marquee offsets + if (!isScrolling() && size() > 0) { + // Always reset the marquee offsets. mMarqueeOffset = 0; mMarqueeOffset2 = 0; - // if we're not scrolling and this object's text goes outside our size, marquee it! + // If we're not scrolling and this object's text goes outside our size, marquee it! const float textLength = mFont->sizeText(mEntries.at((unsigned int)mCursor).name).x(); const float limit = mSize.x() - mHorizontalMargin * 2; - if(textLength > limit) - { - // loop - // pixels per second ( based on nes-mini font at 1920x1080 to produce a speed of 200 ) + if (textLength > limit) { + // Loop. + // Pixels per second (based on nes-mini font at 1920x1080 to produce a speed of 200). const float speed = mFont->sizeText("ABCDEFGHIJKLMNOPQRSTUVWXYZ").x() * 0.247f; const float delay = 3000; const float scrollLength = textLength; @@ -321,12 +327,13 @@ void TextListComponent::update(int deltaTime) const int maxTime = (int)(delay + scrollTime + returnTime); mMarqueeTime += deltaTime; - while(mMarqueeTime > maxTime) + while (mMarqueeTime > maxTime) mMarqueeTime -= maxTime; - mMarqueeOffset = (int)(Math::Scroll::loop(delay, scrollTime + returnTime, (float)mMarqueeTime, scrollLength + returnLength)); + mMarqueeOffset = (int)(Math::Scroll::loop(delay, scrollTime + returnTime, + (float)mMarqueeTime, scrollLength + returnLength)); - if(mMarqueeOffset > (scrollLength - (limit - returnLength))) + if (mMarqueeOffset > (scrollLength - (limit - returnLength))) mMarqueeOffset2 = (int)(mMarqueeOffset - (scrollLength + returnLength)); } } @@ -334,7 +341,7 @@ void TextListComponent::update(int deltaTime) GuiComponent::update(deltaTime); } -//list management stuff +// List management stuff. template void TextListComponent::add(const std::string& name, const T& obj, unsigned int color) { @@ -354,92 +361,89 @@ void TextListComponent::onCursorChanged(const CursorState& state) mMarqueeOffset2 = 0; mMarqueeTime = 0; - if(mCursorChangedCallback) + if (mCursorChangedCallback) mCursorChangedCallback(state); } template -void TextListComponent::applyTheme(const std::shared_ptr& theme, const std::string& view, const std::string& element, unsigned int properties) +void TextListComponent::applyTheme(const std::shared_ptr& theme, + const std::string& view, const std::string& element, unsigned int properties) { GuiComponent::applyTheme(theme, view, element, properties); const ThemeData::ThemeElement* elem = theme->getElement(view, element, "textlist"); - if(!elem) + if (!elem) return; using namespace ThemeFlags; - if(properties & COLOR) - { - if(elem->has("selectorColor")) - { + if (properties & COLOR) { + if (elem->has("selectorColor")) { setSelectorColor(elem->get("selectorColor")); setSelectorColorEnd(elem->get("selectorColor")); } if (elem->has("selectorColorEnd")) setSelectorColorEnd(elem->get("selectorColorEnd")); if (elem->has("selectorGradientType")) - setSelectorColorGradientHorizontal(!(elem->get("selectorGradientType").compare("horizontal"))); - if(elem->has("selectedColor")) + setSelectorColorGradientHorizontal(!(elem->get + ("selectorGradientType").compare("horizontal"))); + if (elem->has("selectedColor")) setSelectedColor(elem->get("selectedColor")); - if(elem->has("primaryColor")) + if (elem->has("primaryColor")) setColor(0, elem->get("primaryColor")); - if(elem->has("secondaryColor")) + if (elem->has("secondaryColor")) setColor(1, elem->get("secondaryColor")); } setFont(Font::getFromTheme(elem, properties, mFont)); - const float selectorHeight = Math::max(mFont->getHeight(1.0), (float)mFont->getSize()) * mLineSpacing; + const float selectorHeight = Math::max(mFont->getHeight(1.0), + (float)mFont->getSize()) * mLineSpacing; setSelectorHeight(selectorHeight); - if(properties & ALIGNMENT) - { - if(elem->has("alignment")) - { + if (properties & ALIGNMENT) { + if (elem->has("alignment")) { const std::string& str = elem->get("alignment"); - if(str == "left") + if (str == "left") setAlignment(ALIGN_LEFT); - else if(str == "center") + else if (str == "center") setAlignment(ALIGN_CENTER); - else if(str == "right") + else if (str == "right") setAlignment(ALIGN_RIGHT); else LOG(LogError) << "Unknown TextListComponent alignment \"" << str << "\"!"; } - if(elem->has("horizontalMargin")) - { - mHorizontalMargin = elem->get("horizontalMargin") * (this->mParent ? this->mParent->getSize().x() : (float)Renderer::getScreenWidth()); + if (elem->has("horizontalMargin")) { + mHorizontalMargin = elem->get("horizontalMargin") * + (this->mParent ? this->mParent->getSize().x() : + (float)Renderer::getScreenWidth()); } } - if(properties & FORCE_UPPERCASE && elem->has("forceUppercase")) + if (properties & FORCE_UPPERCASE && elem->has("forceUppercase")) setUppercase(elem->get("forceUppercase")); - if(properties & LINE_SPACING) - { - if(elem->has("lineSpacing")) + if (properties & LINE_SPACING) { + if (elem->has("lineSpacing")) setLineSpacing(elem->get("lineSpacing")); - if(elem->has("selectorHeight")) - { + if (elem->has("selectorHeight")) setSelectorHeight(elem->get("selectorHeight") * Renderer::getScreenHeight()); - } - if(elem->has("selectorOffsetY")) - { + if (elem->has("selectorOffsetY")) { float scale = this->mParent ? this->mParent->getSize().y() : (float)Renderer::getScreenHeight(); setSelectorOffsetY(elem->get("selectorOffsetY") * scale); - } else { + } + else { setSelectorOffsetY(0.0); } } - if (elem->has("selectorImagePath")) - { + if (elem->has("selectorImagePath")) { std::string path = elem->get("selectorImagePath"); bool tile = elem->has("selectorImageTile") && elem->get("selectorImageTile"); mSelectorImage.setImage(path, tile); mSelectorImage.setSize(mSize.x(), mSelectorHeight); mSelectorImage.setColorShift(mSelectorColor); mSelectorImage.setColorShiftEnd(mSelectorColorEnd); - } else { + } + else { mSelectorImage.setImage(""); } }