mirror of
https://projects.vdr-developer.org/git/vdr-plugin-tvguide.git
synced 2023-10-05 15:01:48 +02:00
Initial push tvguide 0.0.1
This commit is contained in:
commit
47c3fea545
340
COPYING
Normal file
340
COPYING
Normal file
@ -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.
|
6
HISTORY
Normal file
6
HISTORY
Normal file
@ -0,0 +1,6 @@
|
||||
VDR Plugin 'tvguide' Revision History
|
||||
-------------------------------------
|
||||
|
||||
2012-08-12: Version 0.0.1
|
||||
|
||||
- Initial revision.
|
122
Makefile
Normal file
122
Makefile
Normal file
@ -0,0 +1,122 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
PLUGIN = tvguide
|
||||
|
||||
### 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 directory environment:
|
||||
|
||||
# Use package data if installed...otherwise assume we're under the VDR source directory:
|
||||
PKGCFG = $(if $(VDRDIR),$(shell pkg-config --variable=$(1) $(VDRDIR)/vdr.pc),$(shell pkg-config --variable=$(1) vdr || pkg-config --variable=$(1) ../../../vdr.pc))
|
||||
LIBDIR = $(DESTDIR)$(call PKGCFG,libdir)
|
||||
LOCDIR = $(DESTDIR)$(call PKGCFG,locdir)
|
||||
PLGCFG = $(call PKGCFG,plgcfg)
|
||||
CONFDIR= $(DESTDIR)$(call PKGCFG,configdir)
|
||||
TMPDIR ?= /tmp
|
||||
|
||||
### The compiler options:
|
||||
export CFLAGS = $(call PKGCFG,cflags)
|
||||
export CXXFLAGS = $(call PKGCFG,cxxflags)
|
||||
|
||||
### Allow user defined options to overwrite defaults:
|
||||
-include $(PLGCFG)
|
||||
|
||||
APIVERSION = $(call PKGCFG,apiversion)
|
||||
|
||||
### The name of the distribution archive:
|
||||
|
||||
ARCHIVE = $(PLUGIN)-$(VERSION)
|
||||
PACKAGE = vdr-$(ARCHIVE)
|
||||
|
||||
### The name of the shared object file:
|
||||
|
||||
SOFILE = libvdr-$(PLUGIN).so
|
||||
|
||||
### Includes and Defines (add further entries here):
|
||||
|
||||
INCLUDES +=
|
||||
INCLUDES += -I/usr/include/ImageMagick
|
||||
|
||||
DEFINES += -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
|
||||
|
||||
### The object files (add further files here):
|
||||
|
||||
OBJS = $(PLUGIN).o
|
||||
|
||||
### The main target:
|
||||
|
||||
all: $(SOFILE) 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
|
||||
I18Npo = $(wildcard $(PODIR)/*.po)
|
||||
I18Nmo = $(addsuffix .mo, $(foreach file, $(I18Npo), $(basename $(file))))
|
||||
I18Nmsgs = $(addprefix $(LOCDIR)/, $(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 $@ `ls $^`
|
||||
|
||||
%.po: $(I18Npot)
|
||||
msgmerge -U --no-wrap --no-location --backup=none -q -N $@ $<
|
||||
@touch $@
|
||||
|
||||
$(I18Nmsgs): $(LOCDIR)/%/LC_MESSAGES/vdr-$(PLUGIN).mo: $(PODIR)/%.mo
|
||||
install -D -m644 $< $@
|
||||
|
||||
.PHONY: i18n
|
||||
i18n: $(I18Nmo) $(I18Npot)
|
||||
|
||||
install-i18n: $(I18Nmsgs)
|
||||
|
||||
### Targets:
|
||||
$(SOFILE): $(OBJS)
|
||||
$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -lMagick++ -o $@
|
||||
|
||||
install-lib: $(SOFILE)
|
||||
install -D $^ $(LIBDIR)/$^.$(APIVERSION)
|
||||
|
||||
install-themes:
|
||||
@mkdir -p $(CONFDIR)/themes
|
||||
cp themes/* $(CONFDIR)/themes
|
||||
|
||||
install: install-lib install-i18n install-themes
|
||||
|
||||
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 $(PODIR)/*.mo $(PODIR)/*.pot
|
||||
@-rm -f $(OBJS) $(DEPFILE) *.so *.tgz core* *~
|
115
Makefile-smaller-VDR1.7.34
Normal file
115
Makefile-smaller-VDR1.7.34
Normal file
@ -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 = tvguide
|
||||
|
||||
### 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 -Woverloaded-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
|
132
README
Normal file
132
README
Normal file
@ -0,0 +1,132 @@
|
||||
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.17 (TrueColor OSD is mandatorily needed)
|
||||
|
||||
- Installed ImageMagick for showing png/jpg Channel Logos and EPG Images
|
||||
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
"TvGuide" is a highly customizable 2D EPG viewer plugin.
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
After "normal" Plugin installation copy the themes from
|
||||
|
||||
/put/your/path/here/VDR/PLUGINS/src/tvguide/themes/
|
||||
|
||||
to
|
||||
|
||||
VDRCONF/themes/
|
||||
|
||||
Options
|
||||
-------
|
||||
|
||||
-l path, --logodir=path
|
||||
Path to the logos (Default: <vdrconfdir>/plugins/tvguide/channellogos/).
|
||||
|
||||
-i path, --epgimages=path
|
||||
Path to the epgimages (Default: <vdrconfdir>/plugins/tvguide/epgimages/).
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
Remote Control Keys:
|
||||
|
||||
Up/Down/Left/Right: Navigation in the EPG grid
|
||||
Ok: Detailed EPG View of the selected grid
|
||||
2nd Ok closes the detailed view
|
||||
Red: Set recording timer for the currently selected grid
|
||||
Green / Yellow: Jump (default) five channels back / forward
|
||||
Blue: Switch to currently selected channel
|
||||
1 / 3: Big jump (default 3h) back / forward in time
|
||||
4 / 6: huge jump (default 24h) back / forward in time
|
||||
7 / 9: jump to previous / next prime time (8pm)
|
||||
Exit: closes plugin
|
||||
|
||||
|
||||
Setup Options
|
||||
-------------
|
||||
|
||||
* General:
|
||||
|
||||
- Number of Channels / Columns:
|
||||
Number of columns per screen (max. 8)
|
||||
Keep in mind that the True Color OSD displays 64 Pixmaps in maximum, and each EPG
|
||||
entry is a dedicated Pixmap. So if this value is too large, maybe not all EPG
|
||||
information is shown on the screen.
|
||||
|
||||
- Channel Jump (Keys Green / Yellow):
|
||||
Number of channels to jump back / forward, counted from the currently selected
|
||||
channel (channel to which the selected EPG entry belongs)
|
||||
|
||||
- Time to display vertically in minutes
|
||||
With this value the number of minutes per screen is determinated. The value is
|
||||
an approximately value, because rounded values are used during calculation.
|
||||
int((OSD Height - Header Height - Footer Height) / value)
|
||||
--> Number of Pixel for one minute
|
||||
|
||||
- Big Step (Keys 1 / 3) in hours
|
||||
Hours to jump vertically with keys 1 / 3
|
||||
|
||||
- Huge Step (Keys 4 / 6) in hours
|
||||
Hours to jump vertically with keys 4 / 6
|
||||
|
||||
- Time Format (12h/24h)
|
||||
Switching between 12h and 24h time format
|
||||
|
||||
* Screen Layout:
|
||||
|
||||
- Theme
|
||||
Used Theme, theme files have to be placed accordingly
|
||||
|
||||
- Width of left Time Column
|
||||
Width of almost left column in Pixel
|
||||
|
||||
- Height of Header (Channel Logos)
|
||||
Height of header row in Pixel
|
||||
|
||||
- Height of Footer (Buttons)
|
||||
Height of footer with color buttons in Pixel
|
||||
|
||||
- Show Channel Logos
|
||||
show / hide channel logos, if logos are shown:
|
||||
- Logo Extension
|
||||
jpg / png
|
||||
- Logo width
|
||||
in Pixel
|
||||
- Logo height
|
||||
in Pixel
|
||||
|
||||
- Show EPG Images
|
||||
show / hide EPG images, if images are shown:
|
||||
- EPG Image width
|
||||
in Pixel
|
||||
- EPG Image height
|
||||
in Pixel
|
||||
|
||||
* Fonts and Fontsizes:
|
||||
|
||||
- Font:
|
||||
Used Font, all Fonts installed on your system are shown
|
||||
- various font sizes:
|
||||
Size in Pixel used for described purpose
|
||||
|
274
channelcolumn.c
Normal file
274
channelcolumn.c
Normal file
@ -0,0 +1,274 @@
|
||||
#include "channelcolumn.h"
|
||||
|
||||
cChannelColumn::cChannelColumn(int num, cChannel *channel, cMyTime *myTime) {
|
||||
this->channel = channel;
|
||||
this->num = num;
|
||||
this->myTime = myTime;
|
||||
hasTimer = channel->HasTimer();
|
||||
}
|
||||
|
||||
cChannelColumn::~cChannelColumn(void) {
|
||||
grids.Clear();
|
||||
}
|
||||
|
||||
void cChannelColumn::clearGrids() {
|
||||
grids.Clear();
|
||||
}
|
||||
|
||||
void cChannelColumn::createHeader() {
|
||||
color = theme.Color(clrHeader);
|
||||
colorBlending = theme.Color(clrHeaderBlending);
|
||||
caller = cString::sprintf("channelcolumn %s", channel->Name());
|
||||
pixmap = osdManager.requestPixmap(2, cRect(tvguideConfig.timeColWidth + num*tvguideConfig.colWidth, 0, tvguideConfig.colWidth, tvguideConfig.headerHeight),
|
||||
cRect::Null, *caller);
|
||||
if (!pixmap) {
|
||||
return;
|
||||
}
|
||||
drawBackground();
|
||||
cTextWrapper tw;
|
||||
cString headerText = cString::sprintf("%d - %s", channel->Number(), channel->Name());
|
||||
tw.Set(*headerText, tvguideConfig.FontHeader, tvguideConfig.colWidth - 8);
|
||||
int lines = tw.Lines();
|
||||
int lineHeight = tvguideConfig.FontHeader->Height();
|
||||
int yStart = (tvguideConfig.headerHeight - lines*lineHeight)/2 + 8;
|
||||
|
||||
if (!tvguideConfig.hideChannelLogos) {
|
||||
cImageLoader imgLoader;
|
||||
if (imgLoader.LoadLogo(channel->Name())) {
|
||||
cImage logo = imgLoader.GetImage();
|
||||
int logoX = (tvguideConfig.colWidth - tvguideConfig.logoWidth)/2;
|
||||
pixmap->DrawImage(cPoint(logoX, 5), logo);
|
||||
}
|
||||
yStart = tvguideConfig.logoHeight + 8;
|
||||
}
|
||||
for (int i=0; i<lines; i++) {
|
||||
int textWidth = tvguideConfig.FontHeader->Width(tw.GetLine(i));
|
||||
int xText = (tvguideConfig.colWidth - textWidth) / 2;
|
||||
if (xText < 0)
|
||||
xText = 0;
|
||||
pixmap->DrawText(cPoint(xText, yStart + i*lineHeight), tw.GetLine(i), theme.Color(clrFontHeader), clrTransparent, tvguideConfig.FontHeader);
|
||||
}
|
||||
drawBorder();
|
||||
}
|
||||
|
||||
void cChannelColumn::drawHeader() {
|
||||
pixmap->SetViewPort(cRect(tvguideConfig.timeColWidth + num*tvguideConfig.colWidth, 0, tvguideConfig.colWidth, tvguideConfig.headerHeight));
|
||||
}
|
||||
|
||||
bool cChannelColumn::readGrids() {
|
||||
schedules = cSchedules::Schedules(schedulesLock);
|
||||
const cSchedule *Schedule = NULL;
|
||||
Schedule = schedules->GetSchedule(channel);
|
||||
if (!Schedule) {
|
||||
return false;
|
||||
}
|
||||
bool eventFound = false;
|
||||
const cEvent *event = Schedule->GetEventAround(myTime->GetStart());
|
||||
if (event != NULL) {
|
||||
eventFound = true;
|
||||
} else {
|
||||
for (int i=1; i<6; i++) {
|
||||
event = Schedule->GetEventAround(myTime->GetStart()+i*5*60);
|
||||
if (event) {
|
||||
eventFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (eventFound) {
|
||||
bool col = true;
|
||||
for (; event; event = Schedule->Events()->Next(event)) {
|
||||
cEpgGrid *grid = new cEpgGrid(this, event);
|
||||
grid->setText();
|
||||
grid->SetColor(col);
|
||||
col = !col;
|
||||
grids.Add(grid);
|
||||
if (event->EndTime() > myTime->GetStop()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void cChannelColumn::drawGrids() {
|
||||
for (cEpgGrid *grid = grids.First(); grid; grid = grids.Next(grid)) {
|
||||
grid->SetViewportHeight();
|
||||
grid->PositionPixmap();
|
||||
grid->Draw();
|
||||
}
|
||||
}
|
||||
|
||||
int cChannelColumn::getX() {
|
||||
return tvguideConfig.timeColWidth + num*tvguideConfig.colWidth;
|
||||
}
|
||||
|
||||
cEpgGrid * cChannelColumn::getActive() {
|
||||
cMyTime t;
|
||||
t.Now();
|
||||
for (cEpgGrid *grid = grids.First(); grid; grid = grids.Next(grid)) {
|
||||
if (grid->isActiveInitial(t.Get()))
|
||||
return grid;
|
||||
}
|
||||
return grids.First();
|
||||
}
|
||||
|
||||
cEpgGrid * cChannelColumn::getNext(cEpgGrid *activeGrid) {
|
||||
if (activeGrid == NULL)
|
||||
return NULL;
|
||||
cEpgGrid *next = grids.Next(activeGrid);
|
||||
if (next)
|
||||
return next;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cEpgGrid * cChannelColumn::getPrev(cEpgGrid *activeGrid) {
|
||||
if (activeGrid == NULL)
|
||||
return NULL;
|
||||
cEpgGrid *prev = grids.Prev(activeGrid);
|
||||
if (prev)
|
||||
return prev;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cEpgGrid * cChannelColumn::getNeighbor(cEpgGrid *activeGrid) {
|
||||
if (!activeGrid)
|
||||
return NULL;
|
||||
cEpgGrid *neighbor = NULL;
|
||||
int overlap = 0;
|
||||
int overlapNew = 0;
|
||||
cEpgGrid *grid = NULL;
|
||||
grid = grids.First();
|
||||
if (grid) {
|
||||
for (; grid; grid = grids.Next(grid)) {
|
||||
if ( (grid->StartTime() == activeGrid->StartTime()) ) {
|
||||
neighbor = grid;
|
||||
break;
|
||||
}
|
||||
overlapNew = activeGrid->calcOverlap(grid);
|
||||
if (overlapNew > overlap) {
|
||||
neighbor = grid;
|
||||
overlap = overlapNew;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!neighbor)
|
||||
neighbor = grids.First();
|
||||
return neighbor;
|
||||
}
|
||||
|
||||
void cChannelColumn::AddNewGridsAtStart() {
|
||||
cEpgGrid *firstGrid = NULL;
|
||||
firstGrid = grids.First();
|
||||
if (firstGrid == NULL) {
|
||||
//no epg, completely new.
|
||||
schedules = cSchedules::Schedules(schedulesLock);
|
||||
const cSchedule *Schedule = NULL;
|
||||
Schedule = schedules->GetSchedule(channel);
|
||||
if (!Schedule)
|
||||
return;
|
||||
const cEvent *event = Schedule->GetEventAround(myTime->GetStart());
|
||||
if (!event)
|
||||
return;
|
||||
cEpgGrid *grid = new cEpgGrid(this, event);
|
||||
grid->setText();
|
||||
grid->SetColor(true);
|
||||
grids.Ins(grid, grids.First());
|
||||
return;
|
||||
} else {
|
||||
//if first event is long enough, nothing to do.
|
||||
if (firstGrid->StartTime() <= myTime->GetStart()) {
|
||||
return;
|
||||
}
|
||||
//if not, i have to add new ones to the list
|
||||
schedules = cSchedules::Schedules(schedulesLock);
|
||||
const cSchedule *Schedule = NULL;
|
||||
Schedule = schedules->GetSchedule(channel);
|
||||
if (!Schedule)
|
||||
return;
|
||||
bool col = !(firstGrid->IsColor1());
|
||||
for (const cEvent *event = Schedule->GetEventAround(firstGrid->StartTime()-60); event; event = Schedule->Events()->Prev(event)) {
|
||||
if (!event)
|
||||
return;
|
||||
cEpgGrid *grid = new cEpgGrid(this, event);
|
||||
grid->setText();
|
||||
grid->SetColor(col);
|
||||
col = !col;
|
||||
grids.Ins(grid, firstGrid);
|
||||
firstGrid = grid;
|
||||
if (event->StartTime() <= myTime->GetStart()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cChannelColumn::AddNewGridsAtEnd() {
|
||||
cEpgGrid *lastGrid = NULL;
|
||||
lastGrid = grids.Last();
|
||||
if (lastGrid == NULL)
|
||||
return;
|
||||
//if last event is long enough, nothing to do.
|
||||
if (lastGrid->EndTime() > myTime->GetStop()) {
|
||||
return;
|
||||
}
|
||||
//if not, i have to add new ones to the list
|
||||
schedules = cSchedules::Schedules(schedulesLock);
|
||||
const cSchedule *Schedule = NULL;
|
||||
Schedule = schedules->GetSchedule(channel);
|
||||
if (!Schedule)
|
||||
return;
|
||||
bool col = !(lastGrid->IsColor1());
|
||||
for (const cEvent *event = Schedule->GetEventAround(lastGrid->EndTime()+60); event; event = Schedule->Events()->Next(event)) {
|
||||
if (!event)
|
||||
return;
|
||||
cEpgGrid *grid = new cEpgGrid(this, event);
|
||||
grid->setText();
|
||||
grid->SetColor(col);
|
||||
col = !col;
|
||||
grids.Add(grid);
|
||||
if (event->EndTime() > myTime->GetStop()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cChannelColumn::ClearOutdatedStart() {
|
||||
bool goOn = true;
|
||||
cEpgGrid *firstGrid = NULL;
|
||||
while (goOn) {
|
||||
firstGrid = grids.First();
|
||||
if ((firstGrid != NULL)&&(firstGrid->EndTime() < myTime->GetStart())) {
|
||||
grids.Del(firstGrid);
|
||||
firstGrid = NULL;
|
||||
} else {
|
||||
goOn = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cChannelColumn::ClearOutdatedEnd() {
|
||||
bool goOn = true;
|
||||
cEpgGrid *lastGrid = NULL;
|
||||
while (goOn) {
|
||||
lastGrid = grids.Last();
|
||||
if ((lastGrid != NULL)&&(lastGrid->StartTime() > myTime->GetStop())) {
|
||||
grids.Del(lastGrid);
|
||||
lastGrid = NULL;
|
||||
} else {
|
||||
goOn = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cChannelColumn::dumpGrids() {
|
||||
esyslog("------Channel %s ---------", channel->Name());
|
||||
|
||||
for (cEpgGrid *grid = grids.First(); grid; grid = grids.Next(grid)) {
|
||||
grid->debug();
|
||||
}
|
||||
|
||||
}
|
41
channelcolumn.h
Normal file
41
channelcolumn.h
Normal file
@ -0,0 +1,41 @@
|
||||
#ifndef __TVGUIDE_CHANNELCOLUMN_H
|
||||
#define __TVGUIDE_CHANNELCOLUMN_H
|
||||
|
||||
class cEpgGrid;
|
||||
// --- cChannelColumn -------------------------------------------------------------
|
||||
|
||||
class cChannelColumn : public cListObject, public cStyledPixmap {
|
||||
friend class cEpgGrid;
|
||||
private:
|
||||
cMyTime *myTime;
|
||||
int num;
|
||||
cChannel *channel;
|
||||
cList<cEpgGrid> grids;
|
||||
cSchedulesLock schedulesLock;
|
||||
const cSchedules *schedules;
|
||||
bool hasTimer;
|
||||
public:
|
||||
cChannelColumn(int num, cChannel *channel, cMyTime *myTime);
|
||||
virtual ~cChannelColumn(void);
|
||||
void createHeader();
|
||||
void drawHeader();
|
||||
bool readGrids();
|
||||
void drawGrids();
|
||||
int getX();
|
||||
cChannel * getChannel() {return channel;}
|
||||
cEpgGrid * getActive();
|
||||
cEpgGrid * getNext(cEpgGrid *activeGrid);
|
||||
cEpgGrid * getPrev(cEpgGrid *activeGrid);
|
||||
cEpgGrid * getNeighbor(cEpgGrid *activeGrid);
|
||||
void AddNewGridsAtStart();
|
||||
void AddNewGridsAtEnd();
|
||||
void ClearOutdatedStart();
|
||||
void ClearOutdatedEnd();
|
||||
int GetNum() {return num;};
|
||||
void SetNum(int num) {this->num = num;};
|
||||
void setTimer() {hasTimer = true;};
|
||||
void clearGrids();
|
||||
void dumpGrids();
|
||||
};
|
||||
|
||||
#endif //__TVGUIDE_CHANNELCOLUMN_H
|
176
config.c
Normal file
176
config.c
Normal file
@ -0,0 +1,176 @@
|
||||
#include "config.h"
|
||||
|
||||
enum {
|
||||
e12Hours,
|
||||
e24Hours
|
||||
};
|
||||
|
||||
cTvguideConfig::cTvguideConfig() {
|
||||
osdWidth = 0;
|
||||
osdHeight = 0;
|
||||
colWidth = 0;
|
||||
channelCols = 5;
|
||||
displayTime = 160;
|
||||
minuteHeight = 0;
|
||||
timeColWidth = 120;
|
||||
headerHeight = 120;
|
||||
footerHeight = 80;
|
||||
stepMinutes = 30;
|
||||
bigStepHours = 3;
|
||||
hugeStepHours = 24;
|
||||
jumpChannels = 5;
|
||||
hideChannelLogos = 0;
|
||||
logoWidth = 130;
|
||||
logoHeight = 73;
|
||||
logoExtension = 0;
|
||||
hideEpgImages = 0;
|
||||
epgImageWidth = 315;
|
||||
epgImageHeight = 240;
|
||||
fontIndex = 0;
|
||||
fontNameDefault = "VDRSymbols Sans:Book";
|
||||
fontHeaderSize = 33;
|
||||
fontGridSize = 27;
|
||||
fontGridSmallSize = 24;
|
||||
fontTimeLineWeekdaySize = 40;
|
||||
fontTimeLineDateSize = 33;
|
||||
fontTimeLineTimeSize = 0;
|
||||
fontTimeLineTimeSizeDef12 = 24;
|
||||
fontTimeLineTimeSizeDef24 = 33;
|
||||
fontButtonSize = 33;
|
||||
fontDetailViewSize = 33;
|
||||
fontDetailHeaderSize = 40;
|
||||
fontMessageBoxSize = 33;
|
||||
fontMessageBoxLargeSize = 40;
|
||||
|
||||
|
||||
FontHeader = NULL;
|
||||
FontGrid = NULL;
|
||||
FontGridSmall = NULL;
|
||||
FontTimeLineWeekday = NULL;
|
||||
FontTimeLineDate = NULL;
|
||||
FontTimeLineTime = NULL;
|
||||
FontButton = NULL;
|
||||
FontDetailView = NULL;
|
||||
FontDetailHeader = NULL;
|
||||
FontMessageBox = NULL;
|
||||
FontMessageBoxLarge = NULL;
|
||||
|
||||
timeFormat = 1;
|
||||
themeIndex = 0;
|
||||
useBlending = 1;
|
||||
roundedCorners = 0;
|
||||
}
|
||||
|
||||
cTvguideConfig::~cTvguideConfig() {
|
||||
delete FontHeader;
|
||||
delete FontGrid;
|
||||
delete FontGridSmall;
|
||||
delete FontTimeLineWeekday;
|
||||
delete FontTimeLineDate;
|
||||
delete FontTimeLineTime;
|
||||
delete FontButton;
|
||||
delete FontDetailView;
|
||||
delete FontDetailHeader;
|
||||
delete FontMessageBox;
|
||||
delete FontMessageBoxLarge;
|
||||
}
|
||||
|
||||
void cTvguideConfig::setDynamicValues(int width, int height) {
|
||||
osdWidth = width;
|
||||
osdHeight = height;
|
||||
colWidth = (osdWidth - timeColWidth) / channelCols;
|
||||
minuteHeight = (osdHeight - headerHeight - footerHeight) / displayTime;
|
||||
|
||||
if (!fontTimeLineTimeSize) {
|
||||
if (timeFormat == e12Hours) {
|
||||
fontTimeLineTimeSize = fontTimeLineTimeSizeDef12;
|
||||
} else if (timeFormat == e24Hours) {
|
||||
fontTimeLineTimeSize = fontTimeLineTimeSizeDef24;
|
||||
}
|
||||
} else if ((fontTimeLineTimeSize == fontTimeLineTimeSizeDef12) && (timeFormat == e24Hours)) {
|
||||
fontTimeLineTimeSize = fontTimeLineTimeSizeDef24;
|
||||
} else if ((fontTimeLineTimeSize == fontTimeLineTimeSizeDef24) && (timeFormat == e12Hours)) {
|
||||
fontTimeLineTimeSize = fontTimeLineTimeSizeDef12;
|
||||
}
|
||||
cString fontname;
|
||||
if (fontIndex == 0) {
|
||||
fontname = fontNameDefault;
|
||||
} else {
|
||||
cStringList availableFonts;
|
||||
cFont::GetAvailableFontNames(&availableFonts);
|
||||
if (availableFonts[fontIndex-1]) {
|
||||
fontname = availableFonts[fontIndex-1];
|
||||
} else
|
||||
fontname = fontNameDefault;
|
||||
}
|
||||
cFont *test = NULL;
|
||||
test = cFont::CreateFont(*fontname, fontHeaderSize);
|
||||
if (!test) {
|
||||
fontname = DefaultFontSml;
|
||||
}
|
||||
delete test;
|
||||
FontHeader = cFont::CreateFont(*fontname, fontHeaderSize);
|
||||
FontGrid = cFont::CreateFont(*fontname, fontGridSize);
|
||||
FontGridSmall = cFont::CreateFont(*fontname, fontGridSmallSize);
|
||||
FontTimeLineWeekday = cFont::CreateFont(*fontname, fontTimeLineWeekdaySize);
|
||||
FontTimeLineDate = cFont::CreateFont(*fontname, fontTimeLineDateSize);
|
||||
FontTimeLineTime = cFont::CreateFont(*fontname, fontTimeLineTimeSize);
|
||||
FontButton = cFont::CreateFont(*fontname, fontButtonSize);
|
||||
FontDetailView = cFont::CreateFont(*fontname, fontDetailViewSize);
|
||||
FontDetailHeader = cFont::CreateFont(*fontname, fontDetailHeaderSize);
|
||||
FontMessageBox = cFont::CreateFont(*fontname, fontMessageBoxSize);
|
||||
FontMessageBoxLarge = cFont::CreateFont(*fontname, fontMessageBoxLargeSize);
|
||||
}
|
||||
|
||||
void cTvguideConfig::SetLogoPath(cString path) {
|
||||
logoPath = path;
|
||||
}
|
||||
|
||||
void cTvguideConfig::SetImagesPath(cString path) {
|
||||
epgImagePath = path;
|
||||
}
|
||||
|
||||
void cTvguideConfig::loadTheme() {
|
||||
cThemes themes;
|
||||
themes.Load(*cString("tvguide"));
|
||||
const char *FileName = themes.FileName(themeIndex);
|
||||
if (access(FileName, F_OK) == 0) {
|
||||
::theme.Load(FileName);
|
||||
}
|
||||
}
|
||||
|
||||
bool cTvguideConfig::SetupParse(const char *Name, const char *Value) {
|
||||
if (strcmp(Name, "timeFormat") == 0) timeFormat = atoi(Value);
|
||||
else if (strcmp(Name, "themeIndex") == 0) themeIndex = atoi(Value);
|
||||
else if (strcmp(Name, "useBlending") == 0) useBlending = atoi(Value);
|
||||
else if (strcmp(Name, "roundedCorners") == 0) roundedCorners = atoi(Value);
|
||||
else if (strcmp(Name, "channelCols") == 0) channelCols = atoi(Value);
|
||||
else if (strcmp(Name, "displayTime") == 0) displayTime = atoi(Value);
|
||||
else if (strcmp(Name, "hideChannelLogos") == 0) hideChannelLogos = atoi(Value);
|
||||
else if (strcmp(Name, "logoExtension") == 0) logoExtension = atoi(Value);
|
||||
else if (strcmp(Name, "logoWidth") == 0) logoWidth = atoi(Value);
|
||||
else if (strcmp(Name, "logoHeight") == 0) logoHeight = atoi(Value);
|
||||
else if (strcmp(Name, "bigStepHours") == 0) bigStepHours = atoi(Value);
|
||||
else if (strcmp(Name, "hugeStepHours") == 0) hugeStepHours = atoi(Value);
|
||||
else if (strcmp(Name, "jumpChannels") == 0) jumpChannels = atoi(Value);
|
||||
else if (strcmp(Name, "hideEpgImages") == 0) hideEpgImages = atoi(Value);
|
||||
else if (strcmp(Name, "epgImageWidth") == 0) epgImageWidth = atoi(Value);
|
||||
else if (strcmp(Name, "epgImageHeight") == 0) epgImageHeight = atoi(Value);
|
||||
else if (strcmp(Name, "timeColWidth") == 0) timeColWidth = atoi(Value);
|
||||
else if (strcmp(Name, "headerHeight") == 0) headerHeight = atoi(Value);
|
||||
else if (strcmp(Name, "footerHeight") == 0) footerHeight = atoi(Value);
|
||||
else if (strcmp(Name, "fontIndex") == 0) fontIndex = atoi(Value);
|
||||
else if (strcmp(Name, "fontHeaderSize") == 0) fontHeaderSize = atoi(Value);
|
||||
else if (strcmp(Name, "fontGridSize") == 0) fontGridSize = atoi(Value);
|
||||
else if (strcmp(Name, "fontGridSmallSize") == 0) fontGridSmallSize = atoi(Value);
|
||||
else if (strcmp(Name, "fontTimeLineWeekdaySize") == 0) fontTimeLineWeekdaySize = atoi(Value);
|
||||
else if (strcmp(Name, "fontTimeLineDateSize") == 0) fontTimeLineDateSize = atoi(Value);
|
||||
else if (strcmp(Name, "fontTimeLineTimeSize") == 0) fontTimeLineTimeSize = atoi(Value);
|
||||
else if (strcmp(Name, "fontButtonSize") == 0) fontButtonSize = atoi(Value);
|
||||
else if (strcmp(Name, "fontDetailViewSize") == 0) fontDetailViewSize = atoi(Value);
|
||||
else if (strcmp(Name, "fontDetailHeaderSize") == 0) fontDetailHeaderSize = atoi(Value);
|
||||
else if (strcmp(Name, "fontMessageBoxSize") == 0) fontMessageBoxSize = atoi(Value);
|
||||
else if (strcmp(Name, "fontMessageBoxLargeSize") == 0) fontMessageBoxLargeSize = atoi(Value);
|
||||
else return false;
|
||||
return true;
|
||||
}
|
67
config.h
Normal file
67
config.h
Normal file
@ -0,0 +1,67 @@
|
||||
#ifndef __TVGUIDE_CONFIG_H
|
||||
#define __TVGUIDE_CONFIG_H
|
||||
|
||||
class cTvguideConfig {
|
||||
public:
|
||||
cTvguideConfig();
|
||||
~cTvguideConfig();
|
||||
void SetLogoPath(cString path);
|
||||
void SetImagesPath(cString path);
|
||||
int osdWidth;
|
||||
int osdHeight;
|
||||
int colWidth;
|
||||
int channelCols;
|
||||
int displayTime;
|
||||
int minuteHeight;
|
||||
int timeColWidth;
|
||||
int headerHeight;
|
||||
int footerHeight;
|
||||
int stepMinutes;
|
||||
int bigStepHours;
|
||||
int hugeStepHours;
|
||||
int jumpChannels;
|
||||
int hideChannelLogos;
|
||||
int logoWidth;
|
||||
int logoHeight;
|
||||
cString logoPath;
|
||||
int logoExtension;
|
||||
int hideEpgImages;
|
||||
int epgImageWidth;
|
||||
int epgImageHeight;
|
||||
cString epgImagePath;
|
||||
int fontIndex;
|
||||
const char *fontNameDefault;
|
||||
int fontHeaderSize;
|
||||
int fontGridSize;
|
||||
int fontGridSmallSize;
|
||||
int fontTimeLineWeekdaySize;
|
||||
int fontTimeLineDateSize;
|
||||
int fontTimeLineTimeSize;
|
||||
int fontTimeLineTimeSizeDef12;
|
||||
int fontTimeLineTimeSizeDef24;
|
||||
int fontButtonSize;
|
||||
int fontDetailViewSize;
|
||||
int fontDetailHeaderSize;
|
||||
int fontMessageBoxSize;
|
||||
int fontMessageBoxLargeSize;
|
||||
const cFont *FontHeader;
|
||||
const cFont *FontGrid;
|
||||
const cFont *FontGridSmall;
|
||||
const cFont *FontTimeLineWeekday;
|
||||
const cFont *FontTimeLineDate;
|
||||
const cFont *FontTimeLineTime;
|
||||
const cFont *FontButton;
|
||||
const cFont *FontDetailView;
|
||||
const cFont *FontDetailHeader;
|
||||
const cFont *FontMessageBox;
|
||||
const cFont *FontMessageBoxLarge;
|
||||
int timeFormat;
|
||||
int themeIndex;
|
||||
int useBlending;
|
||||
int roundedCorners;
|
||||
void setDynamicValues(int width, int height);
|
||||
bool SetupParse(const char *Name, const char *Value);
|
||||
void loadTheme();
|
||||
};
|
||||
|
||||
#endif //__TVGUIDE_CONFIG_H
|
186
detailview.c
Normal file
186
detailview.c
Normal file
@ -0,0 +1,186 @@
|
||||
#include "detailview.h"
|
||||
|
||||
cDetailView::cDetailView(cEpgGrid *grid) {
|
||||
this->grid = grid;
|
||||
this->event = grid->GetEvent();
|
||||
imgScrollBar = NULL;
|
||||
FrameTime = 40; // ms
|
||||
FadeTime = 500; // ms
|
||||
borderWidth = 100; //px
|
||||
headerHeight = max (80 + tvguideConfig.logoHeight + 3 * tvguideConfig.FontDetailHeader->Height(), // border + logo + 3 Lines
|
||||
80 + tvguideConfig.epgImageHeight);
|
||||
description.Set(event->Description(), tvguideConfig.FontDetailView, tvguideConfig.osdWidth-2*borderWidth - 50 - 40);
|
||||
contentScrollable = setContentDrawportHeight();
|
||||
createPixmaps();
|
||||
}
|
||||
|
||||
cDetailView::~cDetailView(void){
|
||||
delete header;
|
||||
osdManager.releasePixmap(content);
|
||||
osdManager.releasePixmap(scrollBar);
|
||||
osdManager.releasePixmap(footer);
|
||||
delete imgScrollBar;
|
||||
}
|
||||
|
||||
bool cDetailView::setContentDrawportHeight() {
|
||||
int linesContent = description.Lines() + 1;
|
||||
heightContent = linesContent * tvguideConfig.FontDetailView->Height();
|
||||
if (heightContent > (tvguideConfig.osdHeight - 2 * borderWidth - headerHeight))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void cDetailView::createPixmaps() {
|
||||
int scrollBarWidth = 50;
|
||||
|
||||
header = new cStyledPixmap(osdManager.requestPixmap(5, cRect(borderWidth, borderWidth, tvguideConfig.osdWidth - 2*borderWidth, headerHeight), cRect::Null, "detailViewHeader"), "detailViewHeader");
|
||||
header->SetAlpha(0);
|
||||
header->setColor(theme.Color(clrHeader), theme.Color(clrHeaderBlending));
|
||||
content = osdManager.requestPixmap(5, cRect(borderWidth, borderWidth + headerHeight, tvguideConfig.osdWidth - 2*borderWidth - scrollBarWidth, tvguideConfig.osdHeight-2*borderWidth-headerHeight),
|
||||
cRect(0,0, tvguideConfig.osdWidth - 2*borderWidth - scrollBarWidth, max(heightContent, tvguideConfig.osdHeight-2*borderWidth-headerHeight)));
|
||||
content->SetAlpha(0);
|
||||
header->setColor(theme.Color(clrHeader), theme.Color(clrHeaderBlending));
|
||||
|
||||
scrollBar = osdManager.requestPixmap(5, cRect(tvguideConfig.osdWidth-borderWidth-scrollBarWidth, borderWidth + headerHeight, scrollBarWidth, tvguideConfig.osdHeight-2*borderWidth-headerHeight));
|
||||
scrollBar->SetAlpha(0);
|
||||
|
||||
footer = osdManager.requestPixmap(5, cRect(borderWidth, borderWidth + headerHeight + content->ViewPort().Height(), tvguideConfig.osdWidth - 2*borderWidth, 3));
|
||||
footer->SetAlpha(0);
|
||||
footer->Fill(clrWhite);
|
||||
}
|
||||
|
||||
void cDetailView::drawHeader() {
|
||||
header->drawBackground();
|
||||
header->drawBoldBorder();
|
||||
|
||||
int lineHeight = tvguideConfig.FontDetailHeader->Height();
|
||||
int offset = 30;
|
||||
cImageLoader imgLoader;
|
||||
if (tvguideConfig.hideChannelLogos) {
|
||||
header->DrawText(cPoint(20, offset + 10), grid->column->getChannel()->Name(), theme.Color(clrFont), clrTransparent, tvguideConfig.FontDetailHeader);
|
||||
offset += lineHeight + 10;
|
||||
} else {
|
||||
if (imgLoader.LoadLogo(grid->column->getChannel()->Name())) {
|
||||
cImage logo = imgLoader.GetImage();
|
||||
header->DrawImage(cPoint(20, 20), logo);
|
||||
}
|
||||
offset += tvguideConfig.logoHeight;
|
||||
}
|
||||
|
||||
if (!tvguideConfig.hideEpgImages) {
|
||||
if (imgLoader.LoadEPGImage(event->EventID())) {
|
||||
cImage epgImage = imgLoader.GetImage();
|
||||
int epgImageX = header->Width() - 30 - tvguideConfig.epgImageWidth;
|
||||
int epgImageY = (header->Height() - 10 - tvguideConfig.epgImageHeight) / 2;
|
||||
header->DrawRectangle(cRect(epgImageX-2, epgImageY-2, tvguideConfig.epgImageWidth + 4, tvguideConfig.epgImageHeight + 4), theme.Color(clrBorder));
|
||||
header->DrawImage(cPoint(epgImageX, epgImageY), epgImage);
|
||||
}
|
||||
}
|
||||
|
||||
header->DrawText(cPoint(20, offset), event->Title(), theme.Color(clrFont), clrTransparent, tvguideConfig.FontDetailHeader);
|
||||
cString datetime = cString::sprintf("%s, %s - %s (%d min)", *event->GetDateString(), *event->GetTimeString(), *event->GetEndTimeString(), event->Duration()/60);
|
||||
header->DrawText(cPoint(20, offset + lineHeight), *datetime, theme.Color(clrFont), clrTransparent, tvguideConfig.FontDetailView);
|
||||
header->DrawText(cPoint(20, offset + 2 * lineHeight), event->ShortText(), theme.Color(clrFont), clrTransparent, tvguideConfig.FontDetailView);
|
||||
}
|
||||
|
||||
void cDetailView::drawContent() {
|
||||
content->Fill(theme.Color(clrBorder));
|
||||
content->DrawRectangle(cRect(2, 0, content->ViewPort().Width() - 2, content->DrawPort().Height()), theme.Color(clrBackground));
|
||||
|
||||
int textHeight = tvguideConfig.FontDetailView->Height();
|
||||
int textLines = description.Lines();
|
||||
|
||||
for (int i=0; i<textLines; i++) {
|
||||
content->DrawText(cPoint(20, 20 + i*textHeight), description.GetLine(i), theme.Color(clrFont), clrTransparent, tvguideConfig.FontDetailView);
|
||||
}
|
||||
}
|
||||
|
||||
void cDetailView::drawScrollbar() {
|
||||
scrollBar->Fill(theme.Color(clrBorder));
|
||||
double scrollBarOffset = 0.0;
|
||||
if (contentScrollable) {
|
||||
heightScrollbar = ( (double)scrollBar->ViewPort().Height() ) / (double)heightContent * ( (double)scrollBar->ViewPort().Height() );
|
||||
scrollBarOffset = (-1.0)*(double)content->DrawPort().Point().Y() / (double)(content->DrawPort().Height() - (tvguideConfig.osdHeight-2*borderWidth-headerHeight));
|
||||
scrollBarOffset *= ( (double)scrollBar->ViewPort().Height()-7.0 - heightScrollbar);
|
||||
scrollBarOffset++;
|
||||
} else {
|
||||
heightScrollbar = scrollBar->ViewPort().Height();
|
||||
}
|
||||
scrollBar->DrawRectangle(cRect(3,0,scrollBar->ViewPort().Width()-6, scrollBar->ViewPort().Height()), theme.Color(clrBackground));
|
||||
if (imgScrollBar == NULL) {
|
||||
imgScrollBar = createScrollbar(scrollBar->ViewPort().Width()-10, heightScrollbar, theme.Color(clrHighlight), theme.Color(clrHighlightBlending));
|
||||
}
|
||||
scrollBar->DrawImage(cPoint(5, 2 + scrollBarOffset), *imgScrollBar);
|
||||
}
|
||||
|
||||
void cDetailView::scrollUp() {
|
||||
if (contentScrollable) {
|
||||
int newDrawportHeight = content->DrawPort().Point().Y() + tvguideConfig.FontDetailView->Height();
|
||||
content->SetDrawPortPoint(cPoint(0, min(newDrawportHeight,0)));
|
||||
drawScrollbar();
|
||||
}
|
||||
}
|
||||
|
||||
void cDetailView::scrollDown() {
|
||||
if (contentScrollable) {
|
||||
int newDrawportHeight = content->DrawPort().Point().Y() - tvguideConfig.FontDetailView->Height();
|
||||
int maxDrawportHeight = (content->DrawPort().Height() - (tvguideConfig.osdHeight-2*borderWidth-headerHeight));
|
||||
content->SetDrawPortPoint(cPoint(0, max(newDrawportHeight,(-1)*maxDrawportHeight)));
|
||||
drawScrollbar();
|
||||
}
|
||||
}
|
||||
|
||||
cImage *cDetailView::createScrollbar(int width, int height, tColor clrBgr, tColor clrBlend) {
|
||||
cImage *image = new cImage(cSize(width, height));
|
||||
image->Fill(clrBgr);
|
||||
if (tvguideConfig.useBlending) {
|
||||
int numSteps = 64;
|
||||
int alphaStep = 0x03;
|
||||
if (height < 30)
|
||||
return image;
|
||||
else if (height < 100) {
|
||||
numSteps = 32;
|
||||
alphaStep = 0x06;
|
||||
}
|
||||
int stepY = 0.5*height / numSteps;
|
||||
if (stepY == 0)
|
||||
stepY = 1;
|
||||
int alpha = 0x40;
|
||||
tColor clr;
|
||||
for (int i = 0; i<numSteps; i++) {
|
||||
clr = AlphaBlend(clrBgr, clrBlend, alpha);
|
||||
for (int y = i*stepY; y < (i+1)*stepY; y++) {
|
||||
for (int x=0; x<width; x++) {
|
||||
image->SetPixel(cPoint(x,y), clr);
|
||||
}
|
||||
}
|
||||
alpha += alphaStep;
|
||||
}
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
void cDetailView::Action(void) {
|
||||
drawHeader();
|
||||
drawContent();
|
||||
drawScrollbar();
|
||||
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;
|
||||
header->SetAlpha(Alpha);
|
||||
content->SetAlpha(Alpha);
|
||||
scrollBar->SetAlpha(Alpha);
|
||||
footer->SetAlpha(Alpha);
|
||||
osdManager.flush();
|
||||
cPixmap::Unlock();
|
||||
int Delta = cTimeMs::Now() - Now;
|
||||
if (Delta < FrameTime)
|
||||
cCondWait::SleepMs(FrameTime - Delta);
|
||||
if ((Now - Start) > FadeTime)
|
||||
break;
|
||||
}
|
||||
}
|
39
detailview.h
Normal file
39
detailview.h
Normal file
@ -0,0 +1,39 @@
|
||||
#ifndef __TVGUIDE_DETAILVIEW_H
|
||||
#define __TVGUIDE_DETAILVIEW_H
|
||||
|
||||
// --- cDetailView -------------------------------------------------------------
|
||||
|
||||
class cEpgGrid;
|
||||
|
||||
class cDetailView : public cThread {
|
||||
private:
|
||||
cEpgGrid *grid;
|
||||
cStyledPixmap *header;
|
||||
cPixmap *content;
|
||||
cPixmap *scrollBar;
|
||||
cPixmap *footer;
|
||||
const cEvent *event;
|
||||
cImage *imgScrollBar;
|
||||
int FrameTime;
|
||||
int FadeTime;
|
||||
cTextWrapper description;
|
||||
int borderWidth;
|
||||
int headerHeight;
|
||||
bool setContentDrawportHeight();
|
||||
int heightContent;
|
||||
int heightScrollbar;
|
||||
bool contentScrollable;
|
||||
virtual void Action(void);
|
||||
void drawHeader();
|
||||
void drawContent();
|
||||
void drawScrollbar();
|
||||
cImage *createScrollbar(int width, int height, tColor clrBgr, tColor clrBlend);
|
||||
public:
|
||||
cDetailView(cEpgGrid *grid);
|
||||
virtual ~cDetailView(void);
|
||||
void createPixmaps();
|
||||
void scrollUp();
|
||||
void scrollDown();
|
||||
};
|
||||
|
||||
#endif //__TVGUIDE_DETAILVIEW_H
|
146
epggrid.c
Normal file
146
epggrid.c
Normal file
@ -0,0 +1,146 @@
|
||||
#include "channelcolumn.h"
|
||||
#include "epggrid.h"
|
||||
|
||||
cEpgGrid::cEpgGrid(cChannelColumn *c, const cEvent *event) {
|
||||
this->event = event;
|
||||
this->column = c;
|
||||
text = new cTextWrapper();
|
||||
extText = new cTextWrapper();
|
||||
dirty = true;
|
||||
active = false;
|
||||
viewportHeight = 0;
|
||||
borderWidth = 10;
|
||||
hasTimer = false;
|
||||
if (column->hasTimer)
|
||||
hasTimer = event->HasTimer();
|
||||
}
|
||||
|
||||
cEpgGrid::~cEpgGrid(void) {
|
||||
delete text;
|
||||
delete extText;
|
||||
}
|
||||
|
||||
void cEpgGrid::SetViewportHeight() {
|
||||
int viewportHeightOld = viewportHeight;
|
||||
if ( column->myTime->GetStart() > event->StartTime() ) {
|
||||
viewportHeight = (min(event->EndTime(), column->myTime->GetStop()) - column->myTime->GetStart()) /60;
|
||||
} else if ( column->myTime->GetStop() < event->EndTime() ) {
|
||||
viewportHeight = (column->myTime->GetStop() - event->StartTime()) /60;
|
||||
} else {
|
||||
viewportHeight = event->Duration() / 60;
|
||||
}
|
||||
if (viewportHeight != viewportHeightOld)
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
void cEpgGrid::PositionPixmap() {
|
||||
int x0 = column->getX();
|
||||
int y0 = tvguideConfig.headerHeight;
|
||||
if ( column->myTime->GetStart() < event->StartTime() ) {
|
||||
y0 += (event->StartTime() - column->myTime->GetStart())/60*tvguideConfig.minuteHeight;
|
||||
}
|
||||
|
||||
if (!pixmap) {
|
||||
caller = cString::sprintf("epggrid %s %s", column->channel->Name(), event->Title());
|
||||
pixmap = osdManager.requestPixmap(-1, cRect(x0, y0, tvguideConfig.colWidth, viewportHeight * tvguideConfig.minuteHeight),
|
||||
cRect(0, 0, tvguideConfig.colWidth, event->Duration()/60*tvguideConfig.minuteHeight), *caller);
|
||||
} else {
|
||||
pixmap->SetViewPort(cRect(x0, y0, tvguideConfig.colWidth, viewportHeight * tvguideConfig.minuteHeight));
|
||||
}
|
||||
}
|
||||
|
||||
void cEpgGrid::setBackground() {
|
||||
if (active) {
|
||||
color = theme.Color(clrHighlight);
|
||||
colorBlending = theme.Color(clrHighlightBlending);
|
||||
} else {
|
||||
if (isColor1) {
|
||||
color = theme.Color(clrGrid1);
|
||||
colorBlending = theme.Color(clrGrid1Blending);
|
||||
} else {
|
||||
color = theme.Color(clrGrid2);
|
||||
colorBlending = theme.Color(clrGrid2Blending);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cEpgGrid::Draw() {
|
||||
if (!pixmap) {
|
||||
return;
|
||||
}
|
||||
if (dirty) {
|
||||
setBackground();
|
||||
drawBackground();
|
||||
drawText();
|
||||
if (hasTimer)
|
||||
DrawRecIcon();
|
||||
drawBorder();
|
||||
pixmap->SetLayer(1);
|
||||
dirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
void cEpgGrid::DrawRecIcon() {
|
||||
cString recIconText("REC");
|
||||
int width = tvguideConfig.FontGrid->Width(*recIconText)+2*borderWidth;
|
||||
int height = tvguideConfig.FontGrid->Height()+10;
|
||||
pixmap->DrawRectangle( cRect(pixmap->ViewPort().Width() - width - borderWidth, pixmap->ViewPort().Height() - height - borderWidth, width, height), theme.Color(clrButtonRed));
|
||||
pixmap->DrawText(cPoint(pixmap->ViewPort().Width() - width, pixmap->ViewPort().Height() - height - borderWidth/2), *recIconText, theme.Color(clrFont), clrTransparent, tvguideConfig.FontGrid);
|
||||
}
|
||||
|
||||
void cEpgGrid::setText() {
|
||||
cString strText;
|
||||
strText = cString::sprintf("%s - %s:\n%s", *(event->GetTimeString()), *(event->GetEndTimeString()), event->Title());
|
||||
text->Set(*(strText), tvguideConfig.FontGrid, tvguideConfig.colWidth-2*borderWidth);
|
||||
extText->Set(event->ShortText(), tvguideConfig.FontGridSmall, tvguideConfig.colWidth-2*borderWidth);
|
||||
}
|
||||
|
||||
void cEpgGrid::drawText() {
|
||||
int gridHeight = pixmap->ViewPort().Height();
|
||||
if (gridHeight/tvguideConfig.minuteHeight < 6)
|
||||
return;
|
||||
int textHeight = tvguideConfig.FontGrid->Height();
|
||||
int textLines = text->Lines();
|
||||
for (int i=0; i<textLines; i++) {
|
||||
pixmap->DrawText(cPoint(borderWidth, borderWidth + i*textHeight), text->GetLine(i), theme.Color(clrFont), clrTransparent, tvguideConfig.FontGrid);
|
||||
}
|
||||
int extTextLines = extText->Lines();
|
||||
int offset = (textLines+1)*textHeight - 0.5*textHeight;
|
||||
textHeight = tvguideConfig.FontGridSmall->Height();
|
||||
if ((pixmap->ViewPort().Height()-textHeight-10) > offset) {
|
||||
for (int i=0; i<extTextLines; i++) {
|
||||
pixmap->DrawText(cPoint(borderWidth, borderWidth + offset + i*textHeight), extText->GetLine(i), theme.Color(clrFont), clrTransparent, tvguideConfig.FontGridSmall);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int cEpgGrid::calcOverlap(cEpgGrid *neighbor) {
|
||||
int overlap = 0;
|
||||
if (intersects(neighbor)) {
|
||||
if ((event->StartTime() <= neighbor->StartTime()) && (event->EndTime() <= neighbor->EndTime())) {
|
||||
overlap = event->EndTime() - neighbor->StartTime();
|
||||
} else if ((event->StartTime() >= neighbor->StartTime()) && (event->EndTime() >= neighbor->EndTime())) {
|
||||
overlap = neighbor->EndTime() - event->StartTime();
|
||||
} else if ((event->StartTime() >= neighbor->StartTime()) && (event->EndTime() <= neighbor->EndTime())) {
|
||||
overlap = event->Duration();
|
||||
} else if ((event->StartTime() <= neighbor->StartTime()) && (event->EndTime() >= neighbor->EndTime())) {
|
||||
overlap = neighbor->EndTime() - neighbor->StartTime();
|
||||
}
|
||||
}
|
||||
return overlap;
|
||||
}
|
||||
|
||||
bool cEpgGrid::intersects(cEpgGrid *neighbor) {
|
||||
return ! ( (neighbor->EndTime() <= event->StartTime()) || (neighbor->StartTime() >= event->EndTime()) );
|
||||
}
|
||||
|
||||
bool cEpgGrid::isActiveInitial(time_t t) {
|
||||
if ((event->StartTime() < t) && (event->EndTime() > t))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void cEpgGrid::debug() {
|
||||
esyslog("tvguide Grid: %s, %s, viewportHeight: %d, Duration: %d", *(event->GetTimeString()), event->Title(), viewportHeight, event->Duration()/60);
|
||||
}
|
44
epggrid.h
Normal file
44
epggrid.h
Normal file
@ -0,0 +1,44 @@
|
||||
#ifndef __TVGUIDE_EPGGRID_H
|
||||
#define __TVGUIDE_EPGGRID_H
|
||||
|
||||
// --- cEpgGrid -------------------------------------------------------------
|
||||
|
||||
class cEpgGrid : public cListObject, public cStyledPixmap {
|
||||
private:
|
||||
const cEvent *event;
|
||||
cTextWrapper *text;
|
||||
cTextWrapper *extText;
|
||||
int viewportHeight;
|
||||
int borderWidth;
|
||||
void drawText();
|
||||
void setBackground();
|
||||
bool isColor1;
|
||||
bool active;
|
||||
bool dirty;
|
||||
bool intersects(cEpgGrid *neighbor);
|
||||
bool hasTimer;
|
||||
void DrawRecIcon();
|
||||
public:
|
||||
cEpgGrid(cChannelColumn *c, const cEvent *event);
|
||||
virtual ~cEpgGrid(void);
|
||||
cChannelColumn *column;
|
||||
void SetViewportHeight();
|
||||
void PositionPixmap();
|
||||
void setText();
|
||||
void Draw();
|
||||
void SetDirty() {dirty = true;};
|
||||
void SetActive() {dirty = true; active = true;};
|
||||
void SetInActive() {dirty = true; active = false;};
|
||||
void SetColor(bool color) {isColor1 = color;};
|
||||
bool IsColor1() {return isColor1;};
|
||||
int GetViewportHeight() {return viewportHeight;};
|
||||
const cEvent *GetEvent() {return event;};
|
||||
bool isActiveInitial(time_t t);
|
||||
time_t StartTime() { return event->StartTime(); };
|
||||
time_t EndTime() { return event->EndTime(); };
|
||||
int calcOverlap(cEpgGrid *neighbor);
|
||||
void setTimer() {hasTimer = true;};
|
||||
void debug();
|
||||
};
|
||||
|
||||
#endif //__TVGUIDE_EPGGRID_H
|
59
footer.c
Normal file
59
footer.c
Normal file
@ -0,0 +1,59 @@
|
||||
#include "footer.h"
|
||||
|
||||
cFooter::cFooter() {
|
||||
int buttonHeight= tvguideConfig.footerHeight - 20;
|
||||
textY = (buttonHeight - tvguideConfig.FontButton->Height())/2;
|
||||
int distanceX = 20;
|
||||
buttonWidth = (tvguideConfig.osdWidth - tvguideConfig.timeColWidth-5*distanceX)/4;
|
||||
int startX = tvguideConfig.timeColWidth + distanceX;
|
||||
int Y = tvguideConfig.osdHeight - tvguideConfig.footerHeight + (tvguideConfig.footerHeight - buttonHeight)/2;
|
||||
|
||||
buttonRed = new cStyledPixmap(osdManager.requestPixmap(3, cRect(startX, Y, buttonWidth, buttonHeight), cRect::Null, "btnRed"), "btnRed");
|
||||
buttonGreen = new cStyledPixmap(osdManager.requestPixmap(3, cRect(startX + buttonWidth + distanceX, Y, buttonWidth, buttonHeight), cRect::Null, "btnGreen"), "btnGreen");
|
||||
buttonYellow = new cStyledPixmap(osdManager.requestPixmap(3, cRect(startX + 2*(buttonWidth + distanceX), Y, buttonWidth, buttonHeight), cRect::Null, "btnYellow"), "btnYellow");
|
||||
buttonBlue = new cStyledPixmap(osdManager.requestPixmap(3, cRect(startX + 3*(buttonWidth + distanceX), Y, buttonWidth, buttonHeight), cRect::Null, "btnBlue"), "btnBlue");
|
||||
}
|
||||
|
||||
cFooter::~cFooter(void) {
|
||||
delete buttonRed;
|
||||
delete buttonGreen;
|
||||
delete buttonYellow;
|
||||
delete buttonBlue;
|
||||
}
|
||||
|
||||
void cFooter::drawRedButton() {
|
||||
buttonRed->setColor(theme.Color(clrButtonRed), theme.Color(clrButtonRedBlending));
|
||||
buttonRed->drawBackground();
|
||||
buttonRed->drawBorder();
|
||||
cString text(tr("Set Timer"));
|
||||
int width = tvguideConfig.FontButton->Width(*(text));
|
||||
buttonRed->DrawText(cPoint((buttonWidth-width)/2, textY), *(text), theme.Color(clrFontButtons), clrTransparent, tvguideConfig.FontButton);
|
||||
|
||||
}
|
||||
|
||||
void cFooter::drawGreenButton() {
|
||||
buttonGreen->setColor(theme.Color(clrButtonGreen), theme.Color(clrButtonGreenBlending));
|
||||
buttonGreen->drawBackground();
|
||||
buttonGreen->drawBorder();
|
||||
cString text = cString::sprintf("%d %s", tvguideConfig.jumpChannels, tr("Channels back"));
|
||||
int width = tvguideConfig.FontButton->Width(*text);
|
||||
buttonGreen->DrawText(cPoint((buttonWidth-width)/2, textY), *text, theme.Color(clrFontButtons), clrTransparent, tvguideConfig.FontButton);
|
||||
}
|
||||
|
||||
void cFooter::drawYellowButton() {
|
||||
buttonYellow->setColor(theme.Color(clrButtonYellow), theme.Color(clrButtonYellowBlending));
|
||||
buttonYellow->drawBackground();
|
||||
buttonYellow->drawBorder();
|
||||
cString text = cString::sprintf("%d %s", tvguideConfig.jumpChannels, tr("Channels forward"));
|
||||
int width = tvguideConfig.FontButton->Width(*text);
|
||||
buttonYellow->DrawText(cPoint((buttonWidth-width)/2, textY), *text, theme.Color(clrFontButtons), clrTransparent, tvguideConfig.FontButton);
|
||||
}
|
||||
|
||||
void cFooter::drawBlueButton() {
|
||||
buttonBlue->setColor(theme.Color(clrButtonBlue), theme.Color(clrButtonBlueBlending));
|
||||
buttonBlue->drawBackground();
|
||||
buttonBlue->drawBorder();
|
||||
cString text(tr("Switch to Channel"));
|
||||
int width = tvguideConfig.FontButton->Width(*(text));
|
||||
buttonBlue->DrawText(cPoint((buttonWidth-width)/2, textY), *(text), theme.Color(clrFontButtons), clrTransparent, tvguideConfig.FontButton);
|
||||
}
|
23
footer.h
Normal file
23
footer.h
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef __TVGUIDE_FOOTER_H
|
||||
#define __TVGUIDE_FOOTER_H
|
||||
|
||||
// --- cFooter -------------------------------------------------------------
|
||||
|
||||
class cFooter {
|
||||
private:
|
||||
cStyledPixmap *buttonRed;
|
||||
cStyledPixmap *buttonGreen;
|
||||
cStyledPixmap *buttonYellow;
|
||||
cStyledPixmap *buttonBlue;
|
||||
int textY;
|
||||
int buttonWidth;
|
||||
public:
|
||||
cFooter();
|
||||
virtual ~cFooter(void);
|
||||
void drawRedButton();
|
||||
void drawGreenButton();
|
||||
void drawYellowButton();
|
||||
void drawBlueButton();
|
||||
};
|
||||
|
||||
#endif //__TVGUIDE_FOOTER_H
|
78
imageloader.c
Normal file
78
imageloader.c
Normal file
@ -0,0 +1,78 @@
|
||||
#include "imageloader.h"
|
||||
#include <math.h>
|
||||
|
||||
using namespace Magick;
|
||||
|
||||
cImageLoader::cImageLoader() {
|
||||
}
|
||||
|
||||
cImageLoader::~cImageLoader() {
|
||||
}
|
||||
|
||||
bool cImageLoader::LoadLogo(const char *logo)
|
||||
{
|
||||
try
|
||||
{
|
||||
int width = tvguideConfig.logoWidth;
|
||||
int height = tvguideConfig.logoHeight;
|
||||
cString extension;
|
||||
if (tvguideConfig.logoExtension == 0) {
|
||||
extension = "png";
|
||||
} else if (tvguideConfig.logoExtension == 1) {
|
||||
extension = "jpg";
|
||||
}
|
||||
cString Filename = cString::sprintf("%s%s.%s", *tvguideConfig.logoPath, logo, *extension);
|
||||
osdImage.read(*Filename);
|
||||
|
||||
if (height != 0 || width != 0) {
|
||||
osdImage.sample( Geometry(width, height));
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool cImageLoader::LoadEPGImage(int eventID)
|
||||
{
|
||||
try
|
||||
{
|
||||
int width = tvguideConfig.epgImageWidth;
|
||||
int height = tvguideConfig.epgImageHeight;
|
||||
cString Filename = cString::sprintf("%s%d.jpg", *tvguideConfig.epgImagePath, eventID);
|
||||
osdImage.read(*Filename);
|
||||
|
||||
if (height != 0 || width != 0)
|
||||
osdImage.sample( Geometry(width, height));
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
cImage cImageLoader::GetImage()
|
||||
{
|
||||
int w, h;
|
||||
w = osdImage.columns();
|
||||
h = osdImage.rows();
|
||||
cImage image (cSize(w, h));
|
||||
const PixelPacket *pixels = osdImage.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;
|
||||
}
|
23
imageloader.h
Normal file
23
imageloader.h
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef _TVGUIDE_IMAGELOADER_H
|
||||
#define _TVGUIDE_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);
|
||||
bool LoadEPGImage(int eventID);
|
||||
private:
|
||||
Image osdImage;
|
||||
};
|
||||
|
||||
#endif //_TVGUIDE_IMAGELOADER_H
|
114
messagebox.c
Normal file
114
messagebox.c
Normal file
@ -0,0 +1,114 @@
|
||||
#include "messagebox.h"
|
||||
|
||||
cMessageBoxThread::cMessageBoxThread(cPixmap *content, int displayTime) {
|
||||
this->content = content;
|
||||
FrameTime = 30; // ms
|
||||
FadeTime = 200; // ms
|
||||
this->displayTime = displayTime;
|
||||
}
|
||||
|
||||
cMessageBoxThread::~cMessageBoxThread(void) {
|
||||
Cancel(0);
|
||||
}
|
||||
|
||||
void cMessageBoxThread::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;
|
||||
if (content) {
|
||||
content->SetAlpha(Alpha);
|
||||
osdManager.flush();
|
||||
}
|
||||
cPixmap::Unlock();
|
||||
int Delta = cTimeMs::Now() - Now;
|
||||
if (Delta < FrameTime)
|
||||
cCondWait::SleepMs(FrameTime - Delta);
|
||||
if ((Now - Start) > FadeTime)
|
||||
break;
|
||||
}
|
||||
cCondWait::SleepMs(displayTime - 2*FadeTime);
|
||||
Start = cTimeMs::Now();
|
||||
while (Running()) {
|
||||
uint64_t Now = cTimeMs::Now();
|
||||
cPixmap::Lock();
|
||||
double t = min(double(Now - Start) / FadeTime, 1.0);
|
||||
int Alpha = (1-t) * ALPHA_OPAQUE;
|
||||
if (content) {
|
||||
content->SetAlpha(Alpha);
|
||||
osdManager.flush();
|
||||
}
|
||||
cPixmap::Unlock();
|
||||
int Delta = cTimeMs::Now() - Now;
|
||||
if (Delta < FrameTime)
|
||||
cCondWait::SleepMs(FrameTime - Delta);
|
||||
if ((Now - Start) > FadeTime)
|
||||
break;
|
||||
}
|
||||
osdManager.flush();
|
||||
}
|
||||
|
||||
//--cMessageBox-------------------------------------------------------------
|
||||
cMutex cMessageBox::mutex;
|
||||
cMessageBoxThread *cMessageBox::msgboxThread = NULL;
|
||||
cPixmap *cMessageBox::content = NULL;
|
||||
|
||||
bool cMessageBox::Start(int displayTime, cString msg) {
|
||||
cMutexLock MutexLock(&mutex);
|
||||
int width = (tvguideConfig.osdWidth - 600)/2;
|
||||
if (!content) {
|
||||
int height = 400;
|
||||
content = osdManager.requestPixmap(5, cRect((tvguideConfig.osdWidth - width)/2,
|
||||
(tvguideConfig.osdHeight- height)/2,
|
||||
width, height),
|
||||
cRect::Null, "msgbox");
|
||||
}
|
||||
if (msgboxThread) {
|
||||
delete msgboxThread;
|
||||
msgboxThread = NULL;
|
||||
}
|
||||
if (!msgboxThread) {
|
||||
msgboxThread = new cMessageBoxThread(content, displayTime);
|
||||
cTextWrapper message;
|
||||
message.Set(msg, tvguideConfig.FontMessageBox, width - 40);
|
||||
int textHeight = tvguideConfig.FontMessageBox->Height();
|
||||
int textLines = message.Lines();
|
||||
int height = textLines * (textHeight+20);
|
||||
cPixmap::Lock();
|
||||
content->SetViewPort(cRect((tvguideConfig.osdWidth - width)/2,(tvguideConfig.osdHeight- height)/2, width, height));
|
||||
content->SetAlpha(0);
|
||||
content->Fill(theme.Color(clrBorder));
|
||||
content->DrawRectangle(cRect(2,2,width-4, height-4), theme.Color(clrBackground));
|
||||
int textWidth = 0;
|
||||
for (int i=0; i<textLines; i++) {
|
||||
textWidth = tvguideConfig.FontMessageBox->Width(message.GetLine(i));
|
||||
content->DrawText(cPoint((width - textWidth)/2, 20 + i*textHeight), message.GetLine(i), theme.Color(clrFont), clrTransparent, tvguideConfig.FontMessageBox);
|
||||
}
|
||||
cPixmap::Unlock();
|
||||
msgboxThread->Start();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void cMessageBox::Stop(void) {
|
||||
cMutexLock MutexLock(&mutex);
|
||||
if (msgboxThread) {
|
||||
delete msgboxThread;
|
||||
msgboxThread = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void cMessageBox::Destroy(void) {
|
||||
cMutexLock MutexLock(&mutex);
|
||||
if (msgboxThread) {
|
||||
delete msgboxThread;
|
||||
msgboxThread = NULL;
|
||||
}
|
||||
if (content) {
|
||||
osdManager.releasePixmap(content, "msgboxDestroy");
|
||||
content = NULL;
|
||||
}
|
||||
}
|
31
messagebox.h
Normal file
31
messagebox.h
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef __TVGUIDE_MESSAGEBOX_H
|
||||
#define __TVGUIDE_MESSAGEBOX_H
|
||||
|
||||
class cMessageBoxThreadPool;
|
||||
|
||||
// --- cMessageBox -------------------------------------------------------------
|
||||
|
||||
class cMessageBoxThread : public cThread {
|
||||
private:
|
||||
cPixmap *content;
|
||||
int FadeTime;
|
||||
int FrameTime;
|
||||
int displayTime;
|
||||
virtual void Action(void);
|
||||
public:
|
||||
cMessageBoxThread(cPixmap *content, int displayTime);
|
||||
virtual ~cMessageBoxThread(void);
|
||||
};
|
||||
|
||||
class cMessageBox {
|
||||
private:
|
||||
static cMutex mutex;
|
||||
static cMessageBoxThread *msgboxThread;
|
||||
static cPixmap *content;
|
||||
public:
|
||||
static bool Start(int displayTime, cString msg);
|
||||
static void Stop(void);
|
||||
static void Destroy(void);
|
||||
};
|
||||
|
||||
#endif //__TVGUIDE_MESSAGEBOX_H
|
52
osdmanager.c
Normal file
52
osdmanager.c
Normal file
@ -0,0 +1,52 @@
|
||||
#ifndef __TVGUIDE_OSDMANAGER_H
|
||||
#define __TVGUIDE_OSDMANAGER_H
|
||||
|
||||
class cOsdManager {
|
||||
private:
|
||||
cOsd *osd;
|
||||
int activePixmaps;
|
||||
public:
|
||||
cOsdManager(void);
|
||||
bool setOsd();
|
||||
void setBackground();
|
||||
void flush() {osd->Flush();};
|
||||
cPixmap *requestPixmap(int Layer, const cRect &ViewPort, const cRect &DrawPort = cRect::Null, const char *caller = "anonymous");
|
||||
void releasePixmap(cPixmap *pixmap, const char *caller = "anonymous");
|
||||
void deleteOsd() {delete osd;};
|
||||
int Width() { return osd->Width(); };
|
||||
int Height() { return osd->Height(); };
|
||||
};
|
||||
|
||||
#endif //__TVGUIDE_OSDMANAGER_H
|
||||
|
||||
cOsdManager::cOsdManager(void) {
|
||||
activePixmaps = 0;
|
||||
}
|
||||
|
||||
bool cOsdManager::setOsd() {
|
||||
osd = cOsdProvider::NewOsd(cOsd::OsdLeft(), cOsd::OsdTop());
|
||||
if (osd) {
|
||||
tArea Area = { 0, 0, cOsd::OsdWidth(), cOsd::OsdHeight(), 32 };
|
||||
if (osd->SetAreas(&Area, 1) == oeOk) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void cOsdManager::setBackground() {
|
||||
osd->DrawRectangle(0, 0, cOsd::OsdWidth(), cOsd::OsdHeight(), theme.Color(clrBackgroundOSD));
|
||||
}
|
||||
cPixmap *cOsdManager::requestPixmap(int Layer, const cRect &ViewPort, const cRect &DrawPort, const char *caller) {
|
||||
if (activePixmaps >= 64)
|
||||
return NULL;
|
||||
activePixmaps++;
|
||||
//esyslog("tvguide: Pixmap angefordert von %s, verwendet: %d", caller, activePixmaps);
|
||||
return osd->CreatePixmap(Layer, ViewPort, DrawPort);
|
||||
}
|
||||
|
||||
void cOsdManager::releasePixmap(cPixmap *pixmap, const char *caller) {
|
||||
activePixmaps--;
|
||||
//esyslog("tvguide: Pixmap geloescht von %s, verwendet: %d", caller, activePixmaps);
|
||||
osd->DestroyPixmap(pixmap);
|
||||
}
|
139
po/de_DE.po
Executable file
139
po/de_DE.po
Executable file
@ -0,0 +1,139 @@
|
||||
# VDR plugin language source file.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-tvguide 0.0.1\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2012-12-27 15:27+0100\n"
|
||||
"PO-Revision-Date: 2012-08-25 17:49+0200\n"
|
||||
"Last-Translator: Horst\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 "Set Timer"
|
||||
msgstr "Aufnehmen"
|
||||
|
||||
msgid "Channels back"
|
||||
msgstr "Kanäle zurück"
|
||||
|
||||
msgid "Channels forward"
|
||||
msgstr "Kanäle vor"
|
||||
|
||||
msgid "Switch to Channel"
|
||||
msgstr "Umschalten"
|
||||
|
||||
msgid "General Settings"
|
||||
msgstr "Allgemeine Einstellungen"
|
||||
|
||||
msgid "Screen Presentation"
|
||||
msgstr "Anzeigeoptionen"
|
||||
|
||||
msgid "Fonts and Fontsizes"
|
||||
msgstr "Schriften und Schriftgrößen"
|
||||
|
||||
msgid "Number of Channels / Columns"
|
||||
msgstr "Anzahl der Kanäle bzw. Spalten"
|
||||
|
||||
msgid "Channels to Jump (Keys Green / Yellow)"
|
||||
msgstr "Kanalsprung (Tasten Grün / Gelb)"
|
||||
|
||||
msgid "Time to display vertically in minutes"
|
||||
msgstr "Vertikal angezeigte Zeit (in Minuten)"
|
||||
|
||||
msgid "Big Step (Keys 1 / 3) in hours"
|
||||
msgstr "Großer Sprung (Tasten 1 / 3) in Stunden"
|
||||
|
||||
msgid "Huge Step (Keys 4 / 6) in hours"
|
||||
msgstr "Sehr großer Sprung (Tasten 4 / 6) in Stunden"
|
||||
|
||||
msgid "Time Format (12h/24h)"
|
||||
msgstr "Zeitformat (12h/24h)"
|
||||
|
||||
msgid "Theme"
|
||||
msgstr "Theme"
|
||||
|
||||
msgid "Use color gradients"
|
||||
msgstr "Farbverläufe verwenden"
|
||||
|
||||
msgid "Rounded Corners"
|
||||
msgstr "Abgerundete Ecken"
|
||||
|
||||
msgid "Width of Timeline"
|
||||
msgstr "Breite der Zeitleiste"
|
||||
|
||||
msgid "Height of Header"
|
||||
msgstr "Höhe des Headers"
|
||||
|
||||
msgid "Height of Footer"
|
||||
msgstr "Höhe des Footers"
|
||||
|
||||
msgid "Show Channel Logos"
|
||||
msgstr "Kanallogos anzeigen"
|
||||
|
||||
msgid "Logo Path used"
|
||||
msgstr "Benutzer Pfad für Kanallogos"
|
||||
|
||||
msgid "Logo Extension"
|
||||
msgstr "Logo Extension"
|
||||
|
||||
msgid "Logo width"
|
||||
msgstr "Breite der Logos"
|
||||
|
||||
msgid "Logo height"
|
||||
msgstr "Höhe der Logos"
|
||||
|
||||
msgid "Show EPG Images"
|
||||
msgstr "EPG Bilder anzeigen"
|
||||
|
||||
msgid "EPG Images Path used"
|
||||
msgstr "benutzer EPG Bilder Pfad"
|
||||
|
||||
msgid "EPG Image width"
|
||||
msgstr "Breite der EPG Bilder"
|
||||
|
||||
msgid "EPG Image height"
|
||||
msgstr "Höhe der EPG Bilder"
|
||||
|
||||
msgid "Font"
|
||||
msgstr "Schriftart"
|
||||
|
||||
msgid "Channel Header Font Size"
|
||||
msgstr "Kanal Header Schriftgröße"
|
||||
|
||||
msgid "Grid Font Size"
|
||||
msgstr "Grid Schriftgröße"
|
||||
|
||||
msgid "Grid Font Small Size"
|
||||
msgstr "Grid kleine Schriftgröße"
|
||||
|
||||
msgid "Timeline Weekday Font Size"
|
||||
msgstr "Zeitleiste Wochentag Schriftgröße"
|
||||
|
||||
msgid "Timeline Date Font Size"
|
||||
msgstr "Zeitleiste Datum Schriftgröße"
|
||||
|
||||
msgid "Timeline Time Font Size"
|
||||
msgstr "Zeitleiste Zeit Schriftgröße"
|
||||
|
||||
msgid "Button Font Size"
|
||||
msgstr "Button Schriftgröße"
|
||||
|
||||
msgid "Detail EPG View Font Size"
|
||||
msgstr "Detailierte EPG Ansicht Schriftgröße"
|
||||
|
||||
msgid "Detail EPG View Header Font Size"
|
||||
msgstr "Detailierte EPG Ansicht Header Schriftgröße"
|
||||
|
||||
msgid "Message Font Size"
|
||||
msgstr "Nachrichten Schriftgröße"
|
||||
|
||||
msgid "Message Large Font Size"
|
||||
msgstr "Nachrichten große Schriftgröße"
|
||||
|
||||
msgid "Timer not set! There is already a timer for this item."
|
||||
msgstr "Timer wurde nicht gesetzt! Es existiert bereits ein Timer für diese Sendung"
|
||||
|
||||
msgid "Timer set"
|
||||
msgstr "Timer gesetzt"
|
209
setup.c
Normal file
209
setup.c
Normal file
@ -0,0 +1,209 @@
|
||||
#include "setup.h"
|
||||
|
||||
cTvguideSetup::cTvguideSetup() {
|
||||
tmpTvguideConfig = tvguideConfig;
|
||||
Setup();
|
||||
}
|
||||
|
||||
cTvguideSetup::~cTvguideSetup() {
|
||||
}
|
||||
|
||||
|
||||
void cTvguideSetup::Setup(void) {
|
||||
int currentItem = Current();
|
||||
Clear();
|
||||
|
||||
Add(new cOsdItem(tr("General Settings")));
|
||||
Add(new cOsdItem(tr("Screen Presentation")));
|
||||
Add(new cOsdItem(tr("Fonts and Fontsizes")));
|
||||
|
||||
SetCurrent(Get(currentItem));
|
||||
Display();
|
||||
}
|
||||
|
||||
eOSState cTvguideSetup::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("General Settings")) == 0)
|
||||
state = AddSubMenu(new cMenuSetupGeneral(&tmpTvguideConfig));
|
||||
if (strcmp(ItemText, tr("Screen Presentation")) == 0)
|
||||
state = AddSubMenu(new cMenuSetupScreenLayout(&tmpTvguideConfig));
|
||||
if (strcmp(ItemText, tr("Fonts and Fontsizes")) == 0)
|
||||
state = AddSubMenu(new cMenuSetupFont(&tmpTvguideConfig));
|
||||
}
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
void cTvguideSetup::Store(void) {
|
||||
|
||||
tvguideConfig = tmpTvguideConfig;
|
||||
|
||||
SetupStore("themeIndex", tvguideConfig.themeIndex);
|
||||
SetupStore("useBlending", tvguideConfig.useBlending);
|
||||
SetupStore("roundedCorners", tvguideConfig.roundedCorners);
|
||||
SetupStore("timeFormat", tvguideConfig.timeFormat);
|
||||
SetupStore("channelCols", tvguideConfig.channelCols);
|
||||
SetupStore("displayTime", tvguideConfig.displayTime);
|
||||
SetupStore("bigStepHours", tvguideConfig.bigStepHours);
|
||||
SetupStore("hugeStepHours", tvguideConfig.hugeStepHours);
|
||||
SetupStore("jumpChannels", tvguideConfig.jumpChannels);
|
||||
SetupStore("hideChannelLogos", tvguideConfig.hideChannelLogos);
|
||||
SetupStore("logoExtension", tvguideConfig.logoExtension);
|
||||
SetupStore("logoWidth", tvguideConfig.logoWidth);
|
||||
SetupStore("logoHeight", tvguideConfig.logoHeight);
|
||||
SetupStore("hideEpgImages", tvguideConfig.hideEpgImages);
|
||||
SetupStore("epgImageWidth", tvguideConfig.epgImageWidth);
|
||||
SetupStore("epgImageHeight", tvguideConfig.epgImageHeight);
|
||||
SetupStore("epgImageHeight", tvguideConfig.epgImageHeight);
|
||||
SetupStore("timeColWidth", tvguideConfig.timeColWidth);
|
||||
SetupStore("headerHeight", tvguideConfig.headerHeight);
|
||||
SetupStore("footerHeight", tvguideConfig.footerHeight);
|
||||
SetupStore("fontIndex", tvguideConfig.fontIndex);
|
||||
SetupStore("fontHeaderSize", tvguideConfig.fontHeaderSize);
|
||||
SetupStore("fontGridSize", tvguideConfig.fontGridSize);
|
||||
SetupStore("fontGridSmallSize", tvguideConfig.fontGridSmallSize);
|
||||
SetupStore("fontTimeLineWeekdaySize", tvguideConfig.fontTimeLineWeekdaySize);
|
||||
SetupStore("fontTimeLineDateSize", tvguideConfig.fontTimeLineDateSize);
|
||||
SetupStore("fontTimeLineTimeSize", tvguideConfig.fontTimeLineTimeSize);
|
||||
SetupStore("fontButtonSize", tvguideConfig.fontButtonSize);
|
||||
SetupStore("fontDetailViewSize", tvguideConfig.fontDetailViewSize);
|
||||
SetupStore("fontDetailHeaderSize", tvguideConfig.fontDetailHeaderSize);
|
||||
SetupStore("fontMessageBoxSize", tvguideConfig.fontMessageBoxSize);
|
||||
SetupStore("fontMessageBoxLargeSize", tvguideConfig.fontMessageBoxLargeSize);
|
||||
}
|
||||
|
||||
cMenuSetupSubMenu::cMenuSetupSubMenu(const char* Title, cTvguideConfig* data) : cOsdMenu(Title, 30) {
|
||||
tmpTvguideConfig = 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;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
cMenuSetupGeneral::cMenuSetupGeneral(cTvguideConfig* data) : cMenuSetupSubMenu(tr("General Settings"), data) {
|
||||
timeFormatItems[0] = "12h";
|
||||
timeFormatItems[1] = "24h";
|
||||
|
||||
Set();
|
||||
}
|
||||
|
||||
void cMenuSetupGeneral::Set(void) {
|
||||
int currentItem = Current();
|
||||
Clear();
|
||||
|
||||
Add(new cMenuEditIntItem(tr("Number of Channels / Columns"), &tmpTvguideConfig->channelCols, 3, 8));
|
||||
Add(new cMenuEditIntItem(tr("Channels to Jump (Keys Green / Yellow)"), &tmpTvguideConfig->jumpChannels, 2, 30));
|
||||
Add(new cMenuEditIntItem(tr("Time to display vertically in minutes"), &tmpTvguideConfig->displayTime, 120, 320));
|
||||
Add(new cMenuEditIntItem(tr("Big Step (Keys 1 / 3) in hours"), &tmpTvguideConfig->bigStepHours, 1, 12));
|
||||
Add(new cMenuEditIntItem(tr("Huge Step (Keys 4 / 6) in hours"), &tmpTvguideConfig->hugeStepHours, 13, 48));
|
||||
Add(new cMenuEditStraItem(tr("Time Format (12h/24h)"), &tmpTvguideConfig->timeFormat, 2, timeFormatItems));
|
||||
|
||||
SetCurrent(Get(currentItem));
|
||||
Display();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
cMenuSetupScreenLayout::cMenuSetupScreenLayout(cTvguideConfig* data) : cMenuSetupSubMenu(tr("Screen Presentation"), data) {
|
||||
themes.Load(*cString("tvguide"));
|
||||
hideChannelLogosItems[0] = trVDR("yes");
|
||||
hideChannelLogosItems[1] = trVDR("no");
|
||||
logoExtensionItems[0] = "png";
|
||||
logoExtensionItems[1] = "jpg";
|
||||
Set();
|
||||
}
|
||||
|
||||
void cMenuSetupScreenLayout::Set(void) {
|
||||
int currentItem = Current();
|
||||
Clear();
|
||||
if (themes.NumThemes())
|
||||
Add(new cMenuEditStraItem(tr("Theme"), &tmpTvguideConfig->themeIndex, themes.NumThemes(), themes.Descriptions()));
|
||||
Add(new cMenuEditBoolItem(tr("Use color gradients"), &tmpTvguideConfig->useBlending));
|
||||
Add(new cMenuEditBoolItem(tr("Rounded Corners"), &tmpTvguideConfig->roundedCorners));
|
||||
Add(new cMenuEditIntItem(tr("Width of Timeline"), &tmpTvguideConfig->timeColWidth, 50, 300));
|
||||
Add(new cMenuEditIntItem(tr("Height of Header"), &tmpTvguideConfig->headerHeight, 50, 300));
|
||||
Add(new cMenuEditIntItem(tr("Height of Footer"), &tmpTvguideConfig->footerHeight, 50, 300));
|
||||
|
||||
const char *indent = " ";
|
||||
Add(new cMenuEditStraItem(tr("Show Channel Logos"), &tmpTvguideConfig->hideChannelLogos, 2, hideChannelLogosItems));
|
||||
if (!tmpTvguideConfig->hideChannelLogos) {
|
||||
Add(InfoItem(tr("Logo Path used"), *tvguideConfig.logoPath));
|
||||
Add(new cMenuEditStraItem(*cString::sprintf("%s%s", indent, tr("Logo Extension")), &tmpTvguideConfig->logoExtension, 2, logoExtensionItems));
|
||||
Add(new cMenuEditIntItem(*cString::sprintf("%s%s", indent, tr("Logo width")), &tmpTvguideConfig->logoWidth, 0, 350));
|
||||
Add(new cMenuEditIntItem(*cString::sprintf("%s%s", indent, tr("Logo height")), &tmpTvguideConfig->logoHeight, 0, 250));
|
||||
}
|
||||
|
||||
Add(new cMenuEditStraItem(tr("Show EPG Images"), &tmpTvguideConfig->hideEpgImages, 2, hideChannelLogosItems));
|
||||
if (!tmpTvguideConfig->hideEpgImages) {
|
||||
Add(InfoItem(tr("EPG Images Path used"), *tvguideConfig.epgImagePath));
|
||||
Add(new cMenuEditIntItem(*cString::sprintf("%s%s", indent, tr("EPG Image width")), &tmpTvguideConfig->epgImageWidth, 0, 800));
|
||||
Add(new cMenuEditIntItem(*cString::sprintf("%s%s", indent, tr("EPG Image height")), &tmpTvguideConfig->epgImageHeight, 0, 800));
|
||||
}
|
||||
|
||||
SetCurrent(Get(currentItem));
|
||||
Display();
|
||||
}
|
||||
|
||||
eOSState cMenuSetupScreenLayout::ProcessKey(eKeys Key) {
|
||||
eOSState state = cOsdMenu::ProcessKey(Key);
|
||||
if (Key == kOk) {
|
||||
state = osBack;
|
||||
} else if (Key != kNone) {
|
||||
Set();
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
cMenuSetupFont::cMenuSetupFont(cTvguideConfig* data) : cMenuSetupSubMenu(tr("Fonts and Fontsizes"), data) {
|
||||
cFont::GetAvailableFontNames(&fontNames);
|
||||
fontNames.Insert(strdup(tvguideConfig.fontNameDefault));
|
||||
Set();
|
||||
}
|
||||
|
||||
void cMenuSetupFont::Set(void) {
|
||||
int currentItem = Current();
|
||||
Clear();
|
||||
|
||||
Add(new cMenuEditStraItem(tr("Font"), &tmpTvguideConfig->fontIndex, fontNames.Size(), &fontNames[0]));
|
||||
Add(new cMenuEditIntItem(tr("Channel Header Font Size"), &tmpTvguideConfig->fontHeaderSize, 10, 70));
|
||||
Add(new cMenuEditIntItem(tr("Grid Font Size"), &tmpTvguideConfig->fontGridSize, 10, 70));
|
||||
Add(new cMenuEditIntItem(tr("Grid Font Small Size"), &tmpTvguideConfig->fontGridSmallSize, 10, 70));
|
||||
Add(new cMenuEditIntItem(tr("Timeline Weekday Font Size"), &tmpTvguideConfig->fontTimeLineWeekdaySize, 10, 70));
|
||||
Add(new cMenuEditIntItem(tr("Timeline Date Font Size"), &tmpTvguideConfig->fontTimeLineDateSize, 10, 70));
|
||||
Add(new cMenuEditIntItem(tr("Timeline Time Font Size"), &tmpTvguideConfig->fontTimeLineTimeSize, 10, 70));
|
||||
Add(new cMenuEditIntItem(tr("Button Font Size"), &tmpTvguideConfig->fontButtonSize, 10, 70));
|
||||
Add(new cMenuEditIntItem(tr("Detail EPG View Font Size"), &tmpTvguideConfig->fontDetailViewSize, 10, 70));
|
||||
Add(new cMenuEditIntItem(tr("Detail EPG View Header Font Size"), &tmpTvguideConfig->fontDetailHeaderSize, 10, 70));
|
||||
Add(new cMenuEditIntItem(tr("Message Font Size"), &tmpTvguideConfig->fontMessageBoxSize, 10, 70));
|
||||
Add(new cMenuEditIntItem(tr("Message Large Font Size"), &tmpTvguideConfig->fontMessageBoxLargeSize, 10, 70));
|
||||
|
||||
SetCurrent(Get(currentItem));
|
||||
Display();
|
||||
}
|
54
setup.h
Normal file
54
setup.h
Normal file
@ -0,0 +1,54 @@
|
||||
#ifndef __TVGUIDE_SETUP_H
|
||||
#define __TVGUIDE_SETUP_H
|
||||
|
||||
class cTvguideSetup : public cMenuSetupPage {
|
||||
public:
|
||||
cTvguideSetup(void);
|
||||
virtual ~cTvguideSetup();
|
||||
private:
|
||||
cTvguideConfig tmpTvguideConfig;
|
||||
void Setup(void);
|
||||
protected:
|
||||
virtual eOSState ProcessKey(eKeys Key);
|
||||
virtual void Store(void);
|
||||
|
||||
};
|
||||
|
||||
class cMenuSetupSubMenu : public cOsdMenu {
|
||||
protected:
|
||||
cTvguideConfig *tmpTvguideConfig;
|
||||
virtual eOSState ProcessKey(eKeys Key);
|
||||
virtual void Set(void) = 0;
|
||||
cOsdItem *InfoItem(const char *label, const char *value);
|
||||
public:
|
||||
cMenuSetupSubMenu(const char *Title, cTvguideConfig *data);
|
||||
};
|
||||
|
||||
class cMenuSetupGeneral : public cMenuSetupSubMenu {
|
||||
protected:
|
||||
const char * timeFormatItems[2];
|
||||
void Set(void);
|
||||
public:
|
||||
cMenuSetupGeneral(cTvguideConfig *data);
|
||||
};
|
||||
|
||||
class cMenuSetupScreenLayout : public cMenuSetupSubMenu {
|
||||
protected:
|
||||
virtual eOSState ProcessKey(eKeys Key);
|
||||
cThemes themes;
|
||||
const char * hideChannelLogosItems[2];
|
||||
const char * logoExtensionItems[2];
|
||||
void Set(void);
|
||||
public:
|
||||
cMenuSetupScreenLayout(cTvguideConfig *data);
|
||||
};
|
||||
|
||||
class cMenuSetupFont : public cMenuSetupSubMenu {
|
||||
protected:
|
||||
cStringList fontNames;
|
||||
void Set(void);
|
||||
public:
|
||||
cMenuSetupFont(cTvguideConfig *data);
|
||||
};
|
||||
|
||||
#endif //__TVGUIDE_SETUP_H
|
125
styledpixmap.c
Normal file
125
styledpixmap.c
Normal file
@ -0,0 +1,125 @@
|
||||
#include "styledpixmap.h"
|
||||
|
||||
cStyledPixmap::cStyledPixmap(void) {
|
||||
pixmap = NULL;
|
||||
caller = NULL;
|
||||
}
|
||||
|
||||
cStyledPixmap::cStyledPixmap(cPixmap *pixmap, cString caller) {
|
||||
this->pixmap = pixmap;
|
||||
this->caller = caller;
|
||||
}
|
||||
|
||||
cStyledPixmap::~cStyledPixmap(void) {
|
||||
if (pixmap)
|
||||
osdManager.releasePixmap(pixmap, *caller);
|
||||
}
|
||||
|
||||
void cStyledPixmap::setPixmap(cPixmap *pixmap) {
|
||||
if (pixmap) {
|
||||
this->pixmap = pixmap;
|
||||
}
|
||||
}
|
||||
|
||||
void cStyledPixmap::drawBackground() {
|
||||
if (!tvguideConfig.useBlending) {
|
||||
pixmap->Fill(color);
|
||||
} else {
|
||||
drawBlendedBackground();
|
||||
}
|
||||
}
|
||||
|
||||
void cStyledPixmap::drawBlendedBackground() {
|
||||
int width = pixmap->ViewPort().Width();
|
||||
int height = pixmap->ViewPort().Height();
|
||||
pixmap->Fill(color);
|
||||
int numSteps = 64;
|
||||
int alphaStep = 0x04;
|
||||
if (height < 30)
|
||||
return;
|
||||
else if (height < 100) {
|
||||
numSteps = 32;
|
||||
alphaStep = 0x08;
|
||||
}
|
||||
int stepY = 0.5*height / numSteps;
|
||||
if (stepY == 0) stepY = 1;
|
||||
int alpha = 0x00;
|
||||
tColor clr;
|
||||
for (int i = 0; i<numSteps; i++) {
|
||||
clr = AlphaBlend(color, colorBlending, alpha);
|
||||
pixmap->DrawRectangle(cRect(0,i*stepY,width,stepY), clr);
|
||||
alpha += alphaStep;
|
||||
}
|
||||
}
|
||||
|
||||
void cStyledPixmap::drawBorder() {
|
||||
int width = pixmap->ViewPort().Width();
|
||||
int height = pixmap->ViewPort().Height();
|
||||
|
||||
drawDefaultBorder(width, height);
|
||||
if (tvguideConfig.roundedCorners) {
|
||||
int borderRadius = 12;
|
||||
drawRoundedCorners(width, height, borderRadius);
|
||||
}
|
||||
}
|
||||
|
||||
void cStyledPixmap::drawDefaultBorder(int width, int height) {
|
||||
pixmap->DrawRectangle(cRect(0,0,width,2), theme.Color(clrBackground)); //top
|
||||
pixmap->DrawRectangle(cRect(0,0,2,height), theme.Color(clrBackground)); //left
|
||||
pixmap->DrawRectangle(cRect(0,height-2,width,2), theme.Color(clrBackground)); //bottom
|
||||
pixmap->DrawRectangle(cRect(width-2,0,2,height), theme.Color(clrBackground)); //right
|
||||
|
||||
pixmap->DrawRectangle(cRect(2,2,width-4,1), theme.Color(clrBorder)); //top
|
||||
pixmap->DrawRectangle(cRect(2,2,1,height-4), theme.Color(clrBorder)); //left
|
||||
pixmap->DrawRectangle(cRect(2,height-3,width-4,1), theme.Color(clrBorder)); //bottom
|
||||
pixmap->DrawRectangle(cRect(width-3,2,1,height-4), theme.Color(clrBorder)); //right
|
||||
}
|
||||
|
||||
void cStyledPixmap::drawBoldBorder() {
|
||||
int width = pixmap->ViewPort().Width();
|
||||
int height = pixmap->ViewPort().Height();
|
||||
pixmap->DrawRectangle(cRect(0,0,width,2), theme.Color(clrBorder)); //top
|
||||
pixmap->DrawRectangle(cRect(0,0,2,height), theme.Color(clrBorder)); //left
|
||||
pixmap->DrawRectangle(cRect(0,height-2,width,2), theme.Color(clrBorder)); //bottom
|
||||
pixmap->DrawRectangle(cRect(width-2,0,2,height), theme.Color(clrBorder)); //right
|
||||
}
|
||||
|
||||
void cStyledPixmap::drawRoundedCorners(int width, int height, int radius) {
|
||||
pixmap->DrawEllipse(cRect(2,2,radius,radius), theme.Color(clrBorder), -2);
|
||||
pixmap->DrawEllipse(cRect(1,1,radius,radius), theme.Color(clrBackground), -2);
|
||||
|
||||
pixmap->DrawEllipse(cRect(width-radius - 2,2,radius,radius), theme.Color(clrBorder), -1);
|
||||
pixmap->DrawEllipse(cRect(width-radius - 1,1,radius,radius), theme.Color(clrBackground), -1);
|
||||
|
||||
if( height > 2*radius) {
|
||||
pixmap->DrawEllipse(cRect(2,height-radius - 2,radius,radius), theme.Color(clrBorder), -3);
|
||||
pixmap->DrawEllipse(cRect(1,height-radius - 1,radius,radius), theme.Color(clrBackground), -3);
|
||||
|
||||
pixmap->DrawEllipse(cRect(width-radius - 2,height-radius - 2,radius,radius), theme.Color(clrBorder), -4);
|
||||
pixmap->DrawEllipse(cRect(width-radius - 1,height-radius - 1,radius,radius), theme.Color(clrBackground), -4);
|
||||
}
|
||||
}
|
||||
|
||||
void cStyledPixmap::drawVerticalLine(int x, int yStart, int yStop, tColor col) {
|
||||
for (int y = yStart; y <= yStop; y++) {
|
||||
pixmap->DrawPixel(cPoint(x,y), col);
|
||||
}
|
||||
}
|
||||
|
||||
void cStyledPixmap::drawHorizontalLine(int y, int xStart, int xStop, tColor col) {
|
||||
for (int x = xStart; x <= xStop; x++) {
|
||||
pixmap->DrawPixel(cPoint(x,y), col);
|
||||
}
|
||||
}
|
||||
|
||||
void cStyledPixmap::DrawText(const cPoint &Point, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font) {
|
||||
pixmap->DrawText(Point, s, ColorFg, ColorBg, Font);
|
||||
}
|
||||
|
||||
void cStyledPixmap::DrawImage(const cPoint &Point, const cImage &Image) {
|
||||
pixmap->DrawImage(Point, Image);
|
||||
}
|
||||
|
||||
void cStyledPixmap::DrawRectangle(const cRect &Rect, tColor Color) {
|
||||
pixmap->DrawRectangle(Rect,Color);
|
||||
}
|
35
styledpixmap.h
Normal file
35
styledpixmap.h
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef __TVGUIDE_STYLEDPIXMAP_H
|
||||
#define __TVGUIDE_STYLEDPIXMAP_H
|
||||
|
||||
// --- cStyledPixmap -------------------------------------------------------------
|
||||
|
||||
class cStyledPixmap {
|
||||
private:
|
||||
void drawVerticalLine(int x, int yStart, int yStop, tColor col);
|
||||
void drawHorizontalLine(int y, int xStart, int xStop, tColor col);
|
||||
protected:
|
||||
cPixmap *pixmap;
|
||||
cString caller;
|
||||
tColor color;
|
||||
tColor colorBlending;
|
||||
void setPixmap(cPixmap *pixmap);
|
||||
public:
|
||||
cStyledPixmap(void);
|
||||
cStyledPixmap(cPixmap *pixmap, cString caller);
|
||||
virtual ~cStyledPixmap(void);
|
||||
void drawBackground();
|
||||
void drawBlendedBackground();
|
||||
void drawBorder();
|
||||
void drawBoldBorder();
|
||||
void drawDefaultBorder(int width, int height);
|
||||
void drawRoundedCorners(int width, int height, int radius);
|
||||
void setColor(tColor color, tColor colorBlending) {this->color = color; this->colorBlending = colorBlending;};
|
||||
void SetAlpha(int alpha) {pixmap->SetAlpha(alpha);};
|
||||
void DrawText(const cPoint &Point, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font);
|
||||
void DrawImage(const cPoint &Point, const cImage &Image);
|
||||
void DrawRectangle(const cRect &Rect, tColor Color);
|
||||
int Width() {return pixmap->ViewPort().Width();};
|
||||
int Height() {return pixmap->ViewPort().Height();};
|
||||
};
|
||||
|
||||
#endif //__TVGUIDE_STYLEDPIXMAP_H
|
28
themes/tvguide-darkblue.theme
Normal file
28
themes/tvguide-darkblue.theme
Normal file
@ -0,0 +1,28 @@
|
||||
Description = DarkBlue
|
||||
|
||||
clrBackground = FF000000
|
||||
clrBackgroundOSD = FF000000
|
||||
clrGrid1 = FF0E53A7
|
||||
clrGrid1Blending = FF000000
|
||||
clrGrid2 = FF071871
|
||||
clrGrid2Blending = FF000000
|
||||
clrHighlight = FF7A6D6D
|
||||
clrHighlightBlending = FF1C1919
|
||||
clrFont = FFFFFFFF
|
||||
clrFontHeader = FF000000
|
||||
clrFontButtons = FFFFFFFF
|
||||
clrHeader = FF8B9194
|
||||
clrHeaderBlending = FF000000
|
||||
clrBorder = FFFFFFFF
|
||||
clrTimeline1 = FFFFFFFF
|
||||
clrTimeline1Blending = FF828282
|
||||
clrTimeline2 = FF000000
|
||||
clrTimeline2Blending = FF3F3F3F
|
||||
clrButtonRed = FFD42627
|
||||
clrButtonRedBlending = FF000000
|
||||
clrButtonGreen = FF004F00
|
||||
clrButtonGreenBlending = FF000000
|
||||
clrButtonYellow = FFFFA300
|
||||
clrButtonYellowBlending = FF000000
|
||||
clrButtonBlue = FF0000FE
|
||||
clrButtonBlueBlending = FF000000
|
27
themes/tvguide-default.theme
Normal file
27
themes/tvguide-default.theme
Normal file
@ -0,0 +1,27 @@
|
||||
Description = Default
|
||||
clrBackground = FF000000
|
||||
clrBackgroundOSD = FF000000
|
||||
clrGrid1 = FF404749
|
||||
clrGrid1Blending = FF000000
|
||||
clrGrid2 = FF20293F
|
||||
clrGrid2Blending = FF000000
|
||||
clrHighlight = FFFF4D00
|
||||
clrHighlightBlending = FF000000
|
||||
clrFont = FFFFFFFF
|
||||
clrFontHeader = FFFFFFFF
|
||||
clrFontButtons = FFFFFFFF
|
||||
clrHeader = FF000000
|
||||
clrHeaderBlending = FFE0E0E0
|
||||
clrBorder = FFFFFFFF
|
||||
clrTimeline1 = FFFFFFFF
|
||||
clrTimeline1Blending = FF828282
|
||||
clrTimeline2 = FF000000
|
||||
clrTimeline2Blending = FF3F3F3F
|
||||
clrButtonRed = FFD42627
|
||||
clrButtonRedBlending = FFE0E0E0
|
||||
clrButtonGreen = FF004F00
|
||||
clrButtonGreenBlending = FFE0E0E0
|
||||
clrButtonYellow = FFFFA300
|
||||
clrButtonYellowBlending = FFE0E0E0
|
||||
clrButtonBlue = FF0000FE
|
||||
clrButtonBlueBlending = FFE0E0E0
|
115
timeline.c
Normal file
115
timeline.c
Normal file
@ -0,0 +1,115 @@
|
||||
#include "timeline.h"
|
||||
|
||||
cTimeLine::cTimeLine(cMyTime *myTime) {
|
||||
this->myTime = myTime;
|
||||
dateViewer = new cStyledPixmap(osdManager.requestPixmap(3, cRect(0, 0, tvguideConfig.timeColWidth, tvguideConfig.headerHeight), cRect::Null, "dateViewer"), "dateViewer");
|
||||
timeline = osdManager.requestPixmap(2, cRect(0, tvguideConfig.headerHeight, tvguideConfig.timeColWidth, tvguideConfig.osdHeight - tvguideConfig.headerHeight - tvguideConfig.footerHeight),
|
||||
cRect(0,0, tvguideConfig.timeColWidth, 1440*tvguideConfig.minuteHeight), "timeline");
|
||||
clock = new cStyledPixmap(osdManager.requestPixmap(3, cRect(0, tvguideConfig.osdHeight-tvguideConfig.footerHeight, tvguideConfig.timeColWidth, tvguideConfig.footerHeight-9), cRect::Null, "timeViewer"), "timeViewer");
|
||||
}
|
||||
|
||||
cTimeLine::~cTimeLine(void) {
|
||||
delete dateViewer;
|
||||
osdManager.releasePixmap(timeline);
|
||||
delete clock;
|
||||
}
|
||||
|
||||
void cTimeLine::drawDateViewer() {
|
||||
cString weekDay = myTime->GetWeekday();
|
||||
cString date = myTime->GetDate();
|
||||
|
||||
int textHeight = tvguideConfig.FontTimeLineWeekday->Height();
|
||||
int weekdayWidth = tvguideConfig.FontTimeLineWeekday->Width(*weekDay);
|
||||
int dateWidth = tvguideConfig.FontTimeLineDate->Width(*date);
|
||||
|
||||
dateViewer->setColor(theme.Color(clrHeader), theme.Color(clrHeaderBlending));
|
||||
dateViewer->drawBackground();
|
||||
dateViewer->drawBorder();
|
||||
dateViewer->DrawText(cPoint((tvguideConfig.timeColWidth-weekdayWidth)/2, (tvguideConfig.headerHeight-2*textHeight)/2), *weekDay, theme.Color(clrFontHeader), clrTransparent, tvguideConfig.FontTimeLineWeekday);
|
||||
dateViewer->DrawText(cPoint((tvguideConfig.timeColWidth-dateWidth)/2, (tvguideConfig.headerHeight-2*textHeight)/2 + textHeight + 5), *date, theme.Color(clrFontHeader), clrTransparent, tvguideConfig.FontTimeLineDate);
|
||||
}
|
||||
|
||||
void cTimeLine::drawTimeline() {
|
||||
timeline->SetTile(true);
|
||||
timeline->Fill(theme.Color(clrBackground));
|
||||
tColor colorFont;
|
||||
|
||||
const cImage *img1 = createBackgroundImage(tvguideConfig.timeColWidth-4, tvguideConfig.minuteHeight*30, theme.Color(clrTimeline1), theme.Color(clrTimeline1Blending));
|
||||
const cImage *img2 = createBackgroundImage(tvguideConfig.timeColWidth-4, tvguideConfig.minuteHeight*30, theme.Color(clrTimeline2), theme.Color(clrTimeline2Blending));
|
||||
const cImage *img = NULL;
|
||||
|
||||
int textWidth, posY;
|
||||
char timetext[10];
|
||||
|
||||
for (int i=0; i<48; i++) {
|
||||
if (i%2==0) {
|
||||
img = img1;
|
||||
colorFont = theme.Color(clrTimeline2);
|
||||
if (tvguideConfig.timeFormat == e12Hours) {
|
||||
if (i == 0)
|
||||
sprintf(timetext, "12:00 PM");
|
||||
else if (i/2 < 13)
|
||||
sprintf(timetext, "%d:00 AM", i/2);
|
||||
else
|
||||
sprintf(timetext, "%d:00 PM", i/2-12);
|
||||
} else {
|
||||
sprintf(timetext, "%d:00", i/2);
|
||||
}
|
||||
} else {
|
||||
img = img2;
|
||||
colorFont = theme.Color(clrTimeline1);
|
||||
if (tvguideConfig.timeFormat == e12Hours) {
|
||||
if (i == 1)
|
||||
sprintf(timetext, "12:30 PM");
|
||||
else if (i/2 < 13)
|
||||
sprintf(timetext, "%d:30 AM", i/2);
|
||||
else
|
||||
sprintf(timetext, "%d:30 PM", i/2-12);
|
||||
} else {
|
||||
sprintf(timetext, "%d:30", i/2);
|
||||
}
|
||||
}
|
||||
posY = i*tvguideConfig.minuteHeight*30;
|
||||
timeline->DrawImage(cPoint(2, posY), *img);
|
||||
textWidth = tvguideConfig.FontTimeLineTime->Width(timetext);
|
||||
timeline->DrawText(cPoint((tvguideConfig.timeColWidth-textWidth)/2, posY + 5), timetext, colorFont, clrTransparent, tvguideConfig.FontTimeLineTime);
|
||||
}
|
||||
setTimeline();
|
||||
delete img1;
|
||||
delete img2;
|
||||
}
|
||||
|
||||
cImage *cTimeLine::createBackgroundImage(int width, int height, tColor clrBgr, tColor clrBlend) {
|
||||
cImage *image = new cImage(cSize(width, height));
|
||||
image->Fill(clrBgr);
|
||||
if (tvguideConfig.useBlending) {
|
||||
int stepY = 0.5*height / 64;
|
||||
int alpha = 0x00;
|
||||
tColor clr;
|
||||
for (int i = 0; i<64; i++) {
|
||||
clr = AlphaBlend(clrBgr, clrBlend, alpha);
|
||||
for (int y = i*stepY; y < (i+1)*stepY; y++) {
|
||||
for (int x=0; x<width; x++) {
|
||||
image->SetPixel(cPoint(x,y), clr);
|
||||
}
|
||||
}
|
||||
alpha += 0x04;
|
||||
}
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
void cTimeLine::setTimeline() {
|
||||
int offset = myTime->GetTimelineOffset();
|
||||
timeline->SetDrawPortPoint(cPoint(0, -offset*tvguideConfig.minuteHeight));
|
||||
}
|
||||
|
||||
void cTimeLine::drawClock() {
|
||||
cString currentTime = myTime->GetCurrentTime();
|
||||
int textHeight = tvguideConfig.FontTimeLineTime->Height();
|
||||
int clockWidth = tvguideConfig.FontTimeLineTime->Width(*currentTime);
|
||||
clock->setColor(theme.Color(clrHeader), theme.Color(clrHeaderBlending));
|
||||
clock->drawBackground();
|
||||
clock->drawBorder();
|
||||
clock->DrawText(cPoint((tvguideConfig.timeColWidth-clockWidth)/2, (tvguideConfig.footerHeight-textHeight)/2), *currentTime, theme.Color(clrFontHeader), clrTransparent, tvguideConfig.FontTimeLineTime);
|
||||
}
|
22
timeline.h
Normal file
22
timeline.h
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef __TVGUIDE_TIMELINE_H
|
||||
#define __TVGUIDE_TIMELINE_H
|
||||
|
||||
// --- cTimeLine -------------------------------------------------------------
|
||||
|
||||
class cTimeLine {
|
||||
private:
|
||||
cMyTime *myTime;
|
||||
cStyledPixmap *dateViewer;
|
||||
cPixmap *timeline;
|
||||
cStyledPixmap *clock;
|
||||
cImage *createBackgroundImage(int width, int height, tColor clrBgr, tColor clrBlend);
|
||||
public:
|
||||
cTimeLine(cMyTime *myTime);
|
||||
virtual ~cTimeLine(void);
|
||||
void drawDateViewer();
|
||||
void drawTimeline();
|
||||
void setTimeline();
|
||||
void drawClock();
|
||||
};
|
||||
|
||||
#endif //__TVGUIDE_TIMELINE_H
|
106
timer.c
Normal file
106
timer.c
Normal file
@ -0,0 +1,106 @@
|
||||
#include "timer.h"
|
||||
|
||||
cMyTime::~cMyTime(void) {
|
||||
}
|
||||
|
||||
void cMyTime::Now() {
|
||||
t = time(0);
|
||||
tStart = t;
|
||||
tStart = GetRounded();
|
||||
tStop = tStart + (tvguideConfig.osdHeight - tvguideConfig.headerHeight - tvguideConfig.footerHeight)/tvguideConfig.minuteHeight*60;
|
||||
}
|
||||
|
||||
void cMyTime::AddStep(int step) {
|
||||
tStart += step*60;
|
||||
tStop += step*60;
|
||||
}
|
||||
|
||||
bool cMyTime::DelStep(int step) {
|
||||
if ((tStart - step*60)+30*60 < t) {
|
||||
return true;
|
||||
}
|
||||
tStart -= step*60;
|
||||
tStop -= step*60;
|
||||
return false;
|
||||
}
|
||||
|
||||
void cMyTime::SetTime(time_t newTime) {
|
||||
tStart = newTime;
|
||||
tStop = tStart + (tvguideConfig.osdHeight - tvguideConfig.headerHeight - tvguideConfig.footerHeight)/tvguideConfig.minuteHeight*60;
|
||||
}
|
||||
|
||||
time_t cMyTime::getPrevPrimetime(time_t current) {
|
||||
tm *st = localtime(¤t);
|
||||
if (st->tm_hour < 21) {
|
||||
current -= 24 * 60* 60;
|
||||
st = localtime(¤t);
|
||||
}
|
||||
st->tm_hour = 20;
|
||||
st->tm_min = 0;
|
||||
time_t primeTime = mktime(st);
|
||||
return primeTime;
|
||||
}
|
||||
|
||||
time_t cMyTime::getNextPrimetime(time_t current){
|
||||
tm *st = localtime(¤t);
|
||||
if (st->tm_hour > 19) {
|
||||
current += 24 * 60* 60;
|
||||
st = localtime(¤t);
|
||||
}
|
||||
st->tm_hour = 20;
|
||||
st->tm_min = 0;
|
||||
time_t primeTime = mktime(st);
|
||||
return primeTime;
|
||||
}
|
||||
|
||||
bool cMyTime::tooFarInPast(time_t current) {
|
||||
if (current < t) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
cString cMyTime::GetCurrentTime() {
|
||||
char buf[25];
|
||||
t = time(0);
|
||||
tm *st = localtime(&t);
|
||||
//snprintf(text, sizeof(text), "%d:%02d", st->tm_hour, st->tm_min);
|
||||
if (tvguideConfig.timeFormat == e12Hours) {
|
||||
strftime(buf, sizeof(buf), "%I:%M %p", st);
|
||||
} else if (tvguideConfig.timeFormat == e24Hours)
|
||||
strftime(buf, sizeof(buf), "%H:%M", st);
|
||||
return buf;
|
||||
|
||||
}
|
||||
|
||||
cString cMyTime::GetDate() {
|
||||
char text[6];
|
||||
tm *st = localtime(&tStart);
|
||||
snprintf(text, sizeof(text), "%d.%d", st->tm_mday, st->tm_mon+1);
|
||||
return text;
|
||||
}
|
||||
|
||||
cString cMyTime::GetWeekday() {
|
||||
return WeekDayName(tStart);
|
||||
}
|
||||
|
||||
int cMyTime::GetTimelineOffset() {
|
||||
tm *st = localtime(&tStart);
|
||||
int offset = st->tm_hour*60;
|
||||
offset += st->tm_min;
|
||||
return offset;
|
||||
}
|
||||
|
||||
time_t cMyTime::GetRounded() {
|
||||
tm *rounded = localtime ( &tStart );
|
||||
rounded->tm_sec = 0;
|
||||
if (rounded->tm_min > 29)
|
||||
rounded->tm_min = 30;
|
||||
else
|
||||
rounded->tm_min = 0;
|
||||
return mktime(rounded);
|
||||
}
|
||||
|
||||
void cMyTime::debug() {
|
||||
esyslog("t: %s, tStart: %s, tStop: %s", *TimeString(t), *TimeString(tStart), *TimeString(tStop));
|
||||
}
|
32
timer.h
Normal file
32
timer.h
Normal file
@ -0,0 +1,32 @@
|
||||
#ifndef __TVGUIDE_TIMER_H
|
||||
#define __TVGUIDE_TIMER_H
|
||||
|
||||
// --- cMyTime -------------------------------------------------------------
|
||||
|
||||
class cMyTime {
|
||||
private:
|
||||
time_t t;
|
||||
time_t tStart;
|
||||
time_t tStop;
|
||||
public:
|
||||
cMyTime(){};
|
||||
virtual ~cMyTime(void);
|
||||
void Now();
|
||||
void AddStep(int step);
|
||||
bool DelStep(int step);
|
||||
void SetTime(time_t newTime);
|
||||
time_t Get() {return t;};
|
||||
time_t GetStart() {return tStart;};
|
||||
time_t GetStop() {return tStop;};
|
||||
cString GetCurrentTime();
|
||||
cString GetDate();
|
||||
cString GetWeekday();
|
||||
time_t getPrevPrimetime(time_t current);
|
||||
time_t getNextPrimetime(time_t current);
|
||||
bool tooFarInPast(time_t current);
|
||||
int GetTimelineOffset();
|
||||
time_t GetRounded();
|
||||
void debug();
|
||||
};
|
||||
|
||||
#endif //__TVGUIDE_TIMER_H
|
194
tvguide.c
Normal file
194
tvguide.c
Normal file
@ -0,0 +1,194 @@
|
||||
/*
|
||||
* tvguide.c: A plugin for the Video Disk Recorder
|
||||
*
|
||||
* See the README file for copyright information and how to reach the author.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <time.h>
|
||||
#include <getopt.h>
|
||||
#include <vdr/osd.h>
|
||||
#include <vdr/plugin.h>
|
||||
#include <vdr/device.h>
|
||||
|
||||
#include "tvguideosd.c"
|
||||
|
||||
#if defined(APIVERSNUM) && APIVERSNUM < 10717
|
||||
#error "VDR-1.7.17 API version or greater is required!"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
static const char *VERSION = "0.0.1";
|
||||
static const char *DESCRIPTION = "A fancy 2d EPG Viewer";
|
||||
static const char *MAINMENUENTRY = "Tvguide";
|
||||
|
||||
class cPluginTvguide : public cPlugin {
|
||||
private:
|
||||
bool logoPathSet;
|
||||
bool imagesPathSet;
|
||||
public:
|
||||
cPluginTvguide(void);
|
||||
virtual ~cPluginTvguide();
|
||||
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 MAINMENUENTRY; }
|
||||
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);
|
||||
};
|
||||
|
||||
cPluginTvguide::cPluginTvguide(void)
|
||||
{
|
||||
// Initialize any member variables here.
|
||||
// DON'T DO ANYTHING ELSE THAT MAY HAVE SIDE EFFECTS, REQUIRE GLOBAL
|
||||
// VDR OBJECTS TO EXIST OR PRODUCE ANY OUTPUT!
|
||||
logoPathSet = false;
|
||||
imagesPathSet = false;
|
||||
}
|
||||
|
||||
cPluginTvguide::~cPluginTvguide()
|
||||
{
|
||||
// Clean up after yourself!
|
||||
}
|
||||
|
||||
const char *cPluginTvguide::CommandLineHelp(void)
|
||||
{
|
||||
// Return a string that describes all known command line options.
|
||||
return
|
||||
" -i <IMAGESDIR>, --epgimages=<IMAGESDIR> Set directory where epgimages are stored\n"
|
||||
" -l <LOGODIR>, --logodir=<LOGODIR> Set directory where logos are stored.\n";
|
||||
}
|
||||
|
||||
bool cPluginTvguide::ProcessArgs(int argc, char *argv[])
|
||||
{
|
||||
// Implement command line argument processing here if applicable.
|
||||
static const struct option long_options[] = {
|
||||
{ "epgimages", required_argument, NULL, 'i' },
|
||||
{ "logopath", required_argument, NULL, 'l' },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
int c;
|
||||
cString *path = NULL;
|
||||
while ((c = getopt_long(argc, argv, "i:f:l:", long_options, NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 'i':
|
||||
path = new cString(optarg);
|
||||
tvguideConfig.SetImagesPath(*path);
|
||||
imagesPathSet = true;
|
||||
break;
|
||||
case 'l':
|
||||
path = new cString(optarg);
|
||||
tvguideConfig.SetLogoPath(*path);
|
||||
logoPathSet = true;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
if (path)
|
||||
delete path;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cPluginTvguide::Initialize(void)
|
||||
{
|
||||
// Initialize any background activities the plugin shall perform.
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cPluginTvguide::Start(void)
|
||||
{
|
||||
if (!logoPathSet) {
|
||||
cString path = cString::sprintf("%s/channellogos/", cPlugin::ConfigDirectory(PLUGIN_NAME_I18N));
|
||||
tvguideConfig.SetLogoPath(path);
|
||||
logoPathSet = true;
|
||||
}
|
||||
|
||||
if (!imagesPathSet) {
|
||||
cString path = cString::sprintf("%s/epgimages/", cPlugin::ConfigDirectory(PLUGIN_NAME_I18N));
|
||||
tvguideConfig.SetImagesPath(path);
|
||||
logoPathSet = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void cPluginTvguide::Stop(void)
|
||||
{
|
||||
// Stop any background activities the plugin is performing.
|
||||
}
|
||||
|
||||
void cPluginTvguide::Housekeeping(void)
|
||||
{
|
||||
// Perform any cleanup or other regular tasks.
|
||||
}
|
||||
|
||||
void cPluginTvguide::MainThreadHook(void)
|
||||
{
|
||||
// Perform actions in the context of the main program thread.
|
||||
// WARNING: Use with great care - see PLUGINS.html!
|
||||
}
|
||||
|
||||
cString cPluginTvguide::Active(void)
|
||||
{
|
||||
// Return a message string if shutdown should be postponed
|
||||
return NULL;
|
||||
}
|
||||
|
||||
time_t cPluginTvguide::WakeupTime(void)
|
||||
{
|
||||
// Return custom wakeup time for shutdown script
|
||||
return 0;
|
||||
}
|
||||
|
||||
cOsdObject *cPluginTvguide::MainMenuAction(void)
|
||||
{
|
||||
// Perform the action when selected from the main VDR menu.
|
||||
return new cTvGuideOsd;
|
||||
}
|
||||
|
||||
cMenuSetupPage *cPluginTvguide::SetupMenu(void)
|
||||
{
|
||||
// Return a setup menu in case the plugin supports one.
|
||||
return new cTvguideSetup();
|
||||
}
|
||||
|
||||
bool cPluginTvguide::SetupParse(const char *Name, const char *Value)
|
||||
{
|
||||
// Parse your own setup parameters and store their values.
|
||||
return tvguideConfig.SetupParse(Name, Value);
|
||||
}
|
||||
|
||||
bool cPluginTvguide::Service(const char *Id, void *Data)
|
||||
{
|
||||
// Handle custom service requests from other plugins
|
||||
return false;
|
||||
}
|
||||
|
||||
const char **cPluginTvguide::SVDRPHelpPages(void)
|
||||
{
|
||||
// Return help text for SVDRP commands this plugin implements
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cString cPluginTvguide::SVDRPCommand(const char *Command, const char *Option, int &ReplyCode)
|
||||
{
|
||||
// Process SVDRP commands this plugin implements
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VDRPLUGINCREATOR(cPluginTvguide); // Don't touch this!
|
541
tvguideosd.c
Normal file
541
tvguideosd.c
Normal file
@ -0,0 +1,541 @@
|
||||
// --- Theme -------------------------------------------------------------
|
||||
static cTheme theme;
|
||||
|
||||
THEME_CLR(theme, clrBackgroundOSD, clrBlack);
|
||||
THEME_CLR(theme, clrBackground, clrBlack);
|
||||
THEME_CLR(theme, clrGrid1, 0xFF404749);
|
||||
THEME_CLR(theme, clrGrid1Blending, 0xFF000000);
|
||||
THEME_CLR(theme, clrGrid2, 0xFF20293F);
|
||||
THEME_CLR(theme, clrGrid2Blending, 0xFF000000);
|
||||
THEME_CLR(theme, clrHighlight, 0xFFFF4D00);
|
||||
THEME_CLR(theme, clrHighlightBlending, 0xFF000000);
|
||||
THEME_CLR(theme, clrFont, clrWhite);
|
||||
THEME_CLR(theme, clrFontHeader, clrWhite);
|
||||
THEME_CLR(theme, clrFontButtons, clrWhite);
|
||||
THEME_CLR(theme, clrHeader, clrBlack);
|
||||
THEME_CLR(theme, clrHeaderBlending, 0xFFE0E0E0);
|
||||
THEME_CLR(theme, clrBorder, clrWhite);
|
||||
THEME_CLR(theme, clrTimeline1, clrWhite);
|
||||
THEME_CLR(theme, clrTimeline1Blending, 0xFF828282);
|
||||
THEME_CLR(theme, clrTimeline2, clrBlack);
|
||||
THEME_CLR(theme, clrTimeline2Blending, 0xFF3F3F3F);
|
||||
THEME_CLR(theme, clrButtonRed, 0xFFD42627);
|
||||
THEME_CLR(theme, clrButtonRedBlending, 0xFFE0E0E0);
|
||||
THEME_CLR(theme, clrButtonGreen, 0xFF004F00);
|
||||
THEME_CLR(theme, clrButtonGreenBlending, 0xFFE0E0E0);
|
||||
THEME_CLR(theme, clrButtonYellow, 0xFFffa300);
|
||||
THEME_CLR(theme, clrButtonYellowBlending, 0xFFE0E0E0);
|
||||
THEME_CLR(theme, clrButtonBlue, 0xFF0000fe);
|
||||
THEME_CLR(theme, clrButtonBlueBlending, 0xFFE0E0E0);
|
||||
|
||||
#include "config.c"
|
||||
cTvguideConfig tvguideConfig;
|
||||
|
||||
#include "osdmanager.c"
|
||||
cOsdManager osdManager;
|
||||
|
||||
#include "setup.c"
|
||||
#include "imageloader.c"
|
||||
#include "styledpixmap.c"
|
||||
#include "timer.c"
|
||||
#include "messagebox.c"
|
||||
#include "timeline.c"
|
||||
#include "epggrid.c"
|
||||
#include "detailview.c"
|
||||
#include "channelcolumn.c"
|
||||
#include "footer.c"
|
||||
|
||||
#include "tvguideosd.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
cTvGuideOsd::cTvGuideOsd(void) {
|
||||
detailView = NULL;
|
||||
detailViewActive = false;
|
||||
timeLine = NULL;
|
||||
}
|
||||
|
||||
cTvGuideOsd::~cTvGuideOsd() {
|
||||
delete myTime;
|
||||
columns.Clear();
|
||||
if (detailView)
|
||||
delete detailView;
|
||||
delete timeLine;
|
||||
delete footer;
|
||||
cMessageBox::Destroy();
|
||||
osdManager.deleteOsd();
|
||||
}
|
||||
|
||||
void cTvGuideOsd::Show(void) {
|
||||
int start = cTimeMs::Now();
|
||||
bool ok = false;
|
||||
ok = osdManager.setOsd();
|
||||
if (ok) {
|
||||
tvguideConfig.setDynamicValues(osdManager.Width(), osdManager.Height());
|
||||
tvguideConfig.loadTheme();
|
||||
osdManager.setBackground();
|
||||
myTime = new cMyTime();
|
||||
myTime->Now();
|
||||
drawOsd();
|
||||
}
|
||||
esyslog("tvguide: Rendering took %d ms", int(cTimeMs::Now()-start));
|
||||
}
|
||||
|
||||
void cTvGuideOsd::drawOsd() {
|
||||
cPixmap::Lock();
|
||||
cChannel *startChannel = Channels.GetByNumber(cDevice::CurrentChannel());
|
||||
timeLine = new cTimeLine(myTime);
|
||||
timeLine->drawDateViewer();
|
||||
timeLine->drawTimeline();
|
||||
timeLine->drawClock();
|
||||
footer = new cFooter();
|
||||
footer->drawRedButton();
|
||||
footer->drawGreenButton();
|
||||
footer->drawYellowButton();
|
||||
footer->drawBlueButton();
|
||||
osdManager.flush();
|
||||
readChannels(startChannel);
|
||||
drawGridsChannelJump();
|
||||
osdManager.flush();
|
||||
cPixmap::Unlock();
|
||||
}
|
||||
|
||||
void cTvGuideOsd::readChannels(cChannel *channelStart) {
|
||||
int i=0;
|
||||
columns.Clear();
|
||||
if (!channelStart)
|
||||
return;
|
||||
for (cChannel *channel = channelStart; channel; channel = Channels.Next(channel)) {
|
||||
if (!channel->GroupSep()) {
|
||||
cChannelColumn *column = new cChannelColumn(i, channel, myTime);
|
||||
if (column->readGrids()) {
|
||||
columns.Add(column);
|
||||
i++;
|
||||
} else {
|
||||
delete column;
|
||||
}
|
||||
}
|
||||
if (i == tvguideConfig.channelCols)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool cTvGuideOsd::readChannelsReverse(cChannel *channelStart) {
|
||||
bool doUpdate = false;
|
||||
int i = tvguideConfig.channelCols;
|
||||
if (!channelStart)
|
||||
return false;
|
||||
for (cChannel *channel = Channels.Prev(channelStart); channel; channel = Channels.Prev(channel)) {
|
||||
if (!channel->GroupSep()) {
|
||||
cChannelColumn *column = new cChannelColumn(i-1, channel, myTime);
|
||||
if (column->readGrids()) {
|
||||
if (i == tvguideConfig.channelCols) {
|
||||
columns.Clear();
|
||||
doUpdate = true;
|
||||
}
|
||||
columns.Ins(column, columns.First());
|
||||
i--;
|
||||
} else {
|
||||
delete column;
|
||||
}
|
||||
}
|
||||
if (i == 0)
|
||||
break;
|
||||
}
|
||||
return doUpdate;
|
||||
}
|
||||
|
||||
void cTvGuideOsd::drawGridsChannelJump() {
|
||||
if (columns.Count() == 0)
|
||||
return;
|
||||
activeGrid = columns.First()->getActive();
|
||||
if (activeGrid)
|
||||
activeGrid->SetActive();
|
||||
for (cChannelColumn *column = columns.First(); column; column = columns.Next(column)) {
|
||||
column->createHeader();
|
||||
column->drawGrids();
|
||||
}
|
||||
}
|
||||
|
||||
void cTvGuideOsd::drawGridsTimeJump() {
|
||||
if (columns.Count() == 0)
|
||||
return;
|
||||
cChannelColumn *colActive = NULL;
|
||||
if (activeGrid) {
|
||||
colActive = activeGrid->column;
|
||||
} else {
|
||||
colActive = columns.First();
|
||||
}
|
||||
for (cChannelColumn *column = columns.First(); column; column = columns.Next(column)) {
|
||||
column->clearGrids();
|
||||
column->readGrids();
|
||||
column->drawGrids();
|
||||
}
|
||||
activeGrid = colActive->getActive();
|
||||
if (activeGrid) {
|
||||
activeGrid->SetActive();
|
||||
activeGrid->Draw();
|
||||
}
|
||||
}
|
||||
|
||||
void cTvGuideOsd::setNextActiveGrid(cEpgGrid *next) {
|
||||
if (!next || !activeGrid) {
|
||||
return;
|
||||
}
|
||||
activeGrid->SetInActive();
|
||||
activeGrid->Draw();
|
||||
activeGrid = next;
|
||||
activeGrid->SetActive();
|
||||
activeGrid->Draw();
|
||||
}
|
||||
|
||||
void cTvGuideOsd::processKeyUp() {
|
||||
if (detailViewActive) {
|
||||
detailView->scrollUp();
|
||||
} else {
|
||||
if (activeGrid == NULL) {
|
||||
ScrollBack();
|
||||
//Search for new active Grid
|
||||
cEpgGrid *actGrid = NULL;
|
||||
for (cChannelColumn *column = columns.First(); column; column = columns.Next(column)) {
|
||||
actGrid = column->getActive();
|
||||
if (actGrid) {
|
||||
activeGrid = actGrid;
|
||||
activeGrid->SetActive();
|
||||
activeGrid->Draw();
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (activeGrid->StartTime() <= myTime->GetStart()) {
|
||||
activeGrid->debug();
|
||||
ScrollBack();
|
||||
} else {
|
||||
cEpgGrid *prev = NULL;
|
||||
prev = activeGrid->column->getPrev(activeGrid);
|
||||
if (prev) {
|
||||
setNextActiveGrid(prev);
|
||||
} else {
|
||||
ScrollBack();
|
||||
prev = activeGrid->column->getPrev(activeGrid);
|
||||
if (prev) {
|
||||
setNextActiveGrid(prev);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
osdManager.flush();
|
||||
}
|
||||
|
||||
void cTvGuideOsd::processKeyDown() {
|
||||
if (detailViewActive) {
|
||||
detailView->scrollDown();
|
||||
} else {
|
||||
if (activeGrid == NULL) {
|
||||
ScrollForward();
|
||||
} else if (activeGrid->EndTime() > myTime->GetStop()) {
|
||||
ScrollForward();
|
||||
} else {
|
||||
cEpgGrid *next = NULL;
|
||||
next = activeGrid->column->getNext(activeGrid);
|
||||
if (next) {
|
||||
setNextActiveGrid(next);
|
||||
} else {
|
||||
ScrollForward();
|
||||
next = activeGrid->column->getNext(activeGrid);
|
||||
if (next) {
|
||||
setNextActiveGrid(next);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
osdManager.flush();
|
||||
}
|
||||
|
||||
void cTvGuideOsd::ScrollForward() {
|
||||
myTime->AddStep(tvguideConfig.stepMinutes);
|
||||
timeLine->drawDateViewer();
|
||||
timeLine->drawClock();
|
||||
timeLine->setTimeline();
|
||||
for (cChannelColumn *column = columns.First(); column; column = columns.Next(column)) {
|
||||
column->AddNewGridsAtEnd();
|
||||
column->ClearOutdatedStart();
|
||||
column->drawGrids();
|
||||
}
|
||||
}
|
||||
|
||||
void cTvGuideOsd::ScrollBack() {
|
||||
bool tooFarInPast = myTime->DelStep(tvguideConfig.stepMinutes);
|
||||
if (tooFarInPast)
|
||||
return;
|
||||
timeLine->drawDateViewer();
|
||||
timeLine->drawClock();
|
||||
timeLine->setTimeline();
|
||||
for (cChannelColumn *column = columns.First(); column; column = columns.Next(column)) {
|
||||
column->AddNewGridsAtStart();
|
||||
column->ClearOutdatedEnd();
|
||||
column->drawGrids();
|
||||
}
|
||||
}
|
||||
|
||||
void cTvGuideOsd::processKeyLeft() {
|
||||
if (detailViewActive)
|
||||
return;
|
||||
if (activeGrid == NULL)
|
||||
return;
|
||||
cChannelColumn *colLeft = columns.Prev(activeGrid->column);
|
||||
if (!colLeft) {
|
||||
cChannel *channelLeft = activeGrid->column->getChannel();
|
||||
while (channelLeft = Channels.Prev(channelLeft)) {
|
||||
if (!channelLeft->GroupSep()) {
|
||||
colLeft = new cChannelColumn(0, channelLeft, myTime);
|
||||
if (colLeft->readGrids()) {
|
||||
break;
|
||||
} else {
|
||||
delete colLeft;
|
||||
colLeft = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (colLeft) {
|
||||
if (columns.Count() == tvguideConfig.channelCols) {
|
||||
cChannelColumn *cLast = columns.Last();
|
||||
columns.Del(cLast);
|
||||
}
|
||||
for (cChannelColumn *column = columns.First(); column; column = columns.Next(column)) {
|
||||
column->SetNum(column->GetNum() + 1);
|
||||
column->drawHeader();
|
||||
column->drawGrids();
|
||||
}
|
||||
columns.Ins(colLeft, columns.First());
|
||||
colLeft->createHeader();
|
||||
colLeft->drawGrids();
|
||||
}
|
||||
}
|
||||
|
||||
if (colLeft) {
|
||||
cEpgGrid *left = colLeft->getNeighbor(activeGrid);
|
||||
if (left) {
|
||||
setNextActiveGrid(left);
|
||||
}
|
||||
}
|
||||
osdManager.flush();
|
||||
}
|
||||
|
||||
void cTvGuideOsd::processKeyRight() {
|
||||
if (detailViewActive)
|
||||
return;
|
||||
if (activeGrid == NULL)
|
||||
return;
|
||||
cChannelColumn *colRight = columns.Next(activeGrid->column);
|
||||
if (!colRight) {
|
||||
cChannel *channelRight = activeGrid->column->getChannel();
|
||||
while (channelRight = Channels.Next(channelRight)) {
|
||||
if (!channelRight->GroupSep()) {
|
||||
colRight = new cChannelColumn(tvguideConfig.channelCols - 1, channelRight, myTime);
|
||||
if (colRight->readGrids()) {
|
||||
break;
|
||||
} else {
|
||||
delete colRight;
|
||||
colRight = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (colRight) {
|
||||
if (columns.Count() == tvguideConfig.channelCols) {
|
||||
cChannelColumn *cFirst = columns.First();
|
||||
columns.Del(cFirst);
|
||||
}
|
||||
for (cChannelColumn *column = columns.First(); column; column = columns.Next(column)) {
|
||||
column->SetNum(column->GetNum() - 1);
|
||||
column->drawHeader();
|
||||
column->drawGrids();
|
||||
}
|
||||
columns.Add(colRight);
|
||||
colRight->createHeader();
|
||||
colRight->drawGrids();
|
||||
}
|
||||
}
|
||||
if (colRight) {
|
||||
cEpgGrid *right = colRight->getNeighbor(activeGrid);
|
||||
if (right) {
|
||||
setNextActiveGrid(right);
|
||||
}
|
||||
}
|
||||
osdManager.flush();
|
||||
}
|
||||
|
||||
void cTvGuideOsd::processKeyOk() {
|
||||
if (detailViewActive) {
|
||||
delete detailView;
|
||||
detailView = NULL;
|
||||
detailViewActive = false;
|
||||
osdManager.flush();
|
||||
} else {
|
||||
detailViewActive = true;
|
||||
detailView = new cDetailView(activeGrid);
|
||||
detailView->Start();
|
||||
}
|
||||
}
|
||||
|
||||
void cTvGuideOsd::processKeyRed() {
|
||||
if (activeGrid == NULL)
|
||||
return;
|
||||
cTimer *timer = new cTimer(activeGrid->GetEvent());
|
||||
cTimer *t = Timers.GetTimer(timer);
|
||||
cString msg;
|
||||
if (t) {
|
||||
isyslog("timer %s already exists", *timer->ToDescr());
|
||||
delete timer;
|
||||
msg = cString::sprintf(tr("Timer not set! There is already a timer for this item."));
|
||||
} else {
|
||||
Timers.Add(timer);
|
||||
Timers.SetModified();
|
||||
msg = cString::sprintf("%s:\n%s (%s) %s - %s", tr("Timer set"), activeGrid->GetEvent()->Title(), timer->Channel()->Name(), *DayDateTime(timer->StartTime()), *TimeString(timer->StopTime()));
|
||||
timer->SetEvent(activeGrid->GetEvent());
|
||||
activeGrid->setTimer();
|
||||
activeGrid->column->setTimer();
|
||||
activeGrid->SetDirty();
|
||||
activeGrid->Draw();
|
||||
osdManager.flush();
|
||||
isyslog("timer %s added (active)", *timer->ToDescr());
|
||||
}
|
||||
cMessageBox::Start(4000, msg);
|
||||
}
|
||||
|
||||
void cTvGuideOsd::processKeyGreen() {
|
||||
if (activeGrid == NULL)
|
||||
return;
|
||||
cChannel *currentChannel = activeGrid->column->getChannel();
|
||||
bool doUpdate = readChannelsReverse(currentChannel);
|
||||
if (doUpdate && (columns.Count() > 0)) {
|
||||
drawGridsChannelJump();
|
||||
}
|
||||
osdManager.flush();
|
||||
}
|
||||
|
||||
void cTvGuideOsd::processKeyYellow() {
|
||||
if (activeGrid == NULL)
|
||||
return;
|
||||
cChannel *currentChannel = activeGrid->column->getChannel();
|
||||
cChannel *next = NULL;
|
||||
int i=0;
|
||||
for (cChannel *channel = currentChannel; channel; channel = Channels.Next(channel)) {
|
||||
if (!channel->GroupSep()) {
|
||||
next = channel;
|
||||
i++;
|
||||
}
|
||||
if (i == (tvguideConfig.jumpChannels+1))
|
||||
break;
|
||||
}
|
||||
if (next) {
|
||||
readChannels(next);
|
||||
if (columns.Count() > 0) {
|
||||
drawGridsChannelJump();
|
||||
}
|
||||
osdManager.flush();
|
||||
}
|
||||
}
|
||||
|
||||
eOSState cTvGuideOsd::processKeyBlue() {
|
||||
if (activeGrid == NULL)
|
||||
return osContinue;
|
||||
cChannel *currentChannel = activeGrid->column->getChannel();
|
||||
if (currentChannel) {
|
||||
cDevice::PrimaryDevice()->SwitchChannel(currentChannel, true);
|
||||
return osEnd;
|
||||
}
|
||||
return osContinue;
|
||||
}
|
||||
|
||||
void cTvGuideOsd::processKey1() {
|
||||
bool tooFarInPast = myTime->DelStep(tvguideConfig.bigStepHours*60);
|
||||
if (tooFarInPast)
|
||||
return;
|
||||
drawGridsTimeJump();
|
||||
timeLine->drawDateViewer();
|
||||
timeLine->drawClock();
|
||||
timeLine->setTimeline();
|
||||
osdManager.flush();
|
||||
}
|
||||
|
||||
void cTvGuideOsd::processKey3() {
|
||||
myTime->AddStep(tvguideConfig.bigStepHours*60);
|
||||
drawGridsTimeJump();
|
||||
timeLine->drawDateViewer();
|
||||
timeLine->drawClock();
|
||||
timeLine->setTimeline();
|
||||
osdManager.flush();
|
||||
}
|
||||
|
||||
void cTvGuideOsd::processKey4() {
|
||||
bool tooFarInPast = myTime->DelStep(tvguideConfig.hugeStepHours*60);
|
||||
if (tooFarInPast)
|
||||
return;
|
||||
drawGridsTimeJump();
|
||||
timeLine->drawDateViewer();
|
||||
timeLine->drawClock();
|
||||
timeLine->setTimeline();
|
||||
osdManager.flush();
|
||||
}
|
||||
|
||||
void cTvGuideOsd::processKey6() {
|
||||
myTime->AddStep(tvguideConfig.hugeStepHours*60);
|
||||
drawGridsTimeJump();
|
||||
timeLine->drawDateViewer();
|
||||
timeLine->drawClock();
|
||||
timeLine->setTimeline();
|
||||
osdManager.flush();
|
||||
}
|
||||
|
||||
void cTvGuideOsd::processKey7() {
|
||||
cMyTime *primeChecker = new cMyTime();
|
||||
primeChecker->Now();
|
||||
time_t prevPrime = primeChecker->getPrevPrimetime(myTime->GetStart());
|
||||
if (primeChecker->tooFarInPast(prevPrime))
|
||||
return;
|
||||
myTime->SetTime(prevPrime);
|
||||
drawGridsTimeJump();
|
||||
timeLine->drawDateViewer();
|
||||
timeLine->drawClock();
|
||||
timeLine->setTimeline();
|
||||
osdManager.flush();
|
||||
}
|
||||
|
||||
void cTvGuideOsd::processKey9() {
|
||||
cMyTime *primeChecker = new cMyTime();
|
||||
time_t nextPrime = primeChecker->getNextPrimetime(myTime->GetStart());
|
||||
myTime->SetTime(nextPrime);
|
||||
drawGridsTimeJump();
|
||||
timeLine->drawDateViewer();
|
||||
timeLine->drawClock();
|
||||
timeLine->setTimeline();
|
||||
osdManager.flush();
|
||||
}
|
||||
|
||||
eOSState cTvGuideOsd::ProcessKey(eKeys Key) {
|
||||
eOSState state = cOsdObject::ProcessKey(Key);
|
||||
if (state == osUnknown) {
|
||||
cPixmap::Lock();
|
||||
state = osContinue;
|
||||
switch (Key & ~k_Repeat) {
|
||||
case kUp: processKeyUp(); break;
|
||||
case kDown: processKeyDown(); break;
|
||||
case kLeft: processKeyLeft(); break;
|
||||
case kRight: processKeyRight(); break;
|
||||
case kRed: processKeyRed(); break;
|
||||
case kGreen: processKeyGreen(); break;
|
||||
case kYellow: processKeyYellow(); break;
|
||||
case kBlue: state = processKeyBlue(); break;
|
||||
case kOk: processKeyOk(); break;
|
||||
case kBack: state=osEnd; break;
|
||||
case k1: processKey1(); break;
|
||||
case k3: processKey3(); break;
|
||||
case k4: processKey4(); break;
|
||||
case k6: processKey6(); break;
|
||||
case k7: processKey7(); break;
|
||||
case k9: processKey9(); break;
|
||||
default: break;
|
||||
}
|
||||
cPixmap::Unlock();
|
||||
}
|
||||
return state;
|
||||
}
|
45
tvguideosd.h
Normal file
45
tvguideosd.h
Normal file
@ -0,0 +1,45 @@
|
||||
#ifndef __TVGUIDE_TVGUIDEOSD_H
|
||||
#define __TVGUIDE_TVGUIDEOSD_H
|
||||
|
||||
// --- cTvGuideOsd -------------------------------------------------------------
|
||||
|
||||
class cTvGuideOsd : public cOsdObject {
|
||||
private:
|
||||
cMyTime *myTime;
|
||||
cList<cChannelColumn> columns;
|
||||
cEpgGrid *activeGrid;
|
||||
cDetailView *detailView;
|
||||
cTimeLine *timeLine;
|
||||
cFooter *footer;
|
||||
bool detailViewActive;
|
||||
void drawOsd();
|
||||
void readChannels(cChannel *channelStart);
|
||||
bool readChannelsReverse(cChannel *channelStart);
|
||||
void drawGridsChannelJump();
|
||||
void drawGridsTimeJump();
|
||||
void processKeyUp();
|
||||
void processKeyDown();
|
||||
void processKeyLeft();
|
||||
void processKeyRight();
|
||||
void processKeyRed();
|
||||
void processKeyGreen();
|
||||
void processKeyYellow();
|
||||
eOSState processKeyBlue();
|
||||
void processKeyOk();
|
||||
void processKey1();
|
||||
void processKey3();
|
||||
void processKey4();
|
||||
void processKey6();
|
||||
void processKey7();
|
||||
void processKey9();
|
||||
void setNextActiveGrid(cEpgGrid *next);
|
||||
void ScrollForward();
|
||||
void ScrollBack();
|
||||
public:
|
||||
cTvGuideOsd(void);
|
||||
virtual ~cTvGuideOsd(void);
|
||||
virtual void Show(void);
|
||||
virtual eOSState ProcessKey(eKeys Key);
|
||||
};
|
||||
|
||||
#endif //__TVGUIDE_TVGUIDEOSD_H
|
Loading…
Reference in New Issue
Block a user