/** * \brief Reset the image back to the default defined in the theme */ void MythUIImage::Reset(void) { d->m_UpdateLock.lockForWrite(); SetMinArea(MythRect()); if (m_imageProperties.filename != m_OrigFilename) { m_imageProperties.isThemeImage = true; m_imageProperties.filename = m_OrigFilename; if (m_animatedImage) { m_LowNum = 0; m_HighNum = 0; m_animatedImage = false; } emit DependChanged(true); d->m_UpdateLock.unlock(); Load(); } else d->m_UpdateLock.unlock(); MythUIType::Reset(); }
/** * \brief Copy this widgets state from another. */ void MythUIType::CopyFrom(MythUIType *base) { m_Visible = base->m_Visible; m_Enabled = base->m_Enabled; m_CanHaveFocus = base->m_CanHaveFocus; m_focusOrder = base->m_focusOrder; m_Area = base->m_Area; RecalculateArea(); m_EnableInitiator = base->m_EnableInitiator; m_MinSize = base->m_MinSize; m_Vanish = base->m_Vanish; m_Vanished = false; m_Alpha = base->m_Alpha; m_AlphaChangeMode = base->m_AlphaChangeMode; m_AlphaChange = base->m_AlphaChange; m_AlphaMin = base->m_AlphaMin; m_AlphaMax = base->m_AlphaMax; m_Moving = base->m_Moving; m_XYDestination = base->m_XYDestination; m_XYSpeed = base->m_XYSpeed; m_deferload = base->m_deferload; QList<MythUIType *>::Iterator it; for (it = base->m_ChildrenList.begin(); it != base->m_ChildrenList.end(); ++it) { MythUIType *child = GetChild((*it)->objectName()); if (child) child->CopyFrom(*it); else (*it)->CreateCopy(this); } SetMinArea(base->m_MinArea); }
/** * \brief Assign a set of MythImages to the widget for animation. * Use is strongly discouraged, use SetFilepattern() instead. * */ void MythUIImage::SetImages(QVector<MythImage *> *images) { Clear(); QWriteLocker updateLocker(&d->m_UpdateLock); QSize aSize = GetFullArea().size(); m_imageProperties.isThemeImage = false; QVector<MythImage *>::iterator it; for (it = images->begin(); it != images->end(); ++it) { MythImage *im = (*it); if (!im) { QMutexLocker locker(&m_ImagesLock); m_Images[m_Images.size()] = im; continue; } im->IncrRef(); QSize forceSize = m_imageProperties.forceSize; if (!forceSize.isNull()) { int w = (forceSize.width() <= 0) ? im->width() : forceSize.width(); int h = (forceSize.height() <= 0) ? im->height() : forceSize.height(); im->Resize(QSize(w, h), m_imageProperties.preserveAspect); } if (m_imageProperties.isReflected && !im->IsReflected()) im->Reflect(m_imageProperties.reflectAxis, m_imageProperties.reflectShear, m_imageProperties.reflectScale, m_imageProperties.reflectLength, m_imageProperties.reflectSpacing); if (m_imageProperties.isGreyscale && !im->isGrayscale()) im->ToGreyscale(); if (m_imageProperties.isOriented && !im->IsOriented() && (m_imageProperties.orientation >= 1 && m_imageProperties.orientation <= 8)) im->Orientation(m_imageProperties.orientation); m_ImagesLock.lock(); m_Images[m_Images.size()] = im; m_ImagesLock.unlock(); aSize = aSize.expandedTo(im->size()); } SetImageCount(1, m_Images.size()); if (m_imageProperties.forceSize.isNull()) SetSize(aSize); MythRect rect(GetFullArea()); rect.setSize(aSize); SetMinArea(rect); m_CurPos = 0; m_animatedImage = true; m_Initiator = m_EnableInitiator; SetRedraw(); }
/** * \copydoc MythUIType::customEvent() */ void MythUIImage::customEvent(QEvent *event) { if (event->type() == ImageLoadEvent::kEventType) { MythImage *image = NULL; AnimationFrames *animationFrames = NULL; int number = 0; QString filename; bool aborted; ImageLoadEvent *le = static_cast<ImageLoadEvent *>(event); if (le->GetParent() != this) return; image = le->GetImage(); number = le->GetNumber(); filename = le->GetFilename(); animationFrames = le->GetAnimationFrames(); aborted = le->GetAbortState(); m_runningThreads--; d->m_UpdateLock.lockForRead(); // 1) We aborted loading the image for some reason (e.g. two requests // for same image) // 2) Filename changed since we started this image, so abort to avoid // rendering two different images in quick succession which causes // unsightly flickering if (aborted || (le->GetBasefile() != m_imageProperties.filename)) { d->m_UpdateLock.unlock(); if (aborted) LOG(VB_GUI, LOG_DEBUG, QString("Aborted loading image %1") .arg(filename)); if (image) image->DecrRef(); if (animationFrames) { AnimationFrames::iterator it; for (it = animationFrames->begin(); it != animationFrames->end(); ++it) { MythImage *im = (*it).first; if (im) im->DecrRef(); } delete animationFrames; } return; } d->m_UpdateLock.unlock(); if (animationFrames) { SetAnimationFrames(*animationFrames); delete animationFrames; return; } if (image) { // We don't clear until we have the new image ready to display to // avoid unsightly flashing. This isn't currently supported for // animations. if ((m_HighNum == m_LowNum) && !m_animatedImage) Clear(); d->m_UpdateLock.lockForWrite(); if (m_imageProperties.forceSize.isNull()) SetSize(image->size()); MythRect rect(GetFullArea()); rect.setSize(image->size()); SetMinArea(rect); d->m_UpdateLock.unlock(); m_ImagesLock.lock(); if (m_Images[number]) { // If we got to this point, it means this same MythUIImage // was told to reload the same image, so we use the newest // copy of the image. m_Images[number]->DecrRef(); // delete the original } m_Images[number] = image; m_ImagesLock.unlock(); SetRedraw(); d->m_UpdateLock.lockForWrite(); m_LastDisplay = QTime::currentTime(); d->m_UpdateLock.unlock(); return; } // No Images were loaded, so trigger Reset to default Reset(); } }
/** * \brief Load the image(s), wraps ImageLoader::LoadImage() */ bool MythUIImage::Load(bool allowLoadInBackground, bool forceStat) { d->m_UpdateLock.lockForRead(); m_Initiator = m_EnableInitiator; QString bFilename = m_imageProperties.filename; bFilename.detach(); d->m_UpdateLock.unlock(); QString filename = bFilename; if (bFilename.isEmpty()) { Clear(); SetMinArea(MythRect()); SetRedraw(); return false; } if (getenv("DISABLETHREADEDMYTHUIIMAGE")) allowLoadInBackground = false; // Don't clear the widget before we need to, otherwise it causes // unsightly flashing. We exclude animations for now since that requires a // deeper fix bool isAnimation = (m_HighNum != m_LowNum) || m_animatedImage; if (isAnimation) Clear(); QString imagelabel; int j = 0; for (int i = m_LowNum; i <= m_HighNum && !m_animatedImage; i++) { if (!m_animatedImage && m_HighNum != m_LowNum && bFilename.contains("%1")) filename = bFilename.arg(i); ImageProperties imProps = m_imageProperties; imProps.filename = filename; imagelabel = ImageLoader::GenImageLabel(imProps); // Only load in the background if allowed and the image is // not already in our mem cache int cacheMode = kCacheIgnoreDisk; if (forceStat) cacheMode |= (int)kCacheForceStat; int cacheMode2 = kCacheNormal; if (forceStat) cacheMode2 |= (int)kCacheForceStat; bool do_background_load = false; if (allowLoadInBackground) { MythImage *img = GetMythUI()->LoadCacheImage( filename, imagelabel, GetPainter(), static_cast<ImageCacheMode>(cacheMode)); if (img) img->DecrRef(); else do_background_load = true; } if (do_background_load) { SetMinArea(MythRect()); LOG(VB_GUI | VB_FILE, LOG_DEBUG, LOC + QString("Load(), spawning thread to load '%1'").arg(filename)); m_runningThreads++; ImageLoadThread *bImgThread; bImgThread = new ImageLoadThread(this, GetPainter(), imProps, bFilename, i, static_cast<ImageCacheMode>(cacheMode2)); GetMythUI()->GetImageThreadPool()->start(bImgThread, "ImageLoad"); } else { if (!isAnimation && !GetMythUI()->IsImageInCache(imagelabel)) Clear(); // Perform a blocking load LOG(VB_GUI | VB_FILE, LOG_DEBUG, LOC + QString("Load(), loading '%1' in foreground").arg(filename)); bool aborted = false; if (ImageLoader::SupportsAnimation(filename)) { AnimationFrames *myFrames; myFrames = ImageLoader::LoadAnimatedImage(GetPainter(), imProps, static_cast<ImageCacheMode>(cacheMode2), this, aborted); // TODO We might want to handle an abort here more gracefully if (aborted) LOG(VB_GUI, LOG_DEBUG, QString("Aborted loading animated" "image %1 in foreground") .arg(filename)); SetAnimationFrames(*myFrames); delete myFrames; } else { MythImage *image = NULL; image = ImageLoader::LoadImage(GetPainter(), imProps, static_cast<ImageCacheMode>(cacheMode2), this, aborted); // TODO We might want to handle an abort here more gracefully if (aborted) LOG(VB_GUI, LOG_DEBUG, QString("Aborted loading animated" "image %1 in foreground") .arg(filename)); if (image) { if (m_imageProperties.forceSize.isNull()) SetSize(image->size()); MythRect rect(GetFullArea()); rect.setSize(image->size()); SetMinArea(rect); m_ImagesLock.lock(); m_Images[j] = image; m_ImagesLock.unlock(); SetRedraw(); d->m_UpdateLock.lockForWrite(); m_LastDisplay = QTime::currentTime(); d->m_UpdateLock.unlock(); } else { Reset(); m_ImagesLock.lock(); m_Images[j] = NULL; m_ImagesLock.unlock(); } } } ++j; } return true; }
void MythUIText::FillCutMessage() { m_CutMessage.clear(); if (m_Message != m_DefaultMessage) { bool isNumber; int value = m_Message.toInt(&isNumber); if (isNumber && m_TemplateText.contains("%n")) { m_CutMessage = qApp->translate("ThemeUI", m_TemplateText.toUtf8(), NULL, QCoreApplication::UnicodeUTF8, qAbs(value)); } else if (m_TemplateText.contains("%1")) { QString tmp = qApp->translate("ThemeUI", m_TemplateText.toUtf8(), NULL, QCoreApplication::UnicodeUTF8); m_CutMessage = tmp.arg(m_Message); } } if (m_CutMessage.isEmpty()) m_CutMessage = m_Message; if (m_CutMessage.isEmpty()) return; QStringList templist; QStringList::iterator it; switch (m_textCase) { case CaseUpper : m_CutMessage = m_CutMessage.toUpper(); break; case CaseLower : m_CutMessage = m_CutMessage.toLower(); break; case CaseCapitaliseFirst : //m_CutMessage = m_CutMessage.toLower(); templist = m_CutMessage.split(". "); for (it = templist.begin(); it != templist.end(); ++it) (*it).replace(0,1,(*it).left(1).toUpper()); m_CutMessage = templist.join(". "); break; case CaseCapitaliseAll : //m_CutMessage = m_CutMessage.toLower(); templist = m_CutMessage.split(" "); for (it = templist.begin(); it != templist.end(); ++it) (*it).replace(0,1,(*it).left(1).toUpper()); m_CutMessage = templist.join(" "); break; } if (m_MinSize.x() > 0) { QRect rect; MakeNarrow(rect); // Record the minimal area needed for the message. SetMinArea(rect.size()); if (m_MinArea.width() > 0) SetDrawRectSize(m_MinArea.width(), m_MinArea.height()); } if (m_Cutdown) m_CutMessage = cutDown(m_CutMessage, m_Font, m_MultiLine); }