diff options
-rw-r--r-- | COPYING | 340 | ||||
-rw-r--r-- | HISTORY | 48 | ||||
-rw-r--r-- | Makefile | 115 | ||||
-rw-r--r-- | README | 213 | ||||
-rw-r--r-- | config.c | 201 | ||||
-rw-r--r-- | config.h | 109 | ||||
-rw-r--r-- | displaychannel.c | 529 | ||||
-rw-r--r-- | displaychannel.h | 74 | ||||
-rw-r--r-- | displaymenu.c | 461 | ||||
-rw-r--r-- | displaymenu.h | 56 | ||||
-rw-r--r-- | displaymenuview.c | 627 | ||||
-rw-r--r-- | displaymenuview.h | 107 | ||||
-rw-r--r-- | displaymessage.c | 70 | ||||
-rw-r--r-- | displaymessage.h | 20 | ||||
-rw-r--r-- | displayreplay.c | 323 | ||||
-rw-r--r-- | displayreplay.h | 69 | ||||
-rw-r--r-- | displaytracks.c | 184 | ||||
-rw-r--r-- | displaytracks.h | 39 | ||||
-rw-r--r-- | displayvolume.c | 95 | ||||
-rw-r--r-- | displayvolume.h | 26 | ||||
-rw-r--r-- | helpers.c | 38 | ||||
-rw-r--r-- | iconTemplates/IconBorder.png | bin | 0 -> 11033 bytes | |||
-rw-r--r-- | iconTemplates/IconTemplate.xcf | bin | 0 -> 167845 bytes | |||
-rw-r--r-- | icons/Administrative Aufgaben.png | bin | 0 -> 23314 bytes | |||
-rw-r--r-- | icons/Channels.png | bin | 0 -> 20699 bytes | |||
-rw-r--r-- | icons/Channelseparator.png | bin | 0 -> 15388 bytes | |||
-rw-r--r-- | icons/Commands.png | bin | 0 -> 17893 bytes | |||
-rw-r--r-- | icons/DiskUsage.png | bin | 0 -> 24156 bytes | |||
-rw-r--r-- | icons/Recordings.png | bin | 0 -> 22050 bytes | |||
-rw-r--r-- | icons/Schedule.png | bin | 0 -> 21843 bytes | |||
-rw-r--r-- | icons/Setup.png | bin | 0 -> 20218 bytes | |||
-rw-r--r-- | icons/Timers.png | bin | 0 -> 21615 bytes | |||
-rw-r--r-- | icons/Tvguide.png | bin | 0 -> 22966 bytes | |||
-rw-r--r-- | icons/Videotext.png | bin | 0 -> 14735 bytes | |||
-rw-r--r-- | icons/daydelimiter.png | bin | 0 -> 23206 bytes | |||
-rw-r--r-- | icons/fwd.png | bin | 0 -> 18838 bytes | |||
-rw-r--r-- | icons/hd1080i.png | bin | 0 -> 6268 bytes | |||
-rw-r--r-- | icons/hd720p.png | bin | 0 -> 6105 bytes | |||
-rw-r--r-- | icons/pause.png | bin | 0 -> 15668 bytes | |||
-rw-r--r-- | icons/play.png | bin | 0 -> 17112 bytes | |||
-rw-r--r-- | icons/rew.png | bin | 0 -> 18552 bytes | |||
-rw-r--r-- | icons/sd576i.png | bin | 0 -> 6717 bytes | |||
-rw-r--r-- | icons/signal.png | bin | 0 -> 2436 bytes | |||
-rw-r--r-- | icons/tracks.png | bin | 0 -> 29537 bytes | |||
-rw-r--r-- | icons/vdrlogo.png | bin | 0 -> 10150 bytes | |||
-rw-r--r-- | icons/vdrlogo_gen2vdr.png | bin | 0 -> 22710 bytes | |||
-rw-r--r-- | imageloader.c | 157 | ||||
-rw-r--r-- | imageloader.h | 30 | ||||
-rw-r--r-- | menudetailview.c | 246 | ||||
-rw-r--r-- | menudetailview.h | 68 | ||||
-rw-r--r-- | menuitem.c | 406 | ||||
-rw-r--r-- | menuitem.h | 83 | ||||
-rw-r--r-- | nopacity.c | 169 | ||||
-rw-r--r-- | nopacity.h | 28 | ||||
-rw-r--r-- | po/de_DE.po | 211 | ||||
-rw-r--r-- | setup.c | 302 | ||||
-rw-r--r-- | setup.h | 70 | ||||
-rw-r--r-- | skinnopacity.c | 165 | ||||
-rw-r--r-- | symbols/audio.xpm | 23 | ||||
-rw-r--r-- | symbols/dolbydigital.xpm | 23 | ||||
-rw-r--r-- | symbols/encrypted.xpm | 23 | ||||
-rw-r--r-- | symbols/mute.xpm | 25 | ||||
-rw-r--r-- | symbols/radio.xpm | 23 | ||||
-rw-r--r-- | symbols/recording.xpm | 23 | ||||
-rw-r--r-- | symbols/teletext.xpm | 23 | ||||
-rw-r--r-- | themes/nOpacity-goldblue.theme | 63 | ||||
-rw-r--r-- | themes/nOpacity-softblue.theme | 63 |
67 files changed, 5968 insertions, 0 deletions
@@ -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. @@ -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 @@ -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 Binary files differnew file mode 100644 index 0000000..351c34d --- /dev/null +++ b/iconTemplates/IconBorder.png diff --git a/iconTemplates/IconTemplate.xcf b/iconTemplates/IconTemplate.xcf Binary files differnew file mode 100644 index 0000000..79d20fe --- /dev/null +++ b/iconTemplates/IconTemplate.xcf diff --git a/icons/Administrative Aufgaben.png b/icons/Administrative Aufgaben.png Binary files differnew file mode 100644 index 0000000..17f3758 --- /dev/null +++ b/icons/Administrative Aufgaben.png diff --git a/icons/Channels.png b/icons/Channels.png Binary files differnew file mode 100644 index 0000000..faf8126 --- /dev/null +++ b/icons/Channels.png diff --git a/icons/Channelseparator.png b/icons/Channelseparator.png Binary files differnew file mode 100644 index 0000000..906d35d --- /dev/null +++ b/icons/Channelseparator.png diff --git a/icons/Commands.png b/icons/Commands.png Binary files differnew file mode 100644 index 0000000..bebbe49 --- /dev/null +++ b/icons/Commands.png diff --git a/icons/DiskUsage.png b/icons/DiskUsage.png Binary files differnew file mode 100644 index 0000000..f9f8a35 --- /dev/null +++ b/icons/DiskUsage.png diff --git a/icons/Recordings.png b/icons/Recordings.png Binary files differnew file mode 100644 index 0000000..9d23ff4 --- /dev/null +++ b/icons/Recordings.png diff --git a/icons/Schedule.png b/icons/Schedule.png Binary files differnew file mode 100644 index 0000000..396bb74 --- /dev/null +++ b/icons/Schedule.png diff --git a/icons/Setup.png b/icons/Setup.png Binary files differnew file mode 100644 index 0000000..0746ae7 --- /dev/null +++ b/icons/Setup.png diff --git a/icons/Timers.png b/icons/Timers.png Binary files differnew file mode 100644 index 0000000..1d43872 --- /dev/null +++ b/icons/Timers.png diff --git a/icons/Tvguide.png b/icons/Tvguide.png Binary files differnew file mode 100644 index 0000000..6c756b2 --- /dev/null +++ b/icons/Tvguide.png diff --git a/icons/Videotext.png b/icons/Videotext.png Binary files differnew file mode 100644 index 0000000..0419706 --- /dev/null +++ b/icons/Videotext.png diff --git a/icons/daydelimiter.png b/icons/daydelimiter.png Binary files differnew file mode 100644 index 0000000..85e2640 --- /dev/null +++ b/icons/daydelimiter.png diff --git a/icons/fwd.png b/icons/fwd.png Binary files differnew file mode 100644 index 0000000..13b4751 --- /dev/null +++ b/icons/fwd.png diff --git a/icons/hd1080i.png b/icons/hd1080i.png Binary files differnew file mode 100644 index 0000000..21351ce --- /dev/null +++ b/icons/hd1080i.png diff --git a/icons/hd720p.png b/icons/hd720p.png Binary files differnew file mode 100644 index 0000000..1d91b7d --- /dev/null +++ b/icons/hd720p.png diff --git a/icons/pause.png b/icons/pause.png Binary files differnew file mode 100644 index 0000000..e6577cf --- /dev/null +++ b/icons/pause.png diff --git a/icons/play.png b/icons/play.png Binary files differnew file mode 100644 index 0000000..b0c8a18 --- /dev/null +++ b/icons/play.png diff --git a/icons/rew.png b/icons/rew.png Binary files differnew file mode 100644 index 0000000..7055823 --- /dev/null +++ b/icons/rew.png diff --git a/icons/sd576i.png b/icons/sd576i.png Binary files differnew file mode 100644 index 0000000..85c3657 --- /dev/null +++ b/icons/sd576i.png diff --git a/icons/signal.png b/icons/signal.png Binary files differnew file mode 100644 index 0000000..4f03c7a --- /dev/null +++ b/icons/signal.png diff --git a/icons/tracks.png b/icons/tracks.png Binary files differnew file mode 100644 index 0000000..cf19b7e --- /dev/null +++ b/icons/tracks.png diff --git a/icons/vdrlogo.png b/icons/vdrlogo.png Binary files differnew file mode 100644 index 0000000..33294b0 --- /dev/null +++ b/icons/vdrlogo.png diff --git a/icons/vdrlogo_gen2vdr.png b/icons/vdrlogo_gen2vdr.png Binary files differnew file mode 100644 index 0000000..3abbd2f --- /dev/null +++ b/icons/vdrlogo_gen2vdr.png 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" @@ -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 @@ -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 |