mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Implemented 'skins' and 'themes'
This commit is contained in:
parent
7aab06d8b1
commit
5d99df7b77
@ -962,3 +962,7 @@ Marcus M
|
|||||||
|
|
||||||
Pekka Virtanen <pekka.virtanen@sci.fi>
|
Pekka Virtanen <pekka.virtanen@sci.fi>
|
||||||
for adding language code handling to the subtitling descriptor in 'libsi'
|
for adding language code handling to the subtitling descriptor in 'libsi'
|
||||||
|
|
||||||
|
John Kennedy <rkennedy@ix.netcom.com>
|
||||||
|
for publishing "A Fast Bresenham Algorithm For Drawing Ellipses" (found at
|
||||||
|
http://homepage.smc.edu/kennedy_john/BELIPSE.PDF)
|
||||||
|
34
HISTORY
34
HISTORY
@ -2746,7 +2746,7 @@ Video Disk Recorder Revision History
|
|||||||
- Now explicitly turning on the LNB power at startup, because newer drivers don't
|
- Now explicitly turning on the LNB power at startup, because newer drivers don't
|
||||||
do this any more (thanks to Oliver Endriss for pointing this out).
|
do this any more (thanks to Oliver Endriss for pointing this out).
|
||||||
|
|
||||||
2004-03-28: Version 1.3.7
|
2004-05-16: Version 1.3.7
|
||||||
|
|
||||||
- Fixed a memory leak in thread handling when using NPTL (thanks to Jon Burgess).
|
- Fixed a memory leak in thread handling when using NPTL (thanks to Jon Burgess).
|
||||||
- Fixed handling Setup.RecordDolbyDigital, which was broken since version 1.1.6.
|
- Fixed handling Setup.RecordDolbyDigital, which was broken since version 1.1.6.
|
||||||
@ -2759,3 +2759,35 @@ Video Disk Recorder Revision History
|
|||||||
- Moved several menu item classes from menu.c to menuitems.[hc] to make them
|
- Moved several menu item classes from menu.c to menuitems.[hc] to make them
|
||||||
available for plugins.
|
available for plugins.
|
||||||
- The epg2html.pl script now handles '|' in description texts.
|
- The epg2html.pl script now handles '|' in description texts.
|
||||||
|
- The new setup option "OSD/Use small font" can be used to control the use of
|
||||||
|
the small font (see MANUAL for details).
|
||||||
|
- Swapped osd.[hc] and osdbase.[hc] to have the virtual OSD base class named cOsd.
|
||||||
|
Plugins may need to adjust their #include statements.
|
||||||
|
- Colors are now given as AARRGGBB instead of AABBGGRR. The values are mapped to
|
||||||
|
the driver's (wrong) sequence in dvbosd.c (this should really be fixed in the
|
||||||
|
driver, together with the endian problem).
|
||||||
|
- The new OSD setup parameters "Left" and "Top" can be used to define the top left
|
||||||
|
corner of the OSD.
|
||||||
|
- The OSD size prameters are now in pixel (as opposed to formerly characters).
|
||||||
|
When reading a 'setup.conf' file from an older version of VDR, the OSDwidth
|
||||||
|
and OSDheight values will be converted to pixel automatically.
|
||||||
|
- The OSD is now fully device independent. See the comments in VDR/osd.h and the
|
||||||
|
description in PLUGINS.html for information on how a plugin can implement an OSD
|
||||||
|
display on arbitrary hardware.
|
||||||
|
- The OSD (actually its cBitmap class) can now handle XPM files. There are several
|
||||||
|
XPM files in the VDR/symbols directory which can be used by skins (some of these
|
||||||
|
have been taken from the "elchi" patch). See VDR/skinsttng.c for examples on how
|
||||||
|
to use these.
|
||||||
|
- Due to the changes in the OSD handling the DEBUG_OSD option for a textual OSD
|
||||||
|
has been dropped. There will be a plugin that implements a skin with this
|
||||||
|
functionality later.
|
||||||
|
- The entire OSD display can now be implemented via "skins". See VDR/skins.[hc],
|
||||||
|
VDR/skinclassic.[hc], VDR/skinsttng.[hc] and PLUGINS.html for information on how
|
||||||
|
a plugin can implement its own skin. By default VDR comes with a "Classic" skin
|
||||||
|
that implements the OSD display known from previous versions, and the new skin
|
||||||
|
named "ST:TNG Panels", which is also the default skin now. The actual skin can
|
||||||
|
be selected through "Setup/OSD/Skin".
|
||||||
|
- The colors used in a skin can now be configured using "themes". See PLUGINS.html
|
||||||
|
for information on how a skin can make use of themes, and man vdr(5) for the
|
||||||
|
structure of a theme file. The actual theme to use can be selected through
|
||||||
|
"Setup/OSD/Theme".
|
||||||
|
5
INSTALL
5
INSTALL
@ -40,11 +40,6 @@ following values in the 'make' call to activate the respective control mode:
|
|||||||
|
|
||||||
If you want to disable control via the PC keyboard, you can add NO_KBD=1
|
If you want to disable control via the PC keyboard, you can add NO_KBD=1
|
||||||
to the 'make' call.
|
to the 'make' call.
|
||||||
Adding "DEBUG_OSD=1" will use the PC screen (or current window)
|
|
||||||
to display texts instead of the DVB card's on-screen display
|
|
||||||
interface. These modes are useful when testing new menus if you
|
|
||||||
only have a remote connection to the VDR (which, in my case, is
|
|
||||||
located in the living room and has neither a monitor nor a keyboard).
|
|
||||||
|
|
||||||
If your video directory will be on a VFAT partition, add the compile
|
If your video directory will be on a VFAT partition, add the compile
|
||||||
time switch
|
time switch
|
||||||
|
17
MANUAL
17
MANUAL
@ -425,13 +425,26 @@ Version 1.2
|
|||||||
|
|
||||||
Language = English Defines the language used to display the OSD texts.
|
Language = English Defines the language used to display the OSD texts.
|
||||||
|
|
||||||
Width = 52 The width and height of the OSD .
|
Skin = ST:TNG Panels Defines the "skin" used to display the OSD menus.
|
||||||
Height = 18 The valid ranges are width=40...56, height=12...21.
|
|
||||||
|
Theme = Default Defines the "theme" to use with the current skin.
|
||||||
|
|
||||||
|
Left = 54 The top and left offset of the OSD.
|
||||||
|
Top = 45 The valid ranges are left=0...672, top=0...567.
|
||||||
|
|
||||||
|
Width = 624 The width and height of the OSD.
|
||||||
|
Height = 486 The valid ranges are width=480...672, height=324...567.
|
||||||
|
The Width must be a multiple of 8.
|
||||||
|
|
||||||
Message time = 1 The time (in seconds) how long an informational
|
Message time = 1 The time (in seconds) how long an informational
|
||||||
message shall be displayed on the OSD. The valid range
|
message shall be displayed on the OSD. The valid range
|
||||||
is 1...60.
|
is 1...60.
|
||||||
|
|
||||||
|
Use small font = 1 Defines whether the small font shall be used. 0 means never
|
||||||
|
use the small font, 1 means use the small font wherever the
|
||||||
|
current skin wants to, and 2 means always use the small
|
||||||
|
font.
|
||||||
|
|
||||||
Channel info position = bottom
|
Channel info position = bottom
|
||||||
The position of the channel info window in the OSD
|
The position of the channel info window in the OSD
|
||||||
(either 'bottom' or 'top').
|
(either 'bottom' or 'top').
|
||||||
|
12
Makefile
12
Makefile
@ -4,7 +4,7 @@
|
|||||||
# See the main source file 'vdr.c' for copyright information and
|
# See the main source file 'vdr.c' for copyright information and
|
||||||
# how to reach the author.
|
# how to reach the author.
|
||||||
#
|
#
|
||||||
# $Id: Makefile 1.65 2004/01/18 14:16:53 kls Exp $
|
# $Id: Makefile 1.66 2004/05/08 09:15:00 kls Exp $
|
||||||
|
|
||||||
.DELETE_ON_ERROR:
|
.DELETE_ON_ERROR:
|
||||||
|
|
||||||
@ -36,8 +36,9 @@ SILIB = $(LSIDIR)/libsi.a
|
|||||||
OBJS = audio.o channels.o ci.o config.o cutter.o device.o diseqc.o dvbdevice.o dvbosd.o\
|
OBJS = audio.o channels.o ci.o config.o cutter.o device.o diseqc.o dvbdevice.o dvbosd.o\
|
||||||
dvbplayer.o dvbspu.o eit.o eitscan.o epg.o filter.o font.o i18n.o interface.o keys.o\
|
dvbplayer.o dvbspu.o eit.o eitscan.o epg.o filter.o font.o i18n.o interface.o keys.o\
|
||||||
lirc.o menu.o menuitems.o nit.o osdbase.o osd.o pat.o player.o plugin.o rcu.o\
|
lirc.o menu.o menuitems.o nit.o osdbase.o osd.o pat.o player.o plugin.o rcu.o\
|
||||||
receiver.o recorder.o recording.o remote.o remux.o ringbuffer.o sdt.o sections.o sources.o\
|
receiver.o recorder.o recording.o remote.o remux.o ringbuffer.o sdt.o sections.o\
|
||||||
spu.o status.o svdrp.o thread.o timers.o tools.o transfer.o vdr.o videodir.o
|
skinclassic.o skins.o skinsttng.o sources.o spu.o status.o svdrp.o themes.o thread.o\
|
||||||
|
timers.o tools.o transfer.o vdr.o videodir.o
|
||||||
|
|
||||||
FIXFONT_ISO8859_1 = -adobe-courier-bold-r-normal--25-*-100-100-m-*-iso8859-1
|
FIXFONT_ISO8859_1 = -adobe-courier-bold-r-normal--25-*-100-100-m-*-iso8859-1
|
||||||
OSDFONT_ISO8859_1 = -adobe-helvetica-medium-r-normal--23-*-100-100-p-*-iso8859-1
|
OSDFONT_ISO8859_1 = -adobe-helvetica-medium-r-normal--23-*-100-100-p-*-iso8859-1
|
||||||
@ -60,11 +61,6 @@ DEFINES += -D_GNU_SOURCE
|
|||||||
DEFINES += -DVIDEODIR=\"$(VIDEODIR)\"
|
DEFINES += -DVIDEODIR=\"$(VIDEODIR)\"
|
||||||
DEFINES += -DPLUGINDIR=\"$(PLUGINLIBDIR)\"
|
DEFINES += -DPLUGINDIR=\"$(PLUGINLIBDIR)\"
|
||||||
|
|
||||||
ifdef DEBUG_OSD
|
|
||||||
DEFINES += -DDEBUG_OSD
|
|
||||||
NCURSESLIB = -lncurses
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef VFAT
|
ifdef VFAT
|
||||||
# for people who want their video directory on a VFAT partition
|
# for people who want their video directory on a VFAT partition
|
||||||
DEFINES += -DVFAT
|
DEFINES += -DVFAT
|
||||||
|
215
PLUGINS.html
215
PLUGINS.html
@ -9,17 +9,20 @@
|
|||||||
<center><b>Version 1.3</b></center>
|
<center><b>Version 1.3</b></center>
|
||||||
<p>
|
<p>
|
||||||
<center>
|
<center>
|
||||||
Copyright © 2003 Klaus Schmidinger<br>
|
Copyright © 2004 Klaus Schmidinger<br>
|
||||||
<a href="mailto:kls@cadsoft.de">kls@cadsoft.de</a><br>
|
<a href="mailto:kls@cadsoft.de">kls@cadsoft.de</a><br>
|
||||||
<a href="http://www.cadsoft.de/vdr">www.cadsoft.de/vdr</a>
|
<a href="http://www.cadsoft.de/vdr">www.cadsoft.de/vdr</a>
|
||||||
</center>
|
</center>
|
||||||
<p>
|
<p>
|
||||||
<!--X1.2.6--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%>
|
<!--X1.2.6--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%>
|
||||||
Important modifications introduced in version 1.2.6 are marked like this.
|
Important modifications introduced in version 1.2.6 are marked like this.
|
||||||
<!--X1.2.6--></td></tr></table>
|
<!--X1.2.6--></td></tr></table>
|
||||||
<!--X1.3.0--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%>
|
<!--X1.3.0--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%>
|
||||||
Important modifications introduced in version 1.3.0 are marked like this.
|
Important modifications introduced in version 1.3.0 are marked like this.
|
||||||
<!--X1.3.0--></td></tr></table>
|
<!--X1.3.0--></td></tr></table>
|
||||||
|
<!--X1.3.7--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%>
|
||||||
|
Important modifications introduced in version 1.3.7 are marked like this.
|
||||||
|
<!--X1.3.7--></td></tr></table>
|
||||||
<p>
|
<p>
|
||||||
VDR provides an easy to use plugin interface that allows additional functionality
|
VDR provides an easy to use plugin interface that allows additional functionality
|
||||||
to be added to the program by implementing a dynamically loadable library file.
|
to be added to the program by implementing a dynamically loadable library file.
|
||||||
@ -67,10 +70,14 @@ structures and allows it to hook itself into specific areas to perform special a
|
|||||||
<li><a href="#Status monitor">Status monitor</a>
|
<li><a href="#Status monitor">Status monitor</a>
|
||||||
<li><a href="#Players">Players</a>
|
<li><a href="#Players">Players</a>
|
||||||
<li><a href="#Receivers">Receivers</a>
|
<li><a href="#Receivers">Receivers</a>
|
||||||
<!--X1.3.0--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%>
|
<!--X1.3.0--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%>
|
||||||
<li><a href="#Filters">Filters</a>
|
<li><a href="#Filters">Filters</a>
|
||||||
<!--X1.3.0--></td></tr></table>
|
<!--X1.3.0--></td></tr></table>
|
||||||
<li><a href="#The On Screen Display">The On Screen Display</a>
|
<li><a href="#The On Screen Display">The On Screen Display</a>
|
||||||
|
<!--X1.3.7--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%>
|
||||||
|
<li><a href="#Skins">Skins</a>
|
||||||
|
<li><a href="#Themes">Themes</a>
|
||||||
|
<!--X1.3.7--></td></tr></table>
|
||||||
<li><a href="#Devices">Devices</a>
|
<li><a href="#Devices">Devices</a>
|
||||||
<li><a href="#Dolby Digital">Dolby Digital</a>
|
<li><a href="#Dolby Digital">Dolby Digital</a>
|
||||||
<li><a href="#Remote Control">Remote Control</a>
|
<li><a href="#Remote Control">Remote Control</a>
|
||||||
@ -1207,7 +1214,7 @@ Mode</i>).
|
|||||||
If the <tt>cReceiver</tt> isn't needed any more, it may simply be <i>deleted</i>
|
If the <tt>cReceiver</tt> isn't needed any more, it may simply be <i>deleted</i>
|
||||||
and will automatically detach itself from the <tt>cDevice</tt>.
|
and will automatically detach itself from the <tt>cDevice</tt>.
|
||||||
|
|
||||||
<!--X1.3.0--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%>
|
<!--X1.3.0--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%>
|
||||||
<a name="Filters"><hr><h2>Filters</h2>
|
<a name="Filters"><hr><h2>Filters</h2>
|
||||||
|
|
||||||
<center><i><b>A Fistful of Datas</b></i></center><p>
|
<center><i><b>A Fistful of Datas</b></i></center><p>
|
||||||
@ -1253,35 +1260,166 @@ and will automatically detach itself from the <tt>cDevice</tt>.
|
|||||||
See VDR/eit.c or VDR/pat.c to learn how to process filter data.
|
See VDR/eit.c or VDR/pat.c to learn how to process filter data.
|
||||||
<!--X1.3.0--></td></tr></table>
|
<!--X1.3.0--></td></tr></table>
|
||||||
|
|
||||||
|
<!--X1.3.7--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%>
|
||||||
<a name="The On Screen Display"><hr><h2>The On Screen Display</h2>
|
<a name="The On Screen Display"><hr><h2>The On Screen Display</h2>
|
||||||
|
|
||||||
<center><i><b>Express yourself</b></i></center><p>
|
<center><i><b>Window to the world</b></i></center><p>
|
||||||
|
|
||||||
Most of the time a plugin should be able to access the OSD through the
|
|
||||||
standard mechanisms also used by VDR itself. However, these set up the OSD in
|
|
||||||
a manner of textual rows and columns, and automatically set the various
|
|
||||||
windows and color depths.
|
|
||||||
<p>
|
|
||||||
If a plugin needs to have total control over the OSD, it can call the
|
If a plugin needs to have total control over the OSD, it can call the
|
||||||
static function
|
static function
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
#include <vdr/osd.h>
|
#include <vdr/osd.h>
|
||||||
|
|
||||||
cOsdBase *MyOsd = cOsd::OpenRaw(x, y);
|
cOsd *MyOsd = cOsdProvider::NewOsd(x, y);
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
where <tt>x</tt> and <tt>y</tt> are the coordinates of the upper left corner
|
where <tt>x</tt> and <tt>y</tt> are the coordinates of the upper left corner
|
||||||
of the OSD area on the screen. Such a "raw" OSD doesn't display anything
|
of the OSD area on the screen. Such an OSD doesn't display anything
|
||||||
yet, so you need to at least call the function
|
yet, so you need to at least call the function
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
MyOsd->Create(...);
|
tArea Area = { 0, 0, 100, 100, 4 };
|
||||||
|
MyOsd->SetAreas(Area, 1);
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
to define an actual OSD drawing area (see VDR/osdbase.h for the declarations
|
to define an actual OSD drawing area (see VDR/osd.h for the declarations
|
||||||
of these functions, and VDR/osd.c to see how VDR opens the OSD and sets up
|
of these functions, and VDR/skinsttng.c to see how VDR opens the OSD and sets up
|
||||||
its windows and color depths).
|
its windows and color depths).
|
||||||
|
<p>
|
||||||
|
Theoretically the OSD supports a full screen drawing area, with 32 bit color
|
||||||
|
depth. However, the actual OSD device in use may not be able to provide the
|
||||||
|
full area or color depth, maybe because of lack of OSD memory or other restrictions.
|
||||||
|
A plugin that uses the OSD should therefore test whether the OSD is able to
|
||||||
|
provide the requested functionality, and should offer alternate color depths
|
||||||
|
to allow a less powerfull OSD implementation to still work reasonably.
|
||||||
|
Since it is often not really necessary to have hundreds or thousands of colors
|
||||||
|
all over the OSD area, a plugin can divide the total drawing area into several
|
||||||
|
sub-areas with different color depths and separate color palettes, as in
|
||||||
|
|
||||||
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
|
tArea Area = { 0, 0, 99, 99, 4 };
|
||||||
|
if (osd->CanHandleAreas(Area, 1) == oeOk)
|
||||||
|
osd->SetAreas(Area, 1);
|
||||||
|
else {
|
||||||
|
tArea Areas[] = { { 0, 0, 99, 19, 2 },
|
||||||
|
{ 0, 20, 99, 79, 2 },
|
||||||
|
{ 0, 80, 99, 99, 4 }
|
||||||
|
};
|
||||||
|
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||||
|
}
|
||||||
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
|
In this example an OSD with 100 by 100 pixel and 4 bit color depth shall
|
||||||
|
be opened, so at first a single area with the full required resolution
|
||||||
|
is set up and <tt>CanHandleAreas()</tt> is called with it. If the result indicates
|
||||||
|
that the OSD will be able to handle this drawing area, a call to <tt>SetAreas()</tt>
|
||||||
|
actually sets it. If a single area with that resolution can't be handled,
|
||||||
|
a second attempt is made in which the total drawing area is divided into
|
||||||
|
three horizontal stripes, two of which use only 2 bit color depth (because
|
||||||
|
the objects drawn in there can be displayed with 4 colors) while the third
|
||||||
|
one still requests 4 bit color depth.
|
||||||
|
<p>
|
||||||
|
Note that a plugin should always at first request a single drawing area
|
||||||
|
with the full required resolution. Only if this fails shall it use alternate
|
||||||
|
areas. Drawing areas are always rectangular and may not overlap (but do not need
|
||||||
|
to be adjacent).
|
||||||
|
|
||||||
|
<a name="Skins"><hr><h2>Skins</h2>
|
||||||
|
|
||||||
|
<center><i><b>The emperor's new clothes</b></i></center><p>
|
||||||
|
|
||||||
|
The way VDR displays its menus to the user is implemented through <i>skins</i>.
|
||||||
|
A particular skin provides several functions that return objects to be used
|
||||||
|
for displaying a specific part of the OSD, like a menu, the channel display
|
||||||
|
or the volume bar.
|
||||||
|
<p>
|
||||||
|
By default VDR offers the <i>Classic</i> and the <i>ST:TNG Panels</i> skins,
|
||||||
|
which can be selected through Setup/OSD/Skin. A plugin can implement an
|
||||||
|
arbitrary skin of its own by doing something similar to what's done in
|
||||||
|
<tt>VDR/skinclassic.c</tt>.
|
||||||
|
<p>
|
||||||
|
The first step in implementing a new skin is to derive a class from <tt>cSkin</tt>
|
||||||
|
that provides the handling objects necessary to do the actual work:
|
||||||
|
|
||||||
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
|
#include "skins.h"
|
||||||
|
|
||||||
|
class cMySkin : public cSkin {
|
||||||
|
public:
|
||||||
|
cMySkin(void);
|
||||||
|
virtual const char *Description(void);
|
||||||
|
virtual cSkinDisplayChannel *DisplayChannel(bool WithInfo);
|
||||||
|
virtual cSkinDisplayMenu *DisplayMenu(void);
|
||||||
|
virtual cSkinDisplayReplay *DisplayReplay(bool ModeOnly);
|
||||||
|
virtual cSkinDisplayVolume *DisplayVolume(void);
|
||||||
|
virtual cSkinDisplayMessage *DisplayMessage(void);
|
||||||
|
};
|
||||||
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
|
See the comments in <tt>VDR/skins.h</tt> for details. <tt>VDR/skinclassic.[hc]</tt>
|
||||||
|
can be used as an example for how to implement all the necessary classes and
|
||||||
|
functions to compose a complete skin. See also the chapter about <a href="#Themes">themes</a>
|
||||||
|
if you want to make the colors used by your skin configurable.
|
||||||
|
<p>
|
||||||
|
To add your new skin to the list of skins available to the user in Setup/OSD/Skin,
|
||||||
|
all you need to do is create a new object of your skin class, as in
|
||||||
|
|
||||||
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
|
new cMySkin;
|
||||||
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
|
in the <a href="#Getting started"><tt>Start()</tt></a> function of your plugin.
|
||||||
|
Do not delete this object, it will be automatically deleted when the program ends.
|
||||||
|
|
||||||
|
<a name="Themes"><hr><h2>Themes</h2>
|
||||||
|
|
||||||
|
<center><i><b>Eye of the beholder...</b></i></center><p>
|
||||||
|
|
||||||
|
A <i>theme</i> is a collection of colors that can be used by a <a href="#Skins">skin</a>.
|
||||||
|
Since every skin most likely has its own idea about what parts of it can be
|
||||||
|
<i>themed</i>, and different skins may have completely different numbers of
|
||||||
|
"themeable" parts, a particular theme can only be used with the skin it was designed
|
||||||
|
for. A particular skin, however, can have any number of themes. Which theme
|
||||||
|
will be actually used can be defined in Setup/OSD/Theme.
|
||||||
|
<p>
|
||||||
|
In order to make a skin "themeable" is shall create an object of type cTheme, as in
|
||||||
|
|
||||||
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
|
static cTheme Theme;
|
||||||
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
|
The next step is to define the colors that shall be provided by this theme, as in
|
||||||
|
|
||||||
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
|
THEME_CLR(Theme, clrTitle, 0xFFBC8024);
|
||||||
|
THEME_CLR(Theme, clrButtonRedFg, clrWhite);
|
||||||
|
THEME_CLR(Theme, clrButtonRedBg, clrRed);
|
||||||
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
|
<tt>THEME_CLR()</tt> is a helper macro that adds the given color name
|
||||||
|
and its default color value to the theme.
|
||||||
|
<p>
|
||||||
|
Any color names can be used, but they should always start with <tt>clr...</tt> and
|
||||||
|
if a given color has a foreground and a background value, the two names shall be
|
||||||
|
distinguished by appending <tt>...Fg</tt> and <tt>...Bg</tt>, respectively.
|
||||||
|
<p>
|
||||||
|
Color values can be either 32 bit hexadecimal numbers in the form 0xAARRGGBB
|
||||||
|
(where the individual bytes represent Alpha (transparency), Red, Green
|
||||||
|
and Blue component, respectively), or one of the predefined color names from
|
||||||
|
<tt>VDR/osd.h</tt>.
|
||||||
|
<p>
|
||||||
|
In the actual drawing code of a skin, the color names defined with the <tt>THEME_CLR()</tt>
|
||||||
|
macros can be used to fetch the actual color values from the theme, as in
|
||||||
|
|
||||||
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
|
osd->DrawText(x, y, s, Theme.Color(clrButtonRedFg), Theme.Color(clrButtonRedBg), font);
|
||||||
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
|
By default this will use the colors that have been defined in the respective
|
||||||
|
<tt>THEME_CLR()</tt> line, but may be overwritten through user supplied theme
|
||||||
|
files (see <tt>man vdr(5)</tt> for information about the format of a theme file).
|
||||||
|
<!--X1.3.7--></td></tr></table>
|
||||||
|
|
||||||
<a name="Devices"><hr><h2>Devices</h2>
|
<a name="Devices"><hr><h2>Devices</h2>
|
||||||
|
|
||||||
@ -1297,7 +1435,7 @@ into a VDR system; or an analog TV receiver card, which does the MPEG encoding
|
|||||||
"on the fly" - assuming your machine is fast enough), or just a software program that takes an MPEG data
|
"on the fly" - assuming your machine is fast enough), or just a software program that takes an MPEG data
|
||||||
stream and displays it, for instance, on an existing graphics adapter.
|
stream and displays it, for instance, on an existing graphics adapter.
|
||||||
<p>
|
<p>
|
||||||
To implement an additional device, a plugin must derive a class from cDevice:
|
To implement an additional device, a plugin must derive a class from <tt>cDevice</tt>:
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
#include <vdr/device.h>
|
#include <vdr/device.h>
|
||||||
@ -1374,7 +1512,7 @@ The functions to implement replaying capabilites are
|
|||||||
virtual bool HasDecoder(void) const;
|
virtual bool HasDecoder(void) const;
|
||||||
virtual bool CanReplay(void) const;
|
virtual bool CanReplay(void) const;
|
||||||
virtual bool SetPlayMode(ePlayMode PlayMode);
|
virtual bool SetPlayMode(ePlayMode PlayMode);
|
||||||
<!--X1.2.6--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%>
|
<!--X1.2.6--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%>
|
||||||
virtual int64_t GetSTC(void);
|
virtual int64_t GetSTC(void);
|
||||||
<!--X1.2.6--></td></tr></table>
|
<!--X1.2.6--></td></tr></table>
|
||||||
virtual void TrickSpeed(int Speed);
|
virtual void TrickSpeed(int Speed);
|
||||||
@ -1396,7 +1534,7 @@ virtual void SetVideoFormat(bool VideoFormat16_9);
|
|||||||
virtual void SetVolumeDevice(int Volume);
|
virtual void SetVolumeDevice(int Volume);
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
<!--X1.3.0--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%>
|
<!--X1.3.0--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%>
|
||||||
<p>
|
<p>
|
||||||
<b>Section Filtering</b>
|
<b>Section Filtering</b>
|
||||||
<p>
|
<p>
|
||||||
@ -1426,23 +1564,46 @@ handle section data.
|
|||||||
<p>
|
<p>
|
||||||
<b>On Screen Display</b>
|
<b>On Screen Display</b>
|
||||||
<p>
|
<p>
|
||||||
|
<!--X1.3.7--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%>
|
||||||
If your device provides On Screen Display (OSD) capabilities (which every device
|
If your device provides On Screen Display (OSD) capabilities (which every device
|
||||||
that is supposed to be used as a primary device should do), it can implement
|
that is supposed to be used as a primary device should do), it shall implement
|
||||||
the function
|
an "OSD provider" class, derived from <tt>cOsdProvider</tt>, which, when its <tt>CreateOsd()</tt>
|
||||||
|
function is called, returns an object derived from <tt>cOsd</tt>, which can be used to
|
||||||
|
access the device's OSD:
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
virtual cOsdBase *NewOsd(int x, int y);
|
class cMyOsdProvider : public cOsdProvider {
|
||||||
|
public:
|
||||||
|
cMyOsdProvider(void);
|
||||||
|
virtual cOsd *CreateOsd(int Left, int Top);
|
||||||
|
};
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
which must return a newly created object of a derived cOsdBase class that
|
In its <tt>MakePrimaryDevice()</tt> function the device shall create an object
|
||||||
implements the functions necessary to display OSD information on your device.
|
of this class, as in
|
||||||
The caller of this function will delete the object as soon as it is no longer
|
|
||||||
needed.
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
|
void cMyDevice::MakePrimaryDevice(bool On)
|
||||||
|
{
|
||||||
|
new cMyOsdProvider;
|
||||||
|
}
|
||||||
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
|
The OSD provider object is allocated on the heap and shall not be deleted
|
||||||
|
(it will be deleted automatically in case a different device sets up an OSD
|
||||||
|
provider, or when the program ends).
|
||||||
|
|
||||||
|
Note that an OSD implementation need not be physically linked to the device
|
||||||
|
in any way. All it needs to make sure is that the OSD will be visible to the
|
||||||
|
user - whether this goes through OSD facilities of the physical device (like
|
||||||
|
a "full featured" DVB card) or through a graphics adapter that overlays its
|
||||||
|
output with the video signal, doesn't matter.
|
||||||
|
<!--X1.3.7--></td></tr></table>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<b>Initializing new devices</b>
|
<b>Initializing new devices</b>
|
||||||
<p>
|
<p>
|
||||||
A derived cDevice class shall implement a static function
|
A derived <tt>cDevice</tt> class shall implement a static function
|
||||||
in which it determines whether the necessary hardware to run this sort of
|
in which it determines whether the necessary hardware to run this sort of
|
||||||
device is actually present in this machine (or whatever other prerequisites
|
device is actually present in this machine (or whatever other prerequisites
|
||||||
might be important), and then creates as many device objects as necessary.
|
might be important), and then creates as many device objects as necessary.
|
||||||
|
@ -8,3 +8,7 @@ VDR Plugin 'osddemo' Revision History
|
|||||||
2002-12-13: Version 0.1.0
|
2002-12-13: Version 0.1.0
|
||||||
|
|
||||||
- Changed setting of CXX and CXXFLAGS variables in Makefile.
|
- Changed setting of CXX and CXXFLAGS variables in Makefile.
|
||||||
|
|
||||||
|
2004-04-30: Version 0.1.1
|
||||||
|
|
||||||
|
- New OSD handling.
|
||||||
|
@ -3,12 +3,12 @@
|
|||||||
*
|
*
|
||||||
* See the README file for copyright information and how to reach the author.
|
* See the README file for copyright information and how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: osddemo.c 1.2 2002/12/13 15:02:01 kls Exp $
|
* $Id: osddemo.c 1.3 2004/05/16 09:28:51 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <vdr/plugin.h>
|
#include <vdr/plugin.h>
|
||||||
|
|
||||||
static const char *VERSION = "0.1.0";
|
static const char *VERSION = "0.1.1";
|
||||||
static const char *DESCRIPTION = "Demo of arbitrary OSD setup";
|
static const char *DESCRIPTION = "Demo of arbitrary OSD setup";
|
||||||
static const char *MAINMENUENTRY = "Osd Demo";
|
static const char *MAINMENUENTRY = "Osd Demo";
|
||||||
|
|
||||||
@ -16,10 +16,10 @@ static const char *MAINMENUENTRY = "Osd Demo";
|
|||||||
|
|
||||||
class cLineGame : public cOsdObject {
|
class cLineGame : public cOsdObject {
|
||||||
private:
|
private:
|
||||||
cOsdBase *osd;
|
cOsd *osd;
|
||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
eDvbColor color;
|
tColor color;
|
||||||
public:
|
public:
|
||||||
cLineGame(void);
|
cLineGame(void);
|
||||||
~cLineGame();
|
~cLineGame();
|
||||||
@ -41,15 +41,11 @@ cLineGame::~cLineGame()
|
|||||||
|
|
||||||
void cLineGame::Show(void)
|
void cLineGame::Show(void)
|
||||||
{
|
{
|
||||||
osd = cOsd::OpenRaw(100, 50);
|
osd = cOsdProvider::NewOsd(100, 50);
|
||||||
if (osd) {
|
if (osd) {
|
||||||
osd->Create(0, 0, 100, 200, 4);
|
tArea Area = { 0, 0, 99, 199, 4 };
|
||||||
osd->AddColor(clrBackground);
|
osd->SetAreas(&Area, 1);
|
||||||
osd->AddColor(clrRed);
|
osd->DrawRectangle(0, 0, 99, 199, clrGray50);
|
||||||
osd->AddColor(clrGreen);
|
|
||||||
osd->AddColor(clrYellow);
|
|
||||||
osd->AddColor(clrBlue);
|
|
||||||
osd->Clear();
|
|
||||||
osd->Flush();
|
osd->Flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -70,7 +66,7 @@ eOSState cLineGame::ProcessKey(eKeys Key)
|
|||||||
case kOk: return osEnd;
|
case kOk: return osEnd;
|
||||||
default: return state;
|
default: return state;
|
||||||
}
|
}
|
||||||
osd->Fill(x, y, x + 3, y + 3, color);
|
osd->DrawRectangle(x, y, x + 3, y + 3, color);
|
||||||
osd->Flush();
|
osd->Flush();
|
||||||
state = osContinue;
|
state = osContinue;
|
||||||
}
|
}
|
||||||
|
18
channels.c
18
channels.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: channels.c 1.24 2004/02/13 15:37:42 kls Exp $
|
* $Id: channels.c 1.25 2004/04/03 13:42:06 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "channels.h"
|
#include "channels.h"
|
||||||
@ -888,3 +888,19 @@ cChannel *cChannels::NewChannel(const cChannel *Transponder, const char *Name, i
|
|||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *ChannelString(const cChannel *Channel, int Number)
|
||||||
|
{
|
||||||
|
static char buffer[256];
|
||||||
|
if (Channel) {
|
||||||
|
if (Channel->GroupSep())
|
||||||
|
snprintf(buffer, sizeof(buffer), "%s", Channel->Name());
|
||||||
|
else
|
||||||
|
snprintf(buffer, sizeof(buffer), "%d%s %s", Channel->Number(), Number ? "-" : "", Channel->Name());
|
||||||
|
}
|
||||||
|
else if (Number)
|
||||||
|
snprintf(buffer, sizeof(buffer), "%d-", Number);
|
||||||
|
else
|
||||||
|
snprintf(buffer, sizeof(buffer), "%s", tr("*** Invalid Channel ***"));
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: channels.h 1.16 2004/02/13 15:16:36 kls Exp $
|
* $Id: channels.h 1.17 2004/04/03 13:40:47 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __CHANNELS_H
|
#ifndef __CHANNELS_H
|
||||||
@ -203,4 +203,6 @@ public:
|
|||||||
|
|
||||||
extern cChannels Channels;
|
extern cChannels Channels;
|
||||||
|
|
||||||
|
const char *ChannelString(const cChannel *Channel, int Number);
|
||||||
|
|
||||||
#endif //__CHANNELS_H
|
#endif //__CHANNELS_H
|
||||||
|
29
config.c
29
config.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: config.c 1.125 2004/02/28 11:12:20 kls Exp $
|
* $Id: config.c 1.126 2004/05/16 10:08:09 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
@ -245,6 +245,8 @@ cSetup Setup;
|
|||||||
cSetup::cSetup(void)
|
cSetup::cSetup(void)
|
||||||
{
|
{
|
||||||
OSDLanguage = 0;
|
OSDLanguage = 0;
|
||||||
|
strcpy(OSDSkin, "sttng");
|
||||||
|
strcpy(OSDTheme, "default");
|
||||||
PrimaryDVB = 1;
|
PrimaryDVB = 1;
|
||||||
ShowInfoOnChSwitch = 1;
|
ShowInfoOnChSwitch = 1;
|
||||||
MenuScrollPage = 1;
|
MenuScrollPage = 1;
|
||||||
@ -279,9 +281,12 @@ cSetup::cSetup(void)
|
|||||||
UpdateChannels = 4;
|
UpdateChannels = 4;
|
||||||
RecordDolbyDigital = 1;
|
RecordDolbyDigital = 1;
|
||||||
ChannelInfoPos = 0;
|
ChannelInfoPos = 0;
|
||||||
OSDwidth = 52;
|
OSDLeft = 54;
|
||||||
OSDheight = 18;
|
OSDTop = 45;
|
||||||
|
OSDWidth = 624;
|
||||||
|
OSDHeight = 486;
|
||||||
OSDMessageTime = 1;
|
OSDMessageTime = 1;
|
||||||
|
UseSmallFont = 1;
|
||||||
MaxVideoFileSize = MAXVIDEOFILESIZE;
|
MaxVideoFileSize = MAXVIDEOFILESIZE;
|
||||||
SplitEditedFiles = 0;
|
SplitEditedFiles = 0;
|
||||||
MinEventTimeout = 30;
|
MinEventTimeout = 30;
|
||||||
@ -392,6 +397,8 @@ bool cSetup::ParseLanguages(const char *Value, int *Values)
|
|||||||
bool cSetup::Parse(const char *Name, const char *Value)
|
bool cSetup::Parse(const char *Name, const char *Value)
|
||||||
{
|
{
|
||||||
if (!strcasecmp(Name, "OSDLanguage")) OSDLanguage = atoi(Value);
|
if (!strcasecmp(Name, "OSDLanguage")) OSDLanguage = atoi(Value);
|
||||||
|
else if (!strcasecmp(Name, "OSDSkin")) strn0cpy(OSDSkin, Value, MaxSkinName);
|
||||||
|
else if (!strcasecmp(Name, "OSDTheme")) strn0cpy(OSDTheme, Value, MaxThemeName);
|
||||||
else if (!strcasecmp(Name, "PrimaryDVB")) PrimaryDVB = atoi(Value);
|
else if (!strcasecmp(Name, "PrimaryDVB")) PrimaryDVB = atoi(Value);
|
||||||
else if (!strcasecmp(Name, "ShowInfoOnChSwitch")) ShowInfoOnChSwitch = atoi(Value);
|
else if (!strcasecmp(Name, "ShowInfoOnChSwitch")) ShowInfoOnChSwitch = atoi(Value);
|
||||||
else if (!strcasecmp(Name, "MenuScrollPage")) MenuScrollPage = atoi(Value);
|
else if (!strcasecmp(Name, "MenuScrollPage")) MenuScrollPage = atoi(Value);
|
||||||
@ -426,9 +433,12 @@ bool cSetup::Parse(const char *Name, const char *Value)
|
|||||||
else if (!strcasecmp(Name, "UpdateChannels")) UpdateChannels = atoi(Value);
|
else if (!strcasecmp(Name, "UpdateChannels")) UpdateChannels = atoi(Value);
|
||||||
else if (!strcasecmp(Name, "RecordDolbyDigital")) RecordDolbyDigital = atoi(Value);
|
else if (!strcasecmp(Name, "RecordDolbyDigital")) RecordDolbyDigital = atoi(Value);
|
||||||
else if (!strcasecmp(Name, "ChannelInfoPos")) ChannelInfoPos = atoi(Value);
|
else if (!strcasecmp(Name, "ChannelInfoPos")) ChannelInfoPos = atoi(Value);
|
||||||
else if (!strcasecmp(Name, "OSDwidth")) OSDwidth = atoi(Value);
|
else if (!strcasecmp(Name, "OSDLeft")) OSDLeft = atoi(Value);
|
||||||
else if (!strcasecmp(Name, "OSDheight")) OSDheight = atoi(Value);
|
else if (!strcasecmp(Name, "OSDTop")) OSDTop = atoi(Value);
|
||||||
|
else if (!strcasecmp(Name, "OSDWidth")) { OSDWidth = atoi(Value); if (OSDWidth < 100) OSDWidth *= 12; OSDWidth &= ~0x07; } // OSD width must be a multiple of 8
|
||||||
|
else if (!strcasecmp(Name, "OSDHeight")) { OSDHeight = atoi(Value); if (OSDHeight < 100) OSDHeight *= 27; }
|
||||||
else if (!strcasecmp(Name, "OSDMessageTime")) OSDMessageTime = atoi(Value);
|
else if (!strcasecmp(Name, "OSDMessageTime")) OSDMessageTime = atoi(Value);
|
||||||
|
else if (!strcasecmp(Name, "UseSmallFont")) UseSmallFont = atoi(Value);
|
||||||
else if (!strcasecmp(Name, "MaxVideoFileSize")) MaxVideoFileSize = atoi(Value);
|
else if (!strcasecmp(Name, "MaxVideoFileSize")) MaxVideoFileSize = atoi(Value);
|
||||||
else if (!strcasecmp(Name, "SplitEditedFiles")) SplitEditedFiles = atoi(Value);
|
else if (!strcasecmp(Name, "SplitEditedFiles")) SplitEditedFiles = atoi(Value);
|
||||||
else if (!strcasecmp(Name, "MinEventTimeout")) MinEventTimeout = atoi(Value);
|
else if (!strcasecmp(Name, "MinEventTimeout")) MinEventTimeout = atoi(Value);
|
||||||
@ -446,6 +456,8 @@ bool cSetup::Parse(const char *Name, const char *Value)
|
|||||||
bool cSetup::Save(void)
|
bool cSetup::Save(void)
|
||||||
{
|
{
|
||||||
Store("OSDLanguage", OSDLanguage);
|
Store("OSDLanguage", OSDLanguage);
|
||||||
|
Store("OSDSkin", OSDSkin);
|
||||||
|
Store("OSDTheme", OSDTheme);
|
||||||
Store("PrimaryDVB", PrimaryDVB);
|
Store("PrimaryDVB", PrimaryDVB);
|
||||||
Store("ShowInfoOnChSwitch", ShowInfoOnChSwitch);
|
Store("ShowInfoOnChSwitch", ShowInfoOnChSwitch);
|
||||||
Store("MenuScrollPage", MenuScrollPage);
|
Store("MenuScrollPage", MenuScrollPage);
|
||||||
@ -480,9 +492,12 @@ bool cSetup::Save(void)
|
|||||||
Store("UpdateChannels", UpdateChannels);
|
Store("UpdateChannels", UpdateChannels);
|
||||||
Store("RecordDolbyDigital", RecordDolbyDigital);
|
Store("RecordDolbyDigital", RecordDolbyDigital);
|
||||||
Store("ChannelInfoPos", ChannelInfoPos);
|
Store("ChannelInfoPos", ChannelInfoPos);
|
||||||
Store("OSDwidth", OSDwidth);
|
Store("OSDLeft", OSDLeft);
|
||||||
Store("OSDheight", OSDheight);
|
Store("OSDTop", OSDTop);
|
||||||
|
Store("OSDWidth", OSDWidth);
|
||||||
|
Store("OSDHeight", OSDHeight);
|
||||||
Store("OSDMessageTime", OSDMessageTime);
|
Store("OSDMessageTime", OSDMessageTime);
|
||||||
|
Store("UseSmallFont", UseSmallFont);
|
||||||
Store("MaxVideoFileSize", MaxVideoFileSize);
|
Store("MaxVideoFileSize", MaxVideoFileSize);
|
||||||
Store("SplitEditedFiles", SplitEditedFiles);
|
Store("SplitEditedFiles", SplitEditedFiles);
|
||||||
Store("MinEventTimeout", MinEventTimeout);
|
Store("MinEventTimeout", MinEventTimeout);
|
||||||
|
17
config.h
17
config.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: config.h 1.191 2004/03/14 16:51:13 kls Exp $
|
* $Id: config.h 1.192 2004/05/08 09:18:36 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __CONFIG_H
|
#ifndef __CONFIG_H
|
||||||
@ -26,12 +26,14 @@
|
|||||||
#define MAXPRIORITY 99
|
#define MAXPRIORITY 99
|
||||||
#define MAXLIFETIME 99
|
#define MAXLIFETIME 99
|
||||||
|
|
||||||
#define MINOSDWIDTH 40
|
#define MINOSDWIDTH 480
|
||||||
#define MAXOSDWIDTH 56
|
#define MAXOSDWIDTH 672
|
||||||
#define MINOSDHEIGHT 12
|
#define MINOSDHEIGHT 324
|
||||||
#define MAXOSDHEIGHT 21
|
#define MAXOSDHEIGHT 567
|
||||||
|
|
||||||
#define MaxFileName 256
|
#define MaxFileName 256
|
||||||
|
#define MaxSkinName 16
|
||||||
|
#define MaxThemeName 16
|
||||||
|
|
||||||
class cCommand : public cListObject {
|
class cCommand : public cListObject {
|
||||||
private:
|
private:
|
||||||
@ -204,6 +206,8 @@ public:
|
|||||||
// Also adjust cMenuSetup (menu.c) when adding parameters here!
|
// Also adjust cMenuSetup (menu.c) when adding parameters here!
|
||||||
int __BeginData__;
|
int __BeginData__;
|
||||||
int OSDLanguage;
|
int OSDLanguage;
|
||||||
|
char OSDSkin[MaxSkinName];
|
||||||
|
char OSDTheme[MaxThemeName];
|
||||||
int PrimaryDVB;
|
int PrimaryDVB;
|
||||||
int ShowInfoOnChSwitch;
|
int ShowInfoOnChSwitch;
|
||||||
int MenuScrollPage;
|
int MenuScrollPage;
|
||||||
@ -235,8 +239,9 @@ public:
|
|||||||
int UpdateChannels;
|
int UpdateChannels;
|
||||||
int RecordDolbyDigital;
|
int RecordDolbyDigital;
|
||||||
int ChannelInfoPos;
|
int ChannelInfoPos;
|
||||||
int OSDwidth, OSDheight;
|
int OSDLeft, OSDTop, OSDWidth, OSDHeight;
|
||||||
int OSDMessageTime;
|
int OSDMessageTime;
|
||||||
|
int UseSmallFont;
|
||||||
int MaxVideoFileSize;
|
int MaxVideoFileSize;
|
||||||
int SplitEditedFiles;
|
int SplitEditedFiles;
|
||||||
int MinEventTimeout, MinUserInactivity;
|
int MinEventTimeout, MinUserInactivity;
|
||||||
|
17
device.c
17
device.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: device.c 1.53 2004/02/08 15:05:11 kls Exp $
|
* $Id: device.c 1.54 2004/04/17 10:07:10 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
@ -126,11 +126,6 @@ bool cDevice::HasDecoder(void) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
cOsdBase *cDevice::NewOsd(int x, int y)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
cSpuDecoder *cDevice::GetSpuDecoder(void)
|
cSpuDecoder *cDevice::GetSpuDecoder(void)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -360,11 +355,9 @@ bool cDevice::SwitchChannel(const cChannel *Channel, bool LiveView)
|
|||||||
for (int i = 3; i--;) {
|
for (int i = 3; i--;) {
|
||||||
switch (SetChannel(Channel, LiveView)) {
|
switch (SetChannel(Channel, LiveView)) {
|
||||||
case scrOk: return true;
|
case scrOk: return true;
|
||||||
case scrNotAvailable: if (Interface)
|
case scrNotAvailable: Skins.Message(mtError, tr("Channel not available!"));
|
||||||
Interface->Error(tr("Channel not available!"));
|
|
||||||
return false;
|
return false;
|
||||||
case scrNoTransfer: if (Interface)
|
case scrNoTransfer: Skins.Message(mtError, tr("Can't start Transfer Mode!"));
|
||||||
Interface->Error(tr("Can't start Transfer Mode!"));
|
|
||||||
return false;
|
return false;
|
||||||
case scrFailed: break; // loop will retry
|
case scrFailed: break; // loop will retry
|
||||||
}
|
}
|
||||||
@ -396,8 +389,8 @@ bool cDevice::SwitchChannel(int Direction)
|
|||||||
if (PrimaryDevice()->SwitchChannel(channel, true))
|
if (PrimaryDevice()->SwitchChannel(channel, true))
|
||||||
result = true;
|
result = true;
|
||||||
}
|
}
|
||||||
else if (n != first && Interface)
|
else if (n != first)
|
||||||
Interface->Error(tr("Channel not available!"));
|
Skins.Message(mtError, tr("Channel not available!"));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
11
device.h
11
device.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: device.h 1.41 2004/03/14 10:47:01 kls Exp $
|
* $Id: device.h 1.42 2004/04/17 10:15:25 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __DEVICE_H
|
#ifndef __DEVICE_H
|
||||||
@ -54,7 +54,6 @@ enum eVideoSystem { vsPAL,
|
|||||||
vsNTSC
|
vsNTSC
|
||||||
};
|
};
|
||||||
|
|
||||||
class cOsdBase;
|
|
||||||
class cChannel;
|
class cChannel;
|
||||||
class cPlayer;
|
class cPlayer;
|
||||||
class cReceiver;
|
class cReceiver;
|
||||||
@ -139,15 +138,9 @@ public:
|
|||||||
virtual bool HasDecoder(void) const;
|
virtual bool HasDecoder(void) const;
|
||||||
///< Tells whether this device has an MPEG decoder.
|
///< Tells whether this device has an MPEG decoder.
|
||||||
|
|
||||||
// OSD facilities
|
// SPU facilities
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual cOsdBase *NewOsd(int x, int y);
|
|
||||||
///< Creates a new cOsdBase object that can be used by the cOsd class
|
|
||||||
///< to display information on the screen, with the upper left corner
|
|
||||||
///< of the OSD at the given coordinates. If a derived cDevice doesn't
|
|
||||||
///< implement this function, NULL will be returned by default (which
|
|
||||||
///< means the device has no OSD capabilities).
|
|
||||||
virtual cSpuDecoder *GetSpuDecoder(void);
|
virtual cSpuDecoder *GetSpuDecoder(void);
|
||||||
///< Returns a pointer to the device's SPU decoder (or NULL, if this
|
///< Returns a pointer to the device's SPU decoder (or NULL, if this
|
||||||
///< device doesn't have an SPU decoder).
|
///< device doesn't have an SPU decoder).
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: dvbdevice.c 1.83 2004/03/14 14:47:46 kls Exp $
|
* $Id: dvbdevice.c 1.84 2004/05/01 13:15:46 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "dvbdevice.h"
|
#include "dvbdevice.h"
|
||||||
@ -427,7 +427,7 @@ bool cDvbDevice::Initialize(void)
|
|||||||
void cDvbDevice::MakePrimaryDevice(bool On)
|
void cDvbDevice::MakePrimaryDevice(bool On)
|
||||||
{
|
{
|
||||||
if (HasDecoder())
|
if (HasDecoder())
|
||||||
cDvbOsd::SetDvbDevice(On ? this : NULL);
|
new cDvbOsdProvider(fd_osd);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cDvbDevice::HasDecoder(void) const
|
bool cDvbDevice::HasDecoder(void) const
|
||||||
@ -446,11 +446,6 @@ int cDvbDevice::ProvidesCa(const cChannel *Channel) const
|
|||||||
return cDevice::ProvidesCa(Channel);
|
return cDevice::ProvidesCa(Channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
cOsdBase *cDvbDevice::NewOsd(int x, int y)
|
|
||||||
{
|
|
||||||
return new cDvbOsd(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
cSpuDecoder *cDvbDevice::GetSpuDecoder(void)
|
cSpuDecoder *cDvbDevice::GetSpuDecoder(void)
|
||||||
{
|
{
|
||||||
if (!spuDecoder && IsPrimaryDevice())
|
if (!spuDecoder && IsPrimaryDevice())
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: dvbdevice.h 1.26 2004/01/03 10:21:50 kls Exp $
|
* $Id: dvbdevice.h 1.27 2004/04/17 11:56:22 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __DVBDEVICE_H
|
#ifndef __DVBDEVICE_H
|
||||||
@ -26,7 +26,6 @@ class cDvbTuner;
|
|||||||
/// The cDvbDevice implements a DVB device which can be accessed through the Linux DVB driver API.
|
/// The cDvbDevice implements a DVB device which can be accessed through the Linux DVB driver API.
|
||||||
|
|
||||||
class cDvbDevice : public cDevice {
|
class cDvbDevice : public cDevice {
|
||||||
friend class cDvbOsd;
|
|
||||||
private:
|
private:
|
||||||
static bool Probe(const char *FileName);
|
static bool Probe(const char *FileName);
|
||||||
///< Probes for existing DVB devices.
|
///< Probes for existing DVB devices.
|
||||||
@ -38,7 +37,6 @@ public:
|
|||||||
private:
|
private:
|
||||||
fe_type_t frontendType;
|
fe_type_t frontendType;
|
||||||
int fd_osd, fd_audio, fd_video, fd_dvr, fd_stc;
|
int fd_osd, fd_audio, fd_video, fd_dvr, fd_stc;
|
||||||
int OsdDeviceHandle(void) const { return fd_osd; }
|
|
||||||
protected:
|
protected:
|
||||||
virtual void MakePrimaryDevice(bool On);
|
virtual void MakePrimaryDevice(bool On);
|
||||||
public:
|
public:
|
||||||
@ -47,12 +45,11 @@ public:
|
|||||||
virtual int ProvidesCa(const cChannel *Channel) const;
|
virtual int ProvidesCa(const cChannel *Channel) const;
|
||||||
virtual bool HasDecoder(void) const;
|
virtual bool HasDecoder(void) const;
|
||||||
|
|
||||||
// OSD facilities
|
// SPU facilities
|
||||||
|
|
||||||
private:
|
private:
|
||||||
cDvbSpuDecoder *spuDecoder;
|
cDvbSpuDecoder *spuDecoder;
|
||||||
public:
|
public:
|
||||||
cOsdBase *NewOsd(int x, int y);
|
|
||||||
virtual cSpuDecoder *GetSpuDecoder(void);
|
virtual cSpuDecoder *GetSpuDecoder(void);
|
||||||
|
|
||||||
// Channel facilities
|
// Channel facilities
|
||||||
|
168
dvbosd.c
168
dvbosd.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: dvbosd.c 1.21 2003/04/12 12:10:12 kls Exp $
|
* $Id: dvbosd.c 1.22 2004/05/01 15:10:44 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "dvbosd.h"
|
#include "dvbosd.h"
|
||||||
@ -13,40 +13,49 @@
|
|||||||
#include <sys/unistd.h>
|
#include <sys/unistd.h>
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
|
||||||
const cDvbDevice *cDvbOsd::dvbDevice = NULL;
|
// --- cDvbOsd ---------------------------------------------------------------
|
||||||
|
|
||||||
cDvbOsd::cDvbOsd(int x, int y)
|
#define MAXNUMWINDOWS 7 // OSD windows are counted 1...7
|
||||||
:cOsdBase(x, y)
|
#define MAXOSDMEMORY 92000 // number of bytes available to the OSD (depends on firmware version, but there is no way of determining the actual value)
|
||||||
|
|
||||||
|
cDvbOsd::cDvbOsd(int Left, int Top, int OsdDev)
|
||||||
|
:cOsd(Left, Top)
|
||||||
{
|
{
|
||||||
osdDev = dvbDevice ? dvbDevice->OsdDeviceHandle() : -1;
|
osdDev = OsdDev;
|
||||||
if (dvbDevice && osdDev < 0)
|
shown = false;
|
||||||
|
if (osdDev < 0)
|
||||||
esyslog("ERROR: illegal OSD device handle (%d)!", osdDev);
|
esyslog("ERROR: illegal OSD device handle (%d)!", osdDev);
|
||||||
}
|
}
|
||||||
|
|
||||||
cDvbOsd::~cDvbOsd()
|
cDvbOsd::~cDvbOsd()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < NumWindows(); i++)
|
if (shown) {
|
||||||
CloseWindow(GetWindowNr(i));
|
cBitmap *Bitmap;
|
||||||
}
|
for (int i = 0; (Bitmap = GetBitmap(i)) != NULL; i++) {
|
||||||
|
Cmd(OSD_SetWindow, 0, i + 1);
|
||||||
void cDvbOsd::SetDvbDevice(const cDvbDevice *DvbDevice)
|
Cmd(OSD_Close);
|
||||||
{
|
}
|
||||||
dvbDevice = DvbDevice;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cDvbOsd::SetWindow(cWindow *Window)
|
|
||||||
{
|
|
||||||
if (Window) {
|
|
||||||
// Window handles are counted 0...(MAXNUMWINDOWS - 1), but the actual window
|
|
||||||
// numbers in the driver are used from 1...MAXNUMWINDOWS.
|
|
||||||
int Handle = Window->Handle();
|
|
||||||
if (0 <= Handle && Handle < MAXNUMWINDOWS) {
|
|
||||||
Cmd(OSD_SetWindow, 0, Handle + 1);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
esyslog("ERROR: illegal window handle: %d", Handle);
|
|
||||||
}
|
}
|
||||||
return false;
|
}
|
||||||
|
|
||||||
|
eOsdError cDvbOsd::CanHandleAreas(const tArea *Areas, int NumAreas)
|
||||||
|
{
|
||||||
|
eOsdError Result = cOsd::CanHandleAreas(Areas, NumAreas);
|
||||||
|
if (Result == oeOk) {
|
||||||
|
if (NumAreas > MAXNUMWINDOWS)
|
||||||
|
return oeTooManyAreas;
|
||||||
|
int TotalMemory = 0;
|
||||||
|
for (int i = 0; i < NumAreas; i++) {
|
||||||
|
if (Areas[i].bpp != 1 && Areas[i].bpp != 2 && Areas[i].bpp != 4 && Areas[i].bpp != 8)
|
||||||
|
return oeBppNotSupported;
|
||||||
|
if ((Areas[i].Width() & (8 / Areas[i].bpp - 1)) != 0)
|
||||||
|
return oeWrongAlignment;
|
||||||
|
TotalMemory += Areas[i].Width() * Areas[i].Height() / (8 / Areas[i].bpp);
|
||||||
|
}
|
||||||
|
if (TotalMemory > MAXOSDMEMORY)
|
||||||
|
return oeOutOfMemory;
|
||||||
|
}
|
||||||
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cDvbOsd::Cmd(OSD_Command cmd, int color, int x0, int y0, int x1, int y1, const void *data)
|
void cDvbOsd::Cmd(OSD_Command cmd, int color, int x0, int y0, int x1, int y1, const void *data)
|
||||||
@ -64,51 +73,78 @@ void cDvbOsd::Cmd(OSD_Command cmd, int color, int x0, int y0, int x1, int y1, co
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cDvbOsd::OpenWindow(cWindow *Window)
|
void cDvbOsd::Flush(void)
|
||||||
{
|
{
|
||||||
if (SetWindow(Window)) {
|
cBitmap *Bitmap;
|
||||||
Cmd(OSD_Open, Window->Bpp(), X0() + Window->X0(), Y0() + Window->Y0(), X0() + Window->X0() + Window->Width() - 1, Y0() + Window->Y0() + Window->Height() - 1, (void *)1); // initially hidden!
|
for (int i = 0; (Bitmap = GetBitmap(i)) != NULL; i++) {
|
||||||
return true;
|
Cmd(OSD_SetWindow, 0, i + 1);
|
||||||
}
|
if (!shown)
|
||||||
return false;
|
Cmd(OSD_Open, Bitmap->Bpp(), Left() + Bitmap->X0(), Top() + Bitmap->Y0(), Left() + Bitmap->X0() + Bitmap->Width() - 1, Top() + Bitmap->Y0() + Bitmap->Height() - 1, (void *)1); // initially hidden!
|
||||||
}
|
int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
|
||||||
|
if (Bitmap->Dirty(x1, y1, x2, y2)) {
|
||||||
void cDvbOsd::CommitWindow(cWindow *Window)
|
//TODO Workaround: apparently the bitmap sent to the driver always has to be a multiple
|
||||||
{
|
//TODO of 8 bits wide, and (dx * dy) also has to be a multiple of 8.
|
||||||
if (SetWindow(Window)) {
|
//TODO Fix driver (should be able to handle any size bitmaps!)
|
||||||
int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
|
while ((x1 > 0 || x2 < Bitmap->Width() - 1) && ((x2 - x1) & 7) != 7) {
|
||||||
if (Window->Dirty(x1, y1, x2, y2)) {
|
if (x2 < Bitmap->Width() - 1)
|
||||||
// commit colors:
|
x2++;
|
||||||
int FirstColor = 0, LastColor = 0;
|
else if (x1 > 0)
|
||||||
const eDvbColor *pal;
|
x1--;
|
||||||
while ((pal = Window->NewColors(FirstColor, LastColor)) != NULL)
|
}
|
||||||
Cmd(OSD_SetPalette, FirstColor, LastColor, 0, 0, 0, pal);
|
//TODO "... / 2" <==> Bpp???
|
||||||
// commit modified data:
|
while ((y1 > 0 || y2 < Bitmap->Height() - 1) && (((x2 - x1 + 1) * (y2 - y1 + 1) / 2) & 7) != 0) {
|
||||||
Cmd(OSD_SetBlock, Window->Width(), x1, y1, x2, y2, Window->Data(x1, y1));
|
if (y2 < Bitmap->Height() - 1)
|
||||||
}
|
y2++;
|
||||||
|
else if (y1 > 0)
|
||||||
|
y1--;
|
||||||
|
}
|
||||||
|
while ((x1 > 0 || x2 < Bitmap->Width() - 1) && (((x2 - x1 + 1) * (y2 - y1 + 1) / 2) & 7) != 0) {
|
||||||
|
if (x2 < Bitmap->Width() - 1)
|
||||||
|
x2++;
|
||||||
|
else if (x1 > 0)
|
||||||
|
x1--;
|
||||||
|
}
|
||||||
|
// commit colors:
|
||||||
|
int NumColors;
|
||||||
|
const tColor *Colors = Bitmap->Colors(NumColors);
|
||||||
|
if (Colors) {
|
||||||
|
//TODO this should be fixed in the driver!
|
||||||
|
tColor colors[NumColors];
|
||||||
|
for (int i = 0; i < NumColors; i++) {
|
||||||
|
// convert AARRGGBB to AABBGGRR (the driver expects the colors the wrong way):
|
||||||
|
colors[i] = (Colors[i] & 0xFF000000) | ((Colors[i] & 0x0000FF) << 16) | (Colors[i] & 0x00FF00) | ((Colors[i] & 0xFF0000) >> 16);
|
||||||
|
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||||
|
// actually the driver itself should access the bytes according to the current endianness!
|
||||||
|
colors[i] = ((colors[i] & 0xFF) << 24) | ((colors[i] & 0xFF00) << 8) | ((colors[i] & 0xFF0000) >> 8) | ((colors[i] & 0xFF000000) >> 24);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
Colors = colors;
|
||||||
|
//TODO end of stuff that should be fixed in the driver
|
||||||
|
Cmd(OSD_SetPalette, 0, NumColors - 1, 0, 0, 0, Colors);
|
||||||
|
}
|
||||||
|
// commit modified data:
|
||||||
|
Cmd(OSD_SetBlock, Bitmap->Width(), x1, y1, x2, y2, Bitmap->Data(x1, y1));
|
||||||
|
}
|
||||||
|
Bitmap->Clean();
|
||||||
|
}
|
||||||
|
if (!shown) {
|
||||||
|
// Showing the windows in a separate loop to avoid seeing them come up one after another
|
||||||
|
for (int i = 0; (Bitmap = GetBitmap(i)) != NULL; i++) {
|
||||||
|
Cmd(OSD_SetWindow, 0, i + 1);
|
||||||
|
Cmd(OSD_MoveWindow, 0, Left() + Bitmap->X0(), Top() + Bitmap->Y0());
|
||||||
|
}
|
||||||
|
shown = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cDvbOsd::ShowWindow(cWindow *Window)
|
// --- cDvbOsdProvider -------------------------------------------------------
|
||||||
|
|
||||||
|
cDvbOsdProvider::cDvbOsdProvider(int OsdDev)
|
||||||
{
|
{
|
||||||
if (SetWindow(Window))
|
osdDev = OsdDev;
|
||||||
Cmd(OSD_MoveWindow, 0, X0() + Window->X0(), Y0() + Window->Y0());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cDvbOsd::HideWindow(cWindow *Window, bool Hide)
|
cOsd *cDvbOsdProvider::CreateOsd(int Left, int Top)
|
||||||
{
|
{
|
||||||
if (SetWindow(Window))
|
return new cDvbOsd(Left, Top, osdDev);
|
||||||
Cmd(Hide ? OSD_Hide : OSD_Show, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cDvbOsd::MoveWindow(cWindow *Window, int x, int y)
|
|
||||||
{
|
|
||||||
if (SetWindow(Window))
|
|
||||||
Cmd(OSD_MoveWindow, 0, X0() + x, Y0() + y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cDvbOsd::CloseWindow(cWindow *Window)
|
|
||||||
{
|
|
||||||
if (SetWindow(Window))
|
|
||||||
Cmd(OSD_Close);
|
|
||||||
}
|
}
|
||||||
|
29
dvbosd.h
29
dvbosd.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: dvbosd.h 1.16 2002/11/01 10:05:47 kls Exp $
|
* $Id: dvbosd.h 1.17 2004/04/30 13:44:16 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __DVBOSD_H
|
#ifndef __DVBOSD_H
|
||||||
@ -12,25 +12,26 @@
|
|||||||
|
|
||||||
#include <linux/dvb/osd.h>
|
#include <linux/dvb/osd.h>
|
||||||
#include "dvbdevice.h"
|
#include "dvbdevice.h"
|
||||||
#include "osdbase.h"
|
#include "osd.h"
|
||||||
|
|
||||||
class cDvbOsd : public cOsdBase {
|
class cDvbOsd : public cOsd {
|
||||||
private:
|
private:
|
||||||
static const cDvbDevice *dvbDevice;
|
|
||||||
int osdDev;
|
int osdDev;
|
||||||
bool SetWindow(cWindow *Window);
|
bool shown;
|
||||||
void Cmd(OSD_Command cmd, int color = 0, int x0 = 0, int y0 = 0, int x1 = 0, int y1 = 0, const void *data = NULL);
|
void Cmd(OSD_Command cmd, int color = 0, int x0 = 0, int y0 = 0, int x1 = 0, int y1 = 0, const void *data = NULL);
|
||||||
protected:
|
|
||||||
virtual bool OpenWindow(cWindow *Window);
|
|
||||||
virtual void CommitWindow(cWindow *Window);
|
|
||||||
virtual void ShowWindow(cWindow *Window);
|
|
||||||
virtual void HideWindow(cWindow *Window, bool Hide);
|
|
||||||
virtual void MoveWindow(cWindow *Window, int x, int y);
|
|
||||||
virtual void CloseWindow(cWindow *Window);
|
|
||||||
public:
|
public:
|
||||||
cDvbOsd(int x, int y);
|
cDvbOsd(int Left, int Top, int OsdDev);
|
||||||
virtual ~cDvbOsd();
|
virtual ~cDvbOsd();
|
||||||
static void SetDvbDevice(const cDvbDevice *DvbDevice);
|
virtual eOsdError CanHandleAreas(const tArea *Areas, int NumAreas);
|
||||||
|
virtual void Flush(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
class cDvbOsdProvider : public cOsdProvider {
|
||||||
|
private:
|
||||||
|
int osdDev;
|
||||||
|
public:
|
||||||
|
cDvbOsdProvider(int OsdDev);
|
||||||
|
virtual cOsd *CreateOsd(int Left, int Top);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //__DVBOSD_H
|
#endif //__DVBOSD_H
|
||||||
|
17
dvbspu.c
17
dvbspu.c
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
* parts of this file are derived from the OMS program.
|
* parts of this file are derived from the OMS program.
|
||||||
*
|
*
|
||||||
* $Id: dvbspu.c 1.5 2003/10/12 09:43:18 kls Exp $
|
* $Id: dvbspu.c 1.6 2004/04/30 13:45:02 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@ -16,8 +16,6 @@
|
|||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include "osd.h"
|
|
||||||
#include "osdbase.h"
|
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
#include "dvbspu.h"
|
#include "dvbspu.h"
|
||||||
|
|
||||||
@ -105,13 +103,13 @@ cBitmap *cDvbSpuBitmap::getBitmap(const aDvbSpuPalDescr paldescr,
|
|||||||
if (w & 0x03)
|
if (w & 0x03)
|
||||||
w += 4 - (w & 0x03);
|
w += 4 - (w & 0x03);
|
||||||
|
|
||||||
cBitmap *ret = new cBitmap(w, h, 2, true);
|
cBitmap *ret = new cBitmap(w, h, 2);
|
||||||
|
|
||||||
// set the palette
|
// set the palette
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
uint32_t color =
|
uint32_t color =
|
||||||
pal.getColor(paldescr[i].index, paldescr[i].trans);
|
pal.getColor(paldescr[i].index, paldescr[i].trans);
|
||||||
ret->SetColor(i, (eDvbColor) color);
|
ret->SetColor(i, (tColor) color);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the content
|
// set the content
|
||||||
@ -323,8 +321,9 @@ int cDvbSpuDecoder::ScaleYres(int value)
|
|||||||
|
|
||||||
void cDvbSpuDecoder::DrawBmp(sDvbSpuRect & size, cBitmap * bmp)
|
void cDvbSpuDecoder::DrawBmp(sDvbSpuRect & size, cBitmap * bmp)
|
||||||
{
|
{
|
||||||
osd->Create(size.x1, size.y1, size.width(), size.height(), 2, false);
|
tArea Area = { size.x1, size.y1, size.x2, size.y2, 2 };
|
||||||
osd->SetBitmap(size.x1, size.y1, *bmp);
|
osd->SetAreas(&Area, 1);
|
||||||
|
osd->DrawBitmap(size.x1, size.y1, *bmp);
|
||||||
delete bmp;
|
delete bmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -360,8 +359,8 @@ void cDvbSpuDecoder::Draw(void)
|
|||||||
|
|
||||||
if (bg || fg) {
|
if (bg || fg) {
|
||||||
if (osd == NULL)
|
if (osd == NULL)
|
||||||
if ((osd = cOsd::OpenRaw(0, 0)) == NULL) {
|
if ((osd = cOsdProvider::NewOsd(0, 0)) == NULL) {
|
||||||
dsyslog("OpenRaw failed\n");
|
dsyslog("NewOsd failed\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
6
dvbspu.h
6
dvbspu.h
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
* parts of this file are derived from the OMS program.
|
* parts of this file are derived from the OMS program.
|
||||||
*
|
*
|
||||||
* $Id: dvbspu.h 1.2 2002/09/29 13:49:01 kls Exp $
|
* $Id: dvbspu.h 1.3 2004/04/30 13:44:41 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __DVBSPU_H
|
#ifndef __DVBSPU_H
|
||||||
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
#include "osdbase.h"
|
#include "osd.h"
|
||||||
#include "spu.h"
|
#include "spu.h"
|
||||||
|
|
||||||
typedef struct sDvbSpuPalDescr {
|
typedef struct sDvbSpuPalDescr {
|
||||||
@ -91,7 +91,7 @@ class cDvbSpuBitmap {
|
|||||||
|
|
||||||
class cDvbSpuDecoder:public cSpuDecoder {
|
class cDvbSpuDecoder:public cSpuDecoder {
|
||||||
private:
|
private:
|
||||||
cOsdBase * osd;
|
cOsd * osd;
|
||||||
|
|
||||||
// processing state
|
// processing state
|
||||||
uint8_t *spu;
|
uint8_t *spu;
|
||||||
|
@ -4,14 +4,14 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: eitscan.c 1.21 2004/02/14 13:44:31 kls Exp $
|
* $Id: eitscan.c 1.22 2004/04/16 13:33:34 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "eitscan.h"
|
#include "eitscan.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "channels.h"
|
#include "channels.h"
|
||||||
#include "dvbdevice.h"
|
#include "dvbdevice.h"
|
||||||
#include "interface.h"
|
#include "skins.h"
|
||||||
|
|
||||||
// --- cScanData -------------------------------------------------------------
|
// --- cScanData -------------------------------------------------------------
|
||||||
|
|
||||||
@ -149,7 +149,7 @@ void cEITScanner::Process(void)
|
|||||||
if ((!Channel->Ca() || Channel->Ca() == Device->DeviceNumber() + 1 || Channel->Ca() >= 0x0100) && Device->ProvidesTransponder(Channel)) {
|
if ((!Channel->Ca() || Channel->Ca() == Device->DeviceNumber() + 1 || Channel->Ca() >= 0x0100) && Device->ProvidesTransponder(Channel)) {
|
||||||
if (Device == cDevice::PrimaryDevice() && !currentChannel) {
|
if (Device == cDevice::PrimaryDevice() && !currentChannel) {
|
||||||
currentChannel = Device->CurrentChannel();
|
currentChannel = Device->CurrentChannel();
|
||||||
Interface->Info("Starting EPG scan");
|
Skins.Message(mtInfo, "Starting EPG scan");
|
||||||
}
|
}
|
||||||
currentDevice = Device;//XXX see also dvbdevice.c!!!
|
currentDevice = Device;//XXX see also dvbdevice.c!!!
|
||||||
Device->SwitchChannel(Channel, false);
|
Device->SwitchChannel(Channel, false);
|
||||||
|
136
font.c
136
font.c
@ -4,9 +4,11 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: font.c 1.5 2004/01/16 13:17:57 kls Exp $
|
* $Id: font.c 1.6 2004/04/24 15:25:48 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include <ctype.h>
|
||||||
#include "font.h"
|
#include "font.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
|
||||||
@ -22,6 +24,8 @@
|
|||||||
#include "fontosd-iso8859-7.c"
|
#include "fontosd-iso8859-7.c"
|
||||||
#include "fontsml-iso8859-7.c"
|
#include "fontsml-iso8859-7.c"
|
||||||
|
|
||||||
|
// --- cFont -----------------------------------------------------------------
|
||||||
|
|
||||||
static void *FontData[eDvbCodeSize][eDvbFontSize] = {
|
static void *FontData[eDvbCodeSize][eDvbFontSize] = {
|
||||||
{ FontOsd_iso8859_1, FontFix_iso8859_1, FontSml_iso8859_1 },
|
{ FontOsd_iso8859_1, FontFix_iso8859_1, FontSml_iso8859_1 },
|
||||||
{ FontOsd_iso8859_5, FontFix_iso8859_5, FontSml_iso8859_5 },
|
{ FontOsd_iso8859_5, FontFix_iso8859_5, FontSml_iso8859_5 },
|
||||||
@ -44,9 +48,9 @@ cFont::cFont(void *Data)
|
|||||||
|
|
||||||
void cFont::SetData(void *Data)
|
void cFont::SetData(void *Data)
|
||||||
{
|
{
|
||||||
int h = ((tCharData *)Data)->height;
|
height = ((tCharData *)Data)->height;
|
||||||
for (int i = 0; i < NUMCHARS; i++)
|
for (int i = 0; i < NUMCHARS; i++)
|
||||||
data[i] = (tCharData *)&((tPixelData *)Data)[(i < 32 ? 0 : i - 32) * (h + 2)];
|
data[i] = (tCharData *)&((tPixelData *)Data)[(i < 32 ? 0 : i - 32) * (height + 2)];
|
||||||
}
|
}
|
||||||
|
|
||||||
int cFont::Width(const char *s) const
|
int cFont::Width(const char *s) const
|
||||||
@ -61,7 +65,7 @@ int cFont::Height(const char *s) const
|
|||||||
{
|
{
|
||||||
int h = 0;
|
int h = 0;
|
||||||
if (s && *s)
|
if (s && *s)
|
||||||
h = Height(*s); // all characters have the same height!
|
h = height; // all characters have the same height!
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,7 +99,131 @@ void cFont::SetFont(eDvbFont Font, void *Data)
|
|||||||
|
|
||||||
const cFont *cFont::GetFont(eDvbFont Font)
|
const cFont *cFont::GetFont(eDvbFont Font)
|
||||||
{
|
{
|
||||||
|
if (Setup.UseSmallFont == 0 && Font == fontSml)
|
||||||
|
Font = fontOsd;
|
||||||
|
else if (Setup.UseSmallFont == 2 && Font == fontOsd)
|
||||||
|
Font = fontSml;
|
||||||
if (!fonts[Font])
|
if (!fonts[Font])
|
||||||
SetFont(Font);
|
SetFont(Font);
|
||||||
return fonts[Font];
|
return fonts[Font];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- cTextWrapper ----------------------------------------------------------
|
||||||
|
|
||||||
|
cTextWrapper::cTextWrapper(void)
|
||||||
|
{
|
||||||
|
text = eol = NULL;
|
||||||
|
lines = 0;
|
||||||
|
lastLine = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
cTextWrapper::cTextWrapper(const char *Text, const cFont *Font, int Width)
|
||||||
|
{
|
||||||
|
text = NULL;
|
||||||
|
Set(Text, Font, Width);
|
||||||
|
}
|
||||||
|
|
||||||
|
cTextWrapper::~cTextWrapper()
|
||||||
|
{
|
||||||
|
free(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cTextWrapper::Set(const char *Text, const cFont *Font, int Width)
|
||||||
|
{
|
||||||
|
free(text);
|
||||||
|
text = Text ? strdup(Text) : NULL;
|
||||||
|
eol = NULL;
|
||||||
|
lines = 0;
|
||||||
|
lastLine = -1;
|
||||||
|
if (!text)
|
||||||
|
return;
|
||||||
|
lines = 1;
|
||||||
|
if (Width <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
char *Blank = NULL;
|
||||||
|
char *Delim = NULL;
|
||||||
|
int w = 0;
|
||||||
|
|
||||||
|
stripspace(text); // strips trailing newlines
|
||||||
|
|
||||||
|
for (char *p = text; *p; ) {
|
||||||
|
if (*p == '\n') {
|
||||||
|
lines++;
|
||||||
|
w = 0;
|
||||||
|
Blank = Delim = NULL;
|
||||||
|
p++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (isspace(*p))
|
||||||
|
Blank = p;
|
||||||
|
int cw = Font->Width(*p);
|
||||||
|
if (w + cw > Width) {
|
||||||
|
if (Blank) {
|
||||||
|
*Blank = '\n';
|
||||||
|
p = Blank;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Here's the ugly part, where we don't have any whitespace to
|
||||||
|
// punch in a newline, so we need to make room for it:
|
||||||
|
if (Delim)
|
||||||
|
p = Delim + 1; // let's fall back to the most recent delimiter
|
||||||
|
char *s = MALLOC(char, strlen(text) + 2); // The additional '\n' plus the terminating '\0'
|
||||||
|
int l = p - text;
|
||||||
|
strncpy(s, text, l);
|
||||||
|
s[l] = '\n';
|
||||||
|
strcpy(s + l + 1, p);
|
||||||
|
free(text);
|
||||||
|
text = s;
|
||||||
|
p = text + l;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
w += cw;
|
||||||
|
if (strchr("-.,:;!?_", *p)) {
|
||||||
|
Delim = p;
|
||||||
|
Blank = NULL;
|
||||||
|
}
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *cTextWrapper::Text(void)
|
||||||
|
{
|
||||||
|
if (eol) {
|
||||||
|
*eol = '\n';
|
||||||
|
eol = NULL;
|
||||||
|
}
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *cTextWrapper::GetLine(int Line)
|
||||||
|
{
|
||||||
|
char *s = NULL;
|
||||||
|
if (Line < lines) {
|
||||||
|
if (eol) {
|
||||||
|
*eol = '\n';
|
||||||
|
if (Line == lastLine + 1)
|
||||||
|
s = eol + 1;
|
||||||
|
eol = NULL;
|
||||||
|
}
|
||||||
|
if (!s) {
|
||||||
|
s = text;
|
||||||
|
for (int i = 0; i < Line; i++) {
|
||||||
|
s = strchr(s, '\n');
|
||||||
|
if (s)
|
||||||
|
s++;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (s) {
|
||||||
|
if ((eol = strchr(s, '\n')) != NULL)
|
||||||
|
*eol = 0;
|
||||||
|
}
|
||||||
|
lastLine = Line;
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
32
font.h
32
font.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: font.h 1.5 2004/01/16 13:18:28 kls Exp $
|
* $Id: font.h 1.6 2004/04/12 10:21:03 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __FONT_H
|
#ifndef __FONT_H
|
||||||
@ -38,13 +38,20 @@ private:
|
|||||||
static eDvbCode code;
|
static eDvbCode code;
|
||||||
static cFont *fonts[];
|
static cFont *fonts[];
|
||||||
const tCharData *data[NUMCHARS];
|
const tCharData *data[NUMCHARS];
|
||||||
|
int height;
|
||||||
public:
|
public:
|
||||||
cFont(void *Data);
|
cFont(void *Data);
|
||||||
void SetData(void *Data);
|
void SetData(void *Data);
|
||||||
int Width(unsigned char c) const { return data[c]->width; }
|
int Width(unsigned char c) const { return data[c]->width; }
|
||||||
|
///< Returns the width of the given character.
|
||||||
int Width(const char *s) const;
|
int Width(const char *s) const;
|
||||||
|
///< Returns the width of the given string.
|
||||||
int Height(unsigned char c) const { return data[c]->height; }
|
int Height(unsigned char c) const { return data[c]->height; }
|
||||||
|
///< Returns the height of the given character.
|
||||||
int Height(const char *s) const;
|
int Height(const char *s) const;
|
||||||
|
///< Returns the height of the given string.
|
||||||
|
int Height(void) const { return height; }
|
||||||
|
///< Returns the height of this font (all characters have the same height).
|
||||||
const tCharData *CharData(unsigned char c) const { return data[c]; }
|
const tCharData *CharData(unsigned char c) const { return data[c]; }
|
||||||
static bool SetCode(const char *Code);
|
static bool SetCode(const char *Code);
|
||||||
static void SetCode(eDvbCode Code);
|
static void SetCode(eDvbCode Code);
|
||||||
@ -52,4 +59,27 @@ public:
|
|||||||
static const cFont *GetFont(eDvbFont Font);
|
static const cFont *GetFont(eDvbFont Font);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class cTextWrapper {
|
||||||
|
private:
|
||||||
|
char *text;
|
||||||
|
char *eol;
|
||||||
|
int lines;
|
||||||
|
int lastLine;
|
||||||
|
public:
|
||||||
|
cTextWrapper(void);
|
||||||
|
cTextWrapper(const char *Text, const cFont *Font, int Width);
|
||||||
|
~cTextWrapper();
|
||||||
|
void Set(const char *Text, const cFont *Font, int Width);
|
||||||
|
///< Wraps the Text to make it fit into the area defined by the given Width
|
||||||
|
///< when displayed with the given Font.
|
||||||
|
///< Wrapping is done by inserting the necessary number of newline
|
||||||
|
///< characters into the string.
|
||||||
|
const char *Text(void);
|
||||||
|
///< Returns the full wrapped text.
|
||||||
|
int Lines(void) { return lines; }
|
||||||
|
///< Returns the actual number of lines needed to display the full wrapped text.
|
||||||
|
const char *GetLine(int Line);
|
||||||
|
///< Returns the given Line. The first line is numbered 0.
|
||||||
|
};
|
||||||
|
|
||||||
#endif //__FONT_H
|
#endif //__FONT_H
|
||||||
|
182
i18n.c
182
i18n.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: i18n.c 1.153 2004/03/26 15:02:59 kls Exp $
|
* $Id: i18n.c 1.154 2004/05/08 09:25:02 kls Exp $
|
||||||
*
|
*
|
||||||
* Translations provided by:
|
* Translations provided by:
|
||||||
*
|
*
|
||||||
@ -2193,6 +2193,78 @@ const tI18nPhrase Phrases[] = {
|
|||||||
"Idioma",
|
"Idioma",
|
||||||
"Ï×ëÚ",
|
"Ï×ëÚ",
|
||||||
},
|
},
|
||||||
|
{ "Setup.OSD$Skin",
|
||||||
|
"Oberfläche",
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
},
|
||||||
|
{ "Setup.OSD$Theme",
|
||||||
|
"Thema",
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
},
|
||||||
|
{ "Setup.OSD$Left",
|
||||||
|
"Links",
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
},
|
||||||
|
{ "Setup.OSD$Top",
|
||||||
|
"Oben",
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
},
|
||||||
{ "Setup.OSD$Width",
|
{ "Setup.OSD$Width",
|
||||||
"Breite",
|
"Breite",
|
||||||
"Sirina",
|
"Sirina",
|
||||||
@ -2247,6 +2319,78 @@ const tI18nPhrase Phrases[] = {
|
|||||||
"Durada dels missatges (s)",
|
"Durada dels missatges (s)",
|
||||||
"´ÛØâÕÛìÝÞáâì ßÞÚÐ×Ð áÞÞÑéÕÝØÙ (áÕÚ)",
|
"´ÛØâÕÛìÝÞáâì ßÞÚÐ×Ð áÞÞÑéÕÝØÙ (áÕÚ)",
|
||||||
},
|
},
|
||||||
|
{ "Setup.OSD$Use small font",
|
||||||
|
"Kleine Schrift benutzen",
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
},
|
||||||
|
{ "never",
|
||||||
|
"nie",
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
},
|
||||||
|
{ "skin dependent",
|
||||||
|
"je nach Oberfläche",
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
},
|
||||||
|
{ "always",
|
||||||
|
"immer",
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
},
|
||||||
{ "Setup.OSD$Channel info position",
|
{ "Setup.OSD$Channel info position",
|
||||||
"Kanal-Info Position",
|
"Kanal-Info Position",
|
||||||
"Pozicija informacije o kanalu",
|
"Pozicija informacije o kanalu",
|
||||||
@ -4214,6 +4358,42 @@ const tI18nPhrase Phrases[] = {
|
|||||||
"Aquest plugin no admet configuració!",
|
"Aquest plugin no admet configuració!",
|
||||||
"¼ÞÔãÛì ÝÕ ØÜÕÕâ ßÐàÐÜÕâàÞÒ ÝÐáâàÞÙÚØ!",
|
"¼ÞÔãÛì ÝÕ ØÜÕÕâ ßÐàÐÜÕâàÞÒ ÝÐáâàÞÙÚØ!",
|
||||||
},
|
},
|
||||||
|
{ "Classic VDR",
|
||||||
|
"Klassischer VDR",
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
},
|
||||||
|
{ "ST:TNG Panels",
|
||||||
|
"ST:TNG Konsolen",
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
},
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
341
interface.c
341
interface.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: interface.c 1.66 2003/10/24 15:48:00 kls Exp $
|
* $Id: interface.c 1.67 2004/05/02 10:57:06 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "interface.h"
|
#include "interface.h"
|
||||||
@ -12,16 +12,12 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
#include "osd.h"
|
|
||||||
#include "status.h"
|
#include "status.h"
|
||||||
|
|
||||||
cInterface *Interface = NULL;
|
cInterface *Interface = NULL;
|
||||||
|
|
||||||
cInterface::cInterface(int SVDRPport)
|
cInterface::cInterface(int SVDRPport)
|
||||||
{
|
{
|
||||||
open = 0;
|
|
||||||
cols[0] = 0;
|
|
||||||
width = height = 0;
|
|
||||||
interrupted = false;
|
interrupted = false;
|
||||||
SVDRP = NULL;
|
SVDRP = NULL;
|
||||||
if (SVDRPport)
|
if (SVDRPport)
|
||||||
@ -33,38 +29,17 @@ cInterface::~cInterface()
|
|||||||
delete SVDRP;
|
delete SVDRP;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cInterface::Open(int NumCols, int NumLines)
|
|
||||||
{
|
|
||||||
if (!open++) {
|
|
||||||
if (NumCols == 0)
|
|
||||||
NumCols = Setup.OSDwidth;
|
|
||||||
if (NumLines == 0)
|
|
||||||
NumLines = Setup.OSDheight;
|
|
||||||
cOsd::Open(width = NumCols, height = NumLines);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void cInterface::Close(void)
|
|
||||||
{
|
|
||||||
if (open == 1)
|
|
||||||
Clear();
|
|
||||||
if (!--open) {
|
|
||||||
cOsd::Close();
|
|
||||||
width = height = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
eKeys cInterface::GetKey(bool Wait)
|
eKeys cInterface::GetKey(bool Wait)
|
||||||
{
|
{
|
||||||
if (!cRemote::HasKeys())
|
if (!cRemote::HasKeys())
|
||||||
Flush();
|
Skins.Flush();
|
||||||
if (SVDRP) {
|
if (SVDRP) {
|
||||||
if (SVDRP->Process())
|
if (SVDRP->Process())
|
||||||
Wait = false;
|
Wait = false;
|
||||||
if (!open) {
|
if (!Skins.IsOpen()) {
|
||||||
char *message = SVDRP->GetMessage();
|
char *message = SVDRP->GetMessage();
|
||||||
if (message) {
|
if (message) {
|
||||||
Info(message);
|
Skins.Message(mtInfo, message);
|
||||||
free(message);
|
free(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -76,7 +51,7 @@ eKeys cInterface::Wait(int Seconds, bool KeepChar)
|
|||||||
{
|
{
|
||||||
if (Seconds == 0)
|
if (Seconds == 0)
|
||||||
Seconds = Setup.OSDMessageTime;
|
Seconds = Setup.OSDMessageTime;
|
||||||
Flush();
|
Skins.Flush();
|
||||||
eKeys Key = kNone;
|
eKeys Key = kNone;
|
||||||
time_t timeout = time(NULL) + Seconds;
|
time_t timeout = time(NULL) + Seconds;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@ -90,267 +65,37 @@ eKeys cInterface::Wait(int Seconds, bool KeepChar)
|
|||||||
return Key;
|
return Key;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cInterface::Clear(void)
|
|
||||||
{
|
|
||||||
if (open)
|
|
||||||
cOsd::Clear();
|
|
||||||
cStatus::MsgOsdClear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void cInterface::ClearEol(int x, int y, eDvbColor Color)
|
|
||||||
{
|
|
||||||
if (open)
|
|
||||||
cOsd::ClrEol(x, y, Color);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cInterface::Fill(int x, int y, int w, int h, eDvbColor Color)
|
|
||||||
{
|
|
||||||
if (open)
|
|
||||||
cOsd::Fill(x, y, w, h, Color);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cInterface::SetBitmap(int x, int y, const cBitmap &Bitmap)
|
|
||||||
{
|
|
||||||
if (open)
|
|
||||||
cOsd::SetBitmap(x, y, Bitmap);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cInterface::Flush(void)
|
|
||||||
{
|
|
||||||
if (open)
|
|
||||||
cOsd::Flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
void cInterface::SetCols(int *c)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < MaxCols; i++) {
|
|
||||||
cols[i] = *c++;
|
|
||||||
if (cols[i] == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
eDvbFont cInterface::SetFont(eDvbFont Font)
|
|
||||||
{
|
|
||||||
return cOsd::SetFont(Font);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *cInterface::WrapText(const char *Text, int Width, int *Height)
|
|
||||||
{
|
|
||||||
// Wraps the Text to make it fit into the area defined by the given Width
|
|
||||||
// (which is given in character cells).
|
|
||||||
// The actual number of lines resulting from this operation is returned in
|
|
||||||
// Height.
|
|
||||||
// The returned string is newly created on the heap and the caller
|
|
||||||
// is responsible for deleting it once it is no longer used.
|
|
||||||
// Wrapping is done by inserting the necessary number of newline
|
|
||||||
// characters into the string.
|
|
||||||
|
|
||||||
int Lines = 1;
|
|
||||||
char *t = strdup(Text);
|
|
||||||
char *Blank = NULL;
|
|
||||||
char *Delim = NULL;
|
|
||||||
int w = 0;
|
|
||||||
|
|
||||||
Width *= cOsd::CellWidth();
|
|
||||||
|
|
||||||
while (*t && t[strlen(t) - 1] == '\n')
|
|
||||||
t[strlen(t) - 1] = 0; // skips trailing newlines
|
|
||||||
|
|
||||||
for (char *p = t; *p; ) {
|
|
||||||
if (*p == '|')
|
|
||||||
*p = '\n';
|
|
||||||
if (*p == '\n') {
|
|
||||||
Lines++;
|
|
||||||
w = 0;
|
|
||||||
Blank = Delim = NULL;
|
|
||||||
p++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if (isspace(*p))
|
|
||||||
Blank = p;
|
|
||||||
int cw = cOsd::Width(*p);
|
|
||||||
if (w + cw > Width) {
|
|
||||||
if (Blank) {
|
|
||||||
*Blank = '\n';
|
|
||||||
p = Blank;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Here's the ugly part, where we don't have any whitespace to
|
|
||||||
// punch in a newline, so we need to make room for it:
|
|
||||||
if (Delim)
|
|
||||||
p = Delim + 1; // let's fall back to the most recent delimiter
|
|
||||||
char *s = MALLOC(char, strlen(t) + 2); // The additional '\n' plus the terminating '\0'
|
|
||||||
int l = p - t;
|
|
||||||
strncpy(s, t, l);
|
|
||||||
s[l] = '\n';
|
|
||||||
strcpy(s + l + 1, p);
|
|
||||||
free(t);
|
|
||||||
t = s;
|
|
||||||
p = t + l;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
w += cw;
|
|
||||||
if (strchr("-.,:;!?_", *p)) {
|
|
||||||
Delim = p;
|
|
||||||
Blank = NULL;
|
|
||||||
}
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
|
|
||||||
*Height = Lines;
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
void cInterface::Write(int x, int y, const char *s, eDvbColor FgColor, eDvbColor BgColor)
|
|
||||||
{
|
|
||||||
if (open)
|
|
||||||
cOsd::Text(x, y, s, FgColor, BgColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cInterface::WriteText(int x, int y, const char *s, eDvbColor FgColor, eDvbColor BgColor)
|
|
||||||
{
|
|
||||||
if (open) {
|
|
||||||
ClearEol(x, y, BgColor);
|
|
||||||
int col = 0;
|
|
||||||
for (;;) {
|
|
||||||
const char *t = strchr(s, '\t');
|
|
||||||
const char *p = s;
|
|
||||||
char buf[1000];
|
|
||||||
if (t && col < MaxCols && cols[col] > 0) {
|
|
||||||
unsigned int n = t - s;
|
|
||||||
if (n >= sizeof(buf))
|
|
||||||
n = sizeof(buf) - 1;
|
|
||||||
strncpy(buf, s, n);
|
|
||||||
buf[n] = 0;
|
|
||||||
p = buf;
|
|
||||||
s = t + 1;
|
|
||||||
}
|
|
||||||
Write(x, y, p, FgColor, BgColor);
|
|
||||||
if (p == s)
|
|
||||||
break;
|
|
||||||
x += cols[col++];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void cInterface::Title(const char *s)
|
|
||||||
{
|
|
||||||
ClearEol(0, 0, clrCyan);
|
|
||||||
const char *t = strchr(s, '\t');
|
|
||||||
if (t) {
|
|
||||||
char buffer[Width() + 1];
|
|
||||||
unsigned int n = t - s;
|
|
||||||
if (n >= sizeof(buffer))
|
|
||||||
n = sizeof(buffer) - 1;
|
|
||||||
strn0cpy(buffer, s, n + 1);
|
|
||||||
Write(1, 0, buffer, clrBlack, clrCyan);
|
|
||||||
t++;
|
|
||||||
Write(-(cOsd::WidthInCells(t) + 1), 0, t, clrBlack, clrCyan);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
int x = (Width() - strlen(s)) / 2;
|
|
||||||
if (x < 0)
|
|
||||||
x = 0;
|
|
||||||
Write(x, 0, s, clrBlack, clrCyan);
|
|
||||||
}
|
|
||||||
cStatus::MsgOsdTitle(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cInterface::Status(const char *s, eDvbColor FgColor, eDvbColor BgColor)
|
|
||||||
{
|
|
||||||
int Line = (abs(height) == 1) ? 0 : -2;
|
|
||||||
ClearEol(0, Line, s ? BgColor : clrBackground);
|
|
||||||
if (s) {
|
|
||||||
int x = (Width() - int(strlen(s))) / 2;
|
|
||||||
if (x < 0)
|
|
||||||
x = 0;
|
|
||||||
Write(x, Line, s, FgColor, BgColor);
|
|
||||||
}
|
|
||||||
cStatus::MsgOsdStatusMessage(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cInterface::Info(const char *s)
|
|
||||||
{
|
|
||||||
Open(Setup.OSDwidth, -1);
|
|
||||||
isyslog("info: %s", s);
|
|
||||||
Status(s, clrBlack, clrGreen);
|
|
||||||
Wait();
|
|
||||||
Status(NULL);
|
|
||||||
Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
void cInterface::Error(const char *s)
|
|
||||||
{
|
|
||||||
Open(Setup.OSDwidth, -1);
|
|
||||||
esyslog("ERROR: %s", s);
|
|
||||||
Status(s, clrWhite, clrRed);
|
|
||||||
Wait();
|
|
||||||
Status(NULL);
|
|
||||||
Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cInterface::Confirm(const char *s, int Seconds, bool WaitForTimeout)
|
bool cInterface::Confirm(const char *s, int Seconds, bool WaitForTimeout)
|
||||||
{
|
{
|
||||||
Open(Setup.OSDwidth, -1);
|
|
||||||
isyslog("confirm: %s", s);
|
isyslog("confirm: %s", s);
|
||||||
Status(s, clrBlack, clrYellow);
|
eKeys k = Skins.Message(mtWarning, s, Seconds);
|
||||||
eKeys k = Wait(Seconds);
|
|
||||||
bool result = WaitForTimeout ? k == kNone : k == kOk;
|
bool result = WaitForTimeout ? k == kNone : k == kOk;
|
||||||
Status(NULL);
|
|
||||||
Close();
|
|
||||||
isyslog("%sconfirmed", result ? "" : "not ");
|
isyslog("%sconfirmed", result ? "" : "not ");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cInterface::HelpButton(int Index, const char *Text, eDvbColor FgColor, eDvbColor BgColor)
|
bool cInterface::QueryKeys(cRemote *Remote, cSkinDisplayMenu *DisplayMenu)
|
||||||
{
|
{
|
||||||
if (open) {
|
DisplayMenu->SetItem(tr("Phase 1: Detecting RC code type"), 1, false, false);
|
||||||
const int w = Width() / 4;
|
DisplayMenu->SetItem(tr("Press any key on the RC unit"), 3, false, false);
|
||||||
cOsd::Fill(Index * w, -1, w, 1, Text ? BgColor : clrBackground);
|
DisplayMenu->Flush();
|
||||||
if (Text) {
|
|
||||||
int l = (w - int(strlen(Text))) / 2;
|
|
||||||
if (l < 0)
|
|
||||||
l = 0;
|
|
||||||
cOsd::Text(Index * w + l, -1, Text, FgColor, BgColor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void cInterface::Help(const char *Red, const char *Green, const char *Yellow, const char *Blue)
|
|
||||||
{
|
|
||||||
HelpButton(0, Red, clrBlack, clrRed);
|
|
||||||
HelpButton(1, Green, clrBlack, clrGreen);
|
|
||||||
HelpButton(2, Yellow, clrBlack, clrYellow);
|
|
||||||
HelpButton(3, Blue, clrWhite, clrBlue);
|
|
||||||
cStatus::MsgOsdHelpKeys(Red, Green, Yellow, Blue);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cInterface::QueryKeys(cRemote *Remote)
|
|
||||||
{
|
|
||||||
WriteText(1, 3, tr("Phase 1: Detecting RC code type"));
|
|
||||||
WriteText(1, 5, tr("Press any key on the RC unit"));
|
|
||||||
Flush();
|
|
||||||
if (Remote->Initialize()) {
|
if (Remote->Initialize()) {
|
||||||
WriteText(1, 5, tr("RC code detected!"));
|
DisplayMenu->SetItem(tr("RC code detected!"), 3, false, false);
|
||||||
WriteText(1, 6, tr("Do not press any key..."));
|
DisplayMenu->SetItem(tr("Do not press any key..."), 4, false, false);
|
||||||
Flush();
|
DisplayMenu->Flush();
|
||||||
sleep(3);
|
sleep(3);
|
||||||
ClearEol(0, 5);
|
DisplayMenu->SetItem("", 3, false, false);
|
||||||
ClearEol(0, 6);
|
DisplayMenu->SetItem("", 4, false, false);
|
||||||
|
|
||||||
WriteText(1, 3, tr("Phase 2: Learning specific key codes"));
|
DisplayMenu->SetItem(tr("Phase 2: Learning specific key codes"), 1, false, false);
|
||||||
eKeys NewKey = kUp;
|
eKeys NewKey = kUp;
|
||||||
while (NewKey != kNone) {
|
while (NewKey != kNone) {
|
||||||
char *Prompt;
|
char *Prompt;
|
||||||
asprintf(&Prompt, tr("Press key for '%s'"), tr(cKey::ToString(NewKey)));
|
asprintf(&Prompt, tr("Press key for '%s'"), tr(cKey::ToString(NewKey)));
|
||||||
WriteText(1, 5, Prompt);
|
DisplayMenu->SetItem(Prompt, 3, false, false);
|
||||||
free(Prompt);
|
free(Prompt);
|
||||||
cRemote::Clear();
|
cRemote::Clear();
|
||||||
Flush();
|
DisplayMenu->Flush();
|
||||||
for (eKeys k = NewKey; k == NewKey; ) {
|
for (eKeys k = NewKey; k == NewKey; ) {
|
||||||
char *NewCode = NULL;
|
char *NewCode = NULL;
|
||||||
eKeys Key = cRemote::Get(100, &NewCode);
|
eKeys Key = cRemote::Get(100, &NewCode);
|
||||||
@ -362,20 +107,20 @@ bool cInterface::QueryKeys(cRemote *Remote)
|
|||||||
Keys.Del(last);
|
Keys.Del(last);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case kDown: WriteText(1, 5, tr("Press 'Up' to confirm"));
|
case kDown: DisplayMenu->SetItem(tr("Press 'Up' to confirm"), 3, false, false);
|
||||||
WriteText(1, 6, tr("Press 'Down' to continue"));
|
DisplayMenu->SetItem(tr("Press 'Down' to continue"), 4, false, false);
|
||||||
ClearEol(0, 7);
|
DisplayMenu->SetItem("", 5, false, false);
|
||||||
ClearEol(0, 8);
|
DisplayMenu->SetItem("", 6, false, false);
|
||||||
ClearEol(0, 9);
|
DisplayMenu->SetItem("", 7, false, false);
|
||||||
Flush();
|
DisplayMenu->Flush();
|
||||||
for (;;) {
|
for (;;) {
|
||||||
Key = cRemote::Get(100);
|
Key = cRemote::Get(100);
|
||||||
if (Key == kUp) {
|
if (Key == kUp) {
|
||||||
Clear();
|
DisplayMenu->Clear();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (Key == kDown) {
|
else if (Key == kDown) {
|
||||||
ClearEol(0, 6);
|
DisplayMenu->SetItem("", 4, false, false);
|
||||||
k = kNone; // breaks the outer for() loop
|
k = kNone; // breaks the outer for() loop
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -394,17 +139,17 @@ bool cInterface::QueryKeys(cRemote *Remote)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (NewKey > kUp)
|
if (NewKey > kUp)
|
||||||
WriteText(1, 7, tr("(press 'Up' to go back)"));
|
DisplayMenu->SetItem(tr("(press 'Up' to go back)"), 5, false, false);
|
||||||
else
|
else
|
||||||
ClearEol(0, 7);
|
DisplayMenu->SetItem("", 5, false, false);
|
||||||
if (NewKey > kDown)
|
if (NewKey > kDown)
|
||||||
WriteText(1, 8, tr("(press 'Down' to end key definition)"));
|
DisplayMenu->SetItem(tr("(press 'Down' to end key definition)"), 6, false, false);
|
||||||
else
|
else
|
||||||
ClearEol(0, 8);
|
DisplayMenu->SetItem("", 6, false, false);
|
||||||
if (NewKey > kMenu)
|
if (NewKey > kMenu)
|
||||||
WriteText(1, 9, tr("(press 'Menu' to skip this key)"));
|
DisplayMenu->SetItem(tr("(press 'Menu' to skip this key)"), 7, false, false);
|
||||||
else
|
else
|
||||||
ClearEol(0, 9);
|
DisplayMenu->SetItem("", 7, false, false);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -421,33 +166,31 @@ void cInterface::LearnKeys(void)
|
|||||||
bool known = Keys.KnowsRemote(Remote->Name());
|
bool known = Keys.KnowsRemote(Remote->Name());
|
||||||
dsyslog("remote control %s - %s", Remote->Name(), known ? "keys known" : "learning keys");
|
dsyslog("remote control %s - %s", Remote->Name(), known ? "keys known" : "learning keys");
|
||||||
if (!known) {
|
if (!known) {
|
||||||
Open();
|
cSkinDisplayMenu *DisplayMenu = Skins.Current()->DisplayMenu();
|
||||||
char Headline[Width()];
|
char Headline[256];
|
||||||
snprintf(Headline, sizeof(Headline), tr("Learning Remote Control Keys (%s)"), Remote->Name());
|
snprintf(Headline, sizeof(Headline), tr("Learning Remote Control Keys (%s)"), Remote->Name());
|
||||||
Clear();
|
|
||||||
cRemote::Clear();
|
cRemote::Clear();
|
||||||
WriteText(1, 1, Headline);
|
DisplayMenu->SetTitle(Headline);
|
||||||
cRemote::SetLearning(Remote);
|
cRemote::SetLearning(Remote);
|
||||||
bool rc = QueryKeys(Remote);
|
bool rc = QueryKeys(Remote, DisplayMenu);
|
||||||
cRemote::SetLearning(NULL);
|
cRemote::SetLearning(NULL);
|
||||||
Clear();
|
DisplayMenu->Clear();
|
||||||
if (!rc) {
|
if (!rc) {
|
||||||
Close();
|
delete DisplayMenu;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
WriteText(1, 1, Headline);
|
DisplayMenu->SetItem(tr("Phase 3: Saving key codes"), 1, false, false);
|
||||||
WriteText(1, 3, tr("Phase 3: Saving key codes"));
|
DisplayMenu->SetItem(tr("Press 'Up' to save, 'Down' to cancel"), 3, false, false);
|
||||||
WriteText(1, 5, tr("Press 'Up' to save, 'Down' to cancel"));
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
eKeys key = GetKey();
|
eKeys key = GetKey();
|
||||||
if (key == kUp) {
|
if (key == kUp) {
|
||||||
Keys.Save();
|
Keys.Save();
|
||||||
Close();
|
delete DisplayMenu;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (key == kDown) {
|
else if (key == kDown) {
|
||||||
Keys.Load();
|
Keys.Load();
|
||||||
Close();
|
delete DisplayMenu;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
35
interface.h
35
interface.h
@ -4,57 +4,30 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: interface.h 1.30 2003/10/05 09:42:53 kls Exp $
|
* $Id: interface.h 1.31 2004/05/01 11:11:13 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __INTERFACE_H
|
#ifndef __INTERFACE_H
|
||||||
#define __INTERFACE_H
|
#define __INTERFACE_H
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "osdbase.h"
|
|
||||||
#include "remote.h"
|
#include "remote.h"
|
||||||
|
#include "skins.h"
|
||||||
#include "svdrp.h"
|
#include "svdrp.h"
|
||||||
|
|
||||||
class cInterface {
|
class cInterface {
|
||||||
public:
|
|
||||||
enum { MaxCols = 5 };
|
|
||||||
private:
|
private:
|
||||||
int width, height;
|
|
||||||
int open;
|
|
||||||
int cols[MaxCols];
|
|
||||||
bool interrupted;
|
bool interrupted;
|
||||||
cSVDRP *SVDRP;
|
cSVDRP *SVDRP;
|
||||||
bool QueryKeys(cRemote *Remote);
|
bool QueryKeys(cRemote *Remote, cSkinDisplayMenu *DisplayMenu);
|
||||||
void HelpButton(int Index, const char *Text, eDvbColor FgColor, eDvbColor BgColor);
|
|
||||||
eKeys Wait(int Seconds = 0, bool KeepChar = false);
|
|
||||||
public:
|
public:
|
||||||
cInterface(int SVDRPport = 0);
|
cInterface(int SVDRPport = 0);
|
||||||
~cInterface();
|
~cInterface();
|
||||||
bool IsOpen(void) { return open > 0; }
|
|
||||||
void Open(int NumCols = 0, int NumLines = 0);
|
|
||||||
void Close(void);
|
|
||||||
bool HasSVDRPConnection(void) { return SVDRP && SVDRP->HasConnection(); }
|
bool HasSVDRPConnection(void) { return SVDRP && SVDRP->HasConnection(); }
|
||||||
void Interrupt(void) { interrupted = true; }
|
void Interrupt(void) { interrupted = true; }
|
||||||
int Width(void) { return width; }
|
|
||||||
int Height(void) { return height; }
|
|
||||||
eKeys GetKey(bool Wait = true);
|
eKeys GetKey(bool Wait = true);
|
||||||
void Clear(void);
|
eKeys Wait(int Seconds = 0, bool KeepChar = false);
|
||||||
void ClearEol(int x, int y, eDvbColor Color = clrBackground);
|
|
||||||
void Fill(int x, int y, int w, int h, eDvbColor color = clrBackground);
|
|
||||||
void SetBitmap(int x, int y, const cBitmap &Bitmap);
|
|
||||||
void Flush(void);
|
|
||||||
void SetCols(int *c);
|
|
||||||
const int *GetCols(void) { return cols; }
|
|
||||||
eDvbFont SetFont(eDvbFont Font);
|
|
||||||
char *WrapText(const char *Text, int Width, int *Height);
|
|
||||||
void Write(int x, int y, const char *s, eDvbColor FgColor = clrWhite, eDvbColor BgColor = clrBackground);
|
|
||||||
void WriteText(int x, int y, const char *s, eDvbColor FgColor = clrWhite, eDvbColor BgColor = clrBackground);
|
|
||||||
void Title(const char *s);
|
|
||||||
void Status(const char *s, eDvbColor FgColor = clrBlack, eDvbColor BgColor = clrCyan);
|
|
||||||
void Info(const char *s);
|
|
||||||
void Error(const char *s);
|
|
||||||
bool Confirm(const char *s, int Seconds = 10, bool WaitForTimeout = false);
|
bool Confirm(const char *s, int Seconds = 10, bool WaitForTimeout = false);
|
||||||
void Help(const char *Red, const char *Green = NULL, const char *Yellow = NULL, const char *Blue = NULL);
|
|
||||||
void LearnKeys(void);
|
void LearnKeys(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
487
menu.c
487
menu.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: menu.c 1.298 2004/03/28 09:17:15 kls Exp $
|
* $Id: menu.c 1.299 2004/05/15 14:15:33 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
@ -18,12 +18,14 @@
|
|||||||
#include "cutter.h"
|
#include "cutter.h"
|
||||||
#include "eitscan.h"
|
#include "eitscan.h"
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
|
#include "interface.h"
|
||||||
#include "menuitems.h"
|
#include "menuitems.h"
|
||||||
#include "plugin.h"
|
#include "plugin.h"
|
||||||
#include "recording.h"
|
#include "recording.h"
|
||||||
#include "remote.h"
|
#include "remote.h"
|
||||||
#include "sources.h"
|
#include "sources.h"
|
||||||
#include "status.h"
|
#include "status.h"
|
||||||
|
#include "themes.h"
|
||||||
#include "timers.h"
|
#include "timers.h"
|
||||||
#include "transfer.h"
|
#include "transfer.h"
|
||||||
#include "videodir.h"
|
#include "videodir.h"
|
||||||
@ -309,7 +311,7 @@ eOSState cMenuEditChannel::ProcessKey(eKeys Key)
|
|||||||
Channels.SetModified();
|
Channels.SetModified();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Interface->Error(tr("Channel settings are not unique!"));
|
Skins.Message(mtError, tr("Channel settings are not unique!"));
|
||||||
state = osContinue;
|
state = osContinue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -334,7 +336,7 @@ cMenuChannelItem::cMenuChannelItem(cChannel *Channel)
|
|||||||
{
|
{
|
||||||
channel = Channel;
|
channel = Channel;
|
||||||
if (channel->GroupSep())
|
if (channel->GroupSep())
|
||||||
SetColor(clrCyan, clrBackground);
|
SetSelectable(false);
|
||||||
Set();
|
Set();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -433,7 +435,7 @@ eOSState cMenuChannels::Delete(void)
|
|||||||
// Check if there is a timer using this channel:
|
// Check if there is a timer using this channel:
|
||||||
for (cTimer *ti = Timers.First(); ti; ti = Timers.Next(ti)) {
|
for (cTimer *ti = Timers.First(); ti; ti = Timers.Next(ti)) {
|
||||||
if (ti->Channel() == channel) {
|
if (ti->Channel() == channel) {
|
||||||
Interface->Error(tr("Channel is being used by a timer!"));
|
Skins.Message(mtError, tr("Channel is being used by a timer!"));
|
||||||
return osContinue;
|
return osContinue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -498,19 +500,42 @@ eOSState cMenuChannels::ProcessKey(eKeys Key)
|
|||||||
// --- cMenuText -------------------------------------------------------------
|
// --- cMenuText -------------------------------------------------------------
|
||||||
|
|
||||||
class cMenuText : public cOsdMenu {
|
class cMenuText : public cOsdMenu {
|
||||||
|
private:
|
||||||
|
const char *text;
|
||||||
public:
|
public:
|
||||||
cMenuText(const char *Title, const char *Text, eDvbFont Font = fontOsd);
|
cMenuText(const char *Title, const char *Text, eDvbFont Font = fontOsd);
|
||||||
|
virtual void Display(void);
|
||||||
virtual eOSState ProcessKey(eKeys Key);
|
virtual eOSState ProcessKey(eKeys Key);
|
||||||
};
|
};
|
||||||
|
|
||||||
cMenuText::cMenuText(const char *Title, const char *Text, eDvbFont Font)
|
cMenuText::cMenuText(const char *Title, const char *Text, eDvbFont Font)
|
||||||
:cOsdMenu(Title)
|
:cOsdMenu(Title)
|
||||||
{
|
{
|
||||||
Add(new cMenuTextItem(Text, 1, 2, Setup.OSDwidth - 2, MAXOSDITEMS, clrWhite, clrBackground, Font));
|
text = Text;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cMenuText::Display(void)
|
||||||
|
{
|
||||||
|
cOsdMenu::Display();
|
||||||
|
DisplayMenu()->SetText(text, true);//XXX define control character in text to choose the font???
|
||||||
}
|
}
|
||||||
|
|
||||||
eOSState cMenuText::ProcessKey(eKeys Key)
|
eOSState cMenuText::ProcessKey(eKeys Key)
|
||||||
{
|
{
|
||||||
|
switch (Key) {
|
||||||
|
case kUp|k_Repeat:
|
||||||
|
case kUp:
|
||||||
|
case kDown|k_Repeat:
|
||||||
|
case kDown:
|
||||||
|
case kLeft|k_Repeat:
|
||||||
|
case kLeft:
|
||||||
|
case kRight|k_Repeat:
|
||||||
|
case kRight:
|
||||||
|
DisplayMenu()->Scroll(NORMALKEY(Key) == kUp || NORMALKEY(Key) == kLeft, NORMALKEY(Key) == kLeft || NORMALKEY(Key) == kRight);
|
||||||
|
return osContinue;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
eOSState state = cOsdMenu::ProcessKey(Key);
|
eOSState state = cOsdMenu::ProcessKey(Key);
|
||||||
|
|
||||||
if (state == osUnknown) {
|
if (state == osUnknown) {
|
||||||
@ -595,7 +620,7 @@ eOSState cMenuEditTimer::ProcessKey(eKeys Key)
|
|||||||
if (ch)
|
if (ch)
|
||||||
data.channel = ch;
|
data.channel = ch;
|
||||||
else {
|
else {
|
||||||
Interface->Error(tr("*** Invalid Channel ***"));
|
Skins.Message(mtError, tr("*** Invalid Channel ***"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!*data.file)
|
if (!*data.file)
|
||||||
@ -775,6 +800,7 @@ eOSState cMenuTimers::Summary(void)
|
|||||||
cTimer *ti = CurrentTimer();
|
cTimer *ti = CurrentTimer();
|
||||||
if (ti && !isempty(ti->Summary()))
|
if (ti && !isempty(ti->Summary()))
|
||||||
return AddSubMenu(new cMenuText(tr("Summary"), ti->Summary()));
|
return AddSubMenu(new cMenuText(tr("Summary"), ti->Summary()));
|
||||||
|
//XXX cSkin::SetRecording()???
|
||||||
return Edit(); // convenience for people not using the Summary feature ;-)
|
return Edit(); // convenience for people not using the Summary feature ;-)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -812,7 +838,7 @@ private:
|
|||||||
const cEvent *event;
|
const cEvent *event;
|
||||||
public:
|
public:
|
||||||
cMenuEvent(const cEvent *Event, bool CanSwitch = false);
|
cMenuEvent(const cEvent *Event, bool CanSwitch = false);
|
||||||
cMenuEvent(bool Now);
|
virtual void Display(void);
|
||||||
virtual eOSState ProcessKey(eKeys Key);
|
virtual eOSState ProcessKey(eKeys Key);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -823,39 +849,34 @@ cMenuEvent::cMenuEvent(const cEvent *Event, bool CanSwitch)
|
|||||||
if (event) {
|
if (event) {
|
||||||
cChannel *channel = Channels.GetByChannelID(event->ChannelID(), true);
|
cChannel *channel = Channels.GetByChannelID(event->ChannelID(), true);
|
||||||
if (channel) {
|
if (channel) {
|
||||||
char *buffer;
|
SetTitle(channel->Name());
|
||||||
asprintf(&buffer, "%-17.*s\t%.*s %s - %s", 17, channel->Name(), 5, event->GetDateString(), event->GetTimeString(), event->GetEndTimeString());
|
|
||||||
SetTitle(buffer, false);
|
|
||||||
free(buffer);
|
|
||||||
int Line = 2;
|
|
||||||
cMenuTextItem *item;
|
|
||||||
const char *Title = event->Title();
|
|
||||||
const char *Subtitle = event->ShortText();
|
|
||||||
const char *ExtendedDescription = event->Description();
|
|
||||||
if (!isempty(Title)) {
|
|
||||||
Add(item = new cMenuTextItem(Title, 1, Line, Setup.OSDwidth - 2, -1, clrCyan));
|
|
||||||
Line += item->Height() + 1;
|
|
||||||
}
|
|
||||||
if (!isempty(Subtitle)) {
|
|
||||||
Add(item = new cMenuTextItem(Subtitle, 1, Line, Setup.OSDwidth - 2, -1, clrYellow));
|
|
||||||
Line += item->Height() + 1;
|
|
||||||
}
|
|
||||||
if (Event->Vps() && Event->Vps() != Event->StartTime()) {
|
|
||||||
char *buffer;
|
|
||||||
asprintf(&buffer, "VPS: %s", Event->GetVpsString());
|
|
||||||
Add(item = new cMenuTextItem(buffer, 1, Line, Setup.OSDwidth - 2, -1, clrYellow));
|
|
||||||
free(buffer);
|
|
||||||
Line += item->Height() + 1;
|
|
||||||
}
|
|
||||||
if (!isempty(ExtendedDescription))
|
|
||||||
Add(new cMenuTextItem(ExtendedDescription, 1, Line, Setup.OSDwidth - 2, Height() - Line - 2, clrCyan), true);
|
|
||||||
SetHelp(tr("Record"), NULL, NULL, CanSwitch ? tr("Switch") : NULL);
|
SetHelp(tr("Record"), NULL, NULL, CanSwitch ? tr("Switch") : NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cMenuEvent::Display(void)
|
||||||
|
{
|
||||||
|
cOsdMenu::Display();
|
||||||
|
DisplayMenu()->SetEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
eOSState cMenuEvent::ProcessKey(eKeys Key)
|
eOSState cMenuEvent::ProcessKey(eKeys Key)
|
||||||
{
|
{
|
||||||
|
switch (Key) {
|
||||||
|
case kUp|k_Repeat:
|
||||||
|
case kUp:
|
||||||
|
case kDown|k_Repeat:
|
||||||
|
case kDown:
|
||||||
|
case kLeft|k_Repeat:
|
||||||
|
case kLeft:
|
||||||
|
case kRight|k_Repeat:
|
||||||
|
case kRight:
|
||||||
|
DisplayMenu()->Scroll(NORMALKEY(Key) == kUp || NORMALKEY(Key) == kLeft, NORMALKEY(Key) == kLeft || NORMALKEY(Key) == kRight);
|
||||||
|
return osContinue;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
eOSState state = cOsdMenu::ProcessKey(Key);
|
eOSState state = cOsdMenu::ProcessKey(Key);
|
||||||
|
|
||||||
if (state == osUnknown) {
|
if (state == osUnknown) {
|
||||||
@ -942,7 +963,7 @@ eOSState cMenuWhatsOn::Switch(void)
|
|||||||
if (channel && cDevice::PrimaryDevice()->SwitchChannel(channel, true))
|
if (channel && cDevice::PrimaryDevice()->SwitchChannel(channel, true))
|
||||||
return osEnd;
|
return osEnd;
|
||||||
}
|
}
|
||||||
Interface->Error(tr("Can't switch channel!"));
|
Skins.Message(mtError, tr("Can't switch channel!"));
|
||||||
return osContinue;
|
return osContinue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1086,7 +1107,7 @@ eOSState cMenuSchedule::Switch(void)
|
|||||||
if (Channels.SwitchTo(otherChannel))
|
if (Channels.SwitchTo(otherChannel))
|
||||||
return osEnd;
|
return osEnd;
|
||||||
}
|
}
|
||||||
Interface->Error(tr("Can't switch channel!"));
|
Skins.Message(mtError, tr("Can't switch channel!"));
|
||||||
return osContinue;
|
return osContinue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1184,10 +1205,10 @@ eOSState cMenuCommands::Execute(void)
|
|||||||
}
|
}
|
||||||
if (confirmed) {
|
if (confirmed) {
|
||||||
asprintf(&buffer, "%s...", command->Title());
|
asprintf(&buffer, "%s...", command->Title());
|
||||||
Interface->Status(buffer);
|
Skins.Message(mtStatus, buffer);
|
||||||
Interface->Flush();
|
|
||||||
free(buffer);
|
free(buffer);
|
||||||
const char *Result = command->Execute(parameters);
|
const char *Result = command->Execute(parameters);
|
||||||
|
Skins.Message(mtStatus, NULL);
|
||||||
if (Result)
|
if (Result)
|
||||||
return AddSubMenu(new cMenuText(command->Title(), Result, fontFix));
|
return AddSubMenu(new cMenuText(command->Title(), Result, fontFix));
|
||||||
return osEnd;
|
return osEnd;
|
||||||
@ -1388,11 +1409,11 @@ cMenuRecordings::cMenuRecordings(const char *Base, int Level, bool OpenSubMenus)
|
|||||||
base = Base ? strdup(Base) : NULL;
|
base = Base ? strdup(Base) : NULL;
|
||||||
level = Setup.RecordingDirs ? Level : -1;
|
level = Setup.RecordingDirs ? Level : -1;
|
||||||
Display(); // this keeps the higher level menus from showing up briefly when pressing 'Back' during replay
|
Display(); // this keeps the higher level menus from showing up briefly when pressing 'Back' during replay
|
||||||
if (!Base) {
|
if (!Base)
|
||||||
Interface->Status(tr("scanning recordings..."));
|
Skins.Message(mtStatus, tr("scanning recordings..."));
|
||||||
Interface->Flush();
|
|
||||||
}
|
|
||||||
if (Base || Recordings.Load()) {
|
if (Base || Recordings.Load()) {
|
||||||
|
if (!Base)
|
||||||
|
Skins.Message(mtStatus, NULL);
|
||||||
const char *LastReplayed = cReplayControl::LastReplayed();
|
const char *LastReplayed = cReplayControl::LastReplayed();
|
||||||
cMenuRecordingItem *LastItem = NULL;
|
cMenuRecordingItem *LastItem = NULL;
|
||||||
char *LastItemText = NULL;
|
char *LastItemText = NULL;
|
||||||
@ -1459,7 +1480,7 @@ cRecording *cMenuRecordings::GetRecording(cMenuRecordingItem *Item)
|
|||||||
{
|
{
|
||||||
cRecording *recording = Recordings.GetByName(Item->FileName());
|
cRecording *recording = Recordings.GetByName(Item->FileName());
|
||||||
if (!recording)
|
if (!recording)
|
||||||
Interface->Error(tr("Error while accessing recording!"));
|
Skins.Message(mtError, tr("Error while accessing recording!"));
|
||||||
return recording;
|
return recording;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1547,7 +1568,7 @@ eOSState cMenuRecordings::Delete(void)
|
|||||||
return osBack;
|
return osBack;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Interface->Error(tr("Error while deleting recording!"));
|
Skins.Message(mtError, tr("Error while deleting recording!"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1641,39 +1662,101 @@ void cMenuSetupBase::Store(void)
|
|||||||
|
|
||||||
class cMenuSetupOSD : public cMenuSetupBase {
|
class cMenuSetupOSD : public cMenuSetupBase {
|
||||||
private:
|
private:
|
||||||
|
const char *useSmallFontTexts[3];
|
||||||
|
int numSkins;
|
||||||
|
int originalSkinIndex;
|
||||||
|
int skinIndex;
|
||||||
|
const char **skinDescriptions;
|
||||||
|
cThemes themes;
|
||||||
|
int themeIndex;
|
||||||
virtual void Set(void);
|
virtual void Set(void);
|
||||||
public:
|
public:
|
||||||
cMenuSetupOSD(void) { Set(); }
|
cMenuSetupOSD(void);
|
||||||
virtual ~cMenuSetupOSD() { cFont::SetCode(I18nCharSets()[Setup.OSDLanguage]); }
|
virtual ~cMenuSetupOSD();
|
||||||
virtual eOSState ProcessKey(eKeys Key);
|
virtual eOSState ProcessKey(eKeys Key);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
cMenuSetupOSD::cMenuSetupOSD(void)
|
||||||
|
{
|
||||||
|
numSkins = Skins.Count();
|
||||||
|
skinIndex = originalSkinIndex = Skins.Current()->Index();
|
||||||
|
skinDescriptions = new const char*[numSkins];
|
||||||
|
themes.Load(Skins.Current()->Name());
|
||||||
|
themeIndex = Skins.Current()->Theme() ? themes.GetThemeIndex(Skins.Current()->Theme()->Description()) : 0;
|
||||||
|
Set();
|
||||||
|
}
|
||||||
|
|
||||||
|
cMenuSetupOSD::~cMenuSetupOSD()
|
||||||
|
{
|
||||||
|
cFont::SetCode(I18nCharSets()[Setup.OSDLanguage]);
|
||||||
|
delete skinDescriptions;
|
||||||
|
}
|
||||||
|
|
||||||
void cMenuSetupOSD::Set(void)
|
void cMenuSetupOSD::Set(void)
|
||||||
{
|
{
|
||||||
|
int current = Current();
|
||||||
|
for (cSkin *Skin = Skins.First(); Skin; Skin = Skins.Next(Skin))
|
||||||
|
skinDescriptions[Skin->Index()] = Skin->Description();
|
||||||
|
useSmallFontTexts[0] = tr("never");
|
||||||
|
useSmallFontTexts[1] = tr("skin dependent");
|
||||||
|
useSmallFontTexts[2] = tr("always");
|
||||||
Clear();
|
Clear();
|
||||||
SetSection(tr("OSD"));
|
SetSection(tr("OSD"));
|
||||||
Add(new cMenuEditStraItem(tr("Setup.OSD$Language"), &data.OSDLanguage, I18nNumLanguages, I18nLanguages()));
|
Add(new cMenuEditStraItem(tr("Setup.OSD$Language"), &data.OSDLanguage, I18nNumLanguages, I18nLanguages()));
|
||||||
Add(new cMenuEditIntItem( tr("Setup.OSD$Width"), &data.OSDwidth, MINOSDWIDTH, MAXOSDWIDTH));
|
Add(new cMenuEditStraItem(tr("Setup.OSD$Skin"), &skinIndex, numSkins, skinDescriptions));
|
||||||
Add(new cMenuEditIntItem( tr("Setup.OSD$Height"), &data.OSDheight, MINOSDHEIGHT, MAXOSDHEIGHT));
|
if (themes.NumThemes())
|
||||||
|
Add(new cMenuEditStraItem(tr("Setup.OSD$Theme"), &themeIndex, themes.NumThemes(), themes.Descriptions()));
|
||||||
|
Add(new cMenuEditIntItem( tr("Setup.OSD$Left"), &data.OSDLeft, 0, MAXOSDWIDTH));
|
||||||
|
Add(new cMenuEditIntItem( tr("Setup.OSD$Top"), &data.OSDTop, 0, MAXOSDHEIGHT));
|
||||||
|
Add(new cMenuEditIntItem( tr("Setup.OSD$Width"), &data.OSDWidth, MINOSDWIDTH, MAXOSDWIDTH));
|
||||||
|
Add(new cMenuEditIntItem( tr("Setup.OSD$Height"), &data.OSDHeight, MINOSDHEIGHT, MAXOSDHEIGHT));
|
||||||
Add(new cMenuEditIntItem( tr("Setup.OSD$Message time (s)"), &data.OSDMessageTime, 1, 60));
|
Add(new cMenuEditIntItem( tr("Setup.OSD$Message time (s)"), &data.OSDMessageTime, 1, 60));
|
||||||
|
Add(new cMenuEditStraItem(tr("Setup.OSD$Use small font"), &data.UseSmallFont, 3, useSmallFontTexts));
|
||||||
Add(new cMenuEditBoolItem(tr("Setup.OSD$Channel info position"), &data.ChannelInfoPos, tr("bottom"), tr("top")));
|
Add(new cMenuEditBoolItem(tr("Setup.OSD$Channel info position"), &data.ChannelInfoPos, tr("bottom"), tr("top")));
|
||||||
Add(new cMenuEditBoolItem(tr("Setup.OSD$Info on channel switch"), &data.ShowInfoOnChSwitch));
|
Add(new cMenuEditBoolItem(tr("Setup.OSD$Info on channel switch"), &data.ShowInfoOnChSwitch));
|
||||||
Add(new cMenuEditBoolItem(tr("Setup.OSD$Scroll pages"), &data.MenuScrollPage));
|
Add(new cMenuEditBoolItem(tr("Setup.OSD$Scroll pages"), &data.MenuScrollPage));
|
||||||
Add(new cMenuEditBoolItem(tr("Setup.OSD$Sort timers"), &data.SortTimers));
|
Add(new cMenuEditBoolItem(tr("Setup.OSD$Sort timers"), &data.SortTimers));
|
||||||
Add(new cMenuEditBoolItem(tr("Setup.OSD$Recording directories"), &data.RecordingDirs));
|
Add(new cMenuEditBoolItem(tr("Setup.OSD$Recording directories"), &data.RecordingDirs));
|
||||||
|
SetCurrent(Get(current));
|
||||||
|
Display();
|
||||||
}
|
}
|
||||||
|
|
||||||
eOSState cMenuSetupOSD::ProcessKey(eKeys Key)
|
eOSState cMenuSetupOSD::ProcessKey(eKeys Key)
|
||||||
{
|
{
|
||||||
|
if (Key == kOk) {
|
||||||
|
if (skinIndex != originalSkinIndex) {
|
||||||
|
cSkin *Skin = Skins.Get(skinIndex);
|
||||||
|
if (Skin) {
|
||||||
|
strn0cpy(data.OSDSkin, Skin->Name(), sizeof(data.OSDSkin));
|
||||||
|
Skins.SetCurrent(Skin->Name());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (themes.NumThemes() && Skins.Current()->Theme()) {
|
||||||
|
Skins.Current()->Theme()->Load(themes.FileName(themeIndex));
|
||||||
|
strn0cpy(data.OSDTheme, themes.Name(themeIndex), sizeof(data.OSDTheme));
|
||||||
|
}
|
||||||
|
data.OSDWidth &= ~0x07; // OSD width must be a multiple of 8
|
||||||
|
}
|
||||||
|
|
||||||
int osdLanguage = data.OSDLanguage;
|
int osdLanguage = data.OSDLanguage;
|
||||||
|
int oldSkinIndex = skinIndex;
|
||||||
eOSState state = cMenuSetupBase::ProcessKey(Key);
|
eOSState state = cMenuSetupBase::ProcessKey(Key);
|
||||||
|
|
||||||
if (data.OSDLanguage != osdLanguage) {
|
if (data.OSDLanguage != osdLanguage || skinIndex != oldSkinIndex) {
|
||||||
int OriginalOSDLanguage = Setup.OSDLanguage;
|
int OriginalOSDLanguage = Setup.OSDLanguage;
|
||||||
Setup.OSDLanguage = data.OSDLanguage;
|
Setup.OSDLanguage = data.OSDLanguage;
|
||||||
cFont::SetCode(I18nCharSets()[Setup.OSDLanguage]);
|
cFont::SetCode(I18nCharSets()[Setup.OSDLanguage]);
|
||||||
|
|
||||||
|
cSkin *Skin = Skins.Get(skinIndex);
|
||||||
|
if (Skin) {
|
||||||
|
char *d = themes.NumThemes() ? strdup(themes.Descriptions()[themeIndex]) : NULL;
|
||||||
|
themes.Load(Skin->Name());
|
||||||
|
if (skinIndex != oldSkinIndex)
|
||||||
|
themeIndex = d ? themes.GetThemeIndex(d) : 0;
|
||||||
|
free(d);
|
||||||
|
}
|
||||||
|
|
||||||
Set();
|
Set();
|
||||||
Display();
|
|
||||||
Setup.OSDLanguage = OriginalOSDLanguage;
|
Setup.OSDLanguage = OriginalOSDLanguage;
|
||||||
}
|
}
|
||||||
return state;
|
return state;
|
||||||
@ -1912,7 +1995,7 @@ eOSState cMenuSetupCICAM::Menu(void)
|
|||||||
if (CiHandler && CiHandler->EnterMenu(Slot))
|
if (CiHandler && CiHandler->EnterMenu(Slot))
|
||||||
return osEnd; // the CAM menu will be executed explicitly from the main loop
|
return osEnd; // the CAM menu will be executed explicitly from the main loop
|
||||||
else
|
else
|
||||||
Interface->Error(tr("Can't open CAM menu!"));
|
Skins.Message(mtError, tr("Can't open CAM menu!"));
|
||||||
return osContinue;
|
return osContinue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1921,11 +2004,11 @@ eOSState cMenuSetupCICAM::Reset(void)
|
|||||||
int Slot = 0;
|
int Slot = 0;
|
||||||
cCiHandler *CiHandler = GetCurrentCiHandler(&Slot);
|
cCiHandler *CiHandler = GetCurrentCiHandler(&Slot);
|
||||||
if (CiHandler && CiHandler->Reset(Slot)) {
|
if (CiHandler && CiHandler->Reset(Slot)) {
|
||||||
Interface->Info(tr("CAM has been reset"));
|
Skins.Message(mtInfo, tr("CAM has been reset"));
|
||||||
return osEnd;
|
return osEnd;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Interface->Error(tr("Can't reset CAM!"));
|
Skins.Message(mtError, tr("Can't reset CAM!"));
|
||||||
return osContinue;
|
return osContinue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2064,7 +2147,7 @@ eOSState cMenuSetupPlugins::ProcessKey(eKeys Key)
|
|||||||
menu->SetPlugin(p);
|
menu->SetPlugin(p);
|
||||||
return AddSubMenu(menu);
|
return AddSubMenu(menu);
|
||||||
}
|
}
|
||||||
Interface->Info(tr("This plugin has no setup parameters!"));
|
Skins.Message(mtInfo, tr("This plugin has no setup parameters!"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2199,7 +2282,7 @@ cOsdObject *cMenuMain::PluginOsdObject(void)
|
|||||||
void cMenuMain::Set(const char *Plugin)
|
void cMenuMain::Set(const char *Plugin)
|
||||||
{
|
{
|
||||||
Clear();
|
Clear();
|
||||||
//SetTitle("VDR"); // this is done below, including disk usage
|
//XXX //SetTitle("VDR"); // this is done below, including disk usage
|
||||||
SetHasHotkeys();
|
SetHasHotkeys();
|
||||||
|
|
||||||
// Title with disk usage:
|
// Title with disk usage:
|
||||||
@ -2213,6 +2296,7 @@ void cMenuMain::Set(const char *Plugin)
|
|||||||
int Hours = Minutes / 60;
|
int Hours = Minutes / 60;
|
||||||
Minutes %= 60;
|
Minutes %= 60;
|
||||||
snprintf(buffer, sizeof(buffer), "%s - %s %d%% - %2d:%02d %s", tr("VDR"), tr("Disk"), Percent, Hours, Minutes, tr("free"));
|
snprintf(buffer, sizeof(buffer), "%s - %s %d%% - %2d:%02d %s", tr("VDR"), tr("Disk"), Percent, Hours, Minutes, tr("free"));
|
||||||
|
//XXX -> skin function!!!
|
||||||
SetTitle(buffer);
|
SetTitle(buffer);
|
||||||
|
|
||||||
// Basic menu items:
|
// Basic menu items:
|
||||||
@ -2337,9 +2421,7 @@ eOSState cMenuMain::ProcessKey(eKeys Key)
|
|||||||
const char **at = &AudioTracks[CurrentAudioTrack];
|
const char **at = &AudioTracks[CurrentAudioTrack];
|
||||||
if (!*++at)
|
if (!*++at)
|
||||||
at = AudioTracks;
|
at = AudioTracks;
|
||||||
Interface->Clear();
|
|
||||||
cDevice::PrimaryDevice()->SetAudioTrack(at - AudioTracks);
|
cDevice::PrimaryDevice()->SetAudioTrack(at - AudioTracks);
|
||||||
//XXX Interface->Info(*at);
|
|
||||||
state = osEnd;
|
state = osEnd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2376,14 +2458,14 @@ cDisplayChannel::cDisplayChannel(int Number, bool Switched)
|
|||||||
{
|
{
|
||||||
group = -1;
|
group = -1;
|
||||||
withInfo = !Switched || Setup.ShowInfoOnChSwitch;
|
withInfo = !Switched || Setup.ShowInfoOnChSwitch;
|
||||||
int EpgLines = withInfo ? 5 : 1;
|
displayChannel = Skins.Current()->DisplayChannel(withInfo);
|
||||||
lines = 0;
|
|
||||||
number = 0;
|
number = 0;
|
||||||
channel = Channels.GetByNumber(Number);
|
channel = Channels.GetByNumber(Number);
|
||||||
Interface->Open(Setup.OSDwidth, Setup.ChannelInfoPos ? EpgLines : -EpgLines);
|
lastPresent = lastFollowing = NULL;
|
||||||
if (channel) {
|
if (channel) {
|
||||||
DisplayChannel();
|
DisplayChannel();
|
||||||
DisplayInfo();
|
DisplayInfo();
|
||||||
|
displayChannel->Flush();
|
||||||
}
|
}
|
||||||
lastTime = time_ms();
|
lastTime = time_ms();
|
||||||
}
|
}
|
||||||
@ -2392,94 +2474,41 @@ cDisplayChannel::cDisplayChannel(eKeys FirstKey)
|
|||||||
:cOsdObject(true)
|
:cOsdObject(true)
|
||||||
{
|
{
|
||||||
group = -1;
|
group = -1;
|
||||||
lines = 0;
|
|
||||||
number = 0;
|
number = 0;
|
||||||
|
lastPresent = lastFollowing = NULL;
|
||||||
lastTime = time_ms();
|
lastTime = time_ms();
|
||||||
withInfo = Setup.ShowInfoOnChSwitch;
|
withInfo = Setup.ShowInfoOnChSwitch;
|
||||||
int EpgLines = withInfo ? 5 : 1;
|
displayChannel = Skins.Current()->DisplayChannel(withInfo);
|
||||||
Interface->Open(Setup.OSDwidth, Setup.ChannelInfoPos ? EpgLines : -EpgLines);
|
|
||||||
ProcessKey(FirstKey);
|
ProcessKey(FirstKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
cDisplayChannel::~cDisplayChannel()
|
cDisplayChannel::~cDisplayChannel()
|
||||||
{
|
{
|
||||||
Interface->Close();
|
delete displayChannel;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cDisplayChannel::DisplayChannel(void)
|
void cDisplayChannel::DisplayChannel(void)
|
||||||
{
|
{
|
||||||
int BufSize = Width() + 1;
|
displayChannel->SetChannel(channel, number);
|
||||||
char buffer[BufSize];
|
cStatus::MsgOsdChannel(ChannelString(channel, number));
|
||||||
*buffer = 0;
|
lastPresent = lastFollowing = NULL;
|
||||||
if (channel) {
|
|
||||||
if (channel->GroupSep())
|
|
||||||
snprintf(buffer, BufSize, "%s", channel->Name());
|
|
||||||
else
|
|
||||||
snprintf(buffer, BufSize, "%d%s %s", channel->Number(), number ? "-" : "", channel->Name());
|
|
||||||
}
|
|
||||||
else if (number)
|
|
||||||
snprintf(buffer, BufSize, "%d-", number);
|
|
||||||
else
|
|
||||||
snprintf(buffer, BufSize, "%s", tr("*** Invalid Channel ***"));
|
|
||||||
Interface->Fill(0, 0, Setup.OSDwidth, 1, clrBackground);
|
|
||||||
Interface->Write(0, 0, buffer);
|
|
||||||
const char *date = DayDateTime();
|
|
||||||
Interface->Write(-strlen(date), 0, date);
|
|
||||||
cStatus::MsgOsdChannel(buffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cDisplayChannel::DisplayInfo(void)
|
void cDisplayChannel::DisplayInfo(void)
|
||||||
{
|
{
|
||||||
if (withInfo && channel) {
|
if (withInfo && channel) {
|
||||||
const cEvent *Present = NULL, *Following = NULL;
|
|
||||||
cSchedulesLock SchedulesLock;
|
cSchedulesLock SchedulesLock;
|
||||||
const cSchedules *Schedules = cSchedules::Schedules(SchedulesLock);
|
const cSchedules *Schedules = cSchedules::Schedules(SchedulesLock);
|
||||||
if (Schedules) {
|
if (Schedules) {
|
||||||
const cSchedule *Schedule = Schedules->GetSchedule(channel->GetChannelID());
|
const cSchedule *Schedule = Schedules->GetSchedule(channel->GetChannelID());
|
||||||
if (Schedule) {
|
if (Schedule) {
|
||||||
const char *PresentTitle = NULL, *PresentSubtitle = NULL, *FollowingTitle = NULL, *FollowingSubtitle = NULL;
|
const cEvent *Present = Schedule->GetPresentEvent(true);
|
||||||
int Lines = 0;
|
const cEvent *Following = Schedule->GetFollowingEvent(true);
|
||||||
if ((Present = Schedule->GetPresentEvent(true)) != NULL) {
|
if (Present != lastPresent || Following != lastFollowing) {
|
||||||
PresentTitle = Present->Title();
|
displayChannel->SetEvents(Present, Following);
|
||||||
if (!isempty(PresentTitle))
|
cStatus::MsgOsdProgramme(Present ? Present->StartTime() : 0, Present ? Present->Title() : NULL, Present ? Present->ShortText() : NULL, Following ? Following->StartTime() : 0, Following ? Following->Title() : NULL, Following ? Following->ShortText() : NULL);
|
||||||
Lines++;
|
lastPresent = Present;
|
||||||
PresentSubtitle = Present->ShortText();
|
lastFollowing = Following;
|
||||||
if (!isempty(PresentSubtitle))
|
|
||||||
Lines++;
|
|
||||||
}
|
|
||||||
if ((Following = Schedule->GetFollowingEvent(true)) != NULL) {
|
|
||||||
FollowingTitle = Following->Title();
|
|
||||||
if (!isempty(FollowingTitle))
|
|
||||||
Lines++;
|
|
||||||
FollowingSubtitle = Following->ShortText();
|
|
||||||
if (!isempty(FollowingSubtitle))
|
|
||||||
Lines++;
|
|
||||||
}
|
|
||||||
if (Lines > lines) {
|
|
||||||
const int t = 6;
|
|
||||||
int l = 1;
|
|
||||||
Interface->Fill(0, 1, Setup.OSDwidth, Lines, clrBackground);
|
|
||||||
if (!isempty(PresentTitle)) {
|
|
||||||
Interface->Write(0, l, Present->GetTimeString(), clrYellow, clrBackground);
|
|
||||||
Interface->Write(t, l, PresentTitle, clrCyan, clrBackground);
|
|
||||||
l++;
|
|
||||||
}
|
|
||||||
if (!isempty(PresentSubtitle)) {
|
|
||||||
Interface->Write(t, l, PresentSubtitle, clrCyan, clrBackground);
|
|
||||||
l++;
|
|
||||||
}
|
|
||||||
if (!isempty(FollowingTitle)) {
|
|
||||||
Interface->Write(0, l, Following->GetTimeString(), clrYellow, clrBackground);
|
|
||||||
Interface->Write(t, l, FollowingTitle, clrCyan, clrBackground);
|
|
||||||
l++;
|
|
||||||
}
|
|
||||||
if (!isempty(FollowingSubtitle)) {
|
|
||||||
Interface->Write(t, l, FollowingSubtitle, clrCyan, clrBackground);
|
|
||||||
}
|
|
||||||
Interface->Flush();
|
|
||||||
lines = Lines;
|
|
||||||
lastTime = time_ms();
|
|
||||||
cStatus::MsgOsdProgramme(Present ? Present->StartTime() : 0, PresentTitle, PresentSubtitle, Following ? Following->StartTime() : 0, FollowingTitle, FollowingSubtitle);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2488,11 +2517,10 @@ void cDisplayChannel::DisplayInfo(void)
|
|||||||
|
|
||||||
void cDisplayChannel::Refresh(void)
|
void cDisplayChannel::Refresh(void)
|
||||||
{
|
{
|
||||||
Interface->Clear();
|
|
||||||
channel = Channels.GetByNumber(cDevice::CurrentChannel());
|
channel = Channels.GetByNumber(cDevice::CurrentChannel());
|
||||||
DisplayChannel();
|
DisplayChannel();
|
||||||
|
displayChannel->SetEvents(NULL, NULL);
|
||||||
lastTime = time_ms();
|
lastTime = time_ms();
|
||||||
lines = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
eOSState cDisplayChannel::ProcessKey(eKeys Key)
|
eOSState cDisplayChannel::ProcessKey(eKeys Key)
|
||||||
@ -2509,7 +2537,7 @@ eOSState cDisplayChannel::ProcessKey(eKeys Key)
|
|||||||
number = number * 10 + Key - k0;
|
number = number * 10 + Key - k0;
|
||||||
if (number > 0) {
|
if (number > 0) {
|
||||||
channel = Channels.GetByNumber(number);
|
channel = Channels.GetByNumber(number);
|
||||||
Interface->Clear();
|
displayChannel->SetEvents(NULL, NULL);
|
||||||
withInfo = false;
|
withInfo = false;
|
||||||
DisplayChannel();
|
DisplayChannel();
|
||||||
lastTime = time_ms();
|
lastTime = time_ms();
|
||||||
@ -2528,7 +2556,7 @@ eOSState cDisplayChannel::ProcessKey(eKeys Key)
|
|||||||
}
|
}
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
// This channel is the only one that fits the input, so let's take it right away:
|
// This channel is the only one that fits the input, so let's take it right away:
|
||||||
Interface->Flush(); // makes sure the user sees his last input
|
displayChannel->Flush(); // makes sure the user sees his last input
|
||||||
Channels.SwitchTo(number);
|
Channels.SwitchTo(number);
|
||||||
return osEnd;
|
return osEnd;
|
||||||
}
|
}
|
||||||
@ -2555,7 +2583,7 @@ eOSState cDisplayChannel::ProcessKey(eKeys Key)
|
|||||||
group = SaveGroup;
|
group = SaveGroup;
|
||||||
channel = Channels.Get(group);
|
channel = Channels.Get(group);
|
||||||
if (channel) {
|
if (channel) {
|
||||||
Interface->Clear();
|
displayChannel->SetEvents(NULL, NULL);
|
||||||
DisplayChannel();
|
DisplayChannel();
|
||||||
if (!channel->GroupSep())
|
if (!channel->GroupSep())
|
||||||
group = -1;
|
group = -1;
|
||||||
@ -2604,85 +2632,50 @@ eOSState cDisplayChannel::ProcessKey(eKeys Key)
|
|||||||
};
|
};
|
||||||
if (time_ms() - lastTime < INFOTIMEOUT) {
|
if (time_ms() - lastTime < INFOTIMEOUT) {
|
||||||
DisplayInfo();
|
DisplayInfo();
|
||||||
|
displayChannel->Flush();
|
||||||
return osContinue;
|
return osContinue;
|
||||||
}
|
}
|
||||||
return osEnd;
|
return osEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- cVolumeBar ------------------------------------------------------------
|
|
||||||
|
|
||||||
class cVolumeBar : public cBitmap {
|
|
||||||
public:
|
|
||||||
cVolumeBar(int Width, int Height, int Current, int Total, const char *Prompt = NULL);
|
|
||||||
};
|
|
||||||
|
|
||||||
cVolumeBar::cVolumeBar(int Width, int Height, int Current, int Total, const char *Prompt)
|
|
||||||
:cBitmap(Width, Height, 2)
|
|
||||||
{
|
|
||||||
int l = Prompt ? cBitmap::Width(Prompt) : 0;
|
|
||||||
int p = (Width - l) * Current / Total;
|
|
||||||
Text(0, 0, Prompt, clrGreen);
|
|
||||||
Fill(l, 0, p, Height - 1, clrGreen);
|
|
||||||
Fill(l + p, 0, Width - 1, Height - 1, clrWhite);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- cDisplayVolume --------------------------------------------------------
|
// --- cDisplayVolume --------------------------------------------------------
|
||||||
|
|
||||||
#define VOLUMETIMEOUT 1000 //ms
|
#define VOLUMETIMEOUT 1000 //ms
|
||||||
#define MUTETIMEOUT 5000 //ms
|
#define MUTETIMEOUT 5000 //ms
|
||||||
|
|
||||||
cDisplayVolume *cDisplayVolume::displayVolume = NULL;
|
cDisplayVolume *cDisplayVolume::currentDisplayVolume = NULL;
|
||||||
|
|
||||||
cDisplayVolume::cDisplayVolume(void)
|
cDisplayVolume::cDisplayVolume(void)
|
||||||
:cOsdObject(true)
|
:cOsdObject(true)
|
||||||
{
|
{
|
||||||
displayVolume = this;
|
currentDisplayVolume = this;
|
||||||
timeout = time_ms() + (cDevice::PrimaryDevice()->IsMute() ? MUTETIMEOUT : VOLUMETIMEOUT);
|
timeout = time_ms() + (cDevice::PrimaryDevice()->IsMute() ? MUTETIMEOUT : VOLUMETIMEOUT);
|
||||||
Interface->Open(Setup.OSDwidth, -1);
|
displayVolume = Skins.Current()->DisplayVolume();
|
||||||
Show();
|
Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
cDisplayVolume::~cDisplayVolume()
|
cDisplayVolume::~cDisplayVolume()
|
||||||
{
|
{
|
||||||
Interface->Close();
|
delete displayVolume;
|
||||||
displayVolume = NULL;
|
currentDisplayVolume = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cDisplayVolume::Show(void)
|
void cDisplayVolume::Show(void)
|
||||||
{
|
{
|
||||||
cDevice *device = cDevice::PrimaryDevice();
|
displayVolume->SetVolume(cDevice::CurrentVolume(), MAXVOLUME, cDevice::PrimaryDevice()->IsMute());
|
||||||
if (device->IsMute()) {
|
|
||||||
Interface->Fill(0, 0, Width(), 1, clrTransparent);
|
|
||||||
Interface->Write(0, 0, tr("Mute"), clrGreen);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
int Current = cDevice::CurrentVolume();
|
|
||||||
int Total = MAXVOLUME;
|
|
||||||
const char *Prompt = tr("Volume ");
|
|
||||||
#ifdef DEBUG_OSD
|
|
||||||
int l = strlen(Prompt);
|
|
||||||
int p = int(double(Width() - l) * Current / Total + 0.5);
|
|
||||||
Interface->Write(0, 0, Prompt, clrGreen);
|
|
||||||
Interface->Fill(l, 0, p, 1, clrGreen);
|
|
||||||
Interface->Fill(l + p, 0, Width() - l - p, 1, clrWhite);
|
|
||||||
#else
|
|
||||||
cVolumeBar VolumeBar(Width() * cOsd::CellWidth(), cOsd::LineHeight(), Current, Total, Prompt);
|
|
||||||
Interface->SetBitmap(0, 0, VolumeBar);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cDisplayVolume *cDisplayVolume::Create(void)
|
cDisplayVolume *cDisplayVolume::Create(void)
|
||||||
{
|
{
|
||||||
if (!displayVolume)
|
if (!currentDisplayVolume)
|
||||||
new cDisplayVolume;
|
new cDisplayVolume;
|
||||||
return displayVolume;
|
return currentDisplayVolume;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cDisplayVolume::Process(eKeys Key)
|
void cDisplayVolume::Process(eKeys Key)
|
||||||
{
|
{
|
||||||
if (displayVolume)
|
if (currentDisplayVolume)
|
||||||
displayVolume->ProcessKey(Key);
|
currentDisplayVolume->ProcessKey(Key);
|
||||||
}
|
}
|
||||||
|
|
||||||
eOSState cDisplayVolume::ProcessKey(eKeys Key)
|
eOSState cDisplayVolume::ProcessKey(eKeys Key)
|
||||||
@ -2920,9 +2913,7 @@ bool cRecordControls::StopPrimary(bool DoIt)
|
|||||||
|
|
||||||
bool cRecordControls::PauseLiveVideo(void)
|
bool cRecordControls::PauseLiveVideo(void)
|
||||||
{
|
{
|
||||||
Interface->Open(Setup.OSDwidth, -1);
|
Skins.Message(mtStatus, tr("Pausing live video..."));
|
||||||
Interface->Status(tr("Pausing live video..."));
|
|
||||||
Interface->Flush();
|
|
||||||
cReplayControl::SetRecording(NULL, NULL); // make sure the new cRecordControl will set cReplayControl::LastReplayed()
|
cReplayControl::SetRecording(NULL, NULL); // make sure the new cRecordControl will set cReplayControl::LastReplayed()
|
||||||
if (Start(NULL, true)) {
|
if (Start(NULL, true)) {
|
||||||
sleep(2); // allow recorded file to fill up enough to start replaying
|
sleep(2); // allow recorded file to fill up enough to start replaying
|
||||||
@ -2930,11 +2921,11 @@ bool cRecordControls::PauseLiveVideo(void)
|
|||||||
cControl::Launch(rc);
|
cControl::Launch(rc);
|
||||||
cControl::Attach();
|
cControl::Attach();
|
||||||
sleep(1); // allow device to replay some frames, so we have a picture
|
sleep(1); // allow device to replay some frames, so we have a picture
|
||||||
Interface->Close();
|
Skins.Message(mtStatus, NULL);
|
||||||
rc->ProcessKey(kPause); // pause, allowing replay mode display
|
rc->ProcessKey(kPause); // pause, allowing replay mode display
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
Interface->Close();
|
Skins.Message(mtStatus, NULL);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3001,50 +2992,6 @@ void cRecordControls::Shutdown(void)
|
|||||||
DELETENULL(RecordControls[i]);
|
DELETENULL(RecordControls[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- cProgressBar ----------------------------------------------------------
|
|
||||||
|
|
||||||
class cProgressBar : public cBitmap {
|
|
||||||
protected:
|
|
||||||
int total;
|
|
||||||
int Pos(int p) { return p * width / total; }
|
|
||||||
void Mark(int x, bool Start, bool Current);
|
|
||||||
public:
|
|
||||||
cProgressBar(int Width, int Height, int Current, int Total, const cMarks &Marks);
|
|
||||||
};
|
|
||||||
|
|
||||||
cProgressBar::cProgressBar(int Width, int Height, int Current, int Total, const cMarks &Marks)
|
|
||||||
:cBitmap(Width, Height, 2)
|
|
||||||
{
|
|
||||||
total = Total;
|
|
||||||
if (total > 0) {
|
|
||||||
int p = Pos(Current);
|
|
||||||
Fill(0, 0, p, Height - 1, clrGreen);
|
|
||||||
Fill(p + 1, 0, Width - 1, Height - 1, clrWhite);
|
|
||||||
bool Start = true;
|
|
||||||
for (const cMark *m = Marks.First(); m; m = Marks.Next(m)) {
|
|
||||||
int p1 = Pos(m->position);
|
|
||||||
if (Start) {
|
|
||||||
const cMark *m2 = Marks.Next(m);
|
|
||||||
int p2 = Pos(m2 ? m2->position : total);
|
|
||||||
int h = Height / 3;
|
|
||||||
Fill(p1, h, p2, Height - h, clrRed);
|
|
||||||
}
|
|
||||||
Mark(p1, Start, m->position == Current);
|
|
||||||
Start = !Start;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void cProgressBar::Mark(int x, bool Start, bool Current)
|
|
||||||
{
|
|
||||||
Fill(x, 0, x, height - 1, clrBlack);
|
|
||||||
const int d = height / (Current ? 3 : 9);
|
|
||||||
for (int i = 0; i < d; i++) {
|
|
||||||
int h = Start ? i : height - 1 - i;
|
|
||||||
Fill(x - d + i, h, x + d - i, h, Current ? clrRed : clrBlack);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- cReplayControl --------------------------------------------------------
|
// --- cReplayControl --------------------------------------------------------
|
||||||
|
|
||||||
char *cReplayControl::fileName = NULL;
|
char *cReplayControl::fileName = NULL;
|
||||||
@ -3053,8 +3000,11 @@ char *cReplayControl::title = NULL;
|
|||||||
cReplayControl::cReplayControl(void)
|
cReplayControl::cReplayControl(void)
|
||||||
:cDvbPlayerControl(fileName)
|
:cDvbPlayerControl(fileName)
|
||||||
{
|
{
|
||||||
|
displayReplay = NULL;
|
||||||
visible = modeOnly = shown = displayFrames = false;
|
visible = modeOnly = shown = displayFrames = false;
|
||||||
lastCurrent = lastTotal = -1;
|
lastCurrent = lastTotal = -1;
|
||||||
|
lastPlay = lastForward = false;
|
||||||
|
lastSpeed = -1;
|
||||||
timeoutShow = 0;
|
timeoutShow = 0;
|
||||||
timeSearchActive = false;
|
timeSearchActive = false;
|
||||||
marks.Load(fileName);
|
marks.Load(fileName);
|
||||||
@ -3108,61 +3058,36 @@ void cReplayControl::Show(void)
|
|||||||
void cReplayControl::Hide(void)
|
void cReplayControl::Hide(void)
|
||||||
{
|
{
|
||||||
if (visible) {
|
if (visible) {
|
||||||
Interface->Close();
|
delete displayReplay;
|
||||||
|
displayReplay = NULL;
|
||||||
needsFastResponse = visible = false;
|
needsFastResponse = visible = false;
|
||||||
modeOnly = false;
|
modeOnly = false;
|
||||||
|
lastPlay = lastForward = false;
|
||||||
|
lastSpeed = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cReplayControl::DisplayAtBottom(const char *s)
|
|
||||||
{
|
|
||||||
if (s) {
|
|
||||||
int w = cOsd::WidthInCells(s);
|
|
||||||
int d = max(Width() - w, 0) / 2;
|
|
||||||
if (modeOnly) //XXX remove when displaying replay mode differently
|
|
||||||
Interface->Fill(0, -1, Interface->Width(), 1, clrTransparent); //XXX remove when displaying replay mode differently
|
|
||||||
Interface->Write(d, -1, s);
|
|
||||||
Interface->Flush();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Interface->Fill(12, 2, Width() - 22, 1, clrBackground);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cReplayControl::ShowMode(void)
|
void cReplayControl::ShowMode(void)
|
||||||
{
|
{
|
||||||
if (Setup.ShowReplayMode && !timeSearchActive) {
|
if (visible || Setup.ShowReplayMode) {
|
||||||
bool Play, Forward;
|
bool Play, Forward;
|
||||||
int Speed;
|
int Speed;
|
||||||
if (GetReplayMode(Play, Forward, Speed)) {
|
if (GetReplayMode(Play, Forward, Speed) && (!visible || Play != lastPlay || Forward != lastForward || Speed != lastSpeed)) {
|
||||||
bool NormalPlay = (Play && Speed == -1);
|
bool NormalPlay = (Play && Speed == -1);
|
||||||
|
|
||||||
if (!visible) {
|
if (!visible) {
|
||||||
if (NormalPlay)
|
if (NormalPlay)
|
||||||
return; // no need to do indicate ">" unless there was a different mode displayed before
|
return; // no need to do indicate ">" unless there was a different mode displayed before
|
||||||
// open small display
|
|
||||||
/*XXX change when displaying replay mode differently
|
|
||||||
Interface->Open(9, -1);
|
|
||||||
Interface->Clear();
|
|
||||||
XXX*/
|
|
||||||
Interface->Open(0, -1); //XXX remove when displaying replay mode differently
|
|
||||||
visible = modeOnly = true;
|
visible = modeOnly = true;
|
||||||
|
displayReplay = Skins.Current()->DisplayReplay(modeOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (modeOnly && !timeoutShow && NormalPlay)
|
if (modeOnly && !timeoutShow && NormalPlay)
|
||||||
timeoutShow = time(NULL) + MODETIMEOUT;
|
timeoutShow = time(NULL) + MODETIMEOUT;
|
||||||
const char *Mode;
|
displayReplay->SetMode(Play, Forward, Speed);
|
||||||
if (Speed == -1) Mode = Play ? " > " : " || ";
|
lastPlay = Play;
|
||||||
else if (Play) Mode = Forward ? " X>> " : " <<X ";
|
lastForward = Forward;
|
||||||
else Mode = Forward ? " X|> " : " <|X ";
|
lastSpeed = Speed;
|
||||||
char buf[16];
|
|
||||||
strn0cpy(buf, Mode, sizeof(buf));
|
|
||||||
char *p = strchr(buf, 'X');
|
|
||||||
if (p)
|
|
||||||
*p = Speed > 0 ? '1' + Speed - 1 : ' ';
|
|
||||||
|
|
||||||
eDvbFont OldFont = Interface->SetFont(fontFix);
|
|
||||||
DisplayAtBottom(buf);
|
|
||||||
Interface->SetFont(OldFont);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3173,33 +3098,26 @@ bool cReplayControl::ShowProgress(bool Initial)
|
|||||||
|
|
||||||
if (GetIndex(Current, Total) && Total > 0) {
|
if (GetIndex(Current, Total) && Total > 0) {
|
||||||
if (!visible) {
|
if (!visible) {
|
||||||
Interface->Open(Setup.OSDwidth, -3);
|
displayReplay = Skins.Current()->DisplayReplay(modeOnly);
|
||||||
|
displayReplay->SetMarks(&marks);
|
||||||
needsFastResponse = visible = true;
|
needsFastResponse = visible = true;
|
||||||
}
|
}
|
||||||
if (Initial) {
|
if (Initial) {
|
||||||
Interface->Clear();
|
|
||||||
if (title)
|
if (title)
|
||||||
Interface->Write(0, 0, title);
|
displayReplay->SetTitle(title);
|
||||||
lastCurrent = lastTotal = -1;
|
lastCurrent = lastTotal = -1;
|
||||||
}
|
}
|
||||||
if (Total != lastTotal) {
|
if (Total != lastTotal) {
|
||||||
Interface->Write(-7, 2, IndexToHMSF(Total));
|
displayReplay->SetTotal(IndexToHMSF(Total));
|
||||||
if (!Initial)
|
if (!Initial)
|
||||||
Interface->Flush();
|
displayReplay->Flush();
|
||||||
}
|
}
|
||||||
if (Current != lastCurrent || Total != lastTotal) {
|
if (Current != lastCurrent || Total != lastTotal) {
|
||||||
#ifdef DEBUG_OSD
|
displayReplay->SetProgress(Current, Total);
|
||||||
int p = Width() * Current / Total;
|
|
||||||
Interface->Fill(0, 1, p, 1, clrGreen);
|
|
||||||
Interface->Fill(p, 1, Width() - p, 1, clrWhite);
|
|
||||||
#else
|
|
||||||
cProgressBar ProgressBar(Width() * cOsd::CellWidth(), cOsd::LineHeight(), Current, Total, marks);
|
|
||||||
Interface->SetBitmap(0, cOsd::LineHeight(), ProgressBar);
|
|
||||||
if (!Initial)
|
if (!Initial)
|
||||||
Interface->Flush();
|
displayReplay->Flush();
|
||||||
#endif
|
displayReplay->SetCurrent(IndexToHMSF(Current, displayFrames));
|
||||||
Interface->Write(0, 2, IndexToHMSF(Current, displayFrames));
|
displayReplay->Flush();
|
||||||
Interface->Flush();
|
|
||||||
lastCurrent = Current;
|
lastCurrent = Current;
|
||||||
}
|
}
|
||||||
lastTotal = Total;
|
lastTotal = Total;
|
||||||
@ -3223,7 +3141,7 @@ void cReplayControl::TimeSearchDisplay(void)
|
|||||||
char cm10 = timeSearchPos > 1 ? m10 : '-';
|
char cm10 = timeSearchPos > 1 ? m10 : '-';
|
||||||
char cm1 = timeSearchPos > 0 ? m1 : '-';
|
char cm1 = timeSearchPos > 0 ? m1 : '-';
|
||||||
sprintf(buf + len, "%c%c:%c%c", ch10, ch1, cm10, cm1);
|
sprintf(buf + len, "%c%c:%c%c", ch10, ch1, cm10, cm1);
|
||||||
DisplayAtBottom(buf);
|
displayReplay->SetJump(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cReplayControl::TimeSearchProcess(eKeys Key)
|
void cReplayControl::TimeSearchProcess(eKeys Key)
|
||||||
@ -3269,7 +3187,7 @@ void cReplayControl::TimeSearchProcess(eKeys Key)
|
|||||||
if (timeSearchHide)
|
if (timeSearchHide)
|
||||||
Hide();
|
Hide();
|
||||||
else
|
else
|
||||||
DisplayAtBottom();
|
displayReplay->SetJump(NULL);
|
||||||
ShowMode();
|
ShowMode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3354,14 +3272,14 @@ void cReplayControl::EditCut(void)
|
|||||||
Hide();
|
Hide();
|
||||||
if (!cCutter::Active()) {
|
if (!cCutter::Active()) {
|
||||||
if (!marks.Count())
|
if (!marks.Count())
|
||||||
Interface->Error(tr("No editing marks defined!"));
|
Skins.Message(mtError, tr("No editing marks defined!"));
|
||||||
else if (!cCutter::Start(fileName))
|
else if (!cCutter::Start(fileName))
|
||||||
Interface->Error(tr("Can't start editing process!"));
|
Skins.Message(mtError, tr("Can't start editing process!"));
|
||||||
else
|
else
|
||||||
Interface->Info(tr("Editing process started"));
|
Skins.Message(mtInfo, tr("Editing process started"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Interface->Error(tr("Editing process already active!"));
|
Skins.Message(mtError, tr("Editing process already active!"));
|
||||||
ShowMode();
|
ShowMode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3466,8 +3384,5 @@ eOSState cReplayControl::ProcessKey(eKeys Key)
|
|||||||
}
|
}
|
||||||
if (DoShowMode)
|
if (DoShowMode)
|
||||||
ShowMode();
|
ShowMode();
|
||||||
if (DisplayedFrames && !displayFrames)
|
|
||||||
Interface->Fill(0, 2, 11, 1, clrBackground);
|
|
||||||
return osContinue;
|
return osContinue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
16
menu.h
16
menu.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: menu.h 1.60 2004/02/15 14:11:28 kls Exp $
|
* $Id: menu.h 1.61 2004/04/30 13:45:19 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __MENU_H
|
#ifndef __MENU_H
|
||||||
@ -13,10 +13,11 @@
|
|||||||
#include "ci.h"
|
#include "ci.h"
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
#include "epg.h"
|
#include "epg.h"
|
||||||
#include "osd.h"
|
#include "osdbase.h"
|
||||||
#include "dvbplayer.h"
|
#include "dvbplayer.h"
|
||||||
#include "recorder.h"
|
#include "recorder.h"
|
||||||
#include "recording.h"
|
#include "recording.h"
|
||||||
|
#include "skins.h"
|
||||||
|
|
||||||
class cMenuMain : public cOsdMenu {
|
class cMenuMain : public cOsdMenu {
|
||||||
private:
|
private:
|
||||||
@ -32,12 +33,14 @@ public:
|
|||||||
|
|
||||||
class cDisplayChannel : public cOsdObject {
|
class cDisplayChannel : public cOsdObject {
|
||||||
private:
|
private:
|
||||||
|
cSkinDisplayChannel *displayChannel;
|
||||||
int group;
|
int group;
|
||||||
bool withInfo;
|
bool withInfo;
|
||||||
int lines;
|
|
||||||
int lastTime;
|
int lastTime;
|
||||||
int number;
|
int number;
|
||||||
cChannel *channel;
|
cChannel *channel;
|
||||||
|
const cEvent *lastPresent;
|
||||||
|
const cEvent *lastFollowing;
|
||||||
void DisplayChannel(void);
|
void DisplayChannel(void);
|
||||||
void DisplayInfo(void);
|
void DisplayInfo(void);
|
||||||
void Refresh(void);
|
void Refresh(void);
|
||||||
@ -50,8 +53,9 @@ public:
|
|||||||
|
|
||||||
class cDisplayVolume : public cOsdObject {
|
class cDisplayVolume : public cOsdObject {
|
||||||
private:
|
private:
|
||||||
|
cSkinDisplayVolume *displayVolume;
|
||||||
int timeout;
|
int timeout;
|
||||||
static cDisplayVolume *displayVolume;
|
static cDisplayVolume *currentDisplayVolume;
|
||||||
virtual void Show(void);
|
virtual void Show(void);
|
||||||
cDisplayVolume(void);
|
cDisplayVolume(void);
|
||||||
public:
|
public:
|
||||||
@ -150,9 +154,12 @@ public:
|
|||||||
|
|
||||||
class cReplayControl : public cDvbPlayerControl {
|
class cReplayControl : public cDvbPlayerControl {
|
||||||
private:
|
private:
|
||||||
|
cSkinDisplayReplay *displayReplay;
|
||||||
cMarks marks;
|
cMarks marks;
|
||||||
bool visible, modeOnly, shown, displayFrames;
|
bool visible, modeOnly, shown, displayFrames;
|
||||||
int lastCurrent, lastTotal;
|
int lastCurrent, lastTotal;
|
||||||
|
bool lastPlay, lastForward;
|
||||||
|
int lastSpeed;
|
||||||
time_t timeoutShow;
|
time_t timeoutShow;
|
||||||
bool timeSearchActive, timeSearchHide;
|
bool timeSearchActive, timeSearchHide;
|
||||||
int timeSearchTime, timeSearchPos;
|
int timeSearchTime, timeSearchPos;
|
||||||
@ -162,7 +169,6 @@ private:
|
|||||||
void ShowTimed(int Seconds = 0);
|
void ShowTimed(int Seconds = 0);
|
||||||
static char *fileName;
|
static char *fileName;
|
||||||
static char *title;
|
static char *title;
|
||||||
void DisplayAtBottom(const char *s = NULL);
|
|
||||||
void ShowMode(void);
|
void ShowMode(void);
|
||||||
bool ShowProgress(bool Initial);
|
bool ShowProgress(bool Initial);
|
||||||
void MarkToggle(void);
|
void MarkToggle(void);
|
||||||
|
115
menuitems.c
115
menuitems.c
@ -4,13 +4,15 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: menuitems.c 1.16 2004/03/28 09:17:51 kls Exp $
|
* $Id: menuitems.c 1.17 2004/05/02 10:37:34 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "menuitems.h"
|
#include "menuitems.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
#include "plugin.h"
|
#include "plugin.h"
|
||||||
|
#include "remote.h"
|
||||||
|
#include "skins.h"
|
||||||
#include "status.h"
|
#include "status.h"
|
||||||
|
|
||||||
const char *FileNameChars = " abcdefghijklmnopqrstuvwxyz0123456789-.#~";
|
const char *FileNameChars = " abcdefghijklmnopqrstuvwxyz0123456789-.#~";
|
||||||
@ -36,7 +38,6 @@ void cMenuEditItem::SetValue(const char *Value)
|
|||||||
char *buffer = NULL;
|
char *buffer = NULL;
|
||||||
asprintf(&buffer, "%s:\t%s", name, value);
|
asprintf(&buffer, "%s:\t%s", name, value);
|
||||||
SetText(buffer, false);
|
SetText(buffer, false);
|
||||||
Display();
|
|
||||||
cStatus::MsgOsdCurrentItem(buffer);
|
cStatus::MsgOsdCurrentItem(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,9 +254,9 @@ cMenuEditStrItem::~cMenuEditStrItem()
|
|||||||
void cMenuEditStrItem::SetHelpKeys(void)
|
void cMenuEditStrItem::SetHelpKeys(void)
|
||||||
{
|
{
|
||||||
if (pos >= 0)
|
if (pos >= 0)
|
||||||
Interface->Help(tr("ABC/abc"), tr(insert ? "Overwrite" : "Insert"), tr("Delete"));
|
cSkinDisplay::Current()->SetButtons(tr("ABC/abc"), tr(insert ? "Overwrite" : "Insert"), tr("Delete"));
|
||||||
else
|
else
|
||||||
Interface->Help(NULL);
|
cSkinDisplay::Current()->SetButtons(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cMenuEditStrItem::Set(void)
|
void cMenuEditStrItem::Set(void)
|
||||||
@ -264,21 +265,21 @@ void cMenuEditStrItem::Set(void)
|
|||||||
const char *fmt = insert && newchar ? "[]%c%s" : "[%c]%s";
|
const char *fmt = insert && newchar ? "[]%c%s" : "[%c]%s";
|
||||||
|
|
||||||
if (pos >= 0) {
|
if (pos >= 0) {
|
||||||
|
const cFont *font = cFont::GetFont(fontOsd);
|
||||||
strncpy(buf, value, pos);
|
strncpy(buf, value, pos);
|
||||||
snprintf(buf + pos, sizeof(buf) - pos - 2, fmt, *(value + pos), value + pos + 1);
|
snprintf(buf + pos, sizeof(buf) - pos - 2, fmt, *(value + pos), value + pos + 1);
|
||||||
int width = Interface->Width() - Interface->GetCols()[0];
|
int width = cSkinDisplay::Current()->EditableWidth();
|
||||||
if (cOsd::WidthInCells(buf) <= width) {
|
if (font->Width(buf) <= width) {
|
||||||
// the whole buffer fits on the screen
|
// the whole buffer fits on the screen
|
||||||
SetValue(buf);
|
SetValue(buf);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
width *= cOsd::CellWidth();
|
width -= font->Width('>'); // assuming '<' and '>' have the same with
|
||||||
width -= cOsd::Width('>'); // assuming '<' and '>' have the same with
|
|
||||||
int w = 0;
|
int w = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int l = strlen(buf);
|
int l = strlen(buf);
|
||||||
while (i < l && w <= width)
|
while (i < l && w <= width)
|
||||||
w += cOsd::Width(buf[i++]);
|
w += font->Width(buf[i++]);
|
||||||
if (i >= pos + 4) {
|
if (i >= pos + 4) {
|
||||||
// the cursor fits on the screen
|
// the cursor fits on the screen
|
||||||
buf[i - 1] = '>';
|
buf[i - 1] = '>';
|
||||||
@ -295,7 +296,7 @@ void cMenuEditStrItem::Set(void)
|
|||||||
else
|
else
|
||||||
i--;
|
i--;
|
||||||
while (i >= 0 && w <= width)
|
while (i >= 0 && w <= width)
|
||||||
w += cOsd::Width(buf[i--]);
|
w += font->Width(buf[i--]);
|
||||||
buf[++i] = '<';
|
buf[++i] = '<';
|
||||||
SetValue(buf + i);
|
SetValue(buf + i);
|
||||||
}
|
}
|
||||||
@ -461,100 +462,6 @@ void cMenuEditStraItem::Set(void)
|
|||||||
SetValue(strings[*value]);
|
SetValue(strings[*value]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- cMenuTextItem ---------------------------------------------------------
|
|
||||||
|
|
||||||
cMenuTextItem::cMenuTextItem(const char *Text, int X, int Y, int W, int H, eDvbColor FgColor, eDvbColor BgColor, eDvbFont Font)
|
|
||||||
{
|
|
||||||
x = X;
|
|
||||||
y = Y;
|
|
||||||
w = W;
|
|
||||||
h = H;
|
|
||||||
fgColor = FgColor;
|
|
||||||
bgColor = BgColor;
|
|
||||||
font = Font;
|
|
||||||
offset = 0;
|
|
||||||
eDvbFont oldFont = Interface->SetFont(font);
|
|
||||||
text = Interface->WrapText(Text, w - 1, &lines);
|
|
||||||
Interface->SetFont(oldFont);
|
|
||||||
if (h < 0)
|
|
||||||
h = lines;
|
|
||||||
}
|
|
||||||
|
|
||||||
cMenuTextItem::~cMenuTextItem()
|
|
||||||
{
|
|
||||||
free(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cMenuTextItem::Clear(void)
|
|
||||||
{
|
|
||||||
Interface->Fill(x, y, w, h, bgColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cMenuTextItem::Display(int Offset, eDvbColor FgColor, eDvbColor BgColor)
|
|
||||||
{
|
|
||||||
int l = 0;
|
|
||||||
char *t = text;
|
|
||||||
eDvbFont oldFont = Interface->SetFont(font);
|
|
||||||
while (*t) {
|
|
||||||
char *n = strchr(t, '\n');
|
|
||||||
if (l >= offset) {
|
|
||||||
if (n)
|
|
||||||
*n = 0;
|
|
||||||
Interface->Write(x, y + l - offset, t, fgColor, bgColor);
|
|
||||||
if (n)
|
|
||||||
*n = '\n';
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!n)
|
|
||||||
break;
|
|
||||||
t = n + 1;
|
|
||||||
if (++l >= h + offset)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Interface->SetFont(oldFont);
|
|
||||||
// scroll indicators use inverted color scheme!
|
|
||||||
if (CanScrollUp()) Interface->Write(x + w - 1, y, "^", bgColor, fgColor);
|
|
||||||
if (CanScrollDown()) Interface->Write(x + w - 1, y + h - 1, "v", bgColor, fgColor);
|
|
||||||
cStatus::MsgOsdTextItem(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cMenuTextItem::ScrollUp(bool Page)
|
|
||||||
{
|
|
||||||
if (CanScrollUp()) {
|
|
||||||
Clear();
|
|
||||||
offset = max(offset - (Page ? h : 1), 0);
|
|
||||||
Display();
|
|
||||||
}
|
|
||||||
cStatus::MsgOsdTextItem(NULL, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cMenuTextItem::ScrollDown(bool Page)
|
|
||||||
{
|
|
||||||
if (CanScrollDown()) {
|
|
||||||
Clear();
|
|
||||||
offset = min(offset + (Page ? h : 1), lines - h);
|
|
||||||
Display();
|
|
||||||
}
|
|
||||||
cStatus::MsgOsdTextItem(NULL, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
eOSState cMenuTextItem::ProcessKey(eKeys Key)
|
|
||||||
{
|
|
||||||
switch (Key) {
|
|
||||||
case kLeft|k_Repeat:
|
|
||||||
case kLeft:
|
|
||||||
case kUp|k_Repeat:
|
|
||||||
case kUp: ScrollUp(NORMALKEY(Key) == kLeft); break;
|
|
||||||
case kRight|k_Repeat:
|
|
||||||
case kRight:
|
|
||||||
case kDown|k_Repeat:
|
|
||||||
case kDown: ScrollDown(NORMALKEY(Key) == kRight); break;
|
|
||||||
default: return osUnknown;
|
|
||||||
}
|
|
||||||
return osContinue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- cMenuEditChanItem -----------------------------------------------------
|
// --- cMenuEditChanItem -----------------------------------------------------
|
||||||
|
|
||||||
cMenuEditChanItem::cMenuEditChanItem(const char *Name, int *Value)
|
cMenuEditChanItem::cMenuEditChanItem(const char *Name, int *Value)
|
||||||
|
23
menuitems.h
23
menuitems.h
@ -4,13 +4,13 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: menuitems.h 1.7 2004/03/28 09:16:24 kls Exp $
|
* $Id: menuitems.h 1.8 2004/04/30 13:45:28 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __MENUITEMS_H
|
#ifndef __MENUITEMS_H
|
||||||
#define __MENUITEMS_H
|
#define __MENUITEMS_H
|
||||||
|
|
||||||
#include "osd.h"
|
#include "osdbase.h"
|
||||||
|
|
||||||
extern const char *FileNameChars;
|
extern const char *FileNameChars;
|
||||||
|
|
||||||
@ -100,25 +100,6 @@ public:
|
|||||||
cMenuEditStraItem(const char *Name, int *Value, int NumStrings, const char * const *Strings);
|
cMenuEditStraItem(const char *Name, int *Value, int NumStrings, const char * const *Strings);
|
||||||
};
|
};
|
||||||
|
|
||||||
class cMenuTextItem : public cOsdItem {
|
|
||||||
private:
|
|
||||||
char *text;
|
|
||||||
int x, y, w, h, lines, offset;
|
|
||||||
eDvbColor fgColor, bgColor;
|
|
||||||
eDvbFont font;
|
|
||||||
public:
|
|
||||||
cMenuTextItem(const char *Text, int X, int Y, int W, int H = -1, eDvbColor FgColor = clrWhite, eDvbColor BgColor = clrBackground, eDvbFont Font = fontOsd);
|
|
||||||
~cMenuTextItem();
|
|
||||||
int Height(void) { return h; }
|
|
||||||
void Clear(void);
|
|
||||||
virtual void Display(int Offset = -1, eDvbColor FgColor = clrWhite, eDvbColor BgColor = clrBackground);
|
|
||||||
bool CanScrollUp(void) { return offset > 0; }
|
|
||||||
bool CanScrollDown(void) { return h + offset < lines; }
|
|
||||||
void ScrollUp(bool Page);
|
|
||||||
void ScrollDown(bool Page);
|
|
||||||
virtual eOSState ProcessKey(eKeys Key);
|
|
||||||
};
|
|
||||||
|
|
||||||
class cMenuEditChanItem : public cMenuEditIntItem {
|
class cMenuEditChanItem : public cMenuEditIntItem {
|
||||||
protected:
|
protected:
|
||||||
virtual void Set(void);
|
virtual void Set(void);
|
||||||
|
474
osd.h
474
osd.h
@ -4,169 +4,349 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: osd.h 1.40 2003/09/14 10:59:22 kls Exp $
|
* $Id: osd.h 1.41 2004/05/15 14:54:37 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __OSD_H
|
#ifndef __OSD_H
|
||||||
#define __OSD_H
|
#define __OSD_H
|
||||||
|
|
||||||
#if defined(DEBUG_OSD)
|
#include <stdio.h>
|
||||||
#include <ncurses.h>
|
#include <stdint.h>
|
||||||
#endif
|
#include "font.h"
|
||||||
#include "config.h"
|
|
||||||
#include "osdbase.h"
|
|
||||||
#include "interface.h"
|
|
||||||
#include "osdbase.h"
|
|
||||||
#include "tools.h"
|
|
||||||
|
|
||||||
#define MAXOSDITEMS (Setup.OSDheight - 4)
|
#define MAXNUMCOLORS 256
|
||||||
|
|
||||||
enum eOSState { osUnknown,
|
enum {
|
||||||
osContinue,
|
//AARRGGBB
|
||||||
osSchedule,
|
clrTransparent = 0x00000000,
|
||||||
osChannels,
|
clrGray50 = 0x7F000000, // 50% gray
|
||||||
osTimers,
|
clrBlack = 0xFF000000,
|
||||||
osRecordings,
|
clrRed = 0xFFFC1414,
|
||||||
osPlugin,
|
clrGreen = 0xFF24FC24,
|
||||||
osSetup,
|
clrYellow = 0xFFFCC024,
|
||||||
osCommands,
|
clrMagenta = 0xFFB000FC,
|
||||||
osPause,
|
clrBlue = 0xFF0000FC,
|
||||||
osRecord,
|
clrCyan = 0xFF00FCFC,
|
||||||
osReplay,
|
clrWhite = 0xFFFCFCFC,
|
||||||
osStopRecord,
|
};
|
||||||
osStopReplay,
|
|
||||||
osCancelEdit,
|
enum eOsdError { oeOk,
|
||||||
osSwitchDvb,
|
oeTooManyAreas,
|
||||||
osBack,
|
oeTooManyColors,
|
||||||
osEnd,
|
oeBppNotSupported,
|
||||||
os_User, // the following values can be used locally
|
oeAreasOverlap,
|
||||||
osUser1,
|
oeWrongAlignment,
|
||||||
osUser2,
|
oeOutOfMemory,
|
||||||
osUser3,
|
oeUnknown,
|
||||||
osUser4,
|
};
|
||||||
osUser5,
|
|
||||||
osUser6,
|
typedef uint32_t tColor;
|
||||||
osUser7,
|
typedef uint8_t tIndex;
|
||||||
osUser8,
|
|
||||||
osUser9,
|
class cPalette {
|
||||||
osUser10,
|
private:
|
||||||
};
|
tColor color[MAXNUMCOLORS];
|
||||||
|
int bpp;
|
||||||
|
int maxColors, numColors;
|
||||||
|
bool modified;
|
||||||
|
protected:
|
||||||
|
typedef tIndex tIndexes[MAXNUMCOLORS];
|
||||||
|
public:
|
||||||
|
cPalette(int Bpp = 8);
|
||||||
|
///< Initializes the palette with the given color depth.
|
||||||
|
int Bpp(void) { return bpp; }
|
||||||
|
void Reset(void);
|
||||||
|
///< Resets the palette, making it contain no colors.
|
||||||
|
int Index(tColor Color);
|
||||||
|
///< Returns the index of the given Color (the first color has index 0).
|
||||||
|
///< If Color is not yet contained in this palette, it will be added if
|
||||||
|
///< there is a free slot. If the color can't be added to this palette,
|
||||||
|
///< 0 will be returned.
|
||||||
|
tColor Color(int Index) { return Index < maxColors ? color[Index] : 0; }
|
||||||
|
///< Returns the color at the given Index. If Index is outside the valid
|
||||||
|
///< range, 0 will be returned.
|
||||||
|
void SetBpp(int Bpp);
|
||||||
|
///< Sets the color depth of this palette to the given value.
|
||||||
|
///< The palette contents will be reset, so that it contains no colors.
|
||||||
|
void SetColor(int Index, tColor Color);
|
||||||
|
///< Sets the palette entry at Index to Color. If Index is larger than
|
||||||
|
///< the number of currently used entries in this palette, the entries
|
||||||
|
///< in between will have undefined values.
|
||||||
|
const tColor *Colors(int &NumColors);
|
||||||
|
///< Returns a pointer to the complete color table and stores the
|
||||||
|
///< number of valid entries in NumColors. If no colors have been
|
||||||
|
///< stored yet, NumColors will be set to 0 and the function will
|
||||||
|
///< return NULL.
|
||||||
|
void Take(const cPalette &Palette, tIndexes *Indexes = NULL, tColor ColorFg = 0, tColor ColorBg = 0);
|
||||||
|
///< Takes the colors from the given Palette and adds them to this palette,
|
||||||
|
///< using existing entries if possible. If Indexes is given, it will be
|
||||||
|
///< filled with the index values that each color of Palette has in this
|
||||||
|
///< palette. If either of ColorFg or ColorBg is not zero, the first color
|
||||||
|
///< in Palette will be taken as ColorBg, and the second color will become
|
||||||
|
///< ColorFg.
|
||||||
|
};
|
||||||
|
|
||||||
|
enum eTextAlignment { taCenter = 0x00,
|
||||||
|
taLeft = 0x01,
|
||||||
|
taRight = 0x02,
|
||||||
|
taTop = 0x04,
|
||||||
|
taBottom = 0x08,
|
||||||
|
taDefault = taTop | taLeft
|
||||||
|
};
|
||||||
|
|
||||||
|
class cBitmap : public cPalette {
|
||||||
|
private:
|
||||||
|
tIndex *bitmap;
|
||||||
|
int x0, y0;
|
||||||
|
int width, height;
|
||||||
|
int dirtyX1, dirtyY1, dirtyX2, dirtyY2;
|
||||||
|
public:
|
||||||
|
cBitmap(int Width, int Height, int Bpp, int X0 = 0, int Y0 = 0);
|
||||||
|
///< Creates a bitmap with the given Width, Height and color depth (Bpp).
|
||||||
|
///< X0 and Y0 define the offset at which this bitmap will be located on the OSD.
|
||||||
|
///< All coordinates given in the other functions will be relative to
|
||||||
|
///< this offset (unless specified otherwise).
|
||||||
|
cBitmap(const char *FileName);
|
||||||
|
///< Creates a bitmap and loads an XPM image from the given file.
|
||||||
|
cBitmap(char *Xpm[]);
|
||||||
|
///< Creates a bitmap from the given XPM data.
|
||||||
|
virtual ~cBitmap();
|
||||||
|
int X0(void) const { return x0; }
|
||||||
|
int Y0(void) const { return y0; }
|
||||||
|
int Width(void) const { return width; }
|
||||||
|
int Height(void) const { return height; }
|
||||||
|
void SetSize(int Width, int Height);
|
||||||
|
///< Sets the size of this bitmap to the given values. Any previous
|
||||||
|
///< contents of the bitmap will be lost. If Width and Height are the same
|
||||||
|
///< as the current values, nothing will happen and the bitmap remains
|
||||||
|
///< unchanged.
|
||||||
|
bool Contains(int x, int y) const;
|
||||||
|
///< Returns true if this bitmap contains the point (x, y).
|
||||||
|
bool Intersects(int x1, int y1, int x2, int y2) const;
|
||||||
|
///< Returns true if this bitmap intersects with the rectangle
|
||||||
|
///< defined by the given coordinates.
|
||||||
|
bool Dirty(int &x1, int &y1, int &x2, int &y2);
|
||||||
|
///< Tells whether there is a dirty area and returns the bounding
|
||||||
|
///< rectangle of that area (relative to the bitmaps origin).
|
||||||
|
void Clean(void);
|
||||||
|
///< Marks the dirty area as clean.
|
||||||
|
bool LoadXpm(const char *FileName);
|
||||||
|
///< Calls SetXpm() with the data from the file FileName.
|
||||||
|
///< Returns true if the operation was successful.
|
||||||
|
bool SetXpm(char *Xpm[]);
|
||||||
|
///< Sets this bitmap to the given XPM data. Any previous bitmap or
|
||||||
|
///< palette data will be overwritten with the new data.
|
||||||
|
///< Returns true if the operation was successful.
|
||||||
|
void SetIndex(int x, int y, tIndex Index);
|
||||||
|
///< Sets the index at the given coordinates to Index.
|
||||||
|
///< Coordinates are relative to the bitmap's origin.
|
||||||
|
void DrawPixel(int x, int y, tColor Color);
|
||||||
|
///< Sets the pixel at the given coordinates to the given Color, which is
|
||||||
|
///< a full 32 bit ARGB value.
|
||||||
|
///< If the coordinates are outside the bitmap area, no pixel will be set.
|
||||||
|
void DrawBitmap(int x, int y, const cBitmap &Bitmap, tColor ColorFg = 0, tColor ColorBg = 0);
|
||||||
|
///< Sets the pixels in this bitmap with the data from the given
|
||||||
|
///< Bitmap, putting the upper left corner of the Bitmap at (x, y).
|
||||||
|
///< If ColorFg or ColorBg is given, the first palette entry of the Bitmap
|
||||||
|
///< will be mapped to ColorBg and the second palette entry will be mapped to
|
||||||
|
///< ColorFg (palette indexes are defined so that 0 is the background and
|
||||||
|
///< 1 is the foreground color).
|
||||||
|
void DrawText(int x, int y, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font, int Width = 0, int Height = 0, int Alignment = taDefault);
|
||||||
|
///< Draws the given string at coordinates (x, y) with the given foreground
|
||||||
|
///< and background color and font. If Width and Height are given, the text
|
||||||
|
///< will be drawn into a rectangle with the given size and the given
|
||||||
|
///< Alignment (default is top-left).
|
||||||
|
void DrawRectangle(int x1, int y1, int x2, int y2, tColor Color);
|
||||||
|
///< Draws a filled rectangle defined by the upper left (x1, y1) and lower right
|
||||||
|
///< (x2, y2) corners with the given Color. If the rectangle covers the entire
|
||||||
|
///< bitmap area, the color palette will be reset, so that new colors can be
|
||||||
|
///< used for drawing.
|
||||||
|
void DrawEllipse(int x1, int y1, int x2, int y2, tColor Color, int Quadrants = 0);
|
||||||
|
///< Draws a filled ellipse defined by the upper left (x1, y1) and lower right
|
||||||
|
///< (x2, y2) corners with the given Color. Quadrants controls which parts of
|
||||||
|
///< the ellipse are actually drawn:
|
||||||
|
///< 0 draws the entire ellipse
|
||||||
|
///< 1..4 draws only the first, second, third or fourth quadrant, respectively
|
||||||
|
///< 5..8 draws the right, top, left or bottom half, respectively
|
||||||
|
///< -1..-8 draws the inverted part of the given quadrant(s)
|
||||||
|
///< If Quadrants is not 0, the coordinates are those of the actual area, not
|
||||||
|
///< the full circle!
|
||||||
|
void DrawSlope(int x1, int y1, int x2, int y2, tColor Color, int Type);
|
||||||
|
///< Draws a "slope" into the rectangle defined by the upper left (x1, y1) and
|
||||||
|
///< lower right (x2, y2) corners with the given Color. Type controls the
|
||||||
|
///< direction of the slope and which side of it will be drawn:
|
||||||
|
///< 0: horizontal, rising, lower
|
||||||
|
///< 1: horizontal, rising, upper
|
||||||
|
///< 2: horizontal, falling, lower
|
||||||
|
///< 3: horizontal, falling, upper
|
||||||
|
///< 4: vertical, rising, lower
|
||||||
|
///< 5: vertical, rising, upper
|
||||||
|
///< 6: vertical, falling, lower
|
||||||
|
///< 7: vertical, falling, upper
|
||||||
|
const tIndex *Data(int x, int y);
|
||||||
|
///< Returns the address of the index byte at the given coordinates.
|
||||||
|
};
|
||||||
|
|
||||||
|
struct tArea {
|
||||||
|
int x1, y1, x2, y2;
|
||||||
|
int bpp;
|
||||||
|
int Width(void) const { return x2 - x1 + 1; }
|
||||||
|
int Height(void) const { return y2 - y1 + 1; }
|
||||||
|
bool Intersects(const tArea &Area) const { return !(x2 < Area.x1 || x1 > Area.x2 || y2 < Area.y1 || y1 > Area.y2); }
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MAXOSDAREAS 16
|
||||||
|
|
||||||
class cOsd {
|
class cOsd {
|
||||||
private:
|
private:
|
||||||
enum { charWidth = 12, // average character width
|
static bool isOpen;
|
||||||
lineHeight = 27 // smallest text height
|
cBitmap *savedRegion;
|
||||||
};
|
cBitmap *bitmaps[MAXOSDAREAS];
|
||||||
#ifdef DEBUG_OSD
|
int numBitmaps;
|
||||||
static WINDOW *window;
|
int left, top, width, height;
|
||||||
enum { MaxColorPairs = 16 };
|
|
||||||
static int colorPairs[MaxColorPairs];
|
|
||||||
static void SetColor(eDvbColor colorFg, eDvbColor colorBg = clrBackground);
|
|
||||||
#else
|
|
||||||
static cOsdBase *osd;
|
|
||||||
#endif
|
|
||||||
static int cols, rows;
|
|
||||||
public:
|
public:
|
||||||
static void Initialize(void);
|
cOsd(int Left, int Top);
|
||||||
|
///< Initializes the OSD with the given coordinates.
|
||||||
|
///< By default it is assumed that the full area will be able to display
|
||||||
|
///< full 32 bit graphics (ARGB with eight bit for each color and the alpha
|
||||||
|
///< value, repectively). However, the actual hardware in use may not be
|
||||||
|
///< able to display such a high resolution OSD, so there is an option to
|
||||||
|
///< divide the full OSD area into several sub-areas with lower color depths
|
||||||
|
///< and individual palettes. The sub-areas need not necessarily cover the
|
||||||
|
///< entire OSD area, but only the OSD area actually covered by sub-areas
|
||||||
|
///< will be available for drawing.
|
||||||
|
///< At least one area must be defined in order to set the actual width and
|
||||||
|
///< height of the OSD. Also, the caller must first try to use an area that
|
||||||
|
///< consists of only one sub-area that covers the entire drawing space,
|
||||||
|
///< and should require only the minimum necessary color depth. This is
|
||||||
|
///< because a derived cOsd class may or may not be able to handle more
|
||||||
|
///< than one area.
|
||||||
|
virtual ~cOsd();
|
||||||
|
///< Shuts down the OSD.
|
||||||
|
static bool IsOpen(void) { return isOpen; }
|
||||||
|
int Left(void) { return left; }
|
||||||
|
int Top(void) { return top; }
|
||||||
|
int Width(void) { return width; }
|
||||||
|
int Height(void) { return height; }
|
||||||
|
cBitmap *GetBitmap(int Area);
|
||||||
|
///< Returns a pointer to the bitmap for the given Area, or NULL if no
|
||||||
|
///< such bitmap exists.
|
||||||
|
virtual eOsdError CanHandleAreas(const tArea *Areas, int NumAreas);
|
||||||
|
///< Checks whether the OSD can display the given set of sub-areas.
|
||||||
|
///< The return value indicates whether a call to SetAreas() with this
|
||||||
|
///< set of areas will succeed. CanHandleAreas() may be called with an
|
||||||
|
///< OSD that is already in use with other areas and will not interfere
|
||||||
|
///< with the current operation of the OSD.
|
||||||
|
///< A derived class must first call the base class CanHandleAreas()
|
||||||
|
///< to check the basic conditions, like not overlapping etc.
|
||||||
|
virtual eOsdError SetAreas(const tArea *Areas, int NumAreas);
|
||||||
|
///< Sets the sub-areas to the given areas.
|
||||||
|
///< The return value indicates whether the operation was successful.
|
||||||
|
///< If an error is reported, nothing will have changed and the previous
|
||||||
|
///< OSD (if any) will still be displayed as before.
|
||||||
|
///< If the OSD has been divided into several sub-areas, all areas that
|
||||||
|
///< are part of the rectangle that surrounds a given drawing operation
|
||||||
|
///< will be drawn into, with the proper offsets.
|
||||||
|
virtual void SaveRegion(int x1, int y1, int x2, int y2);
|
||||||
|
///< Saves the region defined by the given coordinates for later restoration
|
||||||
|
///< through RestoreRegion(). Only one saved region can be active at any
|
||||||
|
///< given time.
|
||||||
|
virtual void RestoreRegion(void);
|
||||||
|
///< Restores the region previously saved by a call to SaveRegion().
|
||||||
|
///< If SaveRegion() has not been called before, nothing will happen.
|
||||||
|
virtual eOsdError SetPalette(const cPalette &Palette, int Area);
|
||||||
|
///< Sets the Palette for the given Area (the first area is numbered 0).
|
||||||
|
virtual void DrawPixel(int x, int y, tColor Color);
|
||||||
|
///< Sets the pixel at the given coordinates to the given Color, which is
|
||||||
|
///< a full 32 bit ARGB value.
|
||||||
|
///< If the OSD area has been divided into separate sub-areas, and the
|
||||||
|
///< given coordinates don't fall into any of these sub-areas, no pixel will
|
||||||
|
///< be set.
|
||||||
|
virtual void DrawBitmap(int x, int y, const cBitmap &Bitmap, tColor ColorFg = 0, tColor ColorBg = 0);
|
||||||
|
///< Sets the pixels in the OSD with the data from the given
|
||||||
|
///< Bitmap, putting the upper left corner of the Bitmap at (x, y).
|
||||||
|
///< If ColorFg or ColorBg is given, the first palette entry of the Bitmap
|
||||||
|
///< will be mapped to ColorBg and the second palette entry will be mapped to
|
||||||
|
///< ColorFg (palette indexes are defined so that 0 is the background and
|
||||||
|
///< 1 is the foreground color).
|
||||||
|
virtual void DrawText(int x, int y, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font, int Width = 0, int Height = 0, int Alignment = taDefault);
|
||||||
|
///< Draws the given string at coordinates (x, y) with the given foreground
|
||||||
|
///< and background color and font. If Width and Height are given, the text
|
||||||
|
///< will be drawn into a rectangle with the given size and the given
|
||||||
|
///< Alignment (default is top-left).
|
||||||
|
virtual void DrawRectangle(int x1, int y1, int x2, int y2, tColor Color);
|
||||||
|
///< Draws a filled rectangle defined by the upper left (x1, y1) and lower right
|
||||||
|
///< (x2, y2) corners with the given Color.
|
||||||
|
virtual void DrawEllipse(int x1, int y1, int x2, int y2, tColor Color, int Quadrants = 0);
|
||||||
|
///< Draws a filled ellipse defined by the upper left (x1, y1) and lower right
|
||||||
|
///< (x2, y2) corners with the given Color. Quadrants controls which parts of
|
||||||
|
///< the ellipse are actually drawn:
|
||||||
|
///< 0 draws the entire ellipse
|
||||||
|
///< 1..4 draws only the first, second, third or fourth quadrant, respectively
|
||||||
|
///< 5..8 draws the right, top, left or bottom half, respectively
|
||||||
|
///< -1..-8 draws the inverted part of the given quadrant(s)
|
||||||
|
///< If Quadrants is not 0, the coordinates are those of the actual area, not
|
||||||
|
///< the full circle!
|
||||||
|
void DrawSlope(int x1, int y1, int x2, int y2, tColor Color, int Type);
|
||||||
|
///< Draws a "slope" into the rectangle defined by the upper left (x1, y1) and
|
||||||
|
///< lower right (x2, y2) corners with the given Color. Type controls the
|
||||||
|
///< direction of the slope and which side of it will be drawn:
|
||||||
|
///< 0: horizontal, rising, lower
|
||||||
|
///< 1: horizontal, rising, upper
|
||||||
|
///< 2: horizontal, falling, lower
|
||||||
|
///< 3: horizontal, falling, upper
|
||||||
|
///< 4: vertical, rising, lower
|
||||||
|
///< 5: vertical, rising, upper
|
||||||
|
///< 6: vertical, falling, lower
|
||||||
|
///< 7: vertical, falling, upper
|
||||||
|
virtual void Flush(void);
|
||||||
|
///< Actually commits all data to the OSD hardware.
|
||||||
|
};
|
||||||
|
|
||||||
|
class cOsdProvider {
|
||||||
|
private:
|
||||||
|
static cOsdProvider *osdProvider;
|
||||||
|
protected:
|
||||||
|
virtual cOsd *CreateOsd(int Left, int Top) = 0;
|
||||||
|
///< Returns a pointer to a newly created cOsd object, which will be located
|
||||||
|
///< at the given coordinates.
|
||||||
|
public:
|
||||||
|
cOsdProvider(void);
|
||||||
|
//XXX maybe parameter to make this one "sticky"??? (frame-buffer etc.)
|
||||||
|
virtual ~cOsdProvider();
|
||||||
|
static cOsd *NewOsd(int Left, int Top);
|
||||||
|
///< Returns a pointer to a newly created cOsd object, which will be located
|
||||||
|
///< at the given coordinates. When the cOsd object is no longer needed, the
|
||||||
|
///< caller must delete it.
|
||||||
static void Shutdown(void);
|
static void Shutdown(void);
|
||||||
static cOsdBase *OpenRaw(int x, int y);
|
///< Shuts down the OSD provider facility by deleting the current OSD provider.
|
||||||
// Returns a raw OSD without any predefined windows or colors.
|
|
||||||
// If the "normal" OSD is currently in use, NULL will be returned.
|
|
||||||
// The caller must delete this object before the "normal" OSD is used again!
|
|
||||||
static void Open(int w, int h);
|
|
||||||
static void Close(void);
|
|
||||||
static void Clear(void);
|
|
||||||
static void Fill(int x, int y, int w, int h, eDvbColor color = clrBackground);
|
|
||||||
static void SetBitmap(int x, int y, const cBitmap &Bitmap);
|
|
||||||
static void ClrEol(int x, int y, eDvbColor color = clrBackground);
|
|
||||||
static int CellWidth(void);
|
|
||||||
static int LineHeight(void);
|
|
||||||
static int Width(unsigned char c);
|
|
||||||
static int WidthInCells(const char *s);
|
|
||||||
static eDvbFont SetFont(eDvbFont Font);
|
|
||||||
static void Text(int x, int y, const char *s, eDvbColor colorFg = clrWhite, eDvbColor colorBg = clrBackground);
|
|
||||||
static void Flush(void);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class cOsdItem : public cListObject {
|
class cTextScroller {
|
||||||
private:
|
private:
|
||||||
char *text;
|
cOsd *osd;
|
||||||
int offset;
|
int left, top, width, height;
|
||||||
eOSState state;
|
const cFont *font;
|
||||||
protected:
|
tColor colorFg, colorBg;
|
||||||
bool fresh;
|
int offset, shown;
|
||||||
bool userColor;
|
cTextWrapper textWrapper;
|
||||||
eDvbColor fgColor, bgColor;
|
void DrawText(void);
|
||||||
public:
|
public:
|
||||||
cOsdItem(eOSState State = osUnknown);
|
cTextScroller(void);
|
||||||
cOsdItem(const char *Text, eOSState State = osUnknown);
|
cTextScroller(cOsd *Osd, int Left, int Top, int Width, int Height, const char *Text, const cFont *Font, tColor ColorFg, tColor ColorBg);
|
||||||
virtual ~cOsdItem();
|
void Set(cOsd *Osd, int Left, int Top, int Width, int Height, const char *Text, const cFont *Font, tColor ColorFg, tColor ColorBg);
|
||||||
bool HasUserColor(void) { return userColor; }
|
void Reset(void);
|
||||||
void SetText(const char *Text, bool Copy = true);
|
int Left(void) { return left; }
|
||||||
void SetColor(eDvbColor FgColor, eDvbColor BgColor = clrBackground);
|
int Top(void) { return top; }
|
||||||
const char *Text(void) { return text; }
|
int Width(void) { return width; }
|
||||||
virtual void Display(int Offset = -1, eDvbColor FgColor = clrWhite, eDvbColor BgColor = clrBackground);
|
int Height(void) { return height; }
|
||||||
virtual void Set(void) {}
|
int Total(void) { return textWrapper.Lines(); }
|
||||||
virtual eOSState ProcessKey(eKeys Key);
|
int Offset(void) { return offset; }
|
||||||
};
|
int Shown(void) { return shown; }
|
||||||
|
bool CanScroll(void) { return CanScrollUp() || CanScrollDown(); }
|
||||||
class cOsdObject {
|
bool CanScrollUp(void) { return offset > 0; }
|
||||||
friend class cOsdMenu;
|
bool CanScrollDown(void) { return offset + shown < Total(); }
|
||||||
private:
|
void Scroll(bool Up, bool Page);
|
||||||
bool isMenu;
|
|
||||||
protected:
|
|
||||||
bool needsFastResponse;
|
|
||||||
public:
|
|
||||||
cOsdObject(bool FastResponse = false) { isMenu = false; needsFastResponse = FastResponse; }
|
|
||||||
virtual ~cOsdObject() {}
|
|
||||||
int Width(void) { return Interface->Width(); }
|
|
||||||
int Height(void) { return Interface->Height(); }
|
|
||||||
bool NeedsFastResponse(void) { return needsFastResponse; }
|
|
||||||
bool IsMenu(void) { return isMenu; }
|
|
||||||
virtual void Show(void) {}
|
|
||||||
virtual eOSState ProcessKey(eKeys Key) { return osUnknown; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class cOsdMenu : public cOsdObject, public cList<cOsdItem> {
|
|
||||||
private:
|
|
||||||
char *title;
|
|
||||||
int cols[cInterface::MaxCols];
|
|
||||||
int first, current, marked;
|
|
||||||
cOsdMenu *subMenu;
|
|
||||||
const char *helpRed, *helpGreen, *helpYellow, *helpBlue;
|
|
||||||
char *status;
|
|
||||||
int digit;
|
|
||||||
bool hasHotkeys;
|
|
||||||
protected:
|
|
||||||
bool visible;
|
|
||||||
const char *hk(const char *s);
|
|
||||||
void SetHasHotkeys(void);
|
|
||||||
virtual void Clear(void);
|
|
||||||
bool SpecialItem(int idx);
|
|
||||||
void SetCurrent(cOsdItem *Item);
|
|
||||||
void RefreshCurrent(void);
|
|
||||||
void DisplayCurrent(bool Current);
|
|
||||||
void CursorUp(void);
|
|
||||||
void CursorDown(void);
|
|
||||||
void PageUp(void);
|
|
||||||
void PageDown(void);
|
|
||||||
void Mark(void);
|
|
||||||
eOSState HotKey(eKeys Key);
|
|
||||||
eOSState AddSubMenu(cOsdMenu *SubMenu);
|
|
||||||
eOSState CloseSubMenu();
|
|
||||||
bool HasSubMenu(void) { return subMenu; }
|
|
||||||
void SetStatus(const char *s);
|
|
||||||
void SetTitle(const char *Title, bool ShowDate = true);
|
|
||||||
void SetHelp(const char *Red, const char *Green = NULL, const char *Yellow = NULL, const char *Blue = NULL);
|
|
||||||
virtual void Del(int Index);
|
|
||||||
public:
|
|
||||||
cOsdMenu(const char *Title, int c0 = 0, int c1 = 0, int c2 = 0, int c3 = 0, int c4 = 0);
|
|
||||||
virtual ~cOsdMenu();
|
|
||||||
int Current(void) { return current; }
|
|
||||||
void Add(cOsdItem *Item, bool Current = false, cOsdItem *After = NULL);
|
|
||||||
void Ins(cOsdItem *Item, bool Current = false, cOsdItem *Before = NULL);
|
|
||||||
virtual void Display(void);
|
|
||||||
virtual eOSState ProcessKey(eKeys Key);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //__OSD_H
|
#endif //__OSD_H
|
||||||
|
833
osdbase.c
833
osdbase.c
@ -4,495 +4,410 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: osdbase.c 1.12 2004/01/31 10:31:13 kls Exp $
|
* $Id: osdbase.c 1.13 2004/05/01 10:51:43 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "osdbase.h"
|
#include "osdbase.h"
|
||||||
#include <signal.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include "device.h"
|
||||||
#include <sys/ioctl.h>
|
#include "i18n.h"
|
||||||
#include <sys/stat.h>
|
#include "remote.h"
|
||||||
#include <sys/unistd.h>
|
#include "status.h"
|
||||||
#include "tools.h"
|
|
||||||
|
|
||||||
// --- cPalette --------------------------------------------------------------
|
// --- cOsdItem --------------------------------------------------------------
|
||||||
|
|
||||||
cPalette::cPalette(int Bpp)
|
cOsdItem::cOsdItem(eOSState State)
|
||||||
{
|
{
|
||||||
maxColors = 1 << Bpp;
|
text = NULL;
|
||||||
numColors = 0;
|
offset = -1;
|
||||||
full = false;
|
state = State;
|
||||||
|
selectable = true;
|
||||||
|
fresh = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cPalette::SetColor(int Index, eDvbColor Color)
|
cOsdItem::cOsdItem(const char *Text, eOSState State)
|
||||||
{
|
{
|
||||||
if (Index < maxColors) {
|
text = NULL;
|
||||||
if (numColors < Index)
|
offset = -1;
|
||||||
numColors = Index + 1;
|
state = State;
|
||||||
used[Index] = true;
|
selectable = true;
|
||||||
color[Index] = Color;
|
fresh = true;
|
||||||
fetched[Index] = false;
|
SetText(Text);
|
||||||
|
}
|
||||||
|
|
||||||
|
cOsdItem::~cOsdItem()
|
||||||
|
{
|
||||||
|
free(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cOsdItem::SetText(const char *Text, bool Copy)
|
||||||
|
{
|
||||||
|
free(text);
|
||||||
|
text = Copy ? strdup(Text) : (char *)Text; // text assumes ownership!
|
||||||
|
}
|
||||||
|
|
||||||
|
void cOsdItem::SetSelectable(bool Selectable)
|
||||||
|
{
|
||||||
|
selectable = Selectable;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cOsdItem::SetFresh(bool Fresh)
|
||||||
|
{
|
||||||
|
fresh = Fresh;
|
||||||
|
}
|
||||||
|
|
||||||
|
eOSState cOsdItem::ProcessKey(eKeys Key)
|
||||||
|
{
|
||||||
|
return Key == kOk ? state : osUnknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- cOsdMenu --------------------------------------------------------------
|
||||||
|
|
||||||
|
cSkinDisplayMenu *cOsdMenu::displayMenu = NULL;
|
||||||
|
int cOsdMenu::displayMenuCount = 0;
|
||||||
|
int cOsdMenu::displayMenuItems = 0;//XXX dynamic???
|
||||||
|
|
||||||
|
cOsdMenu::cOsdMenu(const char *Title, int c0, int c1, int c2, int c3, int c4)
|
||||||
|
{
|
||||||
|
isMenu = true;
|
||||||
|
digit = 0;
|
||||||
|
hasHotkeys = false;
|
||||||
|
title = NULL;
|
||||||
|
SetTitle(Title);
|
||||||
|
cols[0] = c0;
|
||||||
|
cols[1] = c1;
|
||||||
|
cols[2] = c2;
|
||||||
|
cols[3] = c3;
|
||||||
|
cols[4] = c4;
|
||||||
|
first = 0;
|
||||||
|
current = marked = -1;
|
||||||
|
subMenu = NULL;
|
||||||
|
helpRed = helpGreen = helpYellow = helpBlue = NULL;
|
||||||
|
status = NULL;
|
||||||
|
if (!displayMenuCount++) {
|
||||||
|
displayMenu = Skins.Current()->DisplayMenu();
|
||||||
|
displayMenuItems = displayMenu->MaxItems();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int cPalette::Index(eDvbColor Color)
|
cOsdMenu::~cOsdMenu()
|
||||||
{
|
{
|
||||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
free(title);
|
||||||
Color = eDvbColor(((Color & 0xFF) << 24) | ((Color & 0xFF00) << 8) | ((Color & 0xFF0000) >> 8) | ((Color & 0xFF000000) >> 24));
|
delete subMenu;
|
||||||
#endif
|
free(status);
|
||||||
for (int i = 0; i < numColors; i++) {
|
displayMenu->Clear();
|
||||||
if (color[i] == Color) {
|
cStatus::MsgOsdClear();
|
||||||
used[i] = true;
|
if (!--displayMenuCount)
|
||||||
return i;
|
DELETENULL(displayMenu);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (!full) {
|
const char *cOsdMenu::hk(const char *s)
|
||||||
if (numColors < maxColors) {
|
{
|
||||||
color[numColors++] = Color;
|
static char buffer[64];
|
||||||
used[numColors - 1] = true;
|
if (s && hasHotkeys) {
|
||||||
fetched[numColors - 1] = false;
|
if (digit == 0 && '1' <= *s && *s <= '9' && *(s + 1) == ' ')
|
||||||
return numColors - 1;
|
digit = -1; // prevents automatic hotkeys - input already has them
|
||||||
|
if (digit >= 0) {
|
||||||
|
digit++;
|
||||||
|
snprintf(buffer, sizeof(buffer), " %c %s", (digit < 10) ? '0' + digit : ' ' , s);
|
||||||
|
s = buffer;
|
||||||
}
|
}
|
||||||
for (int i = maxColors; --i >= 0; ) {
|
}
|
||||||
if (!used[i]) {
|
return s;
|
||||||
color[i] = Color;
|
}
|
||||||
used[i] = true;
|
|
||||||
fetched[i] = false;
|
void cOsdMenu::SetHasHotkeys(void)
|
||||||
return i;
|
{
|
||||||
|
hasHotkeys = true;
|
||||||
|
digit = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cOsdMenu::SetStatus(const char *s)
|
||||||
|
{
|
||||||
|
free(status);
|
||||||
|
status = s ? strdup(s) : NULL;
|
||||||
|
displayMenu->SetMessage(mtStatus, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cOsdMenu::SetTitle(const char *Title)
|
||||||
|
{
|
||||||
|
free(title);
|
||||||
|
title = strdup(Title);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cOsdMenu::SetHelp(const char *Red, const char *Green, const char *Yellow, const char *Blue)
|
||||||
|
{
|
||||||
|
// strings are NOT copied - must be constants!!!
|
||||||
|
helpRed = Red;
|
||||||
|
helpGreen = Green;
|
||||||
|
helpYellow = Yellow;
|
||||||
|
helpBlue = Blue;
|
||||||
|
displayMenu->SetButtons(helpRed, helpGreen, helpYellow, helpBlue);
|
||||||
|
cStatus::MsgOsdHelpKeys(helpRed, helpGreen, helpYellow, helpBlue);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cOsdMenu::Del(int Index)
|
||||||
|
{
|
||||||
|
cList<cOsdItem>::Del(Get(Index));
|
||||||
|
if (current == Count())
|
||||||
|
current--;
|
||||||
|
if (Index == first && first > 0)
|
||||||
|
first--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cOsdMenu::Add(cOsdItem *Item, bool Current, cOsdItem *After)
|
||||||
|
{
|
||||||
|
cList<cOsdItem>::Add(Item, After);
|
||||||
|
if (Current)
|
||||||
|
current = Item->Index();
|
||||||
|
}
|
||||||
|
|
||||||
|
void cOsdMenu::Ins(cOsdItem *Item, bool Current, cOsdItem *Before)
|
||||||
|
{
|
||||||
|
cList<cOsdItem>::Ins(Item, Before);
|
||||||
|
if (Current)
|
||||||
|
current = Item->Index();
|
||||||
|
}
|
||||||
|
|
||||||
|
void cOsdMenu::Display(void)
|
||||||
|
{
|
||||||
|
if (subMenu) {
|
||||||
|
subMenu->Display();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
displayMenu->Clear();
|
||||||
|
cStatus::MsgOsdClear();
|
||||||
|
displayMenu->SetTabs(cols[0], cols[1], cols[2], cols[3], cols[4]);//XXX
|
||||||
|
displayMenu->SetTitle(title);
|
||||||
|
cStatus::MsgOsdTitle(title);
|
||||||
|
displayMenu->SetButtons(helpRed, helpGreen, helpYellow, helpBlue);
|
||||||
|
cStatus::MsgOsdHelpKeys(helpRed, helpGreen, helpYellow, helpBlue);
|
||||||
|
int count = Count();
|
||||||
|
if (count > 0) {
|
||||||
|
int ni = 0;
|
||||||
|
for (cOsdItem *item = First(); item; item = Next(item))
|
||||||
|
cStatus::MsgOsdItem(item->Text(), ni++);
|
||||||
|
if (current < 0)
|
||||||
|
current = 0; // just for safety - there HAS to be a current item!
|
||||||
|
if (current - first >= displayMenuItems || current < first) {
|
||||||
|
first = current - displayMenuItems / 2;
|
||||||
|
if (first + displayMenuItems > count)
|
||||||
|
first = count - displayMenuItems;
|
||||||
|
if (first < 0)
|
||||||
|
first = 0;
|
||||||
|
}
|
||||||
|
int i = first;
|
||||||
|
int n = 0;
|
||||||
|
for (cOsdItem *item = Get(first); item; item = Next(item)) {
|
||||||
|
displayMenu->SetItem(item->Text(), i - first, i == current, item->Selectable());
|
||||||
|
if (i == current)
|
||||||
|
cStatus::MsgOsdCurrentItem(item->Text());
|
||||||
|
if (++n == displayMenuItems)
|
||||||
|
break;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isempty(status))
|
||||||
|
displayMenu->SetMessage(mtStatus, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cOsdMenu::SetCurrent(cOsdItem *Item)
|
||||||
|
{
|
||||||
|
current = Item ? Item->Index() : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cOsdMenu::RefreshCurrent(void)
|
||||||
|
{
|
||||||
|
cOsdItem *item = Get(current);
|
||||||
|
if (item)
|
||||||
|
item->Set();
|
||||||
|
}
|
||||||
|
|
||||||
|
void cOsdMenu::DisplayCurrent(bool Current)
|
||||||
|
{
|
||||||
|
cOsdItem *item = Get(current);
|
||||||
|
if (item) {
|
||||||
|
displayMenu->SetItem(item->Text(), current - first, Current, item->Selectable());
|
||||||
|
if (Current)
|
||||||
|
cStatus::MsgOsdCurrentItem(item->Text());
|
||||||
|
if (!Current)
|
||||||
|
item->SetFresh(true); // leaving the current item resets 'fresh'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cOsdMenu::Clear(void)
|
||||||
|
{
|
||||||
|
first = 0;
|
||||||
|
current = marked = -1;
|
||||||
|
cList<cOsdItem>::Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cOsdMenu::SelectableItem(int idx)
|
||||||
|
{
|
||||||
|
cOsdItem *item = Get(idx);
|
||||||
|
return item && item->Selectable();
|
||||||
|
}
|
||||||
|
|
||||||
|
void cOsdMenu::CursorUp(void)
|
||||||
|
{
|
||||||
|
if (current > 0) {
|
||||||
|
int tmpCurrent = current;
|
||||||
|
while (--tmpCurrent >= 0 && !SelectableItem(tmpCurrent));
|
||||||
|
if (tmpCurrent < 0)
|
||||||
|
return;
|
||||||
|
if (tmpCurrent >= first)
|
||||||
|
DisplayCurrent(false);
|
||||||
|
current = tmpCurrent;
|
||||||
|
if (current < first) {
|
||||||
|
first = first > displayMenuItems - 1 ? first - (displayMenuItems - 1) : 0;
|
||||||
|
if (Setup.MenuScrollPage)
|
||||||
|
current = !SelectableItem(first) ? first + 1 : first;
|
||||||
|
Display();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
DisplayCurrent(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cOsdMenu::CursorDown(void)
|
||||||
|
{
|
||||||
|
int last = Count() - 1;
|
||||||
|
int lastOnScreen = first + displayMenuItems - 1;
|
||||||
|
|
||||||
|
if (current < last) {
|
||||||
|
int tmpCurrent = current;
|
||||||
|
while (++tmpCurrent <= last && !SelectableItem(tmpCurrent));
|
||||||
|
if (tmpCurrent > last)
|
||||||
|
return;
|
||||||
|
if (tmpCurrent <= lastOnScreen)
|
||||||
|
DisplayCurrent(false);
|
||||||
|
current = tmpCurrent;
|
||||||
|
if (current > lastOnScreen) {
|
||||||
|
first += displayMenuItems - 1;
|
||||||
|
lastOnScreen = first + displayMenuItems - 1;
|
||||||
|
if (lastOnScreen > last) {
|
||||||
|
first = last - (displayMenuItems - 1);
|
||||||
|
lastOnScreen = last;
|
||||||
|
}
|
||||||
|
if (Setup.MenuScrollPage)
|
||||||
|
current = !SelectableItem(lastOnScreen) ? lastOnScreen - 1 : lastOnScreen;
|
||||||
|
Display();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
DisplayCurrent(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cOsdMenu::PageUp(void)
|
||||||
|
{
|
||||||
|
current -= displayMenuItems;
|
||||||
|
first -= displayMenuItems;
|
||||||
|
if (first < 0)
|
||||||
|
first = current = 0;
|
||||||
|
if (!SelectableItem(current)) {
|
||||||
|
current -= (current > 0) ? 1 : -1;
|
||||||
|
first = min(first, current - 1);
|
||||||
|
}
|
||||||
|
Display();
|
||||||
|
DisplayCurrent(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cOsdMenu::PageDown(void)
|
||||||
|
{
|
||||||
|
current += displayMenuItems;
|
||||||
|
first += displayMenuItems;
|
||||||
|
int count = Count();
|
||||||
|
if (current > count - 1) {
|
||||||
|
current = count - 1;
|
||||||
|
first = max(0, count - displayMenuItems);
|
||||||
|
}
|
||||||
|
if (!SelectableItem(current)) {
|
||||||
|
current += (current < count - 1) ? 1 : -1;
|
||||||
|
first = max(first, current - displayMenuItems);
|
||||||
|
}
|
||||||
|
Display();
|
||||||
|
DisplayCurrent(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cOsdMenu::Mark(void)
|
||||||
|
{
|
||||||
|
if (Count() && marked < 0) {
|
||||||
|
marked = current;
|
||||||
|
SetStatus(tr("Up/Dn for new location - OK to move"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
eOSState cOsdMenu::HotKey(eKeys Key)
|
||||||
|
{
|
||||||
|
for (cOsdItem *item = First(); item; item = Next(item)) {
|
||||||
|
const char *s = item->Text();
|
||||||
|
if (s && (s = skipspace(s)) != NULL) {
|
||||||
|
if (*s == Key - k1 + '1') {
|
||||||
|
current = item->Index();
|
||||||
|
cRemote::Put(kOk, true);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
esyslog("ERROR: too many different colors used in palette");
|
|
||||||
full = true;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void cPalette::Reset(void)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < numColors; i++)
|
|
||||||
used[i] = fetched[i] = false;
|
|
||||||
full = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const eDvbColor *cPalette::NewColors(int &FirstColor, int &LastColor)
|
|
||||||
{
|
|
||||||
for (FirstColor = 0; FirstColor < numColors; FirstColor++) {
|
|
||||||
if (!fetched[FirstColor]) {
|
|
||||||
for (LastColor = FirstColor; LastColor < numColors && !fetched[LastColor]; LastColor++)
|
|
||||||
fetched[LastColor] = true;
|
|
||||||
LastColor--; // the loop ended one past the last one!
|
|
||||||
return &color[FirstColor];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return NULL;
|
return osContinue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const eDvbColor *cPalette::AllColors(int &NumColors)
|
eOSState cOsdMenu::AddSubMenu(cOsdMenu *SubMenu)
|
||||||
{
|
{
|
||||||
NumColors = numColors;
|
delete subMenu;
|
||||||
return numColors ? color : NULL;
|
subMenu = SubMenu;
|
||||||
|
subMenu->Display();
|
||||||
|
return osContinue; // convenience return value
|
||||||
}
|
}
|
||||||
|
|
||||||
void cPalette::Take(const cPalette &Palette, tIndexes *Indexes)
|
eOSState cOsdMenu::CloseSubMenu()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < Palette.numColors; i++) {
|
delete subMenu;
|
||||||
if (Palette.used[i]) {
|
subMenu = NULL;
|
||||||
int n = Index(Palette.color[i]);
|
RefreshCurrent();
|
||||||
if (Indexes)
|
Display();
|
||||||
(*Indexes)[i] = n;
|
return osContinue; // convenience return value
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- cBitmap ---------------------------------------------------------------
|
eOSState cOsdMenu::ProcessKey(eKeys Key)
|
||||||
|
|
||||||
cBitmap::cBitmap(int Width, int Height, int Bpp, bool ClearWithBackground)
|
|
||||||
:cPalette(Bpp)
|
|
||||||
{
|
{
|
||||||
width = Width;
|
if (subMenu) {
|
||||||
height = Height;
|
eOSState state = subMenu->ProcessKey(Key);
|
||||||
clearWithBackground = ClearWithBackground;
|
if (state == osBack)
|
||||||
bitmap = NULL;
|
return CloseSubMenu();
|
||||||
fontType = fontOsd;
|
return state;
|
||||||
font = NULL;
|
|
||||||
if (width > 0 && height > 0) {
|
|
||||||
bitmap = MALLOC(u_char, width * height);
|
|
||||||
if (bitmap) {
|
|
||||||
Clean();
|
|
||||||
memset(bitmap, 0x00, width * height);
|
|
||||||
SetFont(fontOsd);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
esyslog("ERROR: can't allocate bitmap!");
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
esyslog("ERROR: illegal bitmap parameters (%d, %d)!", width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
cBitmap::~cBitmap()
|
cOsdItem *item = Get(current);
|
||||||
{
|
if (marked < 0 && item) {
|
||||||
free(bitmap);
|
eOSState state = item->ProcessKey(Key);
|
||||||
}
|
if (state != osUnknown) {
|
||||||
|
DisplayCurrent(true);
|
||||||
eDvbFont cBitmap::SetFont(eDvbFont Font)
|
return state;
|
||||||
{
|
|
||||||
eDvbFont oldFont = fontType;
|
|
||||||
if (fontType != Font || !font) {
|
|
||||||
font = cFont::GetFont(Font);
|
|
||||||
fontType = Font;
|
|
||||||
}
|
|
||||||
return oldFont;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cBitmap::Dirty(int &x1, int &y1, int &x2, int &y2)
|
|
||||||
{
|
|
||||||
if (dirtyX2 >= 0) {
|
|
||||||
//XXX Workaround: apparently the bitmap sent to the driver always has to be a multiple
|
|
||||||
//XXX of 8 bits wide, and (dx * dy) also has to be a multiple of 8.
|
|
||||||
//TODO Fix driver (should be able to handle any size bitmaps!)
|
|
||||||
while ((dirtyX1 > 0 || dirtyX2 < width - 1) && ((dirtyX2 - dirtyX1) & 7) != 7) {
|
|
||||||
if (dirtyX2 < width - 1)
|
|
||||||
dirtyX2++;
|
|
||||||
else if (dirtyX1 > 0)
|
|
||||||
dirtyX1--;
|
|
||||||
}
|
|
||||||
//XXX "... / 2" <==> Bpp???
|
|
||||||
while ((dirtyY1 > 0 || dirtyY2 < height - 1) && (((dirtyX2 - dirtyX1 + 1) * (dirtyY2 - dirtyY1 + 1) / 2) & 7) != 0) {
|
|
||||||
if (dirtyY2 < height - 1)
|
|
||||||
dirtyY2++;
|
|
||||||
else if (dirtyY1 > 0)
|
|
||||||
dirtyY1--;
|
|
||||||
}
|
|
||||||
while ((dirtyX1 > 0 || dirtyX2 < width - 1) && (((dirtyX2 - dirtyX1 + 1) * (dirtyY2 - dirtyY1 + 1) / 2) & 7) != 0) {
|
|
||||||
if (dirtyX2 < width - 1)
|
|
||||||
dirtyX2++;
|
|
||||||
else if (dirtyX1 > 0)
|
|
||||||
dirtyX1--;
|
|
||||||
}
|
|
||||||
x1 = dirtyX1;
|
|
||||||
y1 = dirtyY1;
|
|
||||||
x2 = dirtyX2;
|
|
||||||
y2 = dirtyY2;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void cBitmap::Clean(void)
|
|
||||||
{
|
|
||||||
dirtyX1 = width;
|
|
||||||
dirtyY1 = height;
|
|
||||||
dirtyX2 = -1;
|
|
||||||
dirtyY2 = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void cBitmap::SetIndex(int x, int y, u_char Index)
|
|
||||||
{
|
|
||||||
if (bitmap) {
|
|
||||||
if (0 <= x && x < width && 0 <= y && y < height) {
|
|
||||||
if (bitmap[width * y + x] != Index) {
|
|
||||||
bitmap[width * y + x] = Index;
|
|
||||||
if (dirtyX1 > x) dirtyX1 = x;
|
|
||||||
if (dirtyY1 > y) dirtyY1 = y;
|
|
||||||
if (dirtyX2 < x) dirtyX2 = x;
|
|
||||||
if (dirtyY2 < y) dirtyY2 = y;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
switch (Key) {
|
||||||
|
case k1...k9: return hasHotkeys ? HotKey(Key) : osUnknown;
|
||||||
void cBitmap::SetPixel(int x, int y, eDvbColor Color)
|
case kUp|k_Repeat:
|
||||||
{
|
case kUp: CursorUp(); break;
|
||||||
SetIndex(x, y, Index(Color));
|
case kDown|k_Repeat:
|
||||||
}
|
case kDown: CursorDown(); break;
|
||||||
|
case kLeft|k_Repeat:
|
||||||
void cBitmap::SetBitmap(int x, int y, const cBitmap &Bitmap)
|
case kLeft: PageUp(); break;
|
||||||
{
|
case kRight|k_Repeat:
|
||||||
if (bitmap && Bitmap.bitmap) {
|
case kRight: PageDown(); break;
|
||||||
tIndexes Indexes;
|
case kBack: return osBack;
|
||||||
Take(Bitmap, &Indexes);
|
case kOk: if (marked >= 0) {
|
||||||
for (int ix = 0; ix < Bitmap.width; ix++) {
|
SetStatus(NULL);
|
||||||
for (int iy = 0; iy < Bitmap.height; iy++)
|
if (marked != current)
|
||||||
SetIndex(x + ix, y + iy, Indexes[int(Bitmap.bitmap[Bitmap.width * iy + ix])]);
|
Move(marked, current);
|
||||||
}
|
marked = -1;
|
||||||
}
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
int cBitmap::Width(unsigned char c)
|
|
||||||
{
|
|
||||||
return font ? font->Width(c) : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int cBitmap::Width(const char *s)
|
|
||||||
{
|
|
||||||
return font ? font->Width(s) : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void cBitmap::Text(int x, int y, const char *s, eDvbColor ColorFg, eDvbColor ColorBg)
|
|
||||||
{
|
|
||||||
if (bitmap) {
|
|
||||||
u_char fg = Index(ColorFg);
|
|
||||||
u_char bg = Index(ColorBg);
|
|
||||||
int h = font->Height(s);
|
|
||||||
while (s && *s) {
|
|
||||||
const cFont::tCharData *CharData = font->CharData(*s++);
|
|
||||||
if (int(x + CharData->width) > width)
|
|
||||||
break;
|
|
||||||
for (int row = 0; row < h; row++) {
|
|
||||||
cFont::tPixelData PixelData = CharData->lines[row];
|
|
||||||
for (int col = CharData->width; col-- > 0; ) {
|
|
||||||
SetIndex(x + col, y + row, (PixelData & 1) ? fg : bg);
|
|
||||||
PixelData >>= 1;
|
|
||||||
}
|
}
|
||||||
}
|
// else run into default
|
||||||
x += CharData->width;
|
default: if (marked < 0)
|
||||||
}
|
return osUnknown;
|
||||||
}
|
}
|
||||||
|
return osContinue;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cBitmap::Fill(int x1, int y1, int x2, int y2, eDvbColor Color)
|
|
||||||
{
|
|
||||||
if (bitmap) {
|
|
||||||
u_char c = Index(Color);
|
|
||||||
for (int y = y1; y <= y2; y++)
|
|
||||||
for (int x = x1; x <= x2; x++)
|
|
||||||
SetIndex(x, y, c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void cBitmap::Clear(void)
|
|
||||||
{
|
|
||||||
Reset();
|
|
||||||
if (clearWithBackground)
|
|
||||||
Fill(0, 0, width - 1, height - 1, clrBackground);
|
|
||||||
}
|
|
||||||
|
|
||||||
const u_char *cBitmap::Data(int x, int y)
|
|
||||||
{
|
|
||||||
return &bitmap[y * width + x];
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- cWindow ---------------------------------------------------------------
|
|
||||||
|
|
||||||
cWindow::cWindow(int Handle, int x, int y, int w, int h, int Bpp, bool ClearWithBackground, bool Tiled)
|
|
||||||
:cBitmap(w, h, Bpp, ClearWithBackground)
|
|
||||||
{
|
|
||||||
handle = Handle;
|
|
||||||
x0 = x;
|
|
||||||
y0 = y;
|
|
||||||
bpp = Bpp;
|
|
||||||
tiled = Tiled;
|
|
||||||
shown = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cWindow::Contains(int x, int y)
|
|
||||||
{
|
|
||||||
x -= x0;
|
|
||||||
y -= y0;
|
|
||||||
return x >= 0 && y >= 0 && x < width && y < height;
|
|
||||||
}
|
|
||||||
|
|
||||||
void cWindow::Relocate(int x, int y)
|
|
||||||
{
|
|
||||||
x0 = x;
|
|
||||||
y0 = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
void cWindow::Fill(int x1, int y1, int x2, int y2, eDvbColor Color)
|
|
||||||
{
|
|
||||||
if (tiled) {
|
|
||||||
x1 -= x0;
|
|
||||||
y1 -= y0;
|
|
||||||
x2 -= x0;
|
|
||||||
y2 -= y0;
|
|
||||||
}
|
|
||||||
cBitmap::Fill(x1, y1, x2, y2, Color);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cWindow::SetBitmap(int x, int y, const cBitmap &Bitmap)
|
|
||||||
{
|
|
||||||
if (tiled) {
|
|
||||||
x -= x0;
|
|
||||||
y -= y0;
|
|
||||||
}
|
|
||||||
cBitmap::SetBitmap(x, y, Bitmap);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cWindow::Text(int x, int y, const char *s, eDvbColor ColorFg, eDvbColor ColorBg)
|
|
||||||
{
|
|
||||||
if (tiled) {
|
|
||||||
x -= x0;
|
|
||||||
y -= y0;
|
|
||||||
}
|
|
||||||
cBitmap::Text(x, y, s, ColorFg, ColorBg);
|
|
||||||
}
|
|
||||||
|
|
||||||
const u_char *cWindow::Data(int x, int y)
|
|
||||||
{
|
|
||||||
return cBitmap::Data(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- cOsdBase --------------------------------------------------------------
|
|
||||||
|
|
||||||
cOsdBase::cOsdBase(int x, int y)
|
|
||||||
{
|
|
||||||
numWindows = 0;
|
|
||||||
x0 = x;
|
|
||||||
y0 = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
cOsdBase::~cOsdBase()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < numWindows; i++)
|
|
||||||
delete window[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
tWindowHandle cOsdBase::Create(int x, int y, int w, int h, int Bpp, bool ClearWithBackground, bool Tiled)
|
|
||||||
{
|
|
||||||
if (numWindows < MAXNUMWINDOWS) {
|
|
||||||
if (x >= 0 && y >= 0 && w > 0 && h > 0 && (Bpp == 1 || Bpp == 2 || Bpp == 4 || Bpp == 8)) {
|
|
||||||
if ((w & 0x03) != 0) {
|
|
||||||
w += 4 - (w & 0x03);
|
|
||||||
dsyslog("OSD window width must be a multiple of 4 - increasing to %d", w);
|
|
||||||
}
|
|
||||||
cWindow *win = new cWindow(numWindows, x, y, w, h, Bpp, ClearWithBackground, Tiled);
|
|
||||||
if (OpenWindow(win)) {
|
|
||||||
window[win->Handle()] = win;
|
|
||||||
numWindows++;
|
|
||||||
return win->Handle();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
delete win;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
esyslog("ERROR: illegal OSD parameters");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
esyslog("ERROR: too many OSD windows");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void cOsdBase::AddColor(eDvbColor Color, tWindowHandle Window)
|
|
||||||
{
|
|
||||||
cWindow *w = GetWindow(Window);
|
|
||||||
if (w) {
|
|
||||||
w->Index(Color);
|
|
||||||
w->Reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cWindow *cOsdBase::GetWindow(int x, int y)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < numWindows; i++) {
|
|
||||||
if (window[i]->Tiled() && window[i]->Contains(x, y))
|
|
||||||
return window[i];
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
cWindow *cOsdBase::GetWindow(tWindowHandle Window)
|
|
||||||
{
|
|
||||||
if (0 <= Window && Window < numWindows)
|
|
||||||
return window[Window];
|
|
||||||
if (Window == LAST_CREATED_WINDOW && numWindows > 0)
|
|
||||||
return window[numWindows - 1];
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void cOsdBase::Flush(void)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < numWindows; i++) {
|
|
||||||
CommitWindow(window[i]);
|
|
||||||
window[i]->Clean();
|
|
||||||
}
|
|
||||||
// Showing the windows in a separate loop to avoid seeing them come up one after another
|
|
||||||
for (int i = 0; i < numWindows; i++) {
|
|
||||||
if (!window[i]->Shown())
|
|
||||||
ShowWindow(window[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void cOsdBase::Clear(tWindowHandle Window)
|
|
||||||
{
|
|
||||||
if (Window == ALL_TILED_WINDOWS || Window == ALL_WINDOWS) {
|
|
||||||
for (int i = 0; i < numWindows; i++)
|
|
||||||
if (Window == ALL_WINDOWS || window[i]->Tiled())
|
|
||||||
window[i]->Clear();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
cWindow *w = GetWindow(Window);
|
|
||||||
if (w)
|
|
||||||
w->Clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void cOsdBase::Fill(int x1, int y1, int x2, int y2, eDvbColor Color, tWindowHandle Window)
|
|
||||||
{
|
|
||||||
cWindow *w = (Window == ALL_TILED_WINDOWS) ? GetWindow(x1, y1) : GetWindow(Window);
|
|
||||||
if (w)
|
|
||||||
w->Fill(x1, y1, x2, y2, Color);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cOsdBase::SetBitmap(int x, int y, const cBitmap &Bitmap, tWindowHandle Window)
|
|
||||||
{
|
|
||||||
cWindow *w = (Window == ALL_TILED_WINDOWS) ? GetWindow(x, y) : GetWindow(Window);
|
|
||||||
if (w)
|
|
||||||
w->SetBitmap(x, y, Bitmap);
|
|
||||||
}
|
|
||||||
|
|
||||||
int cOsdBase::Width(unsigned char c)
|
|
||||||
{
|
|
||||||
return numWindows ? window[0]->Width(c) : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int cOsdBase::Width(const char *s)
|
|
||||||
{
|
|
||||||
return numWindows ? window[0]->Width(s) : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
eDvbFont cOsdBase::SetFont(eDvbFont Font)
|
|
||||||
{
|
|
||||||
eDvbFont oldFont = Font;
|
|
||||||
for (int i = 0; i < numWindows; i++)
|
|
||||||
oldFont = window[i]->SetFont(Font);
|
|
||||||
return oldFont;
|
|
||||||
}
|
|
||||||
|
|
||||||
void cOsdBase::Text(int x, int y, const char *s, eDvbColor ColorFg, eDvbColor ColorBg, tWindowHandle Window)
|
|
||||||
{
|
|
||||||
cWindow *w = (Window == ALL_TILED_WINDOWS) ? GetWindow(x, y) : GetWindow(Window);
|
|
||||||
if (w)
|
|
||||||
w->Text(x, y, s, ColorFg, ColorBg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cOsdBase::Relocate(tWindowHandle Window, int x, int y, int NewWidth, int NewHeight)
|
|
||||||
{
|
|
||||||
cWindow *w = GetWindow(Window);
|
|
||||||
if (w) {
|
|
||||||
if (NewWidth > 0 && NewHeight > 0) {
|
|
||||||
if ((NewWidth & 0x03) != 0) {
|
|
||||||
NewWidth += 4 - (NewWidth & 0x03);
|
|
||||||
dsyslog("OSD window width must be a multiple of 4 - increasing to %d", NewWidth);
|
|
||||||
}
|
|
||||||
CloseWindow(w);
|
|
||||||
cWindow *NewWindow = new cWindow(w->Handle(), x, y, NewWidth, NewHeight, w->Bpp(), w->ClearWithBackground(), w->Tiled());
|
|
||||||
window[w->Handle()] = NewWindow;
|
|
||||||
delete w;
|
|
||||||
OpenWindow(NewWindow);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
MoveWindow(w, x, y);
|
|
||||||
w->Relocate(x, y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void cOsdBase::Hide(tWindowHandle Window)
|
|
||||||
{
|
|
||||||
HideWindow(GetWindow(Window), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cOsdBase::Show(tWindowHandle Window)
|
|
||||||
{
|
|
||||||
HideWindow(GetWindow(Window), false);
|
|
||||||
}
|
|
||||||
|
296
osdbase.h
296
osdbase.h
@ -4,221 +4,127 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: osdbase.h 1.9 2004/01/31 10:28:49 kls Exp $
|
* $Id: osdbase.h 1.10 2004/04/30 13:40:11 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __OSDBASE_H
|
#ifndef __OSDBASE_H
|
||||||
#define __OSDBASE_H
|
#define __OSDBASE_H
|
||||||
|
|
||||||
#include <stdio.h>
|
#include "config.h"
|
||||||
#include "font.h"
|
#include "osd.h"
|
||||||
|
#include "skins.h"
|
||||||
|
#include "tools.h"
|
||||||
|
|
||||||
#define MAXNUMCOLORS 256
|
enum eOSState { osUnknown,
|
||||||
|
osContinue,
|
||||||
|
osSchedule,
|
||||||
|
osChannels,
|
||||||
|
osTimers,
|
||||||
|
osRecordings,
|
||||||
|
osPlugin,
|
||||||
|
osSetup,
|
||||||
|
osCommands,
|
||||||
|
osPause,
|
||||||
|
osRecord,
|
||||||
|
osReplay,
|
||||||
|
osStopRecord,
|
||||||
|
osStopReplay,
|
||||||
|
osCancelEdit,
|
||||||
|
osSwitchDvb,
|
||||||
|
osBack,
|
||||||
|
osEnd,
|
||||||
|
os_User, // the following values can be used locally
|
||||||
|
osUser1,
|
||||||
|
osUser2,
|
||||||
|
osUser3,
|
||||||
|
osUser4,
|
||||||
|
osUser5,
|
||||||
|
osUser6,
|
||||||
|
osUser7,
|
||||||
|
osUser8,
|
||||||
|
osUser9,
|
||||||
|
osUser10,
|
||||||
|
};
|
||||||
|
|
||||||
enum eDvbColor {
|
class cOsdItem : public cListObject {
|
||||||
#ifdef DEBUG_OSD
|
|
||||||
clrBackground,
|
|
||||||
clrTransparent = clrBackground,
|
|
||||||
clrBlack = clrBackground,
|
|
||||||
clrRed,
|
|
||||||
clrGreen,
|
|
||||||
clrYellow,
|
|
||||||
clrBlue,
|
|
||||||
clrMagenta,
|
|
||||||
clrCyan,
|
|
||||||
clrWhite,
|
|
||||||
#else
|
|
||||||
clrTransparent = 0x00000000,
|
|
||||||
clrBackground = 0x7F000000, // 50% gray
|
|
||||||
clrBlack = 0xFF000000,
|
|
||||||
clrRed = 0xFF1414FC,
|
|
||||||
clrGreen = 0xFF24FC24,
|
|
||||||
clrYellow = 0xFF24C0FC,
|
|
||||||
clrMagenta = 0xFFFC00B0,
|
|
||||||
clrBlue = 0xFFFC0000,
|
|
||||||
clrCyan = 0xFFFCFC00,
|
|
||||||
clrWhite = 0xFFFCFCFC,
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
class cPalette {
|
|
||||||
private:
|
private:
|
||||||
eDvbColor color[MAXNUMCOLORS];
|
char *text;
|
||||||
int maxColors, numColors;
|
int offset;
|
||||||
bool used[MAXNUMCOLORS];
|
eOSState state;
|
||||||
bool fetched[MAXNUMCOLORS];
|
bool selectable;
|
||||||
bool full;
|
|
||||||
protected:
|
protected:
|
||||||
typedef u_char tIndexes[MAXNUMCOLORS];
|
bool fresh;
|
||||||
public:
|
public:
|
||||||
cPalette(int Bpp);
|
cOsdItem(eOSState State = osUnknown);
|
||||||
int Index(eDvbColor Color);
|
cOsdItem(const char *Text, eOSState State = osUnknown);
|
||||||
void Reset(void);
|
virtual ~cOsdItem();
|
||||||
void SetColor(int Index, eDvbColor Color);
|
bool Selectable(void) { return selectable; }
|
||||||
eDvbColor GetColor(int Index) { return Index < maxColors ? color[Index] : clrBlack; }
|
void SetText(const char *Text, bool Copy = true);
|
||||||
const eDvbColor *NewColors(int &FirstColor, int &LastColor);
|
void SetSelectable(bool Selectable);
|
||||||
// With every call this function returns a consecutive range of
|
void SetFresh(bool Fresh);
|
||||||
// color entries that have been added since the last call. The
|
const char *Text(void) { return text; }
|
||||||
// return value is the address of the first new color, and the
|
virtual void Set(void) {}
|
||||||
// index of the first and last new color are returned in the given
|
virtual eOSState ProcessKey(eKeys Key);
|
||||||
// int parameters. If there are no new color entries, NULL will
|
|
||||||
// be returned.
|
|
||||||
const eDvbColor *AllColors(int &NumColors);
|
|
||||||
// Returns a pointer to the complete color table and stores the
|
|
||||||
// number of valid entries in NumColors. If no colors have been
|
|
||||||
// stored yet, NumColors will be set to 0 and the function will
|
|
||||||
// return NULL.
|
|
||||||
void Take(const cPalette &Palette, tIndexes *Indexes = NULL);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class cBitmap : public cPalette {
|
class cOsdObject {
|
||||||
|
friend class cOsdMenu;
|
||||||
private:
|
private:
|
||||||
const cFont *font;
|
bool isMenu;
|
||||||
eDvbFont fontType;
|
|
||||||
u_char *bitmap;
|
|
||||||
bool clearWithBackground;
|
|
||||||
protected:
|
protected:
|
||||||
int width, height;
|
bool needsFastResponse;
|
||||||
int dirtyX1, dirtyY1, dirtyX2, dirtyY2;
|
|
||||||
public:
|
public:
|
||||||
cBitmap(int Width, int Height, int Bpp, bool ClearWithBackground = true);
|
cOsdObject(bool FastResponse = false) { isMenu = false; needsFastResponse = FastResponse; }
|
||||||
virtual ~cBitmap();
|
virtual ~cOsdObject() {}
|
||||||
bool ClearWithBackground(void) { return clearWithBackground; }
|
bool NeedsFastResponse(void) { return needsFastResponse; }
|
||||||
eDvbFont SetFont(eDvbFont Font);
|
bool IsMenu(void) { return isMenu; }
|
||||||
bool Dirty(int &x1, int &y1, int &x2, int &y2);
|
virtual void Show(void) {}
|
||||||
void SetIndex(int x, int y, u_char Index);
|
virtual eOSState ProcessKey(eKeys Key) { return osUnknown; }
|
||||||
void SetPixel(int x, int y, eDvbColor Color);
|
|
||||||
void SetBitmap(int x, int y, const cBitmap &Bitmap);
|
|
||||||
int Width(void) { return width; }
|
|
||||||
int Width(unsigned char c);
|
|
||||||
int Width(const char *s);
|
|
||||||
int Height(void) { return height; }
|
|
||||||
void Text(int x, int y, const char *s, eDvbColor ColorFg = clrWhite, eDvbColor ColorBg = clrBackground);
|
|
||||||
void Fill(int x1, int y1, int x2, int y2, eDvbColor Color);
|
|
||||||
void Clean(void);
|
|
||||||
void Clear(void);
|
|
||||||
const u_char *Data(int x, int y);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MAXNUMWINDOWS 7 // OSD windows are counted 1...7
|
class cOsdMenu : public cOsdObject, public cList<cOsdItem> {
|
||||||
|
|
||||||
class cWindow : public cBitmap {
|
|
||||||
private:
|
private:
|
||||||
int handle; // the index within the OSD's window array (0...MAXNUMWINDOWS - 1)
|
static cSkinDisplayMenu *displayMenu;
|
||||||
int x0, y0;
|
static int displayMenuCount;
|
||||||
int bpp;
|
static int displayMenuItems;
|
||||||
bool tiled;
|
char *title;
|
||||||
bool shown;
|
int cols[cSkinDisplayMenu::MaxTabs];
|
||||||
public:
|
int first, current, marked;
|
||||||
cWindow(int Handle, int x, int y, int w, int h, int Bpp, bool ClearWithBackground, bool Tiled);
|
cOsdMenu *subMenu;
|
||||||
int X0(void) { return x0; }
|
const char *helpRed, *helpGreen, *helpYellow, *helpBlue;
|
||||||
int Y0(void) { return y0; }
|
char *status;
|
||||||
int Bpp(void) { return bpp; }
|
int digit;
|
||||||
bool Tiled(void) { return tiled; }
|
bool hasHotkeys;
|
||||||
bool Shown(void) { bool s = shown; shown = true; return s; }
|
|
||||||
int Handle(void) { return handle; }
|
|
||||||
bool Contains(int x, int y);
|
|
||||||
void Relocate(int x, int y);
|
|
||||||
void Fill(int x1, int y1, int x2, int y2, eDvbColor Color);
|
|
||||||
void SetBitmap(int x, int y, const cBitmap &Bitmap);
|
|
||||||
void Text(int x, int y, const char *s, eDvbColor ColorFg = clrWhite, eDvbColor ColorBg = clrBackground);
|
|
||||||
const u_char *Data(int x, int y);
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef int tWindowHandle;
|
|
||||||
|
|
||||||
// '-1' is used as an error return value!
|
|
||||||
#define ALL_WINDOWS (-2)
|
|
||||||
#define ALL_TILED_WINDOWS (-3)
|
|
||||||
#define LAST_CREATED_WINDOW (-4)
|
|
||||||
|
|
||||||
class cOsdBase {
|
|
||||||
private:
|
|
||||||
int numWindows;
|
|
||||||
int x0, y0;
|
|
||||||
cWindow *window[MAXNUMWINDOWS];
|
|
||||||
cWindow *GetWindow(int x, int y);
|
|
||||||
cWindow *GetWindow(tWindowHandle Window);
|
|
||||||
protected:
|
protected:
|
||||||
cWindow *GetWindowNr(int i) { return i < MAXNUMWINDOWS ? window[i] : NULL; }
|
cSkinDisplayMenu *DisplayMenu(void) { return displayMenu; }
|
||||||
int NumWindows(void) { return numWindows; }
|
const char *hk(const char *s);
|
||||||
int X0(void) { return x0; }
|
void SetHasHotkeys(void);
|
||||||
int Y0(void) { return y0; }
|
virtual void Clear(void);
|
||||||
virtual bool OpenWindow(cWindow *Window) = 0;
|
bool SelectableItem(int idx);
|
||||||
// Opens the window on the OSD hardware, without actually showing it (the
|
void SetCurrent(cOsdItem *Item);
|
||||||
// initial state shall be "hidden").
|
void RefreshCurrent(void);
|
||||||
virtual void CommitWindow(cWindow *Window) = 0;
|
void DisplayCurrent(bool Current);
|
||||||
// Write any modified data and color definitions to the OSD hardware.
|
void CursorUp(void);
|
||||||
// Use the window's Dirty() function to find out which area of data
|
void CursorDown(void);
|
||||||
// actually needs to be transferred. If the window has not yet been explicitly
|
void PageUp(void);
|
||||||
// shown through a call to ShowWindow(), no visible activity shall take place.
|
void PageDown(void);
|
||||||
virtual void ShowWindow(cWindow *Window) = 0;
|
void Mark(void);
|
||||||
// Make the window actually visible on the OSD hardware.
|
eOSState HotKey(eKeys Key);
|
||||||
virtual void HideWindow(cWindow *Window, bool Hide) = 0;
|
eOSState AddSubMenu(cOsdMenu *SubMenu);
|
||||||
// Temporarily hide the window (if 'Hide' is 'true') or make a previously
|
eOSState CloseSubMenu();
|
||||||
// hidden window visible again (if 'Hide' is 'false').
|
bool HasSubMenu(void) { return subMenu; }
|
||||||
virtual void MoveWindow(cWindow *Window, int x, int y) = 0;
|
void SetStatus(const char *s);
|
||||||
// Move the window to a new location.
|
void SetTitle(const char *Title);
|
||||||
virtual void CloseWindow(cWindow *Window) = 0;
|
void SetHelp(const char *Red, const char *Green = NULL, const char *Yellow = NULL, const char *Blue = NULL);
|
||||||
// Close the window and release any OSD hardware resources allocated for it.
|
virtual void Del(int Index);
|
||||||
public:
|
public:
|
||||||
cOsdBase(int x, int y);
|
cOsdMenu(const char *Title, int c0 = 0, int c1 = 0, int c2 = 0, int c3 = 0, int c4 = 0);
|
||||||
// Initializes the OSD, starting at screen coordinates (x, y).
|
virtual ~cOsdMenu();
|
||||||
virtual ~cOsdBase();
|
int Current(void) { return current; }
|
||||||
// Destroys all windows and shuts down the OSD.
|
void Add(cOsdItem *Item, bool Current = false, cOsdItem *After = NULL);
|
||||||
tWindowHandle Create(int x, int y, int w, int h, int Bpp, bool ClearWithBackground = true, bool Tiled = true);
|
void Ins(cOsdItem *Item, bool Current = false, cOsdItem *Before = NULL);
|
||||||
// Creates a window at coordinates (x, y), which are relative to the OSD's
|
virtual void Display(void);
|
||||||
// origin given in the constructor, with the given width, height and color
|
virtual eOSState ProcessKey(eKeys Key);
|
||||||
// depth. ClearWithBackground controls whether the window will be filled with
|
|
||||||
// clrBackground when it is cleared. Setting this to 'false' may be useful
|
|
||||||
// for windows that don't need clrBackground but want to save this color
|
|
||||||
// palette entry for a different color. Tiled controls whether this will
|
|
||||||
// be part of a multi section OSD (with several windows that all have
|
|
||||||
// different color depths and palettes and form one large OSD area), or
|
|
||||||
// whether this is a "standalone" window that will be drawn "in front"
|
|
||||||
// of any windows defined *after* this one (this can be used for highlighting
|
|
||||||
// certain parts of the OSD, as would be done in a 'cursor').
|
|
||||||
// Returns a handle that can be used to identify this window.
|
|
||||||
void AddColor(eDvbColor Color, tWindowHandle Window = LAST_CREATED_WINDOW);
|
|
||||||
// Adds the Color to the color palette of the given window if it is not
|
|
||||||
// already contained in the palette (and if the palette still has free
|
|
||||||
// slots for new colors). The default value LAST_CREATED_WINDOW will
|
|
||||||
// access the most recently created window, without the need of explicitly
|
|
||||||
// using a window handle.
|
|
||||||
void Flush(void);
|
|
||||||
// Actually commits all data of all windows to the OSD.
|
|
||||||
void Clear(tWindowHandle Window = ALL_TILED_WINDOWS);
|
|
||||||
// Clears the given window. If ALL_TILED_WINDOWS is given, only the tiled
|
|
||||||
// windows will be cleared, leaving the standalone windows untouched. If
|
|
||||||
// ALL_WINDOWS is given, the standalone windows will also be cleared.
|
|
||||||
void Fill(int x1, int y1, int x2, int y2, eDvbColor Color, tWindowHandle Window = ALL_TILED_WINDOWS);
|
|
||||||
// Fills the rectangle defined by the upper left (x1, y2) and lower right
|
|
||||||
// (x2, y2) corners with the given Color. If a specific window is given,
|
|
||||||
// the coordinates are relative to that window's upper left corner.
|
|
||||||
// Otherwise they are relative to the upper left corner of the entire OSD.
|
|
||||||
// If all tiled windows are selected, only that window which contains the
|
|
||||||
// point (x1, y1) will actually be filled.
|
|
||||||
void SetBitmap(int x, int y, const cBitmap &Bitmap, tWindowHandle Window = ALL_TILED_WINDOWS);
|
|
||||||
// Sets the pixels within the given window with the data from the given
|
|
||||||
// Bitmap. See Fill() for details about the coordinates.
|
|
||||||
int Width(unsigned char c);
|
|
||||||
// Returns the width (in pixels) of the given character in the current font.
|
|
||||||
int Width(const char *s);
|
|
||||||
// Returns the width (in pixels) of the given string in the current font.
|
|
||||||
eDvbFont SetFont(eDvbFont Font);
|
|
||||||
// Sets the current font for subsequent Width() and Text() operations.
|
|
||||||
void Text(int x, int y, const char *s, eDvbColor ColorFg = clrWhite, eDvbColor ColorBg = clrBackground, tWindowHandle Window = ALL_TILED_WINDOWS);
|
|
||||||
// Writes the given string at coordinates (x, y) with the given foreground
|
|
||||||
// and background color into the given window (see Fill() for details
|
|
||||||
// about the coordinates).
|
|
||||||
void Relocate(tWindowHandle Window, int x, int y, int NewWidth = -1, int NewHeight = -1);
|
|
||||||
// Moves the given window to the new location at (x, y). If NewWidth and
|
|
||||||
// NewHeight are also given, the window will also be resized to the new
|
|
||||||
// width and height.
|
|
||||||
void Hide(tWindowHandle Window);
|
|
||||||
// Hides the given window.
|
|
||||||
void Show(tWindowHandle Window);
|
|
||||||
// Shows the given window.
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //__OSDBASE_H
|
#endif //__OSDBASE_H
|
||||||
|
4
player.c
4
player.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: player.c 1.6 2002/11/02 14:55:37 kls Exp $
|
* $Id: player.c 1.7 2004/04/16 13:34:11 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "player.h"
|
#include "player.h"
|
||||||
@ -80,7 +80,7 @@ void cControl::Attach(void)
|
|||||||
if (cDevice::PrimaryDevice()->AttachPlayer(control->player))
|
if (cDevice::PrimaryDevice()->AttachPlayer(control->player))
|
||||||
control->attached = true;
|
control->attached = true;
|
||||||
else {
|
else {
|
||||||
Interface->Error(tr("Channel locked (recording)!"));
|
Skins.Message(mtError, tr("Channel locked (recording)!"));
|
||||||
Shutdown();
|
Shutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
4
player.h
4
player.h
@ -4,14 +4,14 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: player.h 1.10 2002/11/03 11:27:30 kls Exp $
|
* $Id: player.h 1.11 2004/04/30 13:45:59 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __PLAYER_H
|
#ifndef __PLAYER_H
|
||||||
#define __PLAYER_H
|
#define __PLAYER_H
|
||||||
|
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
#include "osd.h"
|
#include "osdbase.h"
|
||||||
|
|
||||||
class cPlayer {
|
class cPlayer {
|
||||||
friend class cDevice;
|
friend class cDevice;
|
||||||
|
4
plugin.h
4
plugin.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: plugin.h 1.6 2003/05/09 14:57:55 kls Exp $
|
* $Id: plugin.h 1.7 2004/04/30 13:46:21 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __PLUGIN_H
|
#ifndef __PLUGIN_H
|
||||||
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
#include "menuitems.h"
|
#include "menuitems.h"
|
||||||
#include "osd.h"
|
#include "osdbase.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
|
||||||
#define VDRPLUGINCREATOR(PluginClass) extern "C" void *VDRPluginCreator(void) { return new PluginClass; }
|
#define VDRPLUGINCREATOR(PluginClass) extern "C" void *VDRPluginCreator(void) { return new PluginClass; }
|
||||||
|
15
recording.c
15
recording.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: recording.c 1.86 2003/11/08 15:25:35 kls Exp $
|
* $Id: recording.c 1.87 2004/05/07 14:24:18 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "recording.h"
|
#include "recording.h"
|
||||||
@ -18,6 +18,7 @@
|
|||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
#include "interface.h"
|
#include "interface.h"
|
||||||
#include "remux.h" //XXX+ I_FRAME
|
#include "remux.h" //XXX+ I_FRAME
|
||||||
|
#include "skins.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
#include "videodir.h"
|
#include "videodir.h"
|
||||||
|
|
||||||
@ -461,7 +462,7 @@ char *cRecording::SortName(void)
|
|||||||
return sortBuffer;
|
return sortBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cRecording::GetResume(void)
|
int cRecording::GetResume(void) const
|
||||||
{
|
{
|
||||||
if (resume == RESUME_NOT_INITIALIZED) {
|
if (resume == RESUME_NOT_INITIALIZED) {
|
||||||
cResumeFile ResumeFile(FileName());
|
cResumeFile ResumeFile(FileName());
|
||||||
@ -476,7 +477,7 @@ bool cRecording::operator< (const cListObject &ListObject)
|
|||||||
return strcasecmp(SortName(), r->SortName()) < 0;
|
return strcasecmp(SortName(), r->SortName()) < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *cRecording::FileName(void)
|
const char *cRecording::FileName(void) const
|
||||||
{
|
{
|
||||||
if (!fileName) {
|
if (!fileName) {
|
||||||
struct tm tm_r;
|
struct tm tm_r;
|
||||||
@ -488,7 +489,7 @@ const char *cRecording::FileName(void)
|
|||||||
return fileName;
|
return fileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *cRecording::Title(char Delimiter, bool NewIndicator, int Level)
|
const char *cRecording::Title(char Delimiter, bool NewIndicator, int Level) const
|
||||||
{
|
{
|
||||||
char New = NewIndicator && IsNew() ? '*' : ' ';
|
char New = NewIndicator && IsNew() ? '*' : ' ';
|
||||||
free(titleBuffer);
|
free(titleBuffer);
|
||||||
@ -548,7 +549,7 @@ const char *cRecording::PrefixFileName(char Prefix)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cRecording::HierarchyLevels(void)
|
int cRecording::HierarchyLevels(void) const
|
||||||
{
|
{
|
||||||
const char *s = name;
|
const char *s = name;
|
||||||
int level = 0;
|
int level = 0;
|
||||||
@ -559,7 +560,7 @@ int cRecording::HierarchyLevels(void)
|
|||||||
return level;
|
return level;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cRecording::IsEdited(void)
|
bool cRecording::IsEdited(void) const
|
||||||
{
|
{
|
||||||
const char *s = strrchr(name, '~');
|
const char *s = strrchr(name, '~');
|
||||||
s = !s ? name : s + 1;
|
s = !s ? name : s + 1;
|
||||||
@ -637,7 +638,7 @@ bool cRecordings::Load(bool Deleted)
|
|||||||
result = Count() > 0;
|
result = Count() > 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Interface->Error("Error while opening pipe!");
|
Skins.Message(mtError, "Error while opening pipe!");
|
||||||
free(cmd);
|
free(cmd);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
26
recording.h
26
recording.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: recording.h 1.28 2003/10/17 14:27:36 kls Exp $
|
* $Id: recording.h 1.29 2004/05/07 14:24:22 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __RECORDING_H
|
#ifndef __RECORDING_H
|
||||||
@ -34,15 +34,15 @@ public:
|
|||||||
|
|
||||||
class cRecording : public cListObject {
|
class cRecording : public cListObject {
|
||||||
private:
|
private:
|
||||||
int resume;
|
mutable int resume;
|
||||||
char *titleBuffer;
|
mutable char *titleBuffer;
|
||||||
char *sortBuffer;
|
char *sortBuffer;
|
||||||
char *fileName;
|
mutable char *fileName;
|
||||||
char *name;
|
mutable char *name;
|
||||||
char *summary;
|
char *summary;
|
||||||
char *StripEpisodeName(char *s);
|
char *StripEpisodeName(char *s);
|
||||||
char *SortName(void);
|
char *SortName(void);
|
||||||
int GetResume(void);
|
int GetResume(void) const;
|
||||||
public:
|
public:
|
||||||
time_t start;
|
time_t start;
|
||||||
int priority;
|
int priority;
|
||||||
@ -51,14 +51,14 @@ public:
|
|||||||
cRecording(const char *FileName);
|
cRecording(const char *FileName);
|
||||||
~cRecording();
|
~cRecording();
|
||||||
virtual bool operator< (const cListObject &ListObject);
|
virtual bool operator< (const cListObject &ListObject);
|
||||||
const char *Name(void) { return name; }
|
const char *Name(void) const { return name; }
|
||||||
const char *FileName(void);
|
const char *FileName(void) const;
|
||||||
const char *Title(char Delimiter = ' ', bool NewIndicator = false, int Level = -1);
|
const char *Title(char Delimiter = ' ', bool NewIndicator = false, int Level = -1) const;
|
||||||
const char *Summary(void) { return summary; }
|
const char *Summary(void) const { return summary; }
|
||||||
const char *PrefixFileName(char Prefix);
|
const char *PrefixFileName(char Prefix);
|
||||||
int HierarchyLevels(void);
|
int HierarchyLevels(void) const;
|
||||||
bool IsNew(void) { return GetResume() <= 0; }
|
bool IsNew(void) const { return GetResume() <= 0; }
|
||||||
bool IsEdited(void);
|
bool IsEdited(void) const;
|
||||||
bool WriteSummary(void);
|
bool WriteSummary(void);
|
||||||
bool Delete(void);
|
bool Delete(void);
|
||||||
// Changes the file name so that it will no longer be visible in the "Recordings" menu
|
// Changes the file name so that it will no longer be visible in the "Recordings" menu
|
||||||
|
541
skinclassic.c
Normal file
541
skinclassic.c
Normal file
@ -0,0 +1,541 @@
|
|||||||
|
/*
|
||||||
|
* skinclassic.c: The 'classic' VDR skin
|
||||||
|
*
|
||||||
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
|
* how to reach the author.
|
||||||
|
*
|
||||||
|
* $Id: skinclassic.c 1.1 2004/05/15 14:51:18 kls Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "skinclassic.h"
|
||||||
|
#include "font.h"
|
||||||
|
#include "i18n.h"
|
||||||
|
#include "osd.h"
|
||||||
|
#include "themes.h"
|
||||||
|
|
||||||
|
#define ScrollWidth 5
|
||||||
|
|
||||||
|
static cTheme Theme;
|
||||||
|
|
||||||
|
THEME_CLR(Theme, clrBackground, clrGray50);
|
||||||
|
THEME_CLR(Theme, clrButtonRedFg, clrWhite);
|
||||||
|
THEME_CLR(Theme, clrButtonRedBg, clrRed);
|
||||||
|
THEME_CLR(Theme, clrButtonGreenFg, clrBlack);
|
||||||
|
THEME_CLR(Theme, clrButtonGreenBg, clrGreen);
|
||||||
|
THEME_CLR(Theme, clrButtonYellowFg, clrBlack);
|
||||||
|
THEME_CLR(Theme, clrButtonYellowBg, clrYellow);
|
||||||
|
THEME_CLR(Theme, clrButtonBlueFg, clrWhite);
|
||||||
|
THEME_CLR(Theme, clrButtonBlueBg, clrBlue);
|
||||||
|
THEME_CLR(Theme, clrMessageStatusFg, clrBlack);
|
||||||
|
THEME_CLR(Theme, clrMessageStatusBg, clrCyan);
|
||||||
|
THEME_CLR(Theme, clrMessageInfoFg, clrBlack);
|
||||||
|
THEME_CLR(Theme, clrMessageInfoBg, clrGreen);
|
||||||
|
THEME_CLR(Theme, clrMessageWarningFg, clrBlack);
|
||||||
|
THEME_CLR(Theme, clrMessageWarningBg, clrYellow);
|
||||||
|
THEME_CLR(Theme, clrMessageErrorFg, clrWhite);
|
||||||
|
THEME_CLR(Theme, clrMessageErrorBg, clrRed);
|
||||||
|
THEME_CLR(Theme, clrVolumePrompt, clrGreen);
|
||||||
|
THEME_CLR(Theme, clrVolumeBarUpper, clrWhite);
|
||||||
|
THEME_CLR(Theme, clrVolumeBarLower, clrGreen);
|
||||||
|
THEME_CLR(Theme, clrChannelName, clrWhite);
|
||||||
|
THEME_CLR(Theme, clrChannelDate, clrWhite);
|
||||||
|
THEME_CLR(Theme, clrChannelEpgTimeFg, clrWhite);
|
||||||
|
THEME_CLR(Theme, clrChannelEpgTimeBg, clrRed);
|
||||||
|
THEME_CLR(Theme, clrChannelEpgTitle, clrCyan);
|
||||||
|
THEME_CLR(Theme, clrChannelEpgShortText, clrYellow);
|
||||||
|
THEME_CLR(Theme, clrMenuTitleFg, clrBlack);
|
||||||
|
THEME_CLR(Theme, clrMenuTitleBg, clrCyan);
|
||||||
|
THEME_CLR(Theme, clrMenuDate, clrBlack);
|
||||||
|
THEME_CLR(Theme, clrMenuItemCurrentFg, clrBlack);
|
||||||
|
THEME_CLR(Theme, clrMenuItemCurrentBg, clrCyan);
|
||||||
|
THEME_CLR(Theme, clrMenuItemSelectable, clrWhite);
|
||||||
|
THEME_CLR(Theme, clrMenuItemNonSelectable, clrCyan);
|
||||||
|
THEME_CLR(Theme, clrMenuEventTime, clrWhite);
|
||||||
|
THEME_CLR(Theme, clrMenuEventVpsFg, clrBlack);
|
||||||
|
THEME_CLR(Theme, clrMenuEventVpsBg, clrWhite);
|
||||||
|
THEME_CLR(Theme, clrMenuEventTitle, clrCyan);
|
||||||
|
THEME_CLR(Theme, clrMenuEventShortText, clrWhite);
|
||||||
|
THEME_CLR(Theme, clrMenuEventDescription, clrCyan);
|
||||||
|
THEME_CLR(Theme, clrMenuScrollbarTotal, clrWhite);
|
||||||
|
THEME_CLR(Theme, clrMenuScrollbarShown, clrCyan);
|
||||||
|
THEME_CLR(Theme, clrMenuText, clrWhite);
|
||||||
|
THEME_CLR(Theme, clrReplayTitle, clrWhite);
|
||||||
|
THEME_CLR(Theme, clrReplayCurrent, clrWhite);
|
||||||
|
THEME_CLR(Theme, clrReplayTotal, clrWhite);
|
||||||
|
THEME_CLR(Theme, clrReplayModeJump, clrWhite);
|
||||||
|
THEME_CLR(Theme, clrReplayProgressSeen, clrGreen);
|
||||||
|
THEME_CLR(Theme, clrReplayProgressRest, clrWhite);
|
||||||
|
THEME_CLR(Theme, clrReplayProgressSelected, clrRed);
|
||||||
|
THEME_CLR(Theme, clrReplayProgressMark, clrBlack);
|
||||||
|
THEME_CLR(Theme, clrReplayProgressCurrent, clrRed);
|
||||||
|
|
||||||
|
// --- cSkinClassicDisplayChannel --------------------------------------------
|
||||||
|
|
||||||
|
class cSkinClassicDisplayChannel : public cSkinDisplayChannel{
|
||||||
|
private:
|
||||||
|
cOsd *osd;
|
||||||
|
int lineHeight;
|
||||||
|
int timeWidth;
|
||||||
|
public:
|
||||||
|
cSkinClassicDisplayChannel(bool WithInfo);
|
||||||
|
virtual ~cSkinClassicDisplayChannel();
|
||||||
|
virtual void SetChannel(const cChannel *Channel, int Number);
|
||||||
|
virtual void SetEvents(const cEvent *Present, const cEvent *Following);
|
||||||
|
virtual void Flush(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
cSkinClassicDisplayChannel::cSkinClassicDisplayChannel(bool WithInfo)
|
||||||
|
{
|
||||||
|
int Lines = WithInfo ? 5 : 1;
|
||||||
|
const cFont *font = cFont::GetFont(fontOsd);
|
||||||
|
lineHeight = font->Height();
|
||||||
|
osd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop + (Setup.ChannelInfoPos ? 0 : Setup.OSDHeight - Lines * lineHeight));
|
||||||
|
timeWidth = font->Width("00:00") + 4;
|
||||||
|
tArea Areas[] = { { 0, 0, Setup.OSDWidth - 1, Lines * lineHeight, 4 } };
|
||||||
|
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||||
|
osd->DrawRectangle(0, 0, osd->Width() - 1, osd->Height() - 1, Theme.Color(clrBackground));
|
||||||
|
}
|
||||||
|
|
||||||
|
cSkinClassicDisplayChannel::~cSkinClassicDisplayChannel()
|
||||||
|
{
|
||||||
|
delete osd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinClassicDisplayChannel::SetChannel(const cChannel *Channel, int Number)
|
||||||
|
{
|
||||||
|
osd->DrawRectangle(0, 0, osd->Width() - 1, lineHeight - 1, Theme.Color(clrBackground));
|
||||||
|
osd->DrawText(2, 0, ChannelString(Channel, Number), Theme.Color(clrChannelName), Theme.Color(clrBackground), cFont::GetFont(fontOsd));
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinClassicDisplayChannel::SetEvents(const cEvent *Present, const cEvent *Following)
|
||||||
|
{
|
||||||
|
osd->DrawRectangle(0, lineHeight, timeWidth - 1, osd->Height(), Theme.Color(clrChannelEpgTimeBg));
|
||||||
|
osd->DrawRectangle(timeWidth, lineHeight, osd->Width() - 1, osd->Height(), Theme.Color(clrBackground));
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
const cEvent *e = !i ? Present : Following;
|
||||||
|
if (e) {
|
||||||
|
osd->DrawText( 2, (2 * i + 1) * lineHeight, e->GetTimeString(), Theme.Color(clrChannelEpgTimeFg), Theme.Color(clrChannelEpgTimeBg), cFont::GetFont(fontOsd));
|
||||||
|
osd->DrawText(timeWidth + 10, (2 * i + 1) * lineHeight, e->Title(), Theme.Color(clrChannelEpgTitle), Theme.Color(clrBackground), cFont::GetFont(fontOsd));
|
||||||
|
osd->DrawText(timeWidth + 10, (2 * i + 2) * lineHeight, e->ShortText(), Theme.Color(clrChannelEpgShortText), Theme.Color(clrBackground), cFont::GetFont(fontSml));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinClassicDisplayChannel::Flush(void)
|
||||||
|
{
|
||||||
|
const char *date = DayDateTime();
|
||||||
|
osd->DrawText(osd->Width() - cFont::GetFont(fontSml)->Width(date) - 2, 0, date, Theme.Color(clrChannelDate), Theme.Color(clrBackground), cFont::GetFont(fontSml));
|
||||||
|
osd->Flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- cSkinClassicDisplayMenu -----------------------------------------------
|
||||||
|
|
||||||
|
class cSkinClassicDisplayMenu : public cSkinDisplayMenu {
|
||||||
|
private:
|
||||||
|
cOsd *osd;
|
||||||
|
int x0, x1;
|
||||||
|
int y0, y1, y2, y3, y4, y5;
|
||||||
|
int lineHeight;
|
||||||
|
void SetScrollbar(void);
|
||||||
|
public:
|
||||||
|
cSkinClassicDisplayMenu(void);
|
||||||
|
virtual ~cSkinClassicDisplayMenu();
|
||||||
|
virtual void Scroll(bool Up, bool Page);
|
||||||
|
virtual int MaxItems(void);
|
||||||
|
virtual void Clear(void);
|
||||||
|
virtual void SetTitle(const char *Title);
|
||||||
|
virtual void SetButtons(const char *Red, const char *Green = NULL, const char *Yellow = NULL, const char *Blue = NULL);
|
||||||
|
virtual void SetMessage(eMessageType Type, const char *Text);
|
||||||
|
virtual void SetItem(const char *Text, int Index, bool Current, bool Selectable);
|
||||||
|
virtual void SetEvent(const cEvent *Event);
|
||||||
|
virtual void SetRecording(const cRecording *Recording);
|
||||||
|
virtual void SetText(const char *Text, bool FixedFont);
|
||||||
|
virtual void Flush(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
cSkinClassicDisplayMenu::cSkinClassicDisplayMenu(void)
|
||||||
|
{
|
||||||
|
const cFont *font = cFont::GetFont(fontOsd);
|
||||||
|
lineHeight = font->Height();
|
||||||
|
x0 = 0;
|
||||||
|
x1 = Setup.OSDWidth;
|
||||||
|
y0 = 0;
|
||||||
|
y1 = lineHeight;
|
||||||
|
y2 = y1 + lineHeight;
|
||||||
|
y5 = Setup.OSDHeight;
|
||||||
|
y4 = y5 - lineHeight;
|
||||||
|
y3 = y4 - lineHeight;
|
||||||
|
osd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop);
|
||||||
|
tArea Areas[] = { { x0, y0, x1 - 1, y5 - 1, 4 } };
|
||||||
|
if (osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
|
||||||
|
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||||
|
else {
|
||||||
|
tArea Areas[] = { { x0, y0, x1 - 1, y1 - 1, 2 },
|
||||||
|
{ x0, y1, x1 - 1, y3 - 1, 2 },
|
||||||
|
{ x0, y3, x1 - 1, y5 - 1, 4 }
|
||||||
|
};
|
||||||
|
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||||
|
}
|
||||||
|
osd->DrawRectangle(x0, y0, x1 - 1, y5 - 1, Theme.Color(clrBackground));
|
||||||
|
}
|
||||||
|
|
||||||
|
cSkinClassicDisplayMenu::~cSkinClassicDisplayMenu()
|
||||||
|
{
|
||||||
|
delete osd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinClassicDisplayMenu::SetScrollbar(void)
|
||||||
|
{
|
||||||
|
if (textScroller.CanScroll()) {
|
||||||
|
int yt = textScroller.Top();
|
||||||
|
int yb = yt + textScroller.Height();
|
||||||
|
int st = yt;
|
||||||
|
int sb = yb;
|
||||||
|
int tt = st + (sb - st) * textScroller.Offset() / textScroller.Total();
|
||||||
|
int tb = tt + (sb - st) * textScroller.Shown() / textScroller.Total();
|
||||||
|
int xl = x1 - ScrollWidth;
|
||||||
|
osd->DrawRectangle(xl, st, x1 - 1, sb, Theme.Color(clrMenuScrollbarTotal));
|
||||||
|
osd->DrawRectangle(xl, tt, x1 - 1, tb, Theme.Color(clrMenuScrollbarShown));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinClassicDisplayMenu::Scroll(bool Up, bool Page)
|
||||||
|
{
|
||||||
|
cSkinDisplayMenu::Scroll(Up, Page);
|
||||||
|
SetScrollbar();
|
||||||
|
}
|
||||||
|
|
||||||
|
int cSkinClassicDisplayMenu::MaxItems(void)
|
||||||
|
{
|
||||||
|
return (y3 - y2) / lineHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinClassicDisplayMenu::Clear(void)
|
||||||
|
{
|
||||||
|
textScroller.Reset();
|
||||||
|
osd->DrawRectangle(x0, y1, x1 - 1, y4 - 1, Theme.Color(clrBackground));
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinClassicDisplayMenu::SetTitle(const char *Title)
|
||||||
|
{
|
||||||
|
const cFont *font = cFont::GetFont(fontOsd);
|
||||||
|
osd->DrawText(x0, y0, Title, Theme.Color(clrMenuTitleFg), Theme.Color(clrMenuTitleBg), font, x1 - x0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinClassicDisplayMenu::SetButtons(const char *Red, const char *Green, const char *Yellow, const char *Blue)
|
||||||
|
{
|
||||||
|
const cFont *font = cFont::GetFont(fontOsd);
|
||||||
|
int w = x1 - x0;
|
||||||
|
int t0 = x0;
|
||||||
|
int t1 = x0 + w / 4;
|
||||||
|
int t2 = x0 + w / 2;
|
||||||
|
int t3 = x1 - w / 4;
|
||||||
|
int t4 = x1;
|
||||||
|
osd->DrawText(t0, y4, Red, Theme.Color(clrButtonRedFg), Theme.Color(clrButtonRedBg), font, t1 - t0, 0, taCenter);
|
||||||
|
osd->DrawText(t1, y4, Green, Theme.Color(clrButtonGreenFg), Theme.Color(clrButtonGreenBg), font, t2 - t1, 0, taCenter);
|
||||||
|
osd->DrawText(t2, y4, Yellow, Theme.Color(clrButtonYellowFg), Theme.Color(clrButtonYellowBg), font, t3 - t2, 0, taCenter);
|
||||||
|
osd->DrawText(t3, y4, Blue, Theme.Color(clrButtonBlueFg), Theme.Color(clrButtonBlueBg), font, t4 - t3, 0, taCenter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinClassicDisplayMenu::SetMessage(eMessageType Type, const char *Text)
|
||||||
|
{
|
||||||
|
const cFont *font = cFont::GetFont(fontOsd);
|
||||||
|
if (Text)
|
||||||
|
osd->DrawText(x0, y3, Text, Theme.Color(clrMessageStatusFg + 2 * Type), Theme.Color(clrMessageStatusBg + 2 * Type), font, x1 - x0, 0, taCenter);
|
||||||
|
else
|
||||||
|
osd->DrawRectangle(x0, y3, x1 - 1, y4 - 1, Theme.Color(clrBackground));
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinClassicDisplayMenu::SetItem(const char *Text, int Index, bool Current, bool Selectable)
|
||||||
|
{
|
||||||
|
int y = y2 + Index * lineHeight;
|
||||||
|
tColor ColorFg, ColorBg;
|
||||||
|
if (Current) {
|
||||||
|
ColorFg = Theme.Color(clrMenuItemCurrentFg);
|
||||||
|
ColorBg = Theme.Color(clrMenuItemCurrentBg);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ColorFg = Theme.Color(Selectable ? clrMenuItemSelectable : clrMenuItemNonSelectable);
|
||||||
|
ColorBg = Theme.Color(clrBackground);
|
||||||
|
}
|
||||||
|
const cFont *font = cFont::GetFont(fontOsd);
|
||||||
|
for (int i = 0; i < MaxTabs; i++) {
|
||||||
|
const char *s = GetTabbedText(Text, i);
|
||||||
|
if (s) {
|
||||||
|
int xt = x0 + Tab(i);
|
||||||
|
osd->DrawText(xt, y, s, ColorFg, ColorBg, font, x1 - xt);
|
||||||
|
}
|
||||||
|
if (!Tab(i + 1))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
SetEditableWidth(x1 - x0 - Tab(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinClassicDisplayMenu::SetEvent(const cEvent *Event)
|
||||||
|
{
|
||||||
|
if (!Event)
|
||||||
|
return;
|
||||||
|
const cFont *font = cFont::GetFont(fontOsd);
|
||||||
|
int xl = x0 + 10;
|
||||||
|
int y = y2;
|
||||||
|
cTextScroller ts;
|
||||||
|
char t[32];
|
||||||
|
snprintf(t, sizeof(t), "%s %s - %s", Event->GetDateString(), Event->GetTimeString(), Event->GetEndTimeString());//TODO dayname, no year
|
||||||
|
ts.Set(osd, xl, y, x1 - xl, y3 - y, t, font, Theme.Color(clrMenuEventTime), Theme.Color(clrBackground));
|
||||||
|
if (Event->Vps() && Event->Vps() != Event->StartTime()) {
|
||||||
|
char *buffer;
|
||||||
|
asprintf(&buffer, " VPS: %s", Event->GetVpsString());
|
||||||
|
const cFont *font = cFont::GetFont(fontSml);
|
||||||
|
osd->DrawText(x1 - font->Width(buffer), y, buffer, Theme.Color(clrMenuEventVpsFg), Theme.Color(clrMenuEventVpsBg), font);
|
||||||
|
free(buffer);
|
||||||
|
}
|
||||||
|
y += ts.Height();
|
||||||
|
y += font->Height();
|
||||||
|
ts.Set(osd, xl, y, x1 - xl, y3 - y, Event->Title(), font, Theme.Color(clrMenuEventTitle), Theme.Color(clrBackground));
|
||||||
|
y += ts.Height();
|
||||||
|
if (!isempty(Event->ShortText())) {
|
||||||
|
const cFont *font = cFont::GetFont(fontSml);
|
||||||
|
ts.Set(osd, xl, y, x1 - xl, y3 - y, Event->ShortText(), font, Theme.Color(clrMenuEventShortText), Theme.Color(clrBackground));
|
||||||
|
y += ts.Height();
|
||||||
|
}
|
||||||
|
y += font->Height();
|
||||||
|
if (!isempty(Event->Description())) {
|
||||||
|
textScroller.Set(osd, xl, y, x1 - xl - 2 * ScrollWidth, y3 - y, Event->Description(), font, Theme.Color(clrMenuEventDescription), Theme.Color(clrBackground));
|
||||||
|
SetScrollbar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinClassicDisplayMenu::SetRecording(const cRecording *Recording)
|
||||||
|
{
|
||||||
|
SetText(Recording->Summary(), false); //TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinClassicDisplayMenu::SetText(const char *Text, bool FixedFont)
|
||||||
|
{
|
||||||
|
const cFont *font = cFont::GetFont(FixedFont ? fontFix : fontOsd);
|
||||||
|
textScroller.Set(osd, x0, y2, x1 - x0 - 2 * ScrollWidth, y3 - y2, Text, font, Theme.Color(clrMenuText), Theme.Color(clrBackground));
|
||||||
|
SetScrollbar();
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinClassicDisplayMenu::Flush(void)
|
||||||
|
{
|
||||||
|
const char *date = DayDateTime();
|
||||||
|
const cFont *font = cFont::GetFont(fontOsd);
|
||||||
|
osd->DrawText(x1 - font->Width(date) - 2, y0, date, Theme.Color(clrMenuDate), Theme.Color(clrMenuTitleBg), font);
|
||||||
|
osd->Flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- cSkinClassicDisplayReplay ---------------------------------------------
|
||||||
|
|
||||||
|
class cSkinClassicDisplayReplay : public cSkinDisplayReplay {
|
||||||
|
private:
|
||||||
|
cOsd *osd;
|
||||||
|
int x0, x1;
|
||||||
|
int y0, y1, y2, y3;
|
||||||
|
int lastCurrentWidth;
|
||||||
|
public:
|
||||||
|
cSkinClassicDisplayReplay(bool ModeOnly);
|
||||||
|
virtual ~cSkinClassicDisplayReplay();
|
||||||
|
virtual void SetTitle(const char *Title);
|
||||||
|
virtual void SetMode(bool Play, bool Forward, int Speed);
|
||||||
|
virtual void SetProgress(int Current, int Total);
|
||||||
|
virtual void SetCurrent(const char *Current);
|
||||||
|
virtual void SetTotal(const char *Total);
|
||||||
|
virtual void SetJump(const char *Jump);
|
||||||
|
virtual void Flush(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
cSkinClassicDisplayReplay::cSkinClassicDisplayReplay(bool ModeOnly)
|
||||||
|
{
|
||||||
|
const cFont *font = cFont::GetFont(fontOsd);
|
||||||
|
int lineHeight = font->Height();
|
||||||
|
lastCurrentWidth = 0;
|
||||||
|
x0 = 0;
|
||||||
|
x1 = Setup.OSDWidth;
|
||||||
|
y0 = 0;
|
||||||
|
y1 = lineHeight;
|
||||||
|
y2 = 2 * lineHeight;
|
||||||
|
y3 = 3 * lineHeight;
|
||||||
|
osd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop + Setup.OSDHeight - y3);
|
||||||
|
tArea Areas[] = { { x0, y0, x1 - 1, y3 - 1, 4 } };
|
||||||
|
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||||
|
osd->DrawRectangle(x0, y0, x1 - 1, y3 - 1, ModeOnly ? clrTransparent : Theme.Color(clrBackground));
|
||||||
|
}
|
||||||
|
|
||||||
|
cSkinClassicDisplayReplay::~cSkinClassicDisplayReplay()
|
||||||
|
{
|
||||||
|
delete osd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinClassicDisplayReplay::SetTitle(const char *Title)
|
||||||
|
{
|
||||||
|
osd->DrawText(x0, y0, Title, Theme.Color(clrReplayTitle), Theme.Color(clrBackground), cFont::GetFont(fontOsd));
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinClassicDisplayReplay::SetMode(bool Play, bool Forward, int Speed)
|
||||||
|
{
|
||||||
|
if (Setup.ShowReplayMode) {
|
||||||
|
const char *Mode;
|
||||||
|
if (Speed == -1) Mode = Play ? " > " : " || ";
|
||||||
|
else if (Play) Mode = Forward ? " X>> " : " <<X ";
|
||||||
|
else Mode = Forward ? " X|> " : " <|X ";
|
||||||
|
char buf[16];
|
||||||
|
strn0cpy(buf, Mode, sizeof(buf));
|
||||||
|
char *p = strchr(buf, 'X');
|
||||||
|
if (p)
|
||||||
|
*p = Speed > 0 ? '1' + Speed - 1 : ' ';
|
||||||
|
SetJump(buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinClassicDisplayReplay::SetProgress(int Current, int Total)
|
||||||
|
{
|
||||||
|
cProgressBar pb(x1 - x0, y2 - y1, Current, Total, marks, Theme.Color(clrReplayProgressSeen), Theme.Color(clrReplayProgressRest), Theme.Color(clrReplayProgressSelected), Theme.Color(clrReplayProgressMark), Theme.Color(clrReplayProgressCurrent));
|
||||||
|
osd->DrawBitmap(x0, y1, pb);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinClassicDisplayReplay::SetCurrent(const char *Current)
|
||||||
|
{
|
||||||
|
const cFont *font = cFont::GetFont(fontOsd);
|
||||||
|
int w = font->Width(Current);
|
||||||
|
osd->DrawText(x0, y2, Current, Theme.Color(clrReplayCurrent), Theme.Color(clrBackground), font, lastCurrentWidth > w ? lastCurrentWidth : 0);
|
||||||
|
lastCurrentWidth = w;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinClassicDisplayReplay::SetTotal(const char *Total)
|
||||||
|
{
|
||||||
|
const cFont *font = cFont::GetFont(fontOsd);
|
||||||
|
osd->DrawText(x1 - font->Width(Total), y2, Total, Theme.Color(clrReplayTotal), Theme.Color(clrBackground), font);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinClassicDisplayReplay::SetJump(const char *Jump)
|
||||||
|
{
|
||||||
|
osd->DrawText(x0 + (x1 - x0) / 4, y2, Jump, Theme.Color(clrReplayModeJump), Theme.Color(clrBackground), cFont::GetFont(fontOsd), (x1 - x0) / 2, 0, taCenter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinClassicDisplayReplay::Flush(void)
|
||||||
|
{
|
||||||
|
osd->Flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- cSkinClassicDisplayVolume ---------------------------------------------
|
||||||
|
|
||||||
|
class cSkinClassicDisplayVolume : public cSkinDisplayVolume {
|
||||||
|
private:
|
||||||
|
cOsd *osd;
|
||||||
|
public:
|
||||||
|
cSkinClassicDisplayVolume(void);
|
||||||
|
virtual ~cSkinClassicDisplayVolume();
|
||||||
|
virtual void SetVolume(int Current, int Total, bool Mute);
|
||||||
|
virtual void Flush(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
cSkinClassicDisplayVolume::cSkinClassicDisplayVolume(void)
|
||||||
|
{
|
||||||
|
const cFont *font = cFont::GetFont(fontOsd);
|
||||||
|
int lineHeight = font->Height();
|
||||||
|
osd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop + Setup.OSDHeight - lineHeight);
|
||||||
|
tArea Areas[] = { { 0, 0, Setup.OSDWidth - 1, lineHeight - 1, 4 } };
|
||||||
|
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||||
|
}
|
||||||
|
|
||||||
|
cSkinClassicDisplayVolume::~cSkinClassicDisplayVolume()
|
||||||
|
{
|
||||||
|
delete osd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinClassicDisplayVolume::SetVolume(int Current, int Total, bool Mute)
|
||||||
|
{
|
||||||
|
const cFont *font = cFont::GetFont(fontOsd);
|
||||||
|
if (Mute) {
|
||||||
|
osd->DrawRectangle(0, 0, osd->Width() - 1, osd->Height() - 1, clrTransparent);
|
||||||
|
osd->DrawText(0, 0, tr("Mute"), Theme.Color(clrVolumePrompt), Theme.Color(clrBackground), font);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const char *Prompt = tr("Volume ");
|
||||||
|
int l = font->Width(Prompt);
|
||||||
|
int p = (osd->Width() - l) * Current / Total;
|
||||||
|
osd->DrawText(0, 0, Prompt, Theme.Color(clrVolumePrompt), Theme.Color(clrBackground), font);
|
||||||
|
osd->DrawRectangle(l, 0, l + p - 1, osd->Height() - 1, Theme.Color(clrVolumeBarLower));
|
||||||
|
osd->DrawRectangle(l + p, 0, osd->Width() - 1, osd->Height() - 1, Theme.Color(clrVolumeBarUpper));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinClassicDisplayVolume::Flush(void)
|
||||||
|
{
|
||||||
|
osd->Flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- cSkinClassicDisplayMessage --------------------------------------------
|
||||||
|
|
||||||
|
class cSkinClassicDisplayMessage : public cSkinDisplayMessage {
|
||||||
|
private:
|
||||||
|
cOsd *osd;
|
||||||
|
public:
|
||||||
|
cSkinClassicDisplayMessage(void);
|
||||||
|
virtual ~cSkinClassicDisplayMessage();
|
||||||
|
virtual void SetMessage(eMessageType Type, const char *Text);
|
||||||
|
virtual void Flush(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
cSkinClassicDisplayMessage::cSkinClassicDisplayMessage(void)
|
||||||
|
{
|
||||||
|
const cFont *font = cFont::GetFont(fontOsd);
|
||||||
|
int lineHeight = font->Height();
|
||||||
|
osd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop + Setup.OSDHeight - lineHeight);
|
||||||
|
tArea Areas[] = { { 0, 0, Setup.OSDWidth - 1, lineHeight - 1, 2 } };
|
||||||
|
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||||
|
}
|
||||||
|
|
||||||
|
cSkinClassicDisplayMessage::~cSkinClassicDisplayMessage()
|
||||||
|
{
|
||||||
|
delete osd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinClassicDisplayMessage::SetMessage(eMessageType Type, const char *Text)
|
||||||
|
{
|
||||||
|
const cFont *font = cFont::GetFont(fontOsd);
|
||||||
|
osd->DrawText(0, 0, Text, Theme.Color(clrMessageStatusFg + 2 * Type), Theme.Color(clrMessageStatusBg + 2 * Type), font, Setup.OSDWidth, 0, taCenter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinClassicDisplayMessage::Flush(void)
|
||||||
|
{
|
||||||
|
osd->Flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- cSkinClassic ----------------------------------------------------------
|
||||||
|
|
||||||
|
cSkinClassic::cSkinClassic(void)
|
||||||
|
:cSkin("classic", &::Theme)//XXX naming problem???
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *cSkinClassic::Description(void)
|
||||||
|
{
|
||||||
|
return tr("Classic VDR");
|
||||||
|
}
|
||||||
|
|
||||||
|
cSkinDisplayChannel *cSkinClassic::DisplayChannel(bool WithInfo)
|
||||||
|
{
|
||||||
|
return new cSkinClassicDisplayChannel(WithInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
cSkinDisplayMenu *cSkinClassic::DisplayMenu(void)
|
||||||
|
{
|
||||||
|
return new cSkinClassicDisplayMenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
cSkinDisplayReplay *cSkinClassic::DisplayReplay(bool ModeOnly)
|
||||||
|
{
|
||||||
|
return new cSkinClassicDisplayReplay(ModeOnly);
|
||||||
|
}
|
||||||
|
|
||||||
|
cSkinDisplayVolume *cSkinClassic::DisplayVolume(void)
|
||||||
|
{
|
||||||
|
return new cSkinClassicDisplayVolume;
|
||||||
|
}
|
||||||
|
|
||||||
|
cSkinDisplayMessage *cSkinClassic::DisplayMessage(void)
|
||||||
|
{
|
||||||
|
return new cSkinClassicDisplayMessage;
|
||||||
|
}
|
26
skinclassic.h
Normal file
26
skinclassic.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* skinclassic.h: The 'classic' VDR skin
|
||||||
|
*
|
||||||
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
|
* how to reach the author.
|
||||||
|
*
|
||||||
|
* $Id: skinclassic.h 1.1 2004/04/18 09:38:02 kls Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SKINCLASSIC_H
|
||||||
|
#define __SKINCLASSIC_H
|
||||||
|
|
||||||
|
#include "skins.h"
|
||||||
|
|
||||||
|
class cSkinClassic : public cSkin {
|
||||||
|
public:
|
||||||
|
cSkinClassic(void);
|
||||||
|
virtual const char *Description(void);
|
||||||
|
virtual cSkinDisplayChannel *DisplayChannel(bool WithInfo);
|
||||||
|
virtual cSkinDisplayMenu *DisplayMenu(void);
|
||||||
|
virtual cSkinDisplayReplay *DisplayReplay(bool ModeOnly);
|
||||||
|
virtual cSkinDisplayVolume *DisplayVolume(void);
|
||||||
|
virtual cSkinDisplayMessage *DisplayMessage(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //__SKINCLASSIC_H
|
201
skins.c
Normal file
201
skins.c
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
/*
|
||||||
|
* skins.c: The optical appearance of the OSD
|
||||||
|
*
|
||||||
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
|
* how to reach the author.
|
||||||
|
*
|
||||||
|
* $Id: skins.c 1.1 2004/05/15 12:34:38 kls Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "skins.h"
|
||||||
|
#include "interface.h"
|
||||||
|
#include "status.h"
|
||||||
|
#include "tools.h"
|
||||||
|
|
||||||
|
// --- cSkinDisplay ----------------------------------------------------------
|
||||||
|
|
||||||
|
cSkinDisplay *cSkinDisplay::current = NULL;
|
||||||
|
|
||||||
|
cSkinDisplay::cSkinDisplay(void)
|
||||||
|
{
|
||||||
|
current = this;
|
||||||
|
editableWidth = 100; //XXX
|
||||||
|
}
|
||||||
|
|
||||||
|
cSkinDisplay::~cSkinDisplay()
|
||||||
|
{
|
||||||
|
current = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- cSkinDisplayMenu ------------------------------------------------------
|
||||||
|
|
||||||
|
cSkinDisplayMenu::cSkinDisplayMenu(void)
|
||||||
|
{
|
||||||
|
SetTabs(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinDisplayMenu::SetTabs(int Tab1, int Tab2, int Tab3, int Tab4, int Tab5)
|
||||||
|
{
|
||||||
|
tabs[0] = 0;
|
||||||
|
tabs[1] = Tab1 ? tabs[0] + Tab1 : 0;
|
||||||
|
tabs[2] = Tab2 ? tabs[1] + Tab2 : 0;
|
||||||
|
tabs[3] = Tab3 ? tabs[2] + Tab3 : 0;
|
||||||
|
tabs[4] = Tab4 ? tabs[3] + Tab4 : 0;
|
||||||
|
tabs[5] = Tab5 ? tabs[4] + Tab5 : 0;
|
||||||
|
for (int i = 1; i < MaxTabs; i++)
|
||||||
|
tabs[i] *= 12;//XXX average character width of font used for items!!!
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinDisplayMenu::Scroll(bool Up, bool Page)
|
||||||
|
{
|
||||||
|
textScroller.Scroll(Up, Page);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *cSkinDisplayMenu::GetTabbedText(const char *s, int Tab)
|
||||||
|
{
|
||||||
|
if (!s)
|
||||||
|
return NULL;
|
||||||
|
static char buffer[1000];
|
||||||
|
const char *a = s;
|
||||||
|
const char *b = strchrnul(a, '\t');
|
||||||
|
while (*b && Tab-- > 0) {
|
||||||
|
a = b + 1;
|
||||||
|
b = strchrnul(a, '\t');
|
||||||
|
}
|
||||||
|
if (!*b)
|
||||||
|
return (Tab <= 0) ? a : NULL;
|
||||||
|
unsigned int n = b - a;
|
||||||
|
if (n >= sizeof(buffer))
|
||||||
|
n = sizeof(buffer) - 1;
|
||||||
|
strncpy(buffer, a, n);
|
||||||
|
buffer[n] = 0;
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- cSkinDisplayReplay::cProgressBar --------------------------------------
|
||||||
|
|
||||||
|
cSkinDisplayReplay::cProgressBar::cProgressBar(int Width, int Height, int Current, int Total, const cMarks *Marks, tColor ColorSeen, tColor ColorRest, tColor ColorSelected, tColor ColorMark, tColor ColorCurrent)
|
||||||
|
:cBitmap(Width, Height, 2)
|
||||||
|
{
|
||||||
|
total = Total;
|
||||||
|
if (total > 0) {
|
||||||
|
int p = Pos(Current);
|
||||||
|
DrawRectangle(0, 0, p, Height - 1, ColorSeen);
|
||||||
|
DrawRectangle(p + 1, 0, Width - 1, Height - 1, ColorRest);
|
||||||
|
if (Marks) {
|
||||||
|
bool Start = true;
|
||||||
|
for (const cMark *m = Marks->First(); m; m = Marks->Next(m)) {
|
||||||
|
int p1 = Pos(m->position);
|
||||||
|
if (Start) {
|
||||||
|
const cMark *m2 = Marks->Next(m);
|
||||||
|
int p2 = Pos(m2 ? m2->position : total);
|
||||||
|
int h = Height / 3;
|
||||||
|
DrawRectangle(p1, h, p2, Height - h, ColorSelected);
|
||||||
|
}
|
||||||
|
Mark(p1, Start, m->position == Current, ColorMark, ColorCurrent);
|
||||||
|
Start = !Start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinDisplayReplay::cProgressBar::Mark(int x, bool Start, bool Current, tColor ColorMark, tColor ColorCurrent)
|
||||||
|
{
|
||||||
|
DrawRectangle(x, 0, x, Height() - 1, ColorMark);
|
||||||
|
const int d = Height() / (Current ? 3 : 9);
|
||||||
|
for (int i = 0; i < d; i++) {
|
||||||
|
int h = Start ? i : Height() - 1 - i;
|
||||||
|
DrawRectangle(x - d + i, h, x + d - i, h, Current ? ColorCurrent : ColorMark);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- cSkinDisplayReplay ----------------------------------------------------
|
||||||
|
|
||||||
|
cSkinDisplayReplay::cSkinDisplayReplay(void)
|
||||||
|
{
|
||||||
|
marks = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinDisplayReplay::SetMarks(const cMarks *Marks)
|
||||||
|
{
|
||||||
|
marks = Marks;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- cSkin -----------------------------------------------------------------
|
||||||
|
|
||||||
|
cSkin::cSkin(const char *Name, cTheme *Theme)
|
||||||
|
{
|
||||||
|
name = strdup(Name);
|
||||||
|
theme = Theme;
|
||||||
|
if (theme)
|
||||||
|
cThemes::Save(name, theme);
|
||||||
|
Skins.Add(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
cSkin::~cSkin()
|
||||||
|
{
|
||||||
|
free(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- cSkins ----------------------------------------------------------------
|
||||||
|
|
||||||
|
cSkins Skins;
|
||||||
|
|
||||||
|
cSkins::cSkins(void)
|
||||||
|
{
|
||||||
|
displayMessage = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
cSkins::~cSkins()
|
||||||
|
{
|
||||||
|
delete displayMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cSkins::SetCurrent(const char *Name)
|
||||||
|
{
|
||||||
|
if (Name) {
|
||||||
|
for (cSkin *Skin = First(); Skin; Skin = Next(Skin)) {
|
||||||
|
if (strcmp(Skin->Name(), Name) == 0) {
|
||||||
|
current = Skin;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
current = First();
|
||||||
|
return current != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
eKeys cSkins::Message(eMessageType Type, const char *s, int Seconds)
|
||||||
|
{
|
||||||
|
switch (Type) {
|
||||||
|
case mtInfo: isyslog("info: %s", s); break;
|
||||||
|
case mtError: esyslog("ERROR: %s", s); break;
|
||||||
|
default: ;
|
||||||
|
}
|
||||||
|
if (!cSkinDisplay::Current() && !displayMessage)
|
||||||
|
displayMessage = Current()->DisplayMessage();
|
||||||
|
cSkinDisplay::Current()->SetMessage(Type, s);
|
||||||
|
cSkinDisplay::Current()->Flush();
|
||||||
|
cStatus::MsgOsdStatusMessage(s);
|
||||||
|
eKeys k = kNone;
|
||||||
|
if (Type != mtStatus) {
|
||||||
|
k = Interface->Wait(Seconds);
|
||||||
|
if (displayMessage) {
|
||||||
|
delete displayMessage;
|
||||||
|
displayMessage = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cSkinDisplay::Current()->SetMessage(Type, NULL);
|
||||||
|
}
|
||||||
|
else if (!s && displayMessage) {
|
||||||
|
delete displayMessage;
|
||||||
|
displayMessage = NULL;
|
||||||
|
}
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkins::Flush(void)
|
||||||
|
{
|
||||||
|
if (cSkinDisplay::Current())
|
||||||
|
cSkinDisplay::Current()->Flush();
|
||||||
|
}
|
297
skins.h
Normal file
297
skins.h
Normal file
@ -0,0 +1,297 @@
|
|||||||
|
/*
|
||||||
|
* skins.h: The optical appearance of the OSD
|
||||||
|
*
|
||||||
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
|
* how to reach the author.
|
||||||
|
*
|
||||||
|
* $Id: skins.h 1.1 2004/05/16 09:40:18 kls Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SKINS_H
|
||||||
|
#define __SKINS_H
|
||||||
|
|
||||||
|
#include "channels.h"
|
||||||
|
#include "epg.h"
|
||||||
|
#include "keys.h"
|
||||||
|
#include "osd.h"
|
||||||
|
#include "recording.h"
|
||||||
|
#include "themes.h"
|
||||||
|
#include "tools.h"
|
||||||
|
|
||||||
|
enum eMessageType { mtStatus = 0, mtInfo, mtWarning, mtError }; // will be used to calculate color offsets!
|
||||||
|
|
||||||
|
class cSkinDisplay {
|
||||||
|
private:
|
||||||
|
static cSkinDisplay *current;
|
||||||
|
int editableWidth; //XXX this is not nice, but how else could we know this value?
|
||||||
|
public:
|
||||||
|
cSkinDisplay(void);
|
||||||
|
virtual ~cSkinDisplay();
|
||||||
|
int EditableWidth(void) { return editableWidth; }
|
||||||
|
void SetEditableWidth(int Width) { editableWidth = Width; }
|
||||||
|
///< If an item is set through a call to cSkinDisplayMenu::SetItem(), this
|
||||||
|
///< function shall be called to set the width of the rightmost tab separated
|
||||||
|
///< field. This information will be used for editable items.
|
||||||
|
virtual void SetButtons(const char *Red, const char *Green = NULL, const char *Yellow = NULL, const char *Blue = NULL) {}
|
||||||
|
///< Sets the color buttons to the given strings, provided this cSkinDisplay
|
||||||
|
///< actually has a color button display.
|
||||||
|
virtual void SetMessage(eMessageType Type, const char *Text) {}
|
||||||
|
///< Sets a one line message Text, with the given Type. Type can be used
|
||||||
|
///< to determine, e.g., the colors for displaying the Text.
|
||||||
|
virtual void Flush(void) {}
|
||||||
|
///< Actually draws the OSD display to the output device.
|
||||||
|
static cSkinDisplay *Current(void) { return current; }
|
||||||
|
///< Returns the currently active cSkinDisplay.
|
||||||
|
};
|
||||||
|
|
||||||
|
class cSkinDisplayChannel : public cSkinDisplay {
|
||||||
|
///< This class is used to display the current channel, together with
|
||||||
|
///< the present and following EPG even. How and to what extent this
|
||||||
|
///< is done is totally up to the derived class.
|
||||||
|
public:
|
||||||
|
virtual void SetChannel(const cChannel *Channel, int Number) = 0;
|
||||||
|
///< Sets the current channel to Channel. If Number is not 0, the
|
||||||
|
///< user is in the process of entering a channel number, which must
|
||||||
|
///< be displayed accordingly.
|
||||||
|
virtual void SetEvents(const cEvent *Present, const cEvent *Following) = 0;
|
||||||
|
///< Sets the Present and Following EPG events. It either of these
|
||||||
|
///< is not available, NULL will be given.
|
||||||
|
/*TODO
|
||||||
|
SetButtons
|
||||||
|
Red = Video options
|
||||||
|
Green = Info now
|
||||||
|
Yellow = Info next
|
||||||
|
Blue = Audio options
|
||||||
|
AudioOptions
|
||||||
|
VideoOptions
|
||||||
|
*/
|
||||||
|
};
|
||||||
|
|
||||||
|
class cSkinDisplayMenu : public cSkinDisplay {
|
||||||
|
///< This class implements the general purpose menu display, which is
|
||||||
|
///< used throughout the program to display information and let the
|
||||||
|
///< user interact with items.
|
||||||
|
///< A menu consists of the following fields, each of which is explicitly
|
||||||
|
///< set by calls to the member functions below:
|
||||||
|
///< - Title: a single line of text, indicating what this menu displays
|
||||||
|
///< - Color buttons: the red, green, yellow and blue buttons, used for
|
||||||
|
///< various functions
|
||||||
|
///< - Message: a one line message, indicating a Status, Info, Warning,
|
||||||
|
///< or Error condition
|
||||||
|
///< - Central area: the main central area of the menu, used to display
|
||||||
|
///< one of the following:
|
||||||
|
///< - Items: a list of single line items, of which the user may be
|
||||||
|
///< able to select one
|
||||||
|
///< - Event: the full information about one EPG event
|
||||||
|
///< - Text: a multi line, scrollable text
|
||||||
|
public:
|
||||||
|
enum { MaxTabs = 6 };
|
||||||
|
private:
|
||||||
|
int tabs[MaxTabs];
|
||||||
|
protected:
|
||||||
|
cTextScroller textScroller;
|
||||||
|
int Tab(int n) { return (n >= 0 && n < MaxTabs) ? tabs[n] : 0; }
|
||||||
|
///< Returns the offset of the given tab from the left border of the
|
||||||
|
///< item display area. The value returned is in pixel.//XXX ncurses???
|
||||||
|
const char *GetTabbedText(const char *s, int Tab);
|
||||||
|
///< Returns the that part of the given string, that follows the given
|
||||||
|
///< Tab (where 0 indicates the beginning of the string). If no such
|
||||||
|
///< part can be found, NULL will be returned.
|
||||||
|
public:
|
||||||
|
cSkinDisplayMenu(void);
|
||||||
|
virtual void SetTabs(int Tab1, int Tab2 = 0, int Tab3 = 0, int Tab4 = 0, int Tab5 = 0);
|
||||||
|
///< Sets the tab columns to the given values, which are the number of
|
||||||
|
///< characters in each column.//XXX ncurses???
|
||||||
|
virtual void Scroll(bool Up, bool Page);
|
||||||
|
///< If this menu contains a text area that can be scrolled, this function
|
||||||
|
///< will be called to actually scroll the text. Up indicates whether the
|
||||||
|
///< text shall be scrolled up or down, and Page is true if it shall be
|
||||||
|
///< scrolled by a full page, rather than a single line. An object of the
|
||||||
|
///< cTextScroller class can be used to implement the scrolling text area.
|
||||||
|
virtual int MaxItems(void) = 0;
|
||||||
|
///< Returns the maximum number of items the menu can display.
|
||||||
|
virtual void Clear(void) = 0;
|
||||||
|
///< Clears the entire central area of the menu.
|
||||||
|
virtual void SetTitle(const char *Title) = 0;
|
||||||
|
///< Sets the title of this menu to Title.
|
||||||
|
virtual void SetButtons(const char *Red, const char *Green = NULL, const char *Yellow = NULL, const char *Blue = NULL) = 0;
|
||||||
|
///< Sets the color buttons to the given strings. If any of the values is
|
||||||
|
///< NULL, any previous text must be removed from the related button.
|
||||||
|
virtual void SetMessage(eMessageType Type, const char *Text) = 0;
|
||||||
|
///< Sets a one line message Text, with the given Type. Type can be used
|
||||||
|
///< to determine, e.g., the colors for displaying the Text.
|
||||||
|
///< If Text is NULL, any previously displayed message must be removed, and
|
||||||
|
///< any previous contents overwritten by the message must be restored.
|
||||||
|
virtual void SetItem(const char *Text, int Index, bool Current, bool Selectable) = 0;
|
||||||
|
///< Sets the item at the given Index to Text. Index is between 0 and the
|
||||||
|
///< value returned by MaxItems(), minus one. Text may contain tab characters ('\t'),
|
||||||
|
///< which shall be used to separate the text into several columns, according to the
|
||||||
|
///< values set by a prior call to SetTabs(). If Current is true, this item shall
|
||||||
|
///< be drawn in a way indicating to the user that it is the currently selected
|
||||||
|
///< one. Selectable can be used to display items differently that can't be
|
||||||
|
///< selected by the user.
|
||||||
|
///< Whenever the current status is moved from one item to another,
|
||||||
|
///< this function will be first called for the old current item
|
||||||
|
///< with Current set to false, and then for the new current item
|
||||||
|
///< with Current set to true.
|
||||||
|
/*TODO
|
||||||
|
virtual void SetItem(const cEvent *Event, int Index, bool Current, bool Selectable, bool NowNext???, bool Schedule???);
|
||||||
|
virtual void SetItem(const cTimer *Timer, int Index, bool Current, bool Selectable);
|
||||||
|
virtual void SetItem(const cChannel *Channel, int Index, bool Current, bool Selectable);
|
||||||
|
virtual void SetItem(const cRecording *Recording, int Index, bool Current, bool Selectable);
|
||||||
|
--> false: call SetItem(text)
|
||||||
|
*/
|
||||||
|
virtual void SetEvent(const cEvent *Event) = 0;
|
||||||
|
///< Sets the Event that shall be displayed, using the entire central area
|
||||||
|
///< of the menu. The Event's 'description' shall be displayed using a
|
||||||
|
///< cTextScroller, and the Scroll() function will be called to drive scrolling
|
||||||
|
///< that text if necessary.
|
||||||
|
virtual void SetRecording(const cRecording *Recording) = 0;
|
||||||
|
///< Sets the Recording that shall be displayed, using the entire central area
|
||||||
|
///< of the menu. The Recording's 'summary' shall be displayed using a
|
||||||
|
///< cTextScroller, and the Scroll() function will be called to drive scrolling
|
||||||
|
///< that text if necessary.
|
||||||
|
virtual void SetText(const char *Text, bool FixedFont) = 0;
|
||||||
|
///< Sets the Text that shall be displayed, using the entire central area
|
||||||
|
///< of the menu. The Text shall be displayed using a cTextScroller, and
|
||||||
|
///< the Scroll() function will be called to drive scrolling that text if
|
||||||
|
///< necessary.
|
||||||
|
//XXX ??? virtual void SetHelp(const char *Help) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class cSkinDisplayReplay : public cSkinDisplay {
|
||||||
|
///< This class implements the progress display used during replay of
|
||||||
|
///< a recording.
|
||||||
|
protected:
|
||||||
|
const cMarks *marks;
|
||||||
|
class cProgressBar : public cBitmap {
|
||||||
|
protected:
|
||||||
|
int total;
|
||||||
|
int Pos(int p) { return p * Width() / total; }
|
||||||
|
void Mark(int x, bool Start, bool Current, tColor ColorMark, tColor ColorCurrent);
|
||||||
|
public:
|
||||||
|
cProgressBar(int Width, int Height, int Current, int Total, const cMarks *Marks, tColor ColorSeen, tColor ColorRest, tColor ColorSelected, tColor ColorMark, tColor ColorCurrent);
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
cSkinDisplayReplay(void);
|
||||||
|
virtual void SetMarks(const cMarks *Marks);
|
||||||
|
///< Sets the editing marks to Marks, which shall be used to display the
|
||||||
|
///< progress bar through a cProgressBar object.
|
||||||
|
virtual void SetTitle(const char *Title) = 0;
|
||||||
|
///< Sets the title of the recording.
|
||||||
|
virtual void SetMode(bool Play, bool Forward, int Speed) = 0;
|
||||||
|
///< Sets the current replay mode, which can be used to display some
|
||||||
|
///< indicator, showing the user whether we are currently in normal
|
||||||
|
///< play mode, fast forward etc.
|
||||||
|
virtual void SetProgress(int Current, int Total) = 0;
|
||||||
|
///< This function will be called whenever the position in of the total
|
||||||
|
///< length of the recording has changed. A cProgressBar shall then be
|
||||||
|
///< used to display a progress indicator.
|
||||||
|
virtual void SetCurrent(const char *Current) = 0;
|
||||||
|
///< Sets the current position within the recording, as a user readable
|
||||||
|
///< string if the form "h:mm:ss.ff". The ".ff" part, indicating the
|
||||||
|
///< frame number, is optional and the actual implementation needs to
|
||||||
|
///< take care that it is erased from the display when a Current string
|
||||||
|
///< _with_ ".ff" is followed by one without it.
|
||||||
|
virtual void SetTotal(const char *Total) = 0;
|
||||||
|
///< Sets the total length of the recording, as a user readable
|
||||||
|
///< string if the form "h:mm:ss".
|
||||||
|
virtual void SetJump(const char *Jump) = 0;
|
||||||
|
///< Sets the prompt that allows the user to enter a jump point.
|
||||||
|
///< Jump is a string of the form "Jump: mm:ss". The actual implementation
|
||||||
|
///< needs to be able to handle variations in the length of this
|
||||||
|
///< string, which will occur when the user enters an actual value.
|
||||||
|
///< If Jump is NULL, the jump prompt shall be removed from the display.
|
||||||
|
};
|
||||||
|
|
||||||
|
class cSkinDisplayVolume : public cSkinDisplay {
|
||||||
|
///< This class implements the volume/mute display.
|
||||||
|
public:
|
||||||
|
virtual void SetVolume(int Current, int Total, bool Mute) = 0;
|
||||||
|
///< Sets the volume to the given Current value, which is in the range
|
||||||
|
///< 0...Total. If Mute is true, audio is currently muted and a "mute"
|
||||||
|
///< indicator shall be displayed.
|
||||||
|
};
|
||||||
|
|
||||||
|
class cSkinDisplayMessage : public cSkinDisplay {
|
||||||
|
///< This class implements a simple message display.
|
||||||
|
public:
|
||||||
|
virtual void SetMessage(eMessageType Type, const char *Text) = 0;
|
||||||
|
///< Sets the message to Text. Type can be used to decide how to display
|
||||||
|
///< the message, for instance in which colors.
|
||||||
|
};
|
||||||
|
|
||||||
|
class cSkin : public cListObject {
|
||||||
|
private:
|
||||||
|
char *name;
|
||||||
|
cTheme *theme;
|
||||||
|
public:
|
||||||
|
cSkin(const char *Name, cTheme *Theme = NULL);
|
||||||
|
///< Creates a new skin class, with the given Name and Theme.
|
||||||
|
///< Name will be used to identify this skin in the 'setup.conf'
|
||||||
|
///< file, and is normally not seen by the user. It should
|
||||||
|
///< consist of only lowercase letters and digits.
|
||||||
|
///< Theme must be a static object that survives the entire lifetime
|
||||||
|
///< of this skin.
|
||||||
|
///< The constructor of a derived class shall not set up any data
|
||||||
|
///< structures yet, because whether or not this skin will actually
|
||||||
|
///< be used is not yet known at this point. All actual work shall
|
||||||
|
///< be done in the pure functions below.
|
||||||
|
///< A cSkin object must be created on the heap and shall not be
|
||||||
|
///< explicitly deleted.
|
||||||
|
virtual ~cSkin();
|
||||||
|
const char *Name(void) { return name; }
|
||||||
|
cTheme *Theme(void) { return theme; }
|
||||||
|
virtual const char *Description(void) = 0;
|
||||||
|
///< Returns a user visible, single line description of this skin,
|
||||||
|
///< which may consist of arbitrary text and can, if the skin
|
||||||
|
///< implementation wishes to do so, be internationalized.
|
||||||
|
///< The actual text shouldn't be too long, so that it can be
|
||||||
|
///< fully displayed in the Setup/OSD menu.
|
||||||
|
virtual cSkinDisplayChannel *DisplayChannel(bool WithInfo) = 0;
|
||||||
|
///< Creates and returns a new object for displaying the current
|
||||||
|
///< channel. WithInfo indicates whether it shall display only
|
||||||
|
///< the basic channel data, or also information about the present
|
||||||
|
///< and following EPG event.
|
||||||
|
///< The caller must delete the object after use.
|
||||||
|
virtual cSkinDisplayMenu *DisplayMenu(void) = 0;
|
||||||
|
///< Creates and returns a new object for displaying a menu.
|
||||||
|
///< The caller must delete the object after use.
|
||||||
|
virtual cSkinDisplayReplay *DisplayReplay(bool ModeOnly) = 0;
|
||||||
|
///< Creates and returns a new object for displaying replay progress.
|
||||||
|
///< ModeOnly indicates whether this should be a full featured replay
|
||||||
|
///< display, or just a replay mode indicator.
|
||||||
|
///< The caller must delete the object after use.
|
||||||
|
virtual cSkinDisplayVolume *DisplayVolume(void) = 0;
|
||||||
|
///< Creates and returns a new object for displaying the current volume.
|
||||||
|
///< The caller must delete the object after use.
|
||||||
|
virtual cSkinDisplayMessage *DisplayMessage(void) = 0;
|
||||||
|
///< Creates and returns a new object for displaying a message.
|
||||||
|
///< The caller must delete the object after use.
|
||||||
|
};
|
||||||
|
|
||||||
|
class cSkins : public cList<cSkin> {
|
||||||
|
private:
|
||||||
|
cSkin *current;
|
||||||
|
cSkinDisplayMessage *displayMessage;
|
||||||
|
public:
|
||||||
|
cSkins(void);
|
||||||
|
~cSkins();
|
||||||
|
bool SetCurrent(const char *Name = NULL);
|
||||||
|
///< Sets the current skin to the one indicated by name.
|
||||||
|
///< If no such skin can be found, the first one will be used.
|
||||||
|
cSkin *Current(void) { return current; }
|
||||||
|
///< Returns a pointer to the current skin.
|
||||||
|
bool IsOpen(void) { return cSkinDisplay::Current(); }
|
||||||
|
///< Returns true if there is currently a skin display object active.
|
||||||
|
eKeys Message(eMessageType Type, const char *s, int Seconds = 0);
|
||||||
|
///< Displays the given message, either through a currently visible
|
||||||
|
///< display object that is capable of doing so, or by creating a
|
||||||
|
///< temporary cSkinDisplayMessage object.
|
||||||
|
void Flush(void);
|
||||||
|
///< Flushes the currently active cSkinDisplay, if any.
|
||||||
|
};
|
||||||
|
|
||||||
|
extern cSkins Skins;
|
||||||
|
|
||||||
|
#endif //__SKINS_H
|
879
skinsttng.c
Normal file
879
skinsttng.c
Normal file
@ -0,0 +1,879 @@
|
|||||||
|
/*
|
||||||
|
* skinsttng.c: A VDR skin with ST:TNG Panels
|
||||||
|
*
|
||||||
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
|
* how to reach the author.
|
||||||
|
*
|
||||||
|
* $Id: skinsttng.c 1.1 2004/05/16 09:27:35 kls Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Star Trek: The Next Generation® is a registered trademark of Paramount Pictures
|
||||||
|
// registered in the United States Patent and Trademark Office.
|
||||||
|
// No infringement intended.
|
||||||
|
|
||||||
|
#include "skinsttng.h"
|
||||||
|
#include "font.h"
|
||||||
|
#include "osd.h"
|
||||||
|
#include "menu.h"
|
||||||
|
#include "themes.h"
|
||||||
|
|
||||||
|
#include "symbols/arrowdown.xpm"
|
||||||
|
#include "symbols/arrowup.xpm"
|
||||||
|
#include "symbols/audio.xpm"
|
||||||
|
#include "symbols/dolbydigital.xpm"
|
||||||
|
#include "symbols/encrypted.xpm"
|
||||||
|
#include "symbols/ffwd.xpm"
|
||||||
|
#include "symbols/ffwd1.xpm"
|
||||||
|
#include "symbols/ffwd2.xpm"
|
||||||
|
#include "symbols/ffwd3.xpm"
|
||||||
|
#include "symbols/frew.xpm"
|
||||||
|
#include "symbols/frew1.xpm"
|
||||||
|
#include "symbols/frew2.xpm"
|
||||||
|
#include "symbols/frew3.xpm"
|
||||||
|
#include "symbols/mute.xpm"
|
||||||
|
#include "symbols/pause.xpm"
|
||||||
|
#include "symbols/play.xpm"
|
||||||
|
#include "symbols/radio.xpm"
|
||||||
|
#include "symbols/recording.xpm"
|
||||||
|
#include "symbols/sfwd.xpm"
|
||||||
|
#include "symbols/sfwd1.xpm"
|
||||||
|
#include "symbols/sfwd2.xpm"
|
||||||
|
#include "symbols/sfwd3.xpm"
|
||||||
|
#include "symbols/srew.xpm"
|
||||||
|
#include "symbols/srew1.xpm"
|
||||||
|
#include "symbols/srew2.xpm"
|
||||||
|
#include "symbols/srew3.xpm"
|
||||||
|
#include "symbols/teletext.xpm"
|
||||||
|
#include "symbols/volume.xpm"
|
||||||
|
|
||||||
|
#define Roundness 10
|
||||||
|
#define Gap 5
|
||||||
|
#define ScrollWidth 5
|
||||||
|
|
||||||
|
static cTheme Theme;
|
||||||
|
|
||||||
|
THEME_CLR(Theme, clrBackground, clrGray50);
|
||||||
|
THEME_CLR(Theme, clrButtonRedFg, clrWhite);
|
||||||
|
THEME_CLR(Theme, clrButtonRedBg, clrRed);
|
||||||
|
THEME_CLR(Theme, clrButtonGreenFg, clrBlack);
|
||||||
|
THEME_CLR(Theme, clrButtonGreenBg, clrGreen);
|
||||||
|
THEME_CLR(Theme, clrButtonYellowFg, clrBlack);
|
||||||
|
THEME_CLR(Theme, clrButtonYellowBg, clrYellow);
|
||||||
|
THEME_CLR(Theme, clrButtonBlueFg, clrWhite);
|
||||||
|
THEME_CLR(Theme, clrButtonBlueBg, clrBlue);
|
||||||
|
THEME_CLR(Theme, clrMessageFrame, clrYellow);
|
||||||
|
THEME_CLR(Theme, clrMessageStatusFg, clrBlack);
|
||||||
|
THEME_CLR(Theme, clrMessageStatusBg, clrCyan);
|
||||||
|
THEME_CLR(Theme, clrMessageInfoFg, clrBlack);
|
||||||
|
THEME_CLR(Theme, clrMessageInfoBg, clrGreen);
|
||||||
|
THEME_CLR(Theme, clrMessageWarningFg, clrBlack);
|
||||||
|
THEME_CLR(Theme, clrMessageWarningBg, clrYellow);
|
||||||
|
THEME_CLR(Theme, clrMessageErrorFg, clrWhite);
|
||||||
|
THEME_CLR(Theme, clrMessageErrorBg, clrRed);
|
||||||
|
THEME_CLR(Theme, clrVolumeFrame, clrYellow);
|
||||||
|
THEME_CLR(Theme, clrVolumeSymbol, clrBlack);
|
||||||
|
THEME_CLR(Theme, clrVolumeBarUpper, 0xFFBC8024);
|
||||||
|
THEME_CLR(Theme, clrVolumeBarLower, 0xFF248024);
|
||||||
|
THEME_CLR(Theme, clrChannelFrame, clrYellow);
|
||||||
|
THEME_CLR(Theme, clrChannelName, clrBlack);
|
||||||
|
THEME_CLR(Theme, clrChannelDate, clrBlack);
|
||||||
|
THEME_CLR(Theme, clrChannelSymbolOn, clrBlack);
|
||||||
|
THEME_CLR(Theme, clrChannelSymbolOff, 0xFFBC8024);
|
||||||
|
THEME_CLR(Theme, clrChannelSymbolRecFg, clrWhite);
|
||||||
|
THEME_CLR(Theme, clrChannelSymbolRecBg, clrRed);
|
||||||
|
THEME_CLR(Theme, clrChannelEpgTime, clrBlack);
|
||||||
|
THEME_CLR(Theme, clrChannelEpgTitle, clrCyan);
|
||||||
|
THEME_CLR(Theme, clrChannelEpgShortText, clrYellow);
|
||||||
|
THEME_CLR(Theme, clrChannelTimebarSeen, clrYellow);
|
||||||
|
THEME_CLR(Theme, clrChannelTimebarRest, clrGray50);
|
||||||
|
THEME_CLR(Theme, clrMenuFrame, clrYellow);
|
||||||
|
THEME_CLR(Theme, clrMenuTitle, clrBlack);
|
||||||
|
THEME_CLR(Theme, clrMenuDate, clrBlack);
|
||||||
|
THEME_CLR(Theme, clrMenuItemCurrentFg, clrBlack);
|
||||||
|
THEME_CLR(Theme, clrMenuItemCurrentBg, clrYellow);
|
||||||
|
THEME_CLR(Theme, clrMenuItemSelectable, clrYellow);
|
||||||
|
THEME_CLR(Theme, clrMenuItemNonSelectable, clrCyan);
|
||||||
|
THEME_CLR(Theme, clrMenuEventTime, clrYellow);
|
||||||
|
THEME_CLR(Theme, clrMenuEventVps, clrBlack);
|
||||||
|
THEME_CLR(Theme, clrMenuEventTitle, clrCyan);
|
||||||
|
THEME_CLR(Theme, clrMenuEventShortText, clrYellow);
|
||||||
|
THEME_CLR(Theme, clrMenuEventDescription, clrCyan);
|
||||||
|
THEME_CLR(Theme, clrMenuScrollbarTotal, clrYellow);
|
||||||
|
THEME_CLR(Theme, clrMenuScrollbarShown, clrCyan);
|
||||||
|
THEME_CLR(Theme, clrMenuScrollbarArrow, clrBlack);
|
||||||
|
THEME_CLR(Theme, clrMenuText, clrCyan);
|
||||||
|
THEME_CLR(Theme, clrReplayFrame, clrYellow);
|
||||||
|
THEME_CLR(Theme, clrReplayTitle, clrBlack);
|
||||||
|
THEME_CLR(Theme, clrReplayMode, clrBlack);
|
||||||
|
THEME_CLR(Theme, clrReplayCurrent, clrBlack);
|
||||||
|
THEME_CLR(Theme, clrReplayTotal, clrBlack);
|
||||||
|
THEME_CLR(Theme, clrReplayJump, clrBlack);
|
||||||
|
THEME_CLR(Theme, clrReplayProgressSeen, clrGreen);
|
||||||
|
THEME_CLR(Theme, clrReplayProgressRest, clrWhite);
|
||||||
|
THEME_CLR(Theme, clrReplayProgressSelected, clrRed);
|
||||||
|
THEME_CLR(Theme, clrReplayProgressMark, clrBlack);
|
||||||
|
THEME_CLR(Theme, clrReplayProgressCurrent, clrRed);
|
||||||
|
|
||||||
|
// --- cSkinSTTNGDisplayChannel ----------------------------------------------
|
||||||
|
|
||||||
|
class cSkinSTTNGDisplayChannel : public cSkinDisplayChannel{
|
||||||
|
private:
|
||||||
|
cOsd *osd;
|
||||||
|
int x0, x1, x2, x3, x4, x5, x6, x7;
|
||||||
|
int y0, y1, y2, y3, y4, y5, y6, y7;
|
||||||
|
bool withInfo;
|
||||||
|
int lineHeight;
|
||||||
|
tColor frameColor;
|
||||||
|
const cEvent *present;
|
||||||
|
int lastSeen;
|
||||||
|
static cBitmap bmTeletext, bmRadio, bmAudio, bmDolbyDigital, bmEncrypted, bmRecording;
|
||||||
|
public:
|
||||||
|
cSkinSTTNGDisplayChannel(bool WithInfo);
|
||||||
|
virtual ~cSkinSTTNGDisplayChannel();
|
||||||
|
virtual void SetChannel(const cChannel *Channel, int Number);
|
||||||
|
virtual void SetEvents(const cEvent *Present, const cEvent *Following);
|
||||||
|
virtual void Flush(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
cBitmap cSkinSTTNGDisplayChannel::bmTeletext(teletext_xpm);
|
||||||
|
cBitmap cSkinSTTNGDisplayChannel::bmRadio(radio_xpm);
|
||||||
|
cBitmap cSkinSTTNGDisplayChannel::bmAudio(audio_xpm);
|
||||||
|
cBitmap cSkinSTTNGDisplayChannel::bmDolbyDigital(dolbydigital_xpm);
|
||||||
|
cBitmap cSkinSTTNGDisplayChannel::bmEncrypted(encrypted_xpm);
|
||||||
|
cBitmap cSkinSTTNGDisplayChannel::bmRecording(recording_xpm);
|
||||||
|
|
||||||
|
cSkinSTTNGDisplayChannel::cSkinSTTNGDisplayChannel(bool WithInfo)
|
||||||
|
{
|
||||||
|
present = NULL;
|
||||||
|
lastSeen = -1;
|
||||||
|
const cFont *font = cFont::GetFont(fontOsd);
|
||||||
|
withInfo = WithInfo;
|
||||||
|
lineHeight = font->Height();
|
||||||
|
frameColor = Theme.Color(clrChannelFrame);
|
||||||
|
if (withInfo) {
|
||||||
|
x0 = 0;
|
||||||
|
x1 = x0 + font->Width("00:00") + 4;
|
||||||
|
x2 = x1 + Roundness;
|
||||||
|
x3 = x2 + Gap;
|
||||||
|
x7 = Setup.OSDWidth;
|
||||||
|
x6 = x7 - lineHeight / 2;
|
||||||
|
x5 = x6 - lineHeight / 2;
|
||||||
|
x4 = x5 - Gap;
|
||||||
|
y0 = 0;
|
||||||
|
y1 = lineHeight;
|
||||||
|
y2 = y1 + Roundness;
|
||||||
|
y3 = y2 + Gap;
|
||||||
|
y4 = y3 + 4 * lineHeight;
|
||||||
|
y5 = y4 + Gap;
|
||||||
|
y6 = y5 + Roundness;
|
||||||
|
y7 = y6 + cFont::GetFont(fontSml)->Height();
|
||||||
|
int yt = (y0 + y1) / 2;
|
||||||
|
int yb = (y6 + y7) / 2;
|
||||||
|
osd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop + (Setup.ChannelInfoPos ? 0 : Setup.OSDHeight - y7));
|
||||||
|
tArea Areas[] = { { 0, 0, x7 - 1, y7 - 1, 4 } };
|
||||||
|
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||||
|
osd->DrawRectangle(x0, y0, x7 - 1, y7 - 1, Theme.Color(clrBackground));
|
||||||
|
osd->DrawRectangle(x0, y0, x1 - 1, y1 - 1, clrTransparent);
|
||||||
|
osd->DrawRectangle(x0, y6, x1 - 1, y7 - 1, clrTransparent);
|
||||||
|
osd->DrawRectangle(x6, y0, x7 - 1, yt - 1, clrTransparent);
|
||||||
|
osd->DrawRectangle(x6, yb, x7 - 1, y7 - 1, clrTransparent);
|
||||||
|
osd->DrawEllipse (x0, y0, x1 - 1, y1 - 1, frameColor, 2);
|
||||||
|
osd->DrawRectangle(x1, y0, x4 - 1, y1 - 1, frameColor);
|
||||||
|
osd->DrawRectangle(x5, y0, x6 - 1, y1 - 1, frameColor);
|
||||||
|
osd->DrawEllipse (x6, y0, x7 - 1, y1 - 1, frameColor, 5);
|
||||||
|
osd->DrawRectangle(x0, y1, x1 - 1, y2 - 1, frameColor);
|
||||||
|
osd->DrawEllipse (x1, y1, x2 - 1, y2 - 1, frameColor, -2);
|
||||||
|
osd->DrawRectangle(x0, y3, x1 - 1, y4 - 1, frameColor);
|
||||||
|
osd->DrawRectangle(x0, y5, x1 - 1, y6 - 1, frameColor);
|
||||||
|
osd->DrawEllipse (x1, y5, x2 - 1, y6 - 1, frameColor, -3);
|
||||||
|
osd->DrawEllipse (x0, y6, x1 - 1, y7 - 1, frameColor, 3);
|
||||||
|
osd->DrawRectangle(x1, y6, x4 - 1, y7 - 1, frameColor);
|
||||||
|
osd->DrawRectangle(x5, y6, x6 - 1, y7 - 1, frameColor);
|
||||||
|
osd->DrawEllipse (x6, y6, x7 - 1, y7 - 1, frameColor, 5);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x0 = 0;
|
||||||
|
x1 = lineHeight / 2;
|
||||||
|
x2 = lineHeight;
|
||||||
|
x3 = x2 + Gap;
|
||||||
|
x7 = Setup.OSDWidth;
|
||||||
|
x6 = x7 - lineHeight / 2;
|
||||||
|
x5 = x6 - lineHeight / 2;
|
||||||
|
x4 = x5 - Gap;
|
||||||
|
y0 = 0;
|
||||||
|
y1 = lineHeight;
|
||||||
|
osd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop + (Setup.ChannelInfoPos ? 0 : Setup.OSDHeight - y1));
|
||||||
|
tArea Areas[] = { { x0, y0, x7 - 1, y1 - 1, 4 } };
|
||||||
|
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||||
|
osd->DrawRectangle(x0, y0, x7 - 1, y1 - 1, clrTransparent);
|
||||||
|
osd->DrawEllipse (x0, y0, x1 - 1, y1 - 1, frameColor, 7);
|
||||||
|
osd->DrawRectangle(x1, y0, x2 - 1, y1 - 1, frameColor);
|
||||||
|
osd->DrawRectangle(x5, y0, x6 - 1, y1 - 1, frameColor);
|
||||||
|
osd->DrawEllipse (x6, y0, x7 - 1, y1 - 1, frameColor, 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cSkinSTTNGDisplayChannel::~cSkinSTTNGDisplayChannel()
|
||||||
|
{
|
||||||
|
delete osd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinSTTNGDisplayChannel::SetChannel(const cChannel *Channel, int Number)
|
||||||
|
{
|
||||||
|
osd->DrawRectangle(x3, y0, x4 - 1, y1 - 1, frameColor);
|
||||||
|
int x = x4 - 5;
|
||||||
|
if (Channel && !Channel->GroupSep()) {
|
||||||
|
int d = 3;
|
||||||
|
bool rec = cRecordControls::Active();
|
||||||
|
x -= bmRecording.Width() + d;
|
||||||
|
osd->DrawBitmap(x, y0 + (y1 - y0 - bmRecording.Height()) / 2, bmRecording, Theme.Color(rec ? clrChannelSymbolRecFg : clrChannelSymbolOff), rec ? Theme.Color(clrChannelSymbolRecBg) : frameColor);
|
||||||
|
x -= bmEncrypted.Width() + d;
|
||||||
|
osd->DrawBitmap(x, y0 + (y1 - y0 - bmEncrypted.Height()) / 2, bmEncrypted, Theme.Color(Channel->Ca() ? clrChannelSymbolOn : clrChannelSymbolOff), frameColor);
|
||||||
|
x -= bmDolbyDigital.Width() + d;
|
||||||
|
osd->DrawBitmap(x, y0 + (y1 - y0 - bmDolbyDigital.Height()) / 2, bmDolbyDigital, Theme.Color(Channel->Dpid1() ? clrChannelSymbolOn : clrChannelSymbolOff), frameColor);
|
||||||
|
x -= bmAudio.Width() + d;
|
||||||
|
osd->DrawBitmap(x, y0 + (y1 - y0 - bmAudio.Height()) / 2, bmAudio, Theme.Color(Channel->Apid2() ? clrChannelSymbolOn : clrChannelSymbolOff), frameColor);
|
||||||
|
if (Channel->Vpid()) {
|
||||||
|
x -= bmTeletext.Width() + d;
|
||||||
|
osd->DrawBitmap(x, y0 + (y1 - y0 - bmTeletext.Height()) / 2, bmTeletext, Theme.Color(Channel->Tpid() ? clrChannelSymbolOn : clrChannelSymbolOff), frameColor);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x -= bmRadio.Width() + d;
|
||||||
|
osd->DrawBitmap(x, y0 + (y1 - y0 - bmRadio.Height()) / 2, bmRadio, Theme.Color(clrChannelSymbolOn), frameColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
osd->DrawText(x3 + 2, y0, ChannelString(Channel, Number), Theme.Color(clrChannelName), frameColor, cFont::GetFont(fontOsd), x - x3 - 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinSTTNGDisplayChannel::SetEvents(const cEvent *Present, const cEvent *Following)
|
||||||
|
{
|
||||||
|
if (!withInfo)
|
||||||
|
return;
|
||||||
|
if (present != Present)
|
||||||
|
lastSeen = -1;
|
||||||
|
present = Present;
|
||||||
|
osd->DrawRectangle(x0, y3, x1 - 1, y4 - 1, frameColor);
|
||||||
|
osd->DrawRectangle(x3, y3, x7 - 1, y4 - 1, Theme.Color(clrBackground));
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
const cEvent *e = !i ? Present : Following;
|
||||||
|
if (e) {
|
||||||
|
osd->DrawText(x0 + 2, y3 + 2 * i * lineHeight, e->GetTimeString(), Theme.Color(clrChannelEpgTime), frameColor, cFont::GetFont(fontOsd));
|
||||||
|
osd->DrawText(x3 + 2, y3 + 2 * i * lineHeight, e->Title(), Theme.Color(clrChannelEpgTitle), Theme.Color(clrBackground), cFont::GetFont(fontOsd), x4 - x3 - 2);
|
||||||
|
osd->DrawText(x3 + 2, y3 + (2 * i + 1) * lineHeight, e->ShortText(), Theme.Color(clrChannelEpgShortText), Theme.Color(clrBackground), cFont::GetFont(fontSml), x4 - x3 - 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinSTTNGDisplayChannel::Flush(void)
|
||||||
|
{
|
||||||
|
if (withInfo) {
|
||||||
|
const char *date = DayDateTime();
|
||||||
|
const cFont *font = cFont::GetFont(fontSml);
|
||||||
|
osd->DrawText(x4 - font->Width(date) - 2, y7 - font->Height(date), date, Theme.Color(clrChannelDate), frameColor, font);
|
||||||
|
|
||||||
|
int seen = 0;
|
||||||
|
if (present) {
|
||||||
|
time_t t = time(NULL);
|
||||||
|
if (t > present->StartTime())
|
||||||
|
seen = min(y4 - y3 - 1, int((y4 - y3) * double(t - present->StartTime()) / present->Duration()));
|
||||||
|
}
|
||||||
|
if (seen != lastSeen) {
|
||||||
|
osd->DrawRectangle(x1 + Gap, y3, x1 + Gap + ScrollWidth - 1, y4 - 1, Theme.Color(clrChannelTimebarRest));
|
||||||
|
if (seen)
|
||||||
|
osd->DrawRectangle(x1 + Gap, y3, x1 + Gap + ScrollWidth - 1, y3 + seen, Theme.Color(clrChannelTimebarSeen));
|
||||||
|
lastSeen = seen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
osd->Flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- cSkinSTTNGDisplayMenu -------------------------------------------------
|
||||||
|
|
||||||
|
class cSkinSTTNGDisplayMenu : public cSkinDisplayMenu {
|
||||||
|
private:
|
||||||
|
cOsd *osd;
|
||||||
|
int x0, x1, x2, x3, x4, x5, x6, x7;
|
||||||
|
int y0, y1, y2, y3, y4, y5, y6, y7;
|
||||||
|
int lineHeight;
|
||||||
|
tColor frameColor;
|
||||||
|
int currentIndex;
|
||||||
|
bool message;
|
||||||
|
void SetScrollbar(void);
|
||||||
|
public:
|
||||||
|
cSkinSTTNGDisplayMenu(void);
|
||||||
|
virtual ~cSkinSTTNGDisplayMenu();
|
||||||
|
virtual void Scroll(bool Up, bool Page);
|
||||||
|
virtual int MaxItems(void);
|
||||||
|
virtual void Clear(void);
|
||||||
|
virtual void SetTitle(const char *Title);
|
||||||
|
virtual void SetButtons(const char *Red, const char *Green = NULL, const char *Yellow = NULL, const char *Blue = NULL);
|
||||||
|
virtual void SetMessage(eMessageType Type, const char *Text);
|
||||||
|
virtual void SetItem(const char *Text, int Index, bool Current, bool Selectable);
|
||||||
|
virtual void SetEvent(const cEvent *Event);
|
||||||
|
virtual void SetRecording(const cRecording *Recording);
|
||||||
|
virtual void SetText(const char *Text, bool FixedFont);
|
||||||
|
virtual void Flush(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
cSkinSTTNGDisplayMenu::cSkinSTTNGDisplayMenu(void)
|
||||||
|
{
|
||||||
|
const cFont *font = cFont::GetFont(fontOsd);
|
||||||
|
lineHeight = font->Height();
|
||||||
|
frameColor = Theme.Color(clrMenuFrame);
|
||||||
|
currentIndex = -1;
|
||||||
|
message = false;
|
||||||
|
x0 = 0;
|
||||||
|
x1 = lineHeight / 2;
|
||||||
|
x2 = x1 + Roundness;
|
||||||
|
x3 = x2 + Gap;
|
||||||
|
x7 = Setup.OSDWidth;
|
||||||
|
x6 = x7 - lineHeight / 2;
|
||||||
|
x5 = x6 - lineHeight / 2;
|
||||||
|
x4 = x5 - Gap;
|
||||||
|
y0 = 0;
|
||||||
|
y1 = lineHeight;
|
||||||
|
y2 = y1 + Roundness;
|
||||||
|
y3 = y2 + Gap;
|
||||||
|
y7 = Setup.OSDHeight;
|
||||||
|
y6 = y7 - cFont::GetFont(fontSml)->Height();
|
||||||
|
y5 = y6 - Roundness;
|
||||||
|
y4 = y5 - Gap;
|
||||||
|
int yt = (y0 + y1) / 2;
|
||||||
|
int yb = (y6 + y7) / 2;
|
||||||
|
osd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop);
|
||||||
|
tArea Areas[] = { { x0, y0, x7 - 1, y7 - 1, 4 } };
|
||||||
|
if (osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
|
||||||
|
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||||
|
else {
|
||||||
|
tArea Areas[] = { { x0, y0, x7 - 1, y1 - 1, 2 },
|
||||||
|
{ x0, y1, x7 - 1, y6 - 1, 2 },
|
||||||
|
{ x0, y6, x7 - 1, y7 - 1, 4 }
|
||||||
|
};
|
||||||
|
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||||
|
/*TODO
|
||||||
|
tArea Areas[] = { { x0, y0, x7 - 1, y3 - 1, 2 },
|
||||||
|
{ x0, y3, x3 - 1, y4 - 1, 1 },
|
||||||
|
{ x3, y3, x5 - 1, y4 - 1, 2 },
|
||||||
|
{ x0, y4, x7 - 1, y7 - 1, 4 }
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
osd->DrawRectangle(x0, y0, x7 - 1, y7 - 1, Theme.Color(clrBackground));
|
||||||
|
osd->DrawRectangle(x0, y0, x1 - 1, y1 - 1, clrTransparent);
|
||||||
|
osd->DrawRectangle(x0, y6, x1 - 1, y7 - 1, clrTransparent);
|
||||||
|
osd->DrawRectangle(x6, y0, x7 - 1, yt - 1, clrTransparent);
|
||||||
|
osd->DrawRectangle(x6, yb, x7 - 1, y7 - 1, clrTransparent);
|
||||||
|
osd->DrawEllipse (x0, y0, x1 - 1, y1 - 1, frameColor, 2);
|
||||||
|
osd->DrawRectangle(x1, y0, x2 - 1, y1 - 1, frameColor);
|
||||||
|
osd->DrawRectangle(x3, y0, x4 - 1, y1 - 1, frameColor);
|
||||||
|
osd->DrawRectangle(x5, y0, x6 - 1, y1 - 1, frameColor);
|
||||||
|
osd->DrawEllipse (x6, y0, x7 - 1, y1 - 1, frameColor, 5);
|
||||||
|
osd->DrawRectangle(x0, y1, x1 - 1, y6 - 1, frameColor);
|
||||||
|
osd->DrawEllipse (x1, y1, x2 - 1, y2 - 1, frameColor, -2);
|
||||||
|
osd->DrawEllipse (x1, y5, x2 - 1, y6 - 1, frameColor, -3);
|
||||||
|
osd->DrawEllipse (x0, y6, x1 - 1, y7 - 1, frameColor, 3);
|
||||||
|
osd->DrawRectangle(x1, y6, x2 - 1, y7 - 1, frameColor);
|
||||||
|
osd->DrawRectangle(x3, y6, x4 - 1, y7 - 1, frameColor);
|
||||||
|
osd->DrawRectangle(x5, y6, x6 - 1, y7 - 1, frameColor);
|
||||||
|
osd->DrawEllipse (x6, y6, x7 - 1, y7 - 1, frameColor, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
cSkinSTTNGDisplayMenu::~cSkinSTTNGDisplayMenu()
|
||||||
|
{
|
||||||
|
delete osd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinSTTNGDisplayMenu::SetScrollbar(void)
|
||||||
|
{
|
||||||
|
if (textScroller.CanScroll()) {
|
||||||
|
int h = lineHeight;
|
||||||
|
int yt = textScroller.Top();
|
||||||
|
int yb = yt + textScroller.Height();
|
||||||
|
int st = yt + h + Gap;
|
||||||
|
int sb = yb - h - Gap;
|
||||||
|
int tt = st + (sb - st) * textScroller.Offset() / textScroller.Total();
|
||||||
|
int tb = tt + (sb - st) * textScroller.Shown() / textScroller.Total();
|
||||||
|
osd->DrawRectangle(x5, st, x5 + ScrollWidth - 1, sb, Theme.Color(clrMenuScrollbarTotal));
|
||||||
|
osd->DrawRectangle(x5, tt, x5 + ScrollWidth - 1, tb, Theme.Color(clrMenuScrollbarShown));
|
||||||
|
osd->DrawRectangle(x5, yt, x6 - 1, yt + h - 1, frameColor);
|
||||||
|
osd->DrawEllipse (x6, yt, x7 - 1, yt + h - 1, frameColor, 5);
|
||||||
|
osd->DrawRectangle(x5, yb - h, x6 - 1, yb - 1, frameColor);
|
||||||
|
osd->DrawEllipse (x6, yb - h, x7 - 1, yb - 1, frameColor, 5);
|
||||||
|
if (textScroller.CanScrollUp()) {
|
||||||
|
cBitmap bm(arrowup_xpm);
|
||||||
|
osd->DrawBitmap(x5 + (x7 - x5 - bm.Width()) / 2 - 2, yt + (h - bm.Height()) / 2, bm, Theme.Color(clrMenuScrollbarArrow), frameColor);
|
||||||
|
}
|
||||||
|
if (textScroller.CanScrollDown()) {
|
||||||
|
cBitmap bm(arrowdown_xpm);
|
||||||
|
osd->DrawBitmap(x5 + (x7 - x5 - bm.Width()) / 2 - 2, yb - h + (h - bm.Height()) / 2, bm, Theme.Color(clrMenuScrollbarArrow), frameColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinSTTNGDisplayMenu::Scroll(bool Up, bool Page)
|
||||||
|
{
|
||||||
|
cSkinDisplayMenu::Scroll(Up, Page);
|
||||||
|
SetScrollbar();
|
||||||
|
}
|
||||||
|
|
||||||
|
int cSkinSTTNGDisplayMenu::MaxItems(void)
|
||||||
|
{
|
||||||
|
return (y4 - y3 - 2 * Roundness) / lineHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinSTTNGDisplayMenu::Clear(void)
|
||||||
|
{
|
||||||
|
textScroller.Reset();
|
||||||
|
osd->DrawRectangle(x1, y3, x7 - 1, y4 - 1, Theme.Color(clrBackground));
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinSTTNGDisplayMenu::SetTitle(const char *Title)
|
||||||
|
{
|
||||||
|
const cFont *font = cFont::GetFont(fontOsd);
|
||||||
|
const char *VDR = " VDR";
|
||||||
|
int w = font->Width(VDR);
|
||||||
|
osd->DrawText(x3 + 5, y0, Title, Theme.Color(clrMenuTitle), frameColor, font, x4 - w - x3 - 5);
|
||||||
|
osd->DrawText(x4 - w, y0, VDR, frameColor, clrBlack, font);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinSTTNGDisplayMenu::SetButtons(const char *Red, const char *Green, const char *Yellow, const char *Blue)
|
||||||
|
{
|
||||||
|
const char *date = DayDateTime();
|
||||||
|
const cFont *font = cFont::GetFont(fontSml);
|
||||||
|
int d = 10;
|
||||||
|
int d2 = d / 2;
|
||||||
|
int t4 = x4 - font->Width(date) - 2;
|
||||||
|
int w = t4 - x3;
|
||||||
|
int t0 = x3 + d2;
|
||||||
|
int t1 = x3 + w / 4;
|
||||||
|
int t2 = x3 + w / 2;
|
||||||
|
int t3 = t4 - w / 4;
|
||||||
|
osd->DrawRectangle(t0 + d2, y6, t1 - d2, y7 - 1, clrBlack);
|
||||||
|
osd->DrawRectangle(t1 + d2, y6, t2 - d2, y7 - 1, clrBlack);
|
||||||
|
osd->DrawRectangle(t2 + d2, y6, t3 - d2, y7 - 1, clrBlack);
|
||||||
|
osd->DrawRectangle(t3 + d2, y6, t4 - d2, y7 - 1, clrBlack);
|
||||||
|
osd->DrawText(t0 + d, y6, Red, Theme.Color(clrButtonRedFg), Theme.Color(clrButtonRedBg), font, t1 - t0 - 2 * d, 0, taCenter);
|
||||||
|
osd->DrawText(t1 + d, y6, Green, Theme.Color(clrButtonGreenFg), Theme.Color(clrButtonGreenBg), font, t2 - t1 - 2 * d, 0, taCenter);
|
||||||
|
osd->DrawText(t2 + d, y6, Yellow, Theme.Color(clrButtonYellowFg), Theme.Color(clrButtonYellowBg), font, t3 - t2 - 2 * d, 0, taCenter);
|
||||||
|
osd->DrawText(t3 + d, y6, Blue, Theme.Color(clrButtonBlueFg), Theme.Color(clrButtonBlueBg), font, t4 - t3 - 2 * d, 0, taCenter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinSTTNGDisplayMenu::SetMessage(eMessageType Type, const char *Text)
|
||||||
|
{
|
||||||
|
const cFont *font = cFont::GetFont(fontSml);
|
||||||
|
if (Text) {
|
||||||
|
osd->SaveRegion(x3, y6, x4 - 1, y7 - 1);
|
||||||
|
osd->DrawText(x3, y6, Text, Theme.Color(clrMessageStatusFg + 2 * Type), Theme.Color(clrMessageStatusBg + 2 * Type), font, x4 - x3, 0, taCenter);
|
||||||
|
message = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
osd->RestoreRegion();
|
||||||
|
message = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinSTTNGDisplayMenu::SetItem(const char *Text, int Index, bool Current, bool Selectable)
|
||||||
|
{
|
||||||
|
int y = y3 + Roundness + Index * lineHeight;
|
||||||
|
tColor ColorFg, ColorBg;
|
||||||
|
if (Current) {
|
||||||
|
ColorFg = Theme.Color(clrMenuItemCurrentFg);
|
||||||
|
ColorBg = Theme.Color(clrMenuItemCurrentBg);
|
||||||
|
osd->DrawEllipse (x1, y - Roundness, x2 - 1, y - 1, frameColor, -3);
|
||||||
|
osd->DrawRectangle(x1, y, x2 - 1, y + lineHeight - 1, frameColor);
|
||||||
|
osd->DrawEllipse (x1, y + lineHeight, x2 - 1, y + lineHeight + Roundness - 1, frameColor, -2);
|
||||||
|
osd->DrawRectangle(x3, y, x4 - 1, y + lineHeight - 1, ColorBg);
|
||||||
|
currentIndex = Index;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ColorFg = Theme.Color(Selectable ? clrMenuItemSelectable : clrMenuItemNonSelectable);
|
||||||
|
ColorBg = Theme.Color(clrBackground);
|
||||||
|
if (currentIndex == Index) {
|
||||||
|
osd->DrawRectangle(x1, y - Roundness, x2 - 1, y + lineHeight + Roundness - 1, Theme.Color(clrBackground));
|
||||||
|
osd->DrawRectangle(x3, y, x4 - 1, y + lineHeight - 1, Theme.Color(clrBackground));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const cFont *font = cFont::GetFont(fontOsd);
|
||||||
|
for (int i = 0; i < MaxTabs; i++) {
|
||||||
|
const char *s = GetTabbedText(Text, i);
|
||||||
|
if (s) {
|
||||||
|
int xt = x3 + 5 + Tab(i);
|
||||||
|
osd->DrawText(xt, y, s, ColorFg, ColorBg, font, x4 - xt);
|
||||||
|
}
|
||||||
|
if (!Tab(i + 1))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
SetEditableWidth(x4 - x3 - 5 - Tab(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinSTTNGDisplayMenu::SetEvent(const cEvent *Event)
|
||||||
|
{
|
||||||
|
if (!Event)
|
||||||
|
return;
|
||||||
|
const cFont *font = cFont::GetFont(fontOsd);
|
||||||
|
int xl = x3 + 5;
|
||||||
|
int y = y3;
|
||||||
|
cTextScroller ts;
|
||||||
|
char t[32];
|
||||||
|
snprintf(t, sizeof(t), "%s %s - %s", Event->GetDateString(), Event->GetTimeString(), Event->GetEndTimeString());//TODO dayname, no year
|
||||||
|
ts.Set(osd, xl, y, x4 - xl, y4 - y, t, font, Theme.Color(clrMenuEventTime), Theme.Color(clrBackground));
|
||||||
|
if (Event->Vps() && Event->Vps() != Event->StartTime()) {
|
||||||
|
char *buffer;
|
||||||
|
asprintf(&buffer, " VPS: %s", Event->GetVpsString());
|
||||||
|
const cFont *font = cFont::GetFont(fontSml);
|
||||||
|
osd->DrawText(x4 - font->Width(buffer), y, buffer, Theme.Color(clrMenuEventVps), frameColor, font);
|
||||||
|
int yb = y + font->Height();
|
||||||
|
osd->DrawRectangle(x5, y, x6 - 1, yb - 1, frameColor);
|
||||||
|
osd->DrawEllipse (x6, y, x7 - 1, yb - 1, frameColor, 5);
|
||||||
|
free(buffer);
|
||||||
|
}
|
||||||
|
y += ts.Height();
|
||||||
|
y += font->Height();
|
||||||
|
ts.Set(osd, xl, y, x4 - xl, y4 - y, Event->Title(), font, Theme.Color(clrMenuEventTitle), Theme.Color(clrBackground));
|
||||||
|
y += ts.Height();
|
||||||
|
if (!isempty(Event->ShortText())) {
|
||||||
|
const cFont *font = cFont::GetFont(fontSml);
|
||||||
|
ts.Set(osd, xl, y, x4 - xl, y4 - y, Event->ShortText(), font, Theme.Color(clrMenuEventShortText), Theme.Color(clrBackground));
|
||||||
|
y += ts.Height();
|
||||||
|
}
|
||||||
|
y += font->Height();
|
||||||
|
if (!isempty(Event->Description())) {
|
||||||
|
int yt = y;
|
||||||
|
int yb = y4 - Roundness;
|
||||||
|
textScroller.Set(osd, xl, yt, x4 - xl, yb - yt, Event->Description(), font, Theme.Color(clrMenuEventDescription), Theme.Color(clrBackground));
|
||||||
|
yb = yt + textScroller.Height();
|
||||||
|
osd->DrawEllipse (x1, yt - Roundness, x2, yt, frameColor, -3);
|
||||||
|
osd->DrawRectangle(x1, yt, x2, yb, frameColor);
|
||||||
|
osd->DrawEllipse (x1, yb, x2, yb + Roundness, frameColor, -2);
|
||||||
|
SetScrollbar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinSTTNGDisplayMenu::SetRecording(const cRecording *Recording)
|
||||||
|
{
|
||||||
|
SetText(Recording->Summary(), false); //XXX
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinSTTNGDisplayMenu::SetText(const char *Text, bool FixedFont)
|
||||||
|
{
|
||||||
|
const cFont *font = cFont::GetFont(FixedFont ? fontFix : fontOsd);
|
||||||
|
font = cFont::GetFont(fontSml);//XXX -> make a way to let the text define which font to use
|
||||||
|
textScroller.Set(osd, x3, y3, x4 - x3, y4 - y3, Text, font, Theme.Color(clrMenuText), Theme.Color(clrBackground));
|
||||||
|
SetScrollbar();
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinSTTNGDisplayMenu::Flush(void)
|
||||||
|
{
|
||||||
|
if (!message) {
|
||||||
|
const char *date = DayDateTime();
|
||||||
|
const cFont *font = cFont::GetFont(fontSml);
|
||||||
|
osd->DrawText(x4 - font->Width(date) - 2, y7 - font->Height(date), date, Theme.Color(clrMenuDate), frameColor, font);
|
||||||
|
}
|
||||||
|
osd->Flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- cSkinSTTNGDisplayReplay -----------------------------------------------
|
||||||
|
|
||||||
|
class cSkinSTTNGDisplayReplay : public cSkinDisplayReplay {
|
||||||
|
private:
|
||||||
|
cOsd *osd;
|
||||||
|
int x0, x1, x2, x3, x4, x5, x6, x7;
|
||||||
|
int y0, y1, y2, y3, y4, y5, y6, y7;
|
||||||
|
tColor frameColor;
|
||||||
|
int lastCurrentWidth;
|
||||||
|
public:
|
||||||
|
cSkinSTTNGDisplayReplay(bool ModeOnly);
|
||||||
|
virtual ~cSkinSTTNGDisplayReplay();
|
||||||
|
virtual void SetTitle(const char *Title);
|
||||||
|
virtual void SetMode(bool Play, bool Forward, int Speed);
|
||||||
|
virtual void SetProgress(int Current, int Total);
|
||||||
|
virtual void SetCurrent(const char *Current);
|
||||||
|
virtual void SetTotal(const char *Total);
|
||||||
|
virtual void SetJump(const char *Jump);
|
||||||
|
virtual void Flush(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
#define SymbolWidth 30
|
||||||
|
#define SymbolHeight 30
|
||||||
|
|
||||||
|
cSkinSTTNGDisplayReplay::cSkinSTTNGDisplayReplay(bool ModeOnly)
|
||||||
|
{
|
||||||
|
const cFont *font = cFont::GetFont(fontSml);
|
||||||
|
int lineHeight = font->Height();
|
||||||
|
frameColor = Theme.Color(clrReplayFrame);
|
||||||
|
lastCurrentWidth = 0;
|
||||||
|
cBitmap bm(play_xpm);
|
||||||
|
x0 = 0;
|
||||||
|
x1 = max(SymbolWidth, bm.Width());
|
||||||
|
x2 = x1 + Roundness;
|
||||||
|
x3 = x2 + Gap;
|
||||||
|
x7 = Setup.OSDWidth;
|
||||||
|
x6 = x7 - lineHeight / 2;
|
||||||
|
x5 = x6 - lineHeight / 2;
|
||||||
|
x4 = x5 - Gap;
|
||||||
|
y0 = 0;
|
||||||
|
y1 = lineHeight;
|
||||||
|
y2 = y1 + Roundness;
|
||||||
|
y3 = y2 + Gap;
|
||||||
|
y4 = y3 + max(SymbolHeight, bm.Height());
|
||||||
|
y5 = y4 + Gap;
|
||||||
|
y6 = y5 + Roundness;
|
||||||
|
y7 = y6 + font->Height();
|
||||||
|
int yt = (y0 + y1) / 2;
|
||||||
|
int yb = (y6 + y7) / 2;
|
||||||
|
osd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop + Setup.OSDHeight - y7);
|
||||||
|
tArea Areas[] = { { 0, 0, x7 - 1, y7 - 1, 4 } };
|
||||||
|
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||||
|
osd->DrawRectangle(x0, y0, x7 - 1, y7 - 1, ModeOnly ? clrTransparent : Theme.Color(clrBackground));
|
||||||
|
if (!ModeOnly) {
|
||||||
|
osd->DrawRectangle(x0, y0, x1 - 1, y1 - 1, clrTransparent);
|
||||||
|
osd->DrawRectangle(x0, y6, x1 - 1, y7 - 1, clrTransparent);
|
||||||
|
osd->DrawRectangle(x6, y0, x7 - 1, yt - 1, clrTransparent);
|
||||||
|
osd->DrawRectangle(x6, yb, x7 - 1, y7 - 1, clrTransparent);
|
||||||
|
osd->DrawEllipse (x0, y0, x1 - 1, y1 - 1, frameColor, 2);
|
||||||
|
osd->DrawRectangle(x1, y0, x4 - 1, y1 - 1, frameColor);
|
||||||
|
osd->DrawRectangle(x5, y0, x6 - 1, y1 - 1, frameColor);
|
||||||
|
osd->DrawEllipse (x6, y0, x7 - 1, y1 - 1, frameColor, 5);
|
||||||
|
osd->DrawRectangle(x0, y1, x1 - 1, y2 - 1, frameColor);
|
||||||
|
osd->DrawEllipse (x1, y1, x2 - 1, y2 - 1, frameColor, -2);
|
||||||
|
}
|
||||||
|
osd->DrawRectangle(x0, y3, x1 - 1, y4 - 1, frameColor);
|
||||||
|
if (!ModeOnly) {
|
||||||
|
osd->DrawRectangle(x0, y5, x1 - 1, y6 - 1, frameColor);
|
||||||
|
osd->DrawEllipse (x1, y5, x2 - 1, y6 - 1, frameColor, -3);
|
||||||
|
osd->DrawEllipse (x0, y6, x1 - 1, y7 - 1, frameColor, 3);
|
||||||
|
osd->DrawRectangle(x1, y6, x4 - 1, y7 - 1, frameColor);
|
||||||
|
osd->DrawRectangle(x5, y6, x6 - 1, y7 - 1, frameColor);
|
||||||
|
osd->DrawEllipse (x6, y6, x7 - 1, y7 - 1, frameColor, 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cSkinSTTNGDisplayReplay::~cSkinSTTNGDisplayReplay()
|
||||||
|
{
|
||||||
|
delete osd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinSTTNGDisplayReplay::SetTitle(const char *Title)
|
||||||
|
{
|
||||||
|
osd->DrawText(x3 + 5, y0, Title, Theme.Color(clrReplayTitle), frameColor, cFont::GetFont(fontSml), x4 - x3 - 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char **ReplaySymbols[2][2][5] = {
|
||||||
|
{ { pause_xpm, srew_xpm, srew1_xpm, srew2_xpm, srew3_xpm },
|
||||||
|
{ pause_xpm, sfwd_xpm, sfwd1_xpm, sfwd2_xpm, sfwd3_xpm }, },
|
||||||
|
{ { play_xpm, frew_xpm, frew1_xpm, frew2_xpm, frew3_xpm },
|
||||||
|
{ play_xpm, ffwd_xpm, ffwd1_xpm, ffwd2_xpm, ffwd3_xpm } }
|
||||||
|
};
|
||||||
|
|
||||||
|
void cSkinSTTNGDisplayReplay::SetMode(bool Play, bool Forward, int Speed)
|
||||||
|
{
|
||||||
|
if (Speed < -1)
|
||||||
|
Speed = -1;
|
||||||
|
if (Speed > 3)
|
||||||
|
Speed = 3;
|
||||||
|
cBitmap bm(ReplaySymbols[Play][Forward][Speed + 1]);
|
||||||
|
osd->DrawBitmap(x0 + (x1 - x0 - bm.Width()) / 2, y3 + (y4 - y3 - bm.Height()) / 2, bm, Theme.Color(clrReplayMode), frameColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinSTTNGDisplayReplay::SetProgress(int Current, int Total)
|
||||||
|
{
|
||||||
|
cProgressBar pb(x4 - x3, y4 - y3, Current, Total, marks, Theme.Color(clrReplayProgressSeen), Theme.Color(clrReplayProgressRest), Theme.Color(clrReplayProgressSelected), Theme.Color(clrReplayProgressMark), Theme.Color(clrReplayProgressCurrent));
|
||||||
|
osd->DrawBitmap(x3, y3, pb);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinSTTNGDisplayReplay::SetCurrent(const char *Current)
|
||||||
|
{
|
||||||
|
const cFont *font = cFont::GetFont(fontSml);
|
||||||
|
int w = font->Width(Current);
|
||||||
|
osd->DrawText(x3, y6, Current, Theme.Color(clrReplayCurrent), frameColor, font, lastCurrentWidth > w ? lastCurrentWidth : 0);
|
||||||
|
lastCurrentWidth = w;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinSTTNGDisplayReplay::SetTotal(const char *Total)
|
||||||
|
{
|
||||||
|
const cFont *font = cFont::GetFont(fontSml);
|
||||||
|
osd->DrawText(x4 - font->Width(Total) - 5, y6, Total, Theme.Color(clrReplayTotal), frameColor, font);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinSTTNGDisplayReplay::SetJump(const char *Jump)
|
||||||
|
{
|
||||||
|
osd->DrawText(x0 + (x4 - x0) / 4, y6, Jump, Theme.Color(clrReplayJump), frameColor, cFont::GetFont(fontSml), (x4 - x3) / 2, 0, taCenter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinSTTNGDisplayReplay::Flush(void)
|
||||||
|
{
|
||||||
|
osd->Flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- cSkinSTTNGDisplayVolume -----------------------------------------------
|
||||||
|
|
||||||
|
class cSkinSTTNGDisplayVolume : public cSkinDisplayVolume {
|
||||||
|
private:
|
||||||
|
cOsd *osd;
|
||||||
|
int x0, x1, x2, x3, x4, x5, x6, x7;
|
||||||
|
int y0, y1;
|
||||||
|
tColor frameColor;
|
||||||
|
int mute;
|
||||||
|
public:
|
||||||
|
cSkinSTTNGDisplayVolume(void);
|
||||||
|
virtual ~cSkinSTTNGDisplayVolume();
|
||||||
|
virtual void SetVolume(int Current, int Total, bool Mute);
|
||||||
|
virtual void Flush(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
cSkinSTTNGDisplayVolume::cSkinSTTNGDisplayVolume(void)
|
||||||
|
{
|
||||||
|
const cFont *font = cFont::GetFont(fontOsd);
|
||||||
|
int lineHeight = font->Height();
|
||||||
|
frameColor = Theme.Color(clrVolumeFrame);
|
||||||
|
mute = -1;
|
||||||
|
x0 = 0;
|
||||||
|
x1 = lineHeight / 2;
|
||||||
|
x2 = lineHeight;
|
||||||
|
x3 = x2 + Gap;
|
||||||
|
x7 = Setup.OSDWidth;
|
||||||
|
x6 = x7 - lineHeight / 2;
|
||||||
|
x5 = x6 - lineHeight / 2;
|
||||||
|
x4 = x5 - Gap;
|
||||||
|
y0 = 0;
|
||||||
|
y1 = lineHeight;
|
||||||
|
osd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop + Setup.OSDHeight - y1);
|
||||||
|
tArea Areas[] = { { x0, y0, x7 - 1, y1 - 1, 4 } };
|
||||||
|
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||||
|
osd->DrawRectangle(x0, y0, x7 - 1, y1 - 1, clrTransparent);
|
||||||
|
osd->DrawEllipse (x0, y0, x1 - 1, y1 - 1, frameColor, 7);
|
||||||
|
osd->DrawRectangle(x1, y0, x2 - 1, y1 - 1, frameColor);
|
||||||
|
osd->DrawRectangle(x3, y0, x4 - 1, y1 - 1, frameColor);
|
||||||
|
osd->DrawRectangle(x5, y0, x6 - 1, y1 - 1, frameColor);
|
||||||
|
osd->DrawEllipse (x6, y0, x7 - 1, y1 - 1, frameColor, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
cSkinSTTNGDisplayVolume::~cSkinSTTNGDisplayVolume()
|
||||||
|
{
|
||||||
|
delete osd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinSTTNGDisplayVolume::SetVolume(int Current, int Total, bool Mute)
|
||||||
|
{
|
||||||
|
int xl = x3 + 5;
|
||||||
|
int xr = x4 - 5;
|
||||||
|
int yt = y0 + 3;
|
||||||
|
int yb = y1 - 3;
|
||||||
|
if (mute != Mute) {
|
||||||
|
osd->DrawRectangle(x3, y0, x4 - 1, y1 - 1, frameColor);
|
||||||
|
mute = Mute;
|
||||||
|
}
|
||||||
|
cBitmap bm(Mute ? mute_xpm : volume_xpm);
|
||||||
|
osd->DrawBitmap(xl, y0 + (y1 - y0 - bm.Height()) / 2, bm, Theme.Color(clrVolumeSymbol), frameColor);
|
||||||
|
if (!Mute) {
|
||||||
|
xl += bm.Width() + 5;
|
||||||
|
int w = (y1 - y0) / 3;
|
||||||
|
int d = 3;
|
||||||
|
int n = (xr - xl + d) / (w + d);
|
||||||
|
int x = xr - n * (w + d);
|
||||||
|
tColor Color = Theme.Color(clrVolumeBarLower);
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
if (Total * i >= Current * n)
|
||||||
|
Color = Theme.Color(clrVolumeBarUpper);
|
||||||
|
osd->DrawRectangle(x, yt, x + w - 1, yb - 1, Color);
|
||||||
|
x += w + d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinSTTNGDisplayVolume::Flush(void)
|
||||||
|
{
|
||||||
|
osd->Flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- cSkinSTTNGDisplayMessage ----------------------------------------------
|
||||||
|
|
||||||
|
class cSkinSTTNGDisplayMessage : public cSkinDisplayMessage {
|
||||||
|
private:
|
||||||
|
cOsd *osd;
|
||||||
|
int x0, x1, x2, x3, x4, x5, x6, x7;
|
||||||
|
int y0, y1;
|
||||||
|
public:
|
||||||
|
cSkinSTTNGDisplayMessage(void);
|
||||||
|
virtual ~cSkinSTTNGDisplayMessage();
|
||||||
|
virtual void SetMessage(eMessageType Type, const char *Text);
|
||||||
|
virtual void Flush(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
cSkinSTTNGDisplayMessage::cSkinSTTNGDisplayMessage(void)
|
||||||
|
{
|
||||||
|
const cFont *font = cFont::GetFont(fontOsd);
|
||||||
|
int lineHeight = font->Height();
|
||||||
|
tColor frameColor = Theme.Color(clrMessageFrame);
|
||||||
|
x0 = 0;
|
||||||
|
x1 = lineHeight / 2;
|
||||||
|
x2 = lineHeight;
|
||||||
|
x3 = x2 + Gap;
|
||||||
|
x7 = Setup.OSDWidth;
|
||||||
|
x6 = x7 - lineHeight / 2;
|
||||||
|
x5 = x6 - lineHeight / 2;
|
||||||
|
x4 = x5 - Gap;
|
||||||
|
y0 = 0;
|
||||||
|
y1 = lineHeight;
|
||||||
|
osd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop + Setup.OSDHeight - y1);
|
||||||
|
tArea Areas[] = { { x0, y0, x7 - 1, y1 - 1, 2 } };
|
||||||
|
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||||
|
osd->DrawRectangle(x0, y0, x7 - 1, y1 - 1, clrTransparent);
|
||||||
|
osd->DrawEllipse (x0, y0, x1 - 1, y1 - 1, frameColor, 7);
|
||||||
|
osd->DrawRectangle(x1, y0, x2 - 1, y1 - 1, frameColor);
|
||||||
|
osd->DrawRectangle(x5, y0, x6 - 1, y1 - 1, frameColor);
|
||||||
|
osd->DrawEllipse (x6, y0, x7 - 1, y1 - 1, frameColor, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
cSkinSTTNGDisplayMessage::~cSkinSTTNGDisplayMessage()
|
||||||
|
{
|
||||||
|
delete osd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinSTTNGDisplayMessage::SetMessage(eMessageType Type, const char *Text)
|
||||||
|
{
|
||||||
|
const cFont *font = cFont::GetFont(fontOsd);
|
||||||
|
osd->DrawText(x3, y0, Text, Theme.Color(clrMessageStatusFg + 2 * Type), Theme.Color(clrMessageStatusBg + 2 * Type), font, x4 - x3, 0, taCenter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinSTTNGDisplayMessage::Flush(void)
|
||||||
|
{
|
||||||
|
osd->Flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- cSkinSTTNG ------------------------------------------------------------
|
||||||
|
|
||||||
|
cSkinSTTNG::cSkinSTTNG(void)
|
||||||
|
:cSkin("sttng", &::Theme)//XXX naming problem???
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *cSkinSTTNG::Description(void)
|
||||||
|
{
|
||||||
|
return tr("ST:TNG Panels");
|
||||||
|
}
|
||||||
|
|
||||||
|
cSkinDisplayChannel *cSkinSTTNG::DisplayChannel(bool WithInfo)
|
||||||
|
{
|
||||||
|
return new cSkinSTTNGDisplayChannel(WithInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
cSkinDisplayMenu *cSkinSTTNG::DisplayMenu(void)
|
||||||
|
{
|
||||||
|
return new cSkinSTTNGDisplayMenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
cSkinDisplayReplay *cSkinSTTNG::DisplayReplay(bool ModeOnly)
|
||||||
|
{
|
||||||
|
return new cSkinSTTNGDisplayReplay(ModeOnly);
|
||||||
|
}
|
||||||
|
|
||||||
|
cSkinDisplayVolume *cSkinSTTNG::DisplayVolume(void)
|
||||||
|
{
|
||||||
|
return new cSkinSTTNGDisplayVolume;
|
||||||
|
}
|
||||||
|
|
||||||
|
cSkinDisplayMessage *cSkinSTTNG::DisplayMessage(void)
|
||||||
|
{
|
||||||
|
return new cSkinSTTNGDisplayMessage;
|
||||||
|
}
|
26
skinsttng.h
Normal file
26
skinsttng.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* skinsttng.h: A VDR skin with ST:TNG Panels
|
||||||
|
*
|
||||||
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
|
* how to reach the author.
|
||||||
|
*
|
||||||
|
* $Id: skinsttng.h 1.1 2004/04/18 09:38:47 kls Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SKINSTTNG_H
|
||||||
|
#define __SKINSTTNG_H
|
||||||
|
|
||||||
|
#include "skins.h"
|
||||||
|
|
||||||
|
class cSkinSTTNG : public cSkin {
|
||||||
|
public:
|
||||||
|
cSkinSTTNG(void);
|
||||||
|
virtual const char *Description(void);
|
||||||
|
virtual cSkinDisplayChannel *DisplayChannel(bool WithInfo);
|
||||||
|
virtual cSkinDisplayMenu *DisplayMenu(void);
|
||||||
|
virtual cSkinDisplayReplay *DisplayReplay(bool ModeOnly);
|
||||||
|
virtual cSkinDisplayVolume *DisplayVolume(void);
|
||||||
|
virtual cSkinDisplayMessage *DisplayMessage(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //__SKINSTTNG_H
|
17
symbols/arrowdown.xpm
Normal file
17
symbols/arrowdown.xpm
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
/* XPM */
|
||||||
|
static char * arrowdown_xpm[] = {
|
||||||
|
"12 12 2 1",
|
||||||
|
". c #FFFFFF",
|
||||||
|
"+ c #000000",
|
||||||
|
"++++++++++++",
|
||||||
|
"++++++++++++",
|
||||||
|
".++++++++++.",
|
||||||
|
".++++++++++.",
|
||||||
|
"..++++++++..",
|
||||||
|
"..++++++++..",
|
||||||
|
"...++++++...",
|
||||||
|
"...++++++...",
|
||||||
|
"....++++....",
|
||||||
|
"....++++....",
|
||||||
|
".....++.....",
|
||||||
|
".....++....."};
|
17
symbols/arrowup.xpm
Normal file
17
symbols/arrowup.xpm
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
/* XPM */
|
||||||
|
static char * arrowup_xpm[] = {
|
||||||
|
"12 12 2 1",
|
||||||
|
". c #FFFFFF",
|
||||||
|
"+ c #000000",
|
||||||
|
".....++.....",
|
||||||
|
".....++.....",
|
||||||
|
"....++++....",
|
||||||
|
"....++++....",
|
||||||
|
"...++++++...",
|
||||||
|
"...++++++...",
|
||||||
|
"..++++++++..",
|
||||||
|
"..++++++++..",
|
||||||
|
".++++++++++.",
|
||||||
|
".++++++++++.",
|
||||||
|
"++++++++++++",
|
||||||
|
"++++++++++++"};
|
23
symbols/audio.xpm
Normal file
23
symbols/audio.xpm
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/* XPM */
|
||||||
|
static char * audio_xpm[] = {
|
||||||
|
"27 18 2 1",
|
||||||
|
". c #FFFFFF",
|
||||||
|
"+ c #000000",
|
||||||
|
"...........................",
|
||||||
|
"...........................",
|
||||||
|
"..+++++++++++++++++++++++..",
|
||||||
|
"..+++++++++++++++++++++++..",
|
||||||
|
"..++...................++..",
|
||||||
|
"..++...................++..",
|
||||||
|
"..++...++++.....++++...++..",
|
||||||
|
"..++..++..++...++..++..++..",
|
||||||
|
"..++.++....++.++....++.++..",
|
||||||
|
"..++..++..++...++..++..++..",
|
||||||
|
"..++...++++.....++++...++..",
|
||||||
|
"..++...................++..",
|
||||||
|
"..++...................++..",
|
||||||
|
"..++...................++..",
|
||||||
|
"..+++++++++++++++++++++++..",
|
||||||
|
"..+++++++++++++++++++++++..",
|
||||||
|
"...........................",
|
||||||
|
"..........................."};
|
23
symbols/dolbydigital.xpm
Normal file
23
symbols/dolbydigital.xpm
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/* XPM */
|
||||||
|
static char * dolbydigital_xpm[] = {
|
||||||
|
"27 18 2 1",
|
||||||
|
". c #FFFFFF",
|
||||||
|
"+ c #000000",
|
||||||
|
"...........................",
|
||||||
|
"...........................",
|
||||||
|
"..+++++++++++.+++++++++++..",
|
||||||
|
"..++.++++++++.++++++++.++..",
|
||||||
|
"..++...++++++.++++++...++..",
|
||||||
|
"..++.....++++.++++.....++..",
|
||||||
|
"..++......+++.+++......++..",
|
||||||
|
"..++.......++.++.......++..",
|
||||||
|
"..++.......++.++.......++..",
|
||||||
|
"..++.......++.++.......++..",
|
||||||
|
"..++.......++.++.......++..",
|
||||||
|
"..++......+++.+++......++..",
|
||||||
|
"..++.....++++.++++.....++..",
|
||||||
|
"..++...++++++.++++++...++..",
|
||||||
|
"..++.++++++++.++++++++.++..",
|
||||||
|
"..+++++++++++.+++++++++++..",
|
||||||
|
"...........................",
|
||||||
|
"..........................."};
|
23
symbols/encrypted.xpm
Normal file
23
symbols/encrypted.xpm
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/* XPM */
|
||||||
|
static char * encrypted_xpm[] = {
|
||||||
|
"27 18 2 1",
|
||||||
|
". c #FFFFFF",
|
||||||
|
"+ c #000000",
|
||||||
|
"...........................",
|
||||||
|
"...........................",
|
||||||
|
"..+++++++++++++++++++++++..",
|
||||||
|
"..+++++++++++++++++++++++..",
|
||||||
|
"..++...................++..",
|
||||||
|
"..++...................++..",
|
||||||
|
"..++............++++...++..",
|
||||||
|
"..++...........++..++..++..",
|
||||||
|
"..++.+++++++++++....++.++..",
|
||||||
|
"..++.+++++++++++....++.++..",
|
||||||
|
"..++..+++......++..++..++..",
|
||||||
|
"..++..+++.......++++...++..",
|
||||||
|
"..++...................++..",
|
||||||
|
"..++...................++..",
|
||||||
|
"..+++++++++++++++++++++++..",
|
||||||
|
"..+++++++++++++++++++++++..",
|
||||||
|
"...........................",
|
||||||
|
"..........................."};
|
31
symbols/ffwd.xpm
Normal file
31
symbols/ffwd.xpm
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/* XPM */
|
||||||
|
static char * ffwd_xpm[] = {
|
||||||
|
"28 26 2 1",
|
||||||
|
". c #FFFFFF",
|
||||||
|
"+ c #000000",
|
||||||
|
"............................",
|
||||||
|
"............................",
|
||||||
|
"..++......++................",
|
||||||
|
"..+++.....+++...............",
|
||||||
|
"..+++++...+++++.............",
|
||||||
|
"..++++++....++++............",
|
||||||
|
"..++++++++...+++++..........",
|
||||||
|
"..+++++++++....++++.........",
|
||||||
|
"..+++++++++++...+++++.......",
|
||||||
|
"..++++++++++++....++++......",
|
||||||
|
"..++++++++++++++...+++++....",
|
||||||
|
"..+++++++++++++++....++++...",
|
||||||
|
"..++++++++++++++++....++++..",
|
||||||
|
"..++++++++++++++++....++++..",
|
||||||
|
"..+++++++++++++++....++++...",
|
||||||
|
"..++++++++++++++...+++++....",
|
||||||
|
"..++++++++++++....++++......",
|
||||||
|
"..+++++++++++...+++++.......",
|
||||||
|
"..+++++++++....++++.........",
|
||||||
|
"..++++++++...+++++..........",
|
||||||
|
"..++++++....++++............",
|
||||||
|
"..+++++...+++++.............",
|
||||||
|
"..+++.....+++...............",
|
||||||
|
"..++......++................",
|
||||||
|
"............................",
|
||||||
|
"............................"};
|
31
symbols/ffwd1.xpm
Normal file
31
symbols/ffwd1.xpm
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/* XPM */
|
||||||
|
static char * ffwd1_xpm[] = {
|
||||||
|
"28 26 2 1",
|
||||||
|
". c #FFFFFF",
|
||||||
|
"+ c #000000",
|
||||||
|
"............................",
|
||||||
|
"............................",
|
||||||
|
"..++......++................",
|
||||||
|
"..+++.....+++...............",
|
||||||
|
"..+++++...+++++.............",
|
||||||
|
"..++++++....++++............",
|
||||||
|
"..++++++++...+++++..........",
|
||||||
|
"..+++++++++....++++.........",
|
||||||
|
"..+++++++++++...+++++.......",
|
||||||
|
"..++++++++++++....++++......",
|
||||||
|
"..++++++++++++++...+++++....",
|
||||||
|
"..++++++++++++++.....++++...",
|
||||||
|
"..++++++++++++++...+++++....",
|
||||||
|
"..++++++++++++....++++......",
|
||||||
|
"..+++++++++++...+++++.......",
|
||||||
|
"..+++++++++....++++.........",
|
||||||
|
"..++++++++...+++++..........",
|
||||||
|
"..++++++....++++............",
|
||||||
|
"..+++++...+++++.............",
|
||||||
|
"..+++.....+++...............",
|
||||||
|
"..++......++................",
|
||||||
|
"............................",
|
||||||
|
"..++++++....................",
|
||||||
|
"..++++++....................",
|
||||||
|
"............................",
|
||||||
|
"............................"};
|
31
symbols/ffwd2.xpm
Normal file
31
symbols/ffwd2.xpm
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/* XPM */
|
||||||
|
static char * ffwd2_xpm[] = {
|
||||||
|
"28 26 2 1",
|
||||||
|
". c #FFFFFF",
|
||||||
|
"+ c #000000",
|
||||||
|
"............................",
|
||||||
|
"............................",
|
||||||
|
"..++......++................",
|
||||||
|
"..+++.....+++...............",
|
||||||
|
"..+++++...+++++.............",
|
||||||
|
"..++++++....++++............",
|
||||||
|
"..++++++++...+++++..........",
|
||||||
|
"..+++++++++....++++.........",
|
||||||
|
"..+++++++++++...+++++.......",
|
||||||
|
"..++++++++++++....++++......",
|
||||||
|
"..++++++++++++++...+++++....",
|
||||||
|
"..++++++++++++++.....++++...",
|
||||||
|
"..++++++++++++++...+++++....",
|
||||||
|
"..++++++++++++....++++......",
|
||||||
|
"..+++++++++++...+++++.......",
|
||||||
|
"..+++++++++....++++.........",
|
||||||
|
"..++++++++...+++++..........",
|
||||||
|
"..++++++....++++............",
|
||||||
|
"..+++++...+++++.............",
|
||||||
|
"..+++.....+++...............",
|
||||||
|
"..++......++................",
|
||||||
|
"............................",
|
||||||
|
"..++++++...++++++...........",
|
||||||
|
"..++++++...++++++...........",
|
||||||
|
"............................",
|
||||||
|
"............................"};
|
31
symbols/ffwd3.xpm
Normal file
31
symbols/ffwd3.xpm
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/* XPM */
|
||||||
|
static char * ffwd3_xpm[] = {
|
||||||
|
"28 26 2 1",
|
||||||
|
". c #FFFFFF",
|
||||||
|
"+ c #000000",
|
||||||
|
"............................",
|
||||||
|
"............................",
|
||||||
|
"..++......++................",
|
||||||
|
"..+++.....+++...............",
|
||||||
|
"..+++++...+++++.............",
|
||||||
|
"..++++++....++++............",
|
||||||
|
"..++++++++...+++++..........",
|
||||||
|
"..+++++++++....++++.........",
|
||||||
|
"..+++++++++++...+++++.......",
|
||||||
|
"..++++++++++++....++++......",
|
||||||
|
"..++++++++++++++...+++++....",
|
||||||
|
"..++++++++++++++.....++++...",
|
||||||
|
"..++++++++++++++...+++++....",
|
||||||
|
"..++++++++++++....++++......",
|
||||||
|
"..+++++++++++...+++++.......",
|
||||||
|
"..+++++++++....++++.........",
|
||||||
|
"..++++++++...+++++..........",
|
||||||
|
"..++++++....++++............",
|
||||||
|
"..+++++...+++++.............",
|
||||||
|
"..+++.....+++...............",
|
||||||
|
"..++......++................",
|
||||||
|
"............................",
|
||||||
|
"..++++++...++++++...++++++..",
|
||||||
|
"..++++++...++++++...++++++..",
|
||||||
|
"............................",
|
||||||
|
"............................"};
|
31
symbols/frew.xpm
Normal file
31
symbols/frew.xpm
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/* XPM */
|
||||||
|
static char * frew_xpm[] = {
|
||||||
|
"28 26 2 1",
|
||||||
|
". c #FFFFFF",
|
||||||
|
"+ c #000000",
|
||||||
|
"............................",
|
||||||
|
"............................",
|
||||||
|
"................++......++..",
|
||||||
|
"...............+++.....+++..",
|
||||||
|
".............+++++...+++++..",
|
||||||
|
"............++++....++++++..",
|
||||||
|
"..........+++++...++++++++..",
|
||||||
|
".........++++....+++++++++..",
|
||||||
|
".......+++++...+++++++++++..",
|
||||||
|
"......++++....++++++++++++..",
|
||||||
|
"....+++++...++++++++++++++..",
|
||||||
|
"...++++....+++++++++++++++..",
|
||||||
|
"..++++....++++++++++++++++..",
|
||||||
|
"..++++....++++++++++++++++..",
|
||||||
|
"...++++....+++++++++++++++..",
|
||||||
|
"....+++++...++++++++++++++..",
|
||||||
|
"......++++....++++++++++++..",
|
||||||
|
".......+++++...+++++++++++..",
|
||||||
|
".........++++....+++++++++..",
|
||||||
|
"..........+++++...++++++++..",
|
||||||
|
"............++++....++++++..",
|
||||||
|
".............+++++...+++++..",
|
||||||
|
"...............+++.....+++..",
|
||||||
|
"................++......++..",
|
||||||
|
"............................",
|
||||||
|
"............................"};
|
31
symbols/frew1.xpm
Normal file
31
symbols/frew1.xpm
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/* XPM */
|
||||||
|
static char * frew1_xpm[] = {
|
||||||
|
"28 26 2 1",
|
||||||
|
". c #FFFFFF",
|
||||||
|
"+ c #000000",
|
||||||
|
"............................",
|
||||||
|
"............................",
|
||||||
|
"................++......++..",
|
||||||
|
"...............+++.....+++..",
|
||||||
|
".............+++++...+++++..",
|
||||||
|
"............++++....++++++..",
|
||||||
|
"..........+++++...++++++++..",
|
||||||
|
".........++++....+++++++++..",
|
||||||
|
".......+++++...+++++++++++..",
|
||||||
|
"......++++....++++++++++++..",
|
||||||
|
"....+++++...++++++++++++++..",
|
||||||
|
"...++++.....++++++++++++++..",
|
||||||
|
"....+++++...++++++++++++++..",
|
||||||
|
"......++++....++++++++++++..",
|
||||||
|
".......+++++...+++++++++++..",
|
||||||
|
".........++++....+++++++++..",
|
||||||
|
"..........+++++...++++++++..",
|
||||||
|
"............++++....++++++..",
|
||||||
|
".............+++++...+++++..",
|
||||||
|
"...............+++.....+++..",
|
||||||
|
"................++......++..",
|
||||||
|
"............................",
|
||||||
|
"....................++++++..",
|
||||||
|
"....................++++++..",
|
||||||
|
"............................",
|
||||||
|
"............................"};
|
31
symbols/frew2.xpm
Normal file
31
symbols/frew2.xpm
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/* XPM */
|
||||||
|
static char * frew2_xpm[] = {
|
||||||
|
"28 26 2 1",
|
||||||
|
". c #FFFFFF",
|
||||||
|
"+ c #000000",
|
||||||
|
"............................",
|
||||||
|
"............................",
|
||||||
|
"................++......++..",
|
||||||
|
"...............+++.....+++..",
|
||||||
|
".............+++++...+++++..",
|
||||||
|
"............++++....++++++..",
|
||||||
|
"..........+++++...++++++++..",
|
||||||
|
".........++++....+++++++++..",
|
||||||
|
".......+++++...+++++++++++..",
|
||||||
|
"......++++....++++++++++++..",
|
||||||
|
"....+++++...++++++++++++++..",
|
||||||
|
"...++++.....++++++++++++++..",
|
||||||
|
"....+++++...++++++++++++++..",
|
||||||
|
"......++++....++++++++++++..",
|
||||||
|
".......+++++...+++++++++++..",
|
||||||
|
".........++++....+++++++++..",
|
||||||
|
"..........+++++...++++++++..",
|
||||||
|
"............++++....++++++..",
|
||||||
|
".............+++++...+++++..",
|
||||||
|
"...............+++.....+++..",
|
||||||
|
"................++......++..",
|
||||||
|
"............................",
|
||||||
|
"...........++++++...++++++..",
|
||||||
|
"...........++++++...++++++..",
|
||||||
|
"............................",
|
||||||
|
"............................"};
|
31
symbols/frew3.xpm
Normal file
31
symbols/frew3.xpm
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/* XPM */
|
||||||
|
static char * frew3_xpm[] = {
|
||||||
|
"28 26 2 1",
|
||||||
|
". c #FFFFFF",
|
||||||
|
"+ c #000000",
|
||||||
|
"............................",
|
||||||
|
"............................",
|
||||||
|
"................++......++..",
|
||||||
|
"...............+++.....+++..",
|
||||||
|
".............+++++...+++++..",
|
||||||
|
"............++++....++++++..",
|
||||||
|
"..........+++++...++++++++..",
|
||||||
|
".........++++....+++++++++..",
|
||||||
|
".......+++++...+++++++++++..",
|
||||||
|
"......++++....++++++++++++..",
|
||||||
|
"....+++++...++++++++++++++..",
|
||||||
|
"...++++.....++++++++++++++..",
|
||||||
|
"....+++++...++++++++++++++..",
|
||||||
|
"......++++....++++++++++++..",
|
||||||
|
".......+++++...+++++++++++..",
|
||||||
|
".........++++....+++++++++..",
|
||||||
|
"..........+++++...++++++++..",
|
||||||
|
"............++++....++++++..",
|
||||||
|
".............+++++...+++++..",
|
||||||
|
"...............+++.....+++..",
|
||||||
|
"................++......++..",
|
||||||
|
"............................",
|
||||||
|
"..++++++...++++++...++++++..",
|
||||||
|
"..++++++...++++++...++++++..",
|
||||||
|
"............................",
|
||||||
|
"............................"};
|
25
symbols/mute.xpm
Normal file
25
symbols/mute.xpm
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/* XPM */
|
||||||
|
static char * mute_xpm[] = {
|
||||||
|
"26 20 2 1",
|
||||||
|
". c #FFFFFF",
|
||||||
|
"+ c #000000",
|
||||||
|
"......++.......++.......++",
|
||||||
|
"......+++....++++......+++",
|
||||||
|
".......+++..+++++.....+++.",
|
||||||
|
"........+++..+.++....+++..",
|
||||||
|
".......+.+++...++...+++...",
|
||||||
|
".....++++.+++..++..+++....",
|
||||||
|
"++++++++...+++....+++.....",
|
||||||
|
"+++++++.....+++..+++......",
|
||||||
|
"++...++......++++++.......",
|
||||||
|
"++...++.......++++........",
|
||||||
|
"++...++.......++++........",
|
||||||
|
"++...++......++++++.......",
|
||||||
|
"+++++++.....+++..+++......",
|
||||||
|
"++++++++...+++....+++.....",
|
||||||
|
".....++++.+++..++..+++....",
|
||||||
|
".......+.+++...++...+++...",
|
||||||
|
"........+++..+.++....+++..",
|
||||||
|
".......+++..+++++.....+++.",
|
||||||
|
"......+++....++++......+++",
|
||||||
|
"......++.......++.......++"};
|
31
symbols/pause.xpm
Normal file
31
symbols/pause.xpm
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/* XPM */
|
||||||
|
static char * pause_xpm[] = {
|
||||||
|
"28 26 2 1",
|
||||||
|
". c #FFFFFF",
|
||||||
|
"+ c #000000",
|
||||||
|
"............................",
|
||||||
|
"............................",
|
||||||
|
"......+++++......+++++......",
|
||||||
|
"......+++++......+++++......",
|
||||||
|
"......+++++......+++++......",
|
||||||
|
"......+++++......+++++......",
|
||||||
|
"......+++++......+++++......",
|
||||||
|
"......+++++......+++++......",
|
||||||
|
"......+++++......+++++......",
|
||||||
|
"......+++++......+++++......",
|
||||||
|
"......+++++......+++++......",
|
||||||
|
"......+++++......+++++......",
|
||||||
|
"......+++++......+++++......",
|
||||||
|
"......+++++......+++++......",
|
||||||
|
"......+++++......+++++......",
|
||||||
|
"......+++++......+++++......",
|
||||||
|
"......+++++......+++++......",
|
||||||
|
"......+++++......+++++......",
|
||||||
|
"......+++++......+++++......",
|
||||||
|
"......+++++......+++++......",
|
||||||
|
"......+++++......+++++......",
|
||||||
|
"......+++++......+++++......",
|
||||||
|
"......+++++......+++++......",
|
||||||
|
"......+++++......+++++......",
|
||||||
|
"............................",
|
||||||
|
"............................"};
|
31
symbols/play.xpm
Normal file
31
symbols/play.xpm
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/* XPM */
|
||||||
|
static char * play_xpm[] = {
|
||||||
|
"28 26 2 1",
|
||||||
|
". c #FFFFFF",
|
||||||
|
"+ c #000000",
|
||||||
|
"............................",
|
||||||
|
"............................",
|
||||||
|
"......++....................",
|
||||||
|
"......+++...................",
|
||||||
|
"......+++++.................",
|
||||||
|
"......++++++................",
|
||||||
|
"......++++++++..............",
|
||||||
|
"......+++++++++.............",
|
||||||
|
"......+++++++++++...........",
|
||||||
|
"......++++++++++++..........",
|
||||||
|
"......++++++++++++++........",
|
||||||
|
"......+++++++++++++++.......",
|
||||||
|
"......++++++++++++++++......",
|
||||||
|
"......++++++++++++++++......",
|
||||||
|
"......+++++++++++++++.......",
|
||||||
|
"......++++++++++++++........",
|
||||||
|
"......++++++++++++..........",
|
||||||
|
"......+++++++++++...........",
|
||||||
|
"......+++++++++.............",
|
||||||
|
"......++++++++..............",
|
||||||
|
"......++++++................",
|
||||||
|
"......+++++.................",
|
||||||
|
"......+++...................",
|
||||||
|
"......++....................",
|
||||||
|
"............................",
|
||||||
|
"............................"};
|
23
symbols/radio.xpm
Normal file
23
symbols/radio.xpm
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/* XPM */
|
||||||
|
static char * radio_xpm[] = {
|
||||||
|
"27 18 2 1",
|
||||||
|
". c #FFFFFF",
|
||||||
|
"+ c #000000",
|
||||||
|
"...........................",
|
||||||
|
"............+++++..........",
|
||||||
|
"............+++++++++......",
|
||||||
|
"............+++++++++++....",
|
||||||
|
"............+++...++++++...",
|
||||||
|
"............+++.....++++...",
|
||||||
|
"............+++.....+++....",
|
||||||
|
"............+++.....++.....",
|
||||||
|
"............+++............",
|
||||||
|
"............+++............",
|
||||||
|
"............+++............",
|
||||||
|
"......+++++++++............",
|
||||||
|
"...+++++++++++++...........",
|
||||||
|
"..+++++++++++++++..........",
|
||||||
|
"..+++++++++++++++..........",
|
||||||
|
"...+++++++++++++...........",
|
||||||
|
".....++++++++++............",
|
||||||
|
"..........................."};
|
23
symbols/recording.xpm
Normal file
23
symbols/recording.xpm
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/* XPM */
|
||||||
|
static char * recording_xpm[] = {
|
||||||
|
"27 18 2 1",
|
||||||
|
". c #FFFFFF",
|
||||||
|
"+ c #000000",
|
||||||
|
"...........................",
|
||||||
|
"...........................",
|
||||||
|
"..++++++...++++++..++++++..",
|
||||||
|
"..+++++++.+++++++.+++++++..",
|
||||||
|
"..++...++.++......++.......",
|
||||||
|
"..++...++.++......++.......",
|
||||||
|
"..++...++.++......++.......",
|
||||||
|
"..++...++.++......++.......",
|
||||||
|
"..++++++..+++++...++.......",
|
||||||
|
"..++++....+++++...++.......",
|
||||||
|
"..++.++...++......++.......",
|
||||||
|
"..++..++..++......++.......",
|
||||||
|
"..++...++.++......++.......",
|
||||||
|
"..++...++.++......++.......",
|
||||||
|
"..++...++.+++++++.+++++++..",
|
||||||
|
"..++...++..++++++..++++++..",
|
||||||
|
"...........................",
|
||||||
|
"..........................."};
|
31
symbols/sfwd.xpm
Normal file
31
symbols/sfwd.xpm
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/* XPM */
|
||||||
|
static char * sfwd_xpm[] = {
|
||||||
|
"28 26 2 1",
|
||||||
|
". c #FFFFFF",
|
||||||
|
"+ c #000000",
|
||||||
|
"............................",
|
||||||
|
"............................",
|
||||||
|
"..+++++...++................",
|
||||||
|
"..+++++...+++...............",
|
||||||
|
"..+++++...+++++.............",
|
||||||
|
"..+++++...++++++............",
|
||||||
|
"..+++++...++++++++..........",
|
||||||
|
"..+++++...+++++++++.........",
|
||||||
|
"..+++++...+++++++++++.......",
|
||||||
|
"..+++++...++++++++++++......",
|
||||||
|
"..+++++...++++++++++++++....",
|
||||||
|
"..+++++...+++++++++++++++...",
|
||||||
|
"..+++++...++++++++++++++++..",
|
||||||
|
"..+++++...++++++++++++++++..",
|
||||||
|
"..+++++...+++++++++++++++...",
|
||||||
|
"..+++++...++++++++++++++....",
|
||||||
|
"..+++++...++++++++++++......",
|
||||||
|
"..+++++...+++++++++++.......",
|
||||||
|
"..+++++...+++++++++.........",
|
||||||
|
"..+++++...++++++++..........",
|
||||||
|
"..+++++...++++++............",
|
||||||
|
"..+++++...+++++.............",
|
||||||
|
"..+++++...+++...............",
|
||||||
|
"..+++++...++................",
|
||||||
|
"............................",
|
||||||
|
"............................"};
|
31
symbols/sfwd1.xpm
Normal file
31
symbols/sfwd1.xpm
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/* XPM */
|
||||||
|
static char * sfwd1_xpm[] = {
|
||||||
|
"28 26 2 1",
|
||||||
|
". c #FFFFFF",
|
||||||
|
"+ c #000000",
|
||||||
|
"............................",
|
||||||
|
"............................",
|
||||||
|
"..+++++...++................",
|
||||||
|
"..+++++...+++...............",
|
||||||
|
"..+++++...+++++.............",
|
||||||
|
"..+++++...++++++............",
|
||||||
|
"..+++++...++++++++..........",
|
||||||
|
"..+++++...+++++++++.........",
|
||||||
|
"..+++++...+++++++++++.......",
|
||||||
|
"..+++++...++++++++++++......",
|
||||||
|
"..+++++...++++++++++++++....",
|
||||||
|
"..+++++...+++++++++++++++...",
|
||||||
|
"..+++++...++++++++++++++....",
|
||||||
|
"..+++++...++++++++++++......",
|
||||||
|
"..+++++...+++++++++++.......",
|
||||||
|
"..+++++...+++++++++.........",
|
||||||
|
"..+++++...++++++++..........",
|
||||||
|
"..+++++...++++++............",
|
||||||
|
"..+++++...+++++.............",
|
||||||
|
"..+++++...+++...............",
|
||||||
|
"..+++++...++................",
|
||||||
|
"............................",
|
||||||
|
"..++++++....................",
|
||||||
|
"..++++++....................",
|
||||||
|
"............................",
|
||||||
|
"............................"};
|
31
symbols/sfwd2.xpm
Normal file
31
symbols/sfwd2.xpm
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/* XPM */
|
||||||
|
static char * sfwd2_xpm[] = {
|
||||||
|
"28 26 2 1",
|
||||||
|
". c #FFFFFF",
|
||||||
|
"+ c #000000",
|
||||||
|
"............................",
|
||||||
|
"............................",
|
||||||
|
"..+++++...++................",
|
||||||
|
"..+++++...+++...............",
|
||||||
|
"..+++++...+++++.............",
|
||||||
|
"..+++++...++++++............",
|
||||||
|
"..+++++...++++++++..........",
|
||||||
|
"..+++++...+++++++++.........",
|
||||||
|
"..+++++...+++++++++++.......",
|
||||||
|
"..+++++...++++++++++++......",
|
||||||
|
"..+++++...++++++++++++++....",
|
||||||
|
"..+++++...+++++++++++++++...",
|
||||||
|
"..+++++...++++++++++++++....",
|
||||||
|
"..+++++...++++++++++++......",
|
||||||
|
"..+++++...+++++++++++.......",
|
||||||
|
"..+++++...+++++++++.........",
|
||||||
|
"..+++++...++++++++..........",
|
||||||
|
"..+++++...++++++............",
|
||||||
|
"..+++++...+++++.............",
|
||||||
|
"..+++++...+++...............",
|
||||||
|
"..+++++...++................",
|
||||||
|
"............................",
|
||||||
|
"..++++++...++++++...........",
|
||||||
|
"..++++++...++++++...........",
|
||||||
|
"............................",
|
||||||
|
"............................"};
|
31
symbols/sfwd3.xpm
Normal file
31
symbols/sfwd3.xpm
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/* XPM */
|
||||||
|
static char * sfwd3_xpm[] = {
|
||||||
|
"28 26 2 1",
|
||||||
|
". c #FFFFFF",
|
||||||
|
"+ c #000000",
|
||||||
|
"............................",
|
||||||
|
"............................",
|
||||||
|
"..+++++...++................",
|
||||||
|
"..+++++...+++...............",
|
||||||
|
"..+++++...+++++.............",
|
||||||
|
"..+++++...++++++............",
|
||||||
|
"..+++++...++++++++..........",
|
||||||
|
"..+++++...+++++++++.........",
|
||||||
|
"..+++++...+++++++++++.......",
|
||||||
|
"..+++++...++++++++++++......",
|
||||||
|
"..+++++...++++++++++++++....",
|
||||||
|
"..+++++...+++++++++++++++...",
|
||||||
|
"..+++++...++++++++++++++....",
|
||||||
|
"..+++++...++++++++++++......",
|
||||||
|
"..+++++...+++++++++++.......",
|
||||||
|
"..+++++...+++++++++.........",
|
||||||
|
"..+++++...++++++++..........",
|
||||||
|
"..+++++...++++++............",
|
||||||
|
"..+++++...+++++.............",
|
||||||
|
"..+++++...+++...............",
|
||||||
|
"..+++++...++................",
|
||||||
|
"............................",
|
||||||
|
"..++++++...++++++...++++++..",
|
||||||
|
"..++++++...++++++...++++++..",
|
||||||
|
"............................",
|
||||||
|
"............................"};
|
31
symbols/srew.xpm
Normal file
31
symbols/srew.xpm
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/* XPM */
|
||||||
|
static char * srew_xpm[] = {
|
||||||
|
"28 26 2 1",
|
||||||
|
". c #FFFFFF",
|
||||||
|
"+ c #000000",
|
||||||
|
"............................",
|
||||||
|
"............................",
|
||||||
|
"................++...+++++..",
|
||||||
|
"...............+++...+++++..",
|
||||||
|
".............+++++...+++++..",
|
||||||
|
"............++++++...+++++..",
|
||||||
|
"..........++++++++...+++++..",
|
||||||
|
".........+++++++++...+++++..",
|
||||||
|
".......+++++++++++...+++++..",
|
||||||
|
"......++++++++++++...+++++..",
|
||||||
|
"....++++++++++++++...+++++..",
|
||||||
|
"...+++++++++++++++...+++++..",
|
||||||
|
"..++++++++++++++++...+++++..",
|
||||||
|
"..++++++++++++++++...+++++..",
|
||||||
|
"...+++++++++++++++...+++++..",
|
||||||
|
"....++++++++++++++...+++++..",
|
||||||
|
"......++++++++++++...+++++..",
|
||||||
|
".......+++++++++++...+++++..",
|
||||||
|
".........+++++++++...+++++..",
|
||||||
|
"..........++++++++...+++++..",
|
||||||
|
"............++++++...+++++..",
|
||||||
|
".............+++++...+++++..",
|
||||||
|
"...............+++...+++++..",
|
||||||
|
"................++...+++++..",
|
||||||
|
"............................",
|
||||||
|
"............................"};
|
31
symbols/srew1.xpm
Normal file
31
symbols/srew1.xpm
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/* XPM */
|
||||||
|
static char * srew1_xpm[] = {
|
||||||
|
"28 26 2 1",
|
||||||
|
". c #FFFFFF",
|
||||||
|
"+ c #000000",
|
||||||
|
"............................",
|
||||||
|
"............................",
|
||||||
|
"................++...+++++..",
|
||||||
|
"...............+++...+++++..",
|
||||||
|
".............+++++...+++++..",
|
||||||
|
"............++++++...+++++..",
|
||||||
|
"..........++++++++...+++++..",
|
||||||
|
".........+++++++++...+++++..",
|
||||||
|
".......+++++++++++...+++++..",
|
||||||
|
"......++++++++++++...+++++..",
|
||||||
|
"....++++++++++++++...+++++..",
|
||||||
|
"...+++++++++++++++...+++++..",
|
||||||
|
"....++++++++++++++...+++++..",
|
||||||
|
"......++++++++++++...+++++..",
|
||||||
|
".......+++++++++++...+++++..",
|
||||||
|
".........+++++++++...+++++..",
|
||||||
|
"..........++++++++...+++++..",
|
||||||
|
"............++++++...+++++..",
|
||||||
|
".............+++++...+++++..",
|
||||||
|
"...............+++...+++++..",
|
||||||
|
"................++...+++++..",
|
||||||
|
"............................",
|
||||||
|
"....................++++++..",
|
||||||
|
"....................++++++..",
|
||||||
|
"............................",
|
||||||
|
"............................"};
|
31
symbols/srew2.xpm
Normal file
31
symbols/srew2.xpm
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/* XPM */
|
||||||
|
static char * srew2_xpm[] = {
|
||||||
|
"28 26 2 1",
|
||||||
|
". c #FFFFFF",
|
||||||
|
"+ c #000000",
|
||||||
|
"............................",
|
||||||
|
"............................",
|
||||||
|
"................++...+++++..",
|
||||||
|
"...............+++...+++++..",
|
||||||
|
".............+++++...+++++..",
|
||||||
|
"............++++++...+++++..",
|
||||||
|
"..........++++++++...+++++..",
|
||||||
|
".........+++++++++...+++++..",
|
||||||
|
".......+++++++++++...+++++..",
|
||||||
|
"......++++++++++++...+++++..",
|
||||||
|
"....++++++++++++++...+++++..",
|
||||||
|
"...+++++++++++++++...+++++..",
|
||||||
|
"....++++++++++++++...+++++..",
|
||||||
|
"......++++++++++++...+++++..",
|
||||||
|
".......+++++++++++...+++++..",
|
||||||
|
".........+++++++++...+++++..",
|
||||||
|
"..........++++++++...+++++..",
|
||||||
|
"............++++++...+++++..",
|
||||||
|
".............+++++...+++++..",
|
||||||
|
"...............+++...+++++..",
|
||||||
|
"................++...+++++..",
|
||||||
|
"............................",
|
||||||
|
"...........++++++...++++++..",
|
||||||
|
"...........++++++...++++++..",
|
||||||
|
"............................",
|
||||||
|
"............................"};
|
31
symbols/srew3.xpm
Normal file
31
symbols/srew3.xpm
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/* XPM */
|
||||||
|
static char * srew3_xpm[] = {
|
||||||
|
"28 26 2 1",
|
||||||
|
". c #FFFFFF",
|
||||||
|
"+ c #000000",
|
||||||
|
"............................",
|
||||||
|
"............................",
|
||||||
|
"................++...+++++..",
|
||||||
|
"...............+++...+++++..",
|
||||||
|
".............+++++...+++++..",
|
||||||
|
"............++++++...+++++..",
|
||||||
|
"..........++++++++...+++++..",
|
||||||
|
".........+++++++++...+++++..",
|
||||||
|
".......+++++++++++...+++++..",
|
||||||
|
"......++++++++++++...+++++..",
|
||||||
|
"....++++++++++++++...+++++..",
|
||||||
|
"...+++++++++++++++...+++++..",
|
||||||
|
"....++++++++++++++...+++++..",
|
||||||
|
"......++++++++++++...+++++..",
|
||||||
|
".......+++++++++++...+++++..",
|
||||||
|
".........+++++++++...+++++..",
|
||||||
|
"..........++++++++...+++++..",
|
||||||
|
"............++++++...+++++..",
|
||||||
|
".............+++++...+++++..",
|
||||||
|
"...............+++...+++++..",
|
||||||
|
"................++...+++++..",
|
||||||
|
"............................",
|
||||||
|
"..++++++...++++++...++++++..",
|
||||||
|
"..++++++...++++++...++++++..",
|
||||||
|
"............................",
|
||||||
|
"............................"};
|
23
symbols/teletext.xpm
Normal file
23
symbols/teletext.xpm
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/* XPM */
|
||||||
|
static char * teletext_xpm[] = {
|
||||||
|
"27 18 2 1",
|
||||||
|
". c #FFFFFF",
|
||||||
|
"+ c #000000",
|
||||||
|
"...........................",
|
||||||
|
"...........................",
|
||||||
|
"..+++++++++++++++++++++++..",
|
||||||
|
"..+++++++++++++++++++++++..",
|
||||||
|
"..++...................++..",
|
||||||
|
"..++..+++++++++++++++..++..",
|
||||||
|
"..++..+++++++++++++++..++..",
|
||||||
|
"..++...................++..",
|
||||||
|
"..++..+++++++++++++++..++..",
|
||||||
|
"..++..+++++++++++++++..++..",
|
||||||
|
"..++...................++..",
|
||||||
|
"..++..+++++++++++++++..++..",
|
||||||
|
"..++..+++++++++++++++..++..",
|
||||||
|
"..++...................++..",
|
||||||
|
"..+++++++++++++++++++++++..",
|
||||||
|
"..+++++++++++++++++++++++..",
|
||||||
|
"...........................",
|
||||||
|
"..........................."};
|
19
symbols/volume.xpm
Normal file
19
symbols/volume.xpm
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/* XPM */
|
||||||
|
static char * volume_xpm[] = {
|
||||||
|
"28 14 2 1",
|
||||||
|
". c #FFFFFF",
|
||||||
|
"+ c #000000",
|
||||||
|
"..........................++",
|
||||||
|
"........................++++",
|
||||||
|
"......................++++++",
|
||||||
|
"....................++++++++",
|
||||||
|
"..................++++++++++",
|
||||||
|
"................++++++++++++",
|
||||||
|
"..............++++++++++++++",
|
||||||
|
"............++++++++++++++++",
|
||||||
|
"..........++++++++++++++++++",
|
||||||
|
"........++++++++++++++++++++",
|
||||||
|
"......++++++++++++++++++++++",
|
||||||
|
"....++++++++++++++++++++++++",
|
||||||
|
"..++++++++++++++++++++++++++",
|
||||||
|
"++++++++++++++++++++++++++++"};
|
305
themes.c
Normal file
305
themes.c
Normal file
@ -0,0 +1,305 @@
|
|||||||
|
/*
|
||||||
|
* themes.c: Color themes used by skins
|
||||||
|
*
|
||||||
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
|
* how to reach the author.
|
||||||
|
*
|
||||||
|
* $Id: themes.c 1.1 2004/05/16 09:43:14 kls Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "themes.h"
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "config.h"
|
||||||
|
#include "tools.h"
|
||||||
|
|
||||||
|
// --- cTheme ----------------------------------------------------------------
|
||||||
|
|
||||||
|
cTheme::cTheme(void)
|
||||||
|
{
|
||||||
|
name = strdup("default");
|
||||||
|
memset(descriptions, 0, sizeof(descriptions));
|
||||||
|
memset(colorNames, 0, sizeof(colorNames));
|
||||||
|
memset(colorValues, 0, sizeof(colorValues));
|
||||||
|
descriptions[0] = strdup("Default");
|
||||||
|
}
|
||||||
|
|
||||||
|
cTheme::~cTheme()
|
||||||
|
{
|
||||||
|
free(name);
|
||||||
|
for (int i = 0; i < I18nNumLanguages; i++)
|
||||||
|
free(descriptions[i]);
|
||||||
|
for (int i = 0; i < MaxThemeColors; i++)
|
||||||
|
free(colorNames[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cTheme::FileNameOk(const char *FileName, bool SetName)
|
||||||
|
{
|
||||||
|
const char *error = NULL;
|
||||||
|
if (!isempty(FileName)) {
|
||||||
|
const char *d = strrchr(FileName, '/');
|
||||||
|
if (d)
|
||||||
|
FileName = d + 1;
|
||||||
|
const char *n = strchr(FileName, '-');
|
||||||
|
if (n) {
|
||||||
|
if (n > FileName) {
|
||||||
|
if (!strchr(++n, '-')) {
|
||||||
|
const char *e = strchr(n, '.');
|
||||||
|
if (e && strcmp(e, ".theme") == 0) {
|
||||||
|
if (e - n >= 1) {
|
||||||
|
// FileName is ok
|
||||||
|
if (SetName) {
|
||||||
|
free(name);
|
||||||
|
name = strndup(n, e - n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
error = "missing theme name";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
error = "invalid extension";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
error = "too many '-'";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
error = "missing skin name";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
error = "missing '-'";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
error = "empty";
|
||||||
|
if (error)
|
||||||
|
esyslog("ERROR: invalid theme file name (%s): '%s'", error, FileName);
|
||||||
|
return !error;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *cTheme::Description(void)
|
||||||
|
{
|
||||||
|
char *s = descriptions[Setup.OSDLanguage];
|
||||||
|
if (!s)
|
||||||
|
s = descriptions[0];
|
||||||
|
return s ? s : name;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cTheme::Load(const char *FileName, bool OnlyDescriptions)
|
||||||
|
{
|
||||||
|
if (!FileNameOk(FileName, true))
|
||||||
|
return false;
|
||||||
|
bool result = false;
|
||||||
|
if (!OnlyDescriptions)
|
||||||
|
isyslog("loading %s", FileName);
|
||||||
|
FILE *f = fopen(FileName, "r");
|
||||||
|
if (f) {
|
||||||
|
int line = 0;
|
||||||
|
result = true;
|
||||||
|
char *s;
|
||||||
|
const char *error = NULL;
|
||||||
|
while ((s = readline(f)) != NULL) {
|
||||||
|
line++;
|
||||||
|
char *p = strchr(s, '#');
|
||||||
|
if (p)
|
||||||
|
*p = 0;
|
||||||
|
s = stripspace(skipspace(s));
|
||||||
|
if (!isempty(s)) {
|
||||||
|
char *n = s;
|
||||||
|
char *v = strchr(s, '=');
|
||||||
|
if (v) {
|
||||||
|
*v++ = 0;
|
||||||
|
n = stripspace(skipspace(n));
|
||||||
|
v = stripspace(skipspace(v));
|
||||||
|
if (strstr(n, "Description") == n) {
|
||||||
|
int lang = 0;
|
||||||
|
char *l = strchr(n, '.');
|
||||||
|
if (l)
|
||||||
|
lang = I18nLanguageIndex(++l);
|
||||||
|
if (lang >= 0)
|
||||||
|
descriptions[lang] = strdup(v);
|
||||||
|
else
|
||||||
|
error = "invalid language code";
|
||||||
|
}
|
||||||
|
else if (!OnlyDescriptions) {
|
||||||
|
for (int i = 0; i < MaxThemeColors; i++) {
|
||||||
|
if (colorNames[i]) {
|
||||||
|
if (strcmp(n, colorNames[i]) == 0) {
|
||||||
|
char *p = NULL;
|
||||||
|
errno = 0;
|
||||||
|
tColor c = strtoul(v, &p, 16);
|
||||||
|
if (!errno && !*p)
|
||||||
|
colorValues[i] = c;
|
||||||
|
else
|
||||||
|
error = "invalid color value";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
error = "unknown color name";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
error = "missing value";
|
||||||
|
}
|
||||||
|
if (error) {
|
||||||
|
result = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!result)
|
||||||
|
esyslog("ERROR: error in %s, line %d%s%s\n", FileName, line, error ? ": " : "", error ? error : "");
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LOG_ERROR_STR(FileName);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cTheme::Save(const char *FileName)
|
||||||
|
{
|
||||||
|
if (!FileNameOk(FileName))
|
||||||
|
return false;
|
||||||
|
bool result = true;
|
||||||
|
cSafeFile f(FileName);
|
||||||
|
if (f.Open()) {
|
||||||
|
for (int i = 0; i < I18nNumLanguages; i++) {
|
||||||
|
if (descriptions[i])
|
||||||
|
fprintf(f, "Description%s%.*s = %s\n", i ? "." : "", 3, i ? I18nLanguageCode(i) : "", descriptions[i]);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < MaxThemeColors; i++) {
|
||||||
|
if (colorNames[i])
|
||||||
|
fprintf(f, "%s = %08X\n", colorNames[i], colorValues[i]);
|
||||||
|
}
|
||||||
|
if (!f.Close())
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
result = false;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cTheme::AddColor(const char *Name, tColor Color)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < MaxThemeColors; i++) {
|
||||||
|
if (colorNames[i]) {
|
||||||
|
if (strcmp(Name, colorNames[i]) == 0) {
|
||||||
|
colorValues[i] = Color;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
colorNames[i] = strdup(Name);
|
||||||
|
colorValues[i] = Color;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
tColor cTheme::Color(int Subject)
|
||||||
|
{
|
||||||
|
return (Subject >= 0 && Subject < MaxThemeColors) ? colorValues[Subject] : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- cThemes ---------------------------------------------------------------
|
||||||
|
|
||||||
|
char *cThemes::themesDirectory = NULL;
|
||||||
|
|
||||||
|
cThemes::cThemes(void)
|
||||||
|
{
|
||||||
|
numThemes = 0;
|
||||||
|
names = 0;
|
||||||
|
fileNames = NULL;
|
||||||
|
descriptions = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
cThemes::~cThemes()
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void cThemes::Clear(void)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < numThemes; i++) {
|
||||||
|
free(names[i]);
|
||||||
|
free(fileNames[i]);
|
||||||
|
free(descriptions[i]);
|
||||||
|
}
|
||||||
|
free(names);
|
||||||
|
free(fileNames);
|
||||||
|
free(descriptions);
|
||||||
|
numThemes = 0;
|
||||||
|
names = 0;
|
||||||
|
fileNames = NULL;
|
||||||
|
descriptions = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cThemes::Load(const char *SkinName)
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
if (themesDirectory) {
|
||||||
|
DIR *d = opendir(themesDirectory);
|
||||||
|
if (d) {
|
||||||
|
struct dirent *e;
|
||||||
|
while ((e = readdir(d)) != NULL) {
|
||||||
|
if (strcmp(e->d_name, ".") && strcmp(e->d_name, "..")) {
|
||||||
|
if (strstr(e->d_name, SkinName) == e->d_name && e->d_name[strlen(SkinName)] == '-') {
|
||||||
|
const char *FileName = AddDirectory(themesDirectory, e->d_name);
|
||||||
|
cTheme Theme;
|
||||||
|
if (Theme.Load(FileName, true)) {
|
||||||
|
names = (char **)realloc(names, (numThemes + 1) * sizeof(char *));
|
||||||
|
names[numThemes] = strdup(Theme.Name());
|
||||||
|
fileNames = (char **)realloc(fileNames, (numThemes + 1) * sizeof(char *));
|
||||||
|
fileNames[numThemes] = strdup(FileName);
|
||||||
|
descriptions = (char **)realloc(descriptions, (numThemes + 1) * sizeof(char *));
|
||||||
|
descriptions[numThemes] = strdup(Theme.Description());
|
||||||
|
numThemes++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closedir(d);
|
||||||
|
return numThemes > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cThemes::GetThemeIndex(const char *Description)
|
||||||
|
{
|
||||||
|
int index = 0;
|
||||||
|
for (int i = 0; i < numThemes; i++) {
|
||||||
|
if (strcmp(descriptions[i], Description) == 0)
|
||||||
|
return i;
|
||||||
|
if (strcmp(descriptions[i], "Default") == 0)
|
||||||
|
index = 1;
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cThemes::SetThemesDirectory(const char *ThemesDirectory)
|
||||||
|
{
|
||||||
|
free(themesDirectory);
|
||||||
|
themesDirectory = strdup(ThemesDirectory);
|
||||||
|
MakeDirs(themesDirectory, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cThemes::Load(const char *SkinName, const char *ThemeName, cTheme *Theme)
|
||||||
|
{
|
||||||
|
char *FileName = NULL;
|
||||||
|
asprintf(&FileName, "%s/%s-%s.theme", themesDirectory, SkinName, ThemeName);
|
||||||
|
if (access(FileName, F_OK) == 0) // the file exists
|
||||||
|
Theme->Load(FileName);
|
||||||
|
free(FileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cThemes::Save(const char *SkinName, cTheme *Theme)
|
||||||
|
{
|
||||||
|
char *FileName = NULL;
|
||||||
|
asprintf(&FileName, "%s/%s-%s.theme", themesDirectory, SkinName, Theme->Name());
|
||||||
|
if (access(FileName, F_OK) != 0) // the file does not exist
|
||||||
|
Theme->Save(FileName);
|
||||||
|
free(FileName);
|
||||||
|
}
|
82
themes.h
Normal file
82
themes.h
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* themes.h: Color themes used by skins
|
||||||
|
*
|
||||||
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
|
* how to reach the author.
|
||||||
|
*
|
||||||
|
* $Id: themes.h 1.1 2004/05/15 14:22:16 kls Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __THEMES_H
|
||||||
|
#define __THEMES_H
|
||||||
|
|
||||||
|
#include "i18n.h"
|
||||||
|
#include "osd.h"
|
||||||
|
|
||||||
|
class cTheme {
|
||||||
|
public:
|
||||||
|
enum { MaxThemeColors = 128 };
|
||||||
|
private:
|
||||||
|
char *name;
|
||||||
|
char *descriptions[I18nNumLanguages];
|
||||||
|
char *colorNames[MaxThemeColors];
|
||||||
|
tColor colorValues[MaxThemeColors];
|
||||||
|
bool FileNameOk(const char *FileName, bool SetName = false);
|
||||||
|
public:
|
||||||
|
cTheme(void);
|
||||||
|
///< Creates a new theme class.
|
||||||
|
~cTheme();
|
||||||
|
const char *Name(void) { return name; }
|
||||||
|
const char *Description(void);
|
||||||
|
///< Returns a user visible, single line description of this theme.
|
||||||
|
///< The actual text shouldn't be too long, so that it can be
|
||||||
|
///< fully displayed in the Setup/OSD menu.
|
||||||
|
bool Load(const char *FileName, bool OnlyDescriptions = false);
|
||||||
|
///< Loads the theme data from the given file.
|
||||||
|
bool Save(const char *FileName);
|
||||||
|
///< Saves the theme data to the given file.
|
||||||
|
///< FileName must be in the form "<skin>-<theme>.theme", where <skin>
|
||||||
|
///< is the name of the skin this theme applies to, and <theme> is the
|
||||||
|
///< actual theme name, which will be used to identify this theme in the
|
||||||
|
///< 'setup.conf', and is normally not seen by the user. It should
|
||||||
|
///< consist of only lowercase letters and digits.
|
||||||
|
int AddColor(const char *Name, tColor Color);
|
||||||
|
///< Adds a color with the given Name to this theme, initializes it
|
||||||
|
///< with Color and returns an index into the color array that can
|
||||||
|
///< be used in a call to Color() later. The index returned from the
|
||||||
|
///< first call to AddColor() is 0, and subsequent calls will return
|
||||||
|
///< values that are incremented by 1 with every call.
|
||||||
|
///< If a color entry with the given Name already exists, its value
|
||||||
|
///< will be overwritten with Color and the returned index will be
|
||||||
|
///< that of the existing entry.
|
||||||
|
tColor Color(int Subject);
|
||||||
|
///< Returns the color for the given Subject. Subject must be one of
|
||||||
|
///< the values returned by a previous call to AddColor().
|
||||||
|
};
|
||||||
|
|
||||||
|
// A helper macro that simplifies defining theme colors.
|
||||||
|
#define THEME_CLR(Theme, Subject, Color) static const int Subject = Theme.AddColor(#Subject, Color)
|
||||||
|
|
||||||
|
class cThemes {
|
||||||
|
private:
|
||||||
|
int numThemes;
|
||||||
|
char **names;
|
||||||
|
char **fileNames;
|
||||||
|
char **descriptions;
|
||||||
|
static char *themesDirectory;
|
||||||
|
void Clear(void);
|
||||||
|
public:
|
||||||
|
cThemes(void);
|
||||||
|
~cThemes();
|
||||||
|
bool Load(const char *SkinName);
|
||||||
|
int NumThemes(void) { return numThemes; }
|
||||||
|
const char *Name(int Index) { return Index < numThemes ? names[Index] : NULL; }
|
||||||
|
const char *FileName(int Index) { return Index < numThemes ? fileNames[Index] : NULL; }
|
||||||
|
const char * const *Descriptions(void) { return descriptions; }
|
||||||
|
int GetThemeIndex(const char *Description);
|
||||||
|
static void SetThemesDirectory(const char *ThemesDirectory);
|
||||||
|
static void Load(const char *SkinName, const char *ThemeName, cTheme *Theme);
|
||||||
|
static void Save(const char *SkinName, cTheme *Theme);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //__THEMES_H
|
44
vdr.5
44
vdr.5
@ -8,7 +8,7 @@
|
|||||||
.\" License as specified in the file COPYING that comes with the
|
.\" License as specified in the file COPYING that comes with the
|
||||||
.\" vdr distribution.
|
.\" vdr distribution.
|
||||||
.\"
|
.\"
|
||||||
.\" $Id: vdr.5 1.26 2004/02/24 12:36:35 kls Exp $
|
.\" $Id: vdr.5 1.27 2004/05/15 09:24:57 kls Exp $
|
||||||
.\"
|
.\"
|
||||||
.TH vdr 5 "1 Jun 2003" "1.2.0" "Video Disk Recorder Files"
|
.TH vdr 5 "1 Jun 2003" "1.2.0" "Video Disk Recorder Files"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
@ -505,6 +505,48 @@ Examples:
|
|||||||
The file \fIsetup.conf\fR contains the basic configuration options for \fBvdr\fR.
|
The file \fIsetup.conf\fR contains the basic configuration options for \fBvdr\fR.
|
||||||
Each line contains one option in the format "Name = Value".
|
Each line contains one option in the format "Name = Value".
|
||||||
See the MANUAL file for a description of the available options.
|
See the MANUAL file for a description of the available options.
|
||||||
|
.SS THEMES
|
||||||
|
The files \fIthemes/<skin>-<theme>.theme\fR in the config directory contain the
|
||||||
|
color theme definitions for the various skins. In the actual file names \fI<skin>\fR
|
||||||
|
will be replaced by the name if the skin this theme belongs to, and \fI<theme>\fR
|
||||||
|
will be the name of this theme.
|
||||||
|
Each line in a theme file contains one option in the format "Name = Value".
|
||||||
|
Anything after (and including) a '#' character is comment.
|
||||||
|
|
||||||
|
The definitions in a theme file are either \fBcolors\fR or a \fBdescription\fR.
|
||||||
|
.br
|
||||||
|
\fBColors\fR are in the form
|
||||||
|
|
||||||
|
\fBclrTitle = FF123456\fR
|
||||||
|
|
||||||
|
where the name (clrTitle) is one of the names defined in the source code of
|
||||||
|
the \fBskin\fR that uses this theme, through the \fBTHEME_CLR()\fR macro.
|
||||||
|
The value (FF123456) is an eight digit hex number that consist of four bytes,
|
||||||
|
representing alpha (transparency), red, green and blue component of the color.
|
||||||
|
An alpha value of 00 means the color will be completely transparent, while FF
|
||||||
|
means it will be opaque. An RGB value of 000000 results in black, while FFFFFF
|
||||||
|
is white.
|
||||||
|
|
||||||
|
A \fBdescription\fR can be given as
|
||||||
|
|
||||||
|
\fBDescription = Shades of blue\fR
|
||||||
|
|
||||||
|
and will be used in the Setup/OSD menu to select a theme for a given skin.
|
||||||
|
The description should give the user an idea what this theme will be like
|
||||||
|
(for instance, in the given example it would use various shades of blue),
|
||||||
|
and shouldn't be too long to make sure it fits on the Setup screen.
|
||||||
|
The default description always should be given in English. If you want,
|
||||||
|
you can provide language specific descriptions as
|
||||||
|
|
||||||
|
\fBDescription.eng = Shades of blue\fR
|
||||||
|
.br
|
||||||
|
\fBDescription.ger = Blautöne\fR
|
||||||
|
|
||||||
|
where the language code (as defined in VDR/i18n.c) is added to the keyword
|
||||||
|
"Description", separated by a dot. You can enter as many language specific
|
||||||
|
descriptions as there are languages defined in VDR/i18n.h.
|
||||||
|
If a theme file doesn't contain a Description, the name of the theme (as
|
||||||
|
given in the theme's file name) will be used.
|
||||||
.SS AUDIO/VIDEO DATA
|
.SS AUDIO/VIDEO DATA
|
||||||
The files \fI001.vdr\fR...\fI255.vdr\fR are the actual recorded MPEG data
|
The files \fI001.vdr\fR...\fI255.vdr\fR are the actual recorded MPEG data
|
||||||
files. In order to keep the size of an individual file below a given limit,
|
files. In order to keep the size of an individual file below a given limit,
|
||||||
|
51
vdr.c
51
vdr.c
@ -22,7 +22,7 @@
|
|||||||
*
|
*
|
||||||
* The project's page is at http://www.cadsoft.de/vdr
|
* The project's page is at http://www.cadsoft.de/vdr
|
||||||
*
|
*
|
||||||
* $Id: vdr.c 1.180 2004/03/14 14:25:02 kls Exp $
|
* $Id: vdr.c 1.181 2004/05/16 10:12:43 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
@ -45,11 +45,14 @@
|
|||||||
#include "keys.h"
|
#include "keys.h"
|
||||||
#include "lirc.h"
|
#include "lirc.h"
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
#include "osd.h"
|
#include "osdbase.h"
|
||||||
#include "plugin.h"
|
#include "plugin.h"
|
||||||
#include "rcu.h"
|
#include "rcu.h"
|
||||||
#include "recording.h"
|
#include "recording.h"
|
||||||
|
#include "skinclassic.h"
|
||||||
|
#include "skinsttng.h"
|
||||||
#include "sources.h"
|
#include "sources.h"
|
||||||
|
#include "themes.h"
|
||||||
#include "timers.h"
|
#include "timers.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
#include "transfer.h"
|
#include "transfer.h"
|
||||||
@ -310,7 +313,6 @@ int main(int argc, char *argv[])
|
|||||||
// Daemon mode:
|
// Daemon mode:
|
||||||
|
|
||||||
if (DaemonMode) {
|
if (DaemonMode) {
|
||||||
#if !defined(DEBUG_OSD)
|
|
||||||
pid_t pid = fork();
|
pid_t pid = fork();
|
||||||
if (pid < 0) {
|
if (pid < 0) {
|
||||||
fprintf(stderr, "%m\n");
|
fprintf(stderr, "%m\n");
|
||||||
@ -322,10 +324,6 @@ int main(int argc, char *argv[])
|
|||||||
fclose(stdin);
|
fclose(stdin);
|
||||||
fclose(stdout);
|
fclose(stdout);
|
||||||
fclose(stderr);
|
fclose(stderr);
|
||||||
#else
|
|
||||||
fprintf(stderr, "vdr: can't run in daemon mode with DEBUG_OSD on!\n");
|
|
||||||
return 2;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else if (Terminal) {
|
else if (Terminal) {
|
||||||
// Claim new controlling terminal
|
// Claim new controlling terminal
|
||||||
@ -348,6 +346,7 @@ int main(int argc, char *argv[])
|
|||||||
ConfigDirectory = VideoDirectory;
|
ConfigDirectory = VideoDirectory;
|
||||||
|
|
||||||
cPlugin::SetConfigDirectory(ConfigDirectory);
|
cPlugin::SetConfigDirectory(ConfigDirectory);
|
||||||
|
cThemes::SetThemesDirectory(AddDirectory(ConfigDirectory, "themes"));
|
||||||
|
|
||||||
Setup.Load(AddDirectory(ConfigDirectory, "setup.conf"));
|
Setup.Load(AddDirectory(ConfigDirectory, "setup.conf"));
|
||||||
if (!(Sources.Load(AddDirectory(ConfigDirectory, "sources.conf"), true, true) &&
|
if (!(Sources.Load(AddDirectory(ConfigDirectory, "sources.conf"), true, true) &&
|
||||||
@ -416,10 +415,6 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// OSD:
|
|
||||||
|
|
||||||
cOsd::Initialize();
|
|
||||||
|
|
||||||
// User interface:
|
// User interface:
|
||||||
|
|
||||||
Interface = new cInterface(SVDRPport);
|
Interface = new cInterface(SVDRPport);
|
||||||
@ -429,6 +424,13 @@ int main(int argc, char *argv[])
|
|||||||
if (!PluginManager.StartPlugins())
|
if (!PluginManager.StartPlugins())
|
||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
|
// Skins:
|
||||||
|
|
||||||
|
new cSkinClassic;
|
||||||
|
new cSkinSTTNG;
|
||||||
|
Skins.SetCurrent(Setup.OSDSkin);
|
||||||
|
cThemes::Load(Skins.Current()->Name(), Setup.OSDTheme, Skins.Current()->Theme());
|
||||||
|
|
||||||
// Remote Controls:
|
// Remote Controls:
|
||||||
#if defined(REMOTE_RCU)
|
#if defined(REMOTE_RCU)
|
||||||
new cRcuRemote("/dev/ttyS1");
|
new cRcuRemote("/dev/ttyS1");
|
||||||
@ -586,7 +588,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// CAM control:
|
// CAM control:
|
||||||
if (!Menu && !Interface->IsOpen())
|
if (!Menu && !cOsd::IsOpen())
|
||||||
Menu = CamControl();
|
Menu = CamControl();
|
||||||
// User Input:
|
// User Input:
|
||||||
cOsdObject *Interact = Menu ? Menu : cControl::Control();
|
cOsdObject *Interact = Menu ? Menu : cControl::Control();
|
||||||
@ -646,7 +648,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
cDevice::PrimaryDevice()->SetVolume(NORMALKEY(key) == kVolDn ? -VOLUMEDELTA : VOLUMEDELTA);
|
cDevice::PrimaryDevice()->SetVolume(NORMALKEY(key) == kVolDn ? -VOLUMEDELTA : VOLUMEDELTA);
|
||||||
if (!Menu && !Interface->IsOpen())
|
if (!Menu && !cOsd::IsOpen())
|
||||||
Menu = Temp = cDisplayVolume::Create();
|
Menu = Temp = cDisplayVolume::Create();
|
||||||
cDisplayVolume::Process(key);
|
cDisplayVolume::Process(key);
|
||||||
key = kNone; // nobody else needs to see these keys
|
key = kNone; // nobody else needs to see these keys
|
||||||
@ -657,7 +659,7 @@ int main(int argc, char *argv[])
|
|||||||
DELETENULL(Menu);
|
DELETENULL(Menu);
|
||||||
Temp = NULL;
|
Temp = NULL;
|
||||||
if (!cRecordControls::PauseLiveVideo())
|
if (!cRecordControls::PauseLiveVideo())
|
||||||
Interface->Error(tr("No free DVB device to record!"));
|
Skins.Message(mtError, tr("No free DVB device to record!"));
|
||||||
key = kNone; // nobody else needs to see this key
|
key = kNone; // nobody else needs to see this key
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -665,9 +667,9 @@ int main(int argc, char *argv[])
|
|||||||
case kRecord:
|
case kRecord:
|
||||||
if (!cControl::Control()) {
|
if (!cControl::Control()) {
|
||||||
if (cRecordControls::Start())
|
if (cRecordControls::Start())
|
||||||
;//XXX Interface->Info(tr("Recording"));
|
;//XXX Skins.Message(mtInfo, tr("Recording"));
|
||||||
else
|
else
|
||||||
Interface->Error(tr("No free DVB device to record!"));
|
Skins.Message(mtError, tr("No free DVB device to record!"));
|
||||||
key = kNone; // nobody else needs to see this key
|
key = kNone; // nobody else needs to see this key
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -677,7 +679,7 @@ int main(int argc, char *argv[])
|
|||||||
cControl::Shutdown();
|
cControl::Shutdown();
|
||||||
Temp = NULL;
|
Temp = NULL;
|
||||||
if (!Shutdown) {
|
if (!Shutdown) {
|
||||||
Interface->Error(tr("Can't shutdown - option '-s' not given!"));
|
Skins.Message(mtError, tr("Can't shutdown - option '-s' not given!"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (cRecordControls::Active()) {
|
if (cRecordControls::Active()) {
|
||||||
@ -699,14 +701,14 @@ int main(int argc, char *argv[])
|
|||||||
cControl::Shutdown(); // just in case
|
cControl::Shutdown(); // just in case
|
||||||
Temp = NULL;
|
Temp = NULL;
|
||||||
if (!cRecordControls::PauseLiveVideo())
|
if (!cRecordControls::PauseLiveVideo())
|
||||||
Interface->Error(tr("No free DVB device to record!"));
|
Skins.Message(mtError, tr("No free DVB device to record!"));
|
||||||
break;
|
break;
|
||||||
case osRecord: DELETENULL(Menu);
|
case osRecord: DELETENULL(Menu);
|
||||||
Temp = NULL;
|
Temp = NULL;
|
||||||
if (cRecordControls::Start())
|
if (cRecordControls::Start())
|
||||||
;//XXX Interface->Info(tr("Recording"));
|
;//XXX Skins.Message(mtInfo, tr("Recording"));
|
||||||
else
|
else
|
||||||
Interface->Error(tr("No free DVB device to record!"));
|
Skins.Message(mtError, tr("No free DVB device to record!"));
|
||||||
break;
|
break;
|
||||||
case osRecordings:
|
case osRecordings:
|
||||||
DELETENULL(Menu);
|
DELETENULL(Menu);
|
||||||
@ -728,7 +730,7 @@ int main(int argc, char *argv[])
|
|||||||
DELETENULL(Menu);
|
DELETENULL(Menu);
|
||||||
cControl::Shutdown();
|
cControl::Shutdown();
|
||||||
Temp = NULL;
|
Temp = NULL;
|
||||||
Interface->Info(tr("Switching primary DVB..."));
|
Skins.Message(mtInfo, tr("Switching primary DVB..."));
|
||||||
cDevice::SetPrimaryDevice(Setup.PrimaryDVB);
|
cDevice::SetPrimaryDevice(Setup.PrimaryDVB);
|
||||||
break;
|
break;
|
||||||
case osPlugin: DELETENULL(Menu);
|
case osPlugin: DELETENULL(Menu);
|
||||||
@ -789,9 +791,9 @@ int main(int argc, char *argv[])
|
|||||||
EITScanner.Process();
|
EITScanner.Process();
|
||||||
if (!cCutter::Active() && cCutter::Ended()) {
|
if (!cCutter::Active() && cCutter::Ended()) {
|
||||||
if (cCutter::Error())
|
if (cCutter::Error())
|
||||||
Interface->Error(tr("Editing process failed!"));
|
Skins.Message(mtError, tr("Editing process failed!"));
|
||||||
else
|
else
|
||||||
Interface->Info(tr("Editing process finished"));
|
Skins.Message(mtInfo, tr("Editing process finished"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!Interact && ((!cRecordControls::Active() && !cCutter::Active() && (!Interface->HasSVDRPConnection() || UserShutdown)) || ForceShutdown)) {
|
if (!Interact && ((!cRecordControls::Active() && !cCutter::Active() && (!Interface->HasSVDRPConnection() || UserShutdown)) || ForceShutdown)) {
|
||||||
@ -862,9 +864,10 @@ int main(int argc, char *argv[])
|
|||||||
delete Menu;
|
delete Menu;
|
||||||
cControl::Shutdown();
|
cControl::Shutdown();
|
||||||
delete Interface;
|
delete Interface;
|
||||||
cOsd::Shutdown();
|
cOsdProvider::Shutdown();
|
||||||
Remotes.Clear();
|
Remotes.Clear();
|
||||||
Audios.Clear();
|
Audios.Clear();
|
||||||
|
Skins.Clear();
|
||||||
Setup.CurrentChannel = cDevice::CurrentChannel();
|
Setup.CurrentChannel = cDevice::CurrentChannel();
|
||||||
Setup.CurrentVolume = cDevice::CurrentVolume();
|
Setup.CurrentVolume = cDevice::CurrentVolume();
|
||||||
Setup.Save();
|
Setup.Save();
|
||||||
|
Loading…
Reference in New Issue
Block a user