// SPDX-License-Identifier: MIT // // EmulationStation Desktop Edition // DateTimeComponent.cpp // // Provides the date and time, in absolute (actual date) or relative // (delta from current date and time) form. // Used by the gamelist views. // #include "components/DateTimeComponent.h" #include "utils/StringUtil.h" #include "Log.h" #include "Settings.h" DateTimeComponent::DateTimeComponent(Window* window) : TextComponent(window), mDisplayRelative(false) { // ISO 8601 date format. setFormat("%Y-%m-%d"); } 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) { // ISO 8601 date format. setFormat("%Y-%m-%d"); } void DateTimeComponent::setValue(const std::string& val) { mTime = val; onTextChanged(); } std::string DateTimeComponent::getValue() const { return mTime; } void DateTimeComponent::setFormat(const std::string& format) { mFormat = format; onTextChanged(); } void DateTimeComponent::setDisplayRelative(bool displayRelative) { mDisplayRelative = displayRelative; onTextChanged(); } void DateTimeComponent::onTextChanged() { mText = getDisplayString(); TextComponent::onTextChanged(); } std::string DateTimeComponent::getDisplayString() const { if (mDisplayRelative) { // Relative time. if (mTime.getTime() == 0) return "never"; Utils::Time::DateTime now(Utils::Time::now()); Utils::Time::Duration dur(now.getTime() - mTime.getTime()); char buf[64]; if (dur.getDays() > 0) sprintf(buf, "%d day%s ago", dur.getDays(), (dur.getDays() > 1) ? "s" : ""); 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 sprintf(buf, "%d second%s ago", dur.getSeconds(), (dur.getSeconds() > 1) ? "s" : ""); return std::string(buf); } if (mTime.getTime() == 0) return "unknown"; return Utils::Time::timeToString(mTime.getTime(), mFormat); } void DateTimeComponent::render(const Transform4x4f& parentTrans) { TextComponent::render(parentTrans); } 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); using namespace ThemeFlags; const ThemeData::ThemeElement* elem = theme->getElement(view, element, "datetime"); if (!elem) return; if (elem->has("displayRelative")) setDisplayRelative(elem->get("displayRelative")); if (elem->has("format")) setFormat(elem->get("format")); if (properties & COLOR && elem->has("color")) setColor(elem->get("color")); setRenderBackground(false); if (properties & COLOR && elem->has("backgroundColor")) { setBackgroundColor(elem->get("backgroundColor")); setRenderBackground(true); } if (properties & ALIGNMENT && elem->has("alignment")) { std::string str = elem->get("alignment"); if (str == "left") setHorizontalAlignment(ALIGN_LEFT); else if (str == "center") setHorizontalAlignment(ALIGN_CENTER); else if (str == "right") setHorizontalAlignment(ALIGN_RIGHT); else LOG(LogError) << "Unknown text alignment string: " << str; } if (properties & FORCE_UPPERCASE && elem->has("forceUppercase")) setUppercase(elem->get("forceUppercase")); if (properties & LINE_SPACING && elem->has("lineSpacing")) setLineSpacing(elem->get("lineSpacing")); setFont(Font::getFromTheme(elem, properties, mFont)); }