summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--COPYING340
-rw-r--r--HISTORY48
-rw-r--r--Makefile115
-rw-r--r--README213
-rw-r--r--config.c201
-rw-r--r--config.h109
-rw-r--r--displaychannel.c529
-rw-r--r--displaychannel.h74
-rw-r--r--displaymenu.c461
-rw-r--r--displaymenu.h56
-rw-r--r--displaymenuview.c627
-rw-r--r--displaymenuview.h107
-rw-r--r--displaymessage.c70
-rw-r--r--displaymessage.h20
-rw-r--r--displayreplay.c323
-rw-r--r--displayreplay.h69
-rw-r--r--displaytracks.c184
-rw-r--r--displaytracks.h39
-rw-r--r--displayvolume.c95
-rw-r--r--displayvolume.h26
-rw-r--r--helpers.c38
-rw-r--r--iconTemplates/IconBorder.pngbin0 -> 11033 bytes
-rw-r--r--iconTemplates/IconTemplate.xcfbin0 -> 167845 bytes
-rw-r--r--icons/Administrative Aufgaben.pngbin0 -> 23314 bytes
-rw-r--r--icons/Channels.pngbin0 -> 20699 bytes
-rw-r--r--icons/Channelseparator.pngbin0 -> 15388 bytes
-rw-r--r--icons/Commands.pngbin0 -> 17893 bytes
-rw-r--r--icons/DiskUsage.pngbin0 -> 24156 bytes
-rw-r--r--icons/Recordings.pngbin0 -> 22050 bytes
-rw-r--r--icons/Schedule.pngbin0 -> 21843 bytes
-rw-r--r--icons/Setup.pngbin0 -> 20218 bytes
-rw-r--r--icons/Timers.pngbin0 -> 21615 bytes
-rw-r--r--icons/Tvguide.pngbin0 -> 22966 bytes
-rw-r--r--icons/Videotext.pngbin0 -> 14735 bytes
-rw-r--r--icons/daydelimiter.pngbin0 -> 23206 bytes
-rw-r--r--icons/fwd.pngbin0 -> 18838 bytes
-rw-r--r--icons/hd1080i.pngbin0 -> 6268 bytes
-rw-r--r--icons/hd720p.pngbin0 -> 6105 bytes
-rw-r--r--icons/pause.pngbin0 -> 15668 bytes
-rw-r--r--icons/play.pngbin0 -> 17112 bytes
-rw-r--r--icons/rew.pngbin0 -> 18552 bytes
-rw-r--r--icons/sd576i.pngbin0 -> 6717 bytes
-rw-r--r--icons/signal.pngbin0 -> 2436 bytes
-rw-r--r--icons/tracks.pngbin0 -> 29537 bytes
-rw-r--r--icons/vdrlogo.pngbin0 -> 10150 bytes
-rw-r--r--icons/vdrlogo_gen2vdr.pngbin0 -> 22710 bytes
-rw-r--r--imageloader.c157
-rw-r--r--imageloader.h30
-rw-r--r--menudetailview.c246
-rw-r--r--menudetailview.h68
-rw-r--r--menuitem.c406
-rw-r--r--menuitem.h83
-rw-r--r--nopacity.c169
-rw-r--r--nopacity.h28
-rw-r--r--po/de_DE.po211
-rw-r--r--setup.c302
-rw-r--r--setup.h70
-rw-r--r--skinnopacity.c165
-rw-r--r--symbols/audio.xpm23
-rw-r--r--symbols/dolbydigital.xpm23
-rw-r--r--symbols/encrypted.xpm23
-rw-r--r--symbols/mute.xpm25
-rw-r--r--symbols/radio.xpm23
-rw-r--r--symbols/recording.xpm23
-rw-r--r--symbols/teletext.xpm23
-rw-r--r--themes/nOpacity-goldblue.theme63
-rw-r--r--themes/nOpacity-softblue.theme63
67 files changed, 5968 insertions, 0 deletions
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..f90922e
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/HISTORY b/HISTORY
new file mode 100644
index 0000000..723ef5f
--- /dev/null
+++ b/HISTORY
@@ -0,0 +1,48 @@
+VDR Plugin 'nOpacity' Revision History
+---------------------------------------
+
+2012-11-17: Version 0.0.1
+
+- Initial revision.
+
+2012-11-18: Version 0.0.2
+
+- Fixed a bug trying to delete uninitialized Fonts in cMenuDetailViewText
+- Fixed a typo in README
+- Added dsyslog messages for image loading (only shown with VDR Loglevel 3)
+- Added themes "SoftBlue" and "GoldBlue"
+- Added templates in directory iconTemplates/ in Gimp and PNG Format as
+ basis for creating new icons
+
+2012-11-24: Version 0.0.3
+
+- Fixed a bug that fade in time for channels switching was not stored
+- Fixed a bug that signal strength and screen resolution are not shown if
+ fade in time was set to zero.
+- Fixed a bug that Title was not shown when displaying a EPG Search Result
+- Fixed a bug that VDR crashes if empty channels where shown in "What's next"
+- Fixed a bug that VDR crashes if channels named "." where shown in
+ Channels menu
+- Fixed a bug that display for jumping in recordings was not shown
+- Changed default path for channel logos, icons and epg images. FHS standard
+ introduced in VDR 1.7.30 is used.
+ channel logos: {ResourceDirectory}/logos/
+ icons: {ResourceDirectory}/icons/
+ epg images: {CacheDirectory}/epgimages/
+- If directories for channel logos, icons or epg images are set via startup
+ parameters, images are searched first in these directories. If the image
+ is not available, an additional search in the according default directory
+ will be performed.
+ With this it is possible to use user images and images provided by a
+ package maintainer or distributor in parallel.
+- rewrote column width handling so that for calculating the width of a column
+ the actually used font size is used.
+- if the width of the text in a column in a default menu is lager than the
+ width of the column itself, the text is cutted to an appropriate width.
+- implemented cSkin::GetTextAreaWidth() and cSkin::GetTextAreaFont()
+- added patch that scales video display into the visible frame
+ if a narrow menu is displayed. Thanks @Zoolook for providing this patch.
+- added a setup option which allows to enable / disable this video scaling
+- Avoided some compiler warnings
+- Clear Message Box in Menu also if Caller not clears it himself
+- Fixed bug when calculating height of schedules menu item
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..2c4ea75
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,115 @@
+#
+# Makefile for a Video Disk Recorder plugin
+#
+# $Id$
+
+# The official name of this plugin.
+# This name will be used in the '-P...' option of VDR to load the plugin.
+# By default the main source file also carries this name.
+# IMPORTANT: the presence of this macro is important for the Make.config
+# file. So it must be defined, even if it is not used here!
+#
+PLUGIN = skinnopacity
+
+### The version number of this plugin (taken from the main source file):
+
+VERSION = $(shell grep 'static const char \*VERSION *=' $(PLUGIN).c | awk '{ print $$6 }' | sed -e 's/[";]//g')
+
+### The C++ compiler and options:
+
+CXX ?= g++
+CXXFLAGS ?= -g -O3 -Wall -Werror=overloaded-virtual -Wno-parentheses
+
+### The directory environment:
+
+VDRDIR ?= ../../..
+LIBDIR ?= ../../lib
+TMPDIR ?= /tmp
+
+### Make sure that necessary options are included:
+
+include $(VDRDIR)/Make.global
+
+### Allow user defined options to overwrite defaults:
+
+-include $(VDRDIR)/Make.config
+
+### The version number of VDR's plugin API (taken from VDR's "config.h"):
+
+APIVERSION = $(shell sed -ne '/define APIVERSION/s/^.*"\(.*\)".*$$/\1/p' $(VDRDIR)/config.h)
+
+### The name of the distribution archive:
+
+ARCHIVE = $(PLUGIN)-$(VERSION)
+PACKAGE = vdr-$(ARCHIVE)
+
+### Includes and Defines (add further entries here):
+
+INCLUDES += -I$(VDRDIR)/include
+INCLUDES += -I/usr/include/ImageMagick
+
+DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
+
+### The object files (add further files here):
+
+OBJS = $(PLUGIN).o
+
+### The main target:
+
+all: libvdr-$(PLUGIN).so i18n
+
+### Implicit rules:
+
+%.o: %.c
+ $(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) $<
+
+### Dependencies:
+
+MAKEDEP = $(CXX) -MM -MG
+DEPFILE = .dependencies
+$(DEPFILE): Makefile
+ @$(MAKEDEP) $(DEFINES) $(INCLUDES) $(OBJS:%.o=%.c) > $@
+
+-include $(DEPFILE)
+
+### Internationalization (I18N):
+
+PODIR = po
+LOCALEDIR = $(VDRDIR)/locale
+I18Npo = $(wildcard $(PODIR)/*.po)
+I18Nmsgs = $(addprefix $(LOCALEDIR)/, $(addsuffix /LC_MESSAGES/vdr-$(PLUGIN).mo, $(notdir $(foreach file, $(I18Npo), $(basename $(file))))))
+I18Npot = $(PODIR)/$(PLUGIN).pot
+
+%.mo: %.po
+ msgfmt -c -o $@ $<
+
+$(I18Npot): $(wildcard *.c)
+ xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=vdr-$(PLUGIN) --package-version=$(VERSION) --msgid-bugs-address='<see README>' -o $@ $^
+
+%.po: $(I18Npot)
+ msgmerge -U --no-wrap --no-location --backup=none -q $@ $<
+ @touch $@
+
+$(I18Nmsgs): $(LOCALEDIR)/%/LC_MESSAGES/vdr-$(PLUGIN).mo: $(PODIR)/%.mo
+ @mkdir -p $(dir $@)
+ cp $< $@
+
+.PHONY: i18n
+i18n: $(I18Nmsgs) $(I18Npot)
+
+### Targets:
+
+libvdr-$(PLUGIN).so: $(OBJS)
+ $(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -lMagick++ -o $@
+ @cp --remove-destination $@ $(LIBDIR)/$@.$(APIVERSION)
+
+dist: $(I18Npo) clean
+ @-rm -rf $(TMPDIR)/$(ARCHIVE)
+ @mkdir $(TMPDIR)/$(ARCHIVE)
+ @cp -a * $(TMPDIR)/$(ARCHIVE)
+ @tar czf $(PACKAGE).tgz -C $(TMPDIR) $(ARCHIVE)
+ @-rm -rf $(TMPDIR)/$(ARCHIVE)
+ @echo Distribution package created as $(PACKAGE).tgz
+
+clean:
+ @-rm -f $(OBJS) $(DEPFILE) *.so *.tgz core* *~ $(PODIR)/*.mo $(PODIR)/*.pot
diff --git a/README b/README
new file mode 100644
index 0000000..b99daa9
--- /dev/null
+++ b/README
@@ -0,0 +1,213 @@
+This is a "plugin" for the Video Disk Recorder (VDR).
+
+Written by: Louis Braun <louis DOT braun AT gmx DOT de>
+
+Project's homepage: URL
+
+Latest version available at: URL
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+See the file COPYING for more information.
+
+Requirements
+------------
+
+- VDR version >= 1.7.30
+
+- Installed ImageMagick for displaying png/jpg Icons, Channel Logos and EPG Images
+
+- VDR Plugin epgsearch for displaying the progress bar in the schedulings "what's now" display.
+
+Description
+-----------
+
+"nOpacity" is a highly customizable native true color skin for the Video Disc Recorder.
+
+Installation
+------------
+
+After "normal" Plugin installation you have to care about the paths for the
+used Icons, the channel logos and epg images. The following paths can be set
+at startup:
+
+-i path, --iconpath=path
+ Path to the icons (Default: <vdrconfdir>/plugins/skinnopacity/icons/).
+
+-l path, --logopath=path
+ Path to the logos (Default: <vdrconfdir>/plugins/skinnopacity/logos/).
+
+-e path, --epgimages=path
+ Path to the epgimages (Default: <vdrconfdir>/plugins/skinnopacity/epgimages/).
+
+First copy the icons from
+/put/your/path/toVDRsources/here/VDR/PLUGINS/src/skinnopcaity/icons/
+to the configured icon path. After that download the logopack from:
+http://www.dvbviewer.tv/forum/topic/21378-logopacks/
+unzip it and place it accordingly the settings for the channel logos path.
+
+if no pathes are set for the different types of images, the following default
+paths are used:
+channel logos: {ResourceDirectory}/logos/
+icons: {ResourceDirectory}/icons/
+epg images: {CacheDirectory}/epgimages/
+
+If directories for channel logos, icons or epg images are set via startup
+parameters, images are searched first in these directories. If the image
+is not available, an additional search in the according default directory
+will be performed.
+With this it is possible to use user images and images provided by a
+package maintainer or distributor in parallel.
+
+For S2-6400 Users: Disable High Level OSD, otherwise the plugin will not be
+loaded because lack of true color support
+
+Usage
+-----
+
+After installation first activate then skin in the VDR OSD menu. nOpacity scales to
+every screen resolution, but in lower resolutions than 1920 * 1080 it may be necessary
+to change some default settings for dimensions and font sizes to achieve the best result
+(see "setup options" below).
+
+nOpacity respects the OSD settings for OSD top, left, width and height. If these values
+are not set to top&left: 0, width&height: 100, you'll get a border around every displayed
+skin element. Additionally you are able to configure an individual border for almost every
+displayed skin element (channel switching, recordings, volume, audio tracks) in the
+skin setup. Only the menu uses the full screen if not configured differently in the
+OSD settings.
+
+As already mentioned, font sizes are customizable via the skins setup menu. The skin
+calculates the font sizes for the used screen resolution individually. The value
+for the different font sizes in the setup options is always the delta to the calculated
+(default) values. If you set a value for a font size of -2 for instance, the default
+font size is decreased by 2, analogue the font size will be increased by setting a
+positive value.
+
+As described in "installation", you should use a special channel logo pack with transparent
+channel logos. In this logo pack all files are named only with lower case letters.
+nOpacity uses the channel name CONVERTED TO LOWER CASE LETTERS to search for aT
+appropriate channel logo. With this, approximately 90% of the channel logos should work
+immediately after placing the channel logos in the correct place. So if you have to change
+the name of a channel logo (may be by inserting a space or a hyphen) so that it fits to
+the channel name, only use lower case letters, and not the name of the channel with upper
+and lower letters as displayed inside VDR.
+Additional hint: some channels have slashes in their name (in germany nick/comedy for instance).
+In this example, as a dirty hack just create a folder in your channel logo directory named
+"nick" and place an image named "comedy.png" inside this folder.
+
+With softhddevice as output plugin, use a Version newer than Revision f640ebde
+(0.5.1, 10.10.2012) to achieve a correct display of the screen resolution during channel switching.
+
+Setup Options
+-------------
+
+* General Options (only non self-explanatory options are described)
+
+- Font: Used Font, all Fonts installed on your system are shown
+
+* VDR menu:
+
+- Fade-In Time in ms (Zero for switching off fading): Default 300ms
+- Width of narrow Menu Bar (% of OSD Width): Width of menu bar for the main menu,
+ schedules menu and channels menu. Default: 30%.
+- Width of Disc Usage and Timers Display (% of OSD Width): Default: 12%
+- Header Height (% of OSD Height): Default: 7%
+- Footer Height (% of OSD Height): Default: 7%
+- Number of Default Menu Entries: Number of menu items for the default menu view.
+- Icon Size (Square Main Menu Icons): This size determinates the number of main
+ menu entries per page.
+- Header Icon Size (Square Header Menu Icons)
+- Channel Logo Width (Menu Buttons): width of channel logos shown in scheduling
+ "what's on" and "what's next" menus and channels menu.
+- Channel Logo Height (Menu Buttons): height of channel logos shown in scheduling
+ "what's on" and "what's next" menus and channels menu. This size determinates
+ the number of menu entries in schedules and channels menu.
+- Main Menu Header Logo Width: Default 104px
+- Main Menu Header Logo Height: Default 78px
+- Detail EPG View Logo Width: Default 260px
+- Detail EPG View Logo Height: Default 200px
+- Detail EPG View EPG Image Width: Default 210px
+- Detail EPG View EPG Image Height: Default 160px
+- Adjust Font Size - Header
+- Adjust Font Size - Date
+- Adjust Font Size - Large Menu Item: Font for Main menu and channels menu items
+- Adjust Font Size - Schedule Menu Item: Font for schedules menu items
+- Adjust Font Size - Default Menu Item
+- Adjust Font Size - Disc Usage
+- Adjust Font Size - Timers Header
+- Adjust Font Size - Timers Title
+- Adjust Font Size - Buttons: Font for color buttons
+- Adjust Font Size - Messages
+- Adjust Font Size - Detail View Text: Font for detailed EPG & recordings view text
+- Adjust Font Size - Detail View Header: Font for Header date/time and short text
+- Adjust Font Size - Detail View Header Large: Font for detailed EPG & recordings
+ view title
+
+* Channel Switching:
+
+- Fade-In Time in ms (Zero for switching off fading): Default 300ms
+- Hight of Channel Display (% of OSD Height): Default 25%
+- Left & Right Border Width: Default 15px
+- Bottom Border Height: Default 15px
+- Channel Logo Width: Default 260px
+- Channel Logo Height: Default 200px
+- Channel Logo Border: Default 15px
+- Display Signal Strength & Quality: Set this to Zero if you want to disable the
+ display of signal strength & quality (for instance if your dvb drivers does not
+ deliver this values)
+- Screen Resolution Icon Size: Default 100px
+- Adjust Font Size - Header: Font for Channel / Channelgroup Name
+- Adjust Font Size - Date
+- Adjust Font Size - EPG Text
+- Adjust Font Size - EPG Infotext
+
+* Replay:
+
+- Fade-In Time in ms (Zero for switching off fading)
+- Hight of Replay Display (% of OSD Height)
+- Left & Right Border Width
+- Bottom Border Height
+- Adjust Font Size - Header
+- Adjust Font Size - Text
+
+* Audio Tracks:
+
+- Fade-In Time in ms (Zero for switching off fading)
+- Width of Tracks Display (% of OSD Height)
+- Hight of Tracks Display (% of OSD Height)
+- Position (0: bot. center, 1: bot. left, ... , 7: bot. right): The following
+ positions are possible, starting at bottom middle:
+ 0: bottom center
+ 1: bottom left
+ 2: middle left
+ 3: top left
+ 4: top middle
+ 5: top right
+ 6: middle right
+ 7: bottom right
+- Border Top / Bottom
+- Border Left / Right
+- Adjust Font Size - Header
+- Adjust Font Size - Buttons
+
+* Messages:
+
+- Fade-In Time in ms (Zero for switching off fading): Default 300ms
+- Width of Message Display (% of OSD Height): Default 90%
+- Hight of Message Display (% of OSD Height): Default 10%
+- Bottom Border Height: Default 10px
+ Remark: with different sizes and a large value for the bottom border height you
+ are able to achieve a positioning for the messages box analogue to the positioning
+ of the audio tracks display.
+- Adjust Font Size
+
+* Volume Display:
+
+- Fade-In Time in ms (Zero for switching off fading): Default 300ms
+- Width of Volume Display (% of OSD Height): Default 40%
+- Hight of Volume Display (% of OSD Height): Default 10%
+ Remark: the volume display is always positioned in the center of the screen
+- Adjust Font Size
diff --git a/config.c b/config.c
new file mode 100644
index 0000000..7368aad
--- /dev/null
+++ b/config.c
@@ -0,0 +1,201 @@
+#include "config.h"
+
+cNopacityConfig::cNopacityConfig() {
+ logoPathSet = false;
+ epgImagePathSet = false;
+ iconPathSet = false;
+ //Common
+ mainMenuEntry = false;
+ fontIndex = 0;
+ fontDefaultName = "VDRSymbols Sans:Book";
+ //DisplayChannel
+ channelHeight = 25;
+ channelBorderVertical = 15;
+ channelBorderBottom = 15;
+ channelFadeTime = 300; // ms
+ logoWidth = 260;
+ logoHeight = 200;
+ logoExtension = "png";
+ logoBorder = 15;
+ displaySignalStrength = 1;
+ fontChannelHeaderSize = 0;
+ fontChannelDateSize = 0;
+ fontEPGSize = 0;
+ fontEPGSmallSize = 0;
+ resolutionIconSize = 100;
+ //Display Replay
+ replayHeight = 25;
+ replayBorderVertical = 15;
+ replayBorderBottom = 15;
+ replayFadeTime = 300; // ms
+ fontReplayHeader = 0;
+ fontReplay = 0;
+ //DisplayMessage
+ messageWidth = 90;
+ messageHeight = 10;
+ messageBorderBottom = 10;
+ fontMessage = 0;
+ messageFadeTime = 300;
+ //DisplayTracks
+ tracksFadeTime = 300;
+ tracksWidth = 25;
+ tracksHeight = 25;
+ tracksPosition = 0;
+ tracksBorderHorizontal = 10;
+ tracksBorderVertical = 10;
+ fontTracksHeader = 0;
+ fontTracks = 0;
+ //DisplayVolume
+ volumeFadeTime = 300;
+ volumeWidth = 40;
+ volumeHeight = 10;
+ fontVolume = 0;
+ //DisplayMenu
+ scalePicture = 1;
+ menuFadeTime = 300;
+ menuWidthNarrow = 30;
+ menuWidthRightItems = 12;
+ headerHeight = 7;
+ footerHeight = 7;
+ numDefaultMenuItems = 16;
+ iconHeight = 100;
+ headerIconHeight = 80;
+ menuHeaderLogoWidth = 104;
+ menuHeaderLogoHeight = 78;
+ menuItemLogoWidth = 130;
+ menuItemLogoHeight = 100;
+ detailViewLogoWidth = 260;
+ detailViewLogoHeight = 200;
+ epgImageWidth = 210;
+ epgImageHeight = 160;
+ fontHeader = 0;
+ fontDate = 0;
+ fontMenuitemLarge = 0;
+ fontMenuitemSchedule = 0;
+ fontMenuitemDefault = 0;
+ fontDiskUsage = 0;
+ fontTimersHead = 0;
+ fontTimers = 0;
+ fontButtons = 0;
+ fontMessageMenu = 0;
+ fontDetailView = 0;
+ fontDetailViewHeader = 0;
+ fontDetailViewHeaderLarge = 0;
+}
+
+cNopacityConfig::~cNopacityConfig() {
+}
+
+void cNopacityConfig::setDynamicValues() {
+ if (fontIndex == 0) {
+ fontName = strdup(fontDefaultName);
+ } else {
+ cStringList availableFonts;
+ cFont::GetAvailableFontNames(&availableFonts);
+ if (availableFonts[fontIndex-1]) {
+ fontName = strdup(availableFonts[fontIndex-1]);
+ } else
+ fontName = strdup(fontDefaultName);
+ }
+ channelFrameTime = channelFadeTime / 10;
+ replayFrameTime = replayFadeTime / 10;
+ messageFrameTime = messageFadeTime / 10;
+ tracksFrameTime = tracksFadeTime / 10;
+ volumeFrameTime = volumeFadeTime / 10;
+ menuFrameTime = menuFadeTime / 10;
+
+ logoPathDefault = cString::sprintf("%s/logos/", cPlugin::ResourceDirectory(PLUGIN_NAME_I18N));
+ iconPathDefault = cString::sprintf("%s/icons/", cPlugin::ResourceDirectory(PLUGIN_NAME_I18N));
+ epgImagePathDefault = cString::sprintf("%s/epgimages/", cPlugin::CacheDirectory(PLUGIN_NAME_I18N));
+
+ dsyslog("nopacity: using Logo Directory %s", (logoPathSet)?(*logoPath):(*logoPathDefault));
+ dsyslog("nopacity: using Icon Directory %s", (iconPathSet)?(*iconPath):(*iconPathDefault));
+ dsyslog("nopacity: using EPG Images Directory %s", (epgImagePathSet)?(*epgImagePath):(*epgImagePathDefault));
+}
+
+void cNopacityConfig::SetLogoPath(cString path) {
+ logoPath = path;
+ logoPathSet = true;
+}
+
+void cNopacityConfig::SetIconPath(cString path) {
+ iconPath = path;
+ iconPathSet = true;
+}
+
+void cNopacityConfig::SetEpgImagePath(cString path) {
+ epgImagePath = path;
+ epgImagePathSet = true;
+}
+
+bool cNopacityConfig::SetupParse(const char *Name, const char *Value) {
+ if (strcmp(Name, "fontIndex") == 0) fontIndex = atoi(Value);
+ else if (strcmp(Name, "channelFadeTime") == 0) channelFadeTime = atoi(Value);
+ else if (strcmp(Name, "channelHeight") == 0) channelHeight = atoi(Value);
+ else if (strcmp(Name, "channelBorderVertical") == 0) channelBorderVertical = atoi(Value);
+ else if (strcmp(Name, "channelBorderBottom") == 0) channelBorderBottom = atoi(Value);
+ else if (strcmp(Name, "logoWidth") == 0) logoWidth = atoi(Value);
+ else if (strcmp(Name, "logoHeight") == 0) logoHeight = atoi(Value);
+ else if (strcmp(Name, "logoBorder") == 0) logoBorder = atoi(Value);
+ else if (strcmp(Name, "displaySignalStrength") == 0) displaySignalStrength = atoi(Value);
+ else if (strcmp(Name, "fontChannelHeaderSize") == 0) fontChannelHeaderSize = atoi(Value);
+ else if (strcmp(Name, "fontChannelDateSize") == 0) fontChannelDateSize = atoi(Value);
+ else if (strcmp(Name, "fontEPGSize") == 0) fontEPGSize = atoi(Value);
+ else if (strcmp(Name, "fontEPGSmallSize") == 0) fontEPGSmallSize = atoi(Value);
+ else if (strcmp(Name, "resolutionIconSize") == 0) resolutionIconSize = atoi(Value);
+ else if (strcmp(Name, "replayHeight") == 0) replayHeight = atoi(Value);
+ else if (strcmp(Name, "replayBorderVertical") == 0) replayBorderVertical = atoi(Value);
+ else if (strcmp(Name, "replayBorderBottom") == 0) replayBorderBottom = atoi(Value);
+ else if (strcmp(Name, "replayFadeTime") == 0) replayFadeTime = atoi(Value);
+ else if (strcmp(Name, "fontReplayHeader") == 0) fontReplayHeader = atoi(Value);
+ else if (strcmp(Name, "fontReplay") == 0) fontReplay = atoi(Value);
+ else if (strcmp(Name, "messageWidth") == 0) messageWidth = atoi(Value);
+ else if (strcmp(Name, "messageHeight") == 0) messageHeight = atoi(Value);
+ else if (strcmp(Name, "messageBorderBottom") == 0) messageBorderBottom = atoi(Value);
+ else if (strcmp(Name, "fontMessage") == 0) fontMessage = atoi(Value);
+ else if (strcmp(Name, "messageFadeTime") == 0) messageFadeTime = atoi(Value);
+ else if (strcmp(Name, "tracksFadeTime") == 0) tracksFadeTime = atoi(Value);
+ else if (strcmp(Name, "tracksWidth") == 0) tracksWidth = atoi(Value);
+ else if (strcmp(Name, "tracksHeight") == 0) tracksHeight = atoi(Value);
+ else if (strcmp(Name, "tracksPosition") == 0) tracksPosition = atoi(Value);
+ else if (strcmp(Name, "tracksBorderHorizontal") == 0) tracksBorderHorizontal = atoi(Value);
+ else if (strcmp(Name, "tracksBorderVertical") == 0) tracksBorderVertical = atoi(Value);
+ else if (strcmp(Name, "fontTracksHeader") == 0) fontTracksHeader = atoi(Value);
+ else if (strcmp(Name, "fontTracks") == 0) fontTracks = atoi(Value);
+ else if (strcmp(Name, "volumeFadeTime") == 0) volumeFadeTime = atoi(Value);
+ else if (strcmp(Name, "volumeWidth") == 0) volumeWidth = atoi(Value);
+ else if (strcmp(Name, "volumeHeight") == 0) volumeHeight = atoi(Value);
+ else if (strcmp(Name, "fontVolume") == 0) fontVolume = atoi(Value);
+ else if (strcmp(Name, "menuFadeTime") == 0) menuFadeTime = atoi(Value);
+ else if (strcmp(Name, "scalePicture") == 0) scalePicture = atoi(Value);
+ else if (strcmp(Name, "menuWidthNarrow") == 0) menuWidthNarrow = atoi(Value);
+ else if (strcmp(Name, "menuWidthRightItems") == 0) menuWidthRightItems = atoi(Value);
+ else if (strcmp(Name, "headerHeight") == 0) headerHeight = atoi(Value);
+ else if (strcmp(Name, "footerHeight") == 0) footerHeight = atoi(Value);
+ else if (strcmp(Name, "numDefaultMenuItems") == 0) numDefaultMenuItems = atoi(Value);
+ else if (strcmp(Name, "iconHeight") == 0) iconHeight = atoi(Value);
+ else if (strcmp(Name, "headerIconHeight") == 0) headerIconHeight = atoi(Value);
+ else if (strcmp(Name, "menuItemLogoWidth") == 0) menuItemLogoWidth = atoi(Value);
+ else if (strcmp(Name, "menuItemLogoHeight") == 0) menuItemLogoHeight = atoi(Value);
+ else if (strcmp(Name, "menuHeaderLogoWidth") == 0) menuHeaderLogoWidth = atoi(Value);
+ else if (strcmp(Name, "menuHeaderLogoHeight") == 0) menuHeaderLogoHeight = atoi(Value);
+ else if (strcmp(Name, "detailViewLogoWidth") == 0) detailViewLogoWidth = atoi(Value);
+ else if (strcmp(Name, "detailViewLogoHeight") == 0) detailViewLogoHeight = atoi(Value);
+ else if (strcmp(Name, "epgImageWidth") == 0) epgImageWidth = atoi(Value);
+ else if (strcmp(Name, "epgImageHeight") == 0) epgImageHeight = atoi(Value);
+ else if (strcmp(Name, "fontHeader") == 0) fontHeader = atoi(Value);
+ else if (strcmp(Name, "fontDate") == 0) fontDate = atoi(Value);
+ else if (strcmp(Name, "fontMenuitemLarge") == 0) fontMenuitemLarge = atoi(Value);
+ else if (strcmp(Name, "fontMenuitemSchedule") == 0) fontMenuitemSchedule = atoi(Value);
+ else if (strcmp(Name, "fontMenuitemDefault") == 0) fontMenuitemDefault = atoi(Value);
+ else if (strcmp(Name, "fontDiskUsage") == 0) fontDiskUsage = atoi(Value);
+ else if (strcmp(Name, "fontTimersHead") == 0) fontTimersHead = atoi(Value);
+ else if (strcmp(Name, "fontTimers") == 0) fontTimers = atoi(Value);
+ else if (strcmp(Name, "fontButtons") == 0) fontButtons = atoi(Value);
+ else if (strcmp(Name, "fontMessageMenu") == 0) fontMessage = atoi(Value);
+ else if (strcmp(Name, "fontDetailView") == 0) fontDetailView = atoi(Value);
+ else if (strcmp(Name, "fontDetailViewHeader") == 0) fontDetailViewHeader = atoi(Value);
+ else if (strcmp(Name, "fontDetailViewHeaderLarge") == 0) fontDetailViewHeaderLarge = atoi(Value);
+ else return false;
+ return true;
+} \ No newline at end of file
diff --git a/config.h b/config.h
new file mode 100644
index 0000000..507968d
--- /dev/null
+++ b/config.h
@@ -0,0 +1,109 @@
+#ifndef __NOPACITY_CONFIG_H
+#define __NOPACITY_CONFIG_H
+
+class cNopacityConfig {
+ private:
+ public:
+ cNopacityConfig();
+ ~cNopacityConfig();
+ bool SetupParse(const char *Name, const char *Value);
+ void SetLogoPath(cString path);
+ void SetIconPath(cString path);
+ void SetEpgImagePath(cString path);
+ bool logoPathSet;
+ bool epgImagePathSet;
+ bool iconPathSet;
+ cString logoPathDefault;
+ cString iconPathDefault;
+ cString epgImagePathDefault;
+ void setDynamicValues();
+ //Common
+ int fontIndex;
+ const char *fontDefaultName;
+ char *fontName;
+ cString logoPath;
+ cString logoExtension;
+ cString iconPath;
+ cString epgImagePath;
+ bool mainMenuEntry;
+ //DisplayChannel
+ int channelHeight;
+ int channelBorderVertical;
+ int channelBorderBottom;
+ int channelFadeTime;
+ int channelFrameTime;
+ int logoWidth;
+ int logoHeight;
+ int logoBorder;
+ int displaySignalStrength;
+ int fontChannelHeaderSize;
+ int fontChannelDateSize;
+ int fontEPGSize;
+ int fontEPGSmallSize;
+ int resolutionIconSize;
+ //DisplayReplay
+ int replayHeight;
+ int replayBorderVertical;
+ int replayBorderBottom;
+ int replayFadeTime;
+ int replayFrameTime;
+ int fontReplayHeader;
+ int fontReplay;
+ //Display Message
+ int messageWidth;
+ int messageHeight;
+ int messageBorderBottom;
+ int fontMessage;
+ int messageFadeTime;
+ int messageFrameTime;
+ //DisplayTracks
+ int tracksFadeTime;
+ int tracksFrameTime;
+ int tracksWidth;
+ int tracksHeight;
+ int tracksPosition;
+ int tracksBorderHorizontal;
+ int tracksBorderVertical;
+ int fontTracksHeader;
+ int fontTracks;
+ //DisplayVolume
+ int volumeFadeTime;
+ int volumeFrameTime;
+ int volumeWidth;
+ int volumeHeight;
+ int fontVolume;
+ //DisplayMenu
+ int scalePicture;
+ int menuFadeTime;
+ int menuFrameTime;
+ int menuWidthNarrow;
+ int menuWidthRightItems;
+ int headerHeight;
+ int footerHeight;
+ int numDefaultMenuItems;
+ int iconHeight;
+ int headerIconHeight;
+ int menuItemLogoWidth;
+ int menuItemLogoHeight;
+ int menuHeaderLogoWidth;
+ int menuHeaderLogoHeight;
+ int detailViewLogoWidth;
+ int detailViewLogoHeight;
+ int epgImageWidth;
+ int epgImageHeight;
+ int fontHeader;
+ int fontDate;
+ int fontMenuitemLarge;
+ int fontMenuitemSchedule;
+ int fontMenuitemDefault;
+ int fontDiskUsage;
+ int fontTimersHead;
+ int fontTimers;
+ int fontButtons;
+ int fontMessageMenu;
+ int fontDetailView;
+ int fontDetailViewHeader;
+ int fontDetailViewHeaderLarge;
+};
+
+#endif //__NOPACITY_CONFIG_H \ No newline at end of file
diff --git a/displaychannel.c b/displaychannel.c
new file mode 100644
index 0000000..ba8102c
--- /dev/null
+++ b/displaychannel.c
@@ -0,0 +1,529 @@
+#include "symbols/audio.xpm"
+#include "symbols/dolbydigital.xpm"
+#include "symbols/encrypted.xpm"
+#include "symbols/radio.xpm"
+#include "symbols/recording.xpm"
+#include "symbols/teletext.xpm"
+
+#include "displaychannel.h"
+
+cNopacityDisplayChannel::cNopacityDisplayChannel(bool WithInfo) {
+ config.setDynamicValues();
+ withInfo = WithInfo;
+ groupSep = false;
+ present = NULL;
+ lastSeen = -1;
+ lastSignalDisplay = 0;
+ lastSignalStrength = 0;
+ lastSignalQuality = 0;
+ lastScreenWidth = 0;
+ currentLast = 0;
+ channelChange = false;
+ initial = true;
+ FrameTime = config.channelFrameTime;
+ FadeTime = config.channelFadeTime;
+ lastDate = "";
+ SetGeometry();
+ CreatePixmaps();
+ CreateFonts();
+ DrawBackground();
+ DrawSignalMeter();
+}
+
+cNopacityDisplayChannel::~cNopacityDisplayChannel() {
+ osd->DestroyPixmap(pixmapBackgroundTop);
+ osd->DestroyPixmap(pixmapBackgroundBottom);
+ osd->DestroyPixmap(pixmapLogo);
+ osd->DestroyPixmap(pixmapChannelInfo);
+ osd->DestroyPixmap(pixmapDate);
+ if (withInfo) {
+ osd->DestroyPixmap(pixmapBackgroundMiddle);
+ osd->DestroyPixmap(pixmapProgressBar);
+ osd->DestroyPixmap(pixmapEPGInfo);
+ }
+ if (pixmapScreenResolution)
+ osd->DestroyPixmap(pixmapScreenResolution);
+ osd->DestroyPixmap(pixmapStreamInfo);
+ if (config.displaySignalStrength && showSignal) {
+ osd->DestroyPixmap(pixmapSignalStrength);
+ osd->DestroyPixmap(pixmapSignalQuality);
+ osd->DestroyPixmap(pixmapSignalMeter);
+ osd->DestroyPixmap(pixmapSignalLabel);
+ }
+ if (config.displaySignalStrength && showSignal) {
+ delete fontInfoline;
+ }
+ delete fontHeader;
+ delete fontDate;
+ delete fontEPG;
+ delete fontEPGSmall;
+ delete osd;
+}
+
+cBitmap cNopacityDisplayChannel::bmTeletext(teletext_xpm);
+cBitmap cNopacityDisplayChannel::bmRadio(radio_xpm);
+cBitmap cNopacityDisplayChannel::bmAudio(audio_xpm);
+cBitmap cNopacityDisplayChannel::bmDolbyDigital(dolbydigital_xpm);
+cBitmap cNopacityDisplayChannel::bmEncrypted(encrypted_xpm);
+cBitmap cNopacityDisplayChannel::bmRecording(recording_xpm);
+
+void cNopacityDisplayChannel::SetGeometry(void) {
+ height = cOsd::OsdHeight() * config.channelHeight / 100;
+ int top = cOsd::OsdTop() + cOsd::OsdHeight() - height - config.channelBorderBottom;
+ osd = CreateOsd(cOsd::OsdLeft(), top, cOsd::OsdWidth(), height);
+ infoWidth = osd->Width() - (config.logoWidth + 2 * config.channelBorderVertical + config.logoBorder);
+ infoX = config.logoWidth + config.channelBorderVertical + config.logoBorder;
+ channelInfoWidth = infoWidth * 0.7;
+ dateWidth = infoWidth - channelInfoWidth;
+ channelInfoHeight = height * 0.2;
+ if (channelInfoHeight%2 != 0)
+ channelInfoHeight++;
+ progressBarHeight = height * 0.1;
+ streamInfoHeight = height * 0.2;
+ if (streamInfoHeight%2 != 0)
+ streamInfoHeight++;
+ epgInfoHeight = height - channelInfoHeight - streamInfoHeight - progressBarHeight;
+ epgInfoLineHeight = epgInfoHeight / 4;
+ streamInfoY = channelInfoHeight + progressBarHeight + epgInfoHeight;
+}
+
+void cNopacityDisplayChannel::CreatePixmaps(void) {
+ int channelInfoY = 0;
+ if (withInfo) {
+ pixmapProgressBar = osd->CreatePixmap(2, cRect(infoX, channelInfoHeight, infoWidth, progressBarHeight));
+ pixmapEPGInfo = osd->CreatePixmap(2, cRect(infoX, channelInfoHeight + progressBarHeight, infoWidth, epgInfoHeight));
+ pixmapBackgroundMiddle = osd->CreatePixmap(1, cRect(infoX, channelInfoHeight, infoWidth, progressBarHeight + epgInfoHeight));
+ } else {
+ channelInfoY = (height - channelInfoHeight) / 3;
+ streamInfoY = (height - channelInfoHeight) / 3 + channelInfoHeight;
+ }
+ pixmapBackgroundTop = osd->CreatePixmap(1, cRect(infoX, channelInfoY, infoWidth, channelInfoHeight));
+ pixmapBackgroundBottom = osd->CreatePixmap(1, cRect(infoX, streamInfoY, infoWidth, streamInfoHeight));
+
+ pixmapChannelInfo = osd->CreatePixmap(2, cRect(infoX, channelInfoY, channelInfoWidth, channelInfoHeight));
+ pixmapDate = osd->CreatePixmap(2, cRect(infoX + channelInfoWidth, channelInfoY, dateWidth, channelInfoHeight));
+ pixmapStreamInfo = osd->CreatePixmap(2, cRect(infoX, streamInfoY, infoWidth, streamInfoHeight));
+ pixmapLogo = osd->CreatePixmap(1, cRect(0, 0, config.logoWidth + 2 * config.logoBorder, height));
+
+ if (config.channelFadeTime) {
+ pixmapBackgroundTop->SetAlpha(0);
+ pixmapBackgroundBottom->SetAlpha(0);
+ pixmapChannelInfo->SetAlpha(0);
+ pixmapDate->SetAlpha(0);
+ pixmapLogo->SetAlpha(0);
+ pixmapStreamInfo->SetAlpha(0);
+ if (withInfo) {
+ pixmapBackgroundMiddle->SetAlpha(0);
+ pixmapProgressBar->SetAlpha(0);
+ pixmapEPGInfo->SetAlpha(0);
+ }
+ }
+ if (withInfo) {
+ pixmapProgressBar->Fill(clrTransparent);
+ pixmapEPGInfo->Fill(clrTransparent);
+ }
+ pixmapScreenResolution = NULL;
+}
+
+void cNopacityDisplayChannel::CreateFonts(void) {
+ fontHeader = cFont::CreateFont(config.fontName, channelInfoHeight - 8 + config.fontChannelHeaderSize);
+ fontDate = cFont::CreateFont(config.fontName, channelInfoHeight/2 + config.fontChannelDateSize);
+ fontEPG = cFont::CreateFont(config.fontName, epgInfoLineHeight + config.fontEPGSize);
+ fontEPGSmall = cFont::CreateFont(config.fontName, epgInfoLineHeight - 6 + config.fontEPGSmallSize);
+}
+
+void cNopacityDisplayChannel::DrawBackground(void){
+
+ DrawBlendedBackground(pixmapBackgroundTop, Theme.Color(clrChannelBackground), Theme.Color(clrChannelBackBlend), true);
+ if (withInfo)
+ pixmapBackgroundMiddle->Fill(Theme.Color(clrChannelBackground));
+ DrawBlendedBackground(pixmapBackgroundBottom, Theme.Color(clrChannelBackground), Theme.Color(clrChannelBackBlend), false);
+
+ pixmapBackgroundTop->DrawEllipse(cRect(0, 0, channelInfoHeight/2, channelInfoHeight/2), clrTransparent, -2);
+ pixmapBackgroundTop->DrawEllipse(cRect(infoWidth - channelInfoHeight/2, 0, channelInfoHeight/2, channelInfoHeight/2), clrTransparent, -1);
+ pixmapBackgroundBottom->DrawEllipse(cRect(0, streamInfoHeight/2, streamInfoHeight/2, streamInfoHeight/2), clrTransparent, -3);
+ pixmapBackgroundBottom->DrawEllipse(cRect(infoWidth - streamInfoHeight/2, streamInfoHeight/2, streamInfoHeight/2, streamInfoHeight/2), clrTransparent, -4);
+
+
+ pixmapChannelInfo->Fill(clrTransparent);
+ pixmapDate->Fill(clrTransparent);
+ pixmapLogo->Fill(clrTransparent);
+ pixmapStreamInfo->Fill(clrTransparent);
+}
+
+void cNopacityDisplayChannel::DrawDate(void) {
+ cString curDate = DayDateTime();
+ if (initial || channelChange || strcmp(curDate, lastDate)) {
+ int strDateWidth = fontDate->Width(curDate);
+ int strDateHeight = fontDate->Height();
+ int x = dateWidth - strDateWidth - channelInfoHeight/2;
+ int y = (channelInfoHeight - strDateHeight) / 2;
+ pixmapDate->Fill(clrTransparent);
+ pixmapDate->DrawText(cPoint(x, y), curDate, Theme.Color(clrChannelHead), clrTransparent, fontDate);
+ lastDate = curDate;
+ }
+}
+
+void cNopacityDisplayChannel::DrawIcons(const cChannel *Channel) {
+ int spacing = 10;
+ int x = infoWidth - config.resolutionIconSize - 3*spacing;
+ int y = 0;
+
+ bool rec = cRecordControls::Active();
+ x -= bmRecording.Width() + spacing;
+ y = (streamInfoHeight - bmRecording.Height()) / 2;
+ pixmapStreamInfo->DrawBitmap(cPoint(x,y), bmRecording, Theme.Color(rec ? clrChannelRecActive : clrChannelSymbolOff), clrTransparent);
+
+ x -= bmEncrypted.Width() + spacing;
+ y = (streamInfoHeight - bmEncrypted.Height()) / 2;
+ pixmapStreamInfo->DrawBitmap(cPoint(x,y), bmEncrypted, Theme.Color(Channel->Ca() ? clrChannelSymbolOn : clrChannelSymbolOff), clrTransparent);
+
+ x -= bmDolbyDigital.Width() + spacing;
+ y = (streamInfoHeight - bmDolbyDigital.Height()) / 2;
+ pixmapStreamInfo->DrawBitmap(cPoint(x,y), bmDolbyDigital, Theme.Color(Channel->Dpid(0) ? clrChannelSymbolOn : clrChannelSymbolOff), clrTransparent);
+
+ x -= bmAudio.Width() + spacing;
+ y = (streamInfoHeight - bmAudio.Height()) / 2;
+ pixmapStreamInfo->DrawBitmap(cPoint(x,y), bmAudio, Theme.Color(Channel->Apid(1) ? clrChannelSymbolOn : clrChannelSymbolOff), clrTransparent);
+
+ if (Channel->Vpid()) {
+ x -= bmTeletext.Width() + spacing;
+ y = (streamInfoHeight - bmTeletext.Height()) / 2;
+ pixmapStreamInfo->DrawBitmap(cPoint(x,y), bmTeletext, Theme.Color(Channel->Tpid() ? clrChannelSymbolOn : clrChannelSymbolOff), clrTransparent);
+ } else if (Channel->Apid(0)) {
+ x -= bmRadio.Width() + spacing;
+ y = (streamInfoHeight - bmTeletext.Height()) / 2;
+ pixmapStreamInfo->DrawBitmap(cPoint(x,y), bmRadio, Theme.Color(clrChannelSymbolOn), clrTransparent);
+ }
+
+}
+
+void cNopacityDisplayChannel::DrawScreenResolution(void) {
+ int spacing = 10;
+ int screenWidth = 0;
+ int screenHeight = 0;
+ double aspect = 0;
+
+ if (!pixmapScreenResolution) {
+ int x = infoX + infoWidth - config.resolutionIconSize - 2*spacing;
+ int y = streamInfoY + streamInfoHeight - config.resolutionIconSize - 3;
+ pixmapScreenResolution = osd->CreatePixmap(3, cRect(x, y, config.resolutionIconSize, config.resolutionIconSize));
+ pixmapScreenResolution->Fill(clrTransparent);
+ if ((initial)&&(config.channelFadeTime))
+ pixmapScreenResolution->SetAlpha(0);
+ }
+
+ cDevice::PrimaryDevice()->GetVideoSize(screenWidth, screenHeight, aspect);
+ if (screenWidth != lastScreenWidth) {
+ cImageLoader imgLoader;
+ cString iconName("");
+ switch (screenWidth) {
+ case 1920:
+ case 1440:
+ iconName = "hd1080i";
+ break;
+ case 1280:
+ iconName = "hd720p";
+ break;
+ case 720:
+ iconName = "sd576i";
+ break;
+ default:
+ iconName = "sd576i";
+ break;
+ }
+ if (imgLoader.LoadIcon(*iconName, config.resolutionIconSize)) {
+ pixmapScreenResolution->DrawImage(cPoint(0,0), imgLoader.GetImage());
+ }
+ lastScreenWidth = screenWidth;
+ }
+}
+
+void cNopacityDisplayChannel::DrawSignalMeter(void) {
+ signalWidth = infoWidth * 0.15;
+ signalHeight = signalWidth *15 / 200;
+ showSignal = false;
+ if (config.displaySignalStrength) {
+ cImageLoader imgLoader;
+ cString signalStrength = "STR";
+ cString signalQuality = "SNR";
+ if (imgLoader.LoadIcon("signal", signalWidth, signalHeight)) {
+ cImage imgSignal = imgLoader.GetImage();
+ signalWidth = imgSignal.Width();
+ signalHeight = imgSignal.Height();
+ int signalMeterY = streamInfoY + (streamInfoHeight - 2*signalHeight - 5)/2;
+ fontInfoline = cFont::CreateFont(config.fontName, signalHeight - 2);
+ int labelWidth = max(fontInfoline->Width(*signalStrength), fontInfoline->Width(*signalQuality)) + 2;
+ signalX = streamInfoHeight / 2 + labelWidth;
+ showSignal = true;
+ pixmapSignalStrength = osd->CreatePixmap(3, cRect(infoX + signalX, signalMeterY + 2, signalWidth + 2, signalHeight + 2));
+ pixmapSignalQuality = osd->CreatePixmap(3, cRect(infoX + signalX, signalMeterY + signalHeight + 5, signalWidth + 2, signalHeight + 2));
+ pixmapSignalMeter = osd->CreatePixmap(4, cRect(infoX + signalX + 1, signalMeterY + 3, signalWidth, 2*signalHeight + 3));
+ pixmapSignalLabel = osd->CreatePixmap(3, cRect(infoX + streamInfoHeight / 2, signalMeterY + 2, labelWidth, 2*signalHeight + 3));
+ pixmapSignalStrength->Fill(Theme.Color(clrProgressBarBack));
+ pixmapSignalQuality->Fill(Theme.Color(clrProgressBarBack));
+ pixmapSignalMeter->Fill(clrTransparent);
+ pixmapSignalLabel->Fill(clrTransparent);
+ if (config.channelFadeTime) {
+ pixmapSignalStrength->SetAlpha(0);
+ pixmapSignalQuality->SetAlpha(0);
+ pixmapSignalMeter->SetAlpha(0);
+ pixmapSignalLabel->SetAlpha(0);
+ }
+ pixmapSignalStrength->DrawImage(cPoint(1,1), imgSignal);
+ pixmapSignalQuality->DrawImage(cPoint(1,1), imgSignal);
+ pixmapSignalLabel->DrawText(cPoint(0, 2), *signalStrength, Theme.Color(clrChannelEPGInfo), clrTransparent, fontInfoline);
+ pixmapSignalLabel->DrawText(cPoint(0, signalHeight + 4), *signalQuality, Theme.Color(clrChannelEPGInfo), clrTransparent, fontInfoline);
+ }
+ }
+}
+
+void cNopacityDisplayChannel::DrawSignal(void) {
+ time_t Now = time(NULL);
+ if (Now != lastSignalDisplay) {
+ int SignalStrength = cDevice::ActualDevice()->SignalStrength();
+ int SignalQuality = cDevice::ActualDevice()->SignalQuality();
+ if ((SignalStrength == 0)&&(SignalQuality==0))
+ return;
+ if ((lastSignalStrength != SignalStrength) || (lastSignalQuality != SignalQuality)) {
+ pixmapSignalMeter->Fill(clrTransparent);
+ pixmapSignalMeter->DrawRectangle(cRect(double(SignalStrength) /100 * signalWidth, 0, signalWidth - (double)SignalStrength /100 * signalWidth + 1, signalHeight), Theme.Color(clrChannelBackground));
+ pixmapSignalMeter->DrawRectangle(cRect(double(SignalQuality) /100 * signalWidth, signalHeight + 3, signalWidth - (double)SignalQuality / 100 * signalWidth + 1, signalHeight + 1), Theme.Color(clrChannelBackground));
+ }
+ lastSignalStrength = SignalStrength;
+ lastSignalQuality = SignalQuality;
+ lastSignalDisplay = Now;
+ }
+
+}
+
+void cNopacityDisplayChannel::SetChannel(const cChannel *Channel, int Number) {
+ pixmapLogo->Fill(clrTransparent);
+ pixmapChannelInfo->Fill(clrTransparent);
+
+ if (withInfo) {
+ pixmapProgressBar->Fill(clrTransparent);
+ pixmapEPGInfo->Fill(clrTransparent);
+ }
+
+ channelChange = true;
+ lastSignalStrength = 0;
+ lastSignalQuality = 0;
+ cString ChannelNumber("");
+ cString ChannelName("");
+ groupSep = false;
+ if (Channel) {
+ ChannelName = Channel->Name();
+ if (!Channel->GroupSep()) {
+ DrawIcons(Channel);
+ ChannelNumber = cString::sprintf("%d%s", Channel->Number(), Number ? "-" : "");
+ } else
+ groupSep = true;
+ } else if (Number) {
+ ChannelNumber = cString::sprintf("%d-", Number);
+ } else {
+ ChannelName = ChannelString(NULL, 0);
+ }
+
+ cString channelString = cString::sprintf("%s %s", *ChannelNumber, *ChannelName);
+
+ if (!groupSep) {
+ pixmapChannelInfo->DrawText(cPoint(channelInfoHeight/2, (channelInfoHeight-fontHeader->Height())/2), channelString, Theme.Color(clrChannelHead), clrTransparent, fontHeader);
+
+ cImageLoader imgLoader;
+ if (imgLoader.LoadLogo(*ChannelName)) {
+ pixmapLogo->DrawImage(cPoint(config.logoBorder, (height-config.logoHeight)/2), imgLoader.GetImage());
+ }
+ } else {
+ if (withInfo) {
+ pixmapProgressBar->Fill(clrTransparent);
+ pixmapEPGInfo->Fill(clrTransparent);
+ pixmapEPGInfo->DrawText(cPoint(channelInfoHeight/2, (epgInfoHeight-fontHeader->Height())/2 - fontHeader->Height()/2), channelString, Theme.Color(clrChannelHead), clrTransparent, fontHeader);
+ } else {
+ pixmapChannelInfo->DrawText(cPoint(channelInfoHeight/2, (channelInfoHeight-fontHeader->Height())/2), channelString, Theme.Color(clrChannelHead), clrTransparent, fontHeader);
+ }
+ cImageLoader imgLoader;
+ if (imgLoader.LoadIcon("Channelseparator", config.logoHeight)) {
+ pixmapLogo->DrawImage(cPoint(config.logoBorder + (config.logoWidth - config.logoHeight)/2, (height-config.logoHeight)/2), imgLoader.GetImage());
+ }
+ }
+}
+
+void cNopacityDisplayChannel::SetEvents(const cEvent *Present, const cEvent *Following) {
+ if (!withInfo)
+ return;
+ if (present != Present)
+ lastSeen = -1;
+ present = Present;
+
+ if (Present || Following) {
+ pixmapProgressBar->Fill(clrTransparent);
+ pixmapEPGInfo->Fill(clrTransparent);
+ }
+ int indent = 20;
+
+ for (int i = 0; i < 2; i++) {
+ const cEvent *e = !i ? Present : Following;
+ int y = !i ? 0 : 2;
+ if (e) {
+ cString startTime = e->GetTimeString();
+ int startTimeWidth = fontEPG->Width(*startTime);
+ int epgWidth = fontEPG->Width(e->Title());
+ int epgWidthShort = fontEPGSmall->Width(e->ShortText());
+ cString strSeen("");
+ if (i==0) {
+ int seen = (int)(time(NULL) - e->StartTime())/60;
+ strSeen = cString::sprintf("%d/%dmin", seen, e->Duration()/60);
+ } else {
+ strSeen = cString::sprintf("%dmin", e->Duration()/60);
+ }
+ int seenWidth = fontEPG->Width(*strSeen);
+ int space = infoWidth - 9*indent - seenWidth - startTimeWidth - config.resolutionIconSize;
+ cString strEPG;
+ if (space < epgWidth) {
+ cTextWrapper epgInfoWrapper(e->Title(), fontEPG, space);
+ strEPG = epgInfoWrapper.GetLine(0);
+ strEPG = cString::sprintf("%s...", *strEPG);
+ } else {
+ strEPG = e->Title();
+ }
+ cString strEPGShort("");
+ int spaceShort = infoWidth - 6*indent - startTimeWidth - config.resolutionIconSize;
+ if (spaceShort < epgWidthShort) {
+ cTextWrapper epgInfoWrapper(e->ShortText(), fontEPGSmall, spaceShort);
+ strEPGShort = epgInfoWrapper.GetLine(0);
+ strEPGShort = cString::sprintf("%s...", *strEPGShort);
+ } else {
+ strEPGShort = e->ShortText();
+ }
+ tColor fontColor = (i==0)?Theme.Color(clrChannelEPG):Theme.Color(clrChannelEPGInfo);
+ pixmapEPGInfo->DrawText(cPoint(indent, y * epgInfoLineHeight), *startTime, fontColor, clrTransparent, fontEPG);
+ pixmapEPGInfo->DrawText(cPoint(2 * indent + startTimeWidth, y * epgInfoLineHeight), *strEPG, fontColor, clrTransparent, fontEPG);
+ pixmapEPGInfo->DrawText(cPoint(2 * indent + startTimeWidth, (y+1) * epgInfoLineHeight + 3), *strEPGShort, fontColor, clrTransparent, fontEPGSmall);
+ int x = infoWidth - indent - seenWidth - config.resolutionIconSize - indent;
+ pixmapEPGInfo->DrawText(cPoint(x, y * epgInfoLineHeight), *strSeen, fontColor, clrTransparent, fontEPG);
+ }
+ }
+}
+
+void cNopacityDisplayChannel::DrawProgressBar(int Current, int Total) {
+ if ((Current < currentLast + 3) && !channelChange)
+ return;
+ currentLast = Current;
+ if ((Current > 0) || (Total > 0)) {
+ int barHeight = pixmapProgressBar->ViewPort().Height()-8;
+ if (barHeight%2 != 0)
+ barHeight++;
+ int barFullWidth = pixmapProgressBar->ViewPort().Width() - 20 - barHeight;
+ double percentSeen = ((double)Current) / (double)Total;
+
+ pixmapProgressBar->DrawEllipse(cRect(9, 3, barHeight+2, barHeight+2), Theme.Color(clrProgressBarBack));
+ pixmapProgressBar->DrawEllipse(cRect(9 + barFullWidth, 3, barHeight+2, barHeight+2), Theme.Color(clrProgressBarBack));
+ pixmapProgressBar->DrawRectangle(cRect( 9 + barHeight/2, 3, barFullWidth, barHeight+1), Theme.Color(clrProgressBarBack));
+
+ pixmapProgressBar->DrawEllipse(cRect(10, 4, barHeight, barHeight), Theme.Color(clrProgressBarBlend));
+ if (Current > 0) {
+ tColor colAct = DrawProgressbarBackground(10 + barHeight/2, 4, barFullWidth * percentSeen, barHeight-1);
+ pixmapProgressBar->DrawEllipse(cRect(10 + barFullWidth * percentSeen, 4, barHeight, barHeight), colAct);
+ //pixmapProgressBar->DrawRectangle(cRect( 10 + barHeight/2, 4, barFullWidth * percentSeen, barHeight-1), Theme.Color(clrProgressBar));
+ }
+ }
+}
+
+tColor cNopacityDisplayChannel::DrawProgressbarBackground(int left, int top, int width, int height) {
+
+ tColor clr1 = Theme.Color(clrProgressBar);
+ tColor clr2 = Theme.Color(clrProgressBarBlend);
+ tColor clr = 0x00000000;
+ int step = width / 256;
+ int alpha = 0x0;
+ int alphaStep;
+ int maximum = 0;
+ if (step == 0) { //width < 256
+ step = 1;
+ alphaStep = 256 / width;
+ maximum = width;
+ } else { //width > 256
+ alphaStep = 0x1;
+ maximum = 256;
+ }
+ int x = 0;
+ for (int i = 0; i < maximum; i++) {
+ x = left + i*step;
+ clr = AlphaBlend(clr1, clr2, alpha);
+ pixmapProgressBar->DrawRectangle(cRect(x,top,step,height), clr);
+ alpha += alphaStep;
+ }
+ if (step > 0) {
+ int rest = width - step*256;
+ pixmapProgressBar->DrawRectangle(cRect(left+step*256, top, rest, height), clr);
+ }
+ return clr;
+}
+
+void cNopacityDisplayChannel::SetMessage(eMessageType Type, const char *Text) {
+}
+
+void cNopacityDisplayChannel::Flush(void) {
+ DrawDate();
+ if (!groupSep)
+ DrawScreenResolution();
+ if (config.displaySignalStrength && showSignal) {
+ DrawSignal();
+ }
+ if (withInfo) {
+ int Current = 0;
+ int Total = 0;
+ if (present) {
+ time_t t = time(NULL);
+ if (t > present->StartTime())
+ Current = t - present->StartTime();
+ Total = present->Duration();
+ DrawProgressBar(Current, Total);
+ }
+ }
+ if (initial) {
+ if (config.channelFadeTime)
+ Start();
+ }
+ initial = false;
+ channelChange = false;
+ osd->Flush();
+}
+
+void cNopacityDisplayChannel::Action(void) {
+ uint64_t Start = cTimeMs::Now();
+ while (true) {
+ uint64_t Now = cTimeMs::Now();
+ cPixmap::Lock();
+ double t = min(double(Now - Start) / FadeTime, 1.0);
+ int Alpha = t * ALPHA_OPAQUE;
+ pixmapBackgroundTop->SetAlpha(Alpha);
+ pixmapBackgroundBottom->SetAlpha(Alpha);
+ pixmapLogo->SetAlpha(Alpha);
+ pixmapChannelInfo->SetAlpha(Alpha);
+ pixmapDate->SetAlpha(Alpha);
+ if (withInfo) {
+ pixmapBackgroundMiddle->SetAlpha(Alpha);
+ pixmapProgressBar->SetAlpha(Alpha);
+ pixmapEPGInfo->SetAlpha(Alpha);
+ }
+ pixmapStreamInfo->SetAlpha(Alpha);
+ if (pixmapScreenResolution)
+ pixmapScreenResolution->SetAlpha(Alpha);
+ if (config.displaySignalStrength && showSignal) {
+ pixmapSignalStrength->SetAlpha(Alpha);
+ pixmapSignalQuality->SetAlpha(Alpha);
+ pixmapSignalMeter->SetAlpha(Alpha);
+ pixmapSignalLabel->SetAlpha(Alpha);
+ }
+ osd->Flush();
+ cPixmap::Unlock();
+ int Delta = cTimeMs::Now() - Now;
+ if (Delta < FrameTime)
+ cCondWait::SleepMs(FrameTime - Delta);
+ if ((int)(Now - Start) > FadeTime) {
+ break;
+ }
+ }
+} \ No newline at end of file
diff --git a/displaychannel.h b/displaychannel.h
new file mode 100644
index 0000000..9052c0e
--- /dev/null
+++ b/displaychannel.h
@@ -0,0 +1,74 @@
+#ifndef __NOPACITY_DISPLAYCHANNEL_H
+#define __NOPACITY_DISPLAYCHANNEL_H
+
+class cNopacityDisplayChannel : public cSkinDisplayChannel, cThread {
+private:
+ int FrameTime;
+ int FadeTime;
+ bool withInfo;
+ bool initial;
+ bool groupSep;
+ bool channelChange;
+ cString lastDate;
+ int lastSeen;
+ time_t lastSignalDisplay;
+ int lastSignalStrength;
+ int lastSignalQuality;
+ int lastScreenWidth;
+ int currentLast;
+ bool showSignal;
+ const cEvent *present;
+ cOsd *osd;
+ cPixmap *pixmapBackgroundTop;
+ cPixmap *pixmapBackgroundMiddle;
+ cPixmap *pixmapBackgroundBottom;
+ cPixmap *pixmapChannelInfo;
+ cPixmap *pixmapDate;
+ cPixmap *pixmapLogo;
+ cPixmap *pixmapProgressBar;
+ cPixmap *pixmapEPGInfo;
+ cPixmap *pixmapStreamInfo;
+ cPixmap *pixmapSignalStrength;
+ cPixmap *pixmapSignalQuality;
+ cPixmap *pixmapSignalMeter;
+ cPixmap *pixmapSignalLabel;
+ cPixmap *pixmapScreenResolution;
+ int height;
+ int infoWidth;
+ int infoX;
+ int channelInfoWidth;
+ int channelInfoHeight;
+ int dateWidth;
+ int progressBarHeight;
+ int epgInfoHeight;
+ int epgInfoLineHeight;
+ int streamInfoHeight;
+ int streamInfoY;
+ int signalWidth, signalHeight, signalX;
+ cFont *fontHeader;
+ cFont *fontDate;
+ cFont *fontEPG;
+ cFont *fontEPGSmall;
+ cFont *fontInfoline;
+ virtual void Action(void);
+ void SetGeometry(void);
+ void CreatePixmaps(void);
+ void CreateFonts(void);
+ void DrawBackground(void);
+ void DrawDate(void);
+ void DrawProgressBar(int Current, int Total);
+ tColor DrawProgressbarBackground(int left, int top, int width, int height);
+ void DrawIcons(const cChannel *channel);
+ void DrawScreenResolution(void);
+ void DrawSignalMeter(void);
+ void DrawSignal(void);
+ static cBitmap bmTeletext, bmRadio, bmAudio, bmDolbyDigital, bmEncrypted, bmRecording;
+public:
+ cNopacityDisplayChannel(bool WithInfo);
+ virtual ~cNopacityDisplayChannel();
+ virtual void SetChannel(const cChannel *Channel, int Number);
+ virtual void SetEvents(const cEvent *Present, const cEvent *Following);
+ virtual void SetMessage(eMessageType Type, const char *Text);
+ virtual void Flush(void);
+};
+#endif //__NOPACITY_DISPLAYCHANNEL_H \ No newline at end of file
diff --git a/displaymenu.c b/displaymenu.c
new file mode 100644
index 0000000..ea1a868
--- /dev/null
+++ b/displaymenu.c
@@ -0,0 +1,461 @@
+#include "displaymenu.h"
+#include <string>
+
+cNopacityDisplayMenu::cNopacityDisplayMenu(void) {
+ int start = cTimeMs::Now();
+ config.setDynamicValues();
+ menuCategoryLast = mcUndefined;
+ menuSubCategory = mcSubUndefined;
+ menuSubCategoryLast = mcSubUndefined;
+ FrameTime = config.menuFrameTime;
+ FadeTime = config.menuFadeTime;
+ initial = true;
+ initMenu = true;
+ diskUsageDrawn = false;
+ timersDrawn = false;
+ lastDiskUsageState = -1;
+ lastTimersState = -1;
+ menuItemIndexLast = -1;
+ currentNumItems = 0;
+ menuHasIcons = true;
+ detailView = NULL;
+ contentNarrow = true;
+ contentNarrowLast = true;
+ menuView = new cNopacityDisplayMenuView();
+ osd = menuView->createOsd();
+ menuView->SetGeometry();
+ menuView->CreatePixmaps();
+ menuView->CreateFonts();
+ menuView->SetAvrgFontWidth();
+ menuView->CreateBackgroundImages(handleBackgrounds, handleButtons);
+ menuView->DrawHeaderLogo();
+ menuView->DrawBorderDecoration();
+ dsyslog("nopacity: Construktor needed %d ms", int(cTimeMs::Now()-start));
+}
+
+cNopacityDisplayMenu::~cNopacityDisplayMenu() {
+ if (Running()) {
+ Cancel();
+ cCondWait::SleepMs(300);
+ }
+ delete menuView;
+ menuItems.Clear();
+ if (detailView) {
+ delete detailView;
+ }
+ timers.Clear();
+ for (int i=0; i<6; i++)
+ cOsdProvider::DropImage(handleBackgrounds[i]);
+ for (int i=0; i<4; i++)
+ cOsdProvider::DropImage(handleButtons[i]);
+
+ delete osd;
+}
+
+void cNopacityDisplayMenu::DrawDisk(void) {
+ if (initial || ((menuCategoryLast!=mcMain)&&(MenuCategory()==mcMain)&&!diskUsageDrawn)) {
+ if (cVideoDiskUsage::HasChanged(lastDiskUsageState)) {
+ menuView->DrawDiskUsage();
+ } else {
+ menuView->ShowDiskUsage(true);
+ }
+ diskUsageDrawn = true;
+ }
+}
+
+void cNopacityDisplayMenu::DrawTimers(void) {
+ int maxTimersHeight = menuView->GetTimersMaxHeight();
+ if (initial || ((menuCategoryLast!=mcMain)&&(MenuCategory()==mcMain)&&!timersDrawn)) {
+ if (Timers.Modified(lastTimersState)) {
+ timers.Clear();
+ cSortedTimers SortedTimers;
+ int numTimers = SortedTimers.Size();
+ int currentHeight = menuView->GetTimersInitHeight();
+ for (int i = 0; i < numTimers; i++) {
+ if (const cTimer *Timer = SortedTimers[i]) {
+ cNopacityTimer *t = menuView->DrawTimer(Timer, currentHeight);
+ if (initial)
+ if (FadeTime)
+ t->SetAlpha(0);
+ currentHeight += t->pixmap->ViewPort().Height() + menuView->spaceMenu;
+ if (currentHeight < maxTimersHeight) {
+ timers.Add(t);
+ } else {
+ delete t;
+ break;
+ }
+ }
+ }
+ } else {
+ for (cNopacityTimer *t = timers.First(); t; t = timers.Next(t)) {
+ t->SetLayer(2);
+ }
+ }
+ timersDrawn = true;
+ }
+}
+
+void cNopacityDisplayMenu::Scroll(bool Up, bool Page) {
+ bool scrolled;
+ scrolled = detailView->Scroll(Up, Page);
+ if (scrolled) {
+ double height = detailView->ScrollbarSize();
+ double offset = detailView->Offset();
+ menuView->DrawScrollbar(height, offset);
+ }
+}
+
+int cNopacityDisplayMenu::MaxItems(void) {
+ int maxItems = 0;
+ if (((MenuCategory() == mcChannel) && (menuSubCategory == mcSubChannelEdit) && (menuSubCategoryLast != mcSubChannelEdit))
+ || (menuSubCategory == mcSubScheduleTimer)){
+ maxItems = config.numDefaultMenuItems;
+ } else {
+ maxItems = menuView->GetMaxItems(MenuCategory());
+ }
+ currentNumItems = maxItems;
+ return maxItems;
+}
+
+void cNopacityDisplayMenu::Clear(void) {
+ if (detailView) {
+ delete detailView;
+ detailView = NULL;
+ }
+ menuItemIndexLast = -1;
+ initMenu = true;
+ menuItems.Clear();
+}
+
+void cNopacityDisplayMenu::SetMenuCategory(eMenuCategory MenuCategory) {
+ /* Categories:
+ mcUndefined = -1,
+ mcUnknown = 0,
+ mcMain = 1,
+ mcSchedule = 2,
+ mcChannel = 3,
+ mcTimer = 4,
+ mcRecording = 5,
+ mcPlugin = 6,
+ mcSetup = 7,
+ mcCommand = 8,
+ mcEvent = 9,
+ mcText = 10,
+ mcFolder = 11,
+ mcCam = 12
+ */
+ menuCategoryLast = this->MenuCategory();
+ cSkinDisplayMenu::SetMenuCategory(MenuCategory);
+ if ((menuCategoryLast == mcMain) && (MenuCategory != mcMain)) {
+ menuView->ShowDiskUsage(false);
+ for (cNopacityTimer *t = timers.First(); t; t = timers.Next(t)) {
+ t->SetLayer(-1);
+ }
+ diskUsageDrawn = false;
+ timersDrawn = false;
+ }
+}
+
+void cNopacityDisplayMenu::SetTitle(const char *Title) {
+ contentNarrowLast = contentNarrow;
+ menuSubCategoryLast = menuSubCategory;
+ int left = 5;
+ menuView->DestroyHeaderIcon();
+ if (Title) {
+ cString title = Title;
+ if (MenuCategory() == mcMain) {
+ title = cString::sprintf("%s %s", Title, VDRVERSION);
+ left += menuView->ShowHeaderLogo(true);
+ contentNarrow = true;
+ menuHasIcons = true;
+ } else {
+ menuView->ShowHeaderLogo(false);
+ if (MenuCategory() == mcSchedule) {
+ if (startswith(Title, trVDR("Schedule"))) {
+ menuSubCategory = mcSubSchedule;
+ left += menuView->ShowHeaderIconChannelLogo(Title);
+ menuHasIcons = true;
+ contentNarrow = true;
+ } else if (endswith(Title, "%")) {
+ //hack for epgsearch timer conflict view
+ menuSubCategory = mcSubScheduleTimer;
+ menuHasIcons = false;
+ contentNarrow = false;
+ currentNumItems = config.numDefaultMenuItems;
+ } else {
+ menuSubCategory = mcSubScheduleWhatsOn;
+ left += menuView->DrawHeaderIcon(mcSchedule);
+ menuHasIcons = true;
+ contentNarrow = true;
+ }
+ } else if (MenuCategory() == mcChannel) {
+ left += menuView->DrawHeaderIcon(mcChannel);
+ if (startswith(Title, trVDR("Channels"))) {
+ contentNarrow = true;
+ menuSubCategory = mcSubChannels;
+ menuHasIcons = true;
+ } else {
+ contentNarrow = false;
+ menuSubCategory = mcSubChannelEdit;
+ menuHasIcons = false;
+ }
+ } else {
+ left += menuView->DrawHeaderIcon(MenuCategory());
+ contentNarrow = false;
+ menuHasIcons = false;
+ }
+ }
+ menuView->AdjustContentBackground(contentNarrow, contentNarrowLast);
+ menuView->DrawHeaderLabel(left, title);
+ if (MenuCategory() == mcEvent) {
+ channelName = Title;
+ }
+ }
+}
+
+void cNopacityDisplayMenu::SetButtons(const char *Red, const char *Green, const char *Yellow, const char *Blue) {
+ if (Red) {
+ menuView->DrawButton(Red, handleButtons[0], Theme.Color(clrButtonRedBorder), 0);
+ } else
+ menuView->ClearButton(0);
+
+ if (Green) {
+ menuView->DrawButton(Green, handleButtons[1], Theme.Color(clrButtonGreenBorder), 1);
+ } else
+ menuView->ClearButton(1);
+
+ if (Yellow) {
+ menuView->DrawButton(Yellow, handleButtons[2], Theme.Color(clrButtonYellowBorder), 2);
+ } else
+ menuView->ClearButton(2);
+
+ if (Blue) {
+ menuView->DrawButton(Blue, handleButtons[3], Theme.Color(clrButtonBlueBorder), 3);
+ } else
+ menuView->ClearButton(3);
+}
+
+void cNopacityDisplayMenu::SetMessage(eMessageType Type, const char *Text) {
+ if (Text) {
+ menuView->DrawMessage(Type, Text);
+ } else {
+ menuView->ClearMessage();
+ }
+}
+
+void cNopacityDisplayMenu::SetItem(const char *Text, int Index, bool Current, bool Selectable) {
+ cString *strItems = new cString[MaxTabs];
+ int *tabItems = new int[2*MaxTabs];
+ for (int i=0; i<MaxTabs; i++) {
+ strItems[i] = "";
+ tabItems[i] = 0;
+ tabItems[i+MaxTabs] = 0;
+ }
+ SplitItem(Text, strItems, tabItems);
+ int menuIconWidth = 0;
+ int menuIconHeight = 0;
+ if (initMenu) {
+ if (Index > menuItemIndexLast) {
+ cNopacityMenuItem *item;
+ cPoint itemSize;
+ if (MenuCategory() == mcMain) {
+ item = new cNopacityMainMenuItem(osd, Text, Current, Selectable);
+ menuView->GetMenuItemSize(mcMain, &itemSize);
+ item->SetFont(menuView->GetMenuItemFont(mcMain));
+ menuIconWidth = menuIconHeight = config.iconHeight;
+ } else if (MenuCategory() == mcSchedule) {
+ if (menuSubCategory == mcSubScheduleTimer) {
+ item = new cNopacityDefaultMenuItem(osd, Text, Current, Selectable);
+ menuView->GetMenuItemSize(mcUnknown, &itemSize);
+ item->SetFont(menuView->GetMenuItemFont(mcUnknown));
+ } else {
+ item = new cNopacityScheduleMenuItem(osd, Text, Current, Selectable, menuSubCategory);
+ menuView->GetMenuItemSize(mcSchedule, &itemSize);
+ item->SetFont(menuView->GetMenuItemFont(mcSchedule));
+ menuIconWidth = config.menuItemLogoWidth;
+ menuIconHeight = config.menuItemLogoHeight;
+ }
+ } else if (MenuCategory() == mcChannel) {
+ if (menuSubCategory == mcSubChannels) {
+ item = new cNopacityChannelMenuItem(osd, Text, Current, Selectable);
+ menuView->GetMenuItemSize(mcChannel, &itemSize);
+ item->SetFont(menuView->GetMenuItemFont(mcChannel));
+ menuIconWidth = config.menuItemLogoWidth;
+ menuIconHeight = config.menuItemLogoHeight;
+ } else {
+ item = new cNopacityDefaultMenuItem(osd, Text, Current, Selectable);
+ menuView->GetMenuItemSize(mcUnknown, &itemSize);
+ item->SetFont(menuView->GetMenuItemFont(mcUnknown));
+ }
+ } else {
+ item = new cNopacityDefaultMenuItem(osd, Text, Current, Selectable);
+ menuView->GetMenuItemSize(mcUnknown, &itemSize);
+ item->SetFont(menuView->GetMenuItemFont(mcUnknown));
+ }
+ item->SetBackgrounds(handleBackgrounds);
+ item->SetTabs(strItems, tabItems, MaxTabs);
+ int spaceTop = menuView->GetMenuTop(currentNumItems, itemSize.Y());
+ if (menuHasIcons) {
+ item->CreatePixmapIcon(spaceTop, menuView->spaceMenu, Index, itemSize.Y(), menuIconWidth, menuIconHeight);
+ }
+ item->CreatePixmap(spaceTop, menuView->spaceMenu, Index, itemSize.X(), itemSize.Y());
+ menuItems.Add(item);
+ item->Render();
+ menuItemIndexLast = Index;
+ if (initial) {
+ if (FadeTime) {
+ item->SetAlpha(0);
+ item->SetAlphaIcon(0);
+ }
+ }
+ } else {
+ //adjust Current if item was added twice
+ cNopacityMenuItem *item = menuItems.Get(Index);
+ item->SetCurrent(Current);
+ item->Render();
+ }
+ } else {
+ cNopacityMenuItem *item = menuItems.Get(Index);
+ item->SetTabs(strItems, tabItems, MaxTabs);
+ item->SetCurrent(Current);
+ item->Render();
+ }
+ SetEditableWidth(menuView->GetEditableWidth());
+}
+
+void cNopacityDisplayMenu::SplitItem(const char *Text, cString *strItems, int *tabItems) {
+ int x = 0;
+ for (int i = 0; i < MaxTabs; i++) {
+ const char *s = GetTabbedText(Text, i);
+ if (s) {
+ strItems[i] = s;
+ tabItems[i] = Tab(i);
+ if (i>0) {
+ tabItems[(i-1) + MaxTabs] = Tab(i) - x;
+ }
+ x += Tab(i) - x;
+ }
+ if (!Tab(i + 1)) {
+ tabItems[i + MaxTabs] = menuView->GetWidthDefaultMenu() - x;
+ break;
+ }
+ }
+}
+
+int cNopacityDisplayMenu::Tab(int n) {
+ return (n >= 0 && n < MaxTabs) ? menuView->mytabs[n] : 0;
+}
+
+void cNopacityDisplayMenu::SetTabs(int Tab1, int Tab2, int Tab3, int Tab4, int Tab5) {
+ menuView->SetTabs(Tab1, Tab2, Tab3, Tab4, Tab5);
+}
+
+int cNopacityDisplayMenu::GetTextAreaWidth(void) const {
+ return menuView->GetTextAreaWidth();
+}
+
+const cFont *cNopacityDisplayMenu::GetTextAreaFont(bool FixedFont) const {
+ return menuView->GetTextAreaFont(FixedFont);
+}
+
+void cNopacityDisplayMenu::SetScrollbar(int Total, int Offset) {
+ if (MaxItems() >= Total) {
+ menuView->ClearScrollbar();
+ return;
+ }
+ double height = (double)MaxItems()/(double)Total;
+ double offset = (double)Offset/(double)Total;
+
+ menuView->DrawScrollbar(height, offset);
+}
+
+void cNopacityDisplayMenu::SetEvent(const cEvent *Event) {
+ if (!Event)
+ return;
+ menuView->AdjustContentBackground(false, contentNarrowLast);
+ detailView = new cNopacityMenuDetailEventView(osd, Event, channelName);
+ menuView->SetDetailViewSize(dvEvent, detailView);
+ detailView->SetFonts();
+ detailView->SetContent(Event->Description());
+ detailView->CreatePixmaps();
+ detailView->Render();
+ if (detailView->Scrollable()) {
+ double height = detailView->ScrollbarSize();
+ double offset = 0.0;
+ menuView->DrawScrollbar(height, offset);
+ }
+}
+
+void cNopacityDisplayMenu::SetRecording(const cRecording *Recording) {
+ if (!Recording)
+ return;
+ menuView->AdjustContentBackground(false, contentNarrowLast);
+ detailView = new cNopacityMenuDetailRecordingView(osd, Recording);
+ menuView->SetDetailViewSize(dvRecording, detailView);
+ detailView->SetFonts();
+ detailView->SetContent(Recording->Info()->Description());
+ detailView->CreatePixmaps();
+ detailView->Render();
+ if (detailView->Scrollable()) {
+ double height = detailView->ScrollbarSize();
+ double offset = 0.0;
+ menuView->DrawScrollbar(height, offset);
+ }
+}
+
+void cNopacityDisplayMenu::SetText(const char *Text, bool FixedFont) {
+ if (!Text)
+ return;
+ menuView->AdjustContentBackground(false, contentNarrowLast);
+ detailView = new cNopacityMenuDetailTextView(osd);
+ menuView->SetDetailViewSize(dvText, detailView);
+ detailView->SetFonts();
+ detailView->SetContent(Text);
+ detailView->CreatePixmaps();
+ detailView->Render();
+ if (detailView->Scrollable()) {
+ double height = detailView->ScrollbarSize();
+ double offset = 0.0;
+ menuView->DrawScrollbar(height, offset);
+ }
+}
+
+void cNopacityDisplayMenu::Flush(void) {
+ menuView->DrawDate(initial);
+ if (MenuCategory() == mcMain) {
+ DrawDisk();
+ DrawTimers();
+ }
+ if (initial) {
+ if (FadeTime)
+ Start();
+ }
+ initMenu = false;
+ initial = false;
+ osd->Flush();
+}
+
+void cNopacityDisplayMenu::Action(void) {
+ uint64_t Start = cTimeMs::Now();
+ while (Running()) {
+ uint64_t Now = cTimeMs::Now();
+ cPixmap::Lock();
+ double t = min(double(Now - Start) / FadeTime, 1.0);
+ int Alpha = t * ALPHA_OPAQUE;
+ menuView->SetPixmapAlpha(Alpha);
+ for (cNopacityMenuItem *item = menuItems.First(); item; item = menuItems.Next(item)) {
+ item->SetAlpha(Alpha);
+ item->SetAlphaIcon(Alpha);
+ }
+ for (cNopacityTimer *t = timers.First(); t; t = timers.Next(t)) {
+ t->SetAlpha(Alpha);
+ }
+ osd->Flush();
+ cPixmap::Unlock();
+ int Delta = cTimeMs::Now() - Now;
+ if (Delta < FrameTime)
+ cCondWait::SleepMs(FrameTime - Delta);
+ if ((int)(Now - Start) > FadeTime)
+ break;
+ }
+}
diff --git a/displaymenu.h b/displaymenu.h
new file mode 100644
index 0000000..438e77e
--- /dev/null
+++ b/displaymenu.h
@@ -0,0 +1,56 @@
+#ifndef __NOPACITY_DISPLAYMENU_H
+#define __NOPACITY_DISPLAYMENU_H
+
+class cNopacityDisplayMenu : public cSkinDisplayMenu , cThread {
+private:
+ cNopacityDisplayMenuView *menuView;
+ cNopacityMenuDetailView *detailView;
+ cOsd *osd;
+ eMenuCategory menuCategoryLast;
+ eMenuSubCategory menuSubCategory;
+ eMenuSubCategory menuSubCategoryLast;
+ int FrameTime;
+ int FadeTime;
+ bool initial;
+ bool initMenu;
+ bool diskUsageDrawn;
+ int lastDiskUsageState;
+ int lastTimersState;
+ bool timersDrawn;
+ int menuItemIndexLast;
+ int currentNumItems;
+ bool menuHasIcons;
+ bool contentNarrow, contentNarrowLast;
+ cList<cNopacityTimer> timers;
+ cList<cNopacityMenuItem> menuItems;
+ int handleBackgrounds[6];
+ int handleButtons[4];
+ void DrawDisk(void);
+ void DrawTimers(void);
+ void SplitItem(const char *Text, cString *strItems, int *tabItems);
+ const char *channelName;
+ virtual void Action(void);
+protected:
+ int Tab(int n);
+public:
+ cNopacityDisplayMenu(void);
+ virtual ~cNopacityDisplayMenu();
+ virtual void Scroll(bool Up, bool Page);
+ virtual int MaxItems(void);
+ virtual void Clear(void);
+ virtual void SetMenuCategory(eMenuCategory MenuCategory);
+ 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 SetScrollbar(int Total, int Offset);
+ virtual void SetEvent(const cEvent *Event);
+ virtual void SetRecording(const cRecording *Recording);
+ virtual void SetText(const char *Text, bool FixedFont);
+ virtual void Flush(void);
+ virtual void SetTabs(int Tab1, int Tab2 = 0, int Tab3 = 0, int Tab4 = 0, int Tab5 = 0);
+ virtual int GetTextAreaWidth(void) const;
+ virtual const cFont *GetTextAreaFont(bool FixedFont) const;
+};
+
+#endif //__NOPACITY_DISPLAYMENU_H \ No newline at end of file
diff --git a/displaymenuview.c b/displaymenuview.c
new file mode 100644
index 0000000..9bc89d0
--- /dev/null
+++ b/displaymenuview.c
@@ -0,0 +1,627 @@
+#include "displaymenuview.h"
+
+cNopacityTimer::cNopacityTimer(cOsd *osd) {
+ this->osd = osd;
+}
+
+cNopacityTimer::~cNopacityTimer(void) {
+ osd->DestroyPixmap(pixmap);
+}
+
+cNopacityDisplayMenuView::cNopacityDisplayMenuView() {
+ diskUsageAlert = 95;
+ pixmapStatus = NULL;
+ pixmapHeaderIcon = NULL;
+}
+
+cNopacityDisplayMenuView::~cNopacityDisplayMenuView(void) {
+ osd->DestroyPixmap(pixmapHeader);
+ osd->DestroyPixmap(pixmapHeaderLogo);
+ osd->DestroyPixmap(pixmapHeaderLabel);
+ osd->DestroyPixmap(pixmapDate);
+ osd->DestroyPixmap(pixmapFooter);
+ osd->DestroyPixmap(pixmapContent);
+ osd->DestroyPixmap(pixmapScrollbar);
+ osd->DestroyPixmap(pixmapDiskUsage);
+ osd->DestroyPixmap(pixmapDiskUsageIcon);
+ osd->DestroyPixmap(pixmapDiskUsageLabel);
+ if (pixmapHeaderIcon)
+ osd->DestroyPixmap(pixmapHeaderIcon);
+
+ delete fontHeader;
+ delete fontDate;
+ delete fontMenuitemLarge;
+ delete fontMenuitemSchedule;
+ delete fontMenuitemDefault;
+ delete fontDiskUsage;
+ delete fontTimers;
+ delete fontTimersHead;
+ delete fontButtons;
+ delete fontMessage;
+#ifdef USE_YAEPG
+ if (config.scalePicture) {
+ tArea availableArea;
+ availableArea.x1 = 0;
+ availableArea.y1 = 0;
+ availableArea.x2 = osdWidth;
+ availableArea.y2 = osdHeight;
+ ScalePreserveAspect(osd->vidWin, 4.0/3.0, availableArea);
+ osd->vidWin.bpp = 12;
+ }
+#endif
+}
+
+cOsd *cNopacityDisplayMenuView::createOsd(void) {
+ osdLeft = cOsd::OsdLeft();
+ osdTop = cOsd::OsdTop();
+ osdWidth = cOsd::OsdWidth();
+ osdHeight = cOsd::OsdHeight();
+ osd = CreateOsd(osdLeft, osdTop, osdWidth, osdHeight);
+ cDevice::PrimaryDevice()->GetVideoSize(screenWidth, screenHeight, aspect);
+ return osd;
+}
+
+void cNopacityDisplayMenuView::SetGeometry(void) {
+ spaceMenu = 5;
+ widthScrollbar = 20;
+ dateWidth = osdWidth * 0.3;
+ headerHeight = osdHeight * config.headerHeight / 100;
+ footerHeight = osdHeight * config.footerHeight / 100;
+ contentHeight = osdHeight - headerHeight - footerHeight;
+ contentWidthNarrow = osdWidth * config.menuWidthNarrow / 100;
+ contentWidthFull = osdWidth - widthScrollbar - spaceMenu;
+ menuItemWidthDefault = contentWidthFull - 4 * spaceMenu;
+ menuItemWidthMain = contentWidthNarrow - 4*spaceMenu;
+ menuItemHeightMain = config.iconHeight + 2;
+ menuItemHeightSchedule = config.menuItemLogoHeight + 2;
+ menuItemHeightDefault = contentHeight / config.numDefaultMenuItems - spaceMenu;
+ diskUsageWidth = diskUsageHeight = timersWidth = osdWidth * config.menuWidthRightItems / 100;
+ buttonsBorder = 10;
+ buttonWidth = (osdWidth / 4) - 2 * buttonsBorder;
+ buttonHeight = footerHeight - 3 * buttonsBorder;
+ messageWidth = 0.8 * osdWidth;
+ messageHeight = 0.1 * osdHeight;
+}
+
+void cNopacityDisplayMenuView::CreatePixmaps(void) {
+ pixmapHeader = osd->CreatePixmap(1, cRect(0, 0, osdWidth, headerHeight));
+ pixmapHeaderLogo = osd->CreatePixmap(-1, cRect(0, 0, config.menuHeaderLogoWidth, config.menuHeaderLogoHeight));
+ pixmapHeaderLabel = osd->CreatePixmap(2, cRect(0, 0, osdWidth - dateWidth, headerHeight));
+ pixmapDate = osd->CreatePixmap(2, cRect(osdWidth - dateWidth, 0, dateWidth, headerHeight));
+ pixmapFooter = osd->CreatePixmap(1, cRect(0, osdHeight-footerHeight, osdWidth, footerHeight));
+ pixmapContent = osd->CreatePixmap(1, cRect(0, headerHeight, osdWidth, contentHeight),
+ cRect(0, 0, osdWidth + contentWidthFull - contentWidthNarrow, contentHeight));
+ pixmapScrollbar = osd->CreatePixmap(2, cRect(contentWidthNarrow, headerHeight + spaceMenu, widthScrollbar, contentHeight - 2 * spaceMenu));
+ pixmapDiskUsage = osd->CreatePixmap(2, cRect(osdWidth - diskUsageWidth - 10, headerHeight + spaceMenu, diskUsageWidth, diskUsageHeight));
+ pixmapDiskUsageIcon = osd->CreatePixmap(3, cRect((osdWidth - diskUsageWidth - 10) + (diskUsageWidth)/8, headerHeight, diskUsageWidth*3/4, diskUsageWidth*3/4));
+ pixmapDiskUsageLabel = osd->CreatePixmap(3, cRect(osdWidth - diskUsageWidth - 10, headerHeight + spaceMenu, diskUsageWidth, diskUsageHeight));
+ pixmapHeaderLogo->Fill(clrTransparent);
+ pixmapHeaderLabel->Fill(clrTransparent);
+ pixmapDiskUsage->Fill(clrTransparent);
+ pixmapDiskUsageIcon->Fill(clrTransparent);
+ pixmapDiskUsageLabel->Fill(clrTransparent);
+ if (config.menuFadeTime) {
+ pixmapHeader->SetAlpha(0);
+ pixmapHeaderLogo->SetAlpha(0);
+ pixmapHeaderLabel->SetAlpha(0);
+ pixmapDate->SetAlpha(0);
+ pixmapFooter->SetAlpha(0);
+ pixmapContent->SetAlpha(0);
+ pixmapScrollbar->SetAlpha(0);
+ pixmapDiskUsage->SetAlpha(0);
+ pixmapDiskUsageIcon->SetAlpha(0);
+ pixmapDiskUsageLabel->SetAlpha(0);
+ }
+}
+
+void cNopacityDisplayMenuView::SetPixmapAlpha(int Alpha) {
+ pixmapHeader->SetAlpha(Alpha);
+ pixmapHeaderLogo->SetAlpha(Alpha);
+ pixmapHeaderLabel->SetAlpha(Alpha);
+ pixmapDate->SetAlpha(Alpha);
+ pixmapContent->SetAlpha(Alpha);
+ pixmapFooter->SetAlpha(Alpha);
+ pixmapScrollbar->SetAlpha(Alpha);
+ pixmapDiskUsage->SetAlpha(Alpha);
+ pixmapDiskUsageIcon->SetAlpha(Alpha);
+ pixmapDiskUsageLabel->SetAlpha(Alpha);
+}
+
+void cNopacityDisplayMenuView::CreateFonts(void) {
+ fontHeader = cFont::CreateFont(config.fontName, headerHeight / 2 + config.fontHeader);
+ fontDate = cFont::CreateFont(config.fontName, headerHeight / 2 + config.fontDate);
+ fontMenuitemLarge = cFont::CreateFont(config.fontName, menuItemHeightMain/3 + 4 + config.fontMenuitemLarge);
+ fontMenuitemSchedule = cFont::CreateFont(config.fontName, menuItemHeightSchedule / 4 + config.fontMenuitemSchedule);
+ fontMenuitemDefault = cFont::CreateFont(config.fontName, menuItemHeightDefault * 2 / 3 + config.fontMenuitemDefault);
+ fontDiskUsage = cFont::CreateFont(config.fontName, (diskUsageHeight/4)/2 - 2 + config.fontDiskUsage);
+ fontTimersHead = cFont::CreateFont(config.fontName, (contentHeight - 3*spaceMenu - diskUsageHeight) / 25 + config.fontTimersHead);
+ fontTimers = cFont::CreateFont(config.fontName, (contentHeight - 3*spaceMenu - diskUsageHeight) / 25 - 6 + config.fontTimers);
+ fontButtons = cFont::CreateFont(config.fontName, buttonHeight*0.8 + config.fontButtons);
+ fontMessage = cFont::CreateFont(config.fontName, messageHeight / 4 + config.fontMessageMenu);
+}
+
+cFont *cNopacityDisplayMenuView::GetMenuItemFont(eMenuCategory menuCat) {
+ switch (menuCat) {
+ case mcUnknown:
+ return fontMenuitemDefault;
+ case mcMain:
+ return fontMenuitemLarge;
+ case mcSchedule:
+ return fontMenuitemSchedule;
+ case mcChannel:
+ return fontMenuitemLarge;
+ default:
+ return fontMenuitemDefault;
+ }
+ return fontMenuitemDefault;
+}
+
+void cNopacityDisplayMenuView::GetMenuItemSize(eMenuCategory menuCat, cPoint *itemSize) {
+ int itemWidth = 0;
+ int itemHeight = 0;
+ switch (menuCat) {
+ case mcUnknown:
+ itemWidth = menuItemWidthDefault;
+ itemHeight = menuItemHeightDefault;
+ break;
+ case mcMain:
+ itemWidth = menuItemWidthMain;
+ itemHeight = menuItemHeightMain;
+ break;
+ case mcSchedule:
+ itemWidth = menuItemWidthMain;
+ itemHeight = menuItemHeightSchedule;
+ break;
+ case mcChannel:
+ itemWidth = menuItemWidthMain;
+ itemHeight = menuItemHeightSchedule;
+ break;
+ default:
+ itemWidth = menuItemWidthDefault;
+ itemHeight = menuItemHeightDefault;
+ break;
+ }
+ itemSize->Set(itemWidth, itemHeight);
+}
+
+int cNopacityDisplayMenuView::GetMaxItems(eMenuCategory menuCat) {
+ int maxItems = 0;
+ switch (menuCat) {
+ case mcUnknown:
+ maxItems = config.numDefaultMenuItems;
+ break;
+ case mcMain:
+ maxItems = contentHeight / (menuItemHeightMain + spaceMenu);
+ break;
+ case mcSchedule:
+ case mcChannel:
+ maxItems = contentHeight / (menuItemHeightSchedule + spaceMenu);
+ break;
+ default:
+ maxItems = config.numDefaultMenuItems;
+ }
+ return maxItems;
+}
+
+int cNopacityDisplayMenuView::GetMenuTop(int numItems, int itemHeight) {
+ return headerHeight + (contentHeight - numItems*(itemHeight + spaceMenu))/2;
+}
+
+void cNopacityDisplayMenuView::SetAvrgFontWidth(void) {
+ avrgFontWidth = fontMenuitemDefault->Width("x")+3;
+}
+
+void cNopacityDisplayMenuView::SetTabs(int Tab1, int Tab2, int Tab3, int Tab4, int Tab5) {
+ mytabs[0] = 1;
+ mytabs[1] = Tab1 ? mytabs[0] + Tab1 : 0;
+ mytabs[2] = Tab2 ? mytabs[1] + Tab2 : 0;
+ mytabs[3] = Tab3 ? mytabs[2] + Tab3 : 0;
+ mytabs[4] = Tab4 ? mytabs[3] + Tab4 : 0;
+ mytabs[5] = Tab5 ? mytabs[4] + Tab5 : 0;
+ if (Tab2) {
+ for (int i = 1; i < cSkinDisplayMenu::MaxTabs; i++)
+ mytabs[i] *= avrgFontWidth;
+ } else if (Tab1) {
+ mytabs[1] = GetEditableWidth();
+ }
+}
+
+int cNopacityDisplayMenuView::GetEditableWidth(void) {
+ return contentWidthFull*0.5;
+}
+
+int cNopacityDisplayMenuView::GetTextAreaWidth(void) {
+ return contentWidthFull - 2*spaceMenu;
+}
+
+const cFont *cNopacityDisplayMenuView::GetTextAreaFont(bool FixedFont) {
+ return cFont::CreateFont(config.fontName, contentHeight / 25 + config.fontDetailView);
+}
+
+void cNopacityDisplayMenuView::CreateBackgroundImages(int *handleBackgrounds, int *handleButtons) {
+ cImageLoader imgLoader;
+ imgLoader.DrawBackground(Theme.Color(clrMenuItem), Theme.Color(clrMenuItemBlend), menuItemWidthDefault-2, menuItemHeightDefault-2);
+ handleBackgrounds[0] = cOsdProvider::StoreImage(imgLoader.GetImage());
+ imgLoader.DrawBackground(Theme.Color(clrMenuItemHigh), Theme.Color(clrMenuItemHighBlend), menuItemWidthDefault-2, menuItemHeightDefault-2);
+ handleBackgrounds[1] = cOsdProvider::StoreImage(imgLoader.GetImage());
+ imgLoader.DrawBackground(Theme.Color(clrMenuItem), Theme.Color(clrMenuItemBlend), menuItemWidthMain-2, menuItemHeightMain-2);
+ handleBackgrounds[2] = cOsdProvider::StoreImage(imgLoader.GetImage());
+ imgLoader.DrawBackground(Theme.Color(clrMenuItemHigh), Theme.Color(clrMenuItemHighBlend), menuItemWidthMain-2, menuItemHeightMain-2);
+ handleBackgrounds[3] = cOsdProvider::StoreImage(imgLoader.GetImage());
+ imgLoader.DrawBackground(Theme.Color(clrMenuItem), Theme.Color(clrMenuItemBlend), menuItemWidthMain-2, menuItemHeightSchedule-2);
+ handleBackgrounds[4] = cOsdProvider::StoreImage(imgLoader.GetImage());
+ imgLoader.DrawBackground(Theme.Color(clrMenuItemHigh), Theme.Color(clrMenuItemHighBlend), menuItemWidthMain-2, menuItemHeightSchedule-2);
+ handleBackgrounds[5] = cOsdProvider::StoreImage(imgLoader.GetImage());
+
+ imgLoader.DrawBackground(Theme.Color(clrMenuBack), Theme.Color(clrButtonRed), buttonWidth-4, buttonHeight-4);
+ handleButtons[0] = cOsdProvider::StoreImage(imgLoader.GetImage());
+ imgLoader.DrawBackground(Theme.Color(clrMenuBack), Theme.Color(clrButtonGreen), buttonWidth-4, buttonHeight-4);
+ handleButtons[1] = cOsdProvider::StoreImage(imgLoader.GetImage());
+ imgLoader.DrawBackground(Theme.Color(clrMenuBack), Theme.Color(clrButtonYellow), buttonWidth-4, buttonHeight-4);
+ handleButtons[2] = cOsdProvider::StoreImage(imgLoader.GetImage());
+ imgLoader.DrawBackground(Theme.Color(clrMenuBack), Theme.Color(clrButtonBlue), buttonWidth-4, buttonHeight-4);
+ handleButtons[3] = cOsdProvider::StoreImage(imgLoader.GetImage());
+}
+
+void cNopacityDisplayMenuView::DrawBorderDecoration() {
+ cImageLoader imgLoader;
+ imgLoader.DrawBackground(Theme.Color(clrMenuItemHighBlend), Theme.Color(clrMenuBack), osdWidth, headerHeight);
+ pixmapHeader->DrawImage(cPoint(0,0), imgLoader.GetImage());
+ pixmapFooter->Fill(Theme.Color(clrMenuBack));
+
+ int borderWidth = 2;
+ int radius = 10;
+
+ pixmapContent->Fill(clrTransparent);
+ pixmapContent->DrawRectangle(cRect(0, 0, contentWidthFull-radius, contentHeight), Theme.Color(clrMenuBack));
+ pixmapContent->DrawRectangle(cRect(contentWidthFull, 0, osdWidth - contentWidthNarrow, borderWidth), Theme.Color(clrMenuBorder));
+ pixmapContent->DrawRectangle(cRect(contentWidthFull, contentHeight - borderWidth, osdWidth - contentWidthNarrow, borderWidth), Theme.Color(clrMenuBorder));
+ pixmapContent->DrawRectangle(cRect(contentWidthFull - radius, 0, radius, radius), Theme.Color(clrMenuBack));
+ pixmapContent->DrawEllipse(cRect(contentWidthFull - radius, 0, radius, radius), Theme.Color(clrMenuBorder),2);
+ pixmapContent->DrawEllipse(cRect(contentWidthFull - radius + borderWidth, borderWidth, radius-borderWidth, radius-borderWidth), clrTransparent, 2);
+ pixmapContent->DrawRectangle(cRect(contentWidthFull-radius, radius, borderWidth, contentHeight - 2*radius), Theme.Color(clrMenuBorder));
+ pixmapContent->DrawRectangle(cRect(contentWidthFull - radius, contentHeight - radius, radius, radius), Theme.Color(clrMenuBack));
+ pixmapContent->DrawEllipse(cRect(contentWidthFull - radius, contentHeight - radius, radius, radius), Theme.Color(clrMenuBorder),3);
+ pixmapContent->DrawEllipse(cRect(contentWidthFull - radius + borderWidth, contentHeight - radius, radius-borderWidth, radius-borderWidth), clrTransparent, 3);
+
+}
+
+void cNopacityDisplayMenuView::AdjustContentBackground(bool contentNarrow, bool contentNarrowLast) {
+ if (contentNarrow) {
+ pixmapContent->SetDrawPortPoint(cPoint(contentWidthNarrow - contentWidthFull, 0));
+#ifdef USE_YAEPG
+ if (config.scalePicture) {
+ tArea availableArea;
+ availableArea.x1 = osdLeft + contentWidthNarrow;
+ availableArea.y1 = osdTop + headerHeight;
+ availableArea.x2 = contentWidthFull;
+ availableArea.y2 = availableArea.y1 + contentHeight;
+ ScalePreserveAspect(osd->vidWin, aspect, availableArea);
+ osd->vidWin.bpp = 12;
+ }
+#endif
+ } else {
+ pixmapContent->SetDrawPortPoint(cPoint(0, 0));
+#ifdef USE_YAEPG
+ if (config.scalePicture) {
+ tArea availableArea;
+ availableArea.x1 = 0;
+ availableArea.y1 = 0;
+ availableArea.x2 = osdWidth;
+ availableArea.y2 = osdHeight;
+ ScalePreserveAspect(osd->vidWin, aspect, availableArea);
+ osd->vidWin.bpp = 12;
+ }
+#endif
+ }
+ if (contentNarrow != contentNarrowLast) {
+ osd->DestroyPixmap(pixmapScrollbar);
+ int contentWidth = (contentNarrow)?contentWidthNarrow:contentWidthFull;
+ pixmapScrollbar = osd->CreatePixmap(2, cRect(contentWidth , headerHeight + spaceMenu, widthScrollbar, osdHeight - headerHeight - footerHeight - 2*spaceMenu));
+ }
+}
+
+void cNopacityDisplayMenuView::ScalePreserveAspect(tArea & videoWindowDest, const double & videoAspect, const tArea & availableArea) {
+ videoWindowDest.x1 = availableArea.x1;
+ videoWindowDest.x2 = availableArea.x2;
+ videoWindowDest.y1 = availableArea.y1;
+ videoWindowDest.y2 = availableArea.y2;
+ if (availableArea.Height() == 0) {
+ videoWindowDest.bpp = 0; // just for safety
+ return;
+ }
+ double availableAspect = double(availableArea.Width())/double(availableArea.Height());
+ if (videoAspect < availableAspect) {
+ int offset = floor(double(availableArea.Width() - availableArea.Height() * videoAspect)/2);
+ videoWindowDest.x1 += offset;
+ videoWindowDest.x2 -= offset;
+ } else {
+ int offset = floor(double(availableArea.Height() - availableArea.Width() / videoAspect)/2);
+ videoWindowDest.y1 += offset;
+ videoWindowDest.y2 -= offset;
+ }
+}
+
+void cNopacityDisplayMenuView::DrawHeaderLogo(void) {
+ cImageLoader imgLoader;
+ if (imgLoader.LoadIcon("vdrlogo", config.menuHeaderLogoWidth, config.menuHeaderLogoHeight)) {
+ pixmapHeaderLogo->DrawImage(cPoint(0,0), imgLoader.GetImage());
+ }
+}
+
+int cNopacityDisplayMenuView::ShowHeaderLogo(bool show) {
+ if (show) {
+ pixmapHeaderLogo->SetLayer(2);
+ } else {
+ pixmapHeaderLogo->SetLayer(-1);
+ }
+ return config.menuHeaderLogoWidth + spaceMenu;
+}
+
+int cNopacityDisplayMenuView::DrawHeaderIcon(eMenuCategory menuCat) {
+ cString icon;
+ bool drawIcon = true;
+ switch (menuCat) {
+ case mcSchedule:
+ icon = "Schedule";
+ break;
+ case mcChannel:
+ icon = "Channels";
+ break;
+ case mcTimer:
+ icon = "Timers";
+ break;
+ case mcRecording:
+ icon = "Recordings";
+ break;
+ case mcSetup:
+ icon = "Setup";
+ break;
+ case mcCommand:
+ icon = "Commands";
+ break;
+ default:
+ drawIcon = false;
+ }
+
+ int left = 0;
+ if (drawIcon) {
+ pixmapHeaderIcon = osd->CreatePixmap(2, cRect(0, 0, config.headerIconHeight, config.headerIconHeight));
+ pixmapHeaderIcon->Fill(clrTransparent);
+ cImageLoader imgLoader;
+ if (imgLoader.LoadIcon(*icon, config.headerIconHeight)) {
+ pixmapHeaderIcon->DrawImage(cPoint(0,0), imgLoader.GetImage());
+ left = config.headerIconHeight + spaceMenu;
+ }
+ }
+ return left;
+}
+
+int cNopacityDisplayMenuView::ShowHeaderIconChannelLogo(const char *Title) {
+ pixmapHeaderIcon = osd->CreatePixmap(2, cRect(0, 0, config.menuItemLogoWidth, config.menuItemLogoHeight));
+ pixmapHeaderIcon->Fill(clrTransparent);
+ std::string channel = Title;
+ std::string remove = trVDR("Schedule");
+ remove.append(" - ");
+ channel.erase(0, remove.length());
+ cImageLoader imgLoader;
+ int left = 0;
+ if (imgLoader.LoadLogo(channel.c_str(), config.menuItemLogoWidth, config.menuItemLogoHeight)) {
+ pixmapHeaderIcon->DrawImage(cPoint(0, 0), imgLoader.GetImage());
+ left = config.menuItemLogoWidth + spaceMenu;
+ }
+ return left;
+}
+
+void cNopacityDisplayMenuView::DestroyHeaderIcon(void) {
+ if (pixmapHeaderIcon) {
+ osd->DestroyPixmap(pixmapHeaderIcon);
+ pixmapHeaderIcon = NULL;
+ }
+}
+
+void cNopacityDisplayMenuView::DrawHeaderLabel(int left, cString label) {
+ pixmapHeaderLabel->Fill(clrTransparent);
+ pixmapHeaderLabel->DrawText(cPoint(left, ((headerHeight - 10) - fontHeader->Height()) / 2), *label, Theme.Color(clrMenuFontHeader), clrTransparent, fontHeader);
+
+}
+
+void cNopacityDisplayMenuView::DrawDate(bool initial) {
+ cString date = DayDateTime();
+ if (initial || strcmp(date, lastDate)) {
+ pixmapDate->Fill(clrTransparent);
+ int dateW = fontDate->Width(date);
+ pixmapDate->DrawText(cPoint(dateWidth - dateW - 2*spaceMenu, (headerHeight - fontDate->Height()) / 2), date, Theme.Color(clrMenuFontDate), clrTransparent, fontDate);
+ lastDate = date;
+ }
+}
+
+void cNopacityDisplayMenuView::DrawDiskUsage(void) {
+ int iconWidth = diskUsageWidth * 3/4;
+ int DiskUsage = cVideoDiskUsage::UsedPercent();
+ bool DiskAlert = DiskUsage > diskUsageAlert;
+ tColor bgColor = DiskAlert ? Theme.Color(clrDiskAlert) : Theme.Color(clrMenuBack);
+ pixmapDiskUsage->Fill(Theme.Color(clrMenuBorder));
+ pixmapDiskUsage->DrawRectangle(cRect(2,2,diskUsageWidth-4, diskUsageHeight-4), bgColor);
+ cImageLoader imgLoader;
+ if (imgLoader.LoadIcon("DiskUsage", iconWidth)) {
+ cImage icon = imgLoader.GetImage();
+ pixmapDiskUsageIcon->DrawImage(cPoint(0,0), icon);
+ }
+ pixmapDiskUsageLabel->Fill(clrTransparent);
+ cString usage = cString::sprintf("%s: %d%%", tr("Disc"), DiskUsage);
+ cString rest = cString::sprintf("%02d:%02dh %s", cVideoDiskUsage::FreeMinutes() / 60, cVideoDiskUsage::FreeMinutes() % 60, tr("free"));
+ pixmapDiskUsageLabel->DrawText(cPoint((diskUsageWidth - fontDiskUsage->Width(*usage))/2, diskUsageHeight - 2*fontDiskUsage->Height() - spaceMenu), *usage, Theme.Color(clrMenuFontDiscUsage), clrTransparent, fontDiskUsage);
+ pixmapDiskUsageLabel->DrawText(cPoint((diskUsageWidth - fontDiskUsage->Width(*rest))/2, diskUsageHeight - fontDiskUsage->Height() - spaceMenu), *rest, Theme.Color(clrMenuFontDiscUsage), clrTransparent, fontDiskUsage);
+ pixmapDiskUsage->SetLayer(2);
+ pixmapDiskUsageIcon->SetLayer(3);
+ pixmapDiskUsageLabel->SetLayer(4);
+}
+
+void cNopacityDisplayMenuView::ShowDiskUsage(bool show) {
+ if (show) {
+ pixmapDiskUsage->SetLayer(2);
+ pixmapDiskUsageIcon->SetLayer(3);
+ pixmapDiskUsageLabel->SetLayer(4);
+ } else {
+ pixmapDiskUsage->SetLayer(-1);
+ pixmapDiskUsageIcon->SetLayer(-1);
+ pixmapDiskUsageLabel->SetLayer(-1);
+ }
+}
+
+void cNopacityDisplayMenuView::DrawButton(const char *text, int handleImage, tColor borderColor, int num) {
+ int top = 2*buttonsBorder;
+ int left = num * buttonWidth + (2*num + 1) * buttonsBorder;
+ pixmapFooter->DrawRectangle(cRect(left, top, buttonWidth, buttonHeight), borderColor);
+ pixmapFooter->DrawImage(cPoint(left+2, top+2), handleImage);
+ int textWidth = fontButtons->Width(text);
+ int textHeight = fontButtons->Height();
+ pixmapFooter->DrawText(cPoint(left + (buttonWidth-textWidth)/2, top + (buttonHeight-textHeight)/2), text, Theme.Color(clrMenuFontButton), clrTransparent, fontButtons);
+}
+
+void cNopacityDisplayMenuView::ClearButton(int num) {
+ int top = 2*buttonsBorder;
+ int left = num * buttonWidth + (2*num + 1) * buttonsBorder;
+ pixmapFooter->DrawRectangle(cRect(left, top, buttonWidth, buttonHeight), Theme.Color(clrMenuBack));
+}
+
+int cNopacityDisplayMenuView::GetTimersInitHeight(void) {
+ return headerHeight + diskUsageHeight + 2*spaceMenu;
+}
+
+int cNopacityDisplayMenuView::GetTimersMaxHeight(void) {
+ return headerHeight + contentHeight;
+}
+
+cNopacityTimer *cNopacityDisplayMenuView::DrawTimer(const cTimer *Timer, int y) {
+ const cChannel *Channel = Timer->Channel();
+ const cEvent *Event = Timer->Event();
+ cString channelName(""), title("");
+ if (Channel) {
+ channelName = Channel->Name();
+ }
+ if (Event) {
+ title = Event->Title();
+ }
+ cTextWrapper titleLines;
+ titleLines.Set(*title, fontTimers, timersWidth-10);
+
+ cString Date;
+ if (Timer->Recording()) {
+ Date = cString::sprintf("-%s", *TimeString(Timer->StopTime()));
+ } else {
+ time_t Now = time(NULL);
+ cString Today = WeekDayName(Now);
+ cString Time = TimeString(Timer->StartTime());
+ cString Day = WeekDayName(Timer->StartTime());
+ if (Timer->StartTime() > Now + 6 * SECSINDAY)
+ Date = DayDateTime(Timer->StartTime());
+ else if (strcmp(Day, Today) != 0)
+ Date = cString::sprintf("%s %s", *Day, *Time);
+ else
+ Date = Time;
+ if (Timer->Flags() & tfVps)
+ Date = cString::sprintf("VPS %s", *Date);
+ }
+
+ int numLines = titleLines.Lines();
+ int lineHeight = fontTimers->Height();
+ int timerHeight = (numLines + 2)*lineHeight + spaceMenu;
+
+ cNopacityTimer *t = new cNopacityTimer(osd);
+ t->pixmap = osd->CreatePixmap(2, cRect(osdWidth - timersWidth - 10, y, timersWidth, timerHeight));
+
+ cImageLoader imgLoader;
+ if(Timer->Recording()) {
+ t->pixmap->Fill(Theme.Color(clrDiskAlert));
+ imgLoader.DrawBackground(Theme.Color(clrDiskAlert), Theme.Color(clrMenuItemHigh), timersWidth-2, timerHeight-2);
+ t->pixmap->DrawImage(cPoint(1,1), imgLoader.GetImage());
+ } else {
+ t->pixmap->Fill(Theme.Color(clrMenuBorder));
+ imgLoader.DrawBackground(Theme.Color(clrMenuItemHighBlend), Theme.Color(clrMenuItemHigh), timersWidth-2, timerHeight-2);
+ t->pixmap->DrawImage(cPoint(1,1), imgLoader.GetImage());
+ }
+ t->pixmap->DrawText(cPoint(5, 0), *Date, Theme.Color(clrMenuFontTimersHeader), clrTransparent, fontTimersHead);
+ t->pixmap->DrawText(cPoint(5, lineHeight+2), *channelName, Theme.Color(clrMenuFontTimersHeader), clrTransparent, fontTimers);
+ int yStart = 2*lineHeight + 3;
+ for (int line=0; line<numLines; line++)
+ t->pixmap->DrawText(cPoint(5, yStart+line*(lineHeight-2)), titleLines.GetLine(line), Theme.Color(clrMenuFontTimers), clrTransparent, fontTimers);
+
+ return t;
+}
+
+void cNopacityDisplayMenuView::DrawScrollbar(double Height, double Offset) {
+ int totalHeight = pixmapScrollbar->ViewPort().Height() - 6;
+ int height = Height * totalHeight;
+ int offset = Offset * totalHeight;
+ pixmapScrollbar->Fill(Theme.Color(clrMenuScrollBar));
+ pixmapScrollbar->DrawRectangle(cRect(2,2,widthScrollbar-4,totalHeight+2), Theme.Color(clrMenuScrollBarBack));
+ pixmapScrollbar->DrawRectangle(cRect(3,3 + offset,widthScrollbar-6,height), Theme.Color(clrMenuScrollBar));
+}
+
+void cNopacityDisplayMenuView::ClearScrollbar(void) {
+ pixmapScrollbar->Fill(clrTransparent);
+}
+
+
+void cNopacityDisplayMenuView::DrawMessage(eMessageType Type, const char *Text) {
+ tColor col = Theme.Color(clrMessageStatus);
+ switch (Type) {
+ case mtStatus:
+ col = Theme.Color(clrMessageStatus);
+ break;
+ case mtInfo:
+ col = Theme.Color(clrMessageInfo);
+ break;
+ case mtWarning:
+ col = Theme.Color(clrMessageWarning);
+ break;
+ case mtError:
+ col = Theme.Color(clrMessageError);
+ break;
+ }
+ if (pixmapStatus) {
+ ClearMessage();
+ }
+ pixmapStatus = osd->CreatePixmap(5, cRect(0.1*osdWidth, 0.8*osdHeight, messageWidth, messageHeight));
+ pixmapStatus->Fill(col);
+ cImageLoader imgLoader;
+ imgLoader.DrawBackground2(Theme.Color(clrMenuBack), col, messageWidth-2, messageHeight-2);
+ pixmapStatus->DrawImage(cPoint(1, 1), imgLoader.GetImage());
+ int textWidth = fontMessage->Width(Text);
+ pixmapStatus->DrawText(cPoint((messageWidth - textWidth) / 2, (messageHeight - fontMessage->Height()) / 2), Text, Theme.Color(clrMenuFontMessages), clrTransparent, fontMessage);
+}
+
+void cNopacityDisplayMenuView::ClearMessage(void) {
+ if (pixmapStatus) {
+ osd->DestroyPixmap(pixmapStatus);
+ pixmapStatus = NULL;
+ }
+}
+
+void cNopacityDisplayMenuView::SetDetailViewSize(eDetailViewType detailViewType, cNopacityMenuDetailView *detailView) {
+ int width = 0;
+ int height = 0;
+ int top = 0;
+ int contentBorder = 20;
+ int detailHeaderHeight = 0;
+
+ switch (detailViewType) {
+ case dvEvent:
+ detailHeaderHeight = max(config.detailViewLogoHeight, config.epgImageHeight)+4;
+ break;
+ case dvRecording:
+ detailHeaderHeight = contentHeight/5;
+ break;
+ case dvText:
+ detailHeaderHeight = 0;
+ break;
+ default:
+ break;
+ }
+ width = contentWidthFull - 2*spaceMenu;
+ height = contentHeight;
+ top = headerHeight;
+ detailView->SetGeometry(width, height, top, contentBorder, detailHeaderHeight);
+} \ No newline at end of file
diff --git a/displaymenuview.h b/displaymenuview.h
new file mode 100644
index 0000000..28ec7ec
--- /dev/null
+++ b/displaymenuview.h
@@ -0,0 +1,107 @@
+#ifndef __NOPACITY_DISPLAYMENUVIEW_H
+#define __NOPACITY_DISPLAYMENUVIEW_H
+
+enum eDetailViewType {dvEvent = 0, dvRecording, dvText};
+
+class cNopacityTimer : public cListObject {
+ private:
+ cOsd *osd;
+ public:
+ cNopacityTimer(cOsd *osd);
+ virtual ~cNopacityTimer(void);
+ void SetAlpha(int alpha) {pixmap->SetAlpha(alpha);}
+ void SetLayer(int layer) {pixmap->SetLayer(layer);}
+ cPixmap *pixmap;
+};
+
+class cNopacityDisplayMenuView {
+ private:
+ cOsd *osd;
+ cString lastDate;
+ int diskUsageAlert;
+ cPixmap *pixmapHeader;
+ cPixmap *pixmapHeaderLogo;
+ cPixmap *pixmapHeaderIcon;
+ cPixmap *pixmapHeaderLabel;
+ cPixmap *pixmapDate;
+ cPixmap *pixmapFooter;
+ cPixmap *pixmapContent;
+ cPixmap *pixmapScrollbar;
+ cPixmap *pixmapDiskUsage;
+ cPixmap *pixmapDiskUsageIcon;
+ cPixmap *pixmapDiskUsageLabel;
+ cPixmap *pixmapStatus;
+ cFont *fontHeader;
+ cFont *fontDate;
+ cFont *fontMenuitemLarge;
+ cFont *fontMenuitemSchedule;
+ cFont *fontMenuitemDefault;
+ cFont *fontDiskUsage;
+ cFont *fontTimers;
+ cFont *fontTimersHead;
+ cFont *fontButtons;
+ cFont *fontMessage;
+ int osdWidth, osdHeight;
+ int osdLeft, osdTop;
+ int screenWidth, screenHeight;
+ double aspect;
+ int widthScrollbar;
+ int dateWidth;
+ int headerHeight, footerHeight, contentHeight;
+ int contentWidthNarrow, contentWidthFull;
+ int menuItemWidthDefault, menuItemHeightDefault;
+ int menuItemWidthMain, menuItemHeightMain;
+ int menuItemHeightSchedule;
+ int diskUsageWidth, diskUsageHeight;
+ int timersWidth;
+ int buttonsBorder, buttonWidth, buttonHeight;
+ int messageWidth, messageHeight;
+ int avrgFontWidth;
+ public:
+ cNopacityDisplayMenuView();
+ virtual ~cNopacityDisplayMenuView(void);
+ cOsd *createOsd(void);
+ void SetGeometry(void);
+ void CreatePixmaps(void);
+ void SetPixmapAlpha(int Alpha);
+ void CreateFonts(void);
+ cFont *GetMenuItemFont(eMenuCategory menuCat);
+ void GetMenuItemSize(eMenuCategory menuCat, cPoint *itemSize);
+ int GetMaxItems(eMenuCategory menuCat);
+ int GetMenuTop(int numItems, int itemHeight);
+ void SetAvrgFontWidth(void);
+ int mytabs[cSkinDisplayMenu::MaxTabs];
+ void SetTabs(int Tab1, int Tab2 = 0, int Tab3 = 0, int Tab4 = 0, int Tab5 = 0);
+ int GetEditableWidth(void);
+ int GetWidthDefaultMenu(void) {return menuItemWidthDefault;};
+ int GetTextAreaWidth(void);
+ const cFont *GetTextAreaFont(bool FixedFont);
+ void CreateBackgroundImages(int *handleBackgrounds, int *handleButtons);
+ void AdjustContentBackground(bool contentNarrow, bool contentNarrowLast);
+ void DrawBorderDecoration(void);
+ int ShowHeaderLogo(bool show);
+ void DrawHeaderLogo(void);
+ int DrawHeaderIcon(eMenuCategory menuCat);
+ int ShowHeaderIconChannelLogo(const char *Title);
+ void DestroyHeaderIcon(void);
+ void DrawHeaderLabel(int left, cString label);
+ void DrawDate(bool initial);
+ void DrawDiskUsage(void);
+ void ShowDiskUsage(bool show);
+ void DrawButton(const char *text, int handleImage, tColor borderColor, int num);
+ void ClearButton(int num);
+ int GetTimersInitHeight(void);
+ int GetTimersMaxHeight(void);
+ cNopacityTimer *DrawTimer(const cTimer *Timer, int y);
+ void DrawScrollbar(double Height, double Offset);
+ void ClearScrollbar(void);
+ void DrawMessage(eMessageType Type, const char *Text);
+ void ClearMessage(void);
+ void SetDetailViewSize(eDetailViewType detailViewType, cNopacityMenuDetailView *detailView);
+ void ScalePreserveAspect(tArea & videoWindowDest, const double & videoAspect, const tArea & availableArea);
+ int spaceMenu;
+};
+
+
+
+#endif //__NOPACITY_DISPLAYMENUVIEW_H \ No newline at end of file
diff --git a/displaymessage.c b/displaymessage.c
new file mode 100644
index 0000000..ad420af
--- /dev/null
+++ b/displaymessage.c
@@ -0,0 +1,70 @@
+#include "displaymessage.h"
+
+cNopacityDisplayMessage::cNopacityDisplayMessage(void) {
+ config.setDynamicValues();
+ height = cOsd::OsdHeight() * config.messageHeight / 100;
+ int top = cOsd::OsdTop() + cOsd::OsdHeight() - height - config.messageBorderBottom;
+ width = cOsd::OsdWidth() * config.messageWidth / 100;
+ int left = (cOsd::OsdLeft() + cOsd::OsdWidth() - width) / 2;
+ osd = CreateOsd(left, top, width, height);
+ pixmap = osd->CreatePixmap(1, cRect(0, 0, width, height));
+ if (config.messageFadeTime)
+ pixmap->SetAlpha(0);
+ font = cFont::CreateFont(config.fontName, height / 4 + config.fontMessage);
+ FrameTime = config.messageFrameTime;
+ FadeTime = config.messageFadeTime;
+}
+
+cNopacityDisplayMessage::~cNopacityDisplayMessage() {
+ osd->DestroyPixmap(pixmap);
+ delete font;
+ delete osd;
+}
+
+void cNopacityDisplayMessage::SetMessage(eMessageType Type, const char *Text) {
+ tColor col = Theme.Color(clrMessageStatus);
+ switch (Type) {
+ case mtStatus:
+ col = Theme.Color(clrMessageStatus);
+ break;
+ case mtInfo:
+ col = Theme.Color(clrMessageInfo);
+ break;
+ case mtWarning:
+ col = Theme.Color(clrMessageWarning);
+ break;
+ case mtError:
+ col = Theme.Color(clrMessageError);
+ break;
+ }
+ pixmap->Fill(col);
+ cImageLoader imgLoader;
+ imgLoader.DrawBackground2(Theme.Color(clrMessageBlend), col, width-2, height-2);
+ pixmap->DrawImage(cPoint(1, 1), imgLoader.GetImage());
+ int textWidth = font->Width(Text);
+ pixmap->DrawText(cPoint((width - textWidth) / 2, (height - font->Height()) / 2), Text, Theme.Color(clrMessageFont), clrTransparent, font);
+ if (config.messageFadeTime)
+ Start();
+}
+
+void cNopacityDisplayMessage::Flush(void) {
+ osd->Flush();
+}
+
+void cNopacityDisplayMessage::Action(void) {
+ uint64_t Start = cTimeMs::Now();
+ while (true) {
+ uint64_t Now = cTimeMs::Now();
+ cPixmap::Lock();
+ double t = min(double(Now - Start) / FadeTime, 1.0);
+ int Alpha = t * ALPHA_OPAQUE;
+ pixmap->SetAlpha(Alpha);
+ osd->Flush();
+ cPixmap::Unlock();
+ int Delta = cTimeMs::Now() - Now;
+ if (Delta < FrameTime)
+ cCondWait::SleepMs(FrameTime - Delta);
+ if ((int)(Now - Start) > FadeTime)
+ break;
+ }
+} \ No newline at end of file
diff --git a/displaymessage.h b/displaymessage.h
new file mode 100644
index 0000000..bc7b6fb
--- /dev/null
+++ b/displaymessage.h
@@ -0,0 +1,20 @@
+#ifndef __NOPACITY_DISPLAYMESSAGE_H
+#define __NOPACITY_DISPLAYMESSAGE_H
+class cNopacityDisplayMessage : public cSkinDisplayMessage , cThread {
+private:
+ cOsd *osd;
+ int width;
+ int height;
+ cPixmap *pixmap;
+ cFont *font;
+ int FrameTime;
+ int FadeTime;
+ virtual void Action(void);
+public:
+ cNopacityDisplayMessage(void);
+ virtual ~cNopacityDisplayMessage();
+ virtual void SetMessage(eMessageType Type, const char *Text);
+ virtual void Flush(void);
+ };
+
+#endif //__NOPACITY_DISPLAYMESSAGE_H \ No newline at end of file
diff --git a/displayreplay.c b/displayreplay.c
new file mode 100644
index 0000000..70beea4
--- /dev/null
+++ b/displayreplay.c
@@ -0,0 +1,323 @@
+#include "displayreplay.h"
+
+cNopacityDisplayReplay::cNopacityDisplayReplay(bool ModeOnly) {
+ config.setDynamicValues();
+ initial = true;
+ modeOnly = ModeOnly;
+ lastDate = "";
+ FrameTime = config.replayFrameTime;
+ FadeTime = config.replayFadeTime;
+
+ SetGeometry();
+ CreatePixmaps();
+ DrawBackground();
+ CreateFonts();
+}
+
+cNopacityDisplayReplay::~cNopacityDisplayReplay() {
+ if (!modeOnly) {
+ osd->DestroyPixmap(pixmapHeader);
+ osd->DestroyPixmap(pixmapBackground);
+ osd->DestroyPixmap(pixmapInfo);
+ osd->DestroyPixmap(pixmapDate);
+ osd->DestroyPixmap(pixmapInfo2);
+ osd->DestroyPixmap(pixmapProgressBar);
+ osd->DestroyPixmap(pixmapCurrent);
+ osd->DestroyPixmap(pixmapTotal);
+ osd->DestroyPixmap(pixmapJump);
+ osd->DestroyPixmap(pixmapFooter);
+ }
+ osd->DestroyPixmap(pixmapControls);
+ osd->DestroyPixmap(pixmapRew);
+ osd->DestroyPixmap(pixmapRewBackground);
+ osd->DestroyPixmap(pixmapRewSpeed);
+ osd->DestroyPixmap(pixmapPauseBackground);
+ osd->DestroyPixmap(pixmapPause);
+ osd->DestroyPixmap(pixmapPlayBackground);
+ osd->DestroyPixmap(pixmapPlay);
+ osd->DestroyPixmap(pixmapFwdBackground);
+ osd->DestroyPixmap(pixmapFwd);
+ osd->DestroyPixmap(pixmapFwdSpeed);
+ delete fontReplayHeader;
+ delete fontReplay;
+ delete osd;
+
+}
+
+void cNopacityDisplayReplay::SetGeometry(void) {
+ height = cOsd::OsdHeight() * config.replayHeight / 100;
+ width = cOsd::OsdWidth() - 2 * config.replayBorderVertical;
+ int top = cOsd::OsdTop() + cOsd::OsdHeight() - height - config.replayBorderBottom;
+ osd = CreateOsd(cOsd::OsdLeft() + config.replayBorderVertical, top, width, height);
+ headerHeight = height * 0.2;
+ if (headerHeight%2 != 0)
+ headerHeight++;
+ footerHeight = headerHeight;
+ info2Height = 0.2 * height;
+ progressBarHeight = 0.1 * height;
+ if (progressBarHeight%2 != 0)
+ progressBarHeight++;
+ currentHeight = progressBarHeight + config.fontReplay;
+ controlsHeight = height - headerHeight - info2Height - footerHeight - progressBarHeight;
+
+ infoWidth = 0.75 * width;
+ dateWidth = width - infoWidth;
+
+ jumpX = (width - 4 * controlsHeight)/2 + 5*controlsHeight;
+ jumpY = headerHeight + info2Height + progressBarHeight;
+ jumpWidth = width - jumpX;
+ jumpHeight = controlsHeight;
+}
+
+void cNopacityDisplayReplay::CreatePixmaps(void) {
+ if (!modeOnly) {
+ pixmapHeader = osd->CreatePixmap(1, cRect(0, 0, width, headerHeight));
+ pixmapBackground = osd->CreatePixmap(1, cRect(0, headerHeight, width, info2Height + progressBarHeight + controlsHeight));
+ pixmapFooter = osd->CreatePixmap(1, cRect(0, headerHeight + info2Height + progressBarHeight + controlsHeight, width, footerHeight));
+ pixmapInfo = osd->CreatePixmap(2, cRect(0, 0, infoWidth, headerHeight));
+ pixmapDate = osd->CreatePixmap(2, cRect(infoWidth, 0, dateWidth, headerHeight));
+ pixmapInfo2 = osd->CreatePixmap(2, cRect(0, headerHeight, width, info2Height));
+ pixmapProgressBar = osd->CreatePixmap(2, cRect(0, headerHeight + info2Height, width, progressBarHeight));
+ pixmapCurrent = osd->CreatePixmap(3, cRect(0, headerHeight + info2Height + progressBarHeight, width/5, currentHeight));
+ pixmapTotal = osd->CreatePixmap(3, cRect(4*width/5, headerHeight + info2Height + progressBarHeight, width/5, currentHeight));
+ pixmapJump = osd->CreatePixmap(4, cRect(jumpX, jumpY, jumpWidth, jumpHeight));
+ }
+
+ int controlY = headerHeight + info2Height + progressBarHeight;
+ iconBorder = 5;
+ iconSize = min(controlsHeight - 2*iconBorder, 128);
+ int backgroundWidth = 2 * iconBorder + iconSize;
+
+ if (!modeOnly) {
+ pixmapControls = osd->CreatePixmap(2, cRect(0, controlY, width, controlsHeight));
+ } else {
+ pixmapControls = osd->CreatePixmap(2, cRect( (width - (5 * backgroundWidth))/2, controlY - 10, 5 * backgroundWidth, controlsHeight + 20));
+ }
+ pixmapRewBackground = osd->CreatePixmap(3, cRect((width - 4 * backgroundWidth)/2, controlY, iconSize + 2*iconBorder, iconSize + 2*iconBorder));
+ pixmapRew = osd->CreatePixmap(4, cRect((width - 4 * backgroundWidth)/2 + iconBorder, controlY + iconBorder, iconSize, iconSize));
+ pixmapRewSpeed = osd->CreatePixmap(5, cRect((width - 4 * backgroundWidth)/2 + iconBorder, controlY + iconBorder, iconSize, iconSize));
+ pixmapPauseBackground = osd->CreatePixmap(3, cRect((width - 4 * backgroundWidth)/2 + iconSize + 2*iconBorder, controlY, iconSize + 2*iconBorder, iconSize + 2*iconBorder));
+ pixmapPause = osd->CreatePixmap(4, cRect((width - 4 * backgroundWidth)/2 + (iconSize + 2*iconBorder) + iconBorder, controlY + iconBorder, iconSize, iconSize));
+ pixmapPlayBackground = osd->CreatePixmap(3, cRect((width - 4 * backgroundWidth)/2 + 2*(iconSize + 2*iconBorder), controlY, iconSize + 2*iconBorder, iconSize + 2*iconBorder));
+ pixmapPlay = osd->CreatePixmap(4, cRect((width - 4 * backgroundWidth)/2 + 2*(iconSize + 2*iconBorder) + iconBorder, controlY + iconBorder, iconSize, iconSize));
+ pixmapFwdBackground = osd->CreatePixmap(3, cRect((width - 4 * backgroundWidth)/2 + 3*(iconSize + 2*iconBorder), controlY, iconSize + 2*iconBorder, iconSize + 2*iconBorder));
+ pixmapFwd = osd->CreatePixmap(4, cRect((width - 4 * backgroundWidth)/2 + 3*(iconSize + 2*iconBorder) + iconBorder, controlY + iconBorder, iconSize, iconSize));
+ pixmapFwdSpeed = osd->CreatePixmap(5, cRect((width - 4 * backgroundWidth)/2 + 3*(iconSize + 2*iconBorder) + iconBorder, controlY + iconBorder, iconSize, iconSize));
+
+ LoadControlIcons();
+
+ if (config.replayFadeTime) {
+ if (!modeOnly) {
+ pixmapHeader->SetAlpha(0);
+ pixmapBackground->SetAlpha(0);
+ pixmapInfo->SetAlpha(0);
+ pixmapDate->SetAlpha(0);
+ pixmapInfo2->SetAlpha(0);
+ pixmapProgressBar->SetAlpha(0);
+ pixmapCurrent->SetAlpha(0);
+ pixmapTotal->SetAlpha(0);
+ pixmapJump->SetAlpha(0);
+ pixmapFooter->SetAlpha(0);
+ }
+ pixmapControls->SetAlpha(0);
+ pixmapRewBackground->SetAlpha(0);
+ pixmapRew->SetAlpha(0);
+ pixmapRewSpeed->SetAlpha(0);
+ pixmapPauseBackground->SetAlpha(0);
+ pixmapPause->SetAlpha(0);
+ pixmapPlayBackground->SetAlpha(0);
+ pixmapPlay->SetAlpha(0);
+ pixmapFwdBackground->SetAlpha(0);
+ pixmapFwd->SetAlpha(0);
+ pixmapFwdSpeed->SetAlpha(0);
+ }
+}
+
+void cNopacityDisplayReplay::CreateFonts(void) {
+ fontReplayHeader = cFont::CreateFont(config.fontName, headerHeight - 8 + config.fontReplayHeader);
+ fontReplay = cFont::CreateFont(config.fontName, currentHeight);
+}
+
+void cNopacityDisplayReplay::DrawBackground(void) {
+ if (!modeOnly) {
+ DrawBlendedBackground(pixmapHeader, Theme.Color(clrReplayBackground), Theme.Color(clrReplayBackBlend), true);
+ pixmapHeader->DrawEllipse(cRect(0,0, headerHeight/2, headerHeight/2), clrTransparent, -2);
+ pixmapHeader->DrawEllipse(cRect(width - headerHeight/2 ,0 ,headerHeight/2,headerHeight/2), clrTransparent, -1);
+ pixmapBackground->Fill(Theme.Color(clrReplayBackground));
+ pixmapControls->Fill(clrTransparent);
+ pixmapProgressBar->Fill(clrTransparent);
+ pixmapJump->Fill(clrTransparent);
+ DrawBlendedBackground(pixmapFooter, Theme.Color(clrReplayBackground), Theme.Color(clrReplayBackBlend), false);
+ pixmapFooter->DrawEllipse(cRect(0,footerHeight/2,footerHeight/2,footerHeight/2), clrTransparent, -3);
+ pixmapFooter->DrawEllipse(cRect(width - footerHeight/2, footerHeight/2 ,footerHeight/2,footerHeight/2), clrTransparent, -4);
+ } else {
+ pixmapControls->Fill(Theme.Color(clrMenuBorder));
+ pixmapControls->DrawRectangle(cRect(2, 2, pixmapControls->ViewPort().Width() - 4, pixmapControls->ViewPort().Height() - 4),Theme.Color(clrReplayBackground));
+ }
+}
+
+void cNopacityDisplayReplay::LoadControlIcons(void) {
+
+ pixmapRew->Fill(clrTransparent);
+ pixmapPause->Fill(clrTransparent);
+ pixmapPlay->Fill(clrTransparent);
+ pixmapFwd->Fill(clrTransparent);
+
+ cImageLoader imgLoader;
+ if (imgLoader.LoadIcon("rew", iconSize)) {
+ pixmapRew->DrawImage(cPoint(0,0), imgLoader.GetImage());
+ }
+ if (imgLoader.LoadIcon("pause", iconSize)) {
+ pixmapPause->DrawImage(cPoint(0,0), imgLoader.GetImage());
+ }
+ if (imgLoader.LoadIcon("play", iconSize)) {
+ pixmapPlay->DrawImage(cPoint(0,0), imgLoader.GetImage());
+ }
+ if (imgLoader.LoadIcon("fwd", iconSize)) {
+ pixmapFwd->DrawImage(cPoint(0,0), imgLoader.GetImage());
+ }
+}
+
+
+void cNopacityDisplayReplay::DrawDate(void) {
+ cString curDate = DayDateTime();
+ if (initial || strcmp(curDate, lastDate)) {
+ int strDateWidth = fontReplay->Width(curDate);
+ int strDateHeight = fontReplay->Height();
+ int x = dateWidth - strDateWidth - headerHeight/2;
+ int y = (headerHeight - strDateHeight) / 2;
+ pixmapDate->Fill(clrTransparent);
+ pixmapDate->DrawText(cPoint(x, y), curDate, Theme.Color(clrReplayHead), clrTransparent, fontReplay);
+ lastDate = curDate;
+ }
+}
+
+void cNopacityDisplayReplay::SetRecording(const cRecording *Recording) {
+ const cRecordingInfo *RecordingInfo = Recording->Info();
+ SetTitle(RecordingInfo->Title());
+ cString info2;
+ if (RecordingInfo->ShortText())
+ info2 = cString::sprintf("%s - %s %s", RecordingInfo->ShortText(), *ShortDateString(Recording->Start()), *TimeString(Recording->Start()));
+ else
+ info2 = cString::sprintf("%s %s", *ShortDateString(Recording->Start()), *TimeString(Recording->Start()));
+
+ pixmapInfo2->Fill(clrTransparent);
+ pixmapInfo2->DrawText(cPoint(headerHeight/2, max( (info2Height - fontReplay->Height())/2 - 10,0 )), *info2, Theme.Color(clrReplayDescription), clrTransparent, fontReplay);
+}
+
+void cNopacityDisplayReplay::SetTitle(const char *Title) {
+ pixmapInfo->Fill(clrTransparent);
+ pixmapInfo->DrawText(cPoint(headerHeight/2, 0), Title, Theme.Color(clrReplayHead), clrTransparent, fontReplayHeader);
+}
+
+void cNopacityDisplayReplay::SetMode(bool Play, bool Forward, int Speed) {
+ pixmapRewBackground->Fill(clrTransparent);
+ pixmapRewSpeed->Fill(clrTransparent);
+ pixmapPauseBackground->Fill(clrTransparent);
+ pixmapPlayBackground->Fill(clrTransparent);
+ pixmapFwdBackground->Fill(clrTransparent);
+ pixmapFwdSpeed->Fill(clrTransparent);
+
+ if (!Play) {
+ pixmapPauseBackground->Fill(Theme.Color(clrReplayHighlightIcon));
+ } else if (Play && (Speed < 0)) {
+ pixmapPlayBackground->Fill(Theme.Color(clrReplayHighlightIcon));
+ } else if (Play && Forward) {
+ pixmapFwdBackground->Fill(Theme.Color(clrReplayHighlightIcon));
+ if (Speed > 0) {
+ cString speed = cString::sprintf("x%d", Speed);
+ int sWidth = fontReplayHeader->Width(*speed);
+ pixmapFwdSpeed->DrawText(cPoint((iconSize - sWidth)/2, (iconSize - fontReplayHeader->Height())/2), *speed, Theme.Color(clrReplayHighlightIcon), clrTransparent, fontReplayHeader);
+ }
+ } else if (Play && !Forward) {
+ pixmapRewBackground->Fill(Theme.Color(clrReplayHighlightIcon));
+ if (Speed > 0) {
+ cString speed = cString::sprintf("x%d", Speed);
+ int sWidth = fontReplayHeader->Width(*speed);
+ pixmapRewSpeed->DrawText(cPoint((iconSize - sWidth)/2, (iconSize - fontReplayHeader->Height())/2), *speed, Theme.Color(clrReplayHighlightIcon), clrTransparent, fontReplayHeader);
+ }
+ }
+
+}
+
+void cNopacityDisplayReplay::SetProgress(int Current, int Total) {
+ int barWidth = width - 2*progressBarHeight;
+ cProgressBar pb(barWidth, progressBarHeight-2, Current, Total, marks, Theme.Color(clrReplayProgressSeen), Theme.Color(clrReplayProgressRest), Theme.Color(clrReplayProgressSelected), Theme.Color(clrReplayProgressMark), Theme.Color(clrReplayProgressCurrent));
+ pixmapProgressBar->DrawEllipse(cRect(progressBarHeight/2, 0, progressBarHeight, progressBarHeight), Theme.Color(clrProgressBarBack));
+ pixmapProgressBar->DrawEllipse(cRect(barWidth + progressBarHeight/2, 0, progressBarHeight, progressBarHeight), Theme.Color(clrProgressBarBack));
+ pixmapProgressBar->DrawRectangle(cRect( progressBarHeight, 0, barWidth, progressBarHeight), Theme.Color(clrProgressBarBack));
+ pixmapProgressBar->DrawEllipse(cRect(progressBarHeight/2+1, 1, progressBarHeight-1, progressBarHeight-2), Theme.Color(clrProgressBar));
+ pixmapProgressBar->DrawBitmap(cPoint(progressBarHeight, 1), pb);
+}
+
+void cNopacityDisplayReplay::SetCurrent(const char *Current) {
+ pixmapCurrent->Fill(clrTransparent);
+ pixmapCurrent->DrawText(cPoint(headerHeight/2, 0), Current, Theme.Color(clrReplayCurrentTotal), clrTransparent, fontReplay);
+}
+
+void cNopacityDisplayReplay::SetTotal(const char *Total) {
+ pixmapTotal->Fill(clrTransparent);
+ pixmapTotal->DrawText(cPoint(width/5 - (fontReplay->Width(Total) + headerHeight/2), 0), Total, Theme.Color(clrReplayCurrentTotal), clrTransparent, fontReplay);
+}
+
+void cNopacityDisplayReplay::SetJump(const char *Jump) {
+ pixmapJump->Fill(clrTransparent);
+ if (Jump) {
+ pixmapJump->DrawText(cPoint(0, (jumpHeight - fontReplayHeader->Height())/2), Jump, Theme.Color(clrReplayCurrentTotal), clrTransparent, fontReplayHeader);
+ }
+}
+
+void cNopacityDisplayReplay::SetMessage(eMessageType Type, const char *Text) {
+}
+
+void cNopacityDisplayReplay::Flush(void) {
+ if (!modeOnly) {
+ DrawDate();
+ }
+ if (initial) {
+ if (config.replayFadeTime)
+ Start();
+ }
+ initial = false;
+ osd->Flush();
+}
+
+void cNopacityDisplayReplay::Action(void) {
+ uint64_t Start = cTimeMs::Now();
+ while (true) {
+ uint64_t Now = cTimeMs::Now();
+ cPixmap::Lock();
+ double t = min(double(Now - Start) / FadeTime, 1.0);
+ int Alpha = t * ALPHA_OPAQUE;
+ if (!modeOnly) {
+ pixmapHeader->SetAlpha(Alpha);
+ pixmapBackground->SetAlpha(Alpha);
+ pixmapInfo->SetAlpha(Alpha);
+ pixmapDate->SetAlpha(Alpha);
+ pixmapInfo2->SetAlpha(Alpha);
+ pixmapProgressBar->SetAlpha(Alpha);
+ pixmapCurrent->SetAlpha(Alpha);
+ pixmapTotal->SetAlpha(Alpha);
+ pixmapJump->SetAlpha(Alpha);
+ pixmapFooter->SetAlpha(Alpha);
+ }
+ pixmapControls->SetAlpha(Alpha);
+ pixmapRewBackground->SetAlpha(Alpha);
+ pixmapRew->SetAlpha(Alpha);
+ pixmapRewSpeed->SetAlpha(Alpha);
+ pixmapPauseBackground->SetAlpha(Alpha);
+ pixmapPause->SetAlpha(Alpha);
+ pixmapPlayBackground->SetAlpha(Alpha);
+ pixmapPlay->SetAlpha(Alpha);
+ pixmapFwdBackground->SetAlpha(Alpha);
+ pixmapFwd->SetAlpha(Alpha);
+ pixmapFwdSpeed->SetAlpha(Alpha);
+ osd->Flush();
+ cPixmap::Unlock();
+ int Delta = cTimeMs::Now() - Now;
+ if (Delta < FrameTime)
+ cCondWait::SleepMs(FrameTime - Delta);
+ if ((int)(Now - Start) > FadeTime)
+ break;
+ }
+}
diff --git a/displayreplay.h b/displayreplay.h
new file mode 100644
index 0000000..015a9f0
--- /dev/null
+++ b/displayreplay.h
@@ -0,0 +1,69 @@
+#ifndef __NOPACITY_DISPLAYREPLAY_H
+#define __NOPACITY_DISPLAYREPLAY_H
+
+class cNopacityDisplayReplay : public cSkinDisplayReplay , cThread{
+private:
+ cOsd *osd;
+ bool initial;
+ bool modeOnly;
+ cString lastDate;
+ int width;
+ int height;
+ int headerHeight;
+ int info2Height;
+ int progressBarHeight;
+ int currentHeight;
+ int controlsHeight;
+ int footerHeight;
+ int infoWidth;
+ int dateWidth;
+ int iconSize, iconBorder;
+ int jumpX, jumpY;
+ int jumpWidth, jumpHeight;
+ int FrameTime;
+ int FadeTime;
+ cPixmap *pixmapHeader;
+ cPixmap *pixmapBackground;
+ cPixmap *pixmapInfo;
+ cPixmap *pixmapDate;
+ cPixmap *pixmapInfo2;
+ cPixmap *pixmapProgressBar;
+ cPixmap *pixmapCurrent;
+ cPixmap *pixmapTotal;
+ cPixmap *pixmapControls;
+ cPixmap *pixmapRew;
+ cPixmap *pixmapRewBackground;
+ cPixmap *pixmapRewSpeed;
+ cPixmap *pixmapPause;
+ cPixmap *pixmapPauseBackground;
+ cPixmap *pixmapPlay;
+ cPixmap *pixmapPlayBackground;
+ cPixmap *pixmapFwd;
+ cPixmap *pixmapFwdBackground;
+ cPixmap *pixmapFwdSpeed;
+ cPixmap *pixmapJump;
+ cPixmap *pixmapFooter;
+ cFont *fontReplayHeader;
+ cFont *fontReplay;
+ virtual void Action(void);
+ void SetGeometry(void);
+ void CreatePixmaps(void);
+ void CreateFonts(void);
+ void DrawBackground(void);
+ void DrawDate(void);
+ void LoadControlIcons(void);
+public:
+ cNopacityDisplayReplay(bool ModeOnly);
+ virtual ~cNopacityDisplayReplay();
+ virtual void SetRecording(const cRecording *Recording);
+ 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 SetMessage(eMessageType Type, const char *Text);
+ virtual void Flush(void);
+ };
+
+#endif //__NOPACITY_DISPLAYREPLAY_H \ No newline at end of file
diff --git a/displaytracks.c b/displaytracks.c
new file mode 100644
index 0000000..ab1add7
--- /dev/null
+++ b/displaytracks.c
@@ -0,0 +1,184 @@
+
+#include "displaytracks.h"
+
+cNopacityDisplayTracks::cNopacityDisplayTracks(const char *Title, int NumTracks, const char * const *Tracks) {
+ config.setDynamicValues();
+ initial = true;
+ currentIndex = -1;
+ numTracks = NumTracks;
+ FrameTime = config.tracksFrameTime;
+ FadeTime = config.tracksFadeTime;
+ SetGeometry();
+ CreatePixmaps();
+ CreateFonts();
+ CreateBackgroundImages();
+ DrawHeader(Title);
+ for (int i = 0; i < NumTracks; i++)
+ SetItem(Tracks[i], i, false);
+}
+
+cNopacityDisplayTracks::~cNopacityDisplayTracks() {
+ osd->DestroyPixmap(pixmapContainer);
+ osd->DestroyPixmap(pixmapHeader);
+ menuItems.Clear();
+ for (int i=0; i<2; i++)
+ cOsdProvider::DropImage(handleBackgrounds[i]);
+ delete font;
+ delete fontHeader;
+ delete osd;
+}
+
+cBitmap cNopacityDisplayTracks::bmStereo(audio_xpm);
+cBitmap cNopacityDisplayTracks::bmDolbyDigital(dolbydigital_xpm);
+
+void cNopacityDisplayTracks::SetGeometry(void) {
+ width = cOsd::OsdWidth() * config.tracksWidth / 100;
+ height = cOsd::OsdHeight() * config.tracksHeight / 100;
+ if (!height%(numTracks + 1)) {
+ height += numTracks + 1 - height%(numTracks + 1);
+ }
+ menuItemWidth = width - 4;
+ menuItemHeight = (height - 2*(numTracks + 1)) / (numTracks + 1) - 1;
+
+ int top, left;
+ switch(config.tracksPosition) {
+ case 0: //middle bottom
+ top = cOsd::OsdHeight() - cOsd::OsdTop() - height - config.tracksBorderHorizontal;
+ left = (cOsd::OsdWidth() - width) / 2;
+ break;
+ case 1: //left bottom
+ top = cOsd::OsdHeight() - cOsd::OsdTop() - height - config.tracksBorderHorizontal;
+ left = cOsd::OsdLeft();
+ break;
+ case 2: //left middle
+ top = (cOsd::OsdHeight() - height) / 2;
+ left = cOsd::OsdLeft() + config.tracksBorderVertical;
+ break;
+ case 3: //left top
+ top = cOsd::OsdTop() + config.tracksBorderHorizontal;
+ left = cOsd::OsdLeft() + config.tracksBorderVertical;
+ break;
+ case 4: //top middle
+ top = cOsd::OsdTop() + config.tracksBorderHorizontal;
+ left = (cOsd::OsdWidth() - width) / 2;
+ break;
+ case 5: //top right
+ top = cOsd::OsdTop() + config.tracksBorderHorizontal;
+ left = cOsd::OsdWidth() - cOsd::OsdLeft() - width - config.tracksBorderVertical;
+ break;
+ case 6: //right middle
+ top = (cOsd::OsdHeight() - height) / 2;
+ left = cOsd::OsdWidth() - cOsd::OsdLeft() - width - config.tracksBorderVertical;
+ break;
+ case 7: //right bottom
+ top = cOsd::OsdHeight() - cOsd::OsdTop() - height - config.tracksBorderHorizontal;
+ left = cOsd::OsdWidth() - cOsd::OsdLeft() - width - config.tracksBorderVertical;
+ break;
+ default: //middle bottom
+ top = cOsd::OsdHeight() - cOsd::OsdTop() - height - config.tracksBorderHorizontal;
+ left = (cOsd::OsdWidth() - width) / 2;
+ break;
+ }
+ osd = CreateOsd(left, top, width, height);
+}
+
+void cNopacityDisplayTracks::CreatePixmaps(void) {
+ pixmapContainer = osd->CreatePixmap(1, cRect(0, 0, width, height));
+ pixmapHeader = osd->CreatePixmap(2, cRect(2, 2, menuItemWidth, menuItemHeight));
+ if (config.tracksFadeTime) {
+ pixmapContainer->SetAlpha(0);
+ pixmapHeader->SetAlpha(0);
+ }
+}
+
+void cNopacityDisplayTracks::CreateFonts(void) {
+ font = cFont::CreateFont(config.fontName, menuItemHeight/3 + config.fontTracks);
+ fontHeader = cFont::CreateFont(config.fontName, menuItemHeight/2 + config.fontTracksHeader);
+}
+
+void cNopacityDisplayTracks::CreateBackgroundImages(void) {
+ cImageLoader imgLoader;
+ imgLoader.DrawBackground(Theme.Color(clrMenuItem), Theme.Color(clrMenuItemBlend), menuItemWidth-2, menuItemHeight-2);
+ handleBackgrounds[0] = cOsdProvider::StoreImage(imgLoader.GetImage());
+ imgLoader.DrawBackground(Theme.Color(clrMenuItemHigh), Theme.Color(clrMenuItemHighBlend), menuItemWidth-2, menuItemHeight-2);
+ handleBackgrounds[1] = cOsdProvider::StoreImage(imgLoader.GetImage());
+}
+
+void cNopacityDisplayTracks::DrawHeader(const char *Title) {
+ pixmapContainer->Fill(Theme.Color(clrMenuBorder));
+ pixmapContainer->DrawRectangle(cRect(1, 1, width-2, height-2), Theme.Color(clrMenuBack));
+
+ pixmapHeader->Fill(Theme.Color(clrMenuItem));
+ pixmapHeader->DrawImage(cPoint(1, 1), handleBackgrounds[0]);
+ pixmapIcon = osd->CreatePixmap(3, cRect(2, 2, menuItemHeight-2, menuItemHeight-2));
+ pixmapIcon->Fill(clrTransparent);
+ cImageLoader imgLoader;
+ if (imgLoader.LoadIcon("tracks", menuItemHeight-6)) {
+ pixmapIcon->DrawImage(cPoint(3, 3), imgLoader.GetImage());
+ }
+ pixmapHeader->DrawText(cPoint((width - fontHeader->Width(Title)) / 2, (menuItemHeight - fontHeader->Height()) / 2), Title, Theme.Color(clrTracksFontHead), clrTransparent, fontHeader);
+}
+
+void cNopacityDisplayTracks::SetItem(const char *Text, int Index, bool Current) {
+ cNopacityMenuItem *item;
+ item = new cNopacityTrackMenuItem(osd, Text, Current);
+ item->SetFont(font);
+ item->CreatePixmap(menuItemHeight+5, 2, Index, menuItemWidth, menuItemHeight);
+ item->SetBackgrounds(handleBackgrounds);
+ menuItems.Add(item);
+ item->Render();
+}
+
+void cNopacityDisplayTracks::SetTrack(int Index, const char * const *Tracks) {
+ cNopacityMenuItem *item;
+ if (currentIndex >= 0) {
+ item = menuItems.Get(currentIndex);
+ item->SetCurrent(false);
+ item->Render();
+ }
+ item = menuItems.Get(Index);
+ item->SetCurrent(true);
+ item->Render();
+ currentIndex = Index;
+}
+
+void cNopacityDisplayTracks::SetAudioChannel(int AudioChannel) {
+ cBitmap *bm = NULL;
+ switch (AudioChannel) {
+ case -1: bm = &bmDolbyDigital; break;
+ case 0: bm = &bmStereo; break;
+ default: ;
+ }
+ if (bm)
+ pixmapHeader->DrawBitmap(cPoint(width - bm->Width() - 10, (menuItemHeight - bm->Width()) / 2), *bm, Theme.Color(clrChannelSymbolOn), Theme.Color(clrMenuBack));
+}
+
+void cNopacityDisplayTracks::Flush(void) {
+ if (initial)
+ if (config.tracksFadeTime)
+ Start();
+ initial = false;
+ osd->Flush();
+}
+
+void cNopacityDisplayTracks::Action(void) {
+ uint64_t Start = cTimeMs::Now();
+ while (true) {
+ uint64_t Now = cTimeMs::Now();
+ cPixmap::Lock();
+ double t = min(double(Now - Start) / FadeTime, 1.0);
+ int Alpha = t * ALPHA_OPAQUE;
+ pixmapContainer->SetAlpha(Alpha);
+ pixmapHeader->SetAlpha(Alpha);
+ for (cNopacityMenuItem *item = menuItems.First(); item; item = menuItems.Next(item)) {
+ item->SetAlpha(Alpha);
+ }
+ osd->Flush();
+ cPixmap::Unlock();
+ int Delta = cTimeMs::Now() - Now;
+ if (Delta < FrameTime)
+ cCondWait::SleepMs(FrameTime - Delta);
+ if ((int)(Now - Start) > FadeTime)
+ break;
+ }
+} \ No newline at end of file
diff --git a/displaytracks.h b/displaytracks.h
new file mode 100644
index 0000000..83e388d
--- /dev/null
+++ b/displaytracks.h
@@ -0,0 +1,39 @@
+#ifndef __NOPACITY_DISPLAYTRACKS_H
+#define __NOPACITY_DISPLAYTRACKS_H
+
+class cNopacityDisplayTracks : public cSkinDisplayTracks, cThread {
+private:
+ cOsd *osd;
+ int FrameTime;
+ int FadeTime;
+ int width, height;
+ int menuItemWidth;
+ int menuItemHeight;
+ bool initial;
+ int currentIndex;
+ int numTracks;
+ cPixmap *pixmapContainer;
+ cPixmap *pixmapHeader;
+ cPixmap *pixmapIcon;
+ cList<cNopacityMenuItem> menuItems;
+ int handleBackgrounds[2];
+ cFont *font;
+ cFont *fontHeader;
+ virtual void Action(void);
+ void SetItem(const char *Text, int Index, bool Current);
+ static cBitmap bmStereo, bmDolbyDigital;
+ void SetGeometry(void);
+ void CreatePixmaps(void);
+ void CreateFonts(void);
+ void CreateBackgroundImages(void);
+ void DrawHeader(const char *Title);
+public:
+ cNopacityDisplayTracks(const char *Title, int NumTracks, const char * const *Tracks);
+ virtual ~cNopacityDisplayTracks();
+ virtual void SetTrack(int Index, const char * const *Tracks);
+ virtual void SetAudioChannel(int AudioChannel);
+ virtual void Flush(void);
+};
+
+
+#endif //__NOPACITY_DISPLAYTRACKS_H \ No newline at end of file
diff --git a/displayvolume.c b/displayvolume.c
new file mode 100644
index 0000000..c6e6a81
--- /dev/null
+++ b/displayvolume.c
@@ -0,0 +1,95 @@
+#include "symbols/mute.xpm"
+#include "displayvolume.h"
+
+cNopacityDisplayVolume::cNopacityDisplayVolume(void) {
+ config.setDynamicValues();
+ initial = true;
+ muted = false;
+ FrameTime = config.volumeFrameTime;
+ FadeTime = config.volumeFadeTime;
+
+ width = cOsd::OsdHeight() * config.volumeWidth / 100;
+ height = cOsd::OsdHeight() * config.volumeHeight / 100;
+
+ int top = (cOsd::OsdHeight() - height) / 2;
+ int left = (cOsd::OsdWidth() - width) / 2;
+
+ osd = CreateOsd(left, top, width, height);
+ pixmapContent = osd->CreatePixmap(1, cRect(0, 0, width, height));
+ pixmapContent->Fill(Theme.Color(clrMenuBorder));
+ cImageLoader imgLoader;
+ imgLoader.DrawBackground(Theme.Color(clrMenuItem), Theme.Color(clrMenuItemBlend), width-2, height-2);
+ pixmapContent->DrawImage(cPoint(1,1), imgLoader.GetImage());
+
+ labelHeight = height/3;
+ pixmapLabel = osd->CreatePixmap(2, cRect(0, 5, width, labelHeight));
+ progressBarWidth = 0.9 * width;
+ progressBarHeight = 0.3 * height;
+ if (progressBarHeight%2 != 0)
+ progressBarHeight++;
+ pixmapProgressBar = osd->CreatePixmap(2, cRect((width - progressBarWidth) / 2, (height - progressBarHeight)*2/3, progressBarWidth, progressBarHeight));
+
+ if (config.volumeFadeTime) {
+ pixmapContent->SetAlpha(0);
+ pixmapProgressBar->SetAlpha(0);
+ pixmapLabel->SetAlpha(0);
+ }
+ font = cFont::CreateFont(config.fontName, labelHeight - 6 + config.fontVolume);
+}
+
+cNopacityDisplayVolume::~cNopacityDisplayVolume() {
+ osd->DestroyPixmap(pixmapContent);
+ osd->DestroyPixmap(pixmapLabel);
+ osd->DestroyPixmap(pixmapProgressBar);
+ delete font;
+ delete osd;
+}
+
+void cNopacityDisplayVolume::SetVolume(int Current, int Total, bool Mute) {
+ pixmapLabel->Fill(clrTransparent);
+ cString label = cString::sprintf("%s: %d", tr("Volume"), Current);
+ pixmapLabel->DrawText(cPoint((width - font->Width(*label)) / 2, (labelHeight - font->Height()) / 2), *label, Theme.Color(clrVolumeFont), clrTransparent, font);
+ if (Mute) {
+ cBitmap bmMute(mute_xpm);
+ pixmapLabel->DrawBitmap(cPoint(width - 2*bmMute.Width(), (labelHeight - bmMute.Height()) / 2), bmMute, Theme.Color(clrDiskAlert), clrTransparent);
+ }
+ pixmapProgressBar->Fill(clrTransparent);
+ double percent = ((double)Current) / (double)Total;
+ int barWidth = progressBarWidth - progressBarHeight;
+ pixmapProgressBar->DrawEllipse(cRect(0, 0, progressBarHeight, progressBarHeight), Theme.Color(clrProgressBarBack));
+ pixmapProgressBar->DrawEllipse(cRect(progressBarWidth - progressBarHeight, 0, progressBarHeight, progressBarHeight), Theme.Color(clrProgressBarBack));
+ pixmapProgressBar->DrawRectangle(cRect(progressBarHeight/2, 0, progressBarWidth - progressBarHeight, progressBarHeight), Theme.Color(clrProgressBarBack));
+ if (Current > 0) {
+ pixmapProgressBar->DrawEllipse(cRect(1, 1, progressBarHeight-2, progressBarHeight-2), Theme.Color(clrProgressBar));
+ pixmapProgressBar->DrawEllipse(cRect(barWidth * percent - 1, 1, progressBarHeight-2, progressBarHeight-2), Theme.Color(clrProgressBar));
+ pixmapProgressBar->DrawRectangle(cRect(progressBarHeight / 2 - 1, 1, barWidth * percent - 2, progressBarHeight - 2), Theme.Color(clrProgressBar));
+ }
+}
+
+void cNopacityDisplayVolume::Flush(void) {
+ if (initial)
+ if (FadeTime)
+ Start();
+ initial = false;
+ osd->Flush();
+}
+
+void cNopacityDisplayVolume::Action(void) {
+ uint64_t Start = cTimeMs::Now();
+ while (true) {
+ uint64_t Now = cTimeMs::Now();
+ cPixmap::Lock();
+ double t = min(double(Now - Start) / FadeTime, 1.0);
+ int Alpha = t * ALPHA_OPAQUE;
+ pixmapContent->SetAlpha(Alpha);
+ pixmapProgressBar->SetAlpha(Alpha);
+ pixmapLabel->SetAlpha(Alpha);
+ osd->Flush();
+ cPixmap::Unlock();
+ int Delta = cTimeMs::Now() - Now;
+ if (Delta < FrameTime)
+ cCondWait::SleepMs(FrameTime - Delta);
+ if ((int)(Now - Start) > FadeTime)
+ break;
+ }
+}
diff --git a/displayvolume.h b/displayvolume.h
new file mode 100644
index 0000000..0ba696e
--- /dev/null
+++ b/displayvolume.h
@@ -0,0 +1,26 @@
+#ifndef __NOPACITY_DISPLAYVOLUME_H
+#define __NOPACITY_DISPLAYVOLUME_H
+
+class cNopacityDisplayVolume : public cSkinDisplayVolume, cThread {
+private:
+ int FrameTime;
+ int FadeTime;
+ bool initial;
+ bool muted;
+ int width, height;
+ int labelHeight;
+ int progressBarWidth, progressBarHeight;
+ cOsd *osd;
+ cPixmap *pixmapContent;
+ cPixmap *pixmapProgressBar;
+ cPixmap *pixmapLabel;
+ cFont *font;
+ virtual void Action(void);
+public:
+ cNopacityDisplayVolume(void);
+ virtual ~cNopacityDisplayVolume();
+ virtual void SetVolume(int Current, int Total, bool Mute);
+ virtual void Flush(void);
+ };
+
+#endif //__NOPACITY_DISPLAYVOLUME_H \ No newline at end of file
diff --git a/helpers.c b/helpers.c
new file mode 100644
index 0000000..1355329
--- /dev/null
+++ b/helpers.c
@@ -0,0 +1,38 @@
+static cOsd *CreateOsd(int Left, int Top, int Width, int Height) {
+ cOsd *osd = cOsdProvider::NewOsd(Left, Top);
+ if (osd) {
+ tArea Area = { 0, 0, Width, Height, 32 };
+ if (osd->SetAreas(&Area, 1) == oeOk) {
+ return osd;
+ }
+ }
+ return NULL;
+}
+
+static void DrawBlendedBackground(cPixmap *pixmap, tColor color, tColor colorBlending, bool fromTop) {
+ int width = pixmap->ViewPort().Width();
+ int height = pixmap->ViewPort().Height();
+ pixmap->Fill(color);
+ int numSteps = 16;
+ int alphaStep = 0x0F;
+ int alpha = 0x00;
+ int step, begin, end;
+ bool cont = true;
+ if (fromTop) {
+ step = 1;
+ begin = 0;
+ end = numSteps;
+ } else {
+ step = -1;
+ begin = height;
+ end = height - numSteps;
+ }
+ tColor clr;
+ for (int i = begin; cont; i = i + step) {
+ clr = AlphaBlend(color, colorBlending, alpha);
+ pixmap->DrawRectangle(cRect(0,i,width,1), clr);
+ alpha += alphaStep;
+ if (i == end)
+ cont = false;
+ }
+} \ No newline at end of file
diff --git a/iconTemplates/IconBorder.png b/iconTemplates/IconBorder.png
new file mode 100644
index 0000000..351c34d
--- /dev/null
+++ b/iconTemplates/IconBorder.png
Binary files differ
diff --git a/iconTemplates/IconTemplate.xcf b/iconTemplates/IconTemplate.xcf
new file mode 100644
index 0000000..79d20fe
--- /dev/null
+++ b/iconTemplates/IconTemplate.xcf
Binary files differ
diff --git a/icons/Administrative Aufgaben.png b/icons/Administrative Aufgaben.png
new file mode 100644
index 0000000..17f3758
--- /dev/null
+++ b/icons/Administrative Aufgaben.png
Binary files differ
diff --git a/icons/Channels.png b/icons/Channels.png
new file mode 100644
index 0000000..faf8126
--- /dev/null
+++ b/icons/Channels.png
Binary files differ
diff --git a/icons/Channelseparator.png b/icons/Channelseparator.png
new file mode 100644
index 0000000..906d35d
--- /dev/null
+++ b/icons/Channelseparator.png
Binary files differ
diff --git a/icons/Commands.png b/icons/Commands.png
new file mode 100644
index 0000000..bebbe49
--- /dev/null
+++ b/icons/Commands.png
Binary files differ
diff --git a/icons/DiskUsage.png b/icons/DiskUsage.png
new file mode 100644
index 0000000..f9f8a35
--- /dev/null
+++ b/icons/DiskUsage.png
Binary files differ
diff --git a/icons/Recordings.png b/icons/Recordings.png
new file mode 100644
index 0000000..9d23ff4
--- /dev/null
+++ b/icons/Recordings.png
Binary files differ
diff --git a/icons/Schedule.png b/icons/Schedule.png
new file mode 100644
index 0000000..396bb74
--- /dev/null
+++ b/icons/Schedule.png
Binary files differ
diff --git a/icons/Setup.png b/icons/Setup.png
new file mode 100644
index 0000000..0746ae7
--- /dev/null
+++ b/icons/Setup.png
Binary files differ
diff --git a/icons/Timers.png b/icons/Timers.png
new file mode 100644
index 0000000..1d43872
--- /dev/null
+++ b/icons/Timers.png
Binary files differ
diff --git a/icons/Tvguide.png b/icons/Tvguide.png
new file mode 100644
index 0000000..6c756b2
--- /dev/null
+++ b/icons/Tvguide.png
Binary files differ
diff --git a/icons/Videotext.png b/icons/Videotext.png
new file mode 100644
index 0000000..0419706
--- /dev/null
+++ b/icons/Videotext.png
Binary files differ
diff --git a/icons/daydelimiter.png b/icons/daydelimiter.png
new file mode 100644
index 0000000..85e2640
--- /dev/null
+++ b/icons/daydelimiter.png
Binary files differ
diff --git a/icons/fwd.png b/icons/fwd.png
new file mode 100644
index 0000000..13b4751
--- /dev/null
+++ b/icons/fwd.png
Binary files differ
diff --git a/icons/hd1080i.png b/icons/hd1080i.png
new file mode 100644
index 0000000..21351ce
--- /dev/null
+++ b/icons/hd1080i.png
Binary files differ
diff --git a/icons/hd720p.png b/icons/hd720p.png
new file mode 100644
index 0000000..1d91b7d
--- /dev/null
+++ b/icons/hd720p.png
Binary files differ
diff --git a/icons/pause.png b/icons/pause.png
new file mode 100644
index 0000000..e6577cf
--- /dev/null
+++ b/icons/pause.png
Binary files differ
diff --git a/icons/play.png b/icons/play.png
new file mode 100644
index 0000000..b0c8a18
--- /dev/null
+++ b/icons/play.png
Binary files differ
diff --git a/icons/rew.png b/icons/rew.png
new file mode 100644
index 0000000..7055823
--- /dev/null
+++ b/icons/rew.png
Binary files differ
diff --git a/icons/sd576i.png b/icons/sd576i.png
new file mode 100644
index 0000000..85c3657
--- /dev/null
+++ b/icons/sd576i.png
Binary files differ
diff --git a/icons/signal.png b/icons/signal.png
new file mode 100644
index 0000000..4f03c7a
--- /dev/null
+++ b/icons/signal.png
Binary files differ
diff --git a/icons/tracks.png b/icons/tracks.png
new file mode 100644
index 0000000..cf19b7e
--- /dev/null
+++ b/icons/tracks.png
Binary files differ
diff --git a/icons/vdrlogo.png b/icons/vdrlogo.png
new file mode 100644
index 0000000..33294b0
--- /dev/null
+++ b/icons/vdrlogo.png
Binary files differ
diff --git a/icons/vdrlogo_gen2vdr.png b/icons/vdrlogo_gen2vdr.png
new file mode 100644
index 0000000..3abbd2f
--- /dev/null
+++ b/icons/vdrlogo_gen2vdr.png
Binary files differ
diff --git a/imageloader.c b/imageloader.c
new file mode 100644
index 0000000..d4f1d21
--- /dev/null
+++ b/imageloader.c
@@ -0,0 +1,157 @@
+#include "imageloader.h"
+#include <math.h>
+#include <string>
+
+using namespace Magick;
+
+cImageLoader::cImageLoader() {
+}
+
+cImageLoader::~cImageLoader() {
+}
+
+bool cImageLoader::LoadLogo(const char *logo, int width = config.logoWidth, int height = config.logoHeight) {
+ if ((width == 0)||(height==0))
+ return false;
+ std::string logoLower = logo;
+ toLowerCase(logoLower);
+ bool success = false;
+ if (config.logoPathSet) {
+ success = LoadImage(logoLower.c_str(), config.logoPath, config.logoExtension);
+ }
+ if (!success) {
+ success = LoadImage(logoLower.c_str(), config.logoPathDefault, config.logoExtension);
+ }
+ if (!success)
+ return false;
+ if (height != 0 || width != 0) {
+ buffer.sample( Geometry(width, height));
+ }
+ return true;
+}
+
+bool cImageLoader::LoadIcon(const char *cIcon, int size) {
+ if (size==0)
+ return false;
+ bool success = false;
+ if (config.iconPathSet) {
+ success = LoadImage(cString(cIcon), config.iconPath, "png");
+ }
+ if (!success) {
+ success = LoadImage(cString(cIcon), config.iconPathDefault, "png");
+ }
+ if (!success)
+ return false;
+ buffer.sample(Geometry(size, size));
+ return true;
+}
+
+bool cImageLoader::LoadIcon(const char *cIcon, int width, int height) {
+ try {
+ if ((width == 0)||(height==0))
+ return false;
+ bool success = false;
+ if (config.iconPathSet) {
+ success = LoadImage(cString(cIcon), config.iconPath, "png");
+ }
+ if (!success) {
+ success = LoadImage(cString(cIcon), config.iconPathDefault, "png");
+ }
+ if (!success)
+ return false;
+ buffer.scale(Geometry(width, height));
+ return true;
+ }
+ catch (...) {
+ return false;
+ }
+}
+
+bool cImageLoader::LoadEPGImage(int eventID) {
+ int width = config.epgImageWidth;
+ int height = config.epgImageHeight;
+ if ((width == 0)||(height==0))
+ return false;
+ bool success = false;
+ if (config.epgImagePathSet) {
+ success = LoadImage(cString::sprintf("%d", eventID), config.epgImagePath, "jpg");
+ }
+ if (!success) {
+ success = LoadImage(cString::sprintf("%d", eventID), config.epgImagePathDefault, "jpg");
+ }
+ if (!success)
+ return false;
+ if (height != 0 || width != 0) {
+ buffer.sample( Geometry(width, height));
+ }
+ return true;
+}
+
+void cImageLoader::DrawBackground(tColor back, tColor blend, int width, int height) {
+ Color Back = Argb2Color(back);
+ Color Blend = Argb2Color(blend);
+ Image tmp(Geometry(width, height), Blend);
+ double arguments[9] = {0.0,(double)height,0.0,-1*(double)width,0.0,0.0,1.5*(double)width,0.0,1.0};
+ tmp.sparseColor(MatteChannel, BarycentricColorInterpolate, 9, arguments);
+ Image tmp2(Geometry(width, height), Back);
+ tmp.composite(tmp2, 0, 0, OverlayCompositeOp);
+ buffer = tmp;
+}
+
+void cImageLoader::DrawBackground2(tColor back, tColor blend, int width, int height) {
+ Color Back = Argb2Color(back);
+ Color Blend = Argb2Color(blend);
+ Image tmp(Geometry(width, height), Blend);
+ double arguments[9] = {0.0,(double)height,0.0,-0.5*(double)width,0.0,0.0,0.75*(double)width,0.0,1.0};
+ tmp.sparseColor(MatteChannel, BarycentricColorInterpolate, 9, arguments);
+ Image tmp2(Geometry(width, height), Back);
+ tmp.composite(tmp2, 0, 0, OverlayCompositeOp);
+ buffer = tmp;
+}
+
+cImage cImageLoader::GetImage() {
+ int w, h;
+ w = buffer.columns();
+ h = buffer.rows();
+ cImage image (cSize(w, h));
+ const PixelPacket *pixels = buffer.getConstPixels(0, 0, w, h);
+ for (int iy = 0; iy < h; ++iy) {
+ for (int ix = 0; ix < w; ++ix) {
+ tColor col = (~int(pixels->opacity * 255 / MaxRGB) << 24)
+ | (int(pixels->green * 255 / MaxRGB) << 8)
+ | (int(pixels->red * 255 / MaxRGB) << 16)
+ | (int(pixels->blue * 255 / MaxRGB) );
+ image.SetPixel(cPoint(ix, iy), col);
+ ++pixels;
+ }
+ }
+ return image;
+}
+
+Color cImageLoader::Argb2Color(tColor col) {
+ tIndex alpha = (col & 0xFF000000) >> 24;
+ tIndex red = (col & 0x00FF0000) >> 16;
+ tIndex green = (col & 0x0000FF00) >> 8;
+ tIndex blue = (col & 0x000000FF);
+ Color color(MaxRGB*red/255, MaxRGB*green/255, MaxRGB*blue/255, MaxRGB*(0xFF-alpha)/255);
+ return color;
+}
+
+void cImageLoader::toLowerCase(std::string &str) {
+ const int length = str.length();
+ for(int i=0; i < length; ++i) {
+ str[i] = std::tolower(str[i]);
+ }
+}
+
+bool cImageLoader::LoadImage(cString FileName, cString Path, cString Extension) {
+ try {
+ cString File = cString::sprintf("%s%s.%s", *Path, *FileName, *Extension);
+ dsyslog("nopacity: trying to load: %s", *File);
+ buffer.read(*File);
+ dsyslog("nopacity: %s sucessfully loaded", *File);
+ } catch (...) {
+ return false;
+ }
+ return true;
+}
diff --git a/imageloader.h b/imageloader.h
new file mode 100644
index 0000000..cade4d0
--- /dev/null
+++ b/imageloader.h
@@ -0,0 +1,30 @@
+#ifndef __NOPACITY_IMAGELOADER_H
+#define __NOPACITY_IMAGELOADER_H
+
+#define X_DISPLAY_MISSING
+
+#include <vdr/osd.h>
+#include <vdr/skins.h>
+#include <Magick++.h>
+
+using namespace Magick;
+
+class cImageLoader {
+public:
+ cImageLoader();
+ ~cImageLoader();
+ cImage GetImage();
+ bool LoadLogo(const char *logo, int width, int height);
+ bool LoadIcon(const char *cIcon, int size);
+ bool LoadIcon(const char *cIcon, int width, int height);
+ bool LoadEPGImage(int eventID);
+ void DrawBackground(tColor back, tColor blend, int width, int height);
+ void DrawBackground2(tColor back, tColor blend, int width, int height);
+private:
+ Image buffer;
+ Color Argb2Color(tColor col);
+ void toLowerCase(std::string &str);
+ bool LoadImage(cString FileName, cString Path, cString Extension);
+};
+
+#endif //__NOPACITY_IMAGELOADER_H
diff --git a/menudetailview.c b/menudetailview.c
new file mode 100644
index 0000000..8dc7d6c
--- /dev/null
+++ b/menudetailview.c
@@ -0,0 +1,246 @@
+#include "menudetailview.h"
+
+cNopacityMenuDetailView::cNopacityMenuDetailView(cOsd *osd) {
+ this->osd = osd;
+ hasScrollbar = false;
+}
+
+cNopacityMenuDetailView::~cNopacityMenuDetailView(void) {
+ delete font;
+ if (fontHeader)
+ delete fontHeader;
+ if (fontHeaderLarge)
+ delete fontHeaderLarge;
+}
+
+void cNopacityMenuDetailView::SetGeometry(int width, int height, int top, int contentBorder, int headerHeight) {
+ this->width = width;
+ this->height = height;
+ this->top = top;
+ this->border = contentBorder;
+ this->headerHeight = headerHeight;
+ contentHeight = height - headerHeight;
+}
+
+void cNopacityMenuDetailView::SetContent(const char *textContent) {
+ if (textContent)
+ content.Set(textContent, font, width - 4 * border);
+ else
+ content.Set("", font, width - 4 * border);
+
+ int textHeight = font->Height();
+ int linesContent = content.Lines() + 2;
+ int heightContentText = linesContent * textHeight;
+ if (heightContentText > contentHeight) {
+ contentDrawPortHeight = heightContentText;
+ hasScrollbar = true;
+ } else {
+ contentDrawPortHeight = contentHeight;
+ }
+}
+
+void cNopacityMenuDetailView::DrawContent(void) {
+ int linesContent = content.Lines();
+ int textHeight = font->Height();
+ for (int i=0; i<linesContent; i++) {
+ pixmapContent->DrawText(cPoint(2*border, (i+1)*textHeight), content.GetLine(i), Theme.Color(clrMenuFontDetailViewText), clrTransparent, font);
+ }
+}
+double cNopacityMenuDetailView::ScrollbarSize(void) {
+ double barSize = (double)contentHeight / (double)contentDrawPortHeight;
+ return barSize;
+}
+
+double cNopacityMenuDetailView::Offset(void) {
+ double offset;
+ if (((-1)*pixmapContent->DrawPort().Point().Y() + contentHeight + font->Height()) > contentDrawPortHeight)
+ offset = (double)1 - ScrollbarSize();
+ else
+ offset = (double)((-1)*pixmapContent->DrawPort().Point().Y())/(double)((-1)*pixmapContent->DrawPort().Point().Y() + contentHeight);
+ return offset;
+
+}
+bool cNopacityMenuDetailView::Scroll(bool Up, bool Page) {
+
+ int aktHeight = pixmapContent->DrawPort().Point().Y();
+ int totalHeight = pixmapContent->DrawPort().Height();
+ int screenHeight = pixmapContent->ViewPort().Height();
+ int lineHeight = font->Height();
+ bool scrolled = false;
+ if (Up) {
+ if (Page) {
+ int newY = aktHeight + screenHeight;
+ if (newY > 0)
+ newY = 0;
+ pixmapContent->SetDrawPortPoint(cPoint(0, newY));
+ scrolled = true;
+ } else {
+ if (aktHeight < 0) {
+ pixmapContent->SetDrawPortPoint(cPoint(0, aktHeight + lineHeight));
+ scrolled = true;
+ }
+ }
+ } else {
+ if (Page) {
+ int newY = aktHeight - screenHeight;
+ if ((-1)*newY > totalHeight - screenHeight)
+ newY = (-1)*(totalHeight - screenHeight);
+ pixmapContent->SetDrawPortPoint(cPoint(0, newY));
+ scrolled = true;
+ } else {
+ if (totalHeight - ((-1)*aktHeight + lineHeight) > screenHeight) {
+ pixmapContent->SetDrawPortPoint(cPoint(0, aktHeight - lineHeight));
+ scrolled = true;
+ }
+ }
+ }
+ return scrolled;
+}
+
+//---------------cNopacityMenuDetailEventView---------------------
+
+cNopacityMenuDetailEventView::cNopacityMenuDetailEventView(cOsd *osd, const cEvent *Event, const char *channel) : cNopacityMenuDetailView(osd) {
+ event = Event;
+ channelName = channel;
+}
+
+cNopacityMenuDetailEventView::~cNopacityMenuDetailEventView(void) {
+ osd->DestroyPixmap(pixmapHeader);
+ osd->DestroyPixmap(pixmapContent);
+ osd->DestroyPixmap(pixmapLogo);
+}
+
+void cNopacityMenuDetailEventView::CreatePixmaps(void) {
+ pixmapHeader = osd->CreatePixmap(3, cRect(0, top, width, headerHeight));
+ pixmapContent = osd->CreatePixmap(3, cRect(0, top + headerHeight, width, contentHeight),
+ cRect(0, 0, width, contentDrawPortHeight));
+ pixmapLogo = osd->CreatePixmap(4, cRect(0 + border, top + max((headerHeight-config.logoHeight)/2,1), config.detailViewLogoWidth, config.detailViewLogoHeight));
+
+ pixmapHeader->Fill(clrTransparent);
+ pixmapHeader->DrawRectangle(cRect(0, headerHeight - 2, width, 2), Theme.Color(clrMenuBorder));
+ pixmapContent->Fill(clrTransparent);
+ pixmapLogo->Fill(clrTransparent);
+
+}
+
+void cNopacityMenuDetailEventView::SetFonts(void) {
+ font = cFont::CreateFont(config.fontName, contentHeight / 25 + 3 + config.fontDetailView);
+ fontHeaderLarge = cFont::CreateFont(config.fontName, headerHeight / 4 + config.fontDetailViewHeaderLarge);
+ fontHeader = cFont::CreateFont(config.fontName, headerHeight / 6 + config.fontDetailViewHeader);
+}
+
+
+void cNopacityMenuDetailEventView::Render(void) {
+ DrawHeader();
+ DrawContent();
+}
+
+void cNopacityMenuDetailEventView::DrawHeader(void) {
+ cImageLoader imgLoader;
+ int logoWidth = config.detailViewLogoWidth;
+ if (imgLoader.LoadLogo(channelName, logoWidth, config.detailViewLogoHeight)) {
+ pixmapLogo->DrawImage(cPoint(0, max((headerHeight - config.detailViewLogoHeight - border)/2, 0)), imgLoader.GetImage());
+ }
+ int widthTextHeader = width - 4 * border - logoWidth;
+ if (imgLoader.LoadEPGImage(event->EventID())) {
+ pixmapHeader->DrawImage(cPoint(width - config.epgImageWidth - border, (headerHeight-config.epgImageHeight)/2), imgLoader.GetImage());
+ widthTextHeader -= config.epgImageWidth;
+ }
+
+ int lineHeight = fontHeaderLarge->Height();
+
+ cString dateTime = cString::sprintf("%s %s - %s", *event->GetDateString(), *event->GetTimeString(), *event->GetEndTimeString());
+ pixmapHeader->DrawText(cPoint(logoWidth + 2*border, (lineHeight - fontHeader->Height())/2), *dateTime, Theme.Color(clrMenuFontDetailViewHeader), clrTransparent, fontHeader);
+
+ cTextWrapper title;
+ title.Set(event->Title(), fontHeaderLarge, widthTextHeader);
+ int currentLineHeight = lineHeight;
+ for (int i=0; i < title.Lines(); i++) {
+ pixmapHeader->DrawText(cPoint(logoWidth + 2*border, currentLineHeight), title.GetLine(i), Theme.Color(clrMenuFontDetailViewHeaderTitle), clrTransparent, fontHeaderLarge);
+ currentLineHeight += lineHeight;
+ }
+
+ cTextWrapper shortText;
+ shortText.Set(event->ShortText(), fontHeader, widthTextHeader);
+ currentLineHeight += (lineHeight - fontHeader->Height())/2;
+ for (int i=0; i < shortText.Lines(); i++) {
+ if ((currentLineHeight + fontHeader->Height()) < headerHeight) {
+ pixmapHeader->DrawText(cPoint(logoWidth + 2*border, currentLineHeight), shortText.GetLine(i), Theme.Color(clrMenuFontDetailViewHeader), clrTransparent, fontHeader);
+ currentLineHeight += fontHeader->Height();
+ } else
+ break;
+ }
+
+}
+
+//------------------cNopacityMenuDetailRecordingView------------------
+
+cNopacityMenuDetailRecordingView::cNopacityMenuDetailRecordingView(cOsd *osd, const cRecording *Recording) : cNopacityMenuDetailView(osd) {
+ recording = Recording;
+ info = Recording->Info();
+}
+
+cNopacityMenuDetailRecordingView::~cNopacityMenuDetailRecordingView(void) {
+ osd->DestroyPixmap(pixmapHeader);
+ osd->DestroyPixmap(pixmapContent);
+}
+
+void cNopacityMenuDetailRecordingView::CreatePixmaps(void) {
+ pixmapHeader = osd->CreatePixmap(3, cRect(0, top, width, headerHeight));
+ pixmapContent = osd->CreatePixmap(3, cRect(0, top + headerHeight, width, contentHeight),
+ cRect(0, 0, width, contentDrawPortHeight));
+
+ pixmapHeader->Fill(clrTransparent);
+ pixmapHeader->DrawRectangle(cRect(0, headerHeight - 2, width, 2), Theme.Color(clrMenuBorder));
+ pixmapContent->Fill(clrTransparent);
+}
+
+void cNopacityMenuDetailRecordingView::SetFonts(void) {
+ font = cFont::CreateFont(config.fontName, contentHeight / 25 + config.fontDetailView);
+ fontHeaderLarge = cFont::CreateFont(config.fontName, headerHeight / 4 + config.fontDetailViewHeaderLarge);
+ fontHeader = cFont::CreateFont(config.fontName, headerHeight / 6 + config.fontDetailViewHeader);
+}
+
+void cNopacityMenuDetailRecordingView::Render(void) {
+ DrawHeader();
+ DrawContent();
+}
+
+void cNopacityMenuDetailRecordingView::DrawHeader(void) {
+ int lineHeight = fontHeaderLarge->Height();
+ cString dateTime = cString::sprintf("%s %s", *DateString(recording->Start()), *TimeString(recording->Start()));
+ const char *Title = info->Title();
+ if (isempty(Title))
+ Title = recording->Name();
+ pixmapHeader->DrawText(cPoint(2*border, (lineHeight - fontHeader->Height())/2), *dateTime, Theme.Color(clrMenuFontDetailViewHeader), clrTransparent, fontHeader);
+ pixmapHeader->DrawText(cPoint(2*border, lineHeight), Title, Theme.Color(clrMenuFontDetailViewHeaderTitle), clrTransparent, fontHeaderLarge);
+ if (!isempty(info->ShortText())) {
+ pixmapHeader->DrawText(cPoint(2*border, 2*lineHeight + (lineHeight - fontHeader->Height())/2), info->ShortText(), Theme.Color(clrMenuFontDetailViewHeader), clrTransparent, fontHeader);
+ }
+}
+
+//---------------cNopacityMenuDetailTextView---------------------
+
+cNopacityMenuDetailTextView::cNopacityMenuDetailTextView(cOsd *osd) : cNopacityMenuDetailView(osd) {
+}
+
+cNopacityMenuDetailTextView::~cNopacityMenuDetailTextView(void) {
+ osd->DestroyPixmap(pixmapContent);
+}
+
+void cNopacityMenuDetailTextView::SetFonts(void) {
+ font = cFont::CreateFont(config.fontName, contentHeight / 25 + config.fontDetailView);
+ fontHeaderLarge = NULL;
+ fontHeader = NULL;
+}
+
+void cNopacityMenuDetailTextView::CreatePixmaps(void) {
+ pixmapContent = osd->CreatePixmap(3, cRect(0, top + headerHeight, width, contentHeight),
+ cRect(0, 0, width, contentDrawPortHeight));
+
+ pixmapContent->Fill(clrTransparent);
+}
+
+void cNopacityMenuDetailTextView::Render(void) {
+ DrawContent();
+} \ No newline at end of file
diff --git a/menudetailview.h b/menudetailview.h
new file mode 100644
index 0000000..51eb0e9
--- /dev/null
+++ b/menudetailview.h
@@ -0,0 +1,68 @@
+#ifndef __NOPACITY_MENUDETAILVIEW_H
+#define __NOPACITY_MENUDETAILVIEW_H
+
+class cNopacityMenuDetailView {
+protected:
+ cOsd *osd;
+ bool hasScrollbar;
+ int width, height, top;
+ int headerHeight;
+ int contentHeight;
+ int contentDrawPortHeight;
+ int border;
+ cTextWrapper content;
+ cFont *font, *fontHeader, *fontHeaderLarge;
+ cPixmap *pixmapHeader;
+ cPixmap *pixmapLogo;
+ cPixmap *pixmapContent;
+ void DrawContent(void);
+public:
+ cNopacityMenuDetailView(cOsd *osd);
+ virtual ~cNopacityMenuDetailView(void);
+ void SetGeometry(int width, int height, int top, int contentBorder, int headerHeight);
+ virtual void SetFonts(void) = 0;
+ void SetContent(const char *textContent);
+ bool Scrollable(void) {return hasScrollbar;}
+ double ScrollbarSize(void);
+ double Offset(void);
+ bool Scroll(bool Up, bool Page);
+ virtual void CreatePixmaps(void) = 0;
+ virtual void Render(void) = 0;
+};
+
+class cNopacityMenuDetailEventView : public cNopacityMenuDetailView {
+private:
+ void DrawHeader(void);
+ const char *channelName;
+ const cEvent *event;
+public:
+ cNopacityMenuDetailEventView(cOsd *osd, const cEvent *Event, const char *channel);
+ virtual ~cNopacityMenuDetailEventView(void);
+ void CreatePixmaps(void);
+ void SetFonts(void);
+ void Render(void);
+};
+
+class cNopacityMenuDetailRecordingView : public cNopacityMenuDetailView {
+private:
+ void DrawHeader(void);
+ const cRecording *recording;
+ const cRecordingInfo *info;
+public:
+ cNopacityMenuDetailRecordingView(cOsd *osd, const cRecording *Recording);
+ virtual ~cNopacityMenuDetailRecordingView(void);
+ void CreatePixmaps(void);
+ void SetFonts(void);
+ void Render(void);
+};
+
+class cNopacityMenuDetailTextView : public cNopacityMenuDetailView {
+private:
+public:
+ cNopacityMenuDetailTextView(cOsd *osd);
+ virtual ~cNopacityMenuDetailTextView(void);
+ void CreatePixmaps(void);
+ void SetFonts(void);
+ void Render(void);
+};
+#endif //__NOPACITY_MENUDETAILVIEW_H \ No newline at end of file
diff --git a/menuitem.c b/menuitem.c
new file mode 100644
index 0000000..94c6569
--- /dev/null
+++ b/menuitem.c
@@ -0,0 +1,406 @@
+#include "menuitem.h"
+#include <string>
+#include <algorithm>
+
+
+// cNopacityMenuItem -------------
+
+cNopacityMenuItem::cNopacityMenuItem(cOsd *osd, const char *text, bool cur, bool sel) {
+ this->osd = osd;
+ hasIcon = false;
+ iconDrawn = false;
+ Text = text;
+ selectable = sel;
+ current = cur;
+ itemTabs = NULL;
+ tabWidth = NULL;
+ pixmapIcon = NULL;
+}
+
+cNopacityMenuItem::~cNopacityMenuItem(void) {
+ delete [] itemTabs;
+ delete [] tabWidth;
+ osd->DestroyPixmap(pixmap);
+ if (pixmapIcon) {
+ osd->DestroyPixmap(pixmapIcon);
+ }
+}
+
+void cNopacityMenuItem::CreatePixmap(int top, int space, int index, int width, int height) {
+ pixmap = osd->CreatePixmap(3, cRect(space, top + index * (height + space), width, height));
+ this->width = width;
+ this->height = height;
+}
+
+void cNopacityMenuItem::CreatePixmapIcon(int top, int space, int index, int itemHeight, int iconWidth, int iconHeight) {
+ pixmapIcon = osd->CreatePixmap(4, cRect(space, top + index * (itemHeight + space), iconWidth, iconHeight));
+ pixmapIcon->Fill(clrTransparent);
+ hasIcon = true;
+}
+
+void cNopacityMenuItem::SetTabs(cString *tabs, int *tabWidths, int numtabs) {
+ if (itemTabs)
+ delete [] itemTabs;
+ if (tabWidth)
+ delete [] tabWidth;
+ itemTabs = tabs;
+ tabWidth = tabWidths;
+ numTabs = numtabs;
+}
+
+void cNopacityMenuItem::SetBackgrounds(int *handleBackgrounds) {
+ this->handleBackgrounds = handleBackgrounds;
+}
+
+void cNopacityMenuItem::DrawDelimiter(const char *del, const char *icon, int handleBgrd) {
+ pixmap->Fill(Theme.Color(clrMenuItem));
+ pixmap->DrawImage(cPoint(1, 1), handleBgrd);
+ cImageLoader imgLoader;
+ if (!iconDrawn) {
+ if (imgLoader.LoadIcon(icon, config.iconHeight)) {
+ pixmapIcon->DrawImage(cPoint(1, (height - config.iconHeight) / 2), imgLoader.GetImage());
+ }
+ iconDrawn = true;
+ }
+ std::string delimiter = del;
+ delimiter.erase(delimiter.find_last_not_of("-")+1);
+ int x = config.iconHeight + 3;
+ int y = (height - font->Height()) / 2;
+ pixmap->DrawText(cPoint(x, y), delimiter.c_str(), Theme.Color(clrMenuFontMenuItemSep), clrTransparent, font);
+}
+
+// cNopacityMainMenuItem -------------
+cNopacityMainMenuItem::cNopacityMainMenuItem(cOsd *osd, const char *text, bool cur, bool sel) : cNopacityMenuItem (osd, text, cur, sel) {
+}
+
+cNopacityMainMenuItem::~cNopacityMainMenuItem(void) {
+}
+
+void cNopacityMainMenuItem::SplitMenuItem() {
+
+ std::string text = skipspace(Text);
+ bool found = false;
+ bool doBreak = false;
+ size_t i = 0;
+ for (; i < text.length(); i++) {
+ char s = text.at(i);
+ if (found) {
+ if (!(s >= '0' && s <= '9')) {
+ doBreak = true;
+ }
+ }
+ if (s >= '0' && s <= '9') {
+ found = true;
+ }
+ if (doBreak)
+ break;
+ if (i>4)
+ break;
+ }
+ if (found) {
+ menuNumber = skipspace(text.substr(0,i).c_str());
+ menuEntry = skipspace(text.substr(i).c_str());
+ } else {
+ menuNumber = "";
+ menuEntry = text.c_str();
+ }
+}
+
+std::string cNopacityMainMenuItem::items[6] = {"Schedule", "Channels", "Timers", "Recordings", "Setup", "Commands"};
+
+cString cNopacityMainMenuItem::GetIconName() {
+ std::string element = *menuEntry;
+ for (int i=0; i<6; i++) {
+ std::string s = trVDR(items[i].c_str());
+ if (s == element)
+ return items[i].c_str();
+ }
+ return menuEntry;
+}
+
+void cNopacityMainMenuItem::Render() {
+
+ pixmap->Fill(Theme.Color(clrMenuBorder));
+ int handleBgrd = (current)?handleBackgrounds[3]:handleBackgrounds[2];
+ tColor clrFont = (current)?Theme.Color(clrMenuFontMenuItemHigh):Theme.Color(clrMenuFontMenuItem);
+ pixmap->DrawImage(cPoint(1, 1), handleBgrd);
+ SplitMenuItem();
+ cString cIcon = GetIconName();
+ if (!iconDrawn) {
+ cImageLoader imgLoader;
+ if (imgLoader.LoadIcon(*cIcon, config.iconHeight)) {
+ pixmapIcon->DrawImage(cPoint(1, 1), imgLoader.GetImage());
+ }
+ iconDrawn = true;
+ }
+
+ int x = config.iconHeight;
+ int numberTotalWidth = font->Width("xxx");
+ int numberWidth = font->Width(*menuNumber);
+ pixmap->DrawText(cPoint(x + (numberTotalWidth - numberWidth)/2, (height - font->Height())/2), *menuNumber, clrFont, clrTransparent, font);
+ x += numberTotalWidth;
+
+ int textWidth = font->Width(*menuEntry);
+ if (textWidth <= width - x) {
+ pixmap->DrawText(cPoint(x, (height - font->Height())/2), *menuEntry, clrFont, clrTransparent, font);
+ } else {
+ cTextWrapper menuText;
+ menuText.Set(*menuEntry, font, width - x);
+ //max. 2 lines
+ pixmap->DrawText(cPoint(x, (height/2 - font->Height()) / 2 ), menuText.GetLine(0), clrFont, clrTransparent, font);
+ pixmap->DrawText(cPoint(x, (height/2 - font->Height()) / 2 + height/2), menuText.GetLine(1), clrFont, clrTransparent, font);
+ }
+}
+
+// cNopacityScheduleMenuItem -------------
+
+cNopacityScheduleMenuItem::cNopacityScheduleMenuItem(cOsd *osd, const char *text, bool cur, bool sel, eMenuSubCategory subCat) : cNopacityMenuItem (osd, text, cur, sel) {
+ subCategory = subCat;
+}
+
+cNopacityScheduleMenuItem::~cNopacityScheduleMenuItem(void) {
+}
+
+void cNopacityScheduleMenuItem::Render() {
+
+ /* Data in Array:
+ Schedule: 0: Date,
+ 1: Time
+ 2: Running, VPS
+ 3: Title
+ What's on Now: 0: Channel Number
+ 1: Channel Name
+ 2: Time
+ Vanilla:
+ 3: Running, VPS
+ 4: Title
+ EPGSearch:
+ 3: Remaining (EPGSearch)
+ 4: Running, VPS
+ 5: Title
+ EPG Search Res: 0: Channel Number
+ 1: Channel Name
+ 2: Date
+ 3: Time
+ 4: " "
+ 5: Title
+ What's on Next: 0: Channel Number
+ 1: Channel Name
+ 2: Time
+ 3: Running, VPS
+ 4: Title
+ EPGSearch Hide Channelnumbers: Each entry -1
+ */
+ cString channelNumber, channelName, startTime, running, remaining, title;
+ bool hasRemaining = false;
+ int handleBgrd = (current)?handleBackgrounds[5]:handleBackgrounds[4];
+ tColor clrFont = (current)?Theme.Color(clrMenuFontMenuItemHigh):Theme.Color(clrMenuFontMenuItem);
+ if (subCategory == mcSubScheduleWhatsOn) {
+ if (selectable) { //Event
+ pixmap->Fill(Theme.Color(clrMenuBorder));
+ if (isnumber(*itemTabs[0])) {
+ channelNumber = itemTabs[0];
+ channelName = itemTabs[1];
+ startTime = itemTabs[2];
+ if ((std::string(skipspace(itemTabs[3])).length() > 0) && (startswith(*itemTabs[3], "["))) { // EPGSearch Progress Bar
+ hasRemaining = true;
+ remaining = itemTabs[3];
+ running = itemTabs[4];
+ title = itemTabs[5];
+ } else if (std::string(skipspace(itemTabs[4])).length() == 0){ //EPG Search Result
+ running = itemTabs[3];
+ title = itemTabs[5];
+ } else {
+ running = itemTabs[3];
+ title = itemTabs[4];
+ }
+ } else {
+ channelName = itemTabs[0];
+ startTime = itemTabs[1];
+ if ((std::string(skipspace(itemTabs[2])).length() > 0) && (startswith(*itemTabs[2], "["))) { // EPGSearch Progress Bar
+ hasRemaining = true;
+ remaining = itemTabs[2];
+ running = itemTabs[3];
+ title = itemTabs[4];
+ } else if (std::string(skipspace(itemTabs[3])).length() == 0){ //EPG Search Result
+ running = itemTabs[2];
+ title = itemTabs[4];
+ } else {
+ running = itemTabs[2];
+ title = itemTabs[3];
+ }
+ }
+ int logoWidth = config.menuItemLogoWidth;
+ int logoHeight = config.menuItemLogoHeight;
+ int xText = logoWidth + 10;
+ cTextWrapper titleLines;
+ titleLines.Set(*title, font, width - xText);
+ int lineHeight = font->Height() - 2;
+ pixmap->DrawImage(cPoint(1, 1), handleBgrd);
+ if (!iconDrawn) {
+ cImageLoader imgLoader;
+ if (imgLoader.LoadLogo(*channelName, logoWidth, logoHeight)) {
+ pixmapIcon->DrawImage(cPoint(1, 1), imgLoader.GetImage());
+ } else {
+ cTextWrapper channel;
+ channel.Set(*channelName, font, logoWidth);
+ int lines = channel.Lines();
+ int heightChannel = lines * lineHeight;
+ int y = (heightChannel>height)?0:(height-heightChannel)/2;
+ for (int line = 0; line < lines; line++) {
+ pixmapIcon->DrawText(cPoint((logoWidth - font->Width(channel.GetLine(line)))/2, y+lineHeight*line), channel.GetLine(line), Theme.Color(clrMenuFontMenuItemHigh), clrTransparent, font);
+ }
+ }
+ iconDrawn = true;
+ }
+
+
+ pixmap->DrawText(cPoint(xText, 0), startTime, Theme.Color(clrMenuFontMenuItemTitle), clrTransparent, font);
+ pixmap->DrawText(cPoint(xText + font->Width(*startTime) + 5, 0), *running, Theme.Color(clrMenuFontMenuItemTitle), clrTransparent, font);
+ for (int line = 0; line < titleLines.Lines(); line++) {
+ if (line == 2) break;
+ pixmap->DrawText(cPoint(xText , lineHeight * (line+1)), titleLines.GetLine(line), clrFont, clrTransparent, font);
+ }
+ if (hasRemaining)
+ DrawRemaining(remaining, xText, height*7/8, width - xText - 10);
+ } else { //Channelseparators
+ DrawDelimiter(*itemTabs[1], "Channelseparator", handleBgrd);
+ }
+ } else {
+ if (selectable) { //Event
+ pixmap->Fill(Theme.Color(clrMenuBorder));
+ pixmap->DrawImage(cPoint(1, 1), handleBgrd);
+ cString dateTime = cString::sprintf("%s %s %s", *itemTabs[0], *itemTabs[1], *itemTabs[2]);
+ pixmap->DrawText(cPoint(5, 3), *dateTime, Theme.Color(clrMenuFontMenuItemTitle), clrTransparent, font);
+ title = itemTabs[3];
+ cTextWrapper titleLines;
+ int lineHeight = font->Height();
+ titleLines.Set(*title, font, width-8);
+ for (int line = 0; line < titleLines.Lines(); line++) {
+ pixmap->DrawText(cPoint(5 , 3 + lineHeight * (line+1)), titleLines.GetLine(line), clrFont, clrTransparent, font);
+ if (line == 3) break;
+ }
+ } else { //Day Delimiter
+ DrawDelimiter(*itemTabs[1], "daydelimiter", handleBgrd);
+ }
+ }
+}
+
+void cNopacityScheduleMenuItem::DrawRemaining(cString remaining, int x, int y, int width) {
+ int seen = 0;
+ int total = 8;
+ if (*remaining) {
+ const char *p = *remaining;
+ p++;
+ while (*p) {
+ if (*p == '|') {
+ seen++;
+ p++;
+ } else
+ break;
+ }
+ }
+ double percentSeen = (double)seen/total;
+ pixmap->DrawEllipse(cRect(x, y, 7, 7), Theme.Color(clrProgressBarBack));
+ pixmap->DrawEllipse(cRect(x+width, y, 7, 7), Theme.Color(clrProgressBarBack));
+ pixmap->DrawRectangle(cRect(x+4, y, width-1, 7), Theme.Color(clrProgressBarBack));
+ pixmap->DrawEllipse(cRect(x+1, y+1, 5, 5), Theme.Color(clrProgressBar));
+ if (percentSeen > 0.0)
+ pixmap->DrawEllipse(cRect(x+(width*percentSeen), y+1, 5, 5), Theme.Color(clrProgressBar));
+ pixmap->DrawRectangle(cRect(x+4, y+1, (width-1)*percentSeen, 5), Theme.Color(clrProgressBar));
+}
+
+// cNopacityChannelMenuItem -------------
+
+cNopacityChannelMenuItem::cNopacityChannelMenuItem(cOsd *osd, const char *text, bool cur, bool sel) : cNopacityMenuItem (osd, text, cur, sel) {
+}
+
+cNopacityChannelMenuItem::~cNopacityChannelMenuItem(void) {
+}
+
+void cNopacityChannelMenuItem::Render() {
+
+ int handleBgrd = (current)?handleBackgrounds[5]:handleBackgrounds[4];
+ tColor clrFont = (current)?Theme.Color(clrMenuFontMenuItemHigh):Theme.Color(clrMenuFontMenuItem);
+ cString channelNumber = *itemTabs[0];
+ cString channelName = *itemTabs[1];
+ if (selectable) { //Channels
+ pixmap->Fill(Theme.Color(clrMenuBorder));
+ int logoWidth = config.menuItemLogoWidth;
+ int logoHeight = config.menuItemLogoHeight;
+ //eliminate strange wareagle icons :-/
+ std::string name = *channelName;
+ if (!isalnum(name.at(0))) {
+ if (name.length() > 3)
+ name = name.substr(4);
+ }
+ name.erase(name.find_last_not_of(" ")+1);
+ pixmap->DrawImage(cPoint(1, 1), handleBgrd);
+ if (!iconDrawn) {
+ cImageLoader imgLoader;
+ if (imgLoader.LoadLogo(name.c_str(), logoWidth, logoHeight)) {
+ pixmapIcon->DrawImage(cPoint(1, 1), imgLoader.GetImage());
+ }
+ iconDrawn = true;
+ }
+ cTextWrapper channel;
+ channel.Set(*cString::sprintf("%s %s", *channelNumber, *channelName), font, width - logoWidth - 6);
+ int lineHeight = font->Height();
+ int lines = channel.Lines();
+ int heightChannel = lines * lineHeight;
+ int y = (heightChannel>height)?0:(height-heightChannel)/2;
+ for (int line = 0; line < lines; line++) {
+ pixmap->DrawText(cPoint(logoWidth + 10, y+lineHeight*line), channel.GetLine(line), clrFont, clrTransparent, font);
+ }
+ } else { //Channelseparators
+ DrawDelimiter(*itemTabs[1], "Channelseparator", handleBgrd);
+ }
+}
+
+// cNopacityDefaultMenuItem -------------
+
+cNopacityDefaultMenuItem::cNopacityDefaultMenuItem(cOsd *osd, const char *text, bool cur, bool sel) : cNopacityMenuItem (osd, text, cur, sel) {
+}
+
+cNopacityDefaultMenuItem::~cNopacityDefaultMenuItem(void) {
+}
+
+void cNopacityDefaultMenuItem::Render() {
+ pixmap->Fill(Theme.Color(clrMenuBorder));
+ int handleBgrd = (current)?handleBackgrounds[1]:handleBackgrounds[0];
+ tColor clrFont = (current)?Theme.Color(clrMenuFontMenuItemHigh):Theme.Color(clrMenuFontMenuItem);
+ pixmap->DrawImage(cPoint(1, 1), handleBgrd);
+ int colWidth = 0;
+ int colTextWidth = 0;
+ cString itemText("");
+ for (int i=0; i<numTabs; i++) {
+ if (tabWidth[i] > 0) {
+ colWidth = tabWidth[i+cSkinDisplayMenu::MaxTabs];
+ colTextWidth = font->Width(*itemTabs[i]);
+ if (colTextWidth > colWidth) {
+ cTextWrapper itemTextWrapped;
+ itemTextWrapped.Set(*itemTabs[i], font, colWidth - font->Width("... "));
+ itemText = cString::sprintf("%s... ", itemTextWrapped.GetLine(0));
+ } else {
+ itemText = itemTabs[i];
+ }
+ pixmap->DrawText(cPoint(tabWidth[i], (height - font->Height()) / 2), *itemText, clrFont, clrTransparent, font);
+ } else
+ break;
+ }
+}
+
+// cNopacityTrackMenuItem -------------
+
+cNopacityTrackMenuItem::cNopacityTrackMenuItem(cOsd *osd, const char *text, bool cur) : cNopacityMenuItem (osd, text, cur, true) {
+}
+
+cNopacityTrackMenuItem::~cNopacityTrackMenuItem(void) {
+}
+
+void cNopacityTrackMenuItem::Render() {
+ pixmap->Fill(Theme.Color(clrMenuBorder));
+ int handleBgrd = (current)?handleBackgrounds[1]:handleBackgrounds[0];
+ pixmap->DrawImage(cPoint(1, 1), handleBgrd);
+ pixmap->DrawText(cPoint(5, (height - font->Height())/2), Text, Theme.Color(clrTracksFontButtons), clrTransparent, font);
+}
diff --git a/menuitem.h b/menuitem.h
new file mode 100644
index 0000000..fd001d6
--- /dev/null
+++ b/menuitem.h
@@ -0,0 +1,83 @@
+#ifndef __NOPACITY_MENUITEM_H
+#define __NOPACITY_MENUITEM_H
+
+class cNopacityMenuItem : public cListObject {
+protected:
+ cOsd *osd;
+ cPixmap *pixmap;
+ cPixmap *pixmapIcon;
+ bool hasIcon;
+ bool iconDrawn;
+ int *handleBackgrounds;
+ const char *Text;
+ bool selectable;
+ bool current;
+ cFont *font;
+ int width, height;
+ cString *itemTabs;
+ int *tabWidth;
+ int numTabs;
+ void DrawDelimiter(const char *del, const char *icon, int handleBgrd);
+public:
+ cNopacityMenuItem(cOsd *osd, const char *text, bool cur, bool sel);
+ virtual ~cNopacityMenuItem(void);
+ void CreatePixmap(int top, int space, int index, int width, int height);
+ void CreatePixmapIcon(int top, int space, int index, int itemHeight, int iconWidth, int iconHeight);
+ void SetFont(cFont *font) {this->font = font;}
+ void SetCurrent(bool cur) {current = cur;}
+ void SetAlpha(int alpha) {this->pixmap->SetAlpha(alpha);}
+ void SetAlphaIcon(int alpha) {if (hasIcon) this->pixmapIcon->SetAlpha(alpha);}
+ void SetTabs(cString *tabs, int *tabWidths, int numtabs);
+ void SetBackgrounds(int *handleBackgrounds);
+ virtual void Render() = 0;
+};
+
+class cNopacityMainMenuItem : public cNopacityMenuItem {
+private:
+ cString menuNumber;
+ cString menuEntry;
+ void SplitMenuItem();
+ static std::string items[6];
+ cString GetIconName();
+public:
+ cNopacityMainMenuItem(cOsd *osd, const char *text, bool cur, bool sel);
+ ~cNopacityMainMenuItem(void);
+ void Render();
+};
+
+enum eMenuSubCategory { mcSubUndefined = -1, mcSubSchedule = 0, mcSubScheduleWhatsOn, mcSubScheduleTimer, mcSubChannels, mcSubChannelEdit};
+
+class cNopacityScheduleMenuItem : public cNopacityMenuItem {
+private:
+ eMenuSubCategory subCategory;
+ void DrawRemaining(cString remaining, int x, int y, int width);
+public:
+ cNopacityScheduleMenuItem(cOsd *osd, const char *text, bool cur, bool sel, eMenuSubCategory subCat);
+ ~cNopacityScheduleMenuItem(void);
+ void Render();
+};
+
+class cNopacityChannelMenuItem : public cNopacityMenuItem {
+private:
+public:
+ cNopacityChannelMenuItem(cOsd *osd, const char *text, bool cur, bool sel);
+ ~cNopacityChannelMenuItem(void);
+ void Render();
+};
+
+class cNopacityDefaultMenuItem : public cNopacityMenuItem {
+private:
+public:
+ cNopacityDefaultMenuItem(cOsd *osd, const char *text, bool cur, bool sel);
+ ~cNopacityDefaultMenuItem(void);
+ void Render();
+};
+
+class cNopacityTrackMenuItem : public cNopacityMenuItem {
+private:
+public:
+ cNopacityTrackMenuItem(cOsd *osd, const char *text, bool cur);
+ ~cNopacityTrackMenuItem(void);
+ void Render();
+};
+#endif //__NOPACITY_MENUITEM_H
diff --git a/nopacity.c b/nopacity.c
new file mode 100644
index 0000000..1ed2561
--- /dev/null
+++ b/nopacity.c
@@ -0,0 +1,169 @@
+#include <vdr/osd.h>
+#include <vdr/menu.h>
+
+static cTheme Theme;
+
+//COMMON
+#define CLR_TRANSBLACK 0xDD000000
+#define CLR_TRANSBLACK2 0xB0000000
+#define CLR_DARKBLUE 0xDD003DF5
+#define CLR_DARKBLUE2 0xB0003DF5
+#define CLR_WHITE 0xFFFFFFFF
+#define CLR_BRIGHTBLUE 0xFF0066FF
+#define CLR_GRAY 0xFF858585
+
+//CHANNELS
+#define CLR_PROGRESSBARBACK 0xDD858585
+#define CLR_PROGRESSBARBLEND 0xDD80B3FF
+#define CLR_CHANNELSYMBOLOFF 0xDD858585
+#define CLR_CHANNELRECACTIVE 0xDDFF0000
+
+//REPLAY
+#define CLR_REPLAYCURRENTTOTAL 0xFF003DF5
+#define CLR_REST 0xDD858585
+#define CLR_EXPOSED 0xFF000000
+#define CLR_CURRENT 0x90FFFFFF
+#define CLR_MARKS 0xFF000000
+
+//MENU
+#define CLR_MENUSCROLLBARBACK 0x40003DF5
+#define CLR_MENUITEM 0xEE444444
+#define CLR_MENUITEMBLEND 0x90000000
+#define CLR_MENUITEMHIGHBLEND 0xEE0033FF
+#define CLR_DISKALERT 0xDDFF0000
+
+//BUTTONS
+#define CLR_BUTTONRED 0x99BB0000
+#define CLR_BUTTONREDBORDER 0xFFBB0000
+#define CLR_BUTTONGREEN 0x9900BB00
+#define CLR_BUTTONGREENBORDER 0xFF00BB00
+#define CLR_BUTTONYELLOW 0x99BBBB00
+#define CLR_BUTTONYELLOWBORDER 0xFFBBBB00
+#define CLR_BUTTONBLUE 0x990000BB
+#define CLR_BUTTONBLUEBORDER 0xFF0000BB
+
+//MESSAGES
+#define CLR_MESSAGESTATUS 0x900000FF
+#define CLR_MESSAGEINFO 0x90009900
+#define CLR_MESSAGEWARNING 0x90BBBB00
+#define CLR_MESSAGEERROR 0x90BB0000
+
+//CHANNELS
+THEME_CLR(Theme, clrChannelBackground, CLR_TRANSBLACK2);
+THEME_CLR(Theme, clrChannelBackBlend, CLR_DARKBLUE2);
+THEME_CLR(Theme, clrChannelHead, CLR_BRIGHTBLUE);
+THEME_CLR(Theme, clrChannelEPG, CLR_WHITE);
+THEME_CLR(Theme, clrChannelEPGInfo, CLR_GRAY);
+THEME_CLR(Theme, clrProgressBar, CLR_DARKBLUE);
+THEME_CLR(Theme, clrProgressBarBack, CLR_PROGRESSBARBACK);
+THEME_CLR(Theme, clrProgressBarBlend, CLR_PROGRESSBARBLEND);
+THEME_CLR(Theme, clrChannelSymbolOn, CLR_DARKBLUE);
+THEME_CLR(Theme, clrChannelSymbolOff, CLR_CHANNELSYMBOLOFF);
+THEME_CLR(Theme, clrChannelRecActive, CLR_CHANNELRECACTIVE);
+//REPLAY
+THEME_CLR(Theme, clrReplayBackground, CLR_TRANSBLACK2);
+THEME_CLR(Theme, clrReplayBackBlend, CLR_DARKBLUE2);
+THEME_CLR(Theme, clrReplayHead, CLR_WHITE);
+THEME_CLR(Theme, clrReplayDescription, CLR_GRAY);
+THEME_CLR(Theme, clrReplayCurrentTotal, CLR_REPLAYCURRENTTOTAL);
+THEME_CLR(Theme, clrReplayProgressSeen, CLR_DARKBLUE);
+THEME_CLR(Theme, clrReplayProgressRest, CLR_REST);
+THEME_CLR(Theme, clrReplayProgressSelected, CLR_EXPOSED);
+THEME_CLR(Theme, clrReplayProgressMark, CLR_MARKS);
+THEME_CLR(Theme, clrReplayProgressCurrent, CLR_CURRENT);
+THEME_CLR(Theme, clrReplayHighlightIcon, CLR_DARKBLUE);
+//TRACKS
+THEME_CLR(Theme, clrTracksFontHead, CLR_GRAY);
+THEME_CLR(Theme, clrTracksFontButtons, CLR_WHITE);
+//Volume
+THEME_CLR(Theme, clrVolumeFont, CLR_GRAY);
+//MENU
+THEME_CLR(Theme, clrMenuBack, CLR_TRANSBLACK);
+THEME_CLR(Theme, clrMenuBorder, CLR_DARKBLUE);
+THEME_CLR(Theme, clrMenuScrollBar, CLR_DARKBLUE);
+THEME_CLR(Theme, clrMenuScrollBarBack, CLR_MENUSCROLLBARBACK);
+THEME_CLR(Theme, clrMenuItem, CLR_MENUITEM);
+THEME_CLR(Theme, clrMenuItemBlend, CLR_MENUITEMBLEND);
+THEME_CLR(Theme, clrMenuItemHigh, CLR_TRANSBLACK);
+THEME_CLR(Theme, clrMenuItemHighBlend, CLR_MENUITEMHIGHBLEND);
+THEME_CLR(Theme, clrDiskAlert, CLR_DISKALERT);
+THEME_CLR(Theme, clrMenuFontHeader, CLR_WHITE);
+THEME_CLR(Theme, clrMenuFontDate, CLR_WHITE);
+THEME_CLR(Theme, clrMenuFontDiscUsage, CLR_WHITE);
+THEME_CLR(Theme, clrMenuFontButton, CLR_WHITE);
+THEME_CLR(Theme, clrMenuFontTimers, CLR_WHITE);
+THEME_CLR(Theme, clrMenuFontTimersHeader, CLR_WHITE);
+THEME_CLR(Theme, clrMenuFontMessages, CLR_WHITE);
+THEME_CLR(Theme, clrMenuFontDetailViewText, CLR_WHITE);
+THEME_CLR(Theme, clrMenuFontDetailViewHeader, CLR_GRAY);
+THEME_CLR(Theme, clrMenuFontDetailViewHeaderTitle, CLR_BRIGHTBLUE);
+THEME_CLR(Theme, clrMenuFontMenuItem, CLR_WHITE);
+THEME_CLR(Theme, clrMenuFontMenuItemHigh, CLR_BRIGHTBLUE);
+THEME_CLR(Theme, clrMenuFontMenuItemTitle, CLR_BRIGHTBLUE);
+THEME_CLR(Theme, clrMenuFontMenuItemSep, CLR_GRAY);
+//BUTTONS
+THEME_CLR(Theme, clrButtonRed, CLR_BUTTONRED);
+THEME_CLR(Theme, clrButtonRedBorder, CLR_BUTTONREDBORDER);
+THEME_CLR(Theme, clrButtonGreen, CLR_BUTTONGREEN);
+THEME_CLR(Theme, clrButtonGreenBorder, CLR_BUTTONGREENBORDER);
+THEME_CLR(Theme, clrButtonYellow, CLR_BUTTONYELLOW);
+THEME_CLR(Theme, clrButtonYellowBorder, CLR_BUTTONYELLOWBORDER);
+THEME_CLR(Theme, clrButtonBlue, CLR_BUTTONBLUE);
+THEME_CLR(Theme, clrButtonBlueBorder, CLR_BUTTONBLUEBORDER);
+//MESSAGES
+THEME_CLR(Theme, clrMessageFont, CLR_WHITE);
+THEME_CLR(Theme, clrMessageStatus, CLR_MESSAGESTATUS);
+THEME_CLR(Theme, clrMessageInfo, CLR_MESSAGEINFO);
+THEME_CLR(Theme, clrMessageWarning, CLR_MESSAGEWARNING);
+THEME_CLR(Theme, clrMessageError, CLR_MESSAGEERROR);
+THEME_CLR(Theme, clrMessageBlend, CLR_TRANSBLACK);
+
+
+#include "config.c"
+cNopacityConfig config;
+#include "setup.c"
+#include "imageloader.c"
+#include "nopacity.h"
+#include "helpers.c"
+#include "displaychannel.c"
+#include "menuitem.c"
+#include "menudetailview.c"
+#include "displaymenuview.c"
+#include "displaymenu.c"
+#include "displayreplay.c"
+#include "displayvolume.c"
+#include "displaytracks.c"
+#include "displaymessage.c"
+
+cNopacity::cNopacity(void) : cSkin("nOpacity", &::Theme) {
+ config.setDynamicValues();
+}
+
+const char *cNopacity::Description(void) {
+ return "nOpacity";
+}
+
+cSkinDisplayChannel *cNopacity::DisplayChannel(bool WithInfo) {
+ return new cNopacityDisplayChannel(WithInfo);
+}
+
+cSkinDisplayMenu *cNopacity::DisplayMenu(void) {
+ return new cNopacityDisplayMenu;
+}
+
+cSkinDisplayReplay *cNopacity::DisplayReplay(bool ModeOnly) {
+ return new cNopacityDisplayReplay(ModeOnly);
+}
+
+cSkinDisplayVolume *cNopacity::DisplayVolume(void) {
+ return new cNopacityDisplayVolume;
+}
+
+cSkinDisplayTracks *cNopacity::DisplayTracks(const char *Title, int NumTracks, const char * const *Tracks) {
+ return new cNopacityDisplayTracks(Title, NumTracks, Tracks);
+}
+
+cSkinDisplayMessage *cNopacity::DisplayMessage(void) {
+ return new cNopacityDisplayMessage;
+}
+
diff --git a/nopacity.h b/nopacity.h
new file mode 100644
index 0000000..f59b397
--- /dev/null
+++ b/nopacity.h
@@ -0,0 +1,28 @@
+/*
+ * skinlcars.h: A VDR skin with Star Trek's "LCARS" layout
+ *
+ * See the main source file 'vdr.c' for copyright information and
+ * how to reach the author.
+ *
+ * $Id: skinlcars.h 2.1 2012/04/15 13:17:35 kls Exp $
+ */
+
+#ifndef __NOPACITY_H
+#define __NOPACITY_H
+
+#include <vdr/skins.h>
+#include <vdr/videodir.h>
+
+class cNopacity : public cSkin {
+public:
+ cNopacity(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 cSkinDisplayTracks *DisplayTracks(const char *Title, int NumTracks, const char * const *Tracks);
+ virtual cSkinDisplayMessage *DisplayMessage(void);
+ };
+
+#endif //__NOPACITY_H
diff --git a/po/de_DE.po b/po/de_DE.po
new file mode 100644
index 0000000..f68d97e
--- /dev/null
+++ b/po/de_DE.po
@@ -0,0 +1,211 @@
+# VDR plugin language source file.
+# Copyright (C) 2012
+# This file is distributed under the same license as the PACKAGE package.
+# louis, 2012.
+#
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: skinnopacity 0.0.1\n"
+"Report-Msgid-Bugs-To: <see README>\n"
+"POT-Creation-Date: 2012-11-24 10:42+0100\n"
+"PO-Revision-Date: 2012-11-11 17:49+0200\n"
+"Last-Translator: louis\n"
+"Language-Team: \n"
+"Language: de\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+msgid "Font"
+msgstr "Schriftart"
+
+msgid "VDR Menu"
+msgstr "VDR Menü"
+
+msgid "Channel Switching"
+msgstr "Kanalwechsel"
+
+msgid "Replay"
+msgstr "Wiedergabe von Aufzeichnungen"
+
+msgid "Audio Tracks"
+msgstr "Audio Spuren"
+
+msgid "Messages"
+msgstr "Nachrichten"
+
+msgid "Volume"
+msgstr "Lautstärke"
+
+msgid "Fade-In Time in ms (Zero for switching off fading)"
+msgstr "Fade-In Zeit in ms (Null zum Abschalten)"
+
+msgid "Scale Video size to fit into menu window"
+msgstr "TV-Bildgröße in Menüfenster einpassen"
+
+msgid "Width of narrow Menu Bar (Percent of OSD Width)"
+msgstr "Breite der schmalen Menüleiste (Proz. der OSD Breite)"
+
+msgid "Width of Disc Usage and Timers Display (Percent of OSD Width)"
+msgstr "Breite der Anzeige der Timer (Proz. der OSD Breite)"
+
+msgid "Header Height (Percent of OSD Height)"
+msgstr "Header Höhe (in Prozent der OSD Höhe"
+
+msgid "Footer Height (Percent of OSD Height)"
+msgstr "Footer Höhe (in Prozent der OSD Höhe"
+
+msgid "Number of Default Menu Entries per Page"
+msgstr "Anzahl der Default-Menüelemente pro Seite"
+
+#, fuzzy
+msgid "Icon Size (Square Main Menu Icons)"
+msgstr "Größe der quadratischen Hauptmenü Icons)"
+
+#, fuzzy
+msgid "Header Icon Size (Square Header Menu Icons)"
+msgstr "Größe der quadratischen Headericons"
+
+msgid "Channel Logo Width (on the Menu Buttons)"
+msgstr "Breite der Kanallogos auf den Menübuttons"
+
+msgid "Channel Logo Height (on the Menu Buttons)"
+msgstr "Höhe der Kanallogos auf den Menübuttons"
+
+msgid "Main Menu Header Logo Width"
+msgstr "Höhe des Logos im Hauptmenü"
+
+msgid "Main Menu Header Logo Height"
+msgstr "Breite des Logos im Hauptmenü"
+
+msgid "Detail EPG View Logo Width"
+msgstr "Breite der Kanallogos in der EPG Detailanzeige"
+
+msgid "Detail EPG View Logo Height"
+msgstr "Höhe der Kanallogos in der EPG Detailanzeige"
+
+msgid "Detail EPG View EPG Image Width"
+msgstr "Breite der EPG Bilder in der EPG Detailanzeige"
+
+msgid "Detail EPG View EPG Image Height"
+msgstr "Höhe der EPG Bilder in der EPG Detailanzeige"
+
+msgid "Adjust Font Size - Header"
+msgstr "Schriftgröße anpassen - Header"
+
+msgid "Adjust Font Size - Date"
+msgstr "Schriftgröße anpassen - Datum und Uhrzeit"
+
+msgid "Adjust Font Size - Large Menu Item"
+msgstr "Schriftgröße anpassen - Große Menübuttons"
+
+msgid "Adjust Font Size - Schedule Menu Item"
+msgstr "Schriftgröße anpassen - Programmübersicht Menübuttons"
+
+msgid "Adjust Font Size - Default Menu Item"
+msgstr "Schriftgröße anpassen - Default Menübuttons"
+
+msgid "Adjust Font Size - Disc Usage"
+msgstr "Schriftgröße anpassen - Festplattenstatus"
+
+msgid "Adjust Font Size - Timers Header"
+msgstr "Schriftgröße anpassen - Timer Header"
+
+msgid "Adjust Font Size - Timers Title"
+msgstr "Schriftgröße anpassen - Timer Name"
+
+msgid "Adjust Font Size - Color Buttons"
+msgstr "Schriftgröße anpassen - Farbbuttons"
+
+msgid "Adjust Font Size - Messages"
+msgstr "Schriftgröße anpassen - Nachrichten"
+
+msgid "Adjust Font Size - Detail View Text"
+msgstr "Schriftgröße anpassen - Text EPG Detailanzeige"
+
+msgid "Adjust Font Size - Detail View Header"
+msgstr "Schriftgröße anpassen - Header EPG Detailanzeige"
+
+msgid "Adjust Font Size - Detail View Header Large"
+msgstr "Schriftgröße anpassen - Header Groß EPG Detailanzeige"
+
+msgid "Hight of Channel Display (Percent of OSD Height)"
+msgstr "Höhe der Kanalwechsel Anzeige (Proz. der OSD Höhe)"
+
+msgid "Left & Right Border Width"
+msgstr "Breite des linken und rechten Rands"
+
+msgid "Bottom Border Height"
+msgstr "Höhe des unteren Rands"
+
+msgid "Channel Logo Width"
+msgstr "Breite der Kanallogos"
+
+msgid "Channel Logo Height"
+msgstr "Höhe der Kanallogos"
+
+msgid "Channel Logo Border"
+msgstr "Rand um die Kanallogos"
+
+msgid "Display Signal Strength & Quality"
+msgstr "Signalstärke- und Qualität anzeigen"
+
+msgid "Screen Resolution Icon Size"
+msgstr "Größe des Icons zur Anzeige der Bildschirmauflösung"
+
+msgid "Adjust Font Size - EPG Text"
+msgstr "Schriftgröße anpassen - EPG Text"
+
+msgid "Adjust Font Size - EPG Infotext"
+msgstr "Schriftgröße anpassen - EPG Infotext"
+
+msgid "Hight of Replay Display (Percent of OSD Height)"
+msgstr "Höhe der Wiedergabe Anzeige (Proz. der OSD Höhe)"
+
+msgid "Adjust Font Size - Text"
+msgstr "Schriftgröße anpassen - Anzeigetext"
+
+msgid "Width of Tracks Display (Percent of OSD Width)"
+msgstr "Breite der Audio Tracks Anzeige (Proz. der OSD Breite)"
+
+#, fuzzy
+msgid "Hight of Tracks Display (Percent of OSD Height)"
+msgstr "Höhe der Wiedergabe Anzeige (Proz. der OSD Höhe)"
+
+msgid "Position (0: bot. center, 1: bot. left, ... , 7: bot. right)"
+msgstr "Position (0: unten mitte, 1: unten links, ... , 7: unten rechts)"
+
+msgid "Border Top / Bottom"
+msgstr "Rand oben und unten"
+
+msgid "Border Left / Right"
+msgstr "Rand links und rechts"
+
+msgid "Adjust Font Size - Buttons"
+msgstr "Schriftgröße anpassen - Buttons"
+
+msgid "Width of Message Display (Percent of OSD Height)"
+msgstr "Breite der Nachrichten Anzeige (Proz. der OSD Breite)"
+
+msgid "Hight of Message Display (Percent of OSD Height)"
+msgstr "Höhe der Nachrichten Anzeige (Proz. der OSD Höhe)"
+
+msgid "Adjust Font Size"
+msgstr "Schriftgröße anpassen"
+
+msgid "Volume Display"
+msgstr "Lautstärke Anzeige"
+
+msgid "Width of Volume Display (Percent of OSD Height)"
+msgstr "Breite der Lautstärken Anzeige (Proz. der OSD Breite)"
+
+#, fuzzy
+msgid "Hight of Volume Display (Percent of OSD Height)"
+msgstr "Breite der Lautstärken Anzeige (Proz. der OSD Breite)"
+
+msgid "Disc"
+msgstr "Festplatte"
+
+msgid "free"
+msgstr "frei"
diff --git a/setup.c b/setup.c
new file mode 100644
index 0000000..84a2479
--- /dev/null
+++ b/setup.c
@@ -0,0 +1,302 @@
+#include "setup.h"
+
+cNopacitySetup::cNopacitySetup() {
+ tmpNopacityConfig = config;
+ cFont::GetAvailableFontNames(&fontNames);
+ fontNames.Insert(strdup(config.fontDefaultName));
+ Setup();
+}
+
+cNopacitySetup::~cNopacitySetup() {
+}
+
+
+void cNopacitySetup::Setup(void) {
+ int currentItem = Current();
+ Clear();
+ Add(new cMenuEditStraItem(tr("Font"), &tmpNopacityConfig.fontIndex, fontNames.Size(), &fontNames[0]));
+ Add(new cOsdItem(tr("VDR Menu")));
+ Add(new cOsdItem(tr("Channel Switching")));
+ Add(new cOsdItem(tr("Replay")));
+ Add(new cOsdItem(tr("Audio Tracks")));
+ Add(new cOsdItem(tr("Messages")));
+ Add(new cOsdItem(tr("Volume")));
+
+ SetCurrent(Get(currentItem));
+ Display();
+}
+
+eOSState cNopacitySetup::ProcessKey(eKeys Key) {
+ bool hadSubMenu = HasSubMenu();
+ eOSState state = cMenuSetupPage::ProcessKey(Key);
+ if (hadSubMenu && Key == kOk)
+ Store();
+ if (!hadSubMenu && (state == osUnknown || Key == kOk)) {
+ if ((Key == kOk && !hadSubMenu)) {
+ const char* ItemText = Get(Current())->Text();
+ if (strcmp(ItemText, tr("VDR Menu")) == 0)
+ state = AddSubMenu(new cNopacitySetupMenuDisplay(&tmpNopacityConfig));
+ if (strcmp(ItemText, tr("Channel Switching")) == 0)
+ state = AddSubMenu(new cNopacitySetupChannelDisplay(&tmpNopacityConfig));
+ if (strcmp(ItemText, tr("Replay")) == 0)
+ state = AddSubMenu(new cNopacitySetupReplayDisplay(&tmpNopacityConfig));
+ if (strcmp(ItemText, tr("Audio Tracks")) == 0)
+ state = AddSubMenu(new cNopacitySetupTrackDisplay(&tmpNopacityConfig));
+ if (strcmp(ItemText, tr("Messages")) == 0)
+ state = AddSubMenu(new cNopacitySetupMessageDisplay(&tmpNopacityConfig));
+ if (strcmp(ItemText, tr("Volume")) == 0)
+ state = AddSubMenu(new cNopacitySetupVolumeDisplay(&tmpNopacityConfig));
+ }
+ }
+ return state;
+}
+
+void cNopacitySetup::Store(void) {
+ config = tmpNopacityConfig;
+ SetupStore("fontIndex", config.fontIndex);
+ SetupStore("channelHeight", config.channelHeight);
+ SetupStore("channelBorderVertical", config.channelBorderVertical);
+ SetupStore("channelBorderBottom", config.channelBorderBottom);
+ SetupStore("logoWidth", config.logoWidth);
+ SetupStore("logoHeight", config.logoHeight);
+ SetupStore("logoBorder", config.logoBorder);
+ SetupStore("displaySignalStrength", config.displaySignalStrength);
+ SetupStore("channelFadeTime", config.channelFadeTime);
+ SetupStore("fontChannelHeaderSize", config.fontChannelHeaderSize);
+ SetupStore("fontChannelDateSize", config.fontChannelDateSize);
+ SetupStore("fontEPGSize", config.fontEPGSize);
+ SetupStore("fontEPGSmallSize", config.fontEPGSmallSize);
+ SetupStore("resolutionIconSize", config.resolutionIconSize);
+ SetupStore("replayHeight", config.replayHeight);
+ SetupStore("replayBorderVertical", config.replayBorderVertical);
+ SetupStore("replayBorderBottom", config.replayBorderBottom);
+ SetupStore("replayFadeTime", config.replayFadeTime);
+ SetupStore("fontReplayHeader", config.fontReplayHeader);
+ SetupStore("fontReplay", config.fontReplay);
+ SetupStore("messageWidth", config.messageWidth);
+ SetupStore("messageHeight", config.messageHeight);
+ SetupStore("messageBorderBottom", config.messageBorderBottom);
+ SetupStore("fontMessage", config.fontMessage);
+ SetupStore("messageFadeTime", config.messageFadeTime);
+ SetupStore("tracksFadeTime", config.tracksFadeTime);
+ SetupStore("tracksWidth", config.tracksWidth);
+ SetupStore("tracksHeight", config.tracksHeight);
+ SetupStore("tracksPosition", config.tracksPosition);
+ SetupStore("tracksBorderHorizontal", config.tracksBorderHorizontal);
+ SetupStore("tracksBorderVertical", config.tracksBorderVertical);
+ SetupStore("fontTracksHeader", config.fontTracksHeader);
+ SetupStore("fontTracks", config.fontTracks);
+ SetupStore("volumeFadeTime", config.volumeFadeTime);
+ SetupStore("volumeWidth", config.volumeWidth);
+ SetupStore("volumeHeight", config.volumeHeight);
+ SetupStore("fontVolume", config.fontVolume);
+ SetupStore("scalePicture", config.scalePicture);
+ SetupStore("menuFadeTime", config.menuFadeTime);
+ SetupStore("menuWidthNarrow", config.menuWidthNarrow);
+ SetupStore("menuWidthRightItems", config.menuWidthRightItems);
+ SetupStore("headerHeight", config.headerHeight);
+ SetupStore("footerHeight", config.footerHeight);
+ SetupStore("numDefaultMenuItems", config.numDefaultMenuItems);
+ SetupStore("iconHeight", config.iconHeight);
+ SetupStore("headerIconHeight", config.headerIconHeight);
+ SetupStore("menuItemLogoWidth", config.menuItemLogoWidth);
+ SetupStore("menuItemLogoHeight", config.menuItemLogoHeight);
+ SetupStore("menuHeaderLogoWidth", config.menuHeaderLogoWidth);
+ SetupStore("menuHeaderLogoHeight", config.menuHeaderLogoHeight);
+ SetupStore("detailViewLogoWidth", config.detailViewLogoWidth);
+ SetupStore("detailViewLogoHeight", config.detailViewLogoHeight);
+ SetupStore("epgImageWidth", config.epgImageWidth);
+ SetupStore("epgImageHeight", config.epgImageHeight);
+ SetupStore("fontHeader", config.fontHeader);
+ SetupStore("fontDate", config.fontDate);
+ SetupStore("fontMenuitemLarge", config.fontMenuitemLarge);
+ SetupStore("fontMenuitemSchedule", config.fontMenuitemSchedule);
+ SetupStore("fontMenuitemDefault", config.fontMenuitemDefault);
+ SetupStore("fontDiskUsage", config.fontDiskUsage);
+ SetupStore("fontTimersHead", config.fontTimersHead);
+ SetupStore("fontTimers", config.fontTimers);
+ SetupStore("fontButtons", config.fontButtons);
+ SetupStore("fontMessageMenu", config.fontMessageMenu);
+ SetupStore("fontDetailView", config.fontDetailView);
+ SetupStore("fontDetailViewHeader", config.fontDetailViewHeader);
+ SetupStore("fontDetailViewHeaderLarge", config.fontDetailViewHeaderLarge);
+}
+
+//------------------------------------------------------------------------------------------------------------------
+
+cMenuSetupSubMenu::cMenuSetupSubMenu(const char* Title, cNopacityConfig* data) : cOsdMenu(Title, 30) {
+ tmpNopacityConfig = data;
+}
+
+cOsdItem *cMenuSetupSubMenu::InfoItem(const char *label, const char *value) {
+ cOsdItem *item;
+ item = new cOsdItem(cString::sprintf("%s: %s", label, value));
+ item->SetSelectable(false);
+ return item;
+}
+
+eOSState cMenuSetupSubMenu::ProcessKey(eKeys Key) {
+ eOSState state = cOsdMenu::ProcessKey(Key);
+ if (state == osUnknown) {
+ switch (Key) {
+ case kOk:
+ return osBack;
+ default:
+ break;
+ }
+ }
+ return state;
+}
+
+//-----MenuDisplay-------------------------------------------------------------------------------------------------------------
+
+cNopacitySetupMenuDisplay::cNopacitySetupMenuDisplay(cNopacityConfig* data) : cMenuSetupSubMenu(tr("VDR Menu"), data) {
+ Set();
+}
+
+void cNopacitySetupMenuDisplay::Set(void) {
+ int currentItem = Current();
+ Clear();
+ Add(new cMenuEditIntItem(tr("Fade-In Time in ms (Zero for switching off fading)"), &tmpNopacityConfig->menuFadeTime, 0, 1000));
+ Add(new cMenuEditBoolItem(tr("Scale Video size to fit into menu window"), &tmpNopacityConfig->scalePicture));
+ Add(new cMenuEditIntItem(tr("Width of narrow Menu Bar (Percent of OSD Width)"), &tmpNopacityConfig->menuWidthNarrow, 10, 100));
+ Add(new cMenuEditIntItem(tr("Width of Disc Usage and Timers Display (Percent of OSD Width)"), &tmpNopacityConfig->menuWidthRightItems, 10, 100));
+ Add(new cMenuEditIntItem(tr("Header Height (Percent of OSD Height)"), &tmpNopacityConfig->headerHeight, 0, 30));
+ Add(new cMenuEditIntItem(tr("Footer Height (Percent of OSD Height)"), &tmpNopacityConfig->footerHeight, 0, 30));
+ Add(new cMenuEditIntItem(tr("Number of Default Menu Entries per Page"), &tmpNopacityConfig->numDefaultMenuItems, 10, 40));
+ Add(new cMenuEditIntItem(tr("Icon Size (Square Main Menu Icons)"), &tmpNopacityConfig->iconHeight, 30, 200));
+ Add(new cMenuEditIntItem(tr("Header Icon Size (Square Header Menu Icons)"), &tmpNopacityConfig->headerIconHeight, 30, 200));
+ Add(new cMenuEditIntItem(tr("Channel Logo Width (on the Menu Buttons)"), &tmpNopacityConfig->menuItemLogoWidth, 30, 200));
+ Add(new cMenuEditIntItem(tr("Channel Logo Height (on the Menu Buttons)"), &tmpNopacityConfig->menuItemLogoHeight, 30, 200));
+ Add(new cMenuEditIntItem(tr("Main Menu Header Logo Width"), &tmpNopacityConfig->menuHeaderLogoWidth, 30, 500));
+ Add(new cMenuEditIntItem(tr("Main Menu Header Logo Height"), &tmpNopacityConfig->menuHeaderLogoHeight, 30, 500));
+ Add(new cMenuEditIntItem(tr("Detail EPG View Logo Width"), &tmpNopacityConfig->detailViewLogoWidth, 30, 500));
+ Add(new cMenuEditIntItem(tr("Detail EPG View Logo Height"), &tmpNopacityConfig->detailViewLogoHeight, 30, 500));
+ Add(new cMenuEditIntItem(tr("Detail EPG View EPG Image Width"), &tmpNopacityConfig->epgImageWidth, 30, 500));
+ Add(new cMenuEditIntItem(tr("Detail EPG View EPG Image Height"), &tmpNopacityConfig->epgImageHeight, 30, 500));
+ Add(new cMenuEditIntItem(tr("Adjust Font Size - Header"), &tmpNopacityConfig->fontHeader, -20, 20));
+ Add(new cMenuEditIntItem(tr("Adjust Font Size - Date"), &tmpNopacityConfig->fontDate, -20, 20));
+ Add(new cMenuEditIntItem(tr("Adjust Font Size - Large Menu Item"), &tmpNopacityConfig->fontMenuitemLarge, -20, 20));
+ Add(new cMenuEditIntItem(tr("Adjust Font Size - Schedule Menu Item"), &tmpNopacityConfig->fontMenuitemSchedule, -20, 20));
+ Add(new cMenuEditIntItem(tr("Adjust Font Size - Default Menu Item"), &tmpNopacityConfig->fontMenuitemDefault, -20, 20));
+ Add(new cMenuEditIntItem(tr("Adjust Font Size - Disc Usage"), &tmpNopacityConfig->fontDiskUsage, -20, 20));
+ Add(new cMenuEditIntItem(tr("Adjust Font Size - Timers Header"), &tmpNopacityConfig->fontTimersHead, -20, 20));
+ Add(new cMenuEditIntItem(tr("Adjust Font Size - Timers Title"), &tmpNopacityConfig->fontTimers, -20, 20));
+ Add(new cMenuEditIntItem(tr("Adjust Font Size - Color Buttons"), &tmpNopacityConfig->fontButtons, -20, 20));
+ Add(new cMenuEditIntItem(tr("Adjust Font Size - Messages"), &tmpNopacityConfig->fontMessageMenu, -20, 20));
+ Add(new cMenuEditIntItem(tr("Adjust Font Size - Detail View Text"), &tmpNopacityConfig->fontDetailView, -20, 20));
+ Add(new cMenuEditIntItem(tr("Adjust Font Size - Detail View Header"), &tmpNopacityConfig->fontDetailViewHeader, -20, 20));
+ Add(new cMenuEditIntItem(tr("Adjust Font Size - Detail View Header Large"), &tmpNopacityConfig->fontDetailViewHeaderLarge, -20, 20));
+
+ SetCurrent(Get(currentItem));
+ Display();
+}
+
+//----ChannelDisplay--------------------------------------------------------------------------------------------------------------
+
+cNopacitySetupChannelDisplay::cNopacitySetupChannelDisplay(cNopacityConfig* data) : cMenuSetupSubMenu(tr("Channel Switching"), data) {
+ Set();
+}
+
+void cNopacitySetupChannelDisplay::Set(void) {
+ int currentItem = Current();
+ Clear();
+
+ Add(new cMenuEditIntItem(tr("Fade-In Time in ms (Zero for switching off fading)"), &tmpNopacityConfig->channelFadeTime, 0, 1000));
+ Add(new cMenuEditIntItem(tr("Hight of Channel Display (Percent of OSD Height)"), &tmpNopacityConfig->channelHeight, 15, 100));
+ Add(new cMenuEditIntItem(tr("Left & Right Border Width"), &tmpNopacityConfig->channelBorderVertical, 0, 300));
+ Add(new cMenuEditIntItem(tr("Bottom Border Height"), &tmpNopacityConfig->channelBorderBottom, 0, 300));
+ Add(new cMenuEditIntItem(tr("Channel Logo Width"), &tmpNopacityConfig->logoWidth, 30, 500));
+ Add(new cMenuEditIntItem(tr("Channel Logo Height"), &tmpNopacityConfig->logoHeight, 30, 500));
+ Add(new cMenuEditIntItem(tr("Channel Logo Border"), &tmpNopacityConfig->logoBorder, 0, 200));
+ Add(new cMenuEditBoolItem(tr("Display Signal Strength & Quality"), &tmpNopacityConfig->displaySignalStrength));
+ Add(new cMenuEditIntItem(tr("Screen Resolution Icon Size"), &tmpNopacityConfig->resolutionIconSize, 30, 200));
+ Add(new cMenuEditIntItem(tr("Adjust Font Size - Header"), &tmpNopacityConfig->fontChannelHeaderSize, -20, 20));
+ Add(new cMenuEditIntItem(tr("Adjust Font Size - Date"), &tmpNopacityConfig->fontChannelDateSize, -20, 20));
+ Add(new cMenuEditIntItem(tr("Adjust Font Size - EPG Text"), &tmpNopacityConfig->fontEPGSize, -20, 20));
+ Add(new cMenuEditIntItem(tr("Adjust Font Size - EPG Infotext"), &tmpNopacityConfig->fontEPGSmallSize, -20, 20));
+ SetCurrent(Get(currentItem));
+ Display();
+}
+
+//-----ReplayDisplay-------------------------------------------------------------------------------------------------------------
+
+cNopacitySetupReplayDisplay::cNopacitySetupReplayDisplay(cNopacityConfig* data) : cMenuSetupSubMenu(tr("Replay"), data) {
+ Set();
+}
+
+void cNopacitySetupReplayDisplay::Set(void) {
+ int currentItem = Current();
+ Clear();
+
+ Add(new cMenuEditIntItem(tr("Fade-In Time in ms (Zero for switching off fading)"), &tmpNopacityConfig->replayFadeTime, 0, 1000));
+ Add(new cMenuEditIntItem(tr("Hight of Replay Display (Percent of OSD Height)"), &tmpNopacityConfig->replayHeight, 15, 100));
+ Add(new cMenuEditIntItem(tr("Left & Right Border Width"), &tmpNopacityConfig->replayBorderVertical, 0, 300));
+ Add(new cMenuEditIntItem(tr("Bottom Border Height"), &tmpNopacityConfig->replayBorderBottom, 0, 300));
+ Add(new cMenuEditIntItem(tr("Adjust Font Size - Header"), &tmpNopacityConfig->fontReplayHeader, -20, 20));
+ Add(new cMenuEditIntItem(tr("Adjust Font Size - Text"), &tmpNopacityConfig->fontReplay, -20, 20));
+
+ SetCurrent(Get(currentItem));
+ Display();
+}
+
+//-----TrackDisplay-------------------------------------------------------------------------------------------------------------
+
+cNopacitySetupTrackDisplay::cNopacitySetupTrackDisplay(cNopacityConfig* data) : cMenuSetupSubMenu(tr("Audio Tracks"), data) {
+ Set();
+}
+
+void cNopacitySetupTrackDisplay::Set(void) {
+ int currentItem = Current();
+ Clear();
+ Add(new cMenuEditIntItem(tr("Fade-In Time in ms (Zero for switching off fading)"), &tmpNopacityConfig->tracksFadeTime, 0, 1000));
+ Add(new cMenuEditIntItem(tr("Width of Tracks Display (Percent of OSD Width)"), &tmpNopacityConfig->tracksWidth, 10, 100));
+ Add(new cMenuEditIntItem(tr("Hight of Tracks Display (Percent of OSD Height)"), &tmpNopacityConfig->tracksHeight, 10, 100));
+ Add(new cMenuEditIntItem(tr("Position (0: bot. center, 1: bot. left, ... , 7: bot. right)"), &tmpNopacityConfig->tracksPosition, 0, 7));
+ Add(new cMenuEditIntItem(tr("Border Top / Bottom"), &tmpNopacityConfig->tracksBorderHorizontal, 0, 100));
+ Add(new cMenuEditIntItem(tr("Border Left / Right"), &tmpNopacityConfig->tracksBorderVertical, 0, 100));
+ Add(new cMenuEditIntItem(tr("Adjust Font Size - Header"), &tmpNopacityConfig->fontTracksHeader, -20, 20));
+ Add(new cMenuEditIntItem(tr("Adjust Font Size - Buttons"), &tmpNopacityConfig->fontTracks, -20, 20));
+
+ SetCurrent(Get(currentItem));
+ Display();
+}
+
+//-----MessageDisplay-------------------------------------------------------------------------------------------------------------
+
+cNopacitySetupMessageDisplay::cNopacitySetupMessageDisplay(cNopacityConfig* data) : cMenuSetupSubMenu(tr("Messages"), data) {
+ Set();
+}
+
+void cNopacitySetupMessageDisplay::Set(void) {
+ int currentItem = Current();
+ Clear();
+
+ Add(new cMenuEditIntItem(tr("Fade-In Time in ms (Zero for switching off fading)"), &tmpNopacityConfig->messageFadeTime, 0, 1000));
+ Add(new cMenuEditIntItem(tr("Width of Message Display (Percent of OSD Height)"), &tmpNopacityConfig->messageWidth, 30, 100));
+ Add(new cMenuEditIntItem(tr("Hight of Message Display (Percent of OSD Height)"), &tmpNopacityConfig->messageHeight, 5, 100));
+ Add(new cMenuEditIntItem(tr("Bottom Border Height"), &tmpNopacityConfig->messageBorderBottom, 0, 1000));
+ Add(new cMenuEditIntItem(tr("Adjust Font Size"), &tmpNopacityConfig->fontMessage, -30, 30));
+
+ SetCurrent(Get(currentItem));
+ Display();
+}
+
+//-----VolumeDisplay-------------------------------------------------------------------------------------------------------------
+
+cNopacitySetupVolumeDisplay::cNopacitySetupVolumeDisplay(cNopacityConfig* data) : cMenuSetupSubMenu(tr("Volume Display"), data) {
+ Set();
+}
+
+void cNopacitySetupVolumeDisplay::Set(void) {
+ int currentItem = Current();
+ Clear();
+
+ Add(new cMenuEditIntItem(tr("Fade-In Time in ms (Zero for switching off fading)"), &tmpNopacityConfig->volumeFadeTime, 0, 1000));
+ Add(new cMenuEditIntItem(tr("Width of Volume Display (Percent of OSD Height)"), &tmpNopacityConfig->volumeWidth, 10, 100));
+ Add(new cMenuEditIntItem(tr("Hight of Volume Display (Percent of OSD Height)"), &tmpNopacityConfig->volumeHeight, 5, 100));
+ Add(new cMenuEditIntItem(tr("Adjust Font Size"), &tmpNopacityConfig->fontVolume, -30, 30));
+
+ SetCurrent(Get(currentItem));
+ Display();
+} \ No newline at end of file
diff --git a/setup.h b/setup.h
new file mode 100644
index 0000000..0b36398
--- /dev/null
+++ b/setup.h
@@ -0,0 +1,70 @@
+#ifndef __NOPACITY_SETUP_H
+#define __NOPACITY_SETUP_H
+
+class cNopacitySetup : public cMenuSetupPage {
+ public:
+ cNopacitySetup(void);
+ virtual ~cNopacitySetup();
+ private:
+ cNopacityConfig tmpNopacityConfig;
+ cStringList fontNames;
+ void Setup(void);
+ protected:
+ virtual eOSState ProcessKey(eKeys Key);
+ virtual void Store(void);
+
+};
+
+
+class cMenuSetupSubMenu : public cOsdMenu {
+ protected:
+ cNopacityConfig *tmpNopacityConfig;
+ virtual eOSState ProcessKey(eKeys Key);
+ virtual void Set(void) = 0;
+ cOsdItem *InfoItem(const char *label, const char *value);
+ public:
+ cMenuSetupSubMenu(const char *Title, cNopacityConfig *data);
+};
+
+class cNopacitySetupMenuDisplay : public cMenuSetupSubMenu {
+ protected:
+ void Set(void);
+ public:
+ cNopacitySetupMenuDisplay(cNopacityConfig *data);
+};
+
+class cNopacitySetupChannelDisplay : public cMenuSetupSubMenu {
+ protected:
+ void Set(void);
+ public:
+ cNopacitySetupChannelDisplay(cNopacityConfig *data);
+};
+
+class cNopacitySetupReplayDisplay : public cMenuSetupSubMenu {
+ protected:
+ void Set(void);
+ public:
+ cNopacitySetupReplayDisplay(cNopacityConfig *data);
+};
+
+class cNopacitySetupTrackDisplay : public cMenuSetupSubMenu {
+ protected:
+ void Set(void);
+ public:
+ cNopacitySetupTrackDisplay(cNopacityConfig *data);
+};
+
+class cNopacitySetupMessageDisplay : public cMenuSetupSubMenu {
+ protected:
+ void Set(void);
+ public:
+ cNopacitySetupMessageDisplay(cNopacityConfig *data);
+};
+
+class cNopacitySetupVolumeDisplay : public cMenuSetupSubMenu {
+ protected:
+ void Set(void);
+ public:
+ cNopacitySetupVolumeDisplay(cNopacityConfig *data);
+};
+#endif //__NOPACITY_SETUP_H \ No newline at end of file
diff --git a/skinnopacity.c b/skinnopacity.c
new file mode 100644
index 0000000..79d7870
--- /dev/null
+++ b/skinnopacity.c
@@ -0,0 +1,165 @@
+/*
+ * skinopacity.c: A plugin for the Video Disk Recorder
+ *
+ * See the README file for copyright information and how to reach the author.
+ *
+ * $Id$
+ */
+#include <getopt.h>
+#include <vdr/plugin.h>
+
+#include "nopacity.c"
+
+#if defined(APIVERSNUM) && APIVERSNUM < 10730
+#error "VDR-1.7. API version or greater is required!"
+#endif
+
+
+static const char *VERSION = "0.0.3";
+static const char *DESCRIPTION = "'nOpacity' Skin";
+static const char *MAINMENUENTRY = "nOpacity";
+
+class cPluginNopacity : public cPlugin {
+private:
+public:
+ cPluginNopacity(void);
+ virtual ~cPluginNopacity();
+ virtual const char *Version(void) { return VERSION; }
+ virtual const char *Description(void) { return DESCRIPTION; }
+ virtual const char *CommandLineHelp(void);
+ virtual bool ProcessArgs(int argc, char *argv[]);
+ virtual bool Initialize(void);
+ virtual bool Start(void);
+ virtual void Stop(void);
+ virtual void Housekeeping(void);
+ virtual void MainThreadHook(void);
+ virtual cString Active(void);
+ virtual time_t WakeupTime(void);
+ virtual const char *MainMenuEntry(void) {return config.mainMenuEntry ? MAINMENUENTRY : NULL;}
+ virtual cOsdObject *MainMenuAction(void);
+ virtual cMenuSetupPage *SetupMenu(void);
+ virtual bool SetupParse(const char *Name, const char *Value);
+ virtual bool Service(const char *Id, void *Data = NULL);
+ virtual const char **SVDRPHelpPages(void);
+ virtual cString SVDRPCommand(const char *Command, const char *Option, int &ReplyCode);
+ };
+
+cPluginNopacity::cPluginNopacity(void)
+{
+}
+
+cPluginNopacity::~cPluginNopacity()
+{
+}
+
+const char *cPluginNopacity::CommandLineHelp(void)
+{
+ return
+ " -e <EPGIMAGESPATH>, --epgimages=<IMAGESPATH> Set directory where epgimages are stored\n"
+ " -i <ICONSPATH>, --iconpath=<ICONSPATH> Set directory where Menu Icons are stored\n"
+ " -l <LOGOPATH>, --logopath=<LOGOPATH> Set directory where Channel Logos are stored.\n";
+}
+
+bool cPluginNopacity::ProcessArgs(int argc, char *argv[])
+{
+ // Implement command line argument processing here if applicable.
+ static const struct option long_options[] = {
+ { "epgimages", required_argument, NULL, 'e' },
+ { "logopath", required_argument, NULL, 'l' },
+ { "iconpath", required_argument, NULL, 'i' },
+ { 0, 0, 0, 0 }
+ };
+
+ int c;
+ cString *path = NULL;
+ while ((c = getopt_long(argc, argv, "e:l:i:", long_options, NULL)) != -1) {
+ switch (c) {
+ case 'l':
+ path = new cString(optarg);
+ config.SetLogoPath(*path);
+ break;
+ case 'e':
+ path = new cString(optarg);
+ config.SetEpgImagePath(*path);
+ break;
+ case 'i':
+ path = new cString(optarg);
+ config.SetIconPath(*path);
+ break;
+ default:
+ return false;
+ }
+ if (path)
+ delete path;
+ }
+ return true;
+}
+
+bool cPluginNopacity::Initialize(void)
+{
+ return true;
+}
+
+bool cPluginNopacity::Start(void)
+{
+ if (!cOsdProvider::SupportsTrueColor()) {
+ esyslog("nopacity: No TrueColor OSD found! Aborting!");
+ return false;
+ } else
+ dsyslog("nopacity: TrueColor OSD found");
+ return new cNopacity;
+}
+
+void cPluginNopacity::Stop(void)
+{
+}
+
+void cPluginNopacity::Housekeeping(void)
+{
+}
+
+void cPluginNopacity::MainThreadHook(void)
+{
+}
+
+cString cPluginNopacity::Active(void)
+{
+ return NULL;
+}
+
+time_t cPluginNopacity::WakeupTime(void)
+{
+ return 0;
+}
+
+cOsdObject *cPluginNopacity::MainMenuAction(void)
+{
+ return NULL;
+}
+
+cMenuSetupPage *cPluginNopacity::SetupMenu(void)
+{
+ return new cNopacitySetup();
+}
+
+bool cPluginNopacity::SetupParse(const char *Name, const char *Value)
+{
+ return config.SetupParse(Name, Value);
+}
+
+bool cPluginNopacity::Service(const char *Id, void *Data)
+{
+ return false;
+}
+
+const char **cPluginNopacity::SVDRPHelpPages(void)
+{
+ return NULL;
+}
+
+cString cPluginNopacity::SVDRPCommand(const char *Command, const char *Option, int &ReplyCode)
+{
+ return NULL;
+}
+
+VDRPLUGINCREATOR(cPluginNopacity); // Don't touch this!
diff --git a/symbols/audio.xpm b/symbols/audio.xpm
new file mode 100644
index 0000000..44021ad
--- /dev/null
+++ b/symbols/audio.xpm
@@ -0,0 +1,23 @@
+/* XPM */
+static const char *const audio_xpm[] = {
+"27 18 2 1",
+". c #FFFFFF",
+"+ c #000000",
+"...........................",
+"...........................",
+"..+++++++++++++++++++++++..",
+"..+++++++++++++++++++++++..",
+"..++...................++..",
+"..++...................++..",
+"..++...++++.....++++...++..",
+"..++..++..++...++..++..++..",
+"..++.++....++.++....++.++..",
+"..++..++..++...++..++..++..",
+"..++...++++.....++++...++..",
+"..++...................++..",
+"..++...................++..",
+"..++...................++..",
+"..+++++++++++++++++++++++..",
+"..+++++++++++++++++++++++..",
+"...........................",
+"..........................."};
diff --git a/symbols/dolbydigital.xpm b/symbols/dolbydigital.xpm
new file mode 100644
index 0000000..432b476
--- /dev/null
+++ b/symbols/dolbydigital.xpm
@@ -0,0 +1,23 @@
+/* XPM */
+static const char *const dolbydigital_xpm[] = {
+"27 18 2 1",
+". c #FFFFFF",
+"+ c #000000",
+"...........................",
+"...........................",
+"..+++++++++++.+++++++++++..",
+"..++.++++++++.++++++++.++..",
+"..++...++++++.++++++...++..",
+"..++.....++++.++++.....++..",
+"..++......+++.+++......++..",
+"..++.......++.++.......++..",
+"..++.......++.++.......++..",
+"..++.......++.++.......++..",
+"..++.......++.++.......++..",
+"..++......+++.+++......++..",
+"..++.....++++.++++.....++..",
+"..++...++++++.++++++...++..",
+"..++.++++++++.++++++++.++..",
+"..+++++++++++.+++++++++++..",
+"...........................",
+"..........................."};
diff --git a/symbols/encrypted.xpm b/symbols/encrypted.xpm
new file mode 100644
index 0000000..fc3178b
--- /dev/null
+++ b/symbols/encrypted.xpm
@@ -0,0 +1,23 @@
+/* XPM */
+static const char *const encrypted_xpm[] = {
+"27 18 2 1",
+". c #FFFFFF",
+"+ c #000000",
+"...........................",
+"...........................",
+"..+++++++++++++++++++++++..",
+"..+++++++++++++++++++++++..",
+"..++...................++..",
+"..++...................++..",
+"..++............++++...++..",
+"..++...........++..++..++..",
+"..++.+++++++++++....++.++..",
+"..++.+++++++++++....++.++..",
+"..++..+++......++..++..++..",
+"..++..+++.......++++...++..",
+"..++...................++..",
+"..++...................++..",
+"..+++++++++++++++++++++++..",
+"..+++++++++++++++++++++++..",
+"...........................",
+"..........................."};
diff --git a/symbols/mute.xpm b/symbols/mute.xpm
new file mode 100644
index 0000000..90fb79c
--- /dev/null
+++ b/symbols/mute.xpm
@@ -0,0 +1,25 @@
+/* XPM */
+static const char *const mute_xpm[] = {
+"26 20 2 1",
+". c #FFFFFF",
+"+ c #000000",
+"......++.......++.......++",
+"......+++....++++......+++",
+".......+++..+++++.....+++.",
+"........+++..+.++....+++..",
+".......+.+++...++...+++...",
+".....++++.+++..++..+++....",
+"++++++++...+++....+++.....",
+"+++++++.....+++..+++......",
+"++...++......++++++.......",
+"++...++.......++++........",
+"++...++.......++++........",
+"++...++......++++++.......",
+"+++++++.....+++..+++......",
+"++++++++...+++....+++.....",
+".....++++.+++..++..+++....",
+".......+.+++...++...+++...",
+"........+++..+.++....+++..",
+".......+++..+++++.....+++.",
+"......+++....++++......+++",
+"......++.......++.......++"};
diff --git a/symbols/radio.xpm b/symbols/radio.xpm
new file mode 100644
index 0000000..a14b0a9
--- /dev/null
+++ b/symbols/radio.xpm
@@ -0,0 +1,23 @@
+/* XPM */
+static const char *const radio_xpm[] = {
+"27 18 2 1",
+". c #FFFFFF",
+"+ c #000000",
+"...........................",
+"............+++++..........",
+"............+++++++++......",
+"............+++++++++++....",
+"............+++...++++++...",
+"............+++.....++++...",
+"............+++.....+++....",
+"............+++.....++.....",
+"............+++............",
+"............+++............",
+"............+++............",
+"......+++++++++............",
+"...+++++++++++++...........",
+"..+++++++++++++++..........",
+"..+++++++++++++++..........",
+"...+++++++++++++...........",
+".....++++++++++............",
+"..........................."};
diff --git a/symbols/recording.xpm b/symbols/recording.xpm
new file mode 100644
index 0000000..155df61
--- /dev/null
+++ b/symbols/recording.xpm
@@ -0,0 +1,23 @@
+/* XPM */
+static const char *const recording_xpm[] = {
+"27 18 2 1",
+". c #FFFFFF",
+"+ c #000000",
+"...........................",
+"...........................",
+"..++++++...++++++..++++++..",
+"..+++++++.+++++++.+++++++..",
+"..++...++.++......++.......",
+"..++...++.++......++.......",
+"..++...++.++......++.......",
+"..++...++.++......++.......",
+"..++++++..+++++...++.......",
+"..++++....+++++...++.......",
+"..++.++...++......++.......",
+"..++..++..++......++.......",
+"..++...++.++......++.......",
+"..++...++.++......++.......",
+"..++...++.+++++++.+++++++..",
+"..++...++..++++++..++++++..",
+"...........................",
+"..........................."};
diff --git a/symbols/teletext.xpm b/symbols/teletext.xpm
new file mode 100644
index 0000000..345ab9e
--- /dev/null
+++ b/symbols/teletext.xpm
@@ -0,0 +1,23 @@
+/* XPM */
+static const char *const teletext_xpm[] = {
+"27 18 2 1",
+". c #FFFFFF",
+"+ c #000000",
+"...........................",
+"...........................",
+"..+++++++++++++++++++++++..",
+"..+++++++++++++++++++++++..",
+"..++...................++..",
+"..++..+++++++++++++++..++..",
+"..++..+++++++++++++++..++..",
+"..++...................++..",
+"..++..+++++++++++++++..++..",
+"..++..+++++++++++++++..++..",
+"..++...................++..",
+"..++..+++++++++++++++..++..",
+"..++..+++++++++++++++..++..",
+"..++...................++..",
+"..+++++++++++++++++++++++..",
+"..+++++++++++++++++++++++..",
+"...........................",
+"..........................."};
diff --git a/themes/nOpacity-goldblue.theme b/themes/nOpacity-goldblue.theme
new file mode 100644
index 0000000..6045974
--- /dev/null
+++ b/themes/nOpacity-goldblue.theme
@@ -0,0 +1,63 @@
+Description = Gold Blue
+clrChannelBackground = B0000000
+clrChannelBackBlend = B0003DF5
+clrChannelHead = FFFFD700
+clrChannelEPG = FFFFFFFF
+clrChannelEPGInfo = FF858585
+clrProgressBar = DD7CFC00
+clrProgressBarBack = DD858585
+clrProgressBarBlend = DD006400
+clrChannelSymbolOn = DD003DF5
+clrChannelSymbolOff = DD858585
+clrChannelRecActive = DDFF0000
+clrReplayBackground = B0000000
+clrReplayBackBlend = B0003DF5
+clrReplayHead = FFFFFFFF
+clrReplayDescription = FF858585
+clrReplayCurrentTotal = FF003DF5
+clrReplayProgressSeen = DD003DF5
+clrReplayProgressRest = DD858585
+clrReplayProgressSelected = FF000000
+clrReplayProgressMark = FF000000
+clrReplayProgressCurrent = 90FFFFFF
+clrReplayHighlightIcon = DD003DF5
+clrTracksFontHead = FF858585
+clrTracksFontButtons = FFFFFFFF
+clrVolumeFont = FF858585
+clrMenuBack = DD000000
+clrMenuBorder = DD003DF5
+clrMenuScrollBar = DD003DF5
+clrMenuScrollBarBack = 40003DF5
+clrMenuItem = EE444444
+clrMenuItemBlend = 90000000
+clrMenuItemHigh = DD000000
+clrMenuItemHighBlend = EEFFD700
+clrDiskAlert = DDFF0000
+clrMenuFontHeader = FFFFFFFF
+clrMenuFontDate = FFFFFFFF
+clrMenuFontDiscUsage = FFFFFFFF
+clrMenuFontButton = FFFFFFFF
+clrMenuFontTimers = FFFFFFFF
+clrMenuFontTimersHeader = FFFFFFFF
+clrMenuFontMessages = FFFFFFFF
+clrMenuFontDetailViewText = FFFFFFFF
+clrMenuFontDetailViewHeader = FF858585
+clrMenuFontDetailViewHeaderTitle = FF0066FF
+clrMenuFontMenuItem = FFFFFFFF
+clrMenuFontMenuItemHigh = FF000000
+clrMenuFontMenuItemTitle = FF0066FF
+clrMenuFontMenuItemSep = FF858585
+clrButtonRed = 99BB0000
+clrButtonRedBorder = FFBB0000
+clrButtonGreen = 9900BB00
+clrButtonGreenBorder = FF00BB00
+clrButtonYellow = 99BBBB00
+clrButtonYellowBorder = FFBBBB00
+clrButtonBlue = 990000BB
+clrButtonBlueBorder = FF0000BB
+clrMessageFont = FFFFFFFF
+clrMessageStatus = 900000FF
+clrMessageInfo = 90009900
+clrMessageWarning = 90BBBB00
+clrMessageError = 90BB0000
+clrMessageBlend = DD000000
diff --git a/themes/nOpacity-softblue.theme b/themes/nOpacity-softblue.theme
new file mode 100644
index 0000000..52f3cf9
--- /dev/null
+++ b/themes/nOpacity-softblue.theme
@@ -0,0 +1,63 @@
+Description = Soft Blue
+clrChannelBackground = B0000000
+clrChannelBackBlend = B0858585
+clrChannelHead = FFEEEEEE
+clrChannelEPG = FFFFFFFF
+clrChannelEPGInfo = FF858585
+clrProgressBar = DD082A43
+clrProgressBarBack = DD858585
+clrProgressBarBlend = DD80B3FF
+clrChannelSymbolOn = DD003DF5
+clrChannelSymbolOff = DD858585
+clrChannelRecActive = DDFF0000
+clrReplayBackground = B0000000
+clrReplayBackBlend = B0858585
+clrReplayHead = FFFFFFFF
+clrReplayDescription = FFBBBBBB
+clrReplayCurrentTotal = FFB6C6E0
+clrReplayProgressSeen = EEB6C6E0
+clrReplayProgressRest = CC618A9E
+clrReplayProgressSelected = FF000000
+clrReplayProgressMark = FF000000
+clrReplayProgressCurrent = 90FFFFFF
+clrReplayHighlightIcon = DDB6C6E0
+clrTracksFontHead = FF858585
+clrTracksFontButtons = FFFFFFFF
+clrVolumeFont = FF858585
+clrMenuBack = DD031B3C
+clrMenuBorder = DD135474
+clrMenuScrollBar = DD135474
+clrMenuScrollBarBack = 40135474
+clrMenuItem = EE444444
+clrMenuItemBlend = 90000000
+clrMenuItemHigh = DD618A9E
+clrMenuItemHighBlend = EE135474
+clrDiskAlert = DDFF0000
+clrMenuFontHeader = FFFFFFFF
+clrMenuFontDate = FFFFFFFF
+clrMenuFontDiscUsage = FFFFFFFF
+clrMenuFontButton = FFFFFFFF
+clrMenuFontTimers = FFFFFFFF
+clrMenuFontTimersHeader = FFFFFFFF
+clrMenuFontMessages = FFFFFFFF
+clrMenuFontDetailViewText = FFFFFFFF
+clrMenuFontDetailViewHeader = FF858585
+clrMenuFontDetailViewHeaderTitle = FFB6C6E0
+clrMenuFontMenuItem = FFFFFFFF
+clrMenuFontMenuItemHigh = FFFFFFFF
+clrMenuFontMenuItemTitle = FFB6C6E0
+clrMenuFontMenuItemSep = FF858585
+clrButtonRed = 99BB0000
+clrButtonRedBorder = FFBB0000
+clrButtonGreen = 9900BB00
+clrButtonGreenBorder = FF00BB00
+clrButtonYellow = 99BBBB00
+clrButtonYellowBorder = FFBBBB00
+clrButtonBlue = 990000BB
+clrButtonBlueBorder = FF0000BB
+clrMessageFont = FFFFFFFF
+clrMessageStatus = 900000FF
+clrMessageInfo = 90009900
+clrMessageWarning = 90BBBB00
+clrMessageError = 90BB0000
+clrMessageBlend = DD000000