#include "symbols/mute.xpm" #include "displayvolume.h" cNopacityDisplayVolume::cNopacityDisplayVolume(void) { config.setDynamicValues(); initial = true; muted = false; FrameTime = config.volumeFrameTime; FadeTime = config.volumeFadeTime; width = cOsd::OsdWidth() * config.volumeWidth / 100; height = cOsd::OsdHeight() * config.volumeHeight / 100; int top = (cOsd::OsdHeight() - height) - config.volumeBorderBottom; int left = (cOsd::OsdWidth() - width) / 2; osd = CreateOsd(left, top, width, height); pixmapBackgroundTop = osd->CreatePixmap(1, cRect(0, 0, width, height/2)); pixmapBackgroundBottom = osd->CreatePixmap(1, cRect(0, height/2, width, height/2)); if (config.doBlending) { DrawBlendedBackground(pixmapBackgroundTop, Theme.Color(clrChannelBackground), Theme.Color(clrChannelBackBlend), true); DrawBlendedBackground(pixmapBackgroundBottom, Theme.Color(clrChannelBackground), Theme.Color(clrChannelBackBlend), false); } else { pixmapBackgroundTop->Fill(Theme.Color(clrChannelBackground)); pixmapBackgroundBottom->Fill(Theme.Color(clrChannelBackground)); } int cornerSize = height/4; if (cornerSize > 2) { pixmapBackgroundTop->DrawEllipse(cRect(0, 0, cornerSize, cornerSize), clrTransparent, -2); pixmapBackgroundTop->DrawEllipse(cRect(width - cornerSize, 0, cornerSize, cornerSize), clrTransparent, -1); pixmapBackgroundBottom->DrawEllipse(cRect(0, cornerSize, cornerSize, cornerSize), clrTransparent, -3); pixmapBackgroundBottom->DrawEllipse(cRect(width - cornerSize, cornerSize, cornerSize, cornerSize), clrTransparent, -4); } labelHeight = height/3; pixmapLabel = osd->CreatePixmap(2, cRect(0, 5, width, labelHeight)); progressBarWidth = 0.9 * width; progressBarHeight = 0.3 * height; if (progressBarHeight%2 != 0) progressBarHeight++; pixmapProgressBar = osd->CreatePixmap(2, cRect((width - progressBarWidth) / 2, (height - progressBarHeight)*2/3, progressBarWidth, progressBarHeight)); if (config.volumeFadeTime) { pixmapBackgroundTop->SetAlpha(0); pixmapBackgroundBottom->SetAlpha(0); pixmapProgressBar->SetAlpha(0); pixmapLabel->SetAlpha(0); } font = cFont::CreateFont(config.fontName, labelHeight - 6 + config.fontVolume); } cNopacityDisplayVolume::~cNopacityDisplayVolume() { Cancel(-1); while (Active()) cCondWait::SleepMs(10); osd->DestroyPixmap(pixmapBackgroundTop); osd->DestroyPixmap(pixmapBackgroundBottom); osd->DestroyPixmap(pixmapLabel); osd->DestroyPixmap(pixmapProgressBar); delete font; delete osd; } void cNopacityDisplayVolume::SetVolume(int Current, int Total, bool Mute) { pixmapLabel->Fill(clrTransparent); cString label = cString::sprintf("%s: %d", tr("Volume"), Current); pixmapLabel->DrawText(cPoint((width - font->Width(*label)) / 2, (labelHeight - font->Height()) / 2), *label, Theme.Color(clrVolumeFont), clrTransparent, font); if (Mute) { cBitmap bmMute(mute_xpm); pixmapLabel->DrawBitmap(cPoint(width - 2*bmMute.Width(), (labelHeight - bmMute.Height()) / 2), bmMute, Theme.Color(clrDiskAlert), clrTransparent); } DrawProgressBar(Current, Total); } void cNopacityDisplayVolume::DrawProgressBar(int Current, int Total) { pixmapProgressBar->Fill(clrTransparent); if (progressBarHeight < 5) return; double percent = ((double)Current) / (double)Total; int barWidth = progressBarWidth - progressBarHeight; if ((Current > 0) || (Total > 0)) { pixmapProgressBar->DrawEllipse(cRect(0, 0, progressBarHeight, progressBarHeight), Theme.Color(clrProgressBarBack)); pixmapProgressBar->DrawEllipse(cRect(progressBarWidth - progressBarHeight, 0, progressBarHeight, progressBarHeight), Theme.Color(clrProgressBarBack)); pixmapProgressBar->DrawRectangle(cRect(progressBarHeight/2, 0, progressBarWidth - progressBarHeight, progressBarHeight), Theme.Color(clrProgressBarBack)); pixmapProgressBar->DrawEllipse(cRect(1, 1, progressBarHeight-2, progressBarHeight-2), Theme.Color(clrProgressBarBlend)); if (Current > 0) { tColor colAct = DrawProgressbarBackground(progressBarHeight / 2 - 1, 1, barWidth * percent - 2, progressBarHeight - 2); pixmapProgressBar->DrawEllipse(cRect(barWidth * percent, 1, progressBarHeight-2, progressBarHeight-2), colAct); } } } tColor cNopacityDisplayVolume::DrawProgressbarBackground(int left, int top, int width, int height) { tColor clr1 = Theme.Color(clrProgressBar); tColor clr2 = Theme.Color(clrProgressBarBlend); tColor clr = 0x00000000; int step = width / 256; int alpha = 0x0; int alphaStep; int maximum = 0; if (step == 0) { //width < 256 step = 1; alphaStep = 256 / width; maximum = width; } else { //width > 256 alphaStep = 0x1; maximum = 256; } int x = 0; for (int i = 0; i < maximum; i++) { x = left + i*step; clr = AlphaBlend(clr1, clr2, alpha); pixmapProgressBar->DrawRectangle(cRect(x,top,step,height), clr); alpha += alphaStep; } if (step > 0) { int rest = width - step*256; pixmapProgressBar->DrawRectangle(cRect(left+step*256, top, rest, height), clr); } return clr; } void cNopacityDisplayVolume::Flush(void) { if (initial) if (config.volumeFadeTime) Start(); initial = false; osd->Flush(); } void cNopacityDisplayVolume::Action(void) { uint64_t Start = cTimeMs::Now(); while (Running()) { uint64_t Now = cTimeMs::Now(); cPixmap::Lock(); double t = min(double(Now - Start) / FadeTime, 1.0); int Alpha = t * ALPHA_OPAQUE; pixmapBackgroundTop->SetAlpha(Alpha); pixmapBackgroundBottom->SetAlpha(Alpha); pixmapProgressBar->SetAlpha(Alpha); pixmapLabel->SetAlpha(Alpha); if (Running()) osd->Flush(); cPixmap::Unlock(); int Delta = cTimeMs::Now() - Now; if (Running() && (Delta < FrameTime)) cCondWait::SleepMs(FrameTime - Delta); if ((int)(Now - Start) > FadeTime) break; } }