summaryrefslogtreecommitdiff
path: root/PLUGINS/src/osddemo
diff options
context:
space:
mode:
authorKlaus Schmidinger <vdr@tvdr.de>2011-02-20 15:12:56 +0100
committerKlaus Schmidinger <vdr@tvdr.de>2011-02-20 15:12:56 +0100
commit6c7089afd257df3a9033a5bd2f205b8f03eccfaf (patch)
treed146c9d9c4b37d52b966607d7c1ef9e3b85dcf0f /PLUGINS/src/osddemo
parent343071cc6ab69169312ae04a7888cd55a79395d0 (diff)
downloadvdr-6c7089afd257df3a9033a5bd2f205b8f03eccfaf.tar.gz
vdr-6c7089afd257df3a9033a5bd2f205b8f03eccfaf.tar.bz2
Implemented support for TrueColor OSD
Diffstat (limited to 'PLUGINS/src/osddemo')
-rw-r--r--PLUGINS/src/osddemo/HISTORY4
-rw-r--r--PLUGINS/src/osddemo/README7
-rw-r--r--PLUGINS/src/osddemo/osddemo.c367
3 files changed, 375 insertions, 3 deletions
diff --git a/PLUGINS/src/osddemo/HISTORY b/PLUGINS/src/osddemo/HISTORY
index 4217cb1e..1270fbf6 100644
--- a/PLUGINS/src/osddemo/HISTORY
+++ b/PLUGINS/src/osddemo/HISTORY
@@ -21,3 +21,7 @@ VDR Plugin 'osddemo' Revision History
2008-04-13: Version 0.1.3
- Fixed setting the OSD level (thanks to Wolfgang Rohdewald).
+
+2011-02-20: Version 0.2.0
+
+- Added support for TrueColor OSD.
diff --git a/PLUGINS/src/osddemo/README b/PLUGINS/src/osddemo/README
index 50d36d8c..90ae2952 100644
--- a/PLUGINS/src/osddemo/README
+++ b/PLUGINS/src/osddemo/README
@@ -19,4 +19,11 @@ Demonstration of how a plugin can have its very own OSD setup.
It's a very primitive game that opens a small window in which the
user can draw lines with the Up, Down, Left and Right buttons.
The color buttons are used to switch color.
+
+On a VDR system with TrueColor support it displays some of the
+possibilities available with the TrueColor OSD. Once the "Animation"
+pixmap is displayed, it can be moved around with the Up, Down, Left
+and Right buttons. The Red button turns off the "Tiled Pixmaps"
+display, and the Green button toggles the color display.
+
Press Ok to close the window.
diff --git a/PLUGINS/src/osddemo/osddemo.c b/PLUGINS/src/osddemo/osddemo.c
index 2a9e09a6..87d94638 100644
--- a/PLUGINS/src/osddemo/osddemo.c
+++ b/PLUGINS/src/osddemo/osddemo.c
@@ -3,12 +3,13 @@
*
* See the README file for copyright information and how to reach the author.
*
- * $Id: osddemo.c 2.1 2008/04/13 12:59:57 kls Exp $
+ * $Id: osddemo.c 2.2 2011/02/20 15:06:18 kls Exp $
*/
+#include <vdr/osd.h>
#include <vdr/plugin.h>
-static const char *VERSION = "0.1.3";
+static const char *VERSION = "0.2.0";
static const char *DESCRIPTION = "Demo of arbitrary OSD setup";
static const char *MAINMENUENTRY = "Osd Demo";
@@ -22,7 +23,7 @@ private:
tColor color;
public:
cLineGame(void);
- ~cLineGame();
+ virtual ~cLineGame();
virtual void Show(void);
virtual eOSState ProcessKey(eKeys Key);
};
@@ -73,6 +74,364 @@ eOSState cLineGame::ProcessKey(eKeys Key)
return state;
}
+// --- cTrueColorDemo --------------------------------------------------------
+
+class cTrueColorDemo : public cOsdObject, public cThread {
+private:
+ cOsd *osd;
+ cPoint cursor;
+ cRect cursorLimits;
+ bool clockwise;
+ cPixmap *destroyablePixmap;
+ cPixmap *toggleablePixmap;
+ virtual void Action(void);
+ cPixmap *CreateTextPixmap(const char *s, int Line, int Layer, tColor ColorFg, tColor ColorBg, const cFont *Font = NULL);
+public:
+ cTrueColorDemo(void);
+ virtual ~cTrueColorDemo();
+ virtual void Show(void);
+ virtual eOSState ProcessKey(eKeys Key);
+ };
+
+cTrueColorDemo::cTrueColorDemo(void)
+{
+ osd = NULL;
+ clockwise = true;
+ destroyablePixmap = NULL;
+ toggleablePixmap = NULL;
+}
+
+cTrueColorDemo::~cTrueColorDemo()
+{
+ delete osd;
+}
+
+cPixmap *cTrueColorDemo::CreateTextPixmap(const char *s, int Line, int Layer, tColor ColorFg, tColor ColorBg, const cFont *Font)
+{
+ if (!Font)
+ Font = cFont::GetFont(fontOsd);
+ const int h = Font->Height(s);
+ int w = Font->Width(s);
+ cPixmap *Pixmap = osd->CreatePixmap(Layer, cRect((osd->Width() - w) / 2, Line, w, h));
+ if (Pixmap) {
+ Pixmap->Clear();
+ Pixmap->SetAlpha(0);
+ Pixmap->DrawText(cPoint(0, 0), s, ColorFg, ColorBg, Font);
+ }
+ return Pixmap;
+}
+
+void cTrueColorDemo::Action(void)
+{
+ cPixmap *FadeInPixmap = NULL;
+ cPixmap *FadeOutPixmap = NULL;
+ cPixmap *MovePixmap = NULL;
+ cPixmap *NextPixmap = NULL;
+ cPixmap *TilePixmap = NULL;
+ cPixmap *ScrollPixmap = NULL;
+ cPixmap *AnimPixmap = NULL;
+ int FrameTime = 40; // ms
+ int FadeTime = 1000; // ms
+ int MoveTime = 4000; // ms
+ int TileTime = 6000; // ms
+ int ScrollWaitTime = 1000; // ms
+ int ScrollLineTime = 200; // ms
+ int ScrollTotalTime = 8000; // ms
+ uint64_t Start = 0;
+ uint64_t ScrollStartTime = 0;
+ int ScrollLineNumber = 0;
+ cPoint MoveStart, MoveEnd;
+ cPoint TileStart, TileEnd;
+ cPoint ScrollStart, ScrollEnd;
+ int Line = osd->Height() / 20;
+ int StartLine = Line;
+ cPoint OldCursor;
+ int State = 0;
+ while (Running()) {
+ cPixmap::Lock();
+ bool Animated = false;
+ uint64_t Now = cTimeMs::Now();
+ if (FadeInPixmap) {
+ double t = min(double(Now - Start) / FadeTime, 1.0);
+ int Alpha = t * ALPHA_OPAQUE;
+ FadeInPixmap->SetAlpha(Alpha);
+ if (t >= 1)
+ FadeInPixmap = NULL;
+ Animated = true;
+ }
+ if (FadeOutPixmap) {
+ double t = min(double(Now - Start) / FadeTime, 1.0);
+ int Alpha = ALPHA_OPAQUE - t * ALPHA_OPAQUE;
+ FadeOutPixmap->SetAlpha(Alpha);
+ if (t >= 1)
+ FadeOutPixmap = NULL;
+ Animated = true;
+ }
+ if (MovePixmap) {
+ double t = min(double(Now - Start) / MoveTime, 1.0);
+ int x = MoveStart.X() + t * (MoveEnd.X() - MoveStart.X());
+ int y = MoveStart.Y() + t * (MoveEnd.Y() - MoveStart.Y());
+ cRect r = MovePixmap->ViewPort();
+ r.SetPoint(x, y);
+ MovePixmap->SetViewPort(r);
+ if (t >= 1)
+ MovePixmap = NULL;
+ Animated = true;
+ }
+ if (TilePixmap) {
+ double t = min(double(Now - Start) / TileTime, 1.0);
+ int x = TileStart.X() + t * (TileEnd.X() - TileStart.X());
+ int y = TileStart.Y() + t * (TileEnd.Y() - TileStart.Y());
+ TilePixmap->SetDrawPortPoint(cPoint(x, y));
+ if (t >= 1) {
+ destroyablePixmap = TilePixmap;
+ TilePixmap = NULL;
+ }
+ Animated = true;
+ }
+ if (ScrollPixmap) {
+ if (int(Now - Start) > ScrollWaitTime) {
+ if (ScrollStartTime) {
+ double t = min(double(Now - ScrollStartTime) / ScrollLineTime, 1.0);
+ int x = ScrollStart.X() + t * (ScrollEnd.X() - ScrollStart.X());
+ int y = ScrollStart.Y() + t * (ScrollEnd.Y() - ScrollStart.Y());
+ ScrollPixmap->SetDrawPortPoint(cPoint(x, y));
+ if (t >= 1) {
+ if (int(Now - Start) < ScrollTotalTime) {
+ cRect r = ScrollPixmap->DrawPort();
+ r.SetPoint(-r.X(), -r.Y());
+ ScrollPixmap->Pan(cPoint(0, 0), r);
+ const cFont *Font = cFont::GetFont(fontOsd);
+ cString s = cString::sprintf("Line %d", ++ScrollLineNumber);
+ ScrollPixmap->DrawRectangle(cRect(0, ScrollPixmap->ViewPort().Height(), ScrollPixmap->DrawPort().Width(), ScrollPixmap->DrawPort().Height()), clrTransparent);
+ ScrollPixmap->DrawText(cPoint(0, ScrollPixmap->ViewPort().Height()), s, clrYellow, clrTransparent, Font);
+ ScrollStartTime = Now;
+ }
+ else {
+ FadeOutPixmap = ScrollPixmap;
+ ScrollPixmap = NULL;
+ Start = cTimeMs::Now();
+ }
+ }
+ }
+ else
+ ScrollStartTime = Now;
+ }
+ Animated = true;
+ }
+ if (AnimPixmap) {
+ int d = AnimPixmap->ViewPort().Height();
+ if (clockwise)
+ d = -d;
+ cPoint p = AnimPixmap->DrawPort().Point().Shifted(0, d);
+ if (clockwise && p.Y() <= -AnimPixmap->DrawPort().Height())
+ p.SetY(0);
+ else if (!clockwise && p.Y() > 0)
+ p.SetY(-(AnimPixmap->DrawPort().Height() - AnimPixmap->ViewPort().Height()));
+ AnimPixmap->SetDrawPortPoint(p);
+ }
+ if (!Animated) {
+ switch (State) {
+ case 0: {
+ if (cFont *Font = cFont::CreateFont(DefaultFontOsd, osd->Height() / 10)) {
+ FadeInPixmap = CreateTextPixmap("VDR", Line, 1, clrYellow, clrTransparent, Font);
+ if (FadeInPixmap)
+ Line += FadeInPixmap->DrawPort().Height();
+ delete Font;
+ Start = cTimeMs::Now();
+ }
+ State++;
+ }
+ break;
+ case 1: {
+ FadeInPixmap = CreateTextPixmap("Video Disk Recorder", Line, 3, clrYellow, clrTransparent);
+ if (FadeInPixmap)
+ Line += FadeInPixmap->DrawPort().Height();
+ Start = cTimeMs::Now();
+ State++;
+ }
+ break;
+ case 2: {
+ FadeInPixmap = CreateTextPixmap("True Color OSD Demo", Line, 1, clrYellow, clrTransparent);
+ if (FadeInPixmap)
+ Line += FadeInPixmap->DrawPort().Height();
+ Start = cTimeMs::Now();
+ State++;
+ }
+ break;
+ case 3: {
+ if (cFont *Font = cFont::CreateFont(DefaultFontOsd, osd->Height() / 10)) {
+ NextPixmap = CreateTextPixmap("Millions of colors", Line, 1, clrYellow, clrTransparent, Font);
+ if (NextPixmap) {
+ FadeInPixmap = NextPixmap;
+ }
+ Start = cTimeMs::Now();
+ StartLine = Line;
+ Line += NextPixmap->DrawPort().Height();
+ }
+ State++;
+ }
+ break;
+ case 4: {
+ Line += osd->Height() / 10;
+ int w = osd->Width() / 2;
+ int h = osd->Height() - Line - osd->Height() / 10;
+ cImage Image(cSize(w, h));
+ for (int y = 0; y < h; y++) {
+ for (int x = 0; x < w; x++)
+ Image.SetPixel(cPoint(x, y), HsvToColor(360 * double(x) / w, 1 - double(y) / h, 1) | 0xDF000000);
+ }
+ if (cPixmap *Pixmap = osd->CreatePixmap(2, cRect((osd->Width() - w) / 2, Line, w, h))) {
+ Pixmap->DrawImage(cPoint(0, 0), Image);
+ toggleablePixmap = Pixmap;
+ }
+ State++;
+ }
+ break;
+ case 5: {
+ if (NextPixmap) {
+ MovePixmap = NextPixmap;
+ MoveStart = MovePixmap->ViewPort().Point();
+ MoveEnd.Set(osd->Width() - MovePixmap->ViewPort().Width(), osd->Height() - MovePixmap->ViewPort().Height());
+ Start = cTimeMs::Now();
+ }
+ State++;
+ }
+ break;
+ case 6: {
+ TilePixmap = CreateTextPixmap("Tiled Pixmaps", StartLine, 1, clrRed, clrWhite);
+ if (TilePixmap) {
+ TilePixmap->SetViewPort(TilePixmap->ViewPort().Grown(TilePixmap->DrawPort().Width(), TilePixmap->DrawPort().Height()));
+ TilePixmap->SetAlpha(200);
+ TilePixmap->SetTile(true);
+ TileStart = TilePixmap->DrawPort().Point();
+ TileEnd = TileStart.Shifted(TilePixmap->ViewPort().Width(), TilePixmap->ViewPort().Height());
+ MovePixmap = TilePixmap;
+ MoveStart = MovePixmap->ViewPort().Point();
+ MoveEnd.Set(10, osd->Height() - MovePixmap->ViewPort().Height() - 10);
+ Start = cTimeMs::Now();
+ }
+ State++;
+ }
+ break;
+ case 7: {
+ const cFont *Font = cFont::GetFont(fontOsd);
+ const char *Text = "Scrolling Pixmaps";
+ int w = Font->Width(Text);
+ int h = Font->Height();
+ if (cPixmap *Pixmap = osd->CreatePixmap(2, cRect((osd->Width() - w) / 2, StartLine, w, 2 * h), cRect(0, 0, w, 3 * h))) {
+ Pixmap->Clear();
+ Pixmap->DrawText(cPoint(0, 0), Text, clrYellow, clrTransparent, Font);
+ cString s = cString::sprintf("Line %d", ++ScrollLineNumber);
+ Pixmap->DrawText(cPoint(0, Pixmap->ViewPort().Height()), s, clrYellow, clrTransparent, Font);
+ ScrollPixmap = Pixmap;
+ ScrollStart.Set(0, 0);
+ ScrollEnd.Set(0, -h);
+ Start = cTimeMs::Now();
+ }
+ State++;
+ }
+ break;
+ case 8: {
+ const cFont *Font = cFont::GetFont(fontSml);
+ const char *Text = "Animation";
+ const int Size = Font->Width(Text) + 10;
+ const int NumDots = 12;
+ const int AnimFrames = NumDots;
+ AnimPixmap = osd->CreatePixmap(3, cRect((osd->Width() - Size) / 2, StartLine, Size, Size), cRect(0, 0, Size, Size * AnimFrames));
+ if (AnimPixmap) {
+ AnimPixmap->SetAlpha(0);
+ AnimPixmap->Clear();
+ const int Diameter = Size / 5;
+ int xc = Size / 2 - Diameter / 2;
+ for (int Frame = 0; Frame < AnimFrames; Frame++) {
+ AnimPixmap->DrawEllipse(cRect(0, Frame * Size, Size, Size), 0xDDFFFFFF);
+ int yc = Frame * Size + Size / 2 - Diameter / 2;
+ int Color = 0xFF;
+ int Delta = Color / NumDots / 3;
+ for (int a = 0; a < NumDots; a++) {
+ double t = 2 * M_PI * (Frame + a) / NumDots;
+ int x = xc + ((Size - Diameter) / 2 - 5) * cos(t);
+ int y = yc + ((Size - Diameter) / 2 - 5) * sin(t);
+ AnimPixmap->DrawEllipse(cRect(x, y, Diameter, Diameter), ArgbToColor(0xFF, Color, Color, Color));
+ Color -= Delta;
+ }
+ AnimPixmap->DrawText(cPoint(0, Frame * Size), "Animation", clrBlack, clrTransparent, cFont::GetFont(fontSml), Size, Size, taCenter);
+ }
+ FadeInPixmap = AnimPixmap;
+ LOCK_THREAD;
+ OldCursor = cursor = AnimPixmap->ViewPort().Point();
+ cursorLimits.Set(0, 0, osd->Width(), osd->Height());
+ cursorLimits.SetRight(cursorLimits.Right() - Size);
+ cursorLimits.SetBottom(cursorLimits.Bottom() - Size);
+ cursorLimits.Grow(-10, -10);
+ Start = cTimeMs::Now();
+ }
+ State++;
+ }
+ break;
+ case 9: {
+ LOCK_THREAD;
+ if (cursor != OldCursor) {
+ MovePixmap = AnimPixmap;
+ MoveStart = MovePixmap->ViewPort().Point();
+ MoveEnd = OldCursor = cursor;
+ MoveTime = 500;
+ Start = cTimeMs::Now();
+ }
+ }
+ break;
+ }
+ }
+ osd->Flush();
+ cPixmap::Unlock();
+ int Delta = cTimeMs::Now() - Now;
+ if (Delta < FrameTime)
+ cCondWait::SleepMs(FrameTime - Delta);
+ }
+}
+
+void cTrueColorDemo::Show(void)
+{
+ osd = cOsdProvider::NewOsd(cOsd::OsdLeft(), cOsd::OsdTop(), 50);
+ if (osd) {
+ tArea Area = { 0, 0, cOsd::OsdWidth() - 1, cOsd::OsdHeight() - 1, 32 };
+ if (osd->SetAreas(&Area, 1) == oeOk) {
+ osd->DrawRectangle(0, 0, osd->Width() -1 , osd->Height() - 1, clrGray50);
+ osd->Flush();
+ Start();
+ }
+ }
+}
+
+eOSState cTrueColorDemo::ProcessKey(eKeys Key)
+{
+ eOSState state = cOsdObject::ProcessKey(Key);
+ if (state == osUnknown) {
+ LOCK_PIXMAPS;
+ LOCK_THREAD;
+ const int d = 80;
+ switch (Key & ~k_Repeat) {
+ case kUp: cursor.SetY(max(cursorLimits.Top(), cursor.Y() - d)); clockwise = false; break;
+ case kDown: cursor.SetY(min(cursorLimits.Bottom(), cursor.Y() + d)); clockwise = true; break;
+ case kLeft: cursor.SetX(max(cursorLimits.Left(), cursor.X() - d)); clockwise = false; break;
+ case kRight: cursor.SetX(min(cursorLimits.Right(), cursor.X() + d)); clockwise = true; break;
+ case kRed: if (destroyablePixmap) {
+ osd->DestroyPixmap(destroyablePixmap);
+ destroyablePixmap = NULL;
+ }
+ break;
+ case kGreen: if (toggleablePixmap)
+ toggleablePixmap->SetLayer(-toggleablePixmap->Layer());
+ break;
+ case kOk: return osEnd;
+ default: return state;
+ }
+ state = osContinue;
+ }
+ return state;
+}
+
// --- cPluginOsddemo --------------------------------------------------------
class cPluginOsddemo : public cPlugin {
@@ -131,6 +490,8 @@ void cPluginOsddemo::Housekeeping(void)
cOsdObject *cPluginOsddemo::MainMenuAction(void)
{
// Perform the action when selected from the main VDR menu.
+ if (cOsdProvider::SupportsTrueColor())
+ return new cTrueColorDemo;
return new cLineGame;
}